OpenBarnyard
 
Loading...
Searching...
No Matches
TTRB.cpp
Go to the documentation of this file.
1#include "ToshiPCH.h"
2#include "TTRB.h"
3#include "TTSF.h"
4
5//-----------------------------------------------------------------------------
6// Enables memory debugging.
7// Note: Should be the last include!
8//-----------------------------------------------------------------------------
10
12
13static constexpr TTRB::t_MemoryFuncAlloc s_cbDefAllocator = []( TTRB::AllocType alloctype, TUINT32 size, short unk1, TUINT32 unk2, void* userData ) {
14 return TMalloc( size );
15};
16
17static constexpr TTRB::t_MemoryFuncDealloc s_cbDefDeallocator = []( TTRB::AllocType alloctype, void* ptr, short unk1, TUINT32 unk2, void* userData ) {
18 TFree( ptr );
19};
20
21void* TTRB::s_pDefAllocatorUserData = TNULL;
22
23// $Barnyard: FUNCTION 006ba9e0
25{
26 m_pHeader = TNULL;
27 m_SYMB = TNULL;
28 SetMemoryFunctions( s_cbDefAllocator, s_cbDefDeallocator, s_pDefAllocatorUserData );
29}
30
31// $Barnyard: FUNCTION 006baff0
33{
34 Close();
35}
36
37// $Barnyard: FUNCTION 006bb000
38TTRB::ERROR TTRB::Load( const TCHAR* a_szFilePath, TUINT32 a_uiUnknown )
39{
41 ERROR error = m_TTSFI.Open( a_szFilePath );
42
43 if ( error == ERROR_OK )
44 {
45 if ( m_TTSFI.m_Magic == TFourCC( "TRBF" ) )
46 {
47 m_UNK = a_uiUnknown;
48
49 if ( ProcessForm( m_TTSFI ) )
50 {
51 error = ERROR_OK;
52 }
53 else
54 {
55 error = ERROR_PARSE_ERROR;
56 }
57 }
58 else
59 {
60 error = ERROR_NOT_TRBF;
61 }
62 }
63 else
64 {
65 error = ERROR_NO_HEADER;
66 }
67
68 m_TTSFI.Close();
69 return error;
70}
71
72// $Barnyard: FUNCTION 006baad0
73TBOOL TTRB::ProcessForm( TTSFI& ttsf )
74{
76
77 static constexpr TUINT32 MAX_RELC_NUM_BATCH = 512;
78 RELCEntry relcEntries[ MAX_RELC_NUM_BATCH ];
79
80 TINT32 fileSize = ttsf.m_CurrentHunk.Size - 4;
81 TINT32 leftSize = fileSize;
82 ttsf.PushForm();
83
84 do
85 {
86 TUINT32 sectionName = 0;
87 TUINT32 sectionSize = 0;
88
89 while ( TTRUE )
90 {
91 if ( fileSize < 1 )
92 {
93 ttsf.PopForm();
94 return TTRUE;
95 }
96
97 uint8_t readResult = ttsf.ReadHunk();
98 if ( readResult != ERROR_OK ) return TFALSE;
99
100 sectionName = ttsf.m_CurrentHunk.Name;
101 sectionSize = ttsf.m_CurrentHunk.Size;
102 leftSize -= TAlignNumUp( sectionSize ) + sizeof( Toshi::TTSF::Hunk );
103
104 if ( TFourCC( "HEAD" ) < sectionName ) break;
105
106 if ( sectionName == TFourCC( "HEAD" ) )
107 {
108 TINT numsections = ( sectionSize - 4 ) / 0xC;
109
110 m_pHeader = static_cast<Header*>( m_MemAllocator( AllocType_Unk0, sizeof( Header ) + sizeof( SecInfo ) * numsections, 0, 0, m_MemUserData ) );
111 m_pHeader->m_ui32Version = { 0 };
112
113 ttsf.ReadRaw( &m_pHeader->m_i32SectionCount, sizeof( m_pHeader->m_i32SectionCount ) );
114
115 TASSERT( m_pHeader->m_i32SectionCount == numsections, "HEAD section has wrong num of sections" );
116
117 for ( TINT i = 0; i < m_pHeader->m_i32SectionCount; i++ )
118 {
119 SecInfo* pSect = GetSectionInfo( i );
120
121 ttsf.ReadRaw( pSect, 0xC );
122 pSect->m_Data = m_MemAllocator( AllocType_Unk1, pSect->m_Size, 0, 0, m_MemUserData );
123 pSect->m_Unk1 = ( pSect->m_Unk1 == 0 ) ? 16 : pSect->m_Unk1;
124 pSect->m_Unk2 = 0;
125 }
126
127 ttsf.SkipHunk();
128 }
129 else if ( sectionName == TFourCC( "SYMB" ) )
130 {
131 m_SYMB = static_cast<SYMB*>( m_MemAllocator( AllocType_Unk2, ttsf.m_CurrentHunk.Size, 0, 0, m_MemUserData ) );
132 ttsf.ReadHunkData( m_SYMB );
133 }
134 else if ( sectionName == TFourCC( "SECC" ) )
135 {
136 Toshi::TCompress::ms_bIsBigEndian = ( CURRENT_ENDIANESS == Endianess_Big );
137
138 for ( TINT i = 0; i < m_pHeader->m_i32SectionCount; i++ )
139 {
140 auto* secInfo = GetSectionInfo( i );
141
142 if ( secInfo->m_Data != TNULL )
143 {
144 ttsf.ReadCompressed( secInfo->m_Data, secInfo->m_Size );
145 }
146 }
147
148 ttsf.SkipHunk();
149 }
150 else if ( sectionName == TFourCC( "RELC" ) )
151 {
152 TUINT32 relocCount = 0;
153 TUINT32 curReloc = 0;
154 TUINT32 readedRelocs = 0;
155
156 ttsf.ReadRaw( &relocCount, sizeof( relocCount ) );
157
158 if ( relocCount < 1 )
159 {
160 relocCount = 0;
161 }
162 else
163 {
164 do
165 {
166 TUINT32 relocReadCount = relocCount - readedRelocs;
167
168 // limit count of RELCs to read
169 relocReadCount = TMath::Min( relocReadCount, MAX_RELC_NUM_BATCH );
170 ttsf.Read( relcEntries, relocReadCount );
171 curReloc = readedRelocs + relocReadCount;
172
173 auto& header = *m_pHeader;
174 for ( TUINT32 i = 0; i < relocReadCount; i++ )
175 {
176 auto& relcEntry = relcEntries[ i ];
177 auto hdrx1 = GetSectionInfo( relcEntry.HDRX1 );
178 auto hdrx2 = hdrx1;
179
180 if ( m_pHeader->m_ui32Version.Value >= TVERSION( 1, 0 ) )
181 {
182 hdrx2 = GetSectionInfo( relcEntry.HDRX2 );
183 }
184
185 // this won't work in x64 because pointers in TRB files are always 4 bytes
186 // need some workaround to support x64 again
187 TSTATICASSERT( sizeof( void* ) == 4 );
188 TUINTPTR* ptr = TREINTERPRETCAST( TUINTPTR*, TUINTPTR( hdrx1->m_Data ) + relcEntry.Offset );
189 *ptr += TUINTPTR( hdrx2->m_Data );
190 }
191
192 readedRelocs += relocReadCount;
193 } while ( curReloc < relocCount );
194 }
195
196 ttsf.SkipHunk();
197 }
198 else
199 {
200 // Unknown section
201 ttsf.SkipHunk();
202 }
203
204 fileSize = leftSize;
205 }
206
207 if ( sectionName != TFourCC( "FORM" ) )
208 {
209 if ( sectionName == TFourCC( "SECT" ) )
210 {
211 for ( TINT i = 0; i < m_pHeader->m_i32SectionCount; i++ )
212 {
213 SecInfo* pSect = GetSectionInfo( i );
214 ttsf.ReadRaw( pSect->m_Data, pSect->m_Size );
215 }
216
217 ttsf.SkipHunk();
218 }
219 else if ( sectionName == TFourCC( "HDRX" ) )
220 {
221 m_pHeader = TSTATICCAST( Header, m_MemAllocator( AllocType_Unk0, sectionSize, 0, 0, m_MemUserData ) );
222 ttsf.ReadHunkData( m_pHeader );
223
224 for ( TINT i = 0; i < m_pHeader->m_i32SectionCount; i++ )
225 {
226 SecInfo* pSect = GetSectionInfo( i );
227 pSect->m_Unk1 = ( pSect->m_Unk1 == 0 ) ? 16 : pSect->m_Unk1;
228 pSect->m_Data = m_MemAllocator( AllocType_Unk1, pSect->m_Size, pSect->m_Unk1, pSect->m_Unk2, m_MemUserData );
229 }
230 }
231 else
232 {
233 // Unknown section
234 ttsf.SkipHunk();
235 }
236
237 fileSize = leftSize;
238 }
239 } while ( TTRUE );
240
241 TFORM form;
242 ttsf.ReadFORM( &form );
243
244 TBOOL result = ProcessForm( ttsf );
245 fileSize = leftSize;
246
247 return result;
248}
249
250// $Barnyard: FUNCTION 006bafa0
251void* TTRB::GetSymbolAddress( const TCHAR* symbName )
252{
253 auto index = GetSymbolIndex( symbName );
254
255 if ( m_SYMB != TNULL && index != -1 && index < m_SYMB->m_i32SymbCount )
256 {
257 auto entry = GetSymbol( index );
258 return static_cast<TCHAR*>( GetSection( entry->HDRX ) ) + entry->DataOffset;
259 }
260
261 return TNULL;
262}
263
264// $Barnyard: FUNCTION 006baeb0
266{
267 if ( m_SYMB != TNULL )
268 {
269 short hash = HashString( symbName );
270
271 for ( TINT i = 0; i < m_SYMB->m_i32SymbCount; i++ )
272 {
273 auto symbol = GetSymbol( i );
274
275 if ( symbol->NameHash == hash )
276 {
277 if ( Toshi::TStringManager::String8Compare( symbName, GetSymbolName( symbol ), -1 ) == 0 )
278 {
279 return i;
280 }
281 }
282 }
283 }
284
285 return -1;
286}
287
288// $Barnyard: FUNCTION 006baa20
290{
291 if ( m_pHeader != TNULL )
292 {
293 for ( TINT i = 0; i < m_pHeader->m_i32SectionCount; i++ )
294 {
295 auto sec = GetSectionInfo( i );
296
297 if ( sec->m_Data != TNULL )
298 {
299 m_MemDeallocator( AllocType_Unk1, sec->m_Data, sec->m_Unk1, sec->m_Unk2, m_MemUserData );
300 }
301 }
302
303 m_MemDeallocator( AllocType_Unk0, m_pHeader, 0, 0, m_MemUserData );
304 m_pHeader = TNULL;
305 }
306
308}
309
310// $Barnyard: FUNCTION 006ba950
311void TTRB::SetMemoryFunctions( t_MemoryFuncAlloc allocator, t_MemoryFuncDealloc deallocator, void* userdata )
312{
313 m_MemAllocator = allocator;
314 m_MemDeallocator = deallocator;
315 m_MemUserData = userdata;
316}
317
318// $Barnyard: FUNCTION 006ba8b0
320{
321 if ( m_SYMB != TNULL )
322 {
323 m_MemDeallocator( AllocType_Unk2, m_SYMB, 0, 0, m_MemUserData );
324 m_SYMB = TNULL;
325 }
326}
327
329{
330 TINT16 hash = 0;
331 TCHAR character;
332
333 while ( *str != '\0' )
334 {
335 character = *( str++ );
336 hash = (TINT16)character + hash * 0x1f;
337 }
338
339 return hash;
340}
341
342// $Barnyard: FUNCTION 006ba920
343const TCHAR* TTRB::GetSymbolName( TTRBSymbol* symbol ) const
344{
345 if ( m_SYMB == TNULL )
346 {
347 return TNULL;
348 }
349
350 return reinterpret_cast<const TCHAR*>(
351 reinterpret_cast<uintptr_t>( m_SYMB ) +
352 GetSymbolTableSize( m_SYMB->m_i32SymbCount ) +
353 symbol->NameOffset
354 );
355}
356
357const TCHAR* TTRB::GetSymbolName( TINT index ) const
358{
359 if ( m_SYMB == TNULL )
360 {
361 return TNULL;
362 }
363
364 return GetSymbolName( reinterpret_cast<TTRBSymbol*>( m_SYMB + 1 ) + index );
365}
366
367// $Barnyard: FUNCTION 006ba8f0
369{
370 if ( m_SYMB == TNULL )
371 {
372 return TNULL;
373 }
374 else if ( index < m_SYMB->m_i32SymbCount )
375 {
376 return reinterpret_cast<TTRBSymbol*>( m_SYMB + 1 ) + index;
377 }
378
379 return TNULL;
380}
381
382// $Barnyard: FUNCTION 006baf60
384{
385 TINT index = GetSymbolIndex( a_symbolName );
386 if ( index == -1 )
387 {
388 return TNULL;
389 }
390
391 return GetSymbol( index );
392}
393
void * TMalloc(TSIZE a_uiSize, Toshi::TMemory::MemBlock *a_pMemBlock, const TCHAR *a_szFileName, TINT a_iLineNum)
Allocates memory from a specific memory block.
Definition TMemory.cpp:973
void TFree(void *a_pMem)
Frees previously allocated memory.
Definition TMemory.cpp:1054
TRB (Toshi Relocatable Binary) resource system for the Toshi engine.
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TREINTERPRETCAST(TYPE, VALUE)
Definition Defines.h:68
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TVERSION(VER_MAJOR, VER_MINOR)
Definition Defines.h:14
#define TSTATICASSERT(...)
Definition Defines.h:67
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
@ Endianess_Big
Definition Endianness.h:9
TFORCEINLINE constexpr T TAlignNumUp(T a_iValue, TSIZE a_uiAlignment=4)
Definition Helpers.h:66
TFORCEINLINE constexpr TUINT32 TFourCC(const TCHAR str[4])
Definition Helpers.h:15
#define TPROFILER_SCOPE()
Definition Profiler.h:17
int32_t TINT32
Definition Typedefs.h:12
uintptr_t TUINTPTR
Definition Typedefs.h:18
int16_t TINT16
Definition Typedefs.h:14
char TCHAR
Definition Typedefs.h:20
#define TNULL
Definition Typedefs.h:23
uint32_t TUINT32
Definition Typedefs.h:13
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
TFORCEINLINE const T & Min(const T &a, const T &b)
TUINT32 Name
Definition TTRB.h:56
TUINT32 Size
Definition TTRB.h:57
Definition TTRB.h:74
void ReadCompressed(void *buffer, TUINT32 size)
Definition TTSF.cpp:170
TUINT8 ReadHunk()
Definition TTSF.cpp:102
TUINT8 SkipHunk()
Definition TTSF.cpp:118
TUINT32 PushForm()
Definition TTSF.cpp:67
void ReadRaw(void *dst, TUINT32 size)
Definition TTSF.cpp:347
void Read(T *a_pDst)
Definition TTRB.h:92
TUINT8 ReadHunkData(void *dest)
Definition TTSF.cpp:141
TUINT32 PopForm()
Definition TTSF.cpp:84
TUINT8 ReadFORM(TFORM *section)
Definition TTSF.cpp:128
void(*)(AllocType alloctype, void *ptr, TINT16 unk1, TUINT32 unk2, void *userData) t_MemoryFuncDealloc
Definition TTRB.h:278
static TINT16 HashString(const TCHAR *str)
Definition TTRB.cpp:328
@ AllocType_Unk0
Definition TTRB.h:272
@ AllocType_Unk1
Definition TTRB.h:273
@ AllocType_Unk2
Definition TTRB.h:274
TTRB()
Definition TTRB.cpp:24
TTRBSymbol * GetSymbol(TINT index) const
Definition TTRB.cpp:368
static TUINT32 GetSymbolTableSize(TUINT32 count)
Definition TTRB.h:354
void DeleteSymbolTable()
Definition TTRB.cpp:319
ERROR Load(const TCHAR *a_szFilePath, TUINT32 a_uiUnknown=0)
Definition TTRB.cpp:38
void * GetSymbolAddress(const TCHAR *symbName)
Definition TTRB.cpp:251
SecInfo * GetSectionInfo(TINT index) const
Definition TTRB.h:337
const TCHAR * GetSymbolName(TINT index) const
Definition TTRB.cpp:357
void SetMemoryFunctions(t_MemoryFuncAlloc allocator, t_MemoryFuncDealloc deallocator, void *userdata)
Definition TTRB.cpp:311
void Close()
Definition TTRB.cpp:289
~TTRB()
Definition TTRB.cpp:32
@ ERROR_NOT_TRBF
Definition TTRB.h:260
@ ERROR_OK
Definition TTRB.h:258
@ ERROR_NO_HEADER
Definition TTRB.h:259
@ ERROR_PARSE_ERROR
Definition TTRB.h:261
TUINT8 ERROR
Definition TTRB.h:255
TUINT8 AllocType
Definition TTRB.h:269
TINT GetSymbolIndex(const TCHAR *symbName)
Definition TTRB.cpp:265
void *(*)(AllocType alloctype, TUINT32 size, TINT16 unk1, TUINT32 unk2, void *userData) t_MemoryFuncAlloc
Definition TTRB.h:277
TVersion m_ui32Version
Definition TTRB.h:291
TUINT16 NameOffset
Definition TTRB.h:305