Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
20 | pmbaty | 1 | #include "datafile.h" |
2 | #include "CORE/FW/bswap.h" |
||
3 | #include "CORE/FW/diag.h" |
||
4 | #include "CORE/FW/file.h" |
||
5 | #include "CORE/FW/fwsetup.h" |
||
6 | #include "CORE/FW/resource.h" |
||
7 | #include "CORE/FW/scratch.h" |
||
8 | #include "CORE/MATH/fixed.h" |
||
9 | #include "CORE/STD/brstdlib.h" |
||
10 | #include "harness/trace.h" |
||
11 | |||
12 | #if BR_ENDIAN_BIG |
||
13 | |||
14 | #define BR_HTON_32(b) (b) |
||
15 | #define BR_HTON_16(b) (b) |
||
16 | #define BR_HTON_F(b) (b) |
||
17 | #define BR_HTON_D(b) (b) |
||
18 | |||
19 | #define BR_NTOH_32(b) (b) |
||
20 | #define BR_NTOH_16(b) (b) |
||
21 | #define BR_NTOH_F(b) (b) |
||
22 | #define BR_NTOH_D(b) (b) |
||
23 | |||
24 | #else |
||
25 | |||
26 | #define BR_HTON_32(b) (3-(b)) |
||
27 | #define BR_HTON_16(b) (1-(b)) |
||
28 | #define BR_HTON_F(b) (3-(b)) |
||
29 | #define BR_HTON_D(b) (7-(b)) |
||
30 | |||
31 | #define BR_NTOH_32(b) (3-(b)) |
||
32 | #define BR_NTOH_16(b) (1-(b)) |
||
33 | #define BR_NTOH_F(b) (3-(b)) |
||
34 | #define BR_NTOH_D(b) (7-(b)) |
||
35 | |||
36 | #endif |
||
37 | |||
38 | br_file_primitives _BrFilePrimsNull = { |
||
39 | "NULL", |
||
40 | (int (*)(br_datafile*, br_uint_32)) & BrNullOther, |
||
41 | (int (*)(br_datafile*, br_uint_32, br_uint_32)) & BrNullOther, |
||
42 | (int (*)(br_datafile*, br_uint_32*)) & BrNullOther, |
||
43 | (void (*)(br_datafile*, br_uint_32)) & BrNullOther, |
||
44 | (br_uint_32(*)(br_datafile*)) & BrNullOther, |
||
45 | (int (*)(br_datafile*)) & BrNullOther, |
||
46 | (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
47 | (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
48 | (int (*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
49 | (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, |
||
50 | (void* (*)(br_datafile*, void*, int*, int, int)) & BrNullOther, |
||
51 | (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, |
||
52 | (int (*)(br_datafile*, char*)) & BrNullOther, |
||
53 | (char* (*)(br_datafile*, char*)) & BrNullOther, |
||
54 | (int (*)(br_datafile*, char*)) & BrNullOther, |
||
55 | }; |
||
56 | |||
57 | br_file_primitives _BrFilePrimsReadBinary = { |
||
58 | "Read Binary", |
||
59 | &DfSkipBinary, |
||
60 | (int (*)(br_datafile*, br_uint_32, br_uint_32)) & BrNullOther, |
||
61 | &DfChunkReadBinary, |
||
62 | (void (*)(br_datafile*, br_uint_32)) & BrNullOther, |
||
63 | &DfCountReadBinary, |
||
64 | &DfCountSizeBinary, |
||
65 | (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
66 | &DfStructReadBinary, |
||
67 | &DfStructSizeBinary, |
||
68 | (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, |
||
69 | &DfBlockReadBinary, |
||
70 | &DfBlockSizeBinary, |
||
71 | (int (*)(br_datafile*, char*)) & BrNullOther, |
||
72 | &DfNameReadBinary, |
||
73 | &DfNameSizeBinary, |
||
74 | }; |
||
75 | |||
76 | br_file_primitives _BrFilePrimsWriteBinary = { |
||
77 | "Write Binary", |
||
78 | &DfSkipBinary, |
||
79 | &DfChunkWriteBinary, |
||
80 | (int (*)(br_datafile*, br_uint_32*)) & BrNullOther, |
||
81 | &DfCountWriteBinary, |
||
82 | (br_uint_32(*)(br_datafile*)) & BrNullOther, |
||
83 | &DfCountSizeBinary, |
||
84 | &DfStructWriteBinary, |
||
85 | (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
86 | &DfStructSizeBinary, |
||
87 | &DfBlockWriteBinary, |
||
88 | (void* (*)(br_datafile*, void*, int*, int, int)) & BrNullOther, |
||
89 | &DfBlockSizeBinary, |
||
90 | &DfNameWriteBinary, |
||
91 | (char* (*)(br_datafile*, char*)) & BrNullOther, |
||
92 | &DfNameSizeBinary, |
||
93 | }; |
||
94 | |||
95 | br_file_primitives _BrFilePrimsReadText = { |
||
96 | "Read Text", |
||
97 | &DfSkipText, |
||
98 | (int (*)(br_datafile*, br_uint_32, br_uint_32)) & BrNullOther, |
||
99 | &DfChunkReadText, |
||
100 | (void (*)(br_datafile*, br_uint_32)) & BrNullOther, |
||
101 | &DfCountReadText, |
||
102 | &DfCountSizeText, |
||
103 | (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
104 | &DfStructReadText, |
||
105 | &DfStructSizeText, |
||
106 | (int (*)(br_datafile*, void*, int, int, int, int)) & BrNullOther, |
||
107 | &DfBlockReadText, |
||
108 | &DfBlockSizeText, |
||
109 | (int (*)(br_datafile*, char*)) & BrNullOther, |
||
110 | &DfNameReadText, |
||
111 | &DfNameSizeText, |
||
112 | }; |
||
113 | |||
114 | br_file_primitives _BrFilePrimsWriteText = { |
||
115 | "Write Text", |
||
116 | &DfSkipText, |
||
117 | &DfChunkWriteText, |
||
118 | (int (*)(br_datafile*, br_uint_32*)) & BrNullOther, |
||
119 | &DfCountWriteText, |
||
120 | (br_uint_32(*)(br_datafile*)) & BrNullOther, |
||
121 | &DfCountSizeText, |
||
122 | &DfStructWriteText, |
||
123 | (br_uint_32(*)(br_datafile*, br_file_struct*, void*)) & BrNullOther, |
||
124 | &DfStructSizeText, |
||
125 | &DfBlockWriteText, |
||
126 | (void* (*)(br_datafile*, void*, int*, int, int)) & BrNullOther, |
||
127 | &DfBlockSizeText, |
||
128 | &DfNameWriteText, |
||
129 | (char* (*)(br_datafile*, char*)) & BrNullOther, |
||
130 | &DfNameSizeText, |
||
131 | }; |
||
132 | |||
133 | char* member_type_names[32] = { |
||
134 | "int_8", |
||
135 | "uint_8", |
||
136 | "int_16", |
||
137 | "uint_16", |
||
138 | "int_32", |
||
139 | "uint_32", |
||
140 | "fixed", |
||
141 | "angle", |
||
142 | "float", |
||
143 | "double", |
||
144 | "scalar", |
||
145 | "fraction", |
||
146 | "ufraction", |
||
147 | "enum_8", |
||
148 | "enum_16", |
||
149 | "enum_32", |
||
150 | "struct", |
||
151 | "asciz", |
||
152 | "colour", |
||
153 | "vector2", |
||
154 | "vector3", |
||
155 | "vector4", |
||
156 | "fixed_fraction", |
||
157 | "fixed_ufraction", |
||
158 | "float_fraction", |
||
159 | "float_ufraction", |
||
160 | "fixed_vector2", |
||
161 | "fixed_vector3", |
||
162 | "fixed_vector4", |
||
163 | "float_vector2", |
||
164 | "float_vector3", |
||
165 | "float_vector4", |
||
166 | }; |
||
167 | |||
168 | struct { |
||
169 | int type; |
||
170 | void* value; |
||
171 | int count; |
||
172 | } DatafileStack[1024]; |
||
173 | |||
174 | #ifdef BRENDER_FIX_BUGS |
||
175 | char* ChunkNames[62] = { |
||
176 | #else |
||
177 | char* ChunkNames[61] = { |
||
178 | #endif |
||
179 | "END", |
||
180 | "IMAGE_PLANE", |
||
181 | "RLE_IMAGE_PLANE", |
||
182 | #ifdef BRENDER_FIX_BUGS |
||
183 | "PIXELMAP_OLD", |
||
184 | #else |
||
185 | "PIXELMAP", |
||
186 | #endif |
||
187 | "MATERIAL_OLD", |
||
188 | "ADD_MATERIAL", |
||
189 | "OLD_ACTOR", |
||
190 | "OLD_ADD_SIBLING", |
||
191 | "OLD_ADD_CHILD", |
||
192 | "OLD_MATERIAL_INDEX", |
||
193 | "OLD_VERTICES", |
||
194 | "OLD_VERTICES_UV", |
||
195 | "OLD_FACES", |
||
196 | "OLD_MODEL", |
||
197 | "ADD_MODEL", |
||
198 | "ANIM", |
||
199 | "ANIM_TRANSFORM", |
||
200 | "ANIM_RATE", |
||
201 | "FILE_INFO", |
||
202 | "OLD_LIGHT", |
||
203 | "OLD_CAMERA", |
||
204 | "PIVOT", |
||
205 | "MATERIAL_INDEX", |
||
206 | "VERTICES", |
||
207 | "VERTEX_UV", |
||
208 | "OLD_FACES_1", |
||
209 | "FACE_MATERIAL", |
||
210 | "OLD_MODEL_1", |
||
211 | "COLOUR_MAP_REF", |
||
212 | "OPACITY_MAP_REF", |
||
213 | "INDEX_BLEND_REF", |
||
214 | "INDEX_SHADE_REF", |
||
215 | "SCREENDOOR_REF", |
||
216 | "PIXELS", |
||
217 | "ADD_MAP", |
||
218 | "ACTOR", |
||
219 | "ACTOR_MODEL", |
||
220 | "ACTOR_TRANSFORM", |
||
221 | "ACTOR_MATERIAL", |
||
222 | "ACTOR_LIGHT", |
||
223 | "ACTOR_CAMERA", |
||
224 | "ACTOR_BOUNDS", |
||
225 | "ACTOR_ADD_CHILD", |
||
226 | "TRANSFORM_MATRIX34", |
||
227 | "TRANSFORM_MATRIX34_LP", |
||
228 | "TRANSFORM_QUAT", |
||
229 | "TRANSFORM_EULER", |
||
230 | "TRANSFORM_LOOK_UP", |
||
231 | "TRANSFORM_TRANSLATION", |
||
232 | "TRANSFORM_IDENTITY", |
||
233 | "BOUNDS", |
||
234 | "LIGHT", |
||
235 | "CAMERA", |
||
236 | "FACES", |
||
237 | "MODEL", |
||
238 | "ACTOR_CLIP_PLANE", |
||
239 | "PLANE", |
||
240 | "SATURN_FACES", |
||
241 | "SATURN_MODEL", |
||
242 | "INDEX_FOG_REF", |
||
243 | #ifdef BRENDER_FIX_BUGS |
||
244 | "MATERIAL", |
||
245 | "PIXELMAP", |
||
246 | #else |
||
247 | "MATERIAL_OLD", |
||
248 | #endif |
||
249 | }; |
||
250 | |||
251 | int DatafileStackTop; |
||
252 | |||
253 | // IDA: void __usercall DfPush(int type@<EAX>, void *value@<EDX>, int count@<EBX>) |
||
254 | void DfPush(int type, void* value, int count) { |
||
255 | LOG_TRACE9("(%d, %p, %d)", type, value, count); |
||
256 | |||
257 | if (DatafileStackTop >= BR_ASIZE(DatafileStack)) { |
||
258 | BrFailure("DatafileStack Overflow"); |
||
259 | } |
||
260 | DatafileStack[DatafileStackTop].type = type; |
||
261 | DatafileStack[DatafileStackTop].count = count; |
||
262 | DatafileStack[DatafileStackTop].value = value; |
||
263 | DatafileStackTop++; |
||
264 | } |
||
265 | |||
266 | // IDA: void* __usercall DfPop@<EAX>(int type@<EAX>, int *countp@<EDX>) |
||
267 | void* DfPop(int type, int* countp) { |
||
268 | LOG_TRACE9("(%d, %p)", type, countp); |
||
269 | |||
270 | if (DatafileStackTop <= 0) { |
||
271 | BrFailure("DatafileStack Underflow"); |
||
272 | } |
||
273 | DatafileStackTop--; |
||
274 | if (type != DatafileStack[DatafileStackTop].type) { |
||
275 | BrFailure("DatafileStack type mismatch, wanted %d, got %d", type, DatafileStack[DatafileStackTop].type); |
||
276 | } |
||
277 | if (countp != NULL) { |
||
278 | *countp = DatafileStack[DatafileStackTop].count; |
||
279 | } |
||
280 | return DatafileStack[DatafileStackTop].value; |
||
281 | } |
||
282 | |||
283 | // IDA: void* __usercall DfTop@<EAX>(int type@<EAX>, int *countp@<EDX>) |
||
284 | void* DfTop(int type, int* countp) { |
||
285 | LOG_TRACE9("(%d, %p)", type, countp); |
||
286 | if (DatafileStackTop <= 0) |
||
287 | BrFailure("DatafileStack Underflow"); |
||
288 | if (type != DatafileStack[DatafileStackTop - 1].type) |
||
289 | BrFailure("DatafileStack type mismatch, wanted %d, got %d", type, DatafileStack[DatafileStackTop].type); |
||
290 | if (countp != NULL) |
||
291 | *countp = DatafileStack[DatafileStackTop - 1].count; |
||
292 | return DatafileStack[DatafileStackTop - 1].value; |
||
293 | } |
||
294 | |||
295 | // IDA: int __cdecl DfTopType() |
||
296 | int DfTopType(void) { |
||
297 | LOG_TRACE9("()"); |
||
298 | if (DatafileStackTop > 0) { |
||
299 | return DatafileStack[DatafileStackTop - 1].type; |
||
300 | } else { |
||
301 | return 0; |
||
302 | } |
||
303 | } |
||
304 | |||
305 | // IDA: int __usercall TextReadLine@<EAX>(br_datafile *df@<EAX>, char **ident@<EDX>, char **data@<EBX>) |
||
306 | int TextReadLine(br_datafile* df, char** ident, char** data) { |
||
307 | char* cp; |
||
308 | LOG_TRACE9("(%p, %p, %p)", df, ident, data); |
||
309 | |||
310 | while (1) { |
||
311 | //int a; // Pierre-Marie Baty -- unused variable |
||
312 | cp = BrScratchString(); |
||
313 | BrFileGetLine(cp, 256, df->h); |
||
314 | if (BrFileEof(df->h) != 0) { |
||
315 | return 0; |
||
316 | } |
||
317 | for (; (*cp == ' ') || (*cp == '\t'); cp++) { |
||
318 | } |
||
319 | if (*cp != '\0') { |
||
320 | break; |
||
321 | } |
||
322 | } |
||
323 | *ident = cp; |
||
324 | while ((*cp != ' ') && (*cp != '\t') && (*cp != '\0')) { |
||
325 | cp++; |
||
326 | } |
||
327 | *cp = '\0'; |
||
328 | cp++; |
||
329 | while ((*cp == ' ') || (*cp == '\t')) { |
||
330 | cp++; |
||
331 | } |
||
332 | *data = cp; |
||
333 | if (*cp == '\"') { |
||
334 | cp++; |
||
335 | while ((*cp != '\0') && (*cp != '\"')) { |
||
336 | cp++; |
||
337 | } |
||
338 | } else { |
||
339 | while ((*cp != ' ') && (*cp != '\t') && (*cp != '\0')) { |
||
340 | cp++; |
||
341 | } |
||
342 | } |
||
343 | *cp = '\0'; |
||
344 | return 1; |
||
345 | } |
||
346 | |||
347 | // IDA: br_uint_16 __usercall scalarTypeConvert@<AX>(br_datafile *df@<EAX>, br_uint_16 t@<EDX>) |
||
348 | br_uint_16 scalarTypeConvert(br_datafile* df, br_uint_16 t) { |
||
349 | LOG_TRACE9("(%p, %d)", df, t); |
||
350 | |||
351 | if (df->scalar_type == BRT_FIXED) { |
||
352 | switch (t) { |
||
353 | case DF_TYPE_BR_SCALAR: |
||
354 | return DF_TYPE_BR_FIXED; |
||
355 | case DF_TYPE_BR_FRACTION: |
||
356 | return DF_TYPE_BR_FRACTION_X; |
||
357 | case DF_TYPE_BR_UFRACTION: |
||
358 | return DF_TYPE_BR_UFRACTION_X; |
||
359 | case DF_TYPE_BR_VECTOR2: |
||
360 | return DF_TYPE_BR_VECTOR2_X; |
||
361 | case DF_TYPE_BR_VECTOR3: |
||
362 | return DF_TYPE_BR_VECTOR3_X; |
||
363 | case DF_TYPE_BR_VECTOR4: |
||
364 | return DF_TYPE_BR_VECTOR4_X; |
||
365 | } |
||
366 | } else if (df->scalar_type == BRT_FLOAT) { |
||
367 | switch (t) { |
||
368 | case DF_TYPE_BR_SCALAR: |
||
369 | return DF_TYPE_FLOAT; |
||
370 | case DF_TYPE_BR_UFRACTION: |
||
371 | return DF_TYPE_BR_FRACTION_F; |
||
372 | case DF_TYPE_BR_FRACTION: |
||
373 | return DF_TYPE_BR_UFRACTION_F; |
||
374 | case DF_TYPE_BR_VECTOR2: |
||
375 | return DF_TYPE_BR_VECTOR2_F; |
||
376 | case DF_TYPE_BR_VECTOR3: |
||
377 | return DF_TYPE_BR_VECTOR3_F; |
||
378 | case DF_TYPE_BR_VECTOR4: |
||
379 | return DF_TYPE_BR_VECTOR4_F; |
||
380 | } |
||
381 | } else if ((t == DF_TYPE_BR_SCALAR) || ((DF_TYPE_BR_VECTOR2 <= t) && (t <= DF_TYPE_BR_VECTOR4))) { |
||
382 | BrFailure("Incorrect scalar type"); |
||
383 | } |
||
384 | return t; |
||
385 | } |
||
386 | |||
387 | // IDA: br_uint_32 __usercall DfStructWriteBinary@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
388 | br_uint_32 DfStructWriteBinary(br_datafile* df, br_file_struct* str, void* base) { |
||
389 | unsigned int m; |
||
390 | int i; |
||
391 | int n; |
||
392 | unsigned char* mp; |
||
393 | br_file_struct_member* sm; |
||
394 | union { // size: 0x8 |
||
395 | unsigned char b[8]; // @0x0 |
||
396 | float f; // @0x0 |
||
397 | double d; // @0x0 |
||
398 | } conv; |
||
399 | LOG_TRACE("(%p, %p, %p)", df, str, base); |
||
400 | |||
401 | for (m = 0; m < str->nmembers; m++) { |
||
402 | sm = &str->members[m]; |
||
403 | mp = ((unsigned char*)base) + sm->offset; |
||
404 | |||
405 | switch (scalarTypeConvert(df, sm->type)) { |
||
406 | case DF_TYPE_BR_INT_8: |
||
407 | case DF_TYPE_BR_UINT_8: |
||
408 | case DF_TYPE_ENUM_8: |
||
409 | BrFilePutChar(((br_uint_8*)mp)[0], df->h); |
||
410 | break; |
||
411 | case DF_TYPE_BR_ANGLE: |
||
412 | case DF_TYPE_BR_INT_16: |
||
413 | case DF_TYPE_BR_UINT_16: |
||
414 | case DF_TYPE_ENUM_16: |
||
415 | BrFilePutChar(mp[BR_HTON_16(0)], df->h); |
||
416 | BrFilePutChar(mp[BR_HTON_16(1)], df->h); |
||
417 | break; |
||
418 | case DF_TYPE_BR_INT_32: |
||
419 | case DF_TYPE_BR_UINT_32: |
||
420 | case DF_TYPE_ENUM_32: |
||
421 | BrFilePutChar(mp[BR_HTON_32(0)], df->h); |
||
422 | BrFilePutChar(mp[BR_HTON_32(1)], df->h); |
||
423 | BrFilePutChar(mp[BR_HTON_32(2)], df->h); |
||
424 | BrFilePutChar(mp[BR_HTON_32(3)], df->h); |
||
425 | break; |
||
426 | case DF_TYPE_FLOAT: |
||
427 | case DF_TYPE_BR_FRACTION_F: |
||
428 | case DF_TYPE_BR_UFRACTION_F: |
||
429 | conv.f = *(float*)mp; |
||
430 | BrFilePutChar(conv.b[BR_HTON_32(0)], df->h); |
||
431 | BrFilePutChar(conv.b[BR_HTON_32(1)], df->h); |
||
432 | BrFilePutChar(conv.b[BR_HTON_32(2)], df->h); |
||
433 | BrFilePutChar(conv.b[BR_HTON_32(3)], df->h); |
||
434 | break; |
||
435 | case DF_TYPE_DOUBLE: |
||
436 | conv.d = *(double*)mp; |
||
437 | BrFilePutChar(conv.b[BR_HTON_D(0)], df->h); |
||
438 | BrFilePutChar(conv.b[BR_HTON_D(1)], df->h); |
||
439 | BrFilePutChar(conv.b[BR_HTON_D(2)], df->h); |
||
440 | BrFilePutChar(conv.b[BR_HTON_D(3)], df->h); |
||
441 | BrFilePutChar(conv.b[BR_HTON_D(4)], df->h); |
||
442 | BrFilePutChar(conv.b[BR_HTON_D(5)], df->h); |
||
443 | BrFilePutChar(conv.b[BR_HTON_D(6)], df->h); |
||
444 | BrFilePutChar(conv.b[BR_HTON_D(7)], df->h); |
||
445 | break; |
||
446 | case DF_TYPE_STRUCT: |
||
447 | DfStructWriteBinary(df, sm->extra, mp); |
||
448 | break; |
||
449 | case DF_TYPE_ASCIZ: |
||
450 | if (*(char**)mp != NULL) { |
||
451 | BrFileWrite(*(char**)mp, 1, BrStrLen(*(char**)mp), df->h); |
||
452 | } |
||
453 | BrFilePutChar('\0', df->h); |
||
454 | break; |
||
455 | case DF_TYPE_BR_COLOUR: |
||
456 | BrFilePutChar(mp[BR_HTON_32(1)], df->h); |
||
457 | BrFilePutChar(mp[BR_HTON_32(2)], df->h); |
||
458 | BrFilePutChar(mp[BR_HTON_32(3)], df->h); |
||
459 | break; |
||
460 | case DF_TYPE_BR_FIXED: |
||
461 | conv.f = BrFixedToFloat(*(br_fixed_ls*)mp); |
||
462 | BrFilePutChar(conv.b[BR_HTON_32(0)], df->h); |
||
463 | BrFilePutChar(conv.b[BR_HTON_32(1)], df->h); |
||
464 | BrFilePutChar(conv.b[BR_HTON_32(2)], df->h); |
||
465 | BrFilePutChar(conv.b[BR_HTON_32(3)], df->h); |
||
466 | break; |
||
467 | case DF_TYPE_BR_FRACTION_X: |
||
468 | conv.f = BrFixedFractionToFloat(*(br_fraction_x*)mp); |
||
469 | BrFilePutChar(conv.b[BR_HTON_32(0)], df->h); |
||
470 | BrFilePutChar(conv.b[BR_HTON_32(1)], df->h); |
||
471 | BrFilePutChar(conv.b[BR_HTON_32(2)], df->h); |
||
472 | BrFilePutChar(conv.b[BR_HTON_32(3)], df->h); |
||
473 | break; |
||
474 | case DF_TYPE_BR_UFRACTION_X: |
||
475 | conv.f = BrFixedUFractionToFloat(*(br_fraction_x*)mp); |
||
476 | BrFilePutChar(conv.b[BR_HTON_32(0)], df->h); |
||
477 | BrFilePutChar(conv.b[BR_HTON_32(1)], df->h); |
||
478 | BrFilePutChar(conv.b[BR_HTON_32(2)], df->h); |
||
479 | BrFilePutChar(conv.b[BR_HTON_32(3)], df->h); |
||
480 | break; |
||
481 | case DF_TYPE_BR_VECTOR2_X: |
||
482 | n = 2; |
||
483 | goto copy_fixed_vector; |
||
484 | case DF_TYPE_BR_VECTOR3_X: |
||
485 | n = 3; |
||
486 | goto copy_fixed_vector; |
||
487 | case DF_TYPE_BR_VECTOR4_X: |
||
488 | n = 4; |
||
489 | copy_fixed_vector: |
||
490 | for (i = 0; i < n; i++) { |
||
491 | conv.f = BrFixedToFloat(*(br_fixed_ls*)mp); |
||
492 | BrFilePutChar(conv.b[BR_HTON_32(0)], df->h); |
||
493 | BrFilePutChar(conv.b[BR_HTON_32(1)], df->h); |
||
494 | BrFilePutChar(conv.b[BR_HTON_32(2)], df->h); |
||
495 | BrFilePutChar(conv.b[BR_HTON_32(3)], df->h); |
||
496 | mp += sizeof(br_fixed_ls); |
||
497 | } |
||
498 | break; |
||
499 | case DF_TYPE_BR_VECTOR2_F: |
||
500 | n = 2; |
||
501 | goto copy_float_vector; |
||
502 | case DF_TYPE_BR_VECTOR3_F: |
||
503 | n = 3; |
||
504 | goto copy_float_vector; |
||
505 | case DF_TYPE_BR_VECTOR4_F: |
||
506 | n = 4; |
||
507 | copy_float_vector: |
||
508 | for (i = 0; i < n; i++) { |
||
509 | conv.f = *(float*)mp; |
||
510 | BrFilePutChar(conv.b[BR_HTON_32(0)], df->h); |
||
511 | BrFilePutChar(conv.b[BR_HTON_32(1)], df->h); |
||
512 | BrFilePutChar(conv.b[BR_HTON_32(2)], df->h); |
||
513 | BrFilePutChar(conv.b[BR_HTON_32(3)], df->h); |
||
514 | mp += sizeof(br_fixed_ls); |
||
515 | } |
||
516 | break; |
||
517 | } |
||
518 | } |
||
519 | return 1; |
||
520 | } |
||
521 | |||
522 | // IDA: br_uint_32 __usercall DfStructReadBinary@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
523 | br_uint_32 DfStructReadBinary(br_datafile* df, br_file_struct* str, void* base) { |
||
524 | char tmp_string[256]; |
||
525 | unsigned int m; |
||
526 | int i; |
||
527 | int c; |
||
528 | int n; |
||
529 | unsigned char* mp; |
||
530 | br_file_struct_member* sm; |
||
531 | union { |
||
532 | unsigned char b[8]; |
||
533 | float f; |
||
534 | double d; |
||
535 | } conv; |
||
536 | |||
537 | LOG_TRACE9("(%p, %p, %p)", df, str, base); |
||
538 | |||
539 | for (m = 0; m < str->nmembers; m++) { |
||
540 | sm = &str->members[m]; |
||
541 | |||
542 | c = scalarTypeConvert(df, sm->type); |
||
543 | mp = ((unsigned char*)base) + sm->offset; |
||
544 | |||
545 | switch (c) { |
||
546 | case DF_TYPE_BR_INT_8: |
||
547 | case DF_TYPE_BR_UINT_8: |
||
548 | case DF_TYPE_ENUM_8: |
||
549 | mp[0] = BrFileGetChar(df->h); |
||
550 | break; |
||
551 | case DF_TYPE_BR_INT_16: |
||
552 | case DF_TYPE_BR_UINT_16: |
||
553 | case DF_TYPE_BR_ANGLE: |
||
554 | case DF_TYPE_ENUM_16: |
||
555 | mp[BR_NTOH_16(0)] = BrFileGetChar(df->h); |
||
556 | mp[BR_NTOH_16(1)] = BrFileGetChar(df->h); |
||
557 | break; |
||
558 | case DF_TYPE_BR_INT_32: |
||
559 | case DF_TYPE_BR_UINT_32: |
||
560 | case DF_TYPE_FLOAT: |
||
561 | case DF_TYPE_ENUM_32: |
||
562 | case DF_TYPE_BR_FRACTION_F: |
||
563 | case DF_TYPE_BR_UFRACTION_F: |
||
564 | mp[BR_NTOH_32(0)] = BrFileGetChar(df->h); |
||
565 | mp[BR_NTOH_32(1)] = BrFileGetChar(df->h); |
||
566 | mp[BR_NTOH_32(2)] = BrFileGetChar(df->h); |
||
567 | mp[BR_NTOH_32(3)] = BrFileGetChar(df->h); |
||
568 | break; |
||
569 | case DF_TYPE_BR_FIXED: |
||
570 | conv.b[BR_NTOH_F(0)] = BrFileGetChar(df->h); |
||
571 | conv.b[BR_NTOH_F(1)] = BrFileGetChar(df->h); |
||
572 | conv.b[BR_NTOH_F(2)] = BrFileGetChar(df->h); |
||
573 | conv.b[BR_NTOH_F(3)] = BrFileGetChar(df->h); |
||
574 | *(br_fixed_ls*)mp = BrFloatToFixed(conv.f); |
||
575 | break; |
||
576 | case DF_TYPE_DOUBLE: |
||
577 | conv.b[BR_NTOH_D(0)] = BrFileGetChar(df->h); |
||
578 | conv.b[BR_NTOH_D(1)] = BrFileGetChar(df->h); |
||
579 | conv.b[BR_NTOH_D(2)] = BrFileGetChar(df->h); |
||
580 | conv.b[BR_NTOH_D(3)] = BrFileGetChar(df->h); |
||
581 | conv.b[BR_NTOH_D(4)] = BrFileGetChar(df->h); |
||
582 | conv.b[BR_NTOH_D(5)] = BrFileGetChar(df->h); |
||
583 | conv.b[BR_NTOH_D(6)] = BrFileGetChar(df->h); |
||
584 | conv.b[BR_NTOH_D(7)] = BrFileGetChar(df->h); |
||
585 | *(double*)mp = conv.d; |
||
586 | break; |
||
587 | case DF_TYPE_STRUCT: |
||
588 | DfStructReadBinary(df, sm->extra, mp); |
||
589 | break; |
||
590 | case DF_TYPE_ASCIZ: |
||
591 | for (n = 0; n < 255; n++) { |
||
592 | c = BrFileGetChar(df->h); |
||
593 | if (c == '\0' || c == -1) |
||
594 | break; |
||
595 | tmp_string[n] = c; |
||
596 | } |
||
597 | tmp_string[n] = 0; |
||
598 | *(char**)mp = (char*)BrResStrDup(df->res ? df->res : fw.res, tmp_string); |
||
599 | break; |
||
600 | case DF_TYPE_BR_COLOUR: |
||
601 | mp[BR_NTOH_32(1)] = BrFileGetChar(df->h); |
||
602 | mp[BR_NTOH_32(2)] = BrFileGetChar(df->h); |
||
603 | mp[BR_NTOH_32(3)] = BrFileGetChar(df->h); |
||
604 | break; |
||
605 | case DF_TYPE_BR_FRACTION_X: |
||
606 | conv.b[BR_NTOH_F(0)] = BrFileGetChar(df->h); |
||
607 | conv.b[BR_NTOH_F(1)] = BrFileGetChar(df->h); |
||
608 | conv.b[BR_NTOH_F(2)] = BrFileGetChar(df->h); |
||
609 | conv.b[BR_NTOH_F(3)] = BrFileGetChar(df->h); |
||
610 | *((br_fraction_x*)mp) = BrFloatToFixedFraction(conv.f); |
||
611 | break; |
||
612 | case DF_TYPE_BR_UFRACTION_X: |
||
613 | conv.b[BR_NTOH_F(0)] = BrFileGetChar(df->h); |
||
614 | conv.b[BR_NTOH_F(1)] = BrFileGetChar(df->h); |
||
615 | conv.b[BR_NTOH_F(2)] = BrFileGetChar(df->h); |
||
616 | conv.b[BR_NTOH_F(3)] = BrFileGetChar(df->h); |
||
617 | *(br_ufraction_x*)mp = BrFloatToFixedUFraction(conv.f); |
||
618 | break; |
||
619 | case DF_TYPE_BR_VECTOR2_X: |
||
620 | n = 2; |
||
621 | goto copy_fixed_vector; |
||
622 | case DF_TYPE_BR_VECTOR3_X: |
||
623 | n = 3; |
||
624 | goto copy_fixed_vector; |
||
625 | case DF_TYPE_BR_VECTOR4_X: |
||
626 | n = 4; |
||
627 | copy_fixed_vector: |
||
628 | for (i = 0; i < n; i++) { |
||
629 | conv.b[BR_NTOH_F(0)] = BrFileGetChar(df->h); |
||
630 | conv.b[BR_NTOH_F(1)] = BrFileGetChar(df->h); |
||
631 | conv.b[BR_NTOH_F(2)] = BrFileGetChar(df->h); |
||
632 | conv.b[BR_NTOH_F(3)] = BrFileGetChar(df->h); |
||
633 | *(br_fixed_ls*)mp = BrFloatToFixed(conv.f); |
||
634 | mp += sizeof(br_fixed_ls); |
||
635 | } |
||
636 | break; |
||
637 | case DF_TYPE_BR_VECTOR2_F: |
||
638 | n = 2; |
||
639 | goto copy_float_vector; |
||
640 | break; |
||
641 | case DF_TYPE_BR_VECTOR3_F: |
||
642 | n = 3; |
||
643 | goto copy_float_vector; |
||
644 | break; |
||
645 | case DF_TYPE_BR_VECTOR4_F: |
||
646 | n = 4; |
||
647 | copy_float_vector: |
||
648 | for (i = 0; i < n; i++) { |
||
649 | conv.b[BR_NTOH_F(0)] = BrFileGetChar(df->h); |
||
650 | conv.b[BR_NTOH_F(1)] = BrFileGetChar(df->h); |
||
651 | conv.b[BR_NTOH_F(2)] = BrFileGetChar(df->h); |
||
652 | conv.b[BR_NTOH_F(3)] = BrFileGetChar(df->h); |
||
653 | *(float*)mp = conv.f; |
||
654 | mp += sizeof(float); |
||
655 | } |
||
656 | break; |
||
657 | } |
||
658 | } |
||
659 | |||
660 | return 1; |
||
661 | } |
||
662 | |||
663 | // IDA: int __usercall DfStructSizeBinary@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
664 | int DfStructSizeBinary(br_datafile* df, br_file_struct* str, void* base) { |
||
665 | unsigned char* mp; |
||
666 | unsigned int m; |
||
667 | br_file_struct_member* sm; |
||
668 | int bytes; |
||
669 | LOG_TRACE("(%p, %p, %p)", df, str, base); |
||
670 | |||
671 | bytes = 0; |
||
672 | for (m = 0; m < str->nmembers; m++) { |
||
673 | sm = &str->members[m]; |
||
674 | |||
675 | mp = ((unsigned char*)base) + sm->offset; |
||
676 | |||
677 | switch (scalarTypeConvert(df, sm->type)) { |
||
678 | case DF_TYPE_BR_INT_8: |
||
679 | case DF_TYPE_BR_UINT_8: |
||
680 | case DF_TYPE_ENUM_8: |
||
681 | bytes += 1; |
||
682 | break; |
||
683 | case DF_TYPE_BR_INT_16: |
||
684 | case DF_TYPE_BR_UINT_16: |
||
685 | case DF_TYPE_BR_ANGLE: |
||
686 | case DF_TYPE_ENUM_16: |
||
687 | bytes += 2; |
||
688 | break; |
||
689 | case DF_TYPE_BR_COLOUR: |
||
690 | bytes += 4; |
||
691 | break; |
||
692 | case DF_TYPE_BR_INT_32: |
||
693 | case DF_TYPE_BR_UINT_32: |
||
694 | case DF_TYPE_FLOAT: |
||
695 | case DF_TYPE_ENUM_32: |
||
696 | case DF_TYPE_BR_FRACTION_F: |
||
697 | case DF_TYPE_BR_UFRACTION_F: |
||
698 | case DF_TYPE_BR_FIXED: |
||
699 | case DF_TYPE_BR_FRACTION_X: |
||
700 | case DF_TYPE_BR_UFRACTION_X: |
||
701 | bytes += 4; |
||
702 | break; |
||
703 | case DF_TYPE_DOUBLE: |
||
704 | bytes += 8; |
||
705 | break; |
||
706 | case DF_TYPE_STRUCT: |
||
707 | bytes += DfStructSizeBinary(df, sm->extra, mp); |
||
708 | break; |
||
709 | case DF_TYPE_ASCIZ: |
||
710 | if (*(char**)mp != NULL) { |
||
711 | bytes += BrStrLen(*(char**)mp); |
||
712 | } |
||
713 | break; |
||
714 | case DF_TYPE_BR_VECTOR2_X: |
||
715 | case DF_TYPE_BR_VECTOR2_F: |
||
716 | bytes += 8; |
||
717 | break; |
||
718 | case DF_TYPE_BR_VECTOR3_X: |
||
719 | case DF_TYPE_BR_VECTOR3_F: |
||
720 | bytes += 12; |
||
721 | break; |
||
722 | case DF_TYPE_BR_VECTOR4_X: |
||
723 | case DF_TYPE_BR_VECTOR4_F: |
||
724 | bytes += 16; |
||
725 | break; |
||
726 | } |
||
727 | } |
||
728 | |||
729 | return bytes; |
||
730 | } |
||
731 | |||
732 | // IDA: int __usercall EnumFromString@<EAX>(br_file_enum *e@<EAX>, char *str@<EDX>) |
||
733 | int EnumFromString(br_file_enum* e, char* str) { |
||
734 | unsigned int m; |
||
735 | LOG_TRACE9("(%p, \"%s\")", e, str); |
||
736 | |||
737 | if (e == NULL) { |
||
738 | BrFailure("Unknown enum string: %s", str); |
||
739 | } |
||
740 | for (m = 0; m < e->nmembers; m++) { |
||
741 | if (BrStrCmp(str, e->members[m].name) == 0) { |
||
742 | return e->members[m].value; |
||
743 | } |
||
744 | } |
||
745 | BrFailure("Unknown enum string: %s", str); |
||
746 | return 0; // Pierre-Marie Baty -- make compiler happy |
||
747 | } |
||
748 | |||
749 | // IDA: char* __usercall EnumToString@<EAX>(br_file_enum *e@<EAX>, int num@<EDX>) |
||
750 | char* EnumToString(br_file_enum* e, int num) { |
||
751 | unsigned int m; |
||
752 | LOG_TRACE9("(%p, %d)", e, num); |
||
753 | |||
754 | if (e == NULL) { |
||
755 | goto fail; |
||
756 | } |
||
757 | for (m = 0; m < e->nmembers; m++) { |
||
758 | if (e->members[m].value == num) { |
||
759 | return e->members[m].name; |
||
760 | } |
||
761 | } |
||
762 | fail: |
||
763 | BrFailure("Unknown enum %d", num); |
||
764 | return NULL; // Pierre-Marie Baty -- make compiler happy |
||
765 | } |
||
766 | |||
767 | // IDA: br_uint_32 __usercall DfStructWriteText@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
768 | br_uint_32 DfStructWriteText(br_datafile* df, br_file_struct* str, void* base) { |
||
769 | LOG_TRACE("(%p, %p, %p)", df, str, base); |
||
770 | |||
771 | BrFilePrintf(df->h, " struct %s\n", str->name); |
||
772 | StructWriteTextSub(df, str, base, 4); |
||
773 | return 1; |
||
774 | } |
||
775 | |||
776 | // IDA: br_uint_32 __usercall StructWriteTextSub@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>, int indent@<ECX>) |
||
777 | br_uint_32 StructWriteTextSub(br_datafile* df, br_file_struct* str, void* base, int indent) { |
||
778 | unsigned int m; |
||
779 | int i; |
||
780 | int w; |
||
781 | int add_comment; |
||
782 | void* mp; |
||
783 | br_file_struct_member* sm; |
||
784 | LOG_TRACE("(%p, %p, %p, %d)", df, str, base, indent); |
||
785 | |||
786 | for (m = 0; m < str->nmembers; m++) { |
||
787 | sm = &str->members[m]; |
||
788 | mp = ((unsigned char*)base) + sm->offset; |
||
789 | w = 0; |
||
790 | add_comment = 1; |
||
791 | |||
792 | for (i = 0; i < indent; i++) { |
||
793 | BrFilePutChar(' ', df->h); |
||
794 | } |
||
795 | |||
796 | // Modified from "%-10s", to ensure space after long type names |
||
797 | BrFilePrintf(df->h, "%-9s ", member_type_names[sm->type]); |
||
798 | |||
799 | switch (scalarTypeConvert(df, sm->type)) { |
||
800 | case DF_TYPE_BR_INT_8: |
||
801 | w = BrFilePrintf(df->h, "%d", *(br_int_8*)mp); |
||
802 | break; |
||
803 | case DF_TYPE_BR_UINT_8: |
||
804 | w = BrFilePrintf(df->h, "%u", *(br_uint_8*)mp); |
||
805 | break; |
||
806 | case DF_TYPE_BR_INT_16: |
||
807 | w = BrFilePrintf(df->h, "%d", *(br_int_16*)mp); |
||
808 | break; |
||
809 | case DF_TYPE_BR_UINT_16: |
||
810 | w = BrFilePrintf(df->h, "%u", *(br_uint_16*)mp); |
||
811 | break; |
||
812 | case DF_TYPE_BR_INT_32: |
||
813 | w = BrFilePrintf(df->h, "%d", *(br_int_32*)mp); |
||
814 | break; |
||
815 | case DF_TYPE_BR_UINT_32: |
||
816 | w = BrFilePrintf(df->h, "%u", *(br_uint_32*)mp); |
||
817 | break; |
||
818 | case DF_TYPE_BR_FIXED: |
||
819 | w = BrFilePrintf(df->h, "%g", BrFixedToFloat(*(br_fixed_ls*)mp)); |
||
820 | break; |
||
821 | case DF_TYPE_BR_ANGLE: |
||
822 | w = BrFilePrintf(df->h, "%g", BrFixedToFloat(BrFixedMul(*(br_angle*)mp, BrIntToFixed(360)))); |
||
823 | break; |
||
824 | case DF_TYPE_FLOAT: |
||
825 | case DF_TYPE_BR_FRACTION_F: |
||
826 | case DF_TYPE_BR_UFRACTION_F: |
||
827 | w = BrFilePrintf(df->h, "%g", (double)*(float*)mp); |
||
828 | break; |
||
829 | case DF_TYPE_DOUBLE: |
||
830 | w = BrFilePrintf(df->h, "%g", *(double*)mp); |
||
831 | break; |
||
832 | case DF_TYPE_ENUM_8: |
||
833 | w = BrFilePrintf(df->h, "%s", EnumToString(sm->extra, *(br_uint_8*)mp)); |
||
834 | break; |
||
835 | case DF_TYPE_ENUM_16: |
||
836 | w = BrFilePrintf(df->h, "%s", EnumToString(sm->extra, *(br_uint_16*)mp)); |
||
837 | break; |
||
838 | case DF_TYPE_ENUM_32: |
||
839 | w = BrFilePrintf(df->h, "%s", EnumToString(sm->extra, *(br_uint_32*)mp)); |
||
840 | break; |
||
841 | case DF_TYPE_STRUCT: |
||
842 | add_comment = 0; |
||
843 | w = BrFilePrintf(df->h, "%s", ((br_file_struct*)sm->extra)->name); |
||
844 | if (sm->name != NULL) { |
||
845 | if (w < 40) { |
||
846 | for (i = 40 - w; i != 0; i--) { |
||
847 | BrFilePutChar(' ', df->h); |
||
848 | } |
||
849 | } |
||
850 | BrFilePrintf(df->h, " # %s", sm->name); |
||
851 | } |
||
852 | BrFilePutChar('\n', df->h); |
||
853 | StructWriteTextSub(df, sm->extra, mp, indent + 2); |
||
854 | break; |
||
855 | case DF_TYPE_ASCIZ: |
||
856 | if (*(char**)mp == NULL) { |
||
857 | w = BrFilePrintf(df->h, "NULL"); |
||
858 | } else { |
||
859 | w = BrFilePrintf(df->h, "\"%s\"", *(char**)mp); |
||
860 | } |
||
861 | break; |
||
862 | case DF_TYPE_BR_COLOUR: |
||
863 | w = BrFilePrintf(df->h, "%d,%d,%d", (br_uint_8)((*(br_uint_32*)mp) >> 16), (br_uint_8)((*(br_uint_32*)mp) >> 8), (br_uint_8)((*(br_uint_32*)mp))); |
||
864 | break; |
||
865 | case DF_TYPE_BR_FRACTION_X: |
||
866 | w = BrFilePrintf(df->h, "%g", (double)BrFixedFractionToFloat(*(br_fraction_x*)mp)); |
||
867 | break; |
||
868 | case DF_TYPE_BR_UFRACTION_X: |
||
869 | w = BrFilePrintf(df->h, "%g", (double)BrFixedUFractionToFloat(*(br_fraction_x*)mp)); |
||
870 | break; |
||
871 | case DF_TYPE_BR_VECTOR2_X: |
||
872 | w = BrFilePrintf(df->h, "%g,%g", BrFixedToFloat(((br_fixed_ls*)mp)[0]), BrFixedToFloat(((br_fixed_ls*)mp)[1])); |
||
873 | break; |
||
874 | case DF_TYPE_BR_VECTOR3_X: |
||
875 | w = BrFilePrintf(df->h, "%g,%g,%g", BrFixedToFloat(((br_fixed_ls*)mp)[0]), BrFixedToFloat(((br_fixed_ls*)mp)[1]), BrFixedToFloat(((br_fixed_ls*)mp)[2])); |
||
876 | break; |
||
877 | case DF_TYPE_BR_VECTOR4_X: |
||
878 | w = BrFilePrintf(df->h, "%g,%g,%g,%g", BrFixedToFloat(((br_fixed_ls*)mp)[0]), BrFixedToFloat(((br_fixed_ls*)mp)[1]), BrFixedToFloat(((br_fixed_ls*)mp)[2]), BrFixedToFloat(((br_fixed_ls*)mp)[3])); |
||
879 | break; |
||
880 | case DF_TYPE_BR_VECTOR2_F: |
||
881 | w = BrFilePrintf(df->h, "%g,%g", ((float*)mp)[0], ((float*)mp)[1]); |
||
882 | break; |
||
883 | case DF_TYPE_BR_VECTOR3_F: |
||
884 | w = BrFilePrintf(df->h, "%g,%g,%g", ((float*)mp)[0], ((float*)mp)[1], ((float*)mp)[2]); |
||
885 | break; |
||
886 | case DF_TYPE_BR_VECTOR4_F: |
||
887 | w = BrFilePrintf(df->h, "%g,%g,%g,%g", ((float*)mp)[0], ((float*)mp)[1], ((float*)mp)[2], ((float*)mp)[3]); |
||
888 | break; |
||
889 | } |
||
890 | if ((add_comment != 0) && (sm->name != NULL)) { |
||
891 | if (w < 40) { |
||
892 | for (i = 40 - w; i != 0; i--) { |
||
893 | BrFilePutChar(' ', df->h); |
||
894 | } |
||
895 | } |
||
896 | BrFilePrintf(df->h, " # %s\n", sm->name); |
||
897 | } |
||
898 | } |
||
899 | |||
900 | return 1; |
||
901 | } |
||
902 | |||
903 | // IDA: br_uint_32 __usercall DfStructReadText@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
904 | br_uint_32 DfStructReadText(br_datafile* df, br_file_struct* str, void* base) { |
||
905 | char* id; |
||
906 | char* data; |
||
907 | LOG_TRACE9("(%p, %p, %p)", df, str, base); |
||
908 | |||
909 | TextReadLine(df, &id, &data); |
||
910 | if (BrStrCmp(id, "struct") != 0) { |
||
911 | BrFailure("Unknown text identifer \"%s\"", id); |
||
912 | } |
||
913 | if (BrStrCmp(data, str->name) != 0) { |
||
914 | BrFailure("Incorrect structure name \"%s\"", data); |
||
915 | } |
||
916 | StructReadTextSub(df, str, base); |
||
917 | return 1; |
||
918 | } |
||
919 | |||
920 | // IDA: br_uint_32 __usercall StructReadTextSub@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
921 | br_uint_32 StructReadTextSub(br_datafile* df, br_file_struct* str, void* base) { |
||
922 | unsigned int m; |
||
923 | unsigned int r; |
||
924 | unsigned int g; |
||
925 | unsigned int b; |
||
926 | int i; |
||
927 | int n; |
||
928 | void* mp; |
||
929 | br_file_struct_member* sm; |
||
930 | char* id; |
||
931 | char* data; |
||
932 | char* ep; |
||
933 | LOG_TRACE9("(%p, %p, %p)", df, str, base); |
||
934 | |||
935 | for (m = 0; m < str->nmembers; m++) { |
||
936 | sm = &str->members[m]; |
||
937 | mp = ((unsigned char*)base) + sm->offset; |
||
938 | |||
939 | if (TextReadLine(df, &id, &data) == 0) { |
||
940 | BrFailure("Unexpected EOF in strructure"); |
||
941 | } |
||
942 | if (BrStrCmp(id, member_type_names[sm->type]) != 0) { |
||
943 | BrFailure("Unknown member identifer \"%s\"", id); |
||
944 | } |
||
945 | |||
946 | switch (scalarTypeConvert(df, sm->type)) { |
||
947 | case DF_TYPE_BR_INT_8: |
||
948 | *(br_int_8*)mp = (br_int_8)BrStrToL(data, NULL, 0); |
||
949 | break; |
||
950 | case DF_TYPE_BR_UINT_8: |
||
951 | *(br_uint_8*)mp = (br_uint_8)BrStrToL(data, NULL, 0); |
||
952 | break; |
||
953 | case DF_TYPE_BR_INT_16: |
||
954 | *(br_int_16*)mp = (br_int_16)BrStrToL(data, NULL, 0); |
||
955 | break; |
||
956 | case DF_TYPE_BR_UINT_16: |
||
957 | *(br_uint_16*)mp = (br_uint_16)BrStrToL(data, NULL, 0); |
||
958 | break; |
||
959 | case DF_TYPE_BR_INT_32: |
||
960 | *(br_int_32*)mp = (br_int_32)BrStrToL(data, NULL, 0); |
||
961 | break; |
||
962 | case DF_TYPE_BR_UINT_32: |
||
963 | *(br_uint_32*)mp = (br_uint_32)BrStrToUL(data, NULL, 0); |
||
964 | break; |
||
965 | case DF_TYPE_BR_FIXED: |
||
966 | *(br_fixed_ls*)mp = BrFloatToFixed(BrStrToD(data, NULL)); |
||
967 | break; |
||
968 | case DF_TYPE_BR_ANGLE: |
||
969 | *(br_angle*)mp = BrFixedMulDiv(BrFloatToFixed(BrStrToF(data, NULL)), BrIntToFixed(1), BrIntToFixed(360)); |
||
970 | break; |
||
971 | case DF_TYPE_FLOAT: |
||
972 | case DF_TYPE_BR_FRACTION_F: |
||
973 | case DF_TYPE_BR_UFRACTION_F: |
||
974 | *(float*)mp = BrStrToF(data, NULL); |
||
975 | break; |
||
976 | case DF_TYPE_DOUBLE: |
||
977 | *(double*)mp = BrStrToD(data, NULL); |
||
978 | break; |
||
979 | case DF_TYPE_ENUM_8: |
||
980 | *(br_uint_8*)mp = EnumFromString(sm->extra, data); |
||
981 | break; |
||
982 | case DF_TYPE_ENUM_16: |
||
983 | *(br_uint_16*)mp = EnumFromString(sm->extra, data); |
||
984 | break; |
||
985 | case DF_TYPE_ENUM_32: |
||
986 | *(br_uint_32*)mp = EnumFromString(sm->extra, data); |
||
987 | break; |
||
988 | case DF_TYPE_STRUCT: |
||
989 | if (BrStrCmp(data, ((br_file_struct*)sm->extra)->name) != 0) { |
||
990 | BrFailure("Incorrect structure name \"%s\"", data); |
||
991 | } |
||
992 | StructReadTextSub(df, sm->extra, mp); |
||
993 | break; |
||
994 | case DF_TYPE_ASCIZ: |
||
995 | if (BrStrCmp(data, "NULL") == 0) { |
||
996 | *(char**)mp = NULL; |
||
997 | } else { |
||
998 | *(char**)mp = BrResStrDup(df->res == NULL ? fw.res : df->res, data + 1); |
||
999 | } |
||
1000 | break; |
||
1001 | case DF_TYPE_BR_COLOUR: |
||
1002 | r = BrStrToUL(data, &ep, 0); |
||
1003 | if (*ep != ',') { |
||
1004 | BrFailure("Incorrect colour"); |
||
1005 | } |
||
1006 | g = BrStrToUL(ep + 1, &ep, 0); |
||
1007 | if (*ep != ',') { |
||
1008 | BrFailure("Incorrect colour"); |
||
1009 | } |
||
1010 | b = BrStrToUL(ep + 1, &ep, 0); |
||
1011 | *(br_colour*)mp = BR_COLOUR_RGB(r, g, b); |
||
1012 | break; |
||
1013 | case DF_TYPE_BR_FRACTION_X: |
||
1014 | *(br_fixed_ss*)mp = BrFloatToFixedFraction(BrStrToD(data, NULL)); |
||
1015 | break; |
||
1016 | case DF_TYPE_BR_UFRACTION_X: |
||
1017 | *(br_fixed_su*)mp = BrFloatToFixedUFraction(BrStrToD(data, NULL)); |
||
1018 | break; |
||
1019 | case DF_TYPE_BR_VECTOR2_X: |
||
1020 | n = 2; |
||
1021 | goto copy_fixed_vector; |
||
1022 | case DF_TYPE_BR_VECTOR3_X: |
||
1023 | n = 3; |
||
1024 | goto copy_fixed_vector; |
||
1025 | case DF_TYPE_BR_VECTOR4_X: |
||
1026 | n = 4; |
||
1027 | copy_fixed_vector: |
||
1028 | for (i = 0; i < n; i++) { |
||
1029 | while (1) { |
||
1030 | if ((*data != ',') && (*data != ' ') && (*data != '\t')) { |
||
1031 | break; |
||
1032 | } |
||
1033 | data++; |
||
1034 | } |
||
1035 | if (*data == '\0') { |
||
1036 | BrFailure("Incorrect vector"); |
||
1037 | } |
||
1038 | *(br_fixed_ls*)mp = BrFloatToFixed(BrStrToF(data, NULL)); |
||
1039 | while ((*data != ' ' && *data != ',' && *data != ' ' && *data != '\t')) { |
||
1040 | data++; |
||
1041 | } |
||
1042 | mp = (char*)mp + sizeof(br_fixed_ls); |
||
1043 | } |
||
1044 | break; |
||
1045 | case DF_TYPE_BR_VECTOR2_F: |
||
1046 | n = 2; |
||
1047 | goto copy_float_vector; |
||
1048 | case DF_TYPE_BR_VECTOR3_F: |
||
1049 | n = 3; |
||
1050 | goto copy_float_vector; |
||
1051 | case DF_TYPE_BR_VECTOR4_F: |
||
1052 | n = 4; |
||
1053 | copy_float_vector: |
||
1054 | for (i = 0; i < n; i++) { |
||
1055 | while (1) { |
||
1056 | if ((*data != ',') && (*data != ' ') && (*data != '\t')) { |
||
1057 | break; |
||
1058 | } |
||
1059 | data++; |
||
1060 | } |
||
1061 | if (*data == '\0') { |
||
1062 | BrFailure("Incorrect vector"); |
||
1063 | } |
||
1064 | *(float*)mp = BrStrToF(data, NULL); |
||
1065 | while ((*data != ' ' && *data != ',' && *data != ' ' && *data != '\t')) { |
||
1066 | data++; |
||
1067 | } |
||
1068 | mp = (char*)mp + sizeof(float); |
||
1069 | } |
||
1070 | break; |
||
1071 | } |
||
1072 | } |
||
1073 | |||
1074 | return 1; |
||
1075 | } |
||
1076 | |||
1077 | // IDA: int __usercall DfStructSizeText@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>) |
||
1078 | int DfStructSizeText(br_datafile* df, br_file_struct* str, void* base) { |
||
1079 | unsigned int m; |
||
1080 | br_file_struct_member* sm; |
||
1081 | int lines; |
||
1082 | LOG_TRACE("(%p, %p, %p)", df, str, base); |
||
1083 | |||
1084 | lines = 1; |
||
1085 | for (m = 0; m < str->nmembers; m++) { |
||
1086 | sm = &str->members[m]; |
||
1087 | if (sm->type == DF_TYPE_STRUCT) { |
||
1088 | lines += DfStructSizeText(df, sm->extra, (br_uint_8*)base + sm->offset); |
||
1089 | } else { |
||
1090 | lines++; |
||
1091 | } |
||
1092 | } |
||
1093 | return lines; |
||
1094 | } |
||
1095 | |||
1096 | // IDA: br_uint_32 __usercall DfStructWriteArray@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>, int n@<ECX>) |
||
1097 | br_uint_32 DfStructWriteArray(br_datafile* df, br_file_struct* str, void* base, int n) { |
||
1098 | char* cp; |
||
1099 | int i; |
||
1100 | LOG_TRACE("(%p, %p, %p, %d)", df, str, base, n); |
||
1101 | |||
1102 | cp = (char*)base; |
||
1103 | for (i = 0; i < n; i++) { |
||
1104 | df->prims->struct_write(df, str, cp); |
||
1105 | cp += str->mem_size; |
||
1106 | } |
||
1107 | return i; |
||
1108 | } |
||
1109 | |||
1110 | // IDA: br_uint_32 __usercall DfStructReadArray@<EAX>(br_datafile *df@<EAX>, br_file_struct *str@<EDX>, void *base@<EBX>, int n@<ECX>) |
||
1111 | br_uint_32 DfStructReadArray(br_datafile* df, br_file_struct* str, void* base, int n) { |
||
1112 | char* cp; |
||
1113 | int i; |
||
1114 | LOG_TRACE9("(%p, %p, %p, %d)", df, str, base, n); |
||
1115 | |||
1116 | cp = (char*)base; |
||
1117 | for (i = 0; i < n; i++) { |
||
1118 | if (BrFileEof(df->h) != 0) { |
||
1119 | break; |
||
1120 | } |
||
1121 | df->prims->struct_read(df, str, cp); |
||
1122 | cp += str->mem_size; |
||
1123 | } |
||
1124 | return i; |
||
1125 | } |
||
1126 | |||
1127 | // IDA: int __usercall DfChunkWriteText@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>) |
||
1128 | int DfChunkWriteText(br_datafile* df, br_uint_32 id, br_uint_32 length) { |
||
1129 | int i; |
||
1130 | LOG_TRACE("(%p, %d, %d)", df, id, length); |
||
1131 | |||
1132 | if (id < BR_ASIZE(ChunkNames)) { |
||
1133 | i = BrFilePrintf(df->h, "*%-16s %d\n", ChunkNames[id], length); |
||
1134 | } else { |
||
1135 | i = BrFilePrintf(df->h, "*0x%08x %d\n", id, length); |
||
1136 | } |
||
1137 | return i; // Pierre-Marie Baty -- must return a value |
||
1138 | } |
||
1139 | |||
1140 | // IDA: int __usercall DfChunkReadText@<EAX>(br_datafile *df@<EAX>, br_uint_32 *plength@<EDX>) |
||
1141 | int DfChunkReadText(br_datafile* df, br_uint_32* plength) { |
||
1142 | int i; |
||
1143 | char* id; |
||
1144 | char* data; |
||
1145 | LOG_TRACE9("(%p, %p)", df, plength); |
||
1146 | |||
1147 | if (TextReadLine(df, &id, &data) == 0) { |
||
1148 | return -1; |
||
1149 | } |
||
1150 | if (*id != '*') { |
||
1151 | BrFailure("Chunk ID not found"); |
||
1152 | } |
||
1153 | id++; |
||
1154 | if (*id == '0') { |
||
1155 | i = BrStrToUL(id, NULL, 0); |
||
1156 | } else { |
||
1157 | for (i = 0; i < BR_ASIZE(ChunkNames); i++) { |
||
1158 | if (BrStrCmp(ChunkNames[i], id) == 0) { |
||
1159 | break; |
||
1160 | } |
||
1161 | } |
||
1162 | if (i >= BR_ASIZE(ChunkNames)) { |
||
1163 | BrFailure("Chunk ID not known: %s", id); |
||
1164 | } |
||
1165 | } |
||
1166 | if (plength != NULL) { |
||
1167 | *plength = BrStrToUL(data, NULL, 0); |
||
1168 | } |
||
1169 | return i; |
||
1170 | } |
||
1171 | |||
1172 | // IDA: int __usercall DfChunkWriteBinary@<EAX>(br_datafile *df@<EAX>, br_uint_32 id@<EDX>, br_uint_32 length@<EBX>) |
||
1173 | int DfChunkWriteBinary(br_datafile* df, br_uint_32 id, br_uint_32 length) { |
||
1174 | br_uint_32 l; |
||
1175 | LOG_TRACE("(%p, %d, %d)", df, id, length); |
||
1176 | |||
1177 | l = BrHtoNL(id); |
||
1178 | BrFileWrite(&l, sizeof(br_uint_32), 1, df->h); |
||
1179 | l = BrHtoNL(length); |
||
1180 | BrFileWrite(&l, sizeof(br_uint_32), 1, df->h); |
||
1181 | return 0; |
||
1182 | } |
||
1183 | |||
1184 | // IDA: int __usercall DfChunkReadBinary@<EAX>(br_datafile *df@<EAX>, br_uint_32 *plength@<EDX>) |
||
1185 | int DfChunkReadBinary(br_datafile* df, br_uint_32* plength) { |
||
1186 | br_uint_32 id; |
||
1187 | br_uint_32 l; |
||
1188 | LOG_TRACE9("(%p, %p)", df, plength); |
||
1189 | |||
1190 | if (BrFileEof(df->h) != 0) { |
||
1191 | return -1; |
||
1192 | } |
||
1193 | BrFileRead(&id, sizeof(br_uint_32), 1, df->h); |
||
1194 | if (BrFileEof(df->h) != 0) { |
||
1195 | return -1; |
||
1196 | } |
||
1197 | id = BrHtoNL(id); |
||
1198 | BrFileRead(&l, sizeof(br_uint_32), 1, df->h); |
||
1199 | if (BrFileEof(df->h) != 0) { |
||
1200 | return -1; |
||
1201 | } |
||
1202 | if (plength != NULL) { |
||
1203 | *plength = BrHtoNL(l); |
||
1204 | } |
||
1205 | return id; |
||
1206 | } |
||
1207 | |||
1208 | // IDA: void __usercall DfCountWriteText(br_datafile *df@<EAX>, br_uint_32 count@<EDX>) |
||
1209 | void DfCountWriteText(br_datafile* df, br_uint_32 count) { |
||
1210 | LOG_TRACE("(%p, %d)", df, count); |
||
1211 | |||
1212 | BrFilePrintf(df->h, " count %d\n", count); |
||
1213 | } |
||
1214 | |||
1215 | // IDA: br_uint_32 __usercall DfCountReadText@<EAX>(br_datafile *df@<EAX>) |
||
1216 | br_uint_32 DfCountReadText(br_datafile* df) { |
||
1217 | char* id; |
||
1218 | char* data; |
||
1219 | LOG_TRACE("(%p)", df); |
||
1220 | |||
1221 | TextReadLine(df, &id, &data); |
||
1222 | if (BrStrCmp(id, "count") != 0) { |
||
1223 | BrFailure("no element count for chunk"); |
||
1224 | } |
||
1225 | return BrStrToUL(data, NULL, 0); |
||
1226 | } |
||
1227 | |||
1228 | // IDA: void __usercall DfCountWriteBinary(br_datafile *df@<EAX>, br_uint_32 count@<EDX>) |
||
1229 | void DfCountWriteBinary(br_datafile* df, br_uint_32 count) { |
||
1230 | br_uint_32 l; |
||
1231 | |||
1232 | l = BrHtoNL(count); |
||
1233 | BrFileWrite(&l, sizeof(l), 1, df->h); |
||
1234 | } |
||
1235 | |||
1236 | // IDA: br_uint_32 __usercall DfCountReadBinary@<EAX>(br_datafile *df@<EAX>) |
||
1237 | br_uint_32 DfCountReadBinary(br_datafile* df) { |
||
1238 | br_uint_32 l; |
||
1239 | LOG_TRACE9("(%p)", df); |
||
1240 | |||
1241 | BrFileRead(&l, sizeof(br_uint_32), 1, df->h); |
||
1242 | return BrHtoNL(l); |
||
1243 | } |
||
1244 | |||
1245 | // IDA: int __usercall DfCountSizeText@<EAX>(br_datafile *df@<EAX>) |
||
1246 | int DfCountSizeText(br_datafile* df) { |
||
1247 | LOG_TRACE("(%p)", df); |
||
1248 | |||
1249 | return 1; |
||
1250 | } |
||
1251 | |||
1252 | // IDA: int __usercall DfCountSizeBinary@<EAX>(br_datafile *df@<EAX>) |
||
1253 | int DfCountSizeBinary(br_datafile* df) { |
||
1254 | LOG_TRACE("(%p)", df); |
||
1255 | |||
1256 | return sizeof(br_uint_32); |
||
1257 | } |
||
1258 | |||
1259 | // IDA: br_uint_8* __usercall BlockWriteSetup@<EAX>(void *base@<EAX>, int block_size@<EDX>, int block_stride@<EBX>, int block_count@<ECX>, int size) |
||
1260 | br_uint_8* BlockWriteSetup(void* base, int block_size, int block_stride, int block_count, int size) { |
||
1261 | //int b; // Pierre-Marie Baty -- unused variable |
||
1262 | //br_uint_8* block; // Pierre-Marie Baty -- unused variable |
||
1263 | //br_uint_8* sp; // Pierre-Marie Baty -- unused variable |
||
1264 | //br_uint_8* dp; // Pierre-Marie Baty -- unused variable |
||
1265 | LOG_TRACE("(%p, %d, %d, %d, %d)", base, block_size, block_stride, block_count, size); |
||
1266 | NOT_IMPLEMENTED(); |
||
1267 | } |
||
1268 | |||
1269 | // IDA: int __usercall DfBlockWriteText@<EAX>(br_datafile *df@<EAX>, void *base@<EDX>, int block_size@<EBX>, int block_stride@<ECX>, int block_count, int size) |
||
1270 | int DfBlockWriteText(br_datafile* df, void* base, int block_size, int block_stride, int block_count, int size) { |
||
1271 | int i; |
||
1272 | //br_uint_8* cp; // Pierre-Marie Baty -- unused variable |
||
1273 | br_uint_8* block; |
||
1274 | int count; |
||
1275 | LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); |
||
1276 | |||
1277 | if (block_stride == block_size) { |
||
1278 | block_size = block_count * block_size; |
||
1279 | block_count = 1; |
||
1280 | } |
||
1281 | block = base; |
||
1282 | #if !BR_ENDIAN_BIG |
||
1283 | if ((size != 1) || (block_count != 1)) { |
||
1284 | #else |
||
1285 | if (block_count != 1) { |
||
1286 | #endif |
||
1287 | block = BrScratchAllocate(block_count * block_size * size); |
||
1288 | for (count = 0; count < block_count; count++) { |
||
1289 | BrMemCpy(block + count * block_size * size, (br_uint_8*)base + count * block_stride * size, block_size * size); |
||
1290 | } |
||
1291 | #if !BR_ENDIAN_BIG |
||
1292 | BrSwapBlock(block, block_count * block_size, size); |
||
1293 | #endif |
||
1294 | } |
||
1295 | BrFilePrintf(df->h, " block %d\n", block_count * block_size); |
||
1296 | BrFilePrintf(df->h, " size %d\n", size); |
||
1297 | for (i = 0; i < block_count * block_size * size; i++) { |
||
1298 | if ((i & 0x1f) == 0) { |
||
1299 | BrFilePrintf(df->h, " %08x: %02x", i, block[i]); |
||
1300 | } else { |
||
1301 | BrFilePrintf(df->h, "%02x", block[i]); |
||
1302 | } |
||
1303 | if ((i & 0x1f) == 0x1f) { |
||
1304 | BrFilePutChar('\n', df->h); |
||
1305 | } |
||
1306 | } |
||
1307 | if ((i & 0x1f) != 0x0) { |
||
1308 | BrFilePutChar('\n', df->h); |
||
1309 | } |
||
1310 | if (block != base) { |
||
1311 | BrScratchFree(block); |
||
1312 | } |
||
1313 | return 0; |
||
1314 | } |
||
1315 | |||
1316 | // IDA: void* __usercall DfBlockReadText@<EAX>(br_datafile *df@<EAX>, void *base@<EDX>, int *count@<EBX>, int size@<ECX>, int mtype) |
||
1317 | void* DfBlockReadText(br_datafile* df, void* base, int* count, int size, int mtype) { |
||
1318 | char* id; |
||
1319 | char* data; |
||
1320 | int l; |
||
1321 | int s; |
||
1322 | int a; |
||
1323 | char b[3]; |
||
1324 | LOG_TRACE9("(%p, %p, %p, %d, %d)", df, base, count, size, mtype); |
||
1325 | |||
1326 | TextReadLine(df, &id, &data); |
||
1327 | if (BrStrCmp(id, "block") != 0) { |
||
1328 | BrFailure("no block"); |
||
1329 | } |
||
1330 | l = BrStrToUL(data, NULL, 0); |
||
1331 | TextReadLine(df, &id, &data); |
||
1332 | if (BrStrCmp(id, "size") != 0) { |
||
1333 | BrFailure("no size"); |
||
1334 | } |
||
1335 | s = BrStrToUL(data, NULL, 0); |
||
1336 | if (s != size) { |
||
1337 | BrFailure("block size mismatch"); |
||
1338 | } |
||
1339 | if (base == NULL) { |
||
1340 | base = BrResAllocate(df->res ? df->res : fw.res, l * size, mtype); |
||
1341 | } else { |
||
1342 | if (*count < l) { |
||
1343 | BrFailure("DfBlockReadText: block too long: %d", l); |
||
1344 | } |
||
1345 | } |
||
1346 | *count = l; |
||
1347 | for (a = 0; a < l * size;) { |
||
1348 | TextReadLine(df, &id, &data); |
||
1349 | if (a != BrStrToL(id, NULL, 16)) { |
||
1350 | BrFailure("block address mismatch"); |
||
1351 | } |
||
1352 | while ((data[0] != '\0') && (data[1] != '\0')) { |
||
1353 | b[0] = data[0]; |
||
1354 | b[1] = data[1]; |
||
1355 | b[2] = '\0'; |
||
1356 | ((br_uint_8*)base)[a] = (br_uint_8)BrStrToUL(b, NULL, 16); |
||
1357 | data += 2; |
||
1358 | a++; |
||
1359 | } |
||
1360 | } |
||
1361 | #if !BR_ENDIAN_BIG |
||
1362 | BrSwapBlock(base, l, size); |
||
1363 | #endif |
||
1364 | return base; |
||
1365 | } |
||
1366 | |||
1367 | // IDA: int __usercall DfBlockWriteBinary@<EAX>(br_datafile *df@<EAX>, void *base@<EDX>, int block_size@<EBX>, int block_stride@<ECX>, int block_count, int size) |
||
1368 | int DfBlockWriteBinary(br_datafile* df, void* base, int block_size, int block_stride, int block_count, int size) { |
||
1369 | int count; |
||
1370 | br_uint_32 l; |
||
1371 | br_uint_32 s; |
||
1372 | void* block; |
||
1373 | LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); |
||
1374 | |||
1375 | l = BrHtoNL(block_count * block_size); |
||
1376 | s = BrHtoNL(size); |
||
1377 | if (block_stride == block_size) { |
||
1378 | block_size = block_count * block_size; |
||
1379 | block_count = 1; |
||
1380 | } |
||
1381 | block = base; |
||
1382 | #if !BR_ENDIAN_BIG |
||
1383 | if ((size != 1) || (block_count != 1)) { |
||
1384 | #else |
||
1385 | if (block_count != 1) { |
||
1386 | #endif |
||
1387 | block = BrScratchAllocate(block_count * block_size * size); |
||
1388 | for (count = 0; count < block_count; count++) { |
||
1389 | BrMemCpy((br_uint_8*)block + count * block_size * size, (br_uint_8*)base + count * block_stride * size, block_size * size); |
||
1390 | } |
||
1391 | #if !BR_ENDIAN_BIG |
||
1392 | BrSwapBlock(block, block_count * block_size, size); |
||
1393 | #endif |
||
1394 | } |
||
1395 | BrFileWrite(&l, sizeof(l), 1, df->h); |
||
1396 | BrFileWrite(&s, sizeof(s), 1, df->h); |
||
1397 | BrFileWrite(block, block_count * block_size, size, df->h); |
||
1398 | if (block != base) { |
||
1399 | BrScratchFree(block); |
||
1400 | } |
||
1401 | return 0; |
||
1402 | } |
||
1403 | |||
1404 | // IDA: void* __usercall DfBlockReadBinary@<EAX>(br_datafile *df@<EAX>, void *base@<EDX>, int *count@<EBX>, int size@<ECX>, int mtype) |
||
1405 | void* DfBlockReadBinary(br_datafile* df, void* base, int* count, int size, int mtype) { |
||
1406 | int l; |
||
1407 | int s; |
||
1408 | LOG_TRACE9("(%p, %p, %p, %d, %d)", df, base, count, size, mtype); |
||
1409 | |||
1410 | BrFileRead(&l, 4, 1, df->h); |
||
1411 | l = BrHtoNL(l); |
||
1412 | BrFileRead(&s, 4, 1, df->h); |
||
1413 | s = BrHtoNL(s); |
||
1414 | if (s != size) { |
||
1415 | BrFailure("block size mismatch"); |
||
1416 | } |
||
1417 | if (base != NULL) { |
||
1418 | if (l > *count) { |
||
1419 | BrFailure("DfBlockReadBinary: block too long: %d", l); |
||
1420 | } |
||
1421 | } else { |
||
1422 | base = BrResAllocate(df->res != NULL ? df->res : fw.res, size * l, mtype); |
||
1423 | } |
||
1424 | *count = l; |
||
1425 | BrFileRead(base, l, size, df->h); |
||
1426 | #if !BR_ENDIAN_BIG |
||
1427 | BrSwapBlock(base, l, size); |
||
1428 | #endif |
||
1429 | return base; |
||
1430 | } |
||
1431 | |||
1432 | // IDA: int __usercall DfBlockSizeText@<EAX>(br_datafile *df@<EAX>, void *base@<EDX>, int block_size@<EBX>, int block_stride@<ECX>, int block_count, int size) |
||
1433 | int DfBlockSizeText(br_datafile* df, void* base, int block_size, int block_stride, int block_count, int size) { |
||
1434 | LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); |
||
1435 | |||
1436 | return ((size * block_count * block_size + (32 - 1)) >> 5) + 2; |
||
1437 | } |
||
1438 | |||
1439 | // IDA: int __usercall DfBlockSizeBinary@<EAX>(br_datafile *df@<EAX>, void *base@<EDX>, int block_size@<EBX>, int block_stride@<ECX>, int block_count, int size) |
||
1440 | int DfBlockSizeBinary(br_datafile* df, void* base, int block_size, int block_stride, int block_count, int size) { |
||
1441 | LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); |
||
1442 | |||
1443 | return size * block_count * block_size + 8; |
||
1444 | } |
||
1445 | |||
1446 | // IDA: char* __usercall DfNameReadText@<EAX>(br_datafile *df@<EAX>, char *name@<EDX>) |
||
1447 | char* DfNameReadText(br_datafile* df, char* name) { |
||
1448 | char* id; |
||
1449 | char* data; |
||
1450 | LOG_TRACE("(%p, \"%s\")", df, name); |
||
1451 | |||
1452 | TextReadLine(df, &id, &data); |
||
1453 | if (BrStrCmp(id, "name") != 0) { |
||
1454 | BrFailure("no name"); |
||
1455 | } |
||
1456 | if ((data != NULL) && (*data == '\"')) { |
||
1457 | BrStrNCpy(name, data + 1, 0xff); |
||
1458 | name[0xff] = '\0'; |
||
1459 | return data; |
||
1460 | } |
||
1461 | BrFailure("no name string"); |
||
1462 | return NULL; // Pierre-Marie Baty -- make compiler happy |
||
1463 | } |
||
1464 | |||
1465 | // IDA: int __usercall DfNameWriteText@<EAX>(br_datafile *df@<EAX>, char *name@<EDX>) |
||
1466 | int DfNameWriteText(br_datafile* df, char* name) { |
||
1467 | LOG_TRACE("(%p, \"%s\")", df, name); |
||
1468 | |||
1469 | if (name == NULL) { |
||
1470 | name = "NULL"; |
||
1471 | } |
||
1472 | BrFilePrintf(df->h, " name \"%s\"\n", name); |
||
1473 | return 0; |
||
1474 | } |
||
1475 | |||
1476 | // IDA: int __usercall DfNameSizeText@<EAX>(br_datafile *df@<EAX>, char *name@<EDX>) |
||
1477 | int DfNameSizeText(br_datafile* df, char* name) { |
||
1478 | LOG_TRACE("(%p, \"%s\")", df, name); |
||
1479 | |||
1480 | return 1; |
||
1481 | } |
||
1482 | |||
1483 | // IDA: char* __usercall DfNameReadBinary@<EAX>(br_datafile *df@<EAX>, char *name@<EDX>) |
||
1484 | char* DfNameReadBinary(br_datafile* df, char* name) { |
||
1485 | int c; |
||
1486 | int i; |
||
1487 | LOG_TRACE9("(%p, \"%s\")", df, name); |
||
1488 | |||
1489 | for (i = 0; i < 255; i++) { |
||
1490 | c = BrFileGetChar(df->h); |
||
1491 | if ((c == 0) || (c == -1)) { |
||
1492 | break; |
||
1493 | } |
||
1494 | name[i] = c; |
||
1495 | } |
||
1496 | name[i] = '\0'; |
||
1497 | return name; |
||
1498 | } |
||
1499 | |||
1500 | // IDA: int __usercall DfNameWriteBinary@<EAX>(br_datafile *df@<EAX>, char *name@<EDX>) |
||
1501 | int DfNameWriteBinary(br_datafile* df, char* name) { |
||
1502 | LOG_TRACE("(%p, \"%s\")", df, name); |
||
1503 | |||
1504 | if (name != NULL) { |
||
1505 | BrFileWrite(name, 1, BrStrLen(name), df->h); |
||
1506 | } |
||
1507 | BrFilePutChar('\0', df->h); |
||
1508 | return 0; |
||
1509 | } |
||
1510 | |||
1511 | // IDA: int __usercall DfNameSizeBinary@<EAX>(br_datafile *df@<EAX>, char *name@<EDX>) |
||
1512 | int DfNameSizeBinary(br_datafile* df, char* name) { |
||
1513 | LOG_TRACE("(%p, \"%s\")", df, name); |
||
1514 | |||
1515 | if (name != NULL) { |
||
1516 | return BrStrLen(name) + 1; |
||
1517 | } |
||
1518 | return 1; |
||
1519 | } |
||
1520 | |||
1521 | // IDA: int __usercall DfSkipText@<EAX>(br_datafile *df@<EAX>, br_uint_32 length@<EDX>) |
||
1522 | int DfSkipText(br_datafile* df, br_uint_32 length) { |
||
1523 | char* id; |
||
1524 | char* data; |
||
1525 | LOG_TRACE("(%p, %d)", df, length); |
||
1526 | |||
1527 | while ((BrFileEof(df->h) == 0) && (length != 0)) { |
||
1528 | TextReadLine(df, &data, &id); |
||
1529 | length--; |
||
1530 | } |
||
1531 | return 0; |
||
1532 | } |
||
1533 | |||
1534 | // IDA: int __usercall DfSkipBinary@<EAX>(br_datafile *df@<EAX>, br_uint_32 length@<EDX>) |
||
1535 | int DfSkipBinary(br_datafile* df, br_uint_32 length) { |
||
1536 | LOG_TRACE9("(%p, %d)", df, length); |
||
1537 | BrFileAdvance(length, df->h); |
||
1538 | return 0; |
||
1539 | } |
||
1540 | |||
1541 | // IDA: int __usercall DfChunksInterpret@<EAX>(br_datafile *df@<EAX>, br_chunks_table *table@<EDX>) |
||
1542 | int DfChunksInterpret(br_datafile* df, br_chunks_table* table) { |
||
1543 | br_uint_32 length; |
||
1544 | br_uint_32 count; |
||
1545 | br_uint_32 id; |
||
1546 | int r; |
||
1547 | int i; |
||
1548 | LOG_TRACE9("(%p, %p)", df, table); |
||
1549 | |||
1550 | while (1) { |
||
1551 | id = df->prims->chunk_read(df, &length); |
||
1552 | // LOG_DEBUG("chunk id=%d, len=%d", id, length); |
||
1553 | if (id == (br_uint_32)-1) { |
||
1554 | break; |
||
1555 | } |
||
1556 | for (i = 0; i < table->nentries; i++) { |
||
1557 | if (table->entries[i].id == id) { |
||
1558 | break; |
||
1559 | } |
||
1560 | } |
||
1561 | if (i >= table->nentries) { |
||
1562 | df->prims->skip(df, length); |
||
1563 | } else { |
||
1564 | if (table->entries[i].has_count != 0) { |
||
1565 | count = df->prims->count_read(df); |
||
1566 | } else { |
||
1567 | count = 0; |
||
1568 | } |
||
1569 | r = table->entries[i].handler(df, id, length, count); |
||
1570 | if (r != 0) { |
||
1571 | return r; |
||
1572 | } |
||
1573 | } |
||
1574 | } |
||
1575 | return 0; |
||
1576 | } |
||
1577 | |||
1578 | // IDA: void __cdecl BrNullOther() |
||
1579 | void BrNullOther(void) { |
||
1580 | LOG_TRACE("()"); |
||
1581 | |||
1582 | // Yes, "invalid" is misspelled. |
||
1583 | BrFatal("datafile.c", 1825, "Invald file primitive call"); |
||
1584 | } |
||
1585 | |||
1586 | // IDA: int __cdecl DfFileIdentify(br_uint_8 *magics, br_size_t n_magics) |
||
1587 | int DfFileIdentify(br_uint_8* magics, br_size_t n_magics) { |
||
1588 | static char text_magics[8] = { '*', 'F', 'I', 'L', 'E', '_', 'I', 'N' }; |
||
1589 | static char binary_magics[8] = { '\0', '\0', '\0', '\x12', '\0', '\0', '\0', '\b' }; |
||
1590 | |||
1591 | if (BrMemCmp(magics, text_magics, sizeof(magics)) == 0) { |
||
1592 | return BR_FS_MODE_TEXT; |
||
1593 | } |
||
1594 | if (BrMemCmp(magics, binary_magics, sizeof(magics)) == 0) { |
||
1595 | return BR_FS_MODE_BINARY; |
||
1596 | } |
||
1597 | LOG_WARN("file does not match magics"); |
||
1598 | return BR_FS_MODE_UNKNOWN; |
||
1599 | } |
||
1600 | |||
1601 | // IDA: br_datafile* __usercall DfOpen@<EAX>(char *name@<EAX>, int write@<EDX>, br_token scalar_type@<EBX>) |
||
1602 | br_datafile* DfOpen(char* name, int write, br_token scalar_type) { |
||
1603 | int mode; |
||
1604 | //char c; // Pierre-Marie Baty -- unused variable |
||
1605 | br_datafile* df; |
||
1606 | void* h; |
||
1607 | LOG_TRACE9("(\"%s\", %d, %d)", name, write, scalar_type); |
||
1608 | |||
1609 | mode = fw.open_mode; |
||
1610 | if (write != 0) { |
||
1611 | h = BrFileOpenWrite(name, fw.open_mode); |
||
1612 | } else { |
||
1613 | h = BrFileOpenRead(name, 8u, DfFileIdentify, &mode); |
||
1614 | } |
||
1615 | if (h == NULL) { |
||
1616 | return NULL; |
||
1617 | } |
||
1618 | df = BrResAllocate(fw.res, sizeof(br_datafile), BR_MEMORY_DATAFILE); |
||
1619 | df->prims = &_BrFilePrimsNull; |
||
1620 | df->h = h; |
||
1621 | df->scalar_type = scalar_type; |
||
1622 | |||
1623 | if (mode == BR_FS_MODE_BINARY) { |
||
1624 | if (write != 0) { |
||
1625 | df->prims = &_BrFilePrimsWriteBinary; |
||
1626 | } else { |
||
1627 | df->prims = &_BrFilePrimsReadBinary; |
||
1628 | } |
||
1629 | } else { |
||
1630 | if (write != 0) |
||
1631 | df->prims = &_BrFilePrimsWriteText; |
||
1632 | else |
||
1633 | df->prims = &_BrFilePrimsReadText; |
||
1634 | } |
||
1635 | DfPush(BR_MEMORY_FILE, df, 1); // Wrong enum -> should be DF_STACK_FILE (see comment in src/BRSRC13/CORE/V1DB/v1dbfile.c) |
||
1636 | return df; |
||
1637 | } |
||
1638 | |||
1639 | // IDA: void __usercall DfClose(br_datafile *df@<EAX>) |
||
1640 | void DfClose(br_datafile* df) { |
||
1641 | br_datafile* dfp; |
||
1642 | LOG_TRACE("(%p)", df); |
||
1643 | |||
1644 | // TODO: this is not quite right according to IDA |
||
1645 | |||
1646 | while (1) { |
||
1647 | if (DatafileStackTop > 0) { |
||
1648 | if (DatafileStack[DatafileStackTop - 1].type == BR_MEMORY_FILE) { |
||
1649 | break; |
||
1650 | } |
||
1651 | DfPop(DatafileStack[DatafileStackTop - 1].type, NULL); |
||
1652 | } |
||
1653 | } |
||
1654 | dfp = DfPop(BR_MEMORY_FILE, NULL); |
||
1655 | BrFileClose(dfp->h); |
||
1656 | BrResFree(dfp); |
||
1657 | } |
||
1658 | |||
1659 | // IDA: int __cdecl BrWriteModeSet(int mode) |
||
1660 | int BrWriteModeSet(int mode) { |
||
1661 | int old; |
||
1662 | LOG_TRACE("(%d)", mode); |
||
1663 | |||
1664 | old = fw.open_mode; |
||
1665 | fw.open_mode = mode; |
||
1666 | return old; |
||
1667 | } |