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 | } |