Subversion Repositories Games.Carmageddon

Rev

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
}