From ba4b7630fbb811ef33e11e8e21096a8bff015e51 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 25 Jan 2022 23:54:30 +0100 Subject: [PATCH] Add all datafile functions (+needed dependent functions) (#73) * brender: add fixed functions + tests * brender: re-order assignment of variables Little nitpick patch, sorry :^) * brender: implement all scratch functions + tests * tests: Actually build and run math test functions * brender: implement BrFilePrintf * brender: BrVsprintfN returns number of characers written * tests: add ability to create temporary file in temporary folder * brender: add binary/text store+load of datafile + tests --- src/BRSRC13/CMakeLists.txt | 2 + src/BRSRC13/CORE/FW/datafile.c | 1261 +++++++++--- src/BRSRC13/CORE/FW/datafile.h | 101 + src/BRSRC13/CORE/FW/file.c | 9 +- src/BRSRC13/CORE/FW/scratch.c | 34 +- src/BRSRC13/CORE/MATH/fixed.c | 661 ++++++ src/BRSRC13/CORE/MATH/fixed.h | 109 + src/BRSRC13/CORE/MATH/plane.c | 16 +- src/BRSRC13/CORE/STD/brstdfile.c | 2 + src/BRSRC13/CORE/STD/brstdlib.c | 1 + test/BRSRC13/test_datafile.c | 3279 +++++++++++++++++++++++++++++- test/BRSRC13/test_fixed.c | 471 +++++ test/BRSRC13/test_matrix23.c | 1 + test/BRSRC13/test_matrix34.c | 1 + test/BRSRC13/test_matrix4.c | 1 + test/BRSRC13/test_quat.c | 1 + test/BRSRC13/test_scratch.c | 100 + test/CMakeLists.txt | 5 + test/main.c | 78 +- test/tests.h | 10 +- 20 files changed, 5843 insertions(+), 300 deletions(-) create mode 100644 src/BRSRC13/CORE/MATH/fixed.c create mode 100644 src/BRSRC13/CORE/MATH/fixed.h create mode 100644 test/BRSRC13/test_fixed.c create mode 100644 test/BRSRC13/test_scratch.c diff --git a/src/BRSRC13/CMakeLists.txt b/src/BRSRC13/CMakeLists.txt index 298cf0ed..9bb81e8c 100644 --- a/src/BRSRC13/CMakeLists.txt +++ b/src/BRSRC13/CMakeLists.txt @@ -113,6 +113,8 @@ target_sources(brender PRIVATE CORE/HOST/memmgmt.h CORE/MATH/angles.c CORE/MATH/angles.h + CORE/MATH/fixed.c + CORE/MATH/fixed.h CORE/MATH/matrix23.c CORE/MATH/matrix23.h CORE/MATH/matrix34.c diff --git a/src/BRSRC13/CORE/FW/datafile.c b/src/BRSRC13/CORE/FW/datafile.c index 9ca4e3b8..ad868ecf 100644 --- a/src/BRSRC13/CORE/FW/datafile.c +++ b/src/BRSRC13/CORE/FW/datafile.c @@ -1,124 +1,221 @@ #include "datafile.h" #include "CORE/FW/bswap.h" #include "CORE/FW/diag.h" +#include "CORE/FW/file.h" #include "CORE/FW/fwsetup.h" #include "CORE/FW/resource.h" +#include "CORE/FW/scratch.h" +#include "CORE/MATH/fixed.h" #include "CORE/STD/brstdlib.h" -#include "file.h" #include "harness/trace.h" -#include -#include - br_file_primitives _BrFilePrimsNull = { "NULL", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + (int(*)(br_datafile*,br_uint_32))&BrNullOther, + (int(*)(br_datafile*, br_uint_32, br_uint_32))&BrNullOther, + (int(*)(br_datafile*, br_uint_32*))&BrNullOther, + (void(*)(br_datafile*, br_uint_32))&BrNullOther, + (br_uint_32(*)(br_datafile*))&BrNullOther, + (int(*)(br_datafile*))&BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (int(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, + (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, + (void*(*)(br_datafile*, void*, int*, int, int))&BrNullOther, + (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, + (int(*)(br_datafile*, char*))&BrNullOther, + (char*(*)(br_datafile*, char*))&BrNullOther, + (int(*)(br_datafile*, char*))&BrNullOther, }; br_file_primitives _BrFilePrimsReadBinary = { "Read Binary", &DfSkipBinary, - NULL, + (int(*)(br_datafile*, br_uint_32, br_uint_32))&BrNullOther, &DfChunkReadBinary, - NULL, + (void(*)(br_datafile*, br_uint_32))&BrNullOther, &DfCountReadBinary, &DfCountSizeBinary, - NULL, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, &DfStructReadBinary, &DfStructSizeBinary, - NULL, + (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, &DfBlockReadBinary, &DfBlockSizeBinary, - NULL, + (int(*)(br_datafile*, char*))&BrNullOther, &DfNameReadBinary, - &DfNameSizeBinary + &DfNameSizeBinary, }; br_file_primitives _BrFilePrimsWriteBinary = { "Write Binary", &DfSkipBinary, &DfChunkWriteBinary, - NULL, + (int(*)(br_datafile*, br_uint_32*))&BrNullOther, &DfCountWriteBinary, - NULL, + (br_uint_32(*)(br_datafile*))&BrNullOther, &DfCountSizeBinary, &DfStructWriteBinary, - NULL, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, &DfStructSizeBinary, &DfBlockWriteBinary, - NULL, + (void*(*)(br_datafile*, void*, int*, int, int))&BrNullOther, &DfBlockSizeBinary, &DfNameWriteBinary, - NULL, - &DfNameSizeBinary + (char*(*)(br_datafile*, char*))&BrNullOther, + &DfNameSizeBinary, }; br_file_primitives _BrFilePrimsReadText = { "Read Text", &DfSkipText, - NULL, + (int(*)(br_datafile*, br_uint_32, br_uint_32))&BrNullOther, &DfChunkReadText, - NULL, + (void(*)(br_datafile*, br_uint_32))&BrNullOther, &DfCountReadText, - (int (*)(br_datafile*))(&DfNameSizeText), - NULL, + &DfCountSizeText, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, &DfStructReadText, &DfStructSizeText, - NULL, + (int(*)(br_datafile*, void*, int, int, int, int))&BrNullOther, &DfBlockReadText, &DfBlockSizeText, - NULL, + (int(*)(br_datafile*, char*))&BrNullOther, &DfNameReadText, - &DfNameSizeText + &DfNameSizeText, }; br_file_primitives _BrFilePrimsWriteText = { "Write Text", &DfSkipText, &DfChunkWriteText, - NULL, + (int(*)(br_datafile*, br_uint_32*))&BrNullOther, &DfCountWriteText, - NULL, - (int (*)(br_datafile*))(&DfNameSizeText), + (br_uint_32(*)(br_datafile*))&BrNullOther, + &DfCountSizeText, &DfStructWriteText, - NULL, + (br_uint_32(*)(br_datafile*, br_file_struct*, void*))&BrNullOther, &DfStructSizeText, &DfBlockWriteText, - NULL, + (void*(*)(br_datafile*, void*, int*, int, int))&BrNullOther, &DfBlockSizeText, &DfNameWriteText, - NULL, - &DfNameSizeText + (char*(*)(br_datafile*, char*))&BrNullOther, + &DfNameSizeText, +}; + +char* member_type_names[32] = { + "int_8", + "uint_8", + "int_16", + "uint_16", + "int_32", + "uint_32", + "fixed", + "angle", + "float", + "double", + "scalar", + "fraction", + "ufraction", + "enum_8", + "enum_16", + "enum_32", + "struct", + "asciz", + "colour", + "vector2", + "vector3", + "vector4", + "fixed_fraction", + "fixed_ufraction", + "float_fraction", + "float_ufraction", + "fixed_vector2", + "fixed_vector3", + "fixed_vector4", + "float_vector2", + "float_vector3", + "float_vector4", }; -char* member_type_names[32]; struct { int type; void* value; int count; } DatafileStack[1024]; -char* ChunkNames[61]; + +char* ChunkNames[61] = { + "END", + "IMAGE_PLANE", + "RLE_IMAGE_PLANE", + "PIXELMAP", + "MATERIAL_OLD", + "ADD_MATERIAL", + "OLD_ACTOR", + "OLD_ADD_SIBLING", + "OLD_ADD_CHILD", + "OLD_MATERIAL_INDEX", + "OLD_VERTICES", + "OLD_VERTICES_UV", + "OLD_FACES", + "OLD_MODEL", + "ADD_MODEL", + "ANIM", + "ANIM_TRANSFORM", + "ANIM_RATE", + "FILE_INFO", + "OLD_LIGHT", + "OLD_CAMERA", + "PIVOT", + "MATERIAL_INDEX", + "VERTICES", + "VERTEX_UV", + "OLD_FACES_1", + "FACE_MATERIAL", + "OLD_MODEL_1", + "COLOUR_MAP_REF", + "OPACITY_MAP_REF", + "INDEX_BLEND_REF", + "INDEX_SHADE_REF", + "SCREENDOOR_REF", + "PIXELS", + "ADD_MAP", + "ACTOR", + "ACTOR_MODEL", + "ACTOR_TRANSFORM", + "ACTOR_MATERIAL", + "ACTOR_LIGHT", + "ACTOR_CAMERA", + "ACTOR_BOUNDS", + "ACTOR_ADD_CHILD", + "TRANSFORM_MATRIX34", + "TRANSFORM_MATRIX34_LP", + "TRANSFORM_QUAT", + "TRANSFORM_EULER", + "TRANSFORM_LOOK_UP", + "TRANSFORM_TRANSLATION", + "TRANSFORM_IDENTITY", + "BOUNDS", + "LIGHT", + "CAMERA", + "FACES", + "MODEL", + "ACTOR_CLIP_PLANE", + "PLANE", + "SATURN_FACES", + "SATURN_MODEL", + "INDEX_FOG_REF", + "MATERIAL_OLD", +}; + int DatafileStackTop; // IDA: void __usercall DfPush(int type@, void *value@, int count@) void DfPush(int type, void* value, int count) { LOG_TRACE9("(%d, %p, %d)", type, value, count); - if (DatafileStackTop >= 1024) { + if (DatafileStackTop >= BR_ASIZE(DatafileStack)) { BrFailure("DatafileStack Overflow"); } DatafileStack[DatafileStackTop].type = type; @@ -138,7 +235,7 @@ void* DfPop(int type, int* countp) { if (type != DatafileStack[DatafileStackTop].type) { BrFailure("DatafileStack type mismatch, wanted %d, got %d", type, DatafileStack[DatafileStackTop].type); } - if (countp) { + if (countp != NULL) { *countp = DatafileStack[DatafileStackTop].count; } return DatafileStack[DatafileStackTop].value; @@ -151,7 +248,7 @@ void* DfTop(int type, int* countp) { BrFailure("DatafileStack Underflow"); if (type != DatafileStack[DatafileStackTop - 1].type) BrFailure("DatafileStack type mismatch, wanted %d, got %d", type, DatafileStack[DatafileStackTop].type); - if (countp) + if (countp != NULL) *countp = DatafileStack[DatafileStackTop - 1].count; return DatafileStack[DatafileStackTop - 1].value; } @@ -170,81 +267,78 @@ int DfTopType() { int TextReadLine(br_datafile* df, char** ident, char** data) { char* cp; LOG_TRACE("(%p, %p, %p)", df, ident, data); - NOT_IMPLEMENTED(); + + while (1) { + cp = BrScratchString(); + int a = BrFileGetLine(cp, 256, df->h); + if (BrFileEof(df->h) != 0) { + return 0; + } + for (; (*cp == ' ') || (*cp == '\t'); cp++) { + } + if (*cp != '\0') break; + } + *ident = cp; + while ((*cp != ' ') && (*cp != '\t') && (*cp != '\0')) { + cp++; + } + *cp = '\0'; + cp++; + while ((*cp == ' ') || (*cp == '\t')) { + cp++; + } + *data = cp; + if (*cp == '\"') { + cp++; + while ((*cp != '\0') && (*cp != '\"')) { + cp++; + } + } else { + while ((*cp != ' ') && (*cp != '\t') && (*cp != '\0')) { + cp++; + } + } + *cp = '\0'; + return 1; } // IDA: br_uint_16 __usercall scalarTypeConvert@(br_datafile *df@, br_uint_16 t@) br_uint_16 scalarTypeConvert(br_datafile* df, br_uint_16 t) { LOG_TRACE9("(%p, %d)", df, t); - if (df->scalar_type < BRT_FIXED) { - goto LABEL_20; - } - - if (df->scalar_type > BRT_FIXED) { - if (df->scalar_type == BRT_FLOAT) { - if (t - 10 <= BRT_FIXED) { - switch (t) { - case 10: - return 8; - case 11: - return 24; - case 12: - return 25; - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - return t; - case 19: - return 29; - break; - case 20: - return 30; - break; - case 21: - return 31; - break; - } - return t; - } - NOT_IMPLEMENTED(); - return t - 10; + if (df->scalar_type == BRT_FIXED) { + switch(t) { + case DF_TYPE_BR_SCALAR: + return DF_TYPE_BR_FIXED; + case DF_TYPE_BR_FRACTION: + return DF_TYPE_BR_FRACTION_X; + case DF_TYPE_BR_UFRACTION: + return DF_TYPE_BR_UFRACTION_X; + case DF_TYPE_BR_VECTOR2: + return DF_TYPE_BR_VECTOR2_X; + case DF_TYPE_BR_VECTOR3: + return DF_TYPE_BR_VECTOR3_X; + case DF_TYPE_BR_VECTOR4: + return DF_TYPE_BR_VECTOR4_X; } - LABEL_20: - if (t >= 0xAu - && (t <= 0xAu || (t >= 0x13u && t <= 0x15u))) { - BrFailure("Incorrect scalar type"); + } else if (df->scalar_type == BRT_FLOAT) { + switch (t) { + case DF_TYPE_BR_SCALAR: + return DF_TYPE_FLOAT; + case DF_TYPE_BR_UFRACTION: + return DF_TYPE_BR_FRACTION_F; + case DF_TYPE_BR_FRACTION: + return DF_TYPE_BR_UFRACTION_F; + case DF_TYPE_BR_VECTOR2: + return DF_TYPE_BR_VECTOR2_F; + case DF_TYPE_BR_VECTOR3: + return DF_TYPE_BR_VECTOR3_F; + case DF_TYPE_BR_VECTOR4: + return DF_TYPE_BR_VECTOR4_F; } - return t; + } else if ((t == DF_TYPE_BR_SCALAR) || ((DF_TYPE_BR_VECTOR2 <= t) && (t <= DF_TYPE_BR_VECTOR4))) { + BrFailure("Incorrect scalar type"); } - if (t - 10 > BRT_FIXED) { - return t; - } - switch (t) { - case 10: - return 6; - case 11: - return 22; - case 12: - return 23; - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - return t; - case 19: - return 26; - case 20: - return 27; - case 21: - return 28; - } - return t; } @@ -255,12 +349,132 @@ br_uint_32 DfStructWriteBinary(br_datafile* df, br_file_struct* str, void* base) int n; unsigned char* mp; br_file_struct_member* sm; - struct { // size: 0x8 + union { // size: 0x8 unsigned char b[8]; // @0x0 float f; // @0x0 + double d; // @0x0 } conv; LOG_TRACE("(%p, %p, %p)", df, str, base); - NOT_IMPLEMENTED(); + + for (m = 0; m < str->nmembers; m++) { + sm = &str->members[m]; + mp = ((unsigned char*)base) + sm->offset; + + switch (scalarTypeConvert(df, sm->type)) { + case DF_TYPE_BR_INT_8: + case DF_TYPE_BR_UINT_8: + case DF_TYPE_ENUM_8: + BrFilePutChar(((br_uint_8*)mp)[0], df->h); + break; + case DF_TYPE_BR_ANGLE: + case DF_TYPE_BR_INT_16: + case DF_TYPE_BR_UINT_16: + case DF_TYPE_ENUM_16: + BrFilePutChar(((br_uint_8*)mp)[1], df->h); + BrFilePutChar(((br_uint_8*)mp)[0], df->h); + break; + case DF_TYPE_BR_INT_32: + case DF_TYPE_BR_UINT_32: + case DF_TYPE_ENUM_32: + BrFilePutChar(((br_uint_8*)mp)[3], df->h); + BrFilePutChar(((br_uint_8*)mp)[2], df->h); + BrFilePutChar(((br_uint_8*)mp)[1], df->h); + BrFilePutChar(((br_uint_8*)mp)[0], df->h); + break; + case DF_TYPE_FLOAT: + case DF_TYPE_BR_FRACTION_F: + case DF_TYPE_BR_UFRACTION_F: + conv.f = *(float*)mp; + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + break; + case DF_TYPE_DOUBLE: + conv.d = *(double*)mp; + BrFilePutChar(conv.b[7], df->h); + BrFilePutChar(conv.b[6], df->h); + BrFilePutChar(conv.b[5], df->h); + BrFilePutChar(conv.b[4], df->h); + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + break; + case DF_TYPE_STRUCT: + DfStructWriteBinary(df, sm->extra, mp); + break; + case DF_TYPE_ASCIZ: + if (*(char **)mp != NULL) { + BrFileWrite(*(char **)mp, 1, BrStrLen(*(char**)mp), df->h); + } + BrFilePutChar('\0', df->h); + break; + case DF_TYPE_BR_COLOUR: + BrFilePutChar(((br_uint_8*)mp)[2], df->h); + BrFilePutChar(((br_uint_8*)mp)[1], df->h); + BrFilePutChar(((br_uint_8*)mp)[0], df->h); + break; + case DF_TYPE_BR_FIXED: + conv.f = BrFixedToFloat(*(br_fixed_ls*)mp); + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + break; + case DF_TYPE_BR_FRACTION_X: + conv.f = BrFixedFractionToFloat(*(br_fraction_x*)mp); + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + break; + case DF_TYPE_BR_UFRACTION_X: + conv.f = BrFixedUFractionToFloat(*(br_fraction_x*)mp); + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + break; + case DF_TYPE_BR_VECTOR2_X: + n = 2; + goto copy_fixed_vector; + case DF_TYPE_BR_VECTOR3_X: + n = 3; + goto copy_fixed_vector; + case DF_TYPE_BR_VECTOR4_X: + n = 4; + copy_fixed_vector: + for (i = 0; i < n; i++) { + conv.f = BrFixedToFloat(*(br_fixed_ls*)mp); + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + mp += sizeof(br_fixed_ls); + } + break; + case DF_TYPE_BR_VECTOR2_F: + n = 2; + goto copy_float_vector; + case DF_TYPE_BR_VECTOR3_F: + n = 3; + goto copy_float_vector; + case DF_TYPE_BR_VECTOR4_F: + n = 4; + copy_float_vector: + for (i = 0; i < n; i++) { + conv.f = *(float*)mp; + BrFilePutChar(conv.b[3], df->h); + BrFilePutChar(conv.b[2], df->h); + BrFilePutChar(conv.b[1], df->h); + BrFilePutChar(conv.b[0], df->h); + mp += sizeof(br_fixed_ls); + } + break; + } + } + return 1; } // IDA: br_uint_32 __usercall DfStructReadBinary@(br_datafile *df@, br_file_struct *str@, void *base@) @@ -275,153 +489,135 @@ br_uint_32 DfStructReadBinary(br_datafile* df, br_file_struct* str, void* base) union { unsigned char b[8]; float f; + double d; } conv; LOG_TRACE9("(%p, %p, %p)", df, str, base); for (m = 0; m < str->nmembers; m++) { - sm = &str->members[m]; c = scalarTypeConvert(df, sm->type); mp = ((unsigned char*)base) + sm->offset; - if (c > 0x1f) { - continue; - } switch (c) { - case 0: - case 1: - case 13: - *mp = BrFileGetChar(df->h); - goto LABEL_33; - case 2: - case 3: - case 7: - case 14: + case DF_TYPE_BR_INT_8: + case DF_TYPE_BR_UINT_8: + case DF_TYPE_ENUM_8: + mp[0] = BrFileGetChar(df->h); + break; + case DF_TYPE_BR_INT_16: + case DF_TYPE_BR_UINT_16: + case DF_TYPE_BR_ANGLE: + case DF_TYPE_ENUM_16: mp[1] = BrFileGetChar(df->h); - *mp = BrFileGetChar(df->h); - goto LABEL_33; - case 4: - case 5: - case 8: - case 15: - case 24: - case 25: + mp[0] = BrFileGetChar(df->h); + break; + case DF_TYPE_BR_INT_32: + case DF_TYPE_BR_UINT_32: + case DF_TYPE_FLOAT: + case DF_TYPE_ENUM_32: + case DF_TYPE_BR_FRACTION_F: + case DF_TYPE_BR_UFRACTION_F: mp[3] = BrFileGetChar(df->h); mp[2] = BrFileGetChar(df->h); mp[1] = BrFileGetChar(df->h); - *mp = BrFileGetChar(df->h); - goto LABEL_33; - case 6: - LOG_PANIC("Not implemented?"); + mp[0] = BrFileGetChar(df->h); + break; + case DF_TYPE_BR_FIXED: conv.b[3] = BrFileGetChar(df->h); conv.b[2] = BrFileGetChar(df->h); conv.b[1] = BrFileGetChar(df->h); conv.b[0] = BrFileGetChar(df->h); - *mp = (int)(conv.f * 65536.0f); - goto LABEL_33; - - case 9: - mp[7] = BrFileGetChar(df->h); - mp[6] = BrFileGetChar(df->h); - mp[5] = BrFileGetChar(df->h); - mp[4] = BrFileGetChar(df->h); - mp[3] = BrFileGetChar(df->h); - mp[2] = BrFileGetChar(df->h); - mp[1] = BrFileGetChar(df->h); - *mp = BrFileGetChar(df->h); - goto LABEL_33; - case 10: - case 11: - case 12: - case 19: - case 20: - case 21: - LOG_WARN("Ignoring member type"); - goto LABEL_33; - case 16: - LOG_PANIC("Not implemented?"); - DfStructReadBinary(df, str, mp); - goto LABEL_33; - case 17: + *(br_fixed_ls*)mp = BrFloatToFixed(conv.f); + break; + case DF_TYPE_DOUBLE: + conv.b[7] = BrFileGetChar(df->h); + conv.b[6] = BrFileGetChar(df->h); + conv.b[5] = BrFileGetChar(df->h); + conv.b[4] = BrFileGetChar(df->h); + conv.b[3] = BrFileGetChar(df->h); + conv.b[2] = BrFileGetChar(df->h); + conv.b[1] = BrFileGetChar(df->h); + conv.b[0] = BrFileGetChar(df->h); + *(double*)mp = conv.d; + break; + case DF_TYPE_STRUCT: + DfStructReadBinary(df, sm->extra, mp); + break; + case DF_TYPE_ASCIZ: for (n = 0; n < 255; n++) { c = BrFileGetChar(df->h); - if (!c || c == -1) + if (c == '\0' || c == -1) break; tmp_string[n] = c; } tmp_string[n] = 0; - *(intptr_t*)mp = (intptr_t*)BrResStrDup(df->res ? df->res : fw.res, tmp_string); - goto LABEL_33; - case 18: + *(char**)mp = (char*)BrResStrDup(df->res ? df->res : fw.res, tmp_string); + break; + case DF_TYPE_BR_COLOUR: mp[2] = BrFileGetChar(df->h); mp[1] = BrFileGetChar(df->h); - *mp = BrFileGetChar(df->h); - goto LABEL_33; - case 22: - LOG_PANIC("Not implemented?"); + mp[0] = BrFileGetChar(df->h); + break; + case DF_TYPE_BR_FRACTION_X: conv.b[3] = BrFileGetChar(df->h); conv.b[2] = BrFileGetChar(df->h); conv.b[1] = BrFileGetChar(df->h); conv.b[0] = BrFileGetChar(df->h); - *mp = (int)(conv.f * 32768.0f); - goto LABEL_33; - case 23: - LOG_PANIC("Not implemented?"); + *((br_fraction_x*)mp) = BrFloatToFixedFraction(conv.f); + break; + case DF_TYPE_BR_UFRACTION_X: conv.b[3] = BrFileGetChar(df->h); conv.b[2] = BrFileGetChar(df->h); conv.b[1] = BrFileGetChar(df->h); conv.b[0] = BrFileGetChar(df->h); - *mp = (int)(conv.f * 65536.0f); - goto LABEL_33; - case 26: + *(br_ufraction_x*)mp = BrFloatToFixedUFraction(conv.f); + break; + case DF_TYPE_BR_VECTOR2_X: n = 2; - goto LABEL_15; - case 27: + goto copy_fixed_vector; + case DF_TYPE_BR_VECTOR3_X: n = 3; - goto LABEL_15; - case 28: + goto copy_fixed_vector; + case DF_TYPE_BR_VECTOR4_X: n = 4; - LABEL_15: - LOG_PANIC("Not implemented?"); - i = 0; + copy_fixed_vector: for (i = 0; i < n; i++) { conv.b[3] = BrFileGetChar(df->h); conv.b[2] = BrFileGetChar(df->h); conv.b[1] = BrFileGetChar(df->h); conv.b[0] = BrFileGetChar(df->h); - *mp = (int)(conv.f * 65536.0f); - mp += sizeof(int); + *(br_fixed_ls*)mp = BrFloatToFixed(conv.f); + mp += sizeof(br_fixed_ls); } - goto LABEL_33; - case 29: + break; + case DF_TYPE_BR_VECTOR2_F: n = 2; + goto copy_float_vector; break; - case 30: + case DF_TYPE_BR_VECTOR3_F: n = 3; + goto copy_float_vector; break; - case 31: + case DF_TYPE_BR_VECTOR4_F: n = 4; + copy_float_vector: + for (i = 0; i < n; i++) { + conv.b[3] = BrFileGetChar(df->h); + conv.b[2] = BrFileGetChar(df->h); + conv.b[1] = BrFileGetChar(df->h); + conv.b[0] = BrFileGetChar(df->h); + *(float*)mp = conv.f; + mp += sizeof(float); + } break; - default: n = 0; } - - for (i = 0; i < n; i++) { - conv.b[3] = BrFileGetChar(df->h); - conv.b[2] = BrFileGetChar(df->h); - conv.b[1] = BrFileGetChar(df->h); - conv.b[0] = BrFileGetChar(df->h); - ((br_fvector4_f*)mp)->v[i] = conv.f; - } - - LABEL_33: - i = 0; } return 1; } - +#include // IDA: int __usercall DfStructSizeBinary@(br_datafile *df@, br_file_struct *str@, void *base@) int DfStructSizeBinary(br_datafile* df, br_file_struct* str, void* base) { unsigned char* mp; @@ -429,27 +625,108 @@ int DfStructSizeBinary(br_datafile* df, br_file_struct* str, void* base) { br_file_struct_member* sm; int bytes; LOG_TRACE("(%p, %p, %p)", df, str, base); - NOT_IMPLEMENTED(); + + bytes = 0; + for (m = 0; m < str->nmembers; m++) { + sm = &str->members[m]; + + mp = ((unsigned char*)base) + sm->offset; + + switch (scalarTypeConvert(df, sm->type)) { + case DF_TYPE_BR_INT_8: + case DF_TYPE_BR_UINT_8: + case DF_TYPE_ENUM_8: + bytes += 1; + break; + case DF_TYPE_BR_INT_16: + case DF_TYPE_BR_UINT_16: + case DF_TYPE_BR_ANGLE: + case DF_TYPE_ENUM_16: + bytes += 2; + break; + case DF_TYPE_BR_COLOUR: + bytes += 4; + break; + case DF_TYPE_BR_INT_32: + case DF_TYPE_BR_UINT_32: + case DF_TYPE_FLOAT: + case DF_TYPE_ENUM_32: + case DF_TYPE_BR_FRACTION_F: + case DF_TYPE_BR_UFRACTION_F: + case DF_TYPE_BR_FIXED: + case DF_TYPE_BR_FRACTION_X: + case DF_TYPE_BR_UFRACTION_X: + bytes += 4; + break; + case DF_TYPE_DOUBLE: + bytes += 8; + break; + case DF_TYPE_STRUCT: + bytes += DfStructSizeBinary(df, sm->extra, mp); + break; + case DF_TYPE_ASCIZ: + if (*(char**)mp != NULL) { + bytes += BrStrLen(*(char**)mp); + } + break; + case DF_TYPE_BR_VECTOR2_X: + case DF_TYPE_BR_VECTOR2_F: + bytes += 8; + break; + case DF_TYPE_BR_VECTOR3_X: + case DF_TYPE_BR_VECTOR3_F: + bytes += 12; + break; + case DF_TYPE_BR_VECTOR4_X: + case DF_TYPE_BR_VECTOR4_F: + bytes += 16; + break; + } + } + + return bytes; } // IDA: int __usercall EnumFromString@(br_file_enum *e@, char *str@) int EnumFromString(br_file_enum* e, char* str) { unsigned int m; LOG_TRACE("(%p, \"%s\")", e, str); - NOT_IMPLEMENTED(); + + if (e == NULL) { + BrFailure("Unknown enum string: %s", str); + } + for (m = 0; m < e->nmembers; m++) { + if (BrStrCmp(str, e->members[m].name) == 0) { + return e->members[m].value; + } + } + BrFailure("Unknown enum string: %s", str); } // IDA: char* __usercall EnumToString@(br_file_enum *e@, int num@) char* EnumToString(br_file_enum* e, int num) { unsigned int m; LOG_TRACE("(%p, %d)", e, num); - NOT_IMPLEMENTED(); + + if (e == NULL) { + goto fail; + } + for (m = 0; m < e->nmembers; m++) { + if (e->members[m].value == num) { + return e->members[m].name; + } + } +fail: + BrFailure("Unknown enum %d", num); } // IDA: br_uint_32 __usercall DfStructWriteText@(br_datafile *df@, br_file_struct *str@, void *base@) br_uint_32 DfStructWriteText(br_datafile* df, br_file_struct* str, void* base) { LOG_TRACE("(%p, %p, %p)", df, str, base); - NOT_IMPLEMENTED(); + + BrFilePrintf(df->h, " struct %s\n", str->name); + StructWriteTextSub(df, str, base, 4); + return 1; } // IDA: br_uint_32 __usercall StructWriteTextSub@(br_datafile *df@, br_file_struct *str@, void *base@, int indent@) @@ -461,7 +738,122 @@ br_uint_32 StructWriteTextSub(br_datafile* df, br_file_struct* str, void* base, void* mp; br_file_struct_member* sm; LOG_TRACE("(%p, %p, %p, %d)", df, str, base, indent); - NOT_IMPLEMENTED(); + + for (m = 0; m < str->nmembers; m++) { + sm = &str->members[m]; + mp = ((unsigned char*)base) + sm->offset; + w = 0; + add_comment = 1; + + for (i = 0; i < indent; i++) { + BrFilePutChar(' ', df->h); + } + + // Modified from "%-10s", to ensure space after long type names + BrFilePrintf(df->h, "%-9s ", member_type_names[sm->type]); + + switch (scalarTypeConvert(df, sm->type)) { + case DF_TYPE_BR_INT_8: + w = BrFilePrintf(df->h, "%d", *(br_int_8*)mp); + break; + case DF_TYPE_BR_UINT_8: + w = BrFilePrintf(df->h, "%u", *(br_uint_8*)mp); + break; + case DF_TYPE_BR_INT_16: + w = BrFilePrintf(df->h, "%d", *(br_int_16*)mp); + break; + case DF_TYPE_BR_UINT_16: + w = BrFilePrintf(df->h, "%u", *(br_uint_16*)mp); + break; + case DF_TYPE_BR_INT_32: + w = BrFilePrintf(df->h, "%d", *(br_int_32*)mp); + break; + case DF_TYPE_BR_UINT_32: + w = BrFilePrintf(df->h, "%u", *(br_uint_32*)mp); + break; + case DF_TYPE_BR_FIXED: + w = BrFilePrintf(df->h, "%g", BrFixedToFloat(*(br_fixed_ls*)mp)); + break; + case DF_TYPE_BR_ANGLE: + w = BrFilePrintf(df->h, "%g", BrFixedToFloat(BrFixedMul(*(br_angle*)mp, BrIntToFixed(360)))); + break; + case DF_TYPE_FLOAT: + case DF_TYPE_BR_FRACTION_F: + case DF_TYPE_BR_UFRACTION_F: + w = BrFilePrintf(df->h, "%g", (double)*(float*)mp); + break; + case DF_TYPE_DOUBLE: + w = BrFilePrintf(df->h, "%g", *(double*)mp); + break; + case DF_TYPE_ENUM_8: + w = BrFilePrintf(df->h, "%s", EnumToString(sm->extra, *(br_uint_8*)mp)); + break; + case DF_TYPE_ENUM_16: + w = BrFilePrintf(df->h, "%s", EnumToString(sm->extra, *(br_uint_16*)mp)); + break; + case DF_TYPE_ENUM_32: + w = BrFilePrintf(df->h, "%s", EnumToString(sm->extra, *(br_uint_32*)mp)); + break; + case DF_TYPE_STRUCT: + add_comment = 0; + w = BrFilePrintf(df->h, "%s", ((br_file_struct*)sm->extra)->name); + if (sm->name != NULL) { + if (w < 40) { + for (i = 40 - w; i != 0; i--) { + BrFilePutChar(' ', df->h); + } + } + BrFilePrintf(df->h, " # %s", sm->name); + } + BrFilePutChar('\n', df->h); + StructWriteTextSub(df, sm->extra, mp, indent + 2); + break; + case DF_TYPE_ASCIZ: + if (*(char **)mp == NULL) { + w = BrFilePrintf(df->h, "NULL"); + } else { + w = BrFilePrintf(df->h, "\"%s\"", *(char **)mp); + } + break; + case DF_TYPE_BR_COLOUR: + 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))); + break; + case DF_TYPE_BR_FRACTION_X: + w = BrFilePrintf(df->h, "%g", (double)BrFixedFractionToFloat(*(br_fraction_x*)mp)); + break; + case DF_TYPE_BR_UFRACTION_X: + w = BrFilePrintf(df->h, "%g", (double)BrFixedUFractionToFloat(*(br_fraction_x*)mp)); + break; + case DF_TYPE_BR_VECTOR2_X: + w = BrFilePrintf(df->h, "%g,%g", BrFixedToFloat(((br_fixed_ls*)mp)[0]), BrFixedToFloat(((br_fixed_ls*)mp)[1])); + break; + case DF_TYPE_BR_VECTOR3_X: + 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])); + break; + case DF_TYPE_BR_VECTOR4_X: + 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])); + break; + case DF_TYPE_BR_VECTOR2_F: + w = BrFilePrintf(df->h, "%g,%g", ((float*)mp)[0], ((float*)mp)[1]); + break; + case DF_TYPE_BR_VECTOR3_F: + w = BrFilePrintf(df->h, "%g,%g,%g", ((float*)mp)[0], ((float*)mp)[1], ((float*)mp)[2]); + break; + case DF_TYPE_BR_VECTOR4_F: + w = BrFilePrintf(df->h, "%g,%g,%g,%g", ((float*)mp)[0], ((float*)mp)[1], ((float*)mp)[2], ((float*)mp)[3]); + break; + } + if ((add_comment != 0) && (sm->name != NULL)) { + if (w < 40) { + for (i = 40 - w; i != 0; i--) { + BrFilePutChar(' ', df->h); + } + } + BrFilePrintf(df->h, " # %s\n", sm->name); + } + } + + return 1; } // IDA: br_uint_32 __usercall DfStructReadText@(br_datafile *df@, br_file_struct *str@, void *base@) @@ -469,7 +861,16 @@ br_uint_32 DfStructReadText(br_datafile* df, br_file_struct* str, void* base) { char* id; char* data; LOG_TRACE("(%p, %p, %p)", df, str, base); - NOT_IMPLEMENTED(); + + TextReadLine(df, &id, &data); + if (BrStrCmp(id, "struct") != 0) { + BrFailure("Unknown text identifer \"%s\"", id); + } + if (BrStrCmp(data, str->name) != 0) { + BrFailure("Incorrect structure name \"%s\"", data); + } + StructReadTextSub(df, str, base); + return 1; } // IDA: br_uint_32 __usercall StructReadTextSub@(br_datafile *df@, br_file_struct *str@, void *base@) @@ -486,7 +887,147 @@ br_uint_32 StructReadTextSub(br_datafile* df, br_file_struct* str, void* base) { char* data; char* ep; LOG_TRACE("(%p, %p, %p)", df, str, base); - NOT_IMPLEMENTED(); + + for (m = 0; m < str->nmembers; m++) { + sm = &str->members[m]; + mp = ((unsigned char*)base) + sm->offset; + + if (TextReadLine(df, &id, &data) == 0) { + BrFailure("Unexpected EOF in strructure"); + } + if (BrStrCmp(id, member_type_names[sm->type]) != 0) { + BrFailure("Unknown member identifer \"%s\"", id); + } + + switch (scalarTypeConvert(df, sm->type)) { + case DF_TYPE_BR_INT_8: + *(br_int_8*)mp = (br_int_8)BrStrToL(data, NULL, 0); + break; + case DF_TYPE_BR_UINT_8: + *(br_uint_8*)mp = (br_uint_8)BrStrToL(data, NULL, 0); + break; + case DF_TYPE_BR_INT_16: + *(br_int_16*)mp = (br_int_16)BrStrToL(data, NULL, 0); + break; + case DF_TYPE_BR_UINT_16: + *(br_uint_16*)mp = (br_uint_16)BrStrToL(data, NULL, 0); + break; + case DF_TYPE_BR_INT_32: + *(br_int_32*)mp = (br_int_32)BrStrToL(data, NULL, 0); + break; + case DF_TYPE_BR_UINT_32: + *(br_uint_32*)mp = (br_uint_32)BrStrToUL(data, NULL, 0); + break; + case DF_TYPE_BR_FIXED: + *(br_fixed_ls*)mp = BrFloatToFixed(BrStrToD(data, NULL)); + break; + case DF_TYPE_BR_ANGLE: + *(br_angle*)mp = BrFixedMulDiv(BrFloatToFixed(BrStrToF(data, NULL)), BrIntToFixed(1), BrIntToFixed(360)); + break; + case DF_TYPE_FLOAT: + case DF_TYPE_BR_FRACTION_F: + case DF_TYPE_BR_UFRACTION_F: + *(float*)mp = BrStrToF(data, NULL); + break; + case DF_TYPE_DOUBLE: + *(double*)mp = BrStrToD(data, NULL); + break; + case DF_TYPE_ENUM_8: + *(br_uint_8*)mp = EnumFromString(sm->extra, data); + break; + case DF_TYPE_ENUM_16: + *(br_uint_16*)mp = EnumFromString(sm->extra, data); + break; + case DF_TYPE_ENUM_32: + *(br_uint_32*)mp = EnumFromString(sm->extra, data); + break; + case DF_TYPE_STRUCT: + if (BrStrCmp(data, ((br_file_struct*)sm->extra)->name) != 0) { + BrFailure("Incorrect structure name \"%s\"", data); + } + StructReadTextSub(df, sm->extra, mp); + break; + case DF_TYPE_ASCIZ: + if (BrStrCmp(data, "NULL") == 0) { + *(char**)mp = NULL; + } else { + *(char**)mp = BrResStrDup(df->res == NULL ? fw.res : df->res, data + 1); + } + break; + case DF_TYPE_BR_COLOUR: + r = BrStrToUL(data, &ep, 0); + if (*ep != ',') { + BrFailure("Incorrect colour"); + } + g = BrStrToUL(ep + 1, &ep, 0); + if (*ep != ',') { + BrFailure("Incorrect colour"); + } + b = BrStrToUL(ep + 1, &ep, 0); + *(br_colour*)mp = BR_COLOUR_RGB(r, g, b); + break; + case DF_TYPE_BR_FRACTION_X: + *(br_fixed_ss*)mp = BrFloatToFixedFraction(BrStrToD(data, NULL)); + break; + case DF_TYPE_BR_UFRACTION_X: + *(br_fixed_su*)mp = BrFloatToFixedUFraction(BrStrToD(data, NULL)); + break; + case DF_TYPE_BR_VECTOR2_X: + n = 2; + goto copy_fixed_vector; + case DF_TYPE_BR_VECTOR3_X: + n = 3; + goto copy_fixed_vector; + case DF_TYPE_BR_VECTOR4_X: + n = 4; + copy_fixed_vector: + for (i = 0; i < n; i++) { + while (1) { + if ((*data != ',') && (*data != ' ') && (*data != '\t')) { + break; + } + data++; + } + if (*data == '\0') { + BrFailure("Incorrect vector"); + } + *(br_fixed_ls*)mp = BrFloatToFixed(BrStrToF(data, NULL)); + while ((*data != ' ' && *data != ',' && *data != ' ' && *data != '\t')) { + data++; + } + mp = (char*)mp + sizeof(br_fixed_ls); + } + break; + case DF_TYPE_BR_VECTOR2_F: + n = 2; + goto copy_float_vector; + case DF_TYPE_BR_VECTOR3_F: + n = 3; + goto copy_float_vector; + case DF_TYPE_BR_VECTOR4_F: + n = 4; + copy_float_vector: + for (i = 0; i < n; i++) { + while (1) { + if ((*data != ',') && (*data != ' ') && (*data != '\t')) { + break; + } + data++; + } + if (*data == '\0') { + BrFailure("Incorrect vector"); + } + *(float*)mp = BrStrToF(data, NULL); + while ((*data != ' ' && *data != ',' && *data != ' ' && *data != '\t')) { + data++; + } + mp = (char*)mp + sizeof(float); + } + break; + } + } + + return 1; } // IDA: int __usercall DfStructSizeText@(br_datafile *df@, br_file_struct *str@, void *base@) @@ -495,7 +1036,17 @@ int DfStructSizeText(br_datafile* df, br_file_struct* str, void* base) { br_file_struct_member* sm; int lines; LOG_TRACE("(%p, %p, %p)", df, str, base); - NOT_IMPLEMENTED(); + + lines = 1; + for (m = 0; m < str->nmembers; m++) { + sm = &str->members[m]; + if (sm->type == DF_TYPE_STRUCT) { + lines += DfStructSizeText(df, sm->extra, (br_uint_8*)base + sm->offset); + } else { + lines++; + } + } + return lines; } // IDA: br_uint_32 __usercall DfStructWriteArray@(br_datafile *df@, br_file_struct *str@, void *base@, int n@) @@ -503,7 +1054,13 @@ br_uint_32 DfStructWriteArray(br_datafile* df, br_file_struct* str, void* base, char* cp; int i; LOG_TRACE("(%p, %p, %p, %d)", df, str, base, n); - NOT_IMPLEMENTED(); + + cp = (char*)base; + for (i = 0; i < n; i++) { + df->prims->struct_write(df, str, cp); + cp += str->mem_size; + } + return i; } // IDA: br_uint_32 __usercall DfStructReadArray@(br_datafile *df@, br_file_struct *str@, void *base@, int n@) @@ -514,7 +1071,7 @@ br_uint_32 DfStructReadArray(br_datafile* df, br_file_struct* str, void* base, i cp = (char*)base; for (i = 0; i < n; i++) { - if (BrFileEof(df->h)) { + if (BrFileEof(df->h) != 0) { break; } df->prims->struct_read(df, str, cp); @@ -526,7 +1083,12 @@ br_uint_32 DfStructReadArray(br_datafile* df, br_file_struct* str, void* base, i // IDA: int __usercall DfChunkWriteText@(br_datafile *df@, br_uint_32 id@, br_uint_32 length@) int DfChunkWriteText(br_datafile* df, br_uint_32 id, br_uint_32 length) { LOG_TRACE("(%p, %d, %d)", df, id, length); - NOT_IMPLEMENTED(); + + if (id < BR_ASIZE(ChunkNames)) { + BrFilePrintf(df->h, "*%-16s %d\n", ChunkNames[id], length); + } else { + BrFilePrintf(df->h, "*0x%08x %d\n", id, length); + } } // IDA: int __usercall DfChunkReadText@(br_datafile *df@, br_uint_32 *plength@) @@ -535,14 +1097,42 @@ int DfChunkReadText(br_datafile* df, br_uint_32* plength) { char* id; char* data; LOG_TRACE("(%p, %p)", df, plength); - NOT_IMPLEMENTED(); + + if (TextReadLine(df, &id, &data) == 0) { + return -1; + } + if (*id != '*') { + BrFailure("Chunk ID not found"); + } + id++; + if (*id == '0') { + i = BrStrToUL(id, NULL, 0); + } else { + for (i = 0; i < BR_ASIZE(ChunkNames); i++) { + if (BrStrCmp(ChunkNames[i], id) == 0) { + break; + } + } + if (i >= BR_ASIZE(ChunkNames)) { + BrFailure("Chunk ID not known: %s", id); + } + } + if (plength != NULL) { + *plength = BrStrToUL(data, NULL, 0); + } + return i; } // IDA: int __usercall DfChunkWriteBinary@(br_datafile *df@, br_uint_32 id@, br_uint_32 length@) int DfChunkWriteBinary(br_datafile* df, br_uint_32 id, br_uint_32 length) { br_uint_32 l; LOG_TRACE("(%p, %d, %d)", df, id, length); - NOT_IMPLEMENTED(); + + l = BrSwap32(id); + BrFileWrite(&l, sizeof(br_uint_32), 1, df->h); + l = BrSwap32(length); + BrFileWrite(&l, sizeof(br_uint_32), 1, df->h); + return 0; } // IDA: int __usercall DfChunkReadBinary@(br_datafile *df@, br_uint_32 *plength@) @@ -551,19 +1141,19 @@ int DfChunkReadBinary(br_datafile* df, br_uint_32* plength) { br_uint_32 l; LOG_TRACE9("(%p, %p)", df, plength); - if (BrFileEof(df->h)) { + if (BrFileEof(df->h) != 0) { return -1; } - BrFileRead(&id, 4, 1, df->h); - if (BrFileEof(df->h)) { + BrFileRead(&id, sizeof(br_uint_32), 1, df->h); + if (BrFileEof(df->h) != 0) { return -1; } id = BrSwap32(id); - BrFileRead(&l, 4, 1, df->h); - if (BrFileEof(df->h)) { + BrFileRead(&l, sizeof(br_uint_32), 1, df->h); + if (BrFileEof(df->h) != 0) { return -1; } - if (plength) { + if (plength != NULL) { *plength = BrSwap32(l); } return id; @@ -572,7 +1162,8 @@ int DfChunkReadBinary(br_datafile* df, br_uint_32* plength) { // IDA: void __usercall DfCountWriteText(br_datafile *df@, br_uint_32 count@) void DfCountWriteText(br_datafile* df, br_uint_32 count) { LOG_TRACE("(%p, %d)", df, count); - NOT_IMPLEMENTED(); + + BrFilePrintf(df->h, " count %d\n", count); } // IDA: br_uint_32 __usercall DfCountReadText@(br_datafile *df@) @@ -580,34 +1171,43 @@ br_uint_32 DfCountReadText(br_datafile* df) { char* id; char* data; LOG_TRACE("(%p)", df); - NOT_IMPLEMENTED(); + + TextReadLine(df, &id, &data); + if (BrStrCmp(id, "count") != 0) { + BrFailure("no element count for chunk"); + } + return BrStrToUL(data, NULL, 0); } // IDA: void __usercall DfCountWriteBinary(br_datafile *df@, br_uint_32 count@) void DfCountWriteBinary(br_datafile* df, br_uint_32 count) { br_uint_32 l; - LOG_TRACE("(%p, %d)", df, count); - NOT_IMPLEMENTED(); + + l = BrSwap32(count); + BrFileWrite(&l, sizeof(l), 1, df->h); } // IDA: br_uint_32 __usercall DfCountReadBinary@(br_datafile *df@) br_uint_32 DfCountReadBinary(br_datafile* df) { br_uint_32 l; LOG_TRACE9("(%p)", df); - BrFileRead(&l, 4, 1, df->h); + + BrFileRead(&l, sizeof(br_uint_32), 1, df->h); return BrSwap32(l); } // IDA: int __usercall DfCountSizeText@(br_datafile *df@) int DfCountSizeText(br_datafile* df) { LOG_TRACE("(%p)", df); - NOT_IMPLEMENTED(); + + return 1; } // IDA: int __usercall DfCountSizeBinary@(br_datafile *df@) int DfCountSizeBinary(br_datafile* df) { LOG_TRACE("(%p)", df); - NOT_IMPLEMENTED(); + + return sizeof(br_uint_32); } // IDA: br_uint_8* __usercall BlockWriteSetup@(void *base@, int block_size@, int block_stride@, int block_count@, int size) @@ -627,7 +1227,38 @@ int DfBlockWriteText(br_datafile* df, void* base, int block_size, int block_stri br_uint_8* block; int count; LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); - NOT_IMPLEMENTED(); + + if (block_stride == block_size) { + block_size = block_count * block_size; + block_count = 1; + } + block = base; + if ((size != 1) || (block_count != 1)) { + block = BrScratchAllocate(block_count * block_size * size); + for (count = 0; count < block_count; count++) { + BrMemCpy(block + count * block_size * size, (br_uint_8*)base + count * block_stride * size, block_size * size); + } + BrSwapBlock(block, block_count * block_size, size); + } + BrFilePrintf(df->h, " block %d\n", block_count * block_size); + BrFilePrintf(df->h, " size %d\n", size); + for (i = 0; i < block_count * block_size * size; i++) { + if ((i & 0x1f) == 0) { + BrFilePrintf(df->h, " %08x: %02x", i, block[i]); + } else { + BrFilePrintf(df->h, "%02x", block[i]); + } + if ((i & 0x1f) == 0x1f) { + BrFilePutChar('\n', df->h); + } + } + if ((i & 0x1f) != 0x1f) { + BrFilePutChar('\n', df->h); + } + if (block != base) { + BrScratchFree(block); + } + return 0; } // IDA: void* __usercall DfBlockReadText@(br_datafile *df@, void *base@, int *count@, int size@, int mtype) @@ -639,7 +1270,44 @@ void* DfBlockReadText(br_datafile* df, void* base, int* count, int size, int mty int a; char b[3]; LOG_TRACE("(%p, %p, %p, %d, %d)", df, base, count, size, mtype); - NOT_IMPLEMENTED(); + + TextReadLine(df, &id, &data); + if (BrStrCmp(id, "block") != 0) { + BrFailure("no block"); + } + l = BrStrToUL(data, NULL, 0); + TextReadLine(df, &id, &data); + if (BrStrCmp(id, "size") != 0) { + BrFailure("no size"); + } + s = BrStrToUL(data, NULL, 0); + if (s != size) { + BrFailure("block size mismatch"); + } + if (base == NULL) { + base = BrResAllocate(df->res ? df->res : fw.res, l * size, mtype); + } else { + if (*count < l) { + BrFailure("DfBlockReadText: block too long: %d", l); + } + } + *count = l; + for (a = 0; a < l * size;) { + TextReadLine(df, &id, &data); + if (a != BrStrToL(id, NULL, 16)) { + BrFailure("block address mismatch"); + } + while ((data[0] != '\0') && (data[1] != '\0')) { + b[0] = data[0]; + b[1] = data[1]; + b[2] = '\0'; + ((br_uint_8*)base)[a] = (br_uint_8)BrStrToUL(b, NULL, 16); + data += 2; + a++; + } + } + BrSwapBlock(base, l, size); + return base; } // IDA: int __usercall DfBlockWriteBinary@(br_datafile *df@, void *base@, int block_size@, int block_stride@, int block_count, int size) @@ -649,7 +1317,28 @@ int DfBlockWriteBinary(br_datafile* df, void* base, int block_size, int block_st br_uint_32 s; void* block; LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); - NOT_IMPLEMENTED(); + + l = BrSwap32(block_count * block_size); + s = BrSwap32(size); + if (block_stride == block_size) { + block_size = block_count * block_size; + block_count = 1; + } + block = base; + if ((size != 1) || (block_count != 1)) { + block = BrScratchAllocate(block_count * block_size * size); + for (count = 0; count < block_count; count++) { + BrMemCpy((br_uint_8*)block + count * block_size * size, (br_uint_8*)base + count * block_stride * size, block_size * size); + } + BrSwapBlock(block, block_count * block_size, size); + } + BrFileWrite(&l, sizeof(l), 1, df->h); + BrFileWrite(&s, sizeof(s), 1, df->h); + BrFileWrite(block, block_count * block_size, size, df->h); + if (block != base) { + BrScratchFree(block); + } + return 0; } // IDA: void* __usercall DfBlockReadBinary@(br_datafile *df@, void *base@, int *count@, int size@, int mtype) @@ -665,12 +1354,12 @@ void* DfBlockReadBinary(br_datafile* df, void* base, int* count, int size, int m if (s != size) { BrFailure("block size mismatch"); } - if (base) { + if (base != NULL) { if (l > *count) { BrFailure("DfBlockReadBinary: block too long: %d", l); } } else { - base = BrResAllocate(df->res ? df->res : fw.res, size * l, mtype); + base = BrResAllocate(df->res != NULL ? df->res : fw.res, size * l, mtype); } *count = l; BrFileRead(base, l, size, df->h); @@ -681,13 +1370,15 @@ void* DfBlockReadBinary(br_datafile* df, void* base, int* count, int size, int m // IDA: int __usercall DfBlockSizeText@(br_datafile *df@, void *base@, int block_size@, int block_stride@, int block_count, int size) int DfBlockSizeText(br_datafile* df, void* base, int block_size, int block_stride, int block_count, int size) { LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); - NOT_IMPLEMENTED(); + + return ((size * block_count * block_size + (32 - 1)) >> 5) + 2; } // IDA: int __usercall DfBlockSizeBinary@(br_datafile *df@, void *base@, int block_size@, int block_stride@, int block_count, int size) int DfBlockSizeBinary(br_datafile* df, void* base, int block_size, int block_stride, int block_count, int size) { LOG_TRACE("(%p, %p, %d, %d, %d, %d)", df, base, block_size, block_stride, block_count, size); - NOT_IMPLEMENTED(); + + return size * block_count * block_size + 8; } // IDA: char* __usercall DfNameReadText@(br_datafile *df@, char *name@) @@ -695,19 +1386,35 @@ char* DfNameReadText(br_datafile* df, char* name) { char* id; char* data; LOG_TRACE("(%p, \"%s\")", df, name); - NOT_IMPLEMENTED(); + + TextReadLine(df, &id, &data); + if (BrStrCmp(id, "name") != 0) { + BrFailure("no name"); + } + if ((data != NULL) && (*data == '\"')) { + BrStrNCpy(name, data + 1, 0xff); + name[0xff] = '\0'; + return data; + } + BrFailure("no name string"); } // IDA: int __usercall DfNameWriteText@(br_datafile *df@, char *name@) int DfNameWriteText(br_datafile* df, char* name) { LOG_TRACE("(%p, \"%s\")", df, name); - NOT_IMPLEMENTED(); + + if (name == NULL) { + name = "NULL"; + } + BrFilePrintf(df->h, " name \"%s\"\n", name); + return 0; } // IDA: int __usercall DfNameSizeText@(br_datafile *df@, char *name@) int DfNameSizeText(br_datafile* df, char* name) { LOG_TRACE("(%p, \"%s\")", df, name); - NOT_IMPLEMENTED(); + + return 1; } // IDA: char* __usercall DfNameReadBinary@(br_datafile *df@, char *name@) @@ -718,10 +1425,7 @@ char* DfNameReadBinary(br_datafile* df, char* name) { for (i = 0; i < 255; i++) { c = BrFileGetChar(df->h); - if (!c) { - break; - } - if (c == -1) { + if ((c == 0) || (c == -1)) { break; } name[i] = c; @@ -733,13 +1437,22 @@ char* DfNameReadBinary(br_datafile* df, char* name) { // IDA: int __usercall DfNameWriteBinary@(br_datafile *df@, char *name@) int DfNameWriteBinary(br_datafile* df, char* name) { LOG_TRACE("(%p, \"%s\")", df, name); - NOT_IMPLEMENTED(); + + if (name != NULL) { + BrFileWrite(name, 1, BrStrLen(name), df->h); + } + BrFilePutChar('\0', df->h); + return 0; } // IDA: int __usercall DfNameSizeBinary@(br_datafile *df@, char *name@) int DfNameSizeBinary(br_datafile* df, char* name) { LOG_TRACE("(%p, \"%s\")", df, name); - NOT_IMPLEMENTED(); + + if (name != NULL) { + return BrStrLen(name) + 1; + } + return 1; } // IDA: int __usercall DfSkipText@(br_datafile *df@, br_uint_32 length@) @@ -747,7 +1460,11 @@ int DfSkipText(br_datafile* df, br_uint_32 length) { char* id; char* data; LOG_TRACE("(%p, %d)", df, length); - NOT_IMPLEMENTED(); + + while ((BrFileEof(df->h) == 0) && (length != 0)) { + TextReadLine(df, &data, &id); + } + return 0; } // IDA: int __usercall DfSkipBinary@(br_datafile *df@, br_uint_32 length@) @@ -769,7 +1486,7 @@ int DfChunksInterpret(br_datafile* df, br_chunks_table* table) { while (1) { id = df->prims->chunk_read(df, &length); //LOG_DEBUG("chunk id=%d, len=%d", id, length); - if (id == -1) { + if (id == (br_uint_32)-1) { break; } for (i = 0; i < table->nentries; i++) { @@ -780,13 +1497,13 @@ int DfChunksInterpret(br_datafile* df, br_chunks_table* table) { if (i >= table->nentries) { df->prims->skip(df, length); } else { - if (table->entries[i].has_count) { + if (table->entries[i].has_count != 0) { count = df->prims->count_read(df); } else { count = 0; } r = table->entries[i].handler(df, id, length, count); - if (r) { + if (r != 0) { return r; } } @@ -797,7 +1514,9 @@ int DfChunksInterpret(br_datafile* df, br_chunks_table* table) { // IDA: void __cdecl BrNullOther() void BrNullOther() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + // Yes, "invalid" is misspelled. + BrFatal("datafile.c", 1825, "Invald file primitive call"); } // IDA: int __cdecl DfFileIdentify(br_uint_8 *magics, br_size_t n_magics) @@ -806,13 +1525,13 @@ int DfFileIdentify(br_uint_8* magics, br_size_t n_magics) { static char binary_magics[8] = { '\0', '\0', '\0', '\x12', '\0', '\0', '\0', '\b' }; if (BrMemCmp(magics, text_magics, sizeof(magics)) == 0) { - return 1; + return BR_FS_MODE_TEXT; } if (BrMemCmp(magics, binary_magics, sizeof(magics)) == 0) { - return 0; + return BR_FS_MODE_BINARY; } LOG_WARN("file does not match magics"); - return 2; + return BR_FS_MODE_UNKNOWN; } // IDA: br_datafile* __usercall DfOpen@(char *name@, int write@, br_token scalar_type@) @@ -823,33 +1542,34 @@ br_datafile* DfOpen(char* name, int write, br_token scalar_type) { void* h; LOG_TRACE9("(\"%s\", %d, %d)", name, write, scalar_type); - if (write) { + mode = fw.open_mode; + if (write != 0) { h = BrFileOpenWrite(name, fw.open_mode); } else { h = BrFileOpenRead(name, 8u, DfFileIdentify, &mode); } - if (!h) { - LOG_WARN("returning 0"); - return 0; + if (h == NULL) { + LOG_WARN("returning NULL"); + return NULL; } df = BrResAllocate(fw.res, sizeof(br_datafile), BR_MEMORY_DATAFILE); df->prims = &_BrFilePrimsNull; df->h = h; df->scalar_type = scalar_type; - if (mode == 0) { - if (write) { + if (mode == BR_FS_MODE_BINARY) { + if (write != 0) { df->prims = &_BrFilePrimsWriteBinary; } else { df->prims = &_BrFilePrimsReadBinary; } } else { - if (write) + if (write != 0) df->prims = &_BrFilePrimsWriteText; else df->prims = &_BrFilePrimsReadText; } - DfPush(BR_MEMORY_FILE, df, 1); + DfPush(BR_MEMORY_FILE, df, 1); // Wrong enum -> should be DF_STACK_FILE (see comment in src/BRSRC13/CORE/V1DB/v1dbfile.c) return df; } @@ -877,5 +1597,8 @@ void DfClose(br_datafile* df) { int BrWriteModeSet(int mode) { int old; LOG_TRACE("(%d)", mode); - NOT_IMPLEMENTED(); + + old = fw.open_mode; + fw.open_mode = mode; + return old; } diff --git a/src/BRSRC13/CORE/FW/datafile.h b/src/BRSRC13/CORE/FW/datafile.h index 61c8ce54..edec36cd 100644 --- a/src/BRSRC13/CORE/FW/datafile.h +++ b/src/BRSRC13/CORE/FW/datafile.h @@ -3,6 +3,107 @@ #include "brender/br_types.h" +// The names of these enum values are a wild guess +enum { + DF_TYPE_BR_INT_8 = 0, + DF_TYPE_BR_UINT_8 = 1, + DF_TYPE_BR_INT_16 = 2, + DF_TYPE_BR_UINT_16 = 3, + DF_TYPE_BR_INT_32 = 4, + DF_TYPE_BR_UINT_32 = 5, + DF_TYPE_BR_FIXED = 6, + DF_TYPE_BR_ANGLE = 7, + DF_TYPE_FLOAT = 8, + DF_TYPE_DOUBLE = 9, + DF_TYPE_BR_SCALAR = 10, + DF_TYPE_BR_FRACTION = 11, + DF_TYPE_BR_UFRACTION = 12, + DF_TYPE_ENUM_8 = 13, + DF_TYPE_ENUM_16 = 14, + DF_TYPE_ENUM_32 = 15, + DF_TYPE_STRUCT = 16, + DF_TYPE_ASCIZ = 17, + DF_TYPE_BR_COLOUR = 18, + DF_TYPE_BR_VECTOR2 = 19, + DF_TYPE_BR_VECTOR3 = 20, + DF_TYPE_BR_VECTOR4 = 21, + DF_TYPE_BR_FRACTION_X = 22, + DF_TYPE_BR_UFRACTION_X = 23, + DF_TYPE_BR_FRACTION_F = 24, + DF_TYPE_BR_UFRACTION_F = 25, + DF_TYPE_BR_VECTOR2_X = 26, + DF_TYPE_BR_VECTOR3_X = 27, + DF_TYPE_BR_VECTOR4_X = 28, + DF_TYPE_BR_VECTOR2_F = 29, + DF_TYPE_BR_VECTOR3_F = 30, + DF_TYPE_BR_VECTOR4_F = 31, + DF_TYPE_COUNT, +}; + +enum { + DF_CHUNKID_END = 0, + DF_CHUNKID_IMAGE_PLANE = 1, + DF_CHUNKID_RLE_IMAGE_PLANE = 2, + DF_CHUNKID_PIXELMAP = 3, + DF_CHUNKID_MATERIAL_OLD = 4, + DF_CHUNKID_ADD_MATERIAL = 5, + DF_CHUNKID_OLD_ACTOR = 6, + DF_CHUNKID_OLD_ADD_SIBLING = 7, + DF_CHUNKID_OLD_ADD_CHILD = 8, + DF_CHUNKID_OLD_MATERIAL_INDEX = 9, + DF_CHUNKID_OLD_VERTICES = 10, + DF_CHUNKID_OLD_VERTICES_UV = 11, + DF_CHUNKID_OLD_FACES = 12, + DF_CHUNKID_OLD_MODEL = 13, + DF_CHUNKID_ADD_MODEL = 14, + DF_CHUNKID_ANIM = 15, + DF_CHUNKID_ANIM_TRANSFORM = 16, + DF_CHUNKID_ANIM_RATE = 17, + DF_CHUNKID_FILE_INFO = 18, + DF_CHUNKID_OLD_LIGHT = 19, + DF_CHUNKID_OLD_CAMERA = 20, + DF_CHUNKID_PIVOT = 21, + DF_CHUNKID_MATERIAL_INDEX = 22, + DF_CHUNKID_VERTICES = 23, + DF_CHUNKID_VERTEX_UV = 24, + DF_CHUNKID_OLD_FACES_1 = 25, + DF_CHUNKID_FACE_MATERIAL = 26, + DF_CHUNKID_OLD_MODEL_1 = 27, + DF_CHUNKID_COLOUR_MAP_REF = 28, + DF_CHUNKID_OPACITY_MAP_REF = 29, + DF_CHUNKID_INDEX_BLEND_REF = 30, + DF_CHUNKID_INDEX_SHADE_REF = 31, + DF_CHUNKID_SCREENDOOR_REF = 32, + DF_CHUNKID_PIXELS = 33, + DF_CHUNKID_ADD_MAP = 34, + DF_CHUNKID_ACTOR = 35, + DF_CHUNKID_ACTOR_MODEL = 36, + DF_CHUNKID_ACTOR_TRANSFORM = 37, + DF_CHUNKID_ACTOR_MATERIAL = 38, + DF_CHUNKID_ACTOR_LIGHT = 39, + DF_CHUNKID_ACTOR_CAMERA = 40, + DF_CHUNKID_ACTOR_BOUNDS = 41, + DF_CHUNKID_ACTOR_ADD_CHILD = 42, + DF_CHUNKID_TRANSFORM_MATRIX34 = 43, + DF_CHUNKID_TRANSFORM_MATRIX34_LP = 44, + DF_CHUNKID_TRANSFORM_QUAT = 45, + DF_CHUNKID_TRANSFORM_EULER = 46, + DF_CHUNKID_TRANSFORM_LOOK_UP = 47, + DF_CHUNKID_TRANSFORM_TRANSLATION = 48, + DF_CHUNKID_TRANSFORM_IDENTITY = 49, + DF_CHUNKID_BOUNDS = 50, + DF_CHUNKID_LIGHT = 51, + DF_CHUNKID_CAMERA = 52, + DF_CHUNKID_FACES = 53, + DF_CHUNKID_MODEL = 54, + DF_CHUNKID_ACTOR_CLIP_PLANE = 55, + DF_CHUNKID_PLANE = 56, + DF_CHUNKID_SATURN_FACES = 57, + DF_CHUNKID_SATURN_MODEL = 58, + DF_CHUNKID_INDEX_FOG_REF = 59, + DF_CHUNKID_MATERIAL_OLD_2 = 60, +}; + void DfPush(int type, void* value, int count); void* DfPop(int type, int* countp); diff --git a/src/BRSRC13/CORE/FW/file.c b/src/BRSRC13/CORE/FW/file.c index dc7af08c..d27d4296 100644 --- a/src/BRSRC13/CORE/FW/file.c +++ b/src/BRSRC13/CORE/FW/file.c @@ -1,4 +1,5 @@ #include "file.h" +#include "scratch.h" #include "CORE/FW/fwsetup.h" #include "CORE/FW/resource.h" #include "CORE/STD/brstdlib.h" @@ -114,6 +115,10 @@ void BrFileAdvance(long count, void* f) { int BrFilePrintf(void* f, char* fmt, ...) { int n; va_list args; - LOG_TRACE("(%p, \"%s\")", f, fmt); - NOT_IMPLEMENTED(); + LOG_TRACE9("(%p, \"%s\")", f, fmt); + + va_start(args, fmt); + n = BrVSprintf(BrScratchString(), fmt, args); + va_end(args); + return BrFileWrite(BrScratchString(), 1, n, f); } diff --git a/src/BRSRC13/CORE/FW/scratch.c b/src/BRSRC13/CORE/FW/scratch.c index df5a08a5..1ae0a4f4 100644 --- a/src/BRSRC13/CORE/FW/scratch.c +++ b/src/BRSRC13/CORE/FW/scratch.c @@ -4,22 +4,22 @@ #include "harness/trace.h" #include "resource.h" -char scratchString[512]; +char scratchString[512] = "SCRATCH"; // IDA: void* __cdecl BrScratchAllocate(br_size_t size) void* BrScratchAllocate(br_size_t size) { LOG_TRACE("(%d)", size); - if (fw.scratch_inuse) + if (fw.scratch_inuse != 0) { BrFailure("Scratchpad not available"); + } fw.scratch_last = size; if (size > fw.scratch_size) { - - if (fw.scratch_ptr) + if (fw.scratch_ptr != NULL) { BrResFree(fw.scratch_ptr); - + } fw.scratch_ptr = BrResAllocate(fw.res, size, BR_MEMORY_SCRATCH); fw.scratch_size = size; } @@ -30,29 +30,41 @@ void* BrScratchAllocate(br_size_t size) { // IDA: void __cdecl BrScratchFree(void *scratch) void BrScratchFree(void* scratch) { LOG_TRACE("(%p)", scratch); + fw.scratch_inuse = 0; } // IDA: void __cdecl BrScratchFlush() void BrScratchFlush() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + if (fw.scratch_inuse != 0) { + BrFailure("Scratchpad cannot be flushed while in use"); + } + if (fw.scratch_ptr != NULL) { + BrResFree(fw.scratch_ptr); + } + fw.scratch_ptr = NULL; + fw.scratch_size = 0; } // IDA: br_size_t __cdecl BrScratchInquire() br_size_t BrScratchInquire() { LOG_TRACE("()"); - NOT_IMPLEMENTED(); + + return fw.scratch_size; } // IDA: char* __cdecl BrScratchString() char* BrScratchString() { - LOG_TRACE("()"); - NOT_IMPLEMENTED(); + LOG_TRACE9("()"); + + return scratchString; } // IDA: br_size_t __cdecl BrScratchStringSize() br_size_t BrScratchStringSize() { - LOG_TRACE("()"); - NOT_IMPLEMENTED(); + LOG_TRACE9("()"); + + return sizeof(scratchString); } diff --git a/src/BRSRC13/CORE/MATH/fixed.c b/src/BRSRC13/CORE/MATH/fixed.c new file mode 100644 index 00000000..0ade25bc --- /dev/null +++ b/src/BRSRC13/CORE/MATH/fixed.c @@ -0,0 +1,661 @@ +#include "fixed.h" +#include "harness/trace.h" + +#include + +#define fixed_cos_table ((unsigned short*)&fixed_sin_table[64]) + +static unsigned short fixed_sin_table[] = { + // start sin table + 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c7, 0x15e1, + 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2527, 0x2826, 0x2b1e, 0x2e10, + 0x30fb, 0x33de, 0x36b9, 0x398c, 0x3c56, 0x3f16, 0x41cd, 0x447a, + 0x471c, 0x49b3, 0x4c3f, 0x4ebf, 0x5133, 0x539a, 0x55f4, 0x5842, + 0x5a81, 0x5cb3, 0x5ed6, 0x60eb, 0x62f1, 0x64e7, 0x66ce, 0x68a5, + 0x6a6c, 0x6c23, 0x6dc9, 0x6f5e, 0x70e1, 0x7254, 0x73b5, 0x7503, + 0x7640, 0x776b, 0x7883, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce2, + 0x7d89, 0x7e1c, 0x7e9c, 0x7f08, 0x7f61, 0x7fa6, 0x7fd7, 0x7ff5, + // start cos table + 0x7fff, 0x7ff5, 0x7fd7, 0x7fa6, 0x7f61, 0x7f08, 0x7e9c, 0x7e1c, + 0x7d89, 0x7ce2, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7883, 0x776b, + 0x7640, 0x7503, 0x73b5, 0x7254, 0x70e1, 0x6f5e, 0x6dc9, 0x6c23, + 0x6a6c, 0x68a5, 0x66ce, 0x64e7, 0x62f1, 0x60eb, 0x5ed6, 0x5cb3, + 0x5a81, 0x5842, 0x55f4, 0x539a, 0x5133, 0x4ebf, 0x4c3f, 0x49b3, + 0x471c, 0x447a, 0x41cd, 0x3f16, 0x3c56, 0x398c, 0x36b9, 0x33de, + 0x30fb, 0x2e10, 0x2b1e, 0x2826, 0x2527, 0x2223, 0x1f19, 0x1c0b, + 0x18f8, 0x15e1, 0x12c7, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, + 0x0000, 0xfcdc, 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed39, 0xea1f, + 0xe708, 0xe3f5, 0xe0e7, 0xdddd, 0xdad9, 0xd7da, 0xd4e2, 0xd1f0, + 0xcf05, 0xcc22, 0xc947, 0xc674, 0xc3aa, 0xc0ea, 0xbe33, 0xbb86, + 0xb8e4, 0xb64d, 0xb3c1, 0xb141, 0xaecd, 0xac66, 0xaa0c, 0xa7be, + 0xa57f, 0xa34d, 0xa12a, 0x9f15, 0x9d0f, 0x9b19, 0x9932, 0x975b, + 0x9594, 0x93dd, 0x9237, 0x90a2, 0x8f1f, 0x8dac, 0x8c4b, 0x8afd, + 0x89c0, 0x8895, 0x877d, 0x8677, 0x8584, 0x84a4, 0x83d7, 0x831e, + 0x8277, 0x81e4, 0x8164, 0x80f8, 0x809f, 0x805a, 0x8029, 0x800b, + 0x8001, 0x800b, 0x8029, 0x805a, 0x809f, 0x80f8, 0x8164, 0x81e4, + 0x8277, 0x831e, 0x83d7, 0x84a4, 0x8584, 0x8677, 0x877d, 0x8895, + 0x89c0, 0x8afd, 0x8c4b, 0x8dac, 0x8f1f, 0x90a2, 0x9237, 0x93dd, + 0x9594, 0x975b, 0x9932, 0x9b19, 0x9d0f, 0x9f15, 0xa12a, 0xa34d, + 0xa57f, 0xa7be, 0xaa0c, 0xac66, 0xaecd, 0xb141, 0xb3c1, 0xb64d, + 0xb8e4, 0xbb86, 0xbe33, 0xc0ea, 0xc3aa, 0xc674, 0xc947, 0xcc22, + 0xcf05, 0xd1f0, 0xd4e2, 0xd7da, 0xdad9, 0xdddd, 0xe0e7, 0xe3f5, + 0xe708, 0xea1f, 0xed39, 0xf055, 0xf375, 0xf696, 0xf9b9, 0xfcdc, + 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c7, 0x15e1, + 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2527, 0x2826, 0x2b1e, 0x2e10, + 0x30fb, 0x33de, 0x36b9, 0x398c, 0x3c56, 0x3f16, 0x41cd, 0x447a, + 0x471c, 0x49b3, 0x4c3f, 0x4ebf, 0x5133, 0x539a, 0x55f4, 0x5842, + 0x5a81, 0x5cb3, 0x5ed6, 0x60eb, 0x62f1, 0x64e7, 0x66ce, 0x68a5, + 0x6a6c, 0x6c23, 0x6dc9, 0x6f5e, 0x70e1, 0x7254, 0x73b5, 0x7503, + 0x7640, 0x776b, 0x7883, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce2, + 0x7d89, 0x7e1c, 0x7e9c, 0x7f08, 0x7f61, 0x7fa6, 0x7fd7, 0x7ff5, + 0x7fff, 0x7fff, +}; + +static unsigned short fixed_asin_table[] = { + 0xc001, 0xc519, 0xc737, 0xc8d7, 0xca37, 0xcb6d, 0xcc87, 0xcd8a, + 0xce7c, 0xcf5f, 0xd037, 0xd104, 0xd1c9, 0xd286, 0xd33c, 0xd3ed, + 0xd498, 0xd53e, 0xd5df, 0xd67c, 0xd716, 0xd7ac, 0xd83f, 0xd8cf, + 0xd95c, 0xd9e7, 0xda6f, 0xdaf4, 0xdb78, 0xdbf9, 0xdc79, 0xdcf7, + 0xdd73, 0xdded, 0xde66, 0xdedd, 0xdf53, 0xdfc8, 0xe03b, 0xe0ad, + 0xe11e, 0xe18d, 0xe1fc, 0xe26a, 0xe2d6, 0xe342, 0xe3ac, 0xe416, + 0xe47f, 0xe4e7, 0xe54e, 0xe5b4, 0xe61a, 0xe67f, 0xe6e3, 0xe746, + 0xe7a9, 0xe80c, 0xe86d, 0xe8ce, 0xe92f, 0xe98f, 0xe9ee, 0xea4d, + 0xeaab, 0xeb09, 0xeb66, 0xebc3, 0xec20, 0xec7c, 0xecd7, 0xed33, + 0xed8d, 0xede8, 0xee42, 0xee9c, 0xeef5, 0xef4e, 0xefa7, 0xefff, + 0xf057, 0xf0af, 0xf106, 0xf15d, 0xf1b4, 0xf20b, 0xf261, 0xf2b8, + 0xf30d, 0xf363, 0xf3b9, 0xf40e, 0xf463, 0xf4b8, 0xf50c, 0xf561, + 0xf5b5, 0xf609, 0xf65d, 0xf6b1, 0xf704, 0xf758, 0xf7ab, 0xf7fe, + 0xf851, 0xf8a4, 0xf8f7, 0xf949, 0xf99c, 0xf9ee, 0xfa41, 0xfa93, + 0xfae5, 0xfb37, 0xfb89, 0xfbdb, 0xfc2d, 0xfc7f, 0xfcd1, 0xfd23, + 0xfd74, 0xfdc6, 0xfe17, 0xfe69, 0xfeba, 0xff0c, 0xff5e, 0xffaf, + 0x0000, 0x0051, 0x00a2, 0x00f4, 0x0146, 0x0197, 0x01e9, 0x023a, + 0x028c, 0x02dd, 0x032f, 0x0381, 0x03d3, 0x0425, 0x0477, 0x04c9, + 0x051b, 0x056d, 0x05bf, 0x0612, 0x0664, 0x06b7, 0x0709, 0x075c, + 0x07af, 0x0802, 0x0855, 0x08a8, 0x08fc, 0x094f, 0x09a3, 0x09f7, + 0x0a4b, 0x0a9f, 0x0af4, 0x0b48, 0x0b9d, 0x0bf2, 0x0c47, 0x0c9d, + 0x0cf3, 0x0d48, 0x0d9f, 0x0df5, 0x0e4c, 0x0ea3, 0x0efa, 0x0f51, + 0x0fa9, 0x1001, 0x1059, 0x10b2, 0x110b, 0x1164, 0x11be, 0x1218, + 0x1273, 0x12cd, 0x1329, 0x1384, 0x13e0, 0x143d, 0x149a, 0x14f7, + 0x1555, 0x15b3, 0x1612, 0x1671, 0x16d1, 0x1732, 0x1793, 0x17f4, + 0x1857, 0x18ba, 0x191d, 0x1981, 0x19e6, 0x1a4c, 0x1ab2, 0x1b19, + 0x1b81, 0x1bea, 0x1c54, 0x1cbe, 0x1d2a, 0x1d96, 0x1e04, 0x1e73, + 0x1ee2, 0x1f53, 0x1fc5, 0x2038, 0x20ad, 0x2123, 0x219a, 0x2213, + 0x228d, 0x2309, 0x2387, 0x2407, 0x2488, 0x250c, 0x2591, 0x2619, + 0x26a4, 0x2731, 0x27c1, 0x2854, 0x28ea, 0x2984, 0x2a21, 0x2ac2, + 0x2b68, 0x2c13, 0x2cc4, 0x2d7a, 0x2e37, 0x2efc, 0x2fc9, 0x30a1, + 0x3184, 0x3276, 0x3379, 0x3493, 0x35c9, 0x3729, 0x38c9, 0x3ae7, + 0x4000, +}; + +static unsigned short fixed_acos_table[] = { + 0x7fff, 0x7ae7, 0x78c9, 0x7729, 0x75c9, 0x7493, 0x7379, 0x7276, + 0x7184, 0x70a1, 0x6fc9, 0x6efc, 0x6e37, 0x6d7a, 0x6cc4, 0x6c13, + 0x6b68, 0x6ac2, 0x6a21, 0x6984, 0x68ea, 0x6854, 0x67c1, 0x6731, + 0x66a4, 0x6619, 0x6591, 0x650c, 0x6488, 0x6407, 0x6387, 0x6309, + 0x628d, 0x6213, 0x619a, 0x6123, 0x60ad, 0x6038, 0x5fc5, 0x5f53, + 0x5ee2, 0x5e73, 0x5e04, 0x5d96, 0x5d2a, 0x5cbe, 0x5c54, 0x5bea, + 0x5b81, 0x5b19, 0x5ab2, 0x5a4c, 0x59e6, 0x5981, 0x591d, 0x58ba, + 0x5857, 0x57f4, 0x5793, 0x5732, 0x56d1, 0x5671, 0x5612, 0x55b3, + 0x5555, 0x54f7, 0x549a, 0x543d, 0x53e0, 0x5384, 0x5329, 0x52cd, + 0x5273, 0x5218, 0x51be, 0x5164, 0x510b, 0x50b2, 0x5059, 0x5001, + 0x4fa9, 0x4f51, 0x4efa, 0x4ea3, 0x4e4c, 0x4df5, 0x4d9f, 0x4d48, + 0x4cf3, 0x4c9d, 0x4c47, 0x4bf2, 0x4b9d, 0x4b48, 0x4af4, 0x4a9f, + 0x4a4b, 0x49f7, 0x49a3, 0x494f, 0x48fc, 0x48a8, 0x4855, 0x4802, + 0x47af, 0x475c, 0x4709, 0x46b7, 0x4664, 0x4612, 0x45bf, 0x456d, + 0x451b, 0x44c9, 0x4477, 0x4425, 0x43d3, 0x4381, 0x432f, 0x42dd, + 0x428c, 0x423a, 0x41e9, 0x4197, 0x4146, 0x40f4, 0x40a2, 0x4051, + 0x3fff, 0x3fae, 0x3f5d, 0x3f0b, 0x3eb9, 0x3e68, 0x3e16, 0x3dc5, + 0x3d73, 0x3d22, 0x3cd0, 0x3c7e, 0x3c2c, 0x3bda, 0x3b88, 0x3b36, + 0x3ae4, 0x3a92, 0x3a40, 0x39ed, 0x399b, 0x3948, 0x38f6, 0x38a3, + 0x3850, 0x37fd, 0x37aa, 0x3757, 0x3703, 0x36b0, 0x365c, 0x3608, + 0x35b4, 0x3560, 0x350b, 0x34b7, 0x3462, 0x340d, 0x33b8, 0x3362, + 0x330c, 0x32b7, 0x3260, 0x320a, 0x31b3, 0x315c, 0x3105, 0x30ae, + 0x3056, 0x2ffe, 0x2fa6, 0x2f4d, 0x2ef4, 0x2e9b, 0x2e41, 0x2de7, + 0x2d8c, 0x2d32, 0x2cd6, 0x2c7b, 0x2c1f, 0x2bc2, 0x2b65, 0x2b08, + 0x2aaa, 0x2a4c, 0x29ed, 0x298e, 0x292e, 0x28cd, 0x286c, 0x280b, + 0x27a8, 0x2745, 0x26e2, 0x267e, 0x2619, 0x25b3, 0x254d, 0x24e6, + 0x247e, 0x2415, 0x23ab, 0x2341, 0x22d5, 0x2269, 0x21fb, 0x218c, + 0x211d, 0x20ac, 0x203a, 0x1fc7, 0x1f52, 0x1edc, 0x1e65, 0x1dec, + 0x1d72, 0x1cf6, 0x1c78, 0x1bf8, 0x1b77, 0x1af3, 0x1a6e, 0x19e6, + 0x195b, 0x18ce, 0x183e, 0x17ab, 0x1715, 0x167b, 0x15de, 0x153d, + 0x1497, 0x13ec, 0x133b, 0x1285, 0x11c8, 0x1103, 0x1036, 0x0f5e, + 0x0e7b, 0x0d89, 0x0c86, 0x0b6c, 0x0a36, 0x08d6, 0x0736, 0x0518, + 0x0000, +}; + +static unsigned short fixed_atan_table[] = { + 0x0000, 0x0028, 0x0051, 0x007a, 0x00a2, 0x00cb, 0x00f4, 0x011d, + 0x0145, 0x016e, 0x0197, 0x01bf, 0x01e8, 0x0211, 0x0239, 0x0262, + 0x028b, 0x02b3, 0x02dc, 0x0304, 0x032d, 0x0355, 0x037e, 0x03a6, + 0x03ce, 0x03f7, 0x041f, 0x0448, 0x0470, 0x0498, 0x04c0, 0x04e8, + 0x0511, 0x0539, 0x0561, 0x0589, 0x05b1, 0x05d9, 0x0601, 0x0628, + 0x0650, 0x0678, 0x06a0, 0x06c7, 0x06ef, 0x0716, 0x073e, 0x0765, + 0x078d, 0x07b4, 0x07db, 0x0803, 0x082a, 0x0851, 0x0878, 0x089f, + 0x08c6, 0x08ed, 0x0913, 0x093a, 0x0961, 0x0987, 0x09ae, 0x09d4, + 0x09fb, 0x0a21, 0x0a47, 0x0a6d, 0x0a94, 0x0aba, 0x0ae0, 0x0b05, + 0x0b2b, 0x0b51, 0x0b77, 0x0b9c, 0x0bc2, 0x0be7, 0x0c0c, 0x0c32, + 0x0c57, 0x0c7c, 0x0ca1, 0x0cc6, 0x0ceb, 0x0d0f, 0x0d34, 0x0d58, + 0x0d7d, 0x0da1, 0x0dc6, 0x0dea, 0x0e0e, 0x0e32, 0x0e56, 0x0e7a, + 0x0e9e, 0x0ec1, 0x0ee5, 0x0f08, 0x0f2c, 0x0f4f, 0x0f72, 0x0f95, + 0x0fb8, 0x0fdb, 0x0ffe, 0x1021, 0x1044, 0x1066, 0x1089, 0x10ab, + 0x10cd, 0x10ef, 0x1111, 0x1133, 0x1155, 0x1177, 0x1199, 0x11ba, + 0x11dc, 0x11fd, 0x121e, 0x123f, 0x1260, 0x1281, 0x12a2, 0x12c3, + 0x12e4, 0x1304, 0x1325, 0x1345, 0x1365, 0x1385, 0x13a5, 0x13c5, + 0x13e5, 0x1405, 0x1424, 0x1444, 0x1463, 0x1483, 0x14a2, 0x14c1, + 0x14e0, 0x14ff, 0x151e, 0x153c, 0x155b, 0x1579, 0x1598, 0x15b6, + 0x15d4, 0x15f2, 0x1610, 0x162e, 0x164c, 0x166a, 0x1687, 0x16a5, + 0x16c2, 0x16df, 0x16fc, 0x1719, 0x1736, 0x1753, 0x1770, 0x178c, + 0x17a9, 0x17c5, 0x17e2, 0x17fe, 0x181a, 0x1836, 0x1852, 0x186e, + 0x188a, 0x18a5, 0x18c1, 0x18dc, 0x18f7, 0x1913, 0x192e, 0x1949, + 0x1964, 0x197f, 0x1999, 0x19b4, 0x19ce, 0x19e9, 0x1a03, 0x1a1d, + 0x1a37, 0x1a51, 0x1a6b, 0x1a85, 0x1a9f, 0x1ab9, 0x1ad2, 0x1aec, + 0x1b05, 0x1b1e, 0x1b37, 0x1b50, 0x1b69, 0x1b82, 0x1b9b, 0x1bb4, + 0x1bcc, 0x1be5, 0x1bfd, 0x1c16, 0x1c2e, 0x1c46, 0x1c5e, 0x1c76, + 0x1c8e, 0x1ca5, 0x1cbd, 0x1cd5, 0x1cec, 0x1d04, 0x1d1b, 0x1d32, + 0x1d49, 0x1d60, 0x1d77, 0x1d8e, 0x1da5, 0x1dbb, 0x1dd2, 0x1de9, + 0x1dff, 0x1e15, 0x1e2c, 0x1e42, 0x1e58, 0x1e6e, 0x1e84, 0x1e99, + 0x1eaf, 0x1ec5, 0x1eda, 0x1ef0, 0x1f05, 0x1f1b, 0x1f30, 0x1f45, + 0x1f5a, 0x1f6f, 0x1f84, 0x1f99, 0x1fad, 0x1fc2, 0x1fd7, 0x1feb, + 0x2000, +}; + +static uint16_t fast_sqrt_table[] = { + 0x8000, 0x80ff, 0x81fc, 0x82f7, 0x83f0, 0x84e7, 0x85dd, 0x86d1, + 0x87c3, 0x88b4, 0x89a3, 0x8a90, 0x8b7c, 0x8c66, 0x8d4e, 0x8e36, + 0x8f1b, 0x9000, 0x90e2, 0x91c4, 0x92a4, 0x9383, 0x9460, 0x953c, + 0x9617, 0x96f1, 0x97ca, 0x98a1, 0x9977, 0x9a4c, 0x9b20, 0x9bf2, + 0x9cc4, 0x9d94, 0x9e64, 0x9f32, 0xa000, 0xa0cc, 0xa197, 0xa261, + 0xa32b, 0xa3f3, 0xa4ba, 0xa581, 0xa646, 0xa70b, 0xa7cf, 0xa892, + 0xa953, 0xaa15, 0xaad5, 0xab94, 0xac53, 0xad11, 0xadcd, 0xae8a, + 0xaf45, 0xb000, 0xb0b9, 0xb172, 0xb22b, 0xb2e2, 0xb399, 0xb44f, + 0xb504, 0xb5b9, 0xb66d, 0xb720, 0xb7d3, 0xb885, 0xb936, 0xb9e7, + 0xba97, 0xbb46, 0xbbf5, 0xbca3, 0xbd50, 0xbdfd, 0xbea9, 0xbf55, + 0xc000, 0xc0aa, 0xc154, 0xc1fd, 0xc2a5, 0xc34e, 0xc3f5, 0xc49c, + 0xc542, 0xc5e8, 0xc68e, 0xc732, 0xc7d7, 0xc87a, 0xc91d, 0xc9c0, + 0xca62, 0xcb04, 0xcba5, 0xcc46, 0xcce6, 0xcd86, 0xce25, 0xcec3, + 0xcf62, 0xd000, 0xd09d, 0xd13a, 0xd1d6, 0xd272, 0xd30d, 0xd3a8, + 0xd443, 0xd4dd, 0xd577, 0xd610, 0xd6a9, 0xd742, 0xd7da, 0xd871, + 0xd908, 0xd99f, 0xda35, 0xdacb, 0xdb61, 0xdbf6, 0xdc8b, 0xdd1f, + 0xddb3, 0xde47, 0xdeda, 0xdf6d, 0xe000, 0xe092, 0xe123, 0xe1b5, + 0xe246, 0xe2d6, 0xe367, 0xe3f7, 0xe486, 0xe515, 0xe5a4, 0xe633, + 0xe6c1, 0xe74f, 0xe7dc, 0xe869, 0xe8f6, 0xe983, 0xea0f, 0xea9b, + 0xeb26, 0xebb1, 0xec3c, 0xecc7, 0xed51, 0xeddb, 0xee65, 0xeeee, + 0xef77, 0xf000, 0xf088, 0xf110, 0xf198, 0xf21f, 0xf2a6, 0xf32d, + 0xf3b4, 0xf43a, 0xf4c0, 0xf546, 0xf5cb, 0xf651, 0xf6d6, 0xf75a, + 0xf7de, 0xf863, 0xf8e6, 0xf96a, 0xf9ed, 0xfa70, 0xfaf3, 0xfb75, + 0xfbf7, 0xfc79, 0xfcfb, 0xfd7c, 0xfdfd, 0xfe7e, 0xfeff, 0xff7f, +}; + +static uint16_t fast_rsqrt_table[] = { + 0xffff, 0xfe05, 0xfc17, 0xfa33, 0xf85b, 0xf68c, 0xf4c8, 0xf30d, + 0xf15b, 0xefb3, 0xee13, 0xec7b, 0xeaeb, 0xe964, 0xe7e3, 0xe66b, + 0xe4f9, 0xe38e, 0xe229, 0xe0cc, 0xdf74, 0xde23, 0xdcd7, 0xdb91, + 0xda51, 0xd916, 0xd7e0, 0xd6b0, 0xd584, 0xd45e, 0xd33c, 0xd21e, + 0xd105, 0xcff1, 0xcee1, 0xcdd4, 0xcccc, 0xcbc8, 0xcac8, 0xc9cb, + 0xc8d2, 0xc7dd, 0xc6eb, 0xc5fc, 0xc511, 0xc429, 0xc344, 0xc263, + 0xc184, 0xc0a8, 0xbfd0, 0xbefa, 0xbe26, 0xbd56, 0xbc88, 0xbbbd, + 0xbaf4, 0xba2e, 0xb96a, 0xb8a9, 0xb7ea, 0xb72d, 0xb673, 0xb5bb, + 0xb504, 0xb450, 0xb39f, 0xb2ef, 0xb241, 0xb195, 0xb0eb, 0xb043, + 0xaf9d, 0xaef8, 0xae56, 0xadb5, 0xad16, 0xac79, 0xabdd, 0xab43, + 0xaaaa, 0xaa13, 0xa97e, 0xa8ea, 0xa858, 0xa7c7, 0xa737, 0xa6a9, + 0xa61d, 0xa592, 0xa508, 0xa47f, 0xa3f8, 0xa372, 0xa2ee, 0xa26a, + 0xa1e8, 0xa167, 0xa0e7, 0xa069, 0x9fec, 0x9f6f, 0x9ef4, 0x9e7a, + 0x9e01, 0x9d89, 0x9d13, 0x9c9d, 0x9c28, 0x9bb4, 0x9b42, 0x9ad0, + 0x9a5f, 0x99ef, 0x9981, 0x9913, 0x98a6, 0x983a, 0x97ce, 0x9764, + 0x96fb, 0x9692, 0x962a, 0x95c3, 0x955d, 0x94f8, 0x9493, 0x9430, + 0x93cd, 0x936b, 0x9309, 0x92a9, 0x9249, 0x91e9, 0x918b, 0x912d, + 0x90d0, 0x9074, 0x9018, 0x8fbd, 0x8f63, 0x8f09, 0x8eb0, 0x8e58, + 0x8e00, 0x8da9, 0x8d53, 0x8cfd, 0x8ca8, 0x8c53, 0x8bff, 0x8bac, + 0x8b59, 0x8b06, 0x8ab5, 0x8a64, 0x8a13, 0x89c3, 0x8973, 0x8924, + 0x88d6, 0x8888, 0x883b, 0x87ee, 0x87a1, 0x8755, 0x870a, 0x86bf, + 0x8675, 0x862b, 0x85e1, 0x8598, 0x8550, 0x8508, 0x84c0, 0x8479, + 0x8432, 0x83ec, 0x83a6, 0x8361, 0x831c, 0x82d7, 0x8293, 0x824f, + 0x820c, 0x81c9, 0x8186, 0x8144, 0x8103, 0x80c1, 0x8080, 0x8040, +}; + +br_fixed_ls BrFixedAbs(br_fixed_ls a) { + LOG_TRACE("(%08x)", a); + + if (a < 0) { + a = -a; + } + return a; +} + +br_fixed_ls BrFixedMul(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return ((long long)a * (long long)b) >> 16; +} + +br_fixed_ls BrFixedMac2(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d) { + LOG_TRACE("(%08x, %08x, %08x, %08x)", a, b, c, d); + + return ((long long)a * (long long)b + (long long)c * (long long)d) >> 16; +} + +br_fixed_ls BrFixedMac3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x, %08x)", a, b, c, d, e, f); + + return ((long long)a * (long long)b + (long long)c * (long long)d + (long long)e * (long long)f) >> 16; +} + +br_fixed_ls BrFixedMac4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f, br_fixed_ls g, br_fixed_ls h) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x)", a, b, c, d, e, f, g, h); + + return ((long long)a * (long long)b + (long long)c * (long long)d + (long long)e * (long long)f + (long long)g * (long long)h) >> 16; +} + +br_fixed_ls BrFixedLength2(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return _BrISqrt64((long long)a * (long long)a + (long long)b * (long long)b); +} + +br_fixed_ls BrFixedLength3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c) { + LOG_TRACE("(%08x, %08x, %08x)", a, b, c); + + return _BrISqrt64((long long)a * (long long)a + (long long)b * (long long)b + (long long)c * (long long)c); +} + +br_fixed_ls BrFixedLength4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d) { + LOG_TRACE("(%08x, %08x, %08x, %08x)", a, b, c, d); + + return _BrISqrt64((long long)a * (long long)a + (long long)b * (long long)b + (long long)c * (long long)c + (long long)d * (long long)d); +} + +br_fixed_ls BrFixedRLength2(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return _BrFastRSqrt64((long long)a * (long long)a + (long long)b * (long long)b); +} + +br_fixed_ls BrFixedRLength3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c) { + LOG_TRACE("(%08x, %08x, %08x)", a, b, c); + + return _BrFastRSqrt64((long long)a * (long long)a + (long long)b * (long long)b + (long long)c * (long long)c); +} + +br_fixed_ls BrFixedRLength4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d) { + LOG_TRACE("(%08x, %08x, %08x, %08x)", a, b, c, d); + + return _BrFastRSqrt64((long long)a * (long long)a + (long long)b * (long long)b + (long long)c * (long long)c + (long long)d * (long long)d); +} + +br_fixed_ls BrFixedDiv(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return (((long long)a) << 16) / (long long)b; +} + +br_fixed_ls BrFixedDivR(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return (((long long)a) << 16 | ((((uint32_t)(a)) & 0x80000000) ? 0xffff : 0x0)) / b; +} + +br_fixed_ls BrFixedDivF(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return (((long long)a) << 31) / b; +} + +br_fixed_ls BrFixedMulDiv(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c) { + LOG_TRACE("(%08x, %08x, %08x)", a, b, c); + + return ((long long)a * (long long)b) / (long long)c; +} + +br_fixed_ls BrFixedMac2Div(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x)", a, b, c, d, e); + + return ((long long)a * (long long)b + (long long)c * (long long)d) / (long long)e; +} + +br_fixed_ls BrFixedMac3Div(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f, br_fixed_ls g) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x, %08x, %08x)", a, b, c, d, e, f, g); + + return ((long long)a * (long long)b + (long long)c * (long long)d + (long long)e * (long long)f) / (long long)g; +} + +br_fixed_ls BrFixedMac4Div(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f, br_fixed_ls g, br_fixed_ls h, br_fixed_ls i) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x)", a, b, c, d, e, f, g, h, i); + + return ((long long)a * (long long)b + (long long)c * (long long)d + (long long)e * (long long)f + (long long)g * (long long)h) / (long long)i; +} + +br_fixed_ls BrFixedFMac2(br_fixed_lsf a, br_fixed_ls b, br_fixed_lsf c, br_fixed_ls d) { + LOG_TRACE("(%08x, %08x, %08x, %08x)", a, b, c, d); + + return ((long long)a * (long long)b + (long long)c * (long long)d) >> 15; +} + +br_fixed_ls BrFixedFMac3(br_fixed_lsf a, br_fixed_ls b, br_fixed_lsf c, br_fixed_ls d, br_fixed_lsf e, br_fixed_ls f) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x, %08x)", a, b, c, d, e, f); + + return ((long long)a * (long long)b + (long long)c * (long long)d + (long long)e * (long long)f) >> 15; +} + +br_fixed_ls BrFixedFMac4(br_fixed_lsf a, br_fixed_ls b, br_fixed_lsf c, br_fixed_ls d, br_fixed_lsf e, br_fixed_ls f, br_fixed_lsf g, br_fixed_ls h) { + LOG_TRACE("(%08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x, %08x)", a, b, c, d, e, f, g, h); + + return ((long long)a * (long long)b + (long long)c * (long long)d + (long long)e * (long long)f + (long long)g * (long long)h) >> 15; +} + +br_fixed_ls BrFixedRcp(br_fixed_ls a) { + LOG_TRACE("(%08x)", a); + + return (br_fixed_ls)(((long long)0x100000000) / a); +} + +br_fixed_ls BrFixedSqr(br_fixed_ls a) { + LOG_TRACE("(%08x)", a); + + return ((long long)a * (long long)a) >> 16; +} + +br_fixed_ls BrFixedSqr2(br_fixed_ls a, br_fixed_ls b) { + LOG_TRACE("(%08x, %08x)", a, b); + + return ((long long)a * (long long)a + (long long)b * (long long)b) >> 16; +} + +br_fixed_ls BrFixedSqr3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c) { + LOG_TRACE("(%08x, %08x, %08x)", a, b, c); + + return ((long long)a * (long long)a + (long long)b * (long long)b + (long long)c * (long long)c) >> 16; +} + +br_fixed_ls BrFixedSqr4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d) { + LOG_TRACE("(%08x, %08x, %08x, %08x)", a, b, c, d); + + return ((long long)a * (long long)a + (long long)b * (long long)b + (long long)c * (long long)c + (long long)d * (long long)d) >> 16; +} + +static int16_t fixed_lut_interpolate(uint16_t *table, uint32_t value) { + uint16_t idx = value >> 8; + int16_t basew = table[idx]; + int16_t deltaw = table[idx+1] - basew; + int16_t errw = (deltaw * (value & 0xff)) >> 8; + return basew + errw; +} + +br_fixed_ls BrFixedSin(br_angle a) { + LOG_TRACE("(%04x)", a); + + return 2 * fixed_lut_interpolate(fixed_sin_table, a); +} + +br_fixed_ls BrFixedCos(br_angle a) { + LOG_TRACE("(%04x)", a); + + return 2 * fixed_lut_interpolate(fixed_cos_table, a); +} + +br_angle BrFixedASin(br_fixed_ls a) { + LOG_TRACE("(%08x)", a); + + assert(a <= BrFloatToFixed(1.f) && "a must be <= BrFloatToFixed(1.f)"); + assert(a >= BrFloatToFixed(-1.f) && "a must be >= BrFloatToFixed(-1.f)"); + + return fixed_lut_interpolate(fixed_asin_table, (a+0x10000) >> 1); +} + +br_angle BrFixedACos(br_fixed_ls a) { + LOG_TRACE("(%08x)", a); + + assert(a <= BrFloatToFixed(1.f) && "a must be <= BrFloatToFixed(1.f)"); + assert(a >= BrFloatToFixed(-1.f) && "a must be >= BrFloatToFixed(-1.f)"); + + return fixed_lut_interpolate(fixed_acos_table, (a+0x10000) >> 1); +} + +br_angle BrFixedATan2(br_fixed_ls x, br_fixed_ls y) { + LOG_TRACE("(%08x %08x)", x, y); + + if (y > 0) { + if (x >= 0) { + if (x > y) { + return fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)y)<<32) / x) >> 16); // atan(y / x) + } else if (x == y) { + return 0x2000; // PI / 4 + } else { + return 0x4000 - fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)x)<<32) / y) >> 16); // PI/2 - atan(x / y) + } + } else { + x = -x; + if (x < y) { + return 0x4000 + fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)x)<<32) / y) >> 16); // PI/2 + atan(x / y) + } else if (x == y) { + return 0x6000; // 3 * PI / 4 + } else { + return 0x8000 - fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)y)<<32) / x) >> 16); // PI - atan(y / x) + } + } + } else if (y < 0) { + y = -y; + if (x < 0) { + x = -x; + if (x > y) { + return 0x8000 + fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)y)<<32) / x) >> 16); // PI + atan(y / x) + } else if (x == y) { + return 0xa000; // 5 * PI / 4 + } else { + return 0xc000 - fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)x)<<32) / y) >> 16); // 3 * PI / 2 - atan(x / y) + } + } else { + if (x < y) { + return 0xc000 + fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)x)<<32) / y) >> 16); // 3 * PI / 2 + atan(x / y) + } else if (x == y) { + return 0xe000; // 7 * PI / 4 + } else { + return -fixed_lut_interpolate(fixed_atan_table, ((((unsigned long long)y)<<32) / x) >> 16); // 2 * pi - atan(y / x) + } + } + } else { + if (x >= 0) { + return 0; // 0 + } else { + return 0x8000; // PI + } + } +} + +br_angle BrFixedATan2Fast(br_fixed_ls x, br_fixed_ls y) { + LOG_TRACE("(%08x %08x)", x, y); + if (y > 0) { + if (x >= 0) { + if (x > y) { + return ((((unsigned long long)y)<<32) / x) >> 19; // atan(y / x) + } else if (x == y) { + return 0x2000; // PI / 4 + } else { + return 0x4000 - (((((unsigned long long)x)<<32) / y) >> 19); // PI/2 - atan(x / y) + } + } else { + x = -x; + if (x < y) { + return 0x4000 + (((((unsigned long long)x)<<32) / y) >> 19); // PI/2 + atan(x / y) + } else if (x == y) { + return 0x6000; // 3 * PI / 4 + } else { + return 0x8000 - (((((unsigned long long)y)<<32) / x) >> 19); // PI - atan(y / x) + } + } + } else if (y < 0) { + y = -y; + if (x < 0) { + x = -x; + if (x > y) { + return 0x8000 + (((((unsigned long long)y)<<32) / x) >> 19); // PI + atan(y / x) + } else if (x == y) { + return 0xa000; // 5 * PI / 4 + } else { + return 0xc000 - (((((unsigned long long)x)<<32) / y) >> 19); // 3 * PI / 2 - atan(x / y) + } + } else { + if (x < y) { + return 0xc000 + (((((unsigned long long)x)<<32) / y) >> 19); // 3 * PI / 2 + atan(x / y) + } else if (x == y) { + return 0xe000; // 7 * PI / 4 + } else { + return (br_angle)(0x10000 - (((((unsigned long long)y)<<32) / x) >> 19)); // 2 * pi - atan(y / x) + } + } + } else { + if (x >= 0) { + return 0; // 0 + } else { + return 0x8000; // PI + } + } + return 0; +} + +uint16_t _BrISqrt32(uint32_t a) { + // Shifting nth root algorithm + uint32_t err; + uint32_t est; + uint32_t est_2; + int i; + LOG_TRACE("(%u)", a); + + err = 0; + est = 0; + est_2 = 0; + + // 2 MSB bits + err = a >> 30; + a <<= 2; + if (err != 0) { + err -= 1; + est = 1; + est_2 = 2; + } + // 14 iterations: 14*2-bit pairs=28 bits + for (i = 0; i < 14; i++) { + err = (err << 2) | (a >> 30); + a <<= 2; + est <<= 1; + est_2 <<= 1; + if (err > est_2) { + err -= est_2 + 1; + est += 1; + est_2 += 2; + } + } + // 2 LSB bits + err = (err << 2) | (a >> 30); + est <<= 1; + est_2 <<= 1; + if (err > est_2) { + est += 1; + } + return est; +} +#include +br_uint_32 _BrISqrt64(uint64_t a) { + // Shifting nth root algorithm + uint64_t err; + uint64_t est; + uint64_t est_2; + int i; + LOG_TRACE("(%lu)", a); + + err = 0; + est = 0; + est_2 = 0; + + // 32 iterations (32 * 2bits) + for (i = 0; i < 32; i++) { + err = (err << 2) | (a >> 62); + a <<= 2; + est <<= 1; + est_2 <<= 1; + if (err > est_2) { + err -= est_2 + 1; + est += 1; + est_2 += 2; + } + } + return (br_uint_32)est; +} + +#if 0 +// working inprecise +uint16_t _BrFastSqrt32(uint32_t v) { + uint32_t exp; + LOG_TRACE("(%u)", v); + + if (v == 0) { + return v; + } + for (exp = 31; (v >> exp) == 0; exp--) { + } + // Exponent must be multiple of 2 (because square root divides exponent by 2) + exp = (exp | 1) + 1; + // Normalise number: exponent in [0..31], mantissa in [0x40-0xff] + v = (v << (31 - exp)) >> 24; + v = fast_sqrt_table[2*v-0x40]; + return (v << 16) >> (32 - (exp >> 1)); +} +#endif + +uint16_t _BrFastSqrt32(uint32_t v) { + uint32_t exp; + LOG_TRACE("(%u)", v); + + if (v == 0) { + return v; + } + for (exp = 31; (v >> exp) == 0; exp--) { + } + // Exponent must be multiple of 2 (because square root divides exponent by 2) + exp = (exp | 1) + 1; + // Normalise number: exponent in [0..31], mantissa in [0x40-0xff] + v = (v << (32 - exp)) >> 24; + v = fast_sqrt_table[v-0x40]; + return (v << 16) >> (32 - (exp >> 1)); +} + +uint32_t _BrFastRSqrt32(uint32_t v) { + uint32_t exp; + LOG_TRACE("(0x%08x)", v); + + if (v == 0) { + return v; + } + for (exp = 31; (v >> exp) == 0; exp--) { + } + exp = exp | 1; + v = (v << (31 - exp)) >> 24; + v = fast_rsqrt_table[v-0x40]; + return v >> (exp >> 1); +} + +br_uint_32 _BrFastRSqrt64(uint64_t v) { + uint32_t exp; + uint32_t tmp; + LOG_TRACE("(0x%016llx)", v); + + if (v == 0) { + return 0; + } + tmp = v >> 32; + if (tmp != 0) { + for (exp = 31; (tmp >> exp) == 0; exp--) { + } + exp = (31-exp) & 0xfe; + v = (v << exp) >> 56; + fflush(stdout); + v = fast_rsqrt_table[v-0x40]; + return (br_uint_32)(v >> ((30 - exp) >> 1)); + } + tmp = (br_uint_32)v; + for (exp = 31; (tmp >> exp) == 0; exp--) { + } + exp = exp | 1; + v = (v << (31 - exp)) >> 24; + v = fast_rsqrt_table[v-0x40]; + return (br_uint_32)((v << 16) >> (exp >> 1)); +} diff --git a/src/BRSRC13/CORE/MATH/fixed.h b/src/BRSRC13/CORE/MATH/fixed.h new file mode 100644 index 00000000..1bd43b3a --- /dev/null +++ b/src/BRSRC13/CORE/MATH/fixed.h @@ -0,0 +1,109 @@ +#ifndef _FIXED_H_ +#define _FIXED_H_ + +#include "brender/br_types.h" + +#define BR_ONE_LS ((br_fixed_ls)0x00010000) +#define BR_ONE_LU ((br_fixed_lu)0x00010000) +#define BR_ONE_LSF ((br_fixed_ls)0x00008000) +#define BR_ONE_LUF ((br_fixed_lu)0x00010000) +#define BR_ONE_SS ((br_fixed_ss)0x0100) +#define BR_ONE_SU ((br_fixed_ss)0x0100) +#define BR_ONE_SSF ((br_fixed_ss)0x0080) +#define BR_ONE_SUF ((br_fixed_ss)0x0100) +#define BrIntToFixed(i) ((i)<<16) +#define BrFloatToFixed(f) ((br_fixed_ls)((f)*65536.f)) +#define BrFixedToInt(i) ((i)>>16) +#define BrFixedToFloat(i) ((float)((i)*(1.f/65536.f))) + +#define BrFloatToFixedFraction(f) ((br_fixed_lsf)((f)*32768.f)) +#define BrFixedFractionToFloat(f) ((float)(((br_fixed_lsf)(f))*(1.f/32768.f))) + +#define BrFloatToFixedUFraction(f) ((br_fixed_luf)((f)*65536.f)) +#define BrFixedUFractionToFloat(f) ((float)(((br_fixed_luf)(f))*(1.f/65536.f))) + +#if 1 +#define BrFloatToScalar(f) f +#define BrScalarToFlat(f) f +#define BrFixedToScalar BrFixedToFloat +#define BrScalarToFixed BrFloatToFixed + +#define BrScalarToFraction(f) f +#define BrFractionToScalar(f) f +#endif + +br_fixed_ls BrFixedAbs(br_fixed_ls a); + +br_fixed_ls BrFixedMul(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedMac2(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d); + +br_fixed_ls BrFixedMac3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f); + +br_fixed_ls BrFixedMac4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f, br_fixed_ls g, br_fixed_ls h); + +br_fixed_ls BrFixedLength2(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedLength3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c); + +br_fixed_ls BrFixedLength4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d); + +br_fixed_ls BrFixedRLength2(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedRLength3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c); + +br_fixed_ls BrFixedRLength4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d); + +br_fixed_ls BrFixedDiv(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedDivR(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedDivF(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedMulDiv(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c); + +br_fixed_ls BrFixedMac2Div(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e); + +br_fixed_ls BrFixedMac3Div(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f, br_fixed_ls g); + +br_fixed_ls BrFixedMac4Div(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d, br_fixed_ls e, br_fixed_ls f, br_fixed_ls g, br_fixed_ls h, br_fixed_ls i); + +br_fixed_ls BrFixedFMac2(br_fixed_lsf a, br_fixed_ls b, br_fixed_lsf c, br_fixed_ls d); + +br_fixed_ls BrFixedFMac3(br_fixed_lsf a, br_fixed_ls b, br_fixed_lsf c, br_fixed_ls d, br_fixed_lsf e, br_fixed_ls f); + +br_fixed_ls BrFixedFMac4(br_fixed_lsf a, br_fixed_ls b, br_fixed_lsf c, br_fixed_ls d, br_fixed_lsf e, br_fixed_ls f, br_fixed_lsf g, br_fixed_ls h); + +br_fixed_ls BrFixedRcp(br_fixed_ls a); + +br_fixed_ls BrFixedSqr(br_fixed_ls a); + +br_fixed_ls BrFixedSqr2(br_fixed_ls a, br_fixed_ls b); + +br_fixed_ls BrFixedSqr3(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c); + +br_fixed_ls BrFixedSqr4(br_fixed_ls a, br_fixed_ls b, br_fixed_ls c, br_fixed_ls d); + +br_fixed_ls BrFixedSin(br_angle a); + +br_fixed_ls BrFixedCos(br_angle a); + +br_angle BrFixedASin(br_fixed_ls a); + +br_angle BrFixedACos(br_fixed_ls a); + +br_angle BrFixedATan2(br_fixed_ls x, br_fixed_ls y); + +br_angle BrFixedATan2Fast(br_fixed_ls x, br_fixed_ls y); + +br_uint_16 _BrISqrt32(br_uint_32 a); + +br_uint_32 _BrISqrt64(uint64_t a); + +br_uint_16 _BrFastSqrt32(br_uint_32 v); + +br_uint_32 _BrFastRSqrt32(br_uint_32 v); + +br_uint_32 _BrFastRSqrt64(uint64_t v); + +#endif diff --git a/src/BRSRC13/CORE/MATH/plane.c b/src/BRSRC13/CORE/MATH/plane.c index 6be3714b..38e89796 100644 --- a/src/BRSRC13/CORE/MATH/plane.c +++ b/src/BRSRC13/CORE/MATH/plane.c @@ -19,25 +19,25 @@ br_int_32 BrPlaneEquation(br_vector4* eqn, br_vector3* v0, br_vector3* v1, br_ve float d; float l; + ax = v1->v[0] - v0->v[0]; ay = v1->v[1] - v0->v[1]; - bz = v2->v[2] - v0->v[2]; az = v1->v[2] - v0->v[2]; bx = v2->v[0] - v0->v[0]; - ax = v1->v[0] - v0->v[0]; by = v2->v[1] - v0->v[1]; + bz = v2->v[2] - v0->v[2]; nx = ay * bz - az * by; ny = az * bx - ax * bz; nz = ax * by - ay * bx; l = nx * nx + ny * ny + nz * nz; l = BrFloatSqrt(l); if (isnan(l)) { - nx = 0.0; - ny = 0.0; - nz = 1.0; + nx = 0.f; + ny = 0.f; + nz = 1.f; } else { - nx = nx * (1.0f / l); - ny = ny * (1.0f / l); - nz = nz * (1.0f / l); + nx = nx * (1.f / l); + ny = ny * (1.f / l); + nz = nz * (1.f / l); } d = nx * v0->v[0] + ny * v0->v[1] + nz * v0->v[2]; eqn->v[0] = nx; diff --git a/src/BRSRC13/CORE/STD/brstdfile.c b/src/BRSRC13/CORE/STD/brstdfile.c index 09727d6f..5604a07c 100644 --- a/src/BRSRC13/CORE/STD/brstdfile.c +++ b/src/BRSRC13/CORE/STD/brstdfile.c @@ -102,6 +102,7 @@ void BrStdioPutChar(int c, void* f) { br_size_t BrStdioRead(void* buf, br_size_t size, unsigned int n, void* f) { int i; + LOG_TRACE9("(%p, %d, %d, %p)", buf, size, n, f); i = fread(buf, size, n, f); return i; @@ -114,6 +115,7 @@ br_size_t BrStdioWrite(void* buf, br_size_t size, unsigned int n, void* f) { br_size_t BrStdioGetLine(char* buf, br_size_t buf_len, void* f) { br_size_t l; + LOG_TRACE9("(%p, %d, %p)", buf, buf_len, f); if (fgets(buf, buf_len, f) == NULL) { return 0; } diff --git a/src/BRSRC13/CORE/STD/brstdlib.c b/src/BRSRC13/CORE/STD/brstdlib.c index 23254877..520316e6 100644 --- a/src/BRSRC13/CORE/STD/brstdlib.c +++ b/src/BRSRC13/CORE/STD/brstdlib.c @@ -124,6 +124,7 @@ br_int_32 BrVSprintfN(char* buf, br_size_t buf_size, const char* fmt, va_list ar strncpy(buf, tmp, n); buf[n] = '\0'; + return n; } br_int_32 BrVSScanf(char* buf, const char* fmt, va_list args) { diff --git a/test/BRSRC13/test_datafile.c b/test/BRSRC13/test_datafile.c index b94808fb..76fe208a 100644 --- a/test/BRSRC13/test_datafile.c +++ b/test/BRSRC13/test_datafile.c @@ -1,18 +1,3283 @@ #include "tests.h" #include "CORE/FW/datafile.h" +#include "CORE/FW/file.h" +#include "CORE/MATH/fixed.h" -void test_datafile_ReadBinary() { - REQUIRES_DATA_DIRECTORY(); +#include - br_datafile* f; - f = DfOpen("DATA/MODELS/CPOINT.DAT", 0, BRT_FLOAT); +#define TEXT_MAGICS "*FILE_IN" +#define BINARY_MAGICS '\0', '\0', '\0', '\x12', '\0', '\0', '\0', '\b' + +char *text_magics = TEXT_MAGICS; +uint8_t binary_magics[] = {BINARY_MAGICS}; + +static void TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(const uint8_t *expected, char *filename, int len) { + FILE *f; + long filesize; + int res; + f = fopen(filename, "rb"); TEST_ASSERT_NOT_NULL(f); - TEST_ASSERT_NOT_NULL(f->h); - DfClose(f); + res = fseek(f, 0, SEEK_END); + TEST_ASSERT_NOT_EQUAL(-1, res); + filesize = ftell(f); + TEST_ASSERT_NOT_EQUAL(-1, filesize); + TEST_ASSERT_EQUAL(len, filesize); + fseek(f, 0, SEEK_SET); + uint8_t* tmpBuffer = (uint8_t*)malloc(filesize); + res = fread(tmpBuffer, filesize, 1, f); + TEST_ASSERT_EQUAL_INT(1, res); + fclose(f); + TEST_ASSERT_EQUAL_MEMORY(expected, tmpBuffer, len); + free(tmpBuffer); +} + +static void TEST_ASSERT_EQUAL_FILE_TEXT(const char *expected, char *filename) { + FILE *f; + long filesize; + int res; + + int len = strlen(expected); + f = fopen(filename, "r"); + TEST_ASSERT_NOT_NULL(f); + res = fseek(f, 0, SEEK_END); + TEST_ASSERT_NOT_EQUAL(-1, res); + filesize = ftell(f); + TEST_ASSERT_NOT_EQUAL(-1, filesize); + fseek(f, 0, SEEK_SET); + char* tmpBuffer = (char*)malloc(filesize+1); + res = fread(tmpBuffer, 1, filesize, f); + TEST_ASSERT_EQUAL_INT(filesize, res); + tmpBuffer[filesize] = '\0'; + fclose(f); + TEST_ASSERT_EQUAL_STRING(expected, tmpBuffer); + TEST_ASSERT_EQUAL(len, filesize); + TEST_ASSERT_EQUAL_INT(filesize, strlen(tmpBuffer)); + free(tmpBuffer); +} + +static void test_datafile_stack() { + int dummy1; + int dummy2; + int val; + void *ptr; + int initialtoptype; + + initialtoptype = DfTopType(); + + DfPush(0xcafebabe, &dummy1, 42); + + TEST_ASSERT_EQUAL_UINT32(0xcafebabe, DfTopType()); + + val = 0; + ptr = NULL; + ptr = DfTop(0xcafebabe, &val); + + TEST_ASSERT_EQUAL_PTR(&dummy1, ptr); + TEST_ASSERT_EQUAL_INT(42, val); + TEST_ASSERT_EQUAL_UINT32(0xcafebabe, DfTopType()); + + DfPush(0xf00dbabe, &dummy2, 9000); + + TEST_ASSERT_EQUAL_UINT32(0xf00dbabe, DfTopType()); + + val = 0; + ptr = NULL; + ptr = DfTop(0xf00dbabe, &val); + + TEST_ASSERT_EQUAL_PTR(&dummy2, ptr); + TEST_ASSERT_EQUAL_INT(9000, val); + TEST_ASSERT_EQUAL_UINT32(0xf00dbabe, DfTopType()); + + val = 0; + ptr = NULL; + ptr = DfPop(0xf00dbabe, &val); + + TEST_ASSERT_EQUAL_PTR(&dummy2, ptr); + TEST_ASSERT_EQUAL_INT(9000, val); + TEST_ASSERT_EQUAL_UINT32(0xcafebabe, DfTopType()); + + val = 0; + ptr = NULL; + ptr = DfPop(0xcafebabe, &val); + + TEST_ASSERT_EQUAL_PTR(&dummy1, ptr); + TEST_ASSERT_EQUAL_INT(42, val); + TEST_ASSERT_EQUAL_UINT32(initialtoptype, DfTopType()); +} + +static void test_datafile_magics() { + TEST_ASSERT_EQUAL_INT(BR_FS_MODE_TEXT, DfFileIdentify(text_magics, sizeof(text_magics))); + TEST_ASSERT_EQUAL_INT(BR_FS_MODE_BINARY, DfFileIdentify(binary_magics, sizeof(binary_magics))); + TEST_ASSERT_EQUAL_INT(BR_FS_MODE_UNKNOWN, DfFileIdentify("nonsense", sizeof("nonsense"))); +} + +typedef struct struct_br_int_8 { + char dummy0[11]; + br_int_8 m1; + char dummy1[13]; + br_int_8 m2; + char dummy2[17]; + br_int_8 m3; + char dummy3[23]; + br_int_8 m4; + char dummy4[27]; +} struct_br_int_8; +static br_file_struct_member struct_br_int_8_file_members[] = { + { DF_TYPE_BR_INT_8, offsetof(struct_br_int_8, m1), "m1", NULL, }, + { DF_TYPE_BR_INT_8, offsetof(struct_br_int_8, m2), "m2", NULL, }, + { DF_TYPE_BR_INT_8, offsetof(struct_br_int_8, m3), "m3", NULL, }, + { DF_TYPE_BR_INT_8, offsetof(struct_br_int_8, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_int_8_file = { + "struct_br_int_8", BR_ASIZE(struct_br_int_8_file_members), struct_br_int_8_file_members, sizeof(struct_br_int_8), +}; +static struct_br_int_8 br_int_8_ref = { { 0 }, 42, { 0 }, -42, { 0 }, -2, { 0 }, 87, { 0 }, }; +static const uint8_t binary_br_int_8_data[] = { BINARY_MAGICS, 0x2a, 0xd6, 0xfe, 0x57, }; +static const char *text_br_int_8_data = + TEXT_MAGICS HOST_NL + " struct struct_br_int_8" HOST_NL + " int_8 42 # m1" HOST_NL + " int_8 -42 # m2" HOST_NL + " int_8 -2 # m3" HOST_NL + " int_8 87 # m4" HOST_NL; +static void test_datafile_binary_br_int_8() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_int_8 read_struct; + + create_temp_file(tmpfilename, "br_int_8_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(4, DfStructSizeBinary(df_w, &struct_br_int_8_file, &br_int_8_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_int_8_file, &br_int_8_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_int_8_data, tmpfilename, sizeof(binary_br_int_8_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_int_8_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_int_8_ref, &read_struct, sizeof(br_int_8_ref)); +} +static void test_datafile_text_br_int_8() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_int_8 read_struct; + + create_temp_file(tmpfilename, "br_int_8_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_int_8_file, &br_int_8_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_int_8_file, &br_int_8_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_int_8_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_int_8_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_int_8_ref, &read_struct, sizeof(br_int_8_ref)); +} + +typedef struct struct_br_uint_8 { + char dummy0[11]; + br_uint_8 m1; + char dummy1[13]; + br_uint_8 m2; + char dummy2[17]; + br_uint_8 m3; + char dummy3[23]; + br_uint_8 m4; + char dummy4[27]; +} struct_br_uint_8; +static br_file_struct_member struct_br_uint_8_file_members[] = { + { DF_TYPE_BR_UINT_8, offsetof(struct_br_uint_8, m1), "m1", NULL, }, + { DF_TYPE_BR_UINT_8, offsetof(struct_br_uint_8, m2), "m2", NULL, }, + { DF_TYPE_BR_UINT_8, offsetof(struct_br_uint_8, m3), "m3", NULL, }, + { DF_TYPE_BR_UINT_8, offsetof(struct_br_uint_8, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_uint_8_file = { + "struct_br_uint_8", BR_ASIZE(struct_br_uint_8_file_members), struct_br_uint_8_file_members, sizeof(struct_br_uint_8), +}; +static struct_br_uint_8 br_uint_8_ref = { { 0 }, 40, { 0 }, 250, { 0 }, 129, { 0 }, 127, { 0 }, }; +static const uint8_t binary_br_uint_8_data[] = { BINARY_MAGICS, 0x28, 0xfa, 0x81, 0x7f, }; +static const char *text_br_uint_8_data = + TEXT_MAGICS HOST_NL + " struct struct_br_uint_8" HOST_NL + " uint_8 40 # m1" HOST_NL + " uint_8 250 # m2" HOST_NL + " uint_8 129 # m3" HOST_NL + " uint_8 127 # m4" HOST_NL; +static void test_datafile_binary_br_uint_8() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_uint_8 read_struct; + + create_temp_file(tmpfilename, "br_uint_8_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(4, DfStructSizeBinary(df_w, &struct_br_uint_8_file, &br_uint_8_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_uint_8_file, &br_uint_8_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_uint_8_data, tmpfilename, sizeof(binary_br_uint_8_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_uint_8_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_uint_8_ref, &read_struct, sizeof(br_uint_8_ref)); +} +static void test_datafile_text_br_uint_8() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_uint_8 read_struct; + + create_temp_file(tmpfilename, "br_uint_8_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_uint_8_file, &br_uint_8_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_uint_8_file, &br_uint_8_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_uint_8_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_uint_8_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_uint_8_ref, &read_struct, sizeof(br_uint_8_ref)); +} + +typedef struct struct_br_int_16 { + char dummy0[11]; + br_int_16 m1; + char dummy1[13]; + br_int_16 m2; + char dummy2[17]; + br_int_16 m3; + char dummy3[23]; + br_int_16 m4; + char dummy4[27]; +} struct_br_int_16; +static br_file_struct_member struct_br_int_16_file_members[] = { + { DF_TYPE_BR_INT_16, offsetof(struct_br_int_16, m1), "m1", NULL, }, + { DF_TYPE_BR_INT_16, offsetof(struct_br_int_16, m2), "m2", NULL, }, + { DF_TYPE_BR_INT_16, offsetof(struct_br_int_16, m3), "m3", NULL, }, + { DF_TYPE_BR_INT_16, offsetof(struct_br_int_16, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_int_16_file = { + "struct_br_int_16", BR_ASIZE(struct_br_int_16_file_members), struct_br_int_16_file_members, sizeof(struct_br_int_16), +}; +static struct_br_int_16 br_int_16_ref = { { 0 }, -32700, { 0 }, 32700, { 0 }, 255, { 0 }, -40, { 0 }, }; +static const uint8_t binary_br_int_16_data[] = { BINARY_MAGICS, 0x80, 0x44, 0x7f, 0xbc, 0x00, 0xff, 0xff, 0xd8, }; +static const char *text_br_int_16_data = + TEXT_MAGICS HOST_NL + " struct struct_br_int_16" HOST_NL + " int_16 -32700 # m1" HOST_NL + " int_16 32700 # m2" HOST_NL + " int_16 255 # m3" HOST_NL + " int_16 -40 # m4" HOST_NL; +static void test_datafile_binary_br_int_16() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_int_16 read_struct; + + create_temp_file(tmpfilename, "br_int_16_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(8, DfStructSizeBinary(df_w, &struct_br_int_16_file, &br_int_16_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_int_16_file, &br_int_16_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_int_16_data, tmpfilename, sizeof(binary_br_int_16_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_int_16_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_int_16_ref, &read_struct, sizeof(br_int_16_ref)); +} +static void test_datafile_text_br_int_16() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_int_16 read_struct; + + create_temp_file(tmpfilename, "br_int_16_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_int_16_file, &br_int_16_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_int_16_file, &br_int_16_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_int_16_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_int_16_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_int_16_ref, &read_struct, sizeof(br_int_16_ref)); +} + +typedef struct struct_br_uint_16 { + char dummy0[11]; + br_uint_16 m1; + char dummy1[13]; + br_uint_16 m2; + char dummy2[17]; + br_uint_16 m3; + char dummy3[23]; + br_uint_16 m4; + char dummy4[27]; +} struct_br_uint_16; +static br_file_struct_member struct_br_uint_16_file_members[] = { + { DF_TYPE_BR_UINT_16, offsetof(struct_br_uint_16, m1), "m1", NULL, }, + { DF_TYPE_BR_UINT_16, offsetof(struct_br_uint_16, m2), "m2", NULL, }, + { DF_TYPE_BR_UINT_16, offsetof(struct_br_uint_16, m3), "m3", NULL, }, + { DF_TYPE_BR_UINT_16, offsetof(struct_br_uint_16, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_uint_16_file = { + "struct_br_uint_16", BR_ASIZE(struct_br_uint_16_file_members), struct_br_uint_16_file_members, sizeof(struct_br_uint_16), +}; +static struct_br_uint_16 br_uint_16_ref = { { 0 }, 65000, { 0 }, 255, { 0 }, 1000, { 0 }, 9000, { 0 }, }; +static const uint8_t binary_br_uint_16_data[] = { BINARY_MAGICS, 0xfd, 0xe8, 0x00, 0xff, 0x03, 0xe8, 0x23, 0x28, }; +static const char *text_br_uint_16_data = + TEXT_MAGICS HOST_NL + " struct struct_br_uint_16" HOST_NL + " uint_16 65000 # m1" HOST_NL + " uint_16 255 # m2" HOST_NL + " uint_16 1000 # m3" HOST_NL + " uint_16 9000 # m4" HOST_NL; +static void test_datafile_binary_br_uint_16() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_uint_16 read_struct; + + create_temp_file(tmpfilename, "br_uint_16_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(8, DfStructSizeBinary(df_w, &struct_br_uint_16_file, &br_uint_16_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_uint_16_file, &br_uint_16_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_uint_16_data, tmpfilename, sizeof(binary_br_uint_16_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_uint_16_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_uint_16_ref, &read_struct, sizeof(br_uint_16_ref)); +} +static void test_datafile_text_br_uint_16() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_uint_16 read_struct; + + create_temp_file(tmpfilename, "br_uint_16_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_uint_16_file, &br_uint_16_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_uint_16_file, &br_uint_16_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_uint_16_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_uint_16_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_uint_16_ref, &read_struct, sizeof(br_uint_16_ref)); +} + +typedef struct struct_br_int_32 { + char dummy0[11]; + br_int_32 m1; + char dummy1[13]; + br_int_32 m2; + char dummy2[17]; + br_int_32 m3; + char dummy3[23]; + br_int_32 m4; + char dummy4[27]; +} struct_br_int_32; +static br_file_struct_member struct_br_int_32_file_members[] = { + { DF_TYPE_BR_INT_32, offsetof(struct_br_int_32, m1), "m1", NULL, }, + { DF_TYPE_BR_INT_32, offsetof(struct_br_int_32, m2), "m2", NULL, }, + { DF_TYPE_BR_INT_32, offsetof(struct_br_int_32, m3), "m3", NULL, }, + { DF_TYPE_BR_INT_32, offsetof(struct_br_int_32, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_int_32_file = { + "struct_br_int_32", BR_ASIZE(struct_br_int_32_file_members), struct_br_int_32_file_members, sizeof(struct_br_int_32), +}; +static struct_br_int_32 br_int_32_ref = { { 0 }, -2147483648, { 0 }, 2147483647, { 0 }, 255, { 0 }, -98765, { 0 }, }; +static const uint8_t binary_br_int_32_data[] = { BINARY_MAGICS, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x7e, 0x33, }; +static const char *text_br_int_32_data = + TEXT_MAGICS HOST_NL + " struct struct_br_int_32" HOST_NL + " int_32 -2147483648 # m1" HOST_NL + " int_32 2147483647 # m2" HOST_NL + " int_32 255 # m3" HOST_NL + " int_32 -98765 # m4" HOST_NL; +static void test_datafile_binary_br_int_32() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_int_32 read_struct; + + create_temp_file(tmpfilename, "br_int_32_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_int_32_file, &br_int_32_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_int_32_file, &br_int_32_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_int_32_data, tmpfilename, sizeof(binary_br_int_32_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_int_32_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_int_32_ref, &read_struct, sizeof(br_int_32_ref)); +} +static void test_datafile_text_br_int_32() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_int_32 read_struct; + + create_temp_file(tmpfilename, "br_int_32_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_int_32_file, &br_int_32_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_int_32_file, &br_int_32_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_int_32_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_int_32_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_int_32_ref, &read_struct, sizeof(br_int_32_ref)); +} + +typedef struct struct_br_uint_32 { + char dummy0[11]; + br_uint_32 m1; + char dummy1[13]; + br_uint_32 m2; + char dummy2[17]; + br_uint_32 m3; + char dummy3[23]; + br_uint_32 m4; + char dummy4[27]; +} struct_br_uint_32; +static br_file_struct_member struct_br_uint_32_file_members[] = { + { DF_TYPE_BR_UINT_32, offsetof(struct_br_uint_32, m1), "m1", NULL, }, + { DF_TYPE_BR_UINT_32, offsetof(struct_br_uint_32, m2), "m2", NULL, }, + { DF_TYPE_BR_UINT_32, offsetof(struct_br_uint_32, m3), "m3", NULL, }, + { DF_TYPE_BR_UINT_32, offsetof(struct_br_uint_32, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_uint_32_file = { + "struct_br_uint_32", BR_ASIZE(struct_br_uint_32_file_members), struct_br_uint_32_file_members, sizeof(struct_br_uint_32), +}; +static struct_br_uint_32 br_uint_32_ref = { { 0 }, 0xffffffff, { 0 }, 1, { 0 }, 1000000, { 0 }, 90000, { 0 }, }; +static const uint8_t binary_br_uint_32_data[] = { BINARY_MAGICS, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x42, 0x40, 0x00, 0x01, 0x5f, 0x90, }; +static const char *text_br_uint_32_data = + TEXT_MAGICS HOST_NL + " struct struct_br_uint_32" HOST_NL + " uint_32 4294967295 # m1" HOST_NL + " uint_32 1 # m2" HOST_NL + " uint_32 1000000 # m3" HOST_NL + " uint_32 90000 # m4" HOST_NL; +static void test_datafile_binary_br_uint_32() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_uint_32 read_struct; + + create_temp_file(tmpfilename, "br_uint_32_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_uint_32_file, &br_uint_32_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_uint_32_file, &br_uint_32_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_uint_32_data, tmpfilename, sizeof(binary_br_uint_32_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_uint_32_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_uint_32_ref, &read_struct, sizeof(br_uint_32_ref)); +} +static void test_datafile_text_br_uint_32() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_uint_32 read_struct; + + create_temp_file(tmpfilename, "br_uint_32_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_uint_32_file, &br_uint_32_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_uint_32_file, &br_uint_32_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_uint_32_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_uint_32_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_uint_32_ref, &read_struct, sizeof(br_uint_32_ref)); +} + +typedef struct struct_br_fixed { + char dummy0[11]; + br_fixed_ls m1; + char dummy1[13]; + br_fixed_ls m2; + char dummy2[17]; + br_fixed_ls m3; + char dummy3[23]; + br_fixed_ls m4; + char dummy4[27]; +} struct_br_fixed; +static br_file_struct_member struct_br_fixed_file_members[] = { + { DF_TYPE_BR_FIXED, offsetof(struct_br_fixed, m1), "m1", NULL, }, + { DF_TYPE_BR_FIXED, offsetof(struct_br_fixed, m2), "m2", NULL, }, + { DF_TYPE_BR_FIXED, offsetof(struct_br_fixed, m3), "m3", NULL, }, + { DF_TYPE_BR_FIXED, offsetof(struct_br_fixed, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_fixed_file = { + "struct_br_fixed", BR_ASIZE(struct_br_fixed_file_members), struct_br_fixed_file_members, sizeof(struct_br_fixed), +}; +static struct_br_fixed br_fixed_ref = { { 0 }, 0x00008000, { 0 }, 0x00020000, { 0 }, 0x00101000, { 0 }, 0x01000000, { 0 }, }; +static const uint8_t binary_br_fixed_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41, 0x80, 0x80, 0x00, 0x43, 0x80, 0x00, 0x00, }; +static const char *text_br_fixed_data = + TEXT_MAGICS HOST_NL + " struct struct_br_fixed" HOST_NL + " fixed 0.5 # m1" HOST_NL + " fixed 2 # m2" HOST_NL + " fixed 16.0625 # m3" HOST_NL + " fixed 256 # m4" HOST_NL; +static void test_datafile_binary_br_fixed() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_fixed read_struct; + + create_temp_file(tmpfilename, "br_fixed_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_fixed_file, &br_fixed_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_fixed_file, &br_fixed_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_fixed_data, tmpfilename, sizeof(binary_br_fixed_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_fixed_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-3), br_fixed_ref.m1, read_struct.m1); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-3), br_fixed_ref.m2, read_struct.m2); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-3), br_fixed_ref.m3, read_struct.m3); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-3), br_fixed_ref.m4, read_struct.m4); +} +static void test_datafile_text_br_fixed() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_fixed read_struct; + + create_temp_file(tmpfilename, "br_fixed_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_fixed_file, &br_fixed_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_fixed_file, &br_fixed_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_fixed_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_fixed_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_fixed_ref, &read_struct, sizeof(br_fixed_ref)); +} + +typedef struct struct_br_angle { + char dummy0[11]; + br_angle m1; + char dummy1[13]; + br_angle m2; + char dummy2[17]; + br_angle m3; + char dummy3[23]; + br_angle m4; + char dummy4[27]; +} struct_br_angle; +static br_file_struct_member struct_br_angle_file_members[] = { + { DF_TYPE_BR_ANGLE, offsetof(struct_br_angle, m1), "m1", NULL, }, + { DF_TYPE_BR_ANGLE, offsetof(struct_br_angle, m2), "m2", NULL, }, + { DF_TYPE_BR_ANGLE, offsetof(struct_br_angle, m3), "m3", NULL, }, + { DF_TYPE_BR_ANGLE, offsetof(struct_br_angle, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_angle_file = { + "struct_br_angle", BR_ASIZE(struct_br_angle_file_members), struct_br_angle_file_members, sizeof(struct_br_angle), +}; +static struct_br_angle br_angle_ref = { { 0 }, 0x0080, { 0 }, 0x2000, { 0 }, 0x4000, { 0 }, 0xe000, { 0 }, }; +static const uint8_t binary_br_angle_data[] = { BINARY_MAGICS, 0x00, 0x80, 0x20, 0x00, 0x40, 0x00, 0xe0, 0x00, }; +static const char *text_br_angle_data = + TEXT_MAGICS HOST_NL + " struct struct_br_angle" HOST_NL + " angle 0.703125 # m1" HOST_NL + " angle 45 # m2" HOST_NL + " angle 90 # m3" HOST_NL + " angle 315 # m4" HOST_NL; +static void test_datafile_binary_br_angle() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_angle read_struct; + + create_temp_file(tmpfilename, "br_angle_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(8, DfStructSizeBinary(df_w, &struct_br_angle_file, &br_angle_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_angle_file, &br_angle_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_angle_data, tmpfilename, sizeof(binary_br_angle_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_angle_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_angle_ref, &read_struct, sizeof(br_angle_ref)); +} +static void test_datafile_text_br_angle() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_angle read_struct; + + create_temp_file(tmpfilename, "br_angle_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_angle_file, &br_angle_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_angle_file, &br_angle_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_angle_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_angle_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_angle_ref, &read_struct, sizeof(br_angle_ref)); +} + +typedef struct struct_float { + char dummy0[11]; + float m1; + char dummy1[13]; + float m2; + char dummy2[17]; + float m3; + char dummy3[23]; + float m4; + char dummy4[27]; +} struct_float; +static br_file_struct_member struct_float_file_members[] = { + { DF_TYPE_FLOAT, offsetof(struct_float, m1), "m1", NULL, }, + { DF_TYPE_FLOAT, offsetof(struct_float, m2), "m2", NULL, }, + { DF_TYPE_FLOAT, offsetof(struct_float, m3), "m3", NULL, }, + { DF_TYPE_FLOAT, offsetof(struct_float, m4), "m4", NULL, }, +}; +static br_file_struct struct_float_file = { + "struct_float", BR_ASIZE(struct_float_file_members), struct_float_file_members, sizeof(struct_float), +}; +static struct_float float_ref = { { 0 }, 0.5f, { 0 }, 256.f, { 0 }, 0.0625f, { 0 }, 3.14159f, { 0 }, }; +static const uint8_t binary_float_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x43, 0x80, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x40, 0x49, 0x0f, 0xd0, }; +static const char *text_float_data = + TEXT_MAGICS HOST_NL + " struct struct_float" HOST_NL + " float 0.5 # m1" HOST_NL + " float 256 # m2" HOST_NL + " float 0.0625 # m3" HOST_NL + " float 3.14159 # m4" HOST_NL; +static void test_datafile_binary_float() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_float read_struct; + + create_temp_file(tmpfilename, "float_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_float_file, &float_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_float_file, &float_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_float_data, tmpfilename, sizeof(binary_float_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_float_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&float_ref, &read_struct, sizeof(float_ref)); +} +static void test_datafile_text_float() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_float read_struct; + + create_temp_file(tmpfilename, "float_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_float_file, &float_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_float_file, &float_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_float_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_float_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&float_ref, &read_struct, sizeof(float_ref)); +} + +typedef struct struct_double { + char dummy0[11]; + double m1; + char dummy1[13]; + double m2; + char dummy2[17]; + double m3; + char dummy3[23]; + double m4; + char dummy4[27]; +} struct_double; +static br_file_struct_member struct_double_file_members[] = { + { DF_TYPE_DOUBLE, offsetof(struct_double, m1), "m1", NULL, }, + { DF_TYPE_DOUBLE, offsetof(struct_double, m2), "m2", NULL, }, + { DF_TYPE_DOUBLE, offsetof(struct_double, m3), "m3", NULL, }, + { DF_TYPE_DOUBLE, offsetof(struct_double, m4), "m4", NULL, }, +}; +static br_file_struct struct_double_file = { + "struct_double", BR_ASIZE(struct_double_file_members), struct_double_file_members, sizeof(struct_double), +}; +static struct_double double_ref = { { 0 }, 0.5, { 0 }, 256., { 0 }, 0.0625, { 0 }, 3.14159, { 0 }, }; +static const uint8_t binary_double_data[] = { BINARY_MAGICS, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x09, 0x21, 0xf9, 0xf0, 0x1b, 0x86, 0x6e, }; +static const char *text_double_data = + TEXT_MAGICS HOST_NL + " struct struct_double" HOST_NL + " double 0.5 # m1" HOST_NL + " double 256 # m2" HOST_NL + " double 0.0625 # m3" HOST_NL + " double 3.14159 # m4" HOST_NL; +static void test_datafile_binary_double() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_double read_struct; + + create_temp_file(tmpfilename, "double_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(32, DfStructSizeBinary(df_w, &struct_double_file, &double_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_double_file, &double_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_double_data, tmpfilename, sizeof(binary_double_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_double_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&double_ref, &read_struct, sizeof(double_ref)); +} +static void test_datafile_text_double() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_double read_struct; + + create_temp_file(tmpfilename, "double_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_double_file, &double_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_double_file, &double_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_double_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_double_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&double_ref, &read_struct, sizeof(double_ref)); +} + +enum { + ENUM_8_TYPE1 = 0, + ENUM_8_TYPE2 = 1, + ENUM_8_TYPE3 = 2, + ENUM_8_TYPE23 = ENUM_8_TYPE2 | ENUM_8_TYPE3, + ENUM_8_TYPE4 = 0xff, +}; +static br_file_enum_member file_test_enum_8_members[] = { + { ENUM_8_TYPE1, "ENUM_8_TYPE1", }, + { ENUM_8_TYPE2, "ENUM_8_TYPE2", }, + { ENUM_8_TYPE3, "ENUM_8_TYPE3", }, + { ENUM_8_TYPE23, "ENUM_8_TYPE2|ENUM_8_TYPE3", }, + { ENUM_8_TYPE4, "ENUM_8_TYPE4", }, +}; +static br_file_enum file_test_enum_8 = { + BR_ASIZE(file_test_enum_8_members), + file_test_enum_8_members, +}; +typedef struct struct_enum_8 { + char dummy0[11]; + br_uint_8 m1; + char dummy1[13]; + br_uint_8 m2; + char dummy2[17]; + br_uint_8 m3; + char dummy3[23]; + br_uint_8 m4; + char dummy4[27]; +} struct_enum_8; +static br_file_struct_member struct_enum_8_file_members[] = { + { DF_TYPE_ENUM_8, offsetof(struct_enum_8, m1), "m1", &file_test_enum_8, }, + { DF_TYPE_ENUM_8, offsetof(struct_enum_8, m2), "m2", &file_test_enum_8, }, + { DF_TYPE_ENUM_8, offsetof(struct_enum_8, m3), "m3", &file_test_enum_8, }, + { DF_TYPE_ENUM_8, offsetof(struct_enum_8, m4), "m4", &file_test_enum_8, }, +}; +static br_file_struct struct_enum_8_file = { + "struct_enum_8", BR_ASIZE(struct_enum_8_file_members), struct_enum_8_file_members, sizeof(struct_enum_8), +}; +static struct_enum_8 enum_8_ref = { { 0 }, ENUM_8_TYPE1, { 0 }, ENUM_8_TYPE2, { 0 }, ENUM_8_TYPE23, { 0 }, ENUM_8_TYPE4, { 0 }, }; +static const uint8_t binary_enum_8_data[] = { BINARY_MAGICS, 0x00, 0x01, 0x03, 0xff, }; +static const char *text_enum_8_data = + TEXT_MAGICS HOST_NL + " struct struct_enum_8" HOST_NL + " enum_8 ENUM_8_TYPE1 # m1" HOST_NL + " enum_8 ENUM_8_TYPE2 # m2" HOST_NL + " enum_8 ENUM_8_TYPE2|ENUM_8_TYPE3 # m3" HOST_NL + " enum_8 ENUM_8_TYPE4 # m4" HOST_NL; +static void test_datafile_binary_enum_8() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_enum_8 read_struct; + + create_temp_file(tmpfilename, "enum_8_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(4, DfStructSizeBinary(df_w, &struct_enum_8_file, &enum_8_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_enum_8_file, &enum_8_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_enum_8_data, tmpfilename, sizeof(binary_enum_8_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_enum_8_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&enum_8_ref, &read_struct, sizeof(enum_8_ref)); +} +static void test_datafile_text_enum_8() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_enum_8 read_struct; + + create_temp_file(tmpfilename, "enum_8_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_enum_8_file, &enum_8_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_enum_8_file, &enum_8_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_enum_8_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_enum_8_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&enum_8_ref, &read_struct, sizeof(enum_8_ref)); +} + +enum { + ENUM_16_TYPE1 = 0, + ENUM_16_TYPE2 = 0x1000, + ENUM_16_TYPE3 = 0x2000, + ENUM_16_TYPE23 = ENUM_16_TYPE2 | ENUM_16_TYPE3, + ENUM_16_TYPE4 = 0xffff, +}; +static br_file_enum_member file_test_enum_16_members[] = { + { ENUM_16_TYPE1, "ENUM_16_TYPE1", }, + { ENUM_16_TYPE2, "ENUM_16_TYPE2", }, + { ENUM_16_TYPE3, "TENUM_16_YPE3", }, + { ENUM_16_TYPE23, "ENUM_16_TYPE2|ENUM_16_TYPE3", }, + { ENUM_16_TYPE4, "ENUM_16_TYPE4", }, +}; +static br_file_enum file_test_enum_16 = { + BR_ASIZE(file_test_enum_16_members), + file_test_enum_16_members, +}; +typedef struct struct_enum_16 { + char dummy0[11]; + br_uint_16 m1; + char dummy1[13]; + br_uint_16 m2; + char dummy2[17]; + br_uint_16 m3; + char dummy3[23]; + br_uint_16 m4; + char dummy4[27]; +} struct_enum_16; +static br_file_struct_member struct_enum_16_file_members[] = { + { DF_TYPE_ENUM_16, offsetof(struct_enum_16, m1), "m1", &file_test_enum_16, }, + { DF_TYPE_ENUM_16, offsetof(struct_enum_16, m2), "m2", &file_test_enum_16, }, + { DF_TYPE_ENUM_16, offsetof(struct_enum_16, m3), "m3", &file_test_enum_16, }, + { DF_TYPE_ENUM_16, offsetof(struct_enum_16, m4), "m4", &file_test_enum_16, }, +}; +static br_file_struct struct_enum_16_file = { + "struct_enum_16", BR_ASIZE(struct_enum_16_file_members), struct_enum_16_file_members, sizeof(struct_enum_16), +}; +static struct_enum_16 enum_16_ref = { { 0 }, ENUM_16_TYPE1, { 0 }, ENUM_16_TYPE2, { 0 }, ENUM_16_TYPE23, { 0 }, ENUM_16_TYPE4, { 0 }, }; +static const uint8_t binary_enum_16_data[] = { BINARY_MAGICS, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0xff, 0xff, }; +static const char *text_enum_16_data = + TEXT_MAGICS HOST_NL + " struct struct_enum_16" HOST_NL + " enum_16 ENUM_16_TYPE1 # m1" HOST_NL + " enum_16 ENUM_16_TYPE2 # m2" HOST_NL + " enum_16 ENUM_16_TYPE2|ENUM_16_TYPE3 # m3" HOST_NL + " enum_16 ENUM_16_TYPE4 # m4" HOST_NL; +static void test_datafile_binary_enum_16() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_enum_16 read_struct; + + create_temp_file(tmpfilename, "enum_16_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(8, DfStructSizeBinary(df_w, &struct_enum_16_file, &enum_16_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_enum_16_file, &enum_16_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_enum_16_data, tmpfilename, sizeof(binary_enum_16_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_enum_16_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&enum_16_ref, &read_struct, sizeof(enum_16_ref)); +} +static void test_datafile_text_enum_16() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_enum_16 read_struct; + + create_temp_file(tmpfilename, "enum_16_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_enum_16_file, &enum_16_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_enum_16_file, &enum_16_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_enum_16_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_enum_16_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&enum_16_ref, &read_struct, sizeof(enum_16_ref)); +} + +enum { + ENUM_32_TYPE1 = 0, + ENUM_32_TYPE2 = 0x10000000, + ENUM_32_TYPE3 = 0x20000000, + ENUM_32_TYPE23 = ENUM_32_TYPE2 | ENUM_32_TYPE3, + ENUM_32_TYPE4 = 0xffffffff, +}; +static br_file_enum_member file_test_enum_32_members[] = { + { ENUM_32_TYPE1, "ENUM_32_TYPE1", }, + { ENUM_32_TYPE2, "ENUM_32_TYPE2", }, + { ENUM_32_TYPE3, "TENUM_32_YPE3", }, + { ENUM_32_TYPE23, "ENUM_32_TYPE2|ENUM_32_TYPE3", }, + { ENUM_32_TYPE4, "ENUM_32_TYPE4", }, +}; +static br_file_enum file_test_enum_32 = { + BR_ASIZE(file_test_enum_32_members), + file_test_enum_32_members, +}; +typedef struct struct_enum_32 { + char dummy0[11]; + br_uint_32 m1; + char dummy1[13]; + br_uint_32 m2; + char dummy2[17]; + br_uint_32 m3; + char dummy3[23]; + br_uint_32 m4; + char dummy4[27]; +} struct_enum_32; +static br_file_struct_member struct_enum_32_file_members[] = { + { DF_TYPE_ENUM_32, offsetof(struct_enum_32, m1), "m1", &file_test_enum_32, }, + { DF_TYPE_ENUM_32, offsetof(struct_enum_32, m2), "m2", &file_test_enum_32, }, + { DF_TYPE_ENUM_32, offsetof(struct_enum_32, m3), "m3", &file_test_enum_32, }, + { DF_TYPE_ENUM_32, offsetof(struct_enum_32, m4), "m4", &file_test_enum_32, }, +}; +static br_file_struct struct_enum_32_file = { + "struct_enum_32", BR_ASIZE(struct_enum_32_file_members), struct_enum_32_file_members, sizeof(struct_enum_32), +}; +static struct_enum_32 enum_32_ref = { { 0 }, ENUM_32_TYPE1, { 0 }, ENUM_32_TYPE2, { 0 }, ENUM_32_TYPE23, { 0 }, ENUM_32_TYPE4, { 0 }, }; +static const uint8_t binary_enum_32_data[] = { BINARY_MAGICS, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, }; +static const char *text_enum_32_data = + TEXT_MAGICS HOST_NL + " struct struct_enum_32" HOST_NL + " enum_32 ENUM_32_TYPE1 # m1" HOST_NL + " enum_32 ENUM_32_TYPE2 # m2" HOST_NL + " enum_32 ENUM_32_TYPE2|ENUM_32_TYPE3 # m3" HOST_NL + " enum_32 ENUM_32_TYPE4 # m4" HOST_NL; +static void test_datafile_binary_enum_32() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_enum_32 read_struct; + + create_temp_file(tmpfilename, "enum_32_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_enum_32_file, &enum_32_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_enum_32_file, &enum_32_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_enum_32_data, tmpfilename, sizeof(binary_enum_32_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_enum_32_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&enum_32_ref, &read_struct, sizeof(enum_32_ref)); +} +static void test_datafile_text_enum_32() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_enum_32 read_struct; + + create_temp_file(tmpfilename, "enum_32_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_enum_32_file, &enum_32_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_enum_32_file, &enum_32_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_enum_32_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_enum_32_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&enum_32_ref, &read_struct, sizeof(enum_32_ref)); +} + +typedef struct struct_asciz { + char dummy0[11]; + char *m1; + char dummy1[13]; + char *m2; + char dummy2[17]; + char *m3; + char dummy3[23]; + char *m4; + char dummy4[27]; +} struct_asciz; +static br_file_struct_member struct_asciz_file_members[] = { + { DF_TYPE_ASCIZ, offsetof(struct_asciz, m1), "m1", NULL, }, + { DF_TYPE_ASCIZ, offsetof(struct_asciz, m2), "m2", NULL, }, + { DF_TYPE_ASCIZ, offsetof(struct_asciz, m3), "m3", NULL, }, + { DF_TYPE_ASCIZ, offsetof(struct_asciz, m4), "m4", NULL, }, +}; +static br_file_struct struct_asciz_file = { + "struct_asciz", BR_ASIZE(struct_asciz_file_members), struct_asciz_file_members, sizeof(struct_asciz), +}; +static struct_asciz asciz_ref = { { 0 }, "dethrace", { 0 }, NULL, { 0 }, "To be or not to be", { 0 }, "A very long string that is meant to test overspill", { 0 }, }; +static const uint8_t binary_asciz_data[] = { + BINARY_MAGICS, + 'd', 'e', 't', 'h', 'r', 'a', 'c', 'e', '\0', '\0', 'T', 'o', ' ', 'b', 'e', ' ', 'o', 'r', ' ', 'n', + 'o', 't', ' ', 't', 'o', ' ', 'b', 'e', '\0', 'A', ' ', 'v', 'e', 'r', 'y', ' ', 'l', 'o', 'n', 'g', + ' ', 's', 't', 'r', 'i', 'n', 'g', ' ', 't', 'h', 'a', 't', ' ', 'i', 's', ' ', 'm', 'e', 'a', 'n', + 't', ' ', 't', 'o', ' ', 't', 'e', 's', 't', ' ', 'o', 'v', 'e', 'r', 's', 'p', 'i', 'l', 'l', '\0', +}; +static const char *text_asciz_data = + TEXT_MAGICS HOST_NL + " struct struct_asciz" HOST_NL + " asciz \"dethrace\" # m1" HOST_NL + " asciz NULL # m2" HOST_NL + " asciz \"To be or not to be\" # m3" HOST_NL + " asciz \"A very long string that is meant to test overspill\" # m4" HOST_NL; + +static void test_datafile_binary_asciz() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_asciz read_struct; + int sumStringLengths; + + create_temp_file(tmpfilename, "asciz_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + sumStringLengths = strlen(asciz_ref.m1) + strlen(asciz_ref.m3) + strlen(asciz_ref.m4); + TEST_ASSERT_EQUAL_INT(sumStringLengths, DfStructSizeBinary(df_w, &struct_asciz_file, &asciz_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_asciz_file, &asciz_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_asciz_data, tmpfilename, sizeof(binary_asciz_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_asciz_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_STRING(asciz_ref.m1, read_struct.m1); + TEST_ASSERT_EQUAL_STRING("", read_struct.m2); + TEST_ASSERT_EQUAL_STRING(asciz_ref.m3, read_struct.m3); + TEST_ASSERT_EQUAL_STRING(asciz_ref.m4, read_struct.m4); +} +static void test_datafile_text_asciz() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_asciz read_struct; + + create_temp_file(tmpfilename, "asciz_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_asciz_file, &asciz_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_asciz_file, &asciz_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_asciz_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_asciz_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_STRING(asciz_ref.m1, read_struct.m1); + TEST_ASSERT_EQUAL_STRING(NULL, read_struct.m2); + TEST_ASSERT_EQUAL_STRING(asciz_ref.m3, read_struct.m3); + TEST_ASSERT_EQUAL_STRING(asciz_ref.m4, read_struct.m4); +} + +typedef struct struct_br_colour { + char dummy0[11]; + br_colour m1; + char dummy1[13]; + br_colour m2; + char dummy2[17]; + br_colour m3; + char dummy3[23]; + br_colour m4; + char dummy4[27]; +} struct_br_colour; +static br_file_struct_member struct_br_colour_file_members[] = { + { DF_TYPE_BR_COLOUR, offsetof(struct_br_colour, m1), "m1", NULL, }, + { DF_TYPE_BR_COLOUR, offsetof(struct_br_colour, m2), "m2", NULL, }, + { DF_TYPE_BR_COLOUR, offsetof(struct_br_colour, m3), "m3", NULL, }, + { DF_TYPE_BR_COLOUR, offsetof(struct_br_colour, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_colour_file = { + "struct_br_colour", BR_ASIZE(struct_br_colour_file_members), struct_br_colour_file_members, sizeof(struct_br_colour), +}; +static struct_br_colour br_colour_ref = { { 0 }, 0xff0000, { 0 }, 0x00ff00, { 0 }, 0x0000ff, { 0 }, 0x4080c0, { 0 }, }; +static const uint8_t binary_br_colour_data[] = { BINARY_MAGICS, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x40, 0x80, 0xc0, }; +static const char *text_br_colour_data = + TEXT_MAGICS HOST_NL + " struct struct_br_colour" HOST_NL + " colour 255,0,0 # m1" HOST_NL + " colour 0,255,0 # m2" HOST_NL + " colour 0,0,255 # m3" HOST_NL + " colour 64,128,192 # m4" HOST_NL; +static void test_datafile_binary_br_colour() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_colour read_struct; + + create_temp_file(tmpfilename, "br_colour_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_colour_file, &br_colour_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_colour_file, &br_colour_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_colour_data, tmpfilename, sizeof(binary_br_colour_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_colour_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_colour_ref, &read_struct, sizeof(br_colour_ref)); +} +static void test_datafile_text_br_colour() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_colour read_struct; + + create_temp_file(tmpfilename, "br_colour_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_colour_file, &br_colour_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_colour_file, &br_colour_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_colour_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_colour_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_colour_ref, &read_struct, sizeof(br_colour_ref)); +} + +typedef struct struct_br_fraction_x { + char dummy0[11]; + br_fraction_x m1; + char dummy1[13]; + br_fraction_x m2; + char dummy2[17]; + br_fraction_x m3; + char dummy3[23]; + br_fraction_x m4; + char dummy4[27]; +} struct_br_fraction_x; +static br_file_struct_member struct_br_fraction_x_file_members[] = { + { DF_TYPE_BR_FRACTION_X, offsetof(struct_br_fraction_x, m1), "m1", NULL, }, + { DF_TYPE_BR_FRACTION_X, offsetof(struct_br_fraction_x, m2), "m2", NULL, }, + { DF_TYPE_BR_FRACTION_X, offsetof(struct_br_fraction_x, m3), "m3", NULL, }, + { DF_TYPE_BR_FRACTION_X, offsetof(struct_br_fraction_x, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_fraction_x_file = { + "struct_br_fraction_x", BR_ASIZE(struct_br_fraction_x_file_members), struct_br_fraction_x_file_members, sizeof(struct_br_fraction_x), +}; +static struct_br_fraction_x br_fraction_x_ref = { { 0 }, 0x00008000, { 0 }, 0x00004000, { 0 }, 0x0000c000, { 0 }, 0x00000000, { 0 }, }; +static const uint8_t binary_br_fraction_x_data[] = { BINARY_MAGICS, 0xbf, 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +static const char *text_br_fraction_x_data = + TEXT_MAGICS HOST_NL + " struct struct_br_fraction_x" HOST_NL + " fixed_fraction -1 # m1" HOST_NL + " fixed_fraction 0.5 # m2" HOST_NL + " fixed_fraction -0.5 # m3" HOST_NL + " fixed_fraction 0 # m4" HOST_NL; +static void test_datafile_binary_br_fraction_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_fraction_x read_struct; + + create_temp_file(tmpfilename, "br_fraction_x_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_fraction_x_file, &br_fraction_x_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_fraction_x_file, &br_fraction_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_fraction_x_data, tmpfilename, sizeof(binary_br_fraction_x_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_fraction_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_fraction_x_ref.m1, read_struct.m1); + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_fraction_x_ref.m2, read_struct.m2); + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_fraction_x_ref.m3, read_struct.m3); + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_fraction_x_ref.m4, read_struct.m4); +} +static void test_datafile_text_br_fraction_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_fraction_x read_struct; + + create_temp_file(tmpfilename, "br_fraction_x_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_fraction_x_file, &br_fraction_x_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_fraction_x_file, &br_fraction_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_fraction_x_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_fraction_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_fraction_x_ref, &read_struct, sizeof(br_fraction_x_ref)); +} + +typedef struct struct_br_ufraction_x { + char dummy0[11]; + br_ufraction_x m1; + char dummy1[13]; + br_ufraction_x m2; + char dummy2[17]; + br_ufraction_x m3; + char dummy3[23]; + br_ufraction_x m4; + char dummy4[27]; +} struct_br_ufraction_x; +static br_file_struct_member struct_br_ufraction_x_file_members[] = { + { DF_TYPE_BR_UFRACTION_X, offsetof(struct_br_ufraction_x, m1), "m1", NULL, }, + { DF_TYPE_BR_UFRACTION_X, offsetof(struct_br_ufraction_x, m2), "m2", NULL, }, + { DF_TYPE_BR_UFRACTION_X, offsetof(struct_br_ufraction_x, m3), "m3", NULL, }, + { DF_TYPE_BR_UFRACTION_X, offsetof(struct_br_ufraction_x, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_ufraction_x_file = { + "struct_br_ufraction_x", BR_ASIZE(struct_br_ufraction_x_file_members), struct_br_ufraction_x_file_members, sizeof(struct_br_ufraction_x), +}; +static struct_br_ufraction_x br_ufraction_x_ref = { { 0 }, 0x00008000, { 0 }, 0x00004000, { 0 }, 0x0000c000, { 0 }, 0x00000000, { 0 }, }; +static const uint8_t binary_br_ufraction_x_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x3f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +static const char *text_br_ufraction_x_data = + TEXT_MAGICS HOST_NL + " struct struct_br_ufraction_x" HOST_NL + " fixed_ufraction 0.5 # m1" HOST_NL + " fixed_ufraction 0.25 # m2" HOST_NL + " fixed_ufraction 0.75 # m3" HOST_NL + " fixed_ufraction 0 # m4" HOST_NL; +static void test_datafile_binary_br_ufraction_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_ufraction_x read_struct; + + create_temp_file(tmpfilename, "br_ufraction_x_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_ufraction_x_file, &br_ufraction_x_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_ufraction_x_file, &br_ufraction_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_ufraction_x_data, tmpfilename, sizeof(binary_br_ufraction_x_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_ufraction_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_ufraction_x_ref.m1, read_struct.m1); + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_ufraction_x_ref.m2, read_struct.m2); + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_ufraction_x_ref.m3, read_struct.m3); + TEST_ASSERT_INT16_WITHIN(BrFloatToFixed(1e-3), br_ufraction_x_ref.m4, read_struct.m4); +} +static void test_datafile_text_br_ufraction_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_ufraction_x read_struct; + + create_temp_file(tmpfilename, "br_ufraction_x_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_ufraction_x_file, &br_ufraction_x_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_ufraction_x_file, &br_ufraction_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_ufraction_x_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_ufraction_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_ufraction_x_ref, &read_struct, sizeof(br_ufraction_x_ref)); +} + +typedef struct struct_br_fraction_f { + char dummy0[11]; + br_fraction_f m1; + char dummy1[13]; + br_fraction_f m2; + char dummy2[17]; + br_fraction_f m3; + char dummy3[23]; + br_fraction_f m4; + char dummy4[27]; +} struct_br_fraction_f; +static br_file_struct_member struct_br_fraction_f_file_members[] = { + { DF_TYPE_BR_FRACTION_F, offsetof(struct_br_fraction_f, m1), "m1", NULL, }, + { DF_TYPE_BR_FRACTION_F, offsetof(struct_br_fraction_f, m2), "m2", NULL, }, + { DF_TYPE_BR_FRACTION_F, offsetof(struct_br_fraction_f, m3), "m3", NULL, }, + { DF_TYPE_BR_FRACTION_F, offsetof(struct_br_fraction_f, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_fraction_f_file = { + "struct_br_fraction_f", BR_ASIZE(struct_br_fraction_f_file_members), struct_br_fraction_f_file_members, sizeof(struct_br_fraction_f), +}; +static struct_br_fraction_f br_fraction_f_ref = { { 0 }, -1.f, { 0 }, 0.5f, { 0 }, -0.5f, { 0 }, 0.f, { 0 }, }; +static const uint8_t binary_br_fraction_f_data[] = { BINARY_MAGICS, 0xbf, 0x80, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +static const char *text_br_fraction_f_data = + TEXT_MAGICS HOST_NL + " struct struct_br_fraction_f" HOST_NL + " float_fraction -1 # m1" HOST_NL + " float_fraction 0.5 # m2" HOST_NL + " float_fraction -0.5 # m3" HOST_NL + " float_fraction 0 # m4" HOST_NL;; +static void test_datafile_binary_br_fraction_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_fraction_f read_struct; + + create_temp_file(tmpfilename, "br_fraction_f_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_fraction_f_file, &br_fraction_f_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_fraction_f_file, &br_fraction_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_fraction_f_data, tmpfilename, sizeof(binary_br_fraction_f_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_fraction_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_fraction_f_ref, &read_struct, sizeof(br_fraction_f_ref)); +} +static void test_datafile_text_br_fraction_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_fraction_f read_struct; + + create_temp_file(tmpfilename, "br_fraction_f_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_fraction_f_file, &br_fraction_f_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_fraction_f_file, &br_fraction_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_fraction_f_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_fraction_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_fraction_f_ref, &read_struct, sizeof(br_fraction_f_ref)); +} + +typedef struct struct_br_ufraction_f { + char dummy0[11]; + br_ufraction_f m1; + char dummy1[13]; + br_ufraction_f m2; + char dummy2[17]; + br_ufraction_f m3; + char dummy3[23]; + br_ufraction_f m4; + char dummy4[27]; +} struct_br_ufraction_f; +static br_file_struct_member struct_br_ufraction_f_file_members[] = { + { DF_TYPE_BR_UFRACTION_F, offsetof(struct_br_ufraction_f, m1), "m1", NULL, }, + { DF_TYPE_BR_UFRACTION_F, offsetof(struct_br_ufraction_f, m2), "m2", NULL, }, + { DF_TYPE_BR_UFRACTION_F, offsetof(struct_br_ufraction_f, m3), "m3", NULL, }, + { DF_TYPE_BR_UFRACTION_F, offsetof(struct_br_ufraction_f, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_ufraction_f_file = { + "struct_br_ufraction_f", BR_ASIZE(struct_br_ufraction_f_file_members), struct_br_ufraction_f_file_members, sizeof(struct_br_ufraction_f), +}; +static struct_br_ufraction_f br_ufraction_f_ref = { { 0 }, 0.5, { 0 }, 0.25f, { 0 }, 0.75f, { 0 }, 0.f, { 0 }, }; +static const uint8_t binary_br_ufraction_f_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x3f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +static const char *text_br_ufraction_f_data = + TEXT_MAGICS HOST_NL + " struct struct_br_ufraction_f" HOST_NL + " float_ufraction 0.5 # m1" HOST_NL + " float_ufraction 0.25 # m2" HOST_NL + " float_ufraction 0.75 # m3" HOST_NL + " float_ufraction 0 # m4" HOST_NL;; +static void test_datafile_binary_br_ufraction_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_ufraction_f read_struct; + + create_temp_file(tmpfilename, "br_ufraction_f_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(16, DfStructSizeBinary(df_w, &struct_br_ufraction_f_file, &br_ufraction_f_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_ufraction_f_file, &br_ufraction_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_ufraction_f_data, tmpfilename, sizeof(binary_br_ufraction_f_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_ufraction_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_ufraction_f_ref, &read_struct, sizeof(br_ufraction_f_ref)); +} +static void test_datafile_text_br_ufraction_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_ufraction_f read_struct; + + create_temp_file(tmpfilename, "br_ufraction_f_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_ufraction_f_file, &br_ufraction_f_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_ufraction_f_file, &br_ufraction_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_ufraction_f_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_ufraction_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_ufraction_f_ref, &read_struct, sizeof(br_ufraction_f_ref)); +} + +typedef struct struct_br_vector2_x { + char dummy0[11]; + br_vector2_x m1; + char dummy1[13]; + br_vector2_x m2; + char dummy2[17]; + br_vector2_x m3; + char dummy3[23]; + br_vector2_x m4; + char dummy4[27]; +} struct_br_vector2_x; +static br_file_struct_member struct_br_vector2_x_file_members[] = { + { DF_TYPE_BR_VECTOR2_X, offsetof(struct_br_vector2_x, m1), "m1", NULL, }, + { DF_TYPE_BR_VECTOR2_X, offsetof(struct_br_vector2_x, m2), "m2", NULL, }, + { DF_TYPE_BR_VECTOR2_X, offsetof(struct_br_vector2_x, m3), "m3", NULL, }, + { DF_TYPE_BR_VECTOR2_X, offsetof(struct_br_vector2_x, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_vector2_x_file = { + "struct_br_vector2_x", BR_ASIZE(struct_br_vector2_x_file_members), struct_br_vector2_x_file_members, sizeof(struct_br_vector2_x), +}; +static struct_br_vector2_x br_vector2_x_ref = { { 0 }, {{0x00008000, 0x00004000}}, { 0 }, {{0x00020000, 0x00040000}}, { 0 }, {{0xffff0000, 0xfffe0000}}, { 0 }, {{0xffff8000, 0xffffc000}}, { 0 }, }; +static const uint8_t binary_br_vector2_x_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x80, 0x00, 0x00, }; +static const char *text_br_vector2_x_data = + TEXT_MAGICS HOST_NL + " struct struct_br_vector2_x" HOST_NL + " fixed_vector2 0.5,0.25 # m1" HOST_NL + " fixed_vector2 2,4 # m2" HOST_NL + " fixed_vector2 -1,-2 # m3" HOST_NL + " fixed_vector2 -0.5,-0.25 # m4" HOST_NL; +static void test_datafile_binary_br_vector2_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector2_x read_struct; + + create_temp_file(tmpfilename, "br_vector2_x_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(32, DfStructSizeBinary(df_w, &struct_br_vector2_x_file, &br_vector2_x_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_vector2_x_file, &br_vector2_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_vector2_x_data, tmpfilename, sizeof(binary_br_vector2_x_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_vector2_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector2_x_ref, &read_struct, sizeof(br_vector2_x_ref)); +} +static void test_datafile_text_br_vector2_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector2_x read_struct; + + create_temp_file(tmpfilename, "br_vector2_x_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_vector2_x_file, &br_vector2_x_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_vector2_x_file, &br_vector2_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_vector2_x_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_vector2_x_file, &read_struct); + DfClose(df_r); + + printf("0x%08x 0x%08x ", br_vector2_x_ref.m1.v[0], read_struct.m1.v[0]);printf("0x%08x 0x%08x\n", br_vector2_x_ref.m1.v[1], read_struct.m1.v[0]); + printf("0x%08x 0x%08x ", br_vector2_x_ref.m2.v[0], read_struct.m2.v[0]);printf("0x%08x 0x%08x\n", br_vector2_x_ref.m2.v[1], read_struct.m2.v[0]); + printf("0x%08x 0x%08x ", br_vector2_x_ref.m3.v[0], read_struct.m3.v[0]);printf("0x%08x 0x%08x\n", br_vector2_x_ref.m3.v[1], read_struct.m3.v[0]); + printf("0x%08x 0x%08x ", br_vector2_x_ref.m4.v[0], read_struct.m4.v[0]);printf("0x%08x 0x%08x\n", br_vector2_x_ref.m4.v[1], read_struct.m4.v[0]); + TEST_ASSERT_EQUAL_MEMORY(&br_vector2_x_ref, &read_struct, sizeof(br_vector2_x_ref)); +} + +typedef struct struct_br_vector3_x { + char dummy0[11]; + br_vector3_x m1; + char dummy1[13]; + br_vector3_x m2; + char dummy2[17]; + br_vector3_x m3; + char dummy3[23]; + br_vector3_x m4; + char dummy4[27]; +} struct_br_vector3_x; +static br_file_struct_member struct_br_vector3_x_file_members[] = { + { DF_TYPE_BR_VECTOR3_X, offsetof(struct_br_vector3_x, m1), "m1", NULL, }, + { DF_TYPE_BR_VECTOR3_X, offsetof(struct_br_vector3_x, m2), "m2", NULL, }, + { DF_TYPE_BR_VECTOR3_X, offsetof(struct_br_vector3_x, m3), "m3", NULL, }, + { DF_TYPE_BR_VECTOR3_X, offsetof(struct_br_vector3_x, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_vector3_x_file = { + "struct_br_vector3_x", BR_ASIZE(struct_br_vector3_x_file_members), struct_br_vector3_x_file_members, sizeof(struct_br_vector3_x), +}; +static struct_br_vector3_x br_vector3_x_ref = { { 0 }, {{0x00008000, 0x00004000, 0x00002000}}, { 0 }, {{0x00020000, 0x00040000, 0x00080000}}, { 0 }, {{0xffff0000, 0xfffe0000, 0xfffc0000}}, { 0 }, {{0xffff8000, 0xffffc000, 0xffffe000}}, { 0 }, }; +static const uint8_t binary_br_vector3_x_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x80, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, }; +static const char *text_br_vector3_x_data = + TEXT_MAGICS HOST_NL + " struct struct_br_vector3_x" HOST_NL + " fixed_vector3 0.5,0.25,0.125 # m1" HOST_NL + " fixed_vector3 2,4,8 # m2" HOST_NL + " fixed_vector3 -1,-2,-4 # m3" HOST_NL + " fixed_vector3 -0.5,-0.25,-0.125 # m4" HOST_NL; +static void test_datafile_binary_br_vector3_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector3_x read_struct; + + create_temp_file(tmpfilename, "br_vector3_x_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(48, DfStructSizeBinary(df_w, &struct_br_vector3_x_file, &br_vector3_x_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_vector3_x_file, &br_vector3_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_vector3_x_data, tmpfilename, sizeof(binary_br_vector3_x_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_vector3_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector3_x_ref, &read_struct, sizeof(br_vector3_x_ref)); +} +static void test_datafile_text_br_vector3_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector3_x read_struct; + + create_temp_file(tmpfilename, "br_vector3_x_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_vector3_x_file, &br_vector3_x_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_vector3_x_file, &br_vector3_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_vector3_x_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_vector3_x_file, &read_struct); + DfClose(df_r); + + printf("0x%08x 0x%08x ", br_vector3_x_ref.m1.v[0], read_struct.m1.v[0]);printf("0x%08x 0x%08x\n", br_vector3_x_ref.m1.v[1], read_struct.m1.v[0]); + printf("0x%08x 0x%08x ", br_vector3_x_ref.m2.v[0], read_struct.m2.v[0]);printf("0x%08x 0x%08x\n", br_vector3_x_ref.m2.v[1], read_struct.m2.v[0]); + printf("0x%08x 0x%08x ", br_vector3_x_ref.m3.v[0], read_struct.m3.v[0]);printf("0x%08x 0x%08x\n", br_vector3_x_ref.m3.v[1], read_struct.m3.v[0]); + printf("0x%08x 0x%08x ", br_vector3_x_ref.m4.v[0], read_struct.m4.v[0]);printf("0x%08x 0x%08x\n", br_vector3_x_ref.m4.v[1], read_struct.m4.v[0]); + TEST_ASSERT_EQUAL_MEMORY(&br_vector3_x_ref, &read_struct, sizeof(br_vector3_x_ref)); +} + +typedef struct struct_br_vector4_x { + char dummy0[11]; + br_vector4_x m1; + char dummy1[13]; + br_vector4_x m2; + char dummy2[17]; + br_vector4_x m3; + char dummy3[23]; + br_vector4_x m4; + char dummy4[27]; +} struct_br_vector4_x; +static br_file_struct_member struct_br_vector4_x_file_members[] = { + { DF_TYPE_BR_VECTOR4_X, offsetof(struct_br_vector4_x, m1), "m1", NULL, }, + { DF_TYPE_BR_VECTOR4_X, offsetof(struct_br_vector4_x, m2), "m2", NULL, }, + { DF_TYPE_BR_VECTOR4_X, offsetof(struct_br_vector4_x, m3), "m3", NULL, }, + { DF_TYPE_BR_VECTOR4_X, offsetof(struct_br_vector4_x, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_vector4_x_file = { + "struct_br_vector4_x", BR_ASIZE(struct_br_vector4_x_file_members), struct_br_vector4_x_file_members, sizeof(struct_br_vector4_x), +}; +static struct_br_vector4_x br_vector4_x_ref = { { 0 }, {{0x00008000, 0x00004000, 0x00002000, 0x00001000}}, { 0 }, {{0x00020000, 0x00040000, 0x00080000, 0x00100000}}, { 0 }, {{0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000}}, { 0 }, {{0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000}}, { 0 }, }; +static const uint8_t binary_br_vector4_x_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x41, 0x80, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x80, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xbd, 0x80, 0x00, 0x00, }; +static const char *text_br_vector4_x_data = + TEXT_MAGICS HOST_NL + " struct struct_br_vector4_x" HOST_NL + " fixed_vector4 0.5,0.25,0.125,0.0625 # m1" HOST_NL + " fixed_vector4 2,4,8,16 # m2" HOST_NL + " fixed_vector4 -1,-2,-4,-8 # m3" HOST_NL + " fixed_vector4 -0.5,-0.25,-0.125,-0.0625 # m4" HOST_NL; +static void test_datafile_binary_br_vector4_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector4_x read_struct; + + create_temp_file(tmpfilename, "br_vector4_x_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(64, DfStructSizeBinary(df_w, &struct_br_vector4_x_file, &br_vector4_x_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_vector4_x_file, &br_vector4_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_vector4_x_data, tmpfilename, sizeof(binary_br_vector4_x_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_vector4_x_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector4_x_ref, &read_struct, sizeof(br_vector4_x_ref)); +} +static void test_datafile_text_br_vector4_x() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector4_x read_struct; + + create_temp_file(tmpfilename, "br_vector4_x_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_vector4_x_file, &br_vector4_x_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_vector4_x_file, &br_vector4_x_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_vector4_x_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_vector4_x_file, &read_struct); + DfClose(df_r); + + printf("0x%08x 0x%08x ", br_vector4_x_ref.m1.v[0], read_struct.m1.v[0]);printf("0x%08x 0x%08x\n", br_vector4_x_ref.m1.v[1], read_struct.m1.v[0]); + printf("0x%08x 0x%08x ", br_vector4_x_ref.m2.v[0], read_struct.m2.v[0]);printf("0x%08x 0x%08x\n", br_vector4_x_ref.m2.v[1], read_struct.m2.v[0]); + printf("0x%08x 0x%08x ", br_vector4_x_ref.m3.v[0], read_struct.m3.v[0]);printf("0x%08x 0x%08x\n", br_vector4_x_ref.m3.v[1], read_struct.m3.v[0]); + printf("0x%08x 0x%08x ", br_vector4_x_ref.m4.v[0], read_struct.m4.v[0]);printf("0x%08x 0x%08x\n", br_vector4_x_ref.m4.v[1], read_struct.m4.v[0]); + TEST_ASSERT_EQUAL_MEMORY(&br_vector4_x_ref, &read_struct, sizeof(br_vector4_x_ref)); +} + +typedef struct struct_br_vector2_f { + char dummy0[11]; + br_vector2_f m1; + char dummy1[13]; + br_vector2_f m2; + char dummy2[17]; + br_vector2_f m3; + char dummy3[23]; + br_vector2_f m4; + char dummy4[27]; +} struct_br_vector2_f; +static br_file_struct_member struct_br_vector2_f_file_members[] = { + { DF_TYPE_BR_VECTOR2_F, offsetof(struct_br_vector2_f, m1), "m1", NULL, }, + { DF_TYPE_BR_VECTOR2_F, offsetof(struct_br_vector2_f, m2), "m2", NULL, }, + { DF_TYPE_BR_VECTOR2_F, offsetof(struct_br_vector2_f, m3), "m3", NULL, }, + { DF_TYPE_BR_VECTOR2_F, offsetof(struct_br_vector2_f, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_vector2_f_file = { + "struct_br_vector2_f", BR_ASIZE(struct_br_vector2_f_file_members), struct_br_vector2_f_file_members, sizeof(struct_br_vector2_f), +}; +static struct_br_vector2_f br_vector2_f_ref = { { 0 }, {{0.5f, 0.25f}}, { 0 }, {{2.f, 4.f}}, { 0 }, {{-1.f, -2.f}}, { 0 }, {{-0.5f, -0.25f}}, { 0 }, }; +static const uint8_t binary_br_vector2_f_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x80, 0x00, 0x00, }; +static const char *text_br_vector2_f_data = + TEXT_MAGICS HOST_NL + " struct struct_br_vector2_f" HOST_NL + " float_vector2 0.5,0.25 # m1" HOST_NL + " float_vector2 2,4 # m2" HOST_NL + " float_vector2 -1,-2 # m3" HOST_NL + " float_vector2 -0.5,-0.25 # m4" HOST_NL; +static void test_datafile_binary_br_vector2_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector2_f read_struct; + + create_temp_file(tmpfilename, "br_vector2_f_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(32, DfStructSizeBinary(df_w, &struct_br_vector2_f_file, &br_vector2_f_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_vector2_f_file, &br_vector2_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_vector2_f_data, tmpfilename, sizeof(binary_br_vector2_f_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_vector2_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector2_f_ref, &read_struct, sizeof(br_vector2_f_ref)); +} +static void test_datafile_text_br_vector2_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector2_f read_struct; + + create_temp_file(tmpfilename, "br_vector2_f_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_vector2_f_file, &br_vector2_f_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_vector2_f_file, &br_vector2_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_vector2_f_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_vector2_f_file, &read_struct); + DfClose(df_r); + + printf("0x%08x 0x%08x ", br_vector2_f_ref.m1.v[0], read_struct.m1.v[0]);printf("0x%08x 0x%08x\n", br_vector2_f_ref.m1.v[1], read_struct.m1.v[0]); + printf("0x%08x 0x%08x ", br_vector2_f_ref.m2.v[0], read_struct.m2.v[0]);printf("0x%08x 0x%08x\n", br_vector2_f_ref.m2.v[1], read_struct.m2.v[0]); + printf("0x%08x 0x%08x ", br_vector2_f_ref.m3.v[0], read_struct.m3.v[0]);printf("0x%08x 0x%08x\n", br_vector2_f_ref.m3.v[1], read_struct.m3.v[0]); + printf("0x%08x 0x%08x ", br_vector2_f_ref.m4.v[0], read_struct.m4.v[0]);printf("0x%08x 0x%08x\n", br_vector2_f_ref.m4.v[1], read_struct.m4.v[0]); + TEST_ASSERT_EQUAL_MEMORY(&br_vector2_f_ref, &read_struct, sizeof(br_vector2_f_ref)); +} + +typedef struct struct_br_vector3_f { + char dummy0[11]; + br_vector3_f m1; + char dummy1[13]; + br_vector3_f m2; + char dummy2[17]; + br_vector3_f m3; + char dummy3[23]; + br_vector3_f m4; + char dummy4[27]; +} struct_br_vector3_f; +static br_file_struct_member struct_br_vector3_f_file_members[] = { + { DF_TYPE_BR_VECTOR3_F, offsetof(struct_br_vector3_f, m1), "m1", NULL, }, + { DF_TYPE_BR_VECTOR3_F, offsetof(struct_br_vector3_f, m2), "m2", NULL, }, + { DF_TYPE_BR_VECTOR3_F, offsetof(struct_br_vector3_f, m3), "m3", NULL, }, + { DF_TYPE_BR_VECTOR3_F, offsetof(struct_br_vector3_f, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_vector3_f_file = { + "struct_br_vector3_f", BR_ASIZE(struct_br_vector3_f_file_members), struct_br_vector3_f_file_members, sizeof(struct_br_vector3_f), +}; +static struct_br_vector3_f br_vector3_f_ref = { { 0 }, {{0.5f, 0.25f, 0.125f}}, { 0 }, {{2.f, 4.f, 8.f}}, { 0 }, {{-1.f, -2.f, -4.f}}, { 0 }, {{-0.5f, -0.25f, -0.125f}}, { 0 }, }; +static const uint8_t binary_br_vector3_f_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x80, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, }; +static const char *text_br_vector3_f_data = + TEXT_MAGICS HOST_NL + " struct struct_br_vector3_f" HOST_NL + " float_vector3 0.5,0.25,0.125 # m1" HOST_NL + " float_vector3 2,4,8 # m2" HOST_NL + " float_vector3 -1,-2,-4 # m3" HOST_NL + " float_vector3 -0.5,-0.25,-0.125 # m4" HOST_NL; +static void test_datafile_binary_br_vector3_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector3_f read_struct; + + create_temp_file(tmpfilename, "br_vector3_f_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(48, DfStructSizeBinary(df_w, &struct_br_vector3_f_file, &br_vector3_f_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_vector3_f_file, &br_vector3_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_vector3_f_data, tmpfilename, sizeof(binary_br_vector3_f_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_vector3_f_file, &read_struct); + DfClose(df_r); + + printf("%f %f", br_vector3_f_ref.m1.v[0], read_struct.m1.v[0]); printf("%f %f", br_vector3_f_ref.m1.v[1], read_struct.m1.v[1]); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector3_f_ref, &read_struct, sizeof(br_vector3_f_ref)); +} +static void test_datafile_text_br_vector3_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector3_f read_struct; + + create_temp_file(tmpfilename, "br_vector3_f_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_vector3_f_file, &br_vector3_f_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_vector3_f_file, &br_vector3_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_vector3_f_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_vector3_f_file, &read_struct); + DfClose(df_r); + + printf("0x%08x 0x%08x ", br_vector3_f_ref.m1.v[0], read_struct.m1.v[0]);printf("0x%08x 0x%08x\n", br_vector3_f_ref.m1.v[1], read_struct.m1.v[0]); + printf("0x%08x 0x%08x ", br_vector3_f_ref.m2.v[0], read_struct.m2.v[0]);printf("0x%08x 0x%08x\n", br_vector3_f_ref.m2.v[1], read_struct.m2.v[0]); + printf("0x%08x 0x%08x ", br_vector3_f_ref.m3.v[0], read_struct.m3.v[0]);printf("0x%08x 0x%08x\n", br_vector3_f_ref.m3.v[1], read_struct.m3.v[0]); + printf("0x%08x 0x%08x ", br_vector3_f_ref.m4.v[0], read_struct.m4.v[0]);printf("0x%08x 0x%08x\n", br_vector3_f_ref.m4.v[1], read_struct.m4.v[0]); + TEST_ASSERT_EQUAL_MEMORY(&br_vector3_f_ref, &read_struct, sizeof(br_vector3_f_ref)); +} + +typedef struct struct_br_vector4_f { + char dummy0[11]; + br_vector4_f m1; + char dummy1[13]; + br_vector4_f m2; + char dummy2[17]; + br_vector4_f m3; + char dummy3[23]; + br_vector4_f m4; + char dummy4[27]; +} struct_br_vector4_f; +static br_file_struct_member struct_br_vector4_f_file_members[] = { + { DF_TYPE_BR_VECTOR4_F, offsetof(struct_br_vector4_f, m1), "m1", NULL, }, + { DF_TYPE_BR_VECTOR4_F, offsetof(struct_br_vector4_f, m2), "m2", NULL, }, + { DF_TYPE_BR_VECTOR4_F, offsetof(struct_br_vector4_f, m3), "m3", NULL, }, + { DF_TYPE_BR_VECTOR4_F, offsetof(struct_br_vector4_f, m4), "m4", NULL, }, +}; +static br_file_struct struct_br_vector4_f_file = { + "struct_br_vector4_f", BR_ASIZE(struct_br_vector4_f_file_members), struct_br_vector4_f_file_members, sizeof(struct_br_vector4_f), +}; +static struct_br_vector4_f br_vector4_f_ref = { { 0 }, {{0.5f, 0.25f, 0.125f, 0.0625f}}, { 0 }, {{2.f, 4.f, 8.f, 16.f}}, { 0 }, {{-1.f, -2.f, -4.f, -8.f}}, { 0 }, {{-0.5f, -0.25f, -0.125f, -0.0625f}}, { 0 }, }; +static const uint8_t binary_br_vector4_f_data[] = { BINARY_MAGICS, 0x3f, 0x00, 0x00, 0x00, 0x3e, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3d, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x41, 0x80, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbe, 0x80, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xbd, 0x80, 0x00, 0x00, }; +static const char *text_br_vector4_f_data = + TEXT_MAGICS HOST_NL + " struct struct_br_vector4_f" HOST_NL + " float_vector4 0.5,0.25,0.125,0.0625 # m1" HOST_NL + " float_vector4 2,4,8,16 # m2" HOST_NL + " float_vector4 -1,-2,-4,-8 # m3" HOST_NL + " float_vector4 -0.5,-0.25,-0.125,-0.0625 # m4" HOST_NL; +static void test_datafile_binary_br_vector4_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector4_f read_struct; + + create_temp_file(tmpfilename, "br_vector4_f_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(64, DfStructSizeBinary(df_w, &struct_br_vector4_f_file, &br_vector4_f_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_br_vector4_f_file, &br_vector4_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_br_vector4_f_data, tmpfilename, sizeof(binary_br_vector4_f_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_br_vector4_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector4_f_ref, &read_struct, sizeof(br_vector4_f_ref)); +} +static void test_datafile_text_br_vector4_f() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_br_vector4_f read_struct; + + create_temp_file(tmpfilename, "br_vector4_f_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(5, DfStructSizeText(df_w, &struct_br_vector4_f_file, &br_vector4_f_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_br_vector4_f_file, &br_vector4_f_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_br_vector4_f_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_br_vector4_f_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_MEMORY(&br_vector4_f_ref, &read_struct, sizeof(br_vector4_f_ref)); +} + +typedef struct { + float float1; + br_fixed_ls fixed1; + br_uint_32 u32_1; + char *s; +} struct_substruct1; +static br_file_struct_member struct_struct_substruct1_members[] = { + { DF_TYPE_FLOAT, offsetof(struct_substruct1, float1), "float1", NULL, }, + { DF_TYPE_BR_FIXED, offsetof(struct_substruct1, fixed1), "fixed1", NULL, }, + { DF_TYPE_BR_UINT_32, offsetof(struct_substruct1, u32_1), "u32_1", NULL, }, +}; +static br_file_struct struct_substruct1_file = { + "struct_substruct1", BR_ASIZE(struct_struct_substruct1_members), struct_struct_substruct1_members, sizeof(struct_substruct1), +}; +typedef struct { + br_vector3_f vf2; + br_angle a2; + br_uint_8 e8_2; + struct_substruct1 s_2; +} struct_substruct2; +static br_file_struct_member struct_struct_substruct2_members[] = { + { DF_TYPE_BR_VECTOR2_F, offsetof(struct_substruct2, vf2), "vf2", NULL, }, + { DF_TYPE_BR_ANGLE, offsetof(struct_substruct2, a2), "a2", NULL, }, + { DF_TYPE_ENUM_8, offsetof(struct_substruct2, e8_2), "e8_2", &file_test_enum_8, }, + { DF_TYPE_STRUCT, offsetof(struct_substruct2, s_2), "s_2", &struct_substruct1_file, }, +}; +static br_file_struct struct_substruct2_file = { + "struct_substruct2", BR_ASIZE(struct_struct_substruct2_members), struct_struct_substruct2_members, sizeof(struct_substruct2), +}; +typedef struct { + char *s; + struct_substruct1 sub1; + struct_substruct2 sub2; +} struct_substruct; +static br_file_struct_member struct_struct_substruct_members[] = { + { DF_TYPE_ASCIZ, offsetof(struct_substruct, s), "s", NULL, }, + { DF_TYPE_STRUCT, offsetof(struct_substruct, sub1), "sub1", &struct_substruct1_file, }, + { DF_TYPE_STRUCT, offsetof(struct_substruct, sub2), "sub2", &struct_substruct2_file, }, +}; +static br_file_struct struct_substruct_file = { + "struct_substruct", BR_ASIZE(struct_struct_substruct_members), struct_struct_substruct_members, sizeof(struct_substruct), +}; +static struct_substruct struct_substruct_ref = { "Hello world", {3.14f, 0x00144000, 0x12345678, }, { { 1.4f, -0.5f}, 0x2000, ENUM_8_TYPE23, { 2.71f, 0xffff8000, 0x10101010, }}}; +static const uint8_t binary_struct_data[] = { BINARY_MAGICS, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x00, 0x40, 0x48, 0xf5, 0xc3, 0x41, 0xa2, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0x3f, 0xb3, 0x33, 0x33, 0xbf, 0x00, 0x00, 0x00, 0x20, 0x00, 0x03, 0x40, 0x2d, 0x70, 0xa4, 0xbf, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, }; +static const char *text_struct_data = + TEXT_MAGICS HOST_NL + " struct struct_substruct" HOST_NL + " asciz \"Hello world\" # s" HOST_NL + " struct struct_substruct1 # sub1" HOST_NL + " float 3.14 # float1" HOST_NL + " fixed 20.25 # fixed1" HOST_NL + " uint_32 305419896 # u32_1" HOST_NL + " struct struct_substruct2 # sub2" HOST_NL + " float_vector2 1.4,-0.5 # vf2" HOST_NL + " angle 45 # a2" HOST_NL + " enum_8 ENUM_8_TYPE2|ENUM_8_TYPE3 # e8_2" HOST_NL + " struct struct_substruct1 # s_2" HOST_NL + " float 2.71 # float1" HOST_NL + " fixed -0.5 # fixed1" HOST_NL + " uint_32 269488144 # u32_1" HOST_NL; +static void test_datafile_binary_substruct() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_substruct read_struct; + + create_temp_file(tmpfilename, "struct_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(46, DfStructSizeBinary(df_w, &struct_substruct_file, &struct_substruct_ref)); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfStructWriteBinary(df_w, &struct_substruct_file, &struct_substruct_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_struct_data, tmpfilename, sizeof(binary_struct_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfStructReadBinary(df_r, &struct_substruct_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_STRING(struct_substruct_ref.s, read_struct.s); + TEST_ASSERT_EQUAL_MEMORY(&struct_substruct_ref.sub1, &read_struct.sub1, sizeof(struct_substruct_ref.sub1)); + TEST_ASSERT_EQUAL_MEMORY(&struct_substruct_ref.sub2, &read_struct.sub2, sizeof(struct_substruct_ref.sub2)); +} +static void test_datafile_text_substruct() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + struct_substruct read_struct; + + create_temp_file(tmpfilename, "struct_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + TEST_ASSERT_EQUAL_INT(14, DfStructSizeText(df_w, &struct_substruct_file, &struct_substruct_ref)); + + BrFilePutLine(text_magics, df_w->h); + DfStructWriteText(df_w, &struct_substruct_file, &struct_substruct_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_struct_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + memset(&read_struct, 0, sizeof(read_struct)); + BrFileAdvance(strlen(text_magics), df_r->h); + DfStructReadText(df_r, &struct_substruct_file, &read_struct); + DfClose(df_r); + + TEST_ASSERT_EQUAL_STRING(struct_substruct_ref.s, read_struct.s); + TEST_ASSERT_EQUAL_MEMORY(&struct_substruct_ref.sub1, &read_struct.sub1, sizeof(struct_substruct_ref.sub1)); + TEST_ASSERT_EQUAL_MEMORY(&struct_substruct_ref.sub2, &read_struct.sub2, sizeof(struct_substruct_ref.sub2)); +} + +static const br_uint_32 chunk_id_ref = DF_CHUNKID_PIXELMAP; +static const br_uint_32 chunk_length_ref = 0x100; +static const uint8_t binary_chunk_data[] = { BINARY_MAGICS, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x00, }; +static const char *text_chunk_data = + TEXT_MAGICS HOST_NL + "*PIXELMAP 256" HOST_NL; +static void test_datafile_binary_chunk() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + int read_id; + br_uint_32 read_length; + + create_temp_file(tmpfilename, "chunk_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfChunkWriteBinary(df_w, chunk_id_ref, chunk_length_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_chunk_data, tmpfilename, sizeof(binary_chunk_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + BrFileAdvance(sizeof(binary_magics), df_r->h); + read_length = 0; + read_id = DfChunkReadBinary(df_r, &read_length); + + TEST_ASSERT_EQUAL_UINT32(chunk_id_ref, read_id); + TEST_ASSERT_EQUAL_INT(chunk_length_ref, read_length); + + DfClose(df_r); +} +static void test_datafile_text_chunk() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + int read_id; + br_uint_32 read_length; + + create_temp_file(tmpfilename, "chunk_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFilePutLine(text_magics, df_w->h); + DfChunkWriteText(df_w, chunk_id_ref, chunk_length_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_chunk_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + BrFileAdvance(strlen(text_magics), df_r->h); + read_length = 0; + read_id = DfChunkReadText(df_r, &read_length); + + TEST_ASSERT_EQUAL_UINT32(chunk_id_ref, read_id); + TEST_ASSERT_EQUAL_INT(chunk_length_ref, read_length); + + DfClose(df_r); +} + +static const br_uint_32 chunk_unknown_id_ref = 0x9000; +static const br_uint_32 chunk_unknown_length_ref = 0x123456; +static const uint8_t binary_chunk_unknown_data[] = { BINARY_MAGICS, 0x00, 0x00, 0x90, 0x00, 0x00, 0x12, 0x34, 0x56, }; +static const char *text_chunk_unknown_data = + TEXT_MAGICS HOST_NL + "*0x00009000 1193046" HOST_NL; +static void test_datafile_binary_chunk_unknown() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + int read_id; + br_uint_32 read_length; + + create_temp_file(tmpfilename, "chunk_unknown_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfChunkWriteBinary(df_w, chunk_unknown_id_ref, chunk_unknown_length_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_chunk_unknown_data, tmpfilename, sizeof(binary_chunk_unknown_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + BrFileAdvance(sizeof(binary_magics), df_r->h); + read_length = 0; + read_id = DfChunkReadBinary(df_r, &read_length); + + TEST_ASSERT_EQUAL_UINT32(chunk_unknown_id_ref, read_id); + TEST_ASSERT_EQUAL_INT(chunk_unknown_length_ref, read_length); + + DfClose(df_r); +} +static void test_datafile_text_chunk_unknown() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + int read_id; + br_uint_32 read_length; + + create_temp_file(tmpfilename, "chunk_unknown_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFilePutLine(text_magics, df_w->h); + DfChunkWriteText(df_w, chunk_unknown_id_ref, chunk_unknown_length_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_chunk_unknown_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + BrFileAdvance(strlen(text_magics), df_r->h); + read_length = 0; + read_id = DfChunkReadText(df_r, &read_length); + + TEST_ASSERT_EQUAL_UINT32(chunk_unknown_id_ref, read_id); + TEST_ASSERT_EQUAL_INT(chunk_unknown_length_ref, read_length); + + DfClose(df_r); +} + +static const br_uint_32 count_ref = 0x1234567; +static const uint8_t binary_count_data[] = { BINARY_MAGICS, 0x01, 0x23, 0x45, 0x67, }; +static const char *text_count_data = + TEXT_MAGICS HOST_NL + " count 19088743" HOST_NL; +static void test_datafile_binary_count() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + br_uint_32 read_count; + + create_temp_file(tmpfilename, "count_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(4, DfCountSizeBinary(df_w)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfCountWriteBinary(df_w, count_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_count_data, tmpfilename, sizeof(binary_count_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + BrFileAdvance(sizeof(binary_magics), df_r->h); + read_count = DfCountReadBinary(df_r); + + TEST_ASSERT_EQUAL_UINT32(count_ref, read_count); + + DfClose(df_r); +} +static void test_datafile_text_count() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + br_uint_32 read_count; + + create_temp_file(tmpfilename, "count_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(1, DfCountSizeText(df_w)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFilePutLine(text_magics, df_w->h); + DfCountWriteText(df_w, count_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_count_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + BrFileAdvance(strlen(text_magics), df_r->h); + read_count = DfCountReadText(df_r); + + TEST_ASSERT_EQUAL_UINT32(count_ref, read_count); + + DfClose(df_r); +} + +static char* name_ref = "DETHRACE_NAME"; +static const uint8_t binary_name_data[] = { BINARY_MAGICS, 'D', 'E', 'T', 'H', 'R', 'A','C', 'E', '_', 'N', 'A', 'M', 'E', '\0', }; +static const char *text_name_data = + TEXT_MAGICS HOST_NL + " name \"DETHRACE_NAME\"" HOST_NL; +static void test_datafile_binary_name() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + char nameBuffer[256]; + + create_temp_file(tmpfilename, "name_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(strlen(name_ref) + 1, DfNameSizeBinary(df_w, name_ref)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfNameWriteBinary(df_w, name_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_name_data, tmpfilename, sizeof(binary_name_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + nameBuffer[0] = '\0'; + BrFileAdvance(sizeof(binary_magics), df_r->h); + DfNameReadBinary(df_r, nameBuffer); + + TEST_ASSERT_EQUAL_STRING(name_ref, nameBuffer);; + + DfClose(df_r); +} +static void test_datafile_text_name() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + char nameBuffer[256]; + + create_temp_file(tmpfilename, "name_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(1, DfNameSizeText(df_w, name_ref)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFilePutLine(text_magics, df_w->h); + DfNameWriteText(df_w, name_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_name_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + nameBuffer[0] = '\0'; + BrFileAdvance(strlen(text_magics), df_r->h); + DfNameReadText(df_r, nameBuffer); + + TEST_ASSERT_EQUAL_STRING(name_ref, nameBuffer); + + DfClose(df_r); +} + +static const int block_continguous_block_size_ref = 8; +static const int block_continguous_block_stride_ref = 8; +static const int block_continguous_block_count_ref = 7; +static const int block_continguous_size_ref = 2; +static br_uint_16 block_continguous_ref[7][8] = { + { 0x4fd2, 0x73c4, 0xdb2b, 0x81d7, 0xa39f, 0x4b0e, 0x9238, 0xa263, }, + { 0x5ca8, 0xa44b, 0x6ef6, 0x5670, 0x7645, 0x78a9, 0x2ade, 0x7e1b, }, + { 0x846a, 0x96b3, 0x6c19, 0xeed2, 0x0d5c, 0x1339, 0x7ab1, 0x8844, }, + { 0xb820, 0xa176, 0xf77a, 0xc1cb, 0x6098, 0xfb5a, 0x1793, 0xcc1f, }, + { 0x4c24, 0x86bd, 0xf802, 0x6517, 0x2a97, 0x819c, 0x9ccf, 0x57e2, }, + { 0x6d30, 0xda19, 0xfbfb, 0xf64e, 0x7867, 0x4693, 0xcfb5, 0x1960, }, + { 0xd4a5, 0x3514, 0x0158, 0xe78e, 0xe109, 0xcf80, 0x5394, 0xe367, }, +}; +static const uint8_t binary_block_continguous_data[] = { BINARY_MAGICS, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x02, + 0x4f, 0xd2, 0x73, 0xc4, 0xdb, 0x2b, 0x81, 0xd7, 0xa3, 0x9f, 0x4b, 0x0e, 0x92, 0x38, 0xa2, 0x63, + 0x5c, 0xa8, 0xa4, 0x4b, 0x6e, 0xf6, 0x56, 0x70, 0x76, 0x45, 0x78, 0xa9, 0x2a, 0xde, 0x7e, 0x1b, + 0x84, 0x6a, 0x96, 0xb3, 0x6c, 0x19, 0xee, 0xd2, 0x0d, 0x5c, 0x13, 0x39, 0x7a, 0xb1, 0x88, 0x44, + 0xb8, 0x20, 0xa1, 0x76, 0xf7, 0x7a, 0xc1, 0xcb, 0x60, 0x98, 0xfb, 0x5a, 0x17, 0x93, 0xcc, 0x1f, + 0x4c, 0x24, 0x86, 0xbd, 0xf8, 0x02, 0x65, 0x17, 0x2a, 0x97, 0x81, 0x9c, 0x9c, 0xcf, 0x57, 0xe2, + 0x6d, 0x30, 0xda, 0x19, 0xfb, 0xfb, 0xf6, 0x4e, 0x78, 0x67, 0x46, 0x93, 0xcf, 0xb5, 0x19, 0x60, + 0xd4, 0xa5, 0x35, 0x14, 0x01, 0x58, 0xe7, 0x8e, 0xe1, 0x09, 0xcf, 0x80, 0x53, 0x94, 0xe3, 0x67, +}; +static const char *text_block_continguous_data = + TEXT_MAGICS HOST_NL + " block 56" HOST_NL + " size 2" HOST_NL + " 00000000: 4fd273c4db2b81d7a39f4b0e9238a2635ca8a44b6ef65670764578a92ade7e1b" HOST_NL + " 00000020: 846a96b36c19eed20d5c13397ab18844b820a176f77ac1cb6098fb5a1793cc1f" HOST_NL + " 00000040: 4c2486bdf80265172a97819c9ccf57e26d30da19fbfbf64e78674693cfb51960" HOST_NL + " 00000060: d4a535140158e78ee109cf805394e367" HOST_NL; +static void test_datafile_binary_block_continguous() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + br_uint_32 read_count; + br_uint_16 read_block_continguous[20][8]; + br_uint_8 *read_blocks; + + create_temp_file(tmpfilename, "block_continguous_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(120, DfBlockSizeBinary(df_w, block_continguous_ref, block_continguous_block_size_ref, block_continguous_block_stride_ref, block_continguous_block_count_ref, block_continguous_size_ref)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfBlockWriteBinary(df_w, block_continguous_ref, block_continguous_block_size_ref, block_continguous_block_stride_ref, block_continguous_block_count_ref, block_continguous_size_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_block_continguous_data, tmpfilename, sizeof(binary_block_continguous_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + read_count = sizeof(read_block_continguous) / sizeof(br_uint_16); + BrFileAdvance(sizeof(binary_magics), df_r->h); + read_blocks = DfBlockReadBinary(df_r, read_block_continguous, &read_count, block_continguous_size_ref, BR_MEMORY_APPLICATION); + + TEST_ASSERT_EQUAL_PTR(read_block_continguous, read_blocks); + TEST_ASSERT_EQUAL_INT(block_continguous_block_size_ref * block_continguous_block_count_ref, read_count); + TEST_ASSERT_EQUAL_MEMORY(block_continguous_ref, read_block_continguous, sizeof(block_continguous_ref)); + + DfClose(df_r); +} +static void test_datafile_text_block_continguous() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + br_uint_32 read_count; + br_uint_16 read_block_continguous[20][8]; + br_uint_8 *read_blocks; + + create_temp_file(tmpfilename, "block_continguous_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(6, DfBlockSizeText(df_w, block_continguous_ref, block_continguous_block_size_ref, block_continguous_block_stride_ref, block_continguous_block_count_ref, block_continguous_size_ref)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFilePutLine(text_magics, df_w->h); + DfBlockWriteText(df_w, block_continguous_ref, block_continguous_block_size_ref, block_continguous_block_stride_ref, block_continguous_block_count_ref, block_continguous_size_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_block_continguous_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + read_count = sizeof(read_block_continguous) / sizeof(br_uint_16); + BrFileAdvance(strlen(text_magics), df_r->h); + read_blocks = DfBlockReadText(df_r, read_block_continguous, &read_count, block_continguous_size_ref, BR_MEMORY_APPLICATION); + + TEST_ASSERT_EQUAL_PTR(read_block_continguous, read_blocks); + TEST_ASSERT_EQUAL_INT(block_continguous_block_size_ref * block_continguous_block_count_ref, read_count); + TEST_ASSERT_EQUAL_MEMORY(block_continguous_ref, read_block_continguous, sizeof(block_continguous_ref)); + + DfClose(df_r); +} + +static const int block_striped_block_size_ref = 8; + static const int block_striped_block_stride_ref = 16; +static const int block_striped_block_count_ref = 3; +static const int block_striped_size_ref = 2; +static br_uint_16 block_striped_input_ref[6][8] = { + { 0x4fd2, 0x73c4, 0xdb2b, 0x81d7, 0xa39f, 0x4b0e, 0x9238, 0xa263, }, + { 0x5ca8, 0xa44b, 0x6ef6, 0x5670, 0x7645, 0x78a9, 0x2ade, 0x7e1b, }, + { 0x846a, 0x96b3, 0x6c19, 0xeed2, 0x0d5c, 0x1339, 0x7ab1, 0x8844, }, + { 0xb820, 0xa176, 0xf77a, 0xc1cb, 0x6098, 0xfb5a, 0x1793, 0xcc1f, }, + { 0x4c24, 0x86bd, 0xf802, 0x6517, 0x2a97, 0x819c, 0x9ccf, 0x57e2, }, + { 0x6d30, 0xda19, 0xfbfb, 0xf64e, 0x7867, 0x4693, 0xcfb5, 0x1960, }, +}; +static br_uint_16 block_striped_output_ref[3][8] = { + { 0x4fd2, 0x73c4, 0xdb2b, 0x81d7, 0xa39f, 0x4b0e, 0x9238, 0xa263, }, + { 0x846a, 0x96b3, 0x6c19, 0xeed2, 0x0d5c, 0x1339, 0x7ab1, 0x8844, }, + { 0x4c24, 0x86bd, 0xf802, 0x6517, 0x2a97, 0x819c, 0x9ccf, 0x57e2, }, +}; +static const uint8_t binary_block_striped_data[] = { BINARY_MAGICS, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, + 0x4f, 0xd2, 0x73, 0xc4, 0xdb, 0x2b, 0x81, 0xd7, 0xa3, 0x9f, 0x4b, 0x0e, 0x92, 0x38, 0xa2, 0x63, + 0x84, 0x6a, 0x96, 0xb3, 0x6c, 0x19, 0xee, 0xd2, 0x0d, 0x5c, 0x13, 0x39, 0x7a, 0xb1, 0x88, 0x44, + 0x4c, 0x24, 0x86, 0xbd, 0xf8, 0x02, 0x65, 0x17, 0x2a, 0x97, 0x81, 0x9c, 0x9c, 0xcf, 0x57, 0xe2, +}; +static const char *text_block_striped_data = + TEXT_MAGICS HOST_NL + " block 24" HOST_NL + " size 2" HOST_NL + " 00000000: 4fd273c4db2b81d7a39f4b0e9238a263846a96b36c19eed20d5c13397ab18844" HOST_NL + " 00000020: 4c2486bdf80265172a97819c9ccf57e2" HOST_NL; +static void test_datafile_binary_block_striped() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + br_uint_32 read_count; + br_uint_16 read_block_striped[20][8]; + br_uint_8 *read_blocks; + + create_temp_file(tmpfilename, "block_striped_binary"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(56, DfBlockSizeBinary(df_w, block_striped_input_ref, block_striped_block_size_ref, block_striped_block_stride_ref, block_striped_block_count_ref, block_striped_size_ref)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFileWrite(binary_magics, sizeof(binary_magics), 1, df_w->h); + DfBlockWriteBinary(df_w, block_striped_input_ref, block_striped_block_size_ref, block_striped_block_stride_ref, block_striped_block_count_ref, block_striped_size_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_CONTENTS_BINARY(binary_block_striped_data, tmpfilename, sizeof(binary_block_striped_data)); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + read_count = sizeof(read_block_striped) / sizeof(br_uint_16); + BrFileAdvance(sizeof(binary_magics), df_r->h); + read_blocks = DfBlockReadBinary(df_r, read_block_striped, &read_count, block_striped_size_ref, BR_MEMORY_APPLICATION); + + TEST_ASSERT_EQUAL_PTR(read_block_striped, read_blocks); + TEST_ASSERT_EQUAL_INT(block_striped_block_size_ref * block_striped_block_count_ref, read_count); + TEST_ASSERT_EQUAL_MEMORY(block_striped_output_ref, read_block_striped, sizeof(block_striped_output_ref)); + + DfClose(df_r); +} +static void test_datafile_text_block_striped() { + br_datafile* df_w; + br_datafile* df_r; + char tmpfilename[PATH_MAX+1]; + br_uint_32 read_count; + br_uint_16 read_block_striped[20][8]; + br_uint_8 *read_blocks; + + create_temp_file(tmpfilename, "block_striped_text"); + + df_w = DfOpen(tmpfilename, 1, BRT_FLOAT); + + TEST_ASSERT_EQUAL_INT(4, DfBlockSizeText(df_w, block_striped_input_ref, block_striped_block_size_ref, block_striped_block_stride_ref, block_striped_block_count_ref, block_striped_size_ref)); + + TEST_ASSERT_NOT_NULL(df_w); + TEST_ASSERT_NOT_NULL(df_w->h); + + BrFilePutLine(text_magics, df_w->h); + DfBlockWriteText(df_w, block_striped_input_ref, block_striped_block_size_ref, block_striped_block_stride_ref, block_striped_block_count_ref, block_striped_size_ref); + DfClose(df_w); + + TEST_ASSERT_EQUAL_FILE_TEXT(text_block_striped_data, tmpfilename); + + df_r = DfOpen(tmpfilename, 0, BRT_FLOAT); + + TEST_ASSERT_NOT_NULL(df_r); + TEST_ASSERT_NOT_NULL(df_r->h); + + read_count = sizeof(read_block_striped) / sizeof(br_uint_16); + BrFileAdvance(strlen(text_magics), df_r->h); + read_blocks = DfBlockReadText(df_r, read_block_striped, &read_count, block_striped_size_ref, BR_MEMORY_APPLICATION); + + TEST_ASSERT_EQUAL_PTR(read_block_striped, read_blocks); + TEST_ASSERT_EQUAL_INT(block_striped_block_size_ref * block_striped_block_count_ref, read_count); + TEST_ASSERT_EQUAL_MEMORY(block_striped_output_ref, read_block_striped, sizeof(block_striped_output_ref)); + + DfClose(df_r); +} + +static void test_datafile_OpenFile() { + br_datafile* df; + + REQUIRES_DATA_DIRECTORY(); + df = DfOpen("DATA/MODELS/CPOINT.DAT", 0, BRT_FLOAT); + TEST_ASSERT_NOT_NULL(df); + TEST_ASSERT_NOT_NULL(df->h); + DfClose(df); } void test_datafile_suite() { UnitySetTestFile(__FILE__); - RUN_TEST(test_datafile_ReadBinary); + RUN_TEST(test_datafile_stack); + RUN_TEST(test_datafile_magics); + RUN_TEST(test_datafile_binary_br_int_8); + RUN_TEST(test_datafile_text_br_int_8); + RUN_TEST(test_datafile_binary_br_uint_8); + RUN_TEST(test_datafile_text_br_int_16); + RUN_TEST(test_datafile_binary_br_int_16); + RUN_TEST(test_datafile_text_br_int_16); + RUN_TEST(test_datafile_binary_br_uint_16); + RUN_TEST(test_datafile_text_br_uint_8); + RUN_TEST(test_datafile_binary_br_int_32); + RUN_TEST(test_datafile_text_br_int_32); + RUN_TEST(test_datafile_binary_br_uint_32); + RUN_TEST(test_datafile_text_br_uint_32); + RUN_TEST(test_datafile_binary_br_fixed); + RUN_TEST(test_datafile_text_br_fixed); + RUN_TEST(test_datafile_binary_br_angle); + RUN_TEST(test_datafile_text_br_angle); + RUN_TEST(test_datafile_binary_float); + RUN_TEST(test_datafile_text_float); + RUN_TEST(test_datafile_binary_double); + RUN_TEST(test_datafile_text_double); + RUN_TEST(test_datafile_binary_enum_8); + RUN_TEST(test_datafile_text_enum_8); + RUN_TEST(test_datafile_binary_enum_16); + RUN_TEST(test_datafile_text_enum_16); + RUN_TEST(test_datafile_binary_enum_32); + RUN_TEST(test_datafile_text_enum_32); + RUN_TEST(test_datafile_binary_asciz); + RUN_TEST(test_datafile_text_asciz); + RUN_TEST(test_datafile_binary_br_colour); + RUN_TEST(test_datafile_text_br_colour); + RUN_TEST(test_datafile_binary_br_fraction_x); + RUN_TEST(test_datafile_text_br_fraction_x); + RUN_TEST(test_datafile_binary_br_ufraction_x); + RUN_TEST(test_datafile_text_br_ufraction_x); + RUN_TEST(test_datafile_binary_br_fraction_f); + RUN_TEST(test_datafile_text_br_fraction_f); + RUN_TEST(test_datafile_binary_br_ufraction_f); + RUN_TEST(test_datafile_text_br_ufraction_f); + RUN_TEST(test_datafile_binary_br_vector2_x); + RUN_TEST(test_datafile_text_br_vector2_x); + RUN_TEST(test_datafile_binary_br_vector3_x); + RUN_TEST(test_datafile_text_br_vector3_x); + RUN_TEST(test_datafile_binary_br_vector4_x); + RUN_TEST(test_datafile_text_br_vector4_x); + RUN_TEST(test_datafile_binary_br_vector2_f); + RUN_TEST(test_datafile_text_br_vector2_f); + RUN_TEST(test_datafile_binary_br_vector3_f); + RUN_TEST(test_datafile_text_br_vector3_f); + RUN_TEST(test_datafile_binary_br_vector4_f); + RUN_TEST(test_datafile_text_br_vector4_f); + RUN_TEST(test_datafile_binary_substruct); + RUN_TEST(test_datafile_text_substruct); + RUN_TEST(test_datafile_binary_chunk); + RUN_TEST(test_datafile_text_chunk); + RUN_TEST(test_datafile_binary_chunk_unknown); + RUN_TEST(test_datafile_text_chunk_unknown); + RUN_TEST(test_datafile_binary_count); + RUN_TEST(test_datafile_text_count); + RUN_TEST(test_datafile_binary_name); + RUN_TEST(test_datafile_text_name); + RUN_TEST(test_datafile_binary_block_continguous); + RUN_TEST(test_datafile_text_block_continguous); + RUN_TEST(test_datafile_binary_block_striped); + RUN_TEST(test_datafile_text_block_striped); + RUN_TEST(test_datafile_OpenFile); } diff --git a/test/BRSRC13/test_fixed.c b/test/BRSRC13/test_fixed.c new file mode 100644 index 00000000..f1f2880b --- /dev/null +++ b/test/BRSRC13/test_fixed.c @@ -0,0 +1,471 @@ +#include "CORE/MATH/fixed.h" +#include "tests.h" +#include +#include + +static void test_fixed_conversions() { + TEST_ASSERT_EQUAL_INT(1<<16, BR_ONE_LS); + TEST_ASSERT_EQUAL_INT(1<<16, BR_ONE_LU); + TEST_ASSERT_EQUAL_INT(1<<8, BR_ONE_SS); + TEST_ASSERT_EQUAL_INT(1<<8, BR_ONE_SU); + + TEST_ASSERT_EQUAL_INT(1<<15, BR_ONE_LSF); + TEST_ASSERT_EQUAL_INT(1<<16, BR_ONE_LUF); + TEST_ASSERT_EQUAL_INT(1<<7, BR_ONE_SSF); + TEST_ASSERT_EQUAL_INT(1<<8, BR_ONE_SUF); + + TEST_ASSERT_EQUAL_INT(0, BrIntToFixed(0)); + TEST_ASSERT_EQUAL_INT((br_fixed_ls)0xffff0000, BrIntToFixed(-1)); + TEST_ASSERT_EQUAL_INT((br_fixed_ls)(42<<16), BrIntToFixed(42)); + + TEST_ASSERT_EQUAL_INT(42<<16, BrFloatToFixed(42.f)); + TEST_ASSERT_EQUAL_INT((br_fixed_ls)0x00008000, BrFloatToFixed(.5f)); + TEST_ASSERT_EQUAL_INT((br_fixed_ls)0xffff8000, BrFloatToFixed(-.5f)); + TEST_ASSERT_EQUAL_INT((br_fixed_ls)0x00005555, BrFloatToFixed(.333333333333f)); + + TEST_ASSERT_EQUAL_INT(0x00005555, BrScalarToFixed(BR_SCALAR(.333333333333f))); + + TEST_ASSERT_EQUAL_INT(0x42, BrFixedToInt(0x0042ffff)); + + TEST_ASSERT_EQUAL_FLOAT(.5f, BrFixedToFloat(0x00008000)); + TEST_ASSERT_FLOAT_WITHIN(1e-5f, .333333333333f, BrFixedToFloat(0x00005555)); + + TEST_ASSERT_FLOAT_WITHIN(1e-5f, .333333333333f, BrFixedToScalar(0x00005555)); + + TEST_ASSERT_EQUAL_UINT16(0x0000, BrFloatToFixedFraction(0.f)); + TEST_ASSERT_EQUAL_UINT16(0x7fff, BrFloatToFixedFraction(0.99999f)); + TEST_ASSERT_EQUAL_UINT16(0x8000, BrFloatToFixedFraction(-1.f)); + TEST_ASSERT_EQUAL_UINT16(0x6000, BrFloatToFixedFraction(0.75f)); + TEST_ASSERT_EQUAL_UINT16(0xa000, BrFloatToFixedFraction(-0.75f)); + + TEST_ASSERT_EQUAL_FLOAT(0.f, BrFixedFractionToFloat(0x0000)); + TEST_ASSERT_EQUAL_FLOAT(0.9999695f, BrFixedFractionToFloat(0x7fff)); + TEST_ASSERT_EQUAL_FLOAT(-1.f, BrFixedFractionToFloat(0x8000)); + TEST_ASSERT_EQUAL_FLOAT(0.75f, BrFixedFractionToFloat(0x6000)); + TEST_ASSERT_EQUAL_FLOAT(-0.75f, BrFixedFractionToFloat(0xa000)); +} + +static void test_fixed_BrFixedAbs() { + TEST_ASSERT_EQUAL(BrFloatToFixed(42.f), BrFixedAbs(BrFloatToFixed(42.f))); + TEST_ASSERT_EQUAL(BrFloatToFixed(42.f), BrFixedAbs(BrFloatToFixed(-42.f))); + TEST_ASSERT_EQUAL(BrFloatToFixed(1.234f), BrFixedAbs(BrFloatToFixed(-1.234f))); +} + +static void test_fixed_BrFixedMul() { + TEST_ASSERT_EQUAL(BrFloatToFixed(63.f), BrFixedMul(BrFloatToFixed(1.5f), BrFloatToFixed(42.f))); + TEST_ASSERT_EQUAL(BrFloatToFixed(-63.f), BrFixedMul(BrFloatToFixed(1.5f), BrFloatToFixed(-42.f))); + TEST_ASSERT_EQUAL(BrFloatToFixed(63.f), BrFixedMul(BrFloatToFixed(-1.5f), BrFloatToFixed(-42.f))); +} + +static void test_fixed_BrFixedMac2() { + TEST_ASSERT_EQUAL(BrFloatToFixed(108.f), BrFixedMac2(BrFloatToFixed(1.5f), BrFloatToFixed(42.f), + BrFloatToFixed(.5f), BrFloatToFixed(90.f))); + +} + +static void test_fixed_BrFixedMac3() { + TEST_ASSERT_EQUAL(BrFloatToFixed(133.f), BrFixedMac3(BrFloatToFixed(1.5f), BrFloatToFixed(42.f), + BrFloatToFixed(.5f), BrFloatToFixed(90.f), + BrFloatToFixed(.25f), BrFloatToFixed(100.f))); + +} + +static void test_fixed_BrFixedMac4() { + TEST_ASSERT_EQUAL(BrFloatToFixed(138.f), BrFixedMac4(BrFloatToFixed(1.5f), BrFloatToFixed(42.f), + BrFloatToFixed(.5f), BrFloatToFixed(90.f), + BrFloatToFixed(.25f), BrFloatToFixed(100.f), + BrFloatToFixed(.125f), BrFloatToFixed(40.f))); + +} + +static void test_fixed_BrISqrt32() { + TEST_ASSERT_EQUAL_UINT16(0, _BrISqrt32(0)); + TEST_ASSERT_EQUAL_UINT16(1, _BrISqrt32(1)); + TEST_ASSERT_EQUAL_UINT16(1, _BrISqrt32(2)); + TEST_ASSERT_EQUAL_UINT16(2, _BrISqrt32(4)); + TEST_ASSERT_EQUAL_UINT16(2, _BrISqrt32(8)); + TEST_ASSERT_EQUAL_UINT16(3, _BrISqrt32(9)); + TEST_ASSERT_EQUAL_UINT16(3, _BrISqrt32(15)); + TEST_ASSERT_EQUAL_UINT16(4, _BrISqrt32(16)); + TEST_ASSERT_EQUAL_UINT16(4, _BrISqrt32(24)); + TEST_ASSERT_EQUAL_UINT16(5, _BrISqrt32(25)); + TEST_ASSERT_EQUAL_UINT16(15, _BrISqrt32(255)); + TEST_ASSERT_EQUAL_UINT16(16, _BrISqrt32(256)); + TEST_ASSERT_EQUAL_UINT16(99, _BrISqrt32(9999)); + TEST_ASSERT_EQUAL_UINT16(100, _BrISqrt32(10000)); + TEST_ASSERT_EQUAL_UINT16(17320, _BrISqrt32(300000000)); + TEST_ASSERT_EQUAL_UINT16(0xffff, _BrISqrt32(0xffffffff)); +} + +static void test_fixed_BrISqrt64() { + TEST_ASSERT_EQUAL_UINT32(0, _BrISqrt64(0)); + TEST_ASSERT_EQUAL_UINT32(1, _BrISqrt64(1)); + TEST_ASSERT_EQUAL_UINT32(1, _BrISqrt64(2)); + TEST_ASSERT_EQUAL_UINT32(2, _BrISqrt64(4)); + TEST_ASSERT_EQUAL_UINT32(2, _BrISqrt64(8)); + TEST_ASSERT_EQUAL_UINT32(3, _BrISqrt64(9)); + TEST_ASSERT_EQUAL_UINT32(3, _BrISqrt64(15)); + TEST_ASSERT_EQUAL_UINT32(4, _BrISqrt64(16)); + TEST_ASSERT_EQUAL_UINT32(4, _BrISqrt64(24)); + TEST_ASSERT_EQUAL_UINT32(5, _BrISqrt64(25)); + TEST_ASSERT_EQUAL_UINT32(15, _BrISqrt64(255)); + TEST_ASSERT_EQUAL_UINT32(16, _BrISqrt64(256)); + TEST_ASSERT_EQUAL_UINT32(99, _BrISqrt64(9999)); + TEST_ASSERT_EQUAL_UINT32(100, _BrISqrt64(10000)); + TEST_ASSERT_EQUAL_UINT32(17320, _BrISqrt64(300000000)); + TEST_ASSERT_EQUAL_UINT32(0xffff, _BrISqrt64(0xffffffff)); + TEST_ASSERT_EQUAL_UINT32(0xffffffff, _BrISqrt64(0xffffffffffffffff)); +} + +static void test_fixed_BrFixedLength2() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(5.f), BrFixedLength2(BrFloatToFixed(3.f), BrFloatToFixed(4.f))); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-4f), BrFloatToFixed(.5f), BrFixedLength2(BrFloatToFixed(.3f), BrFloatToFixed(.4f))); +} + +static void test_fixed_BrFixedLength3() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(7.f), BrFixedLength3(BrFloatToFixed(2.f), BrFloatToFixed(3.f), BrFloatToFixed(6.f))); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1.e-4f), BrFloatToFixed(.7f), BrFixedLength3(BrFloatToFixed(.2f), BrFloatToFixed(.3f), BrFloatToFixed(.6f))); +} + +static void test_fixed_BrFixedLength4() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(9.f), BrFixedLength4(BrFloatToFixed(2.f), BrFloatToFixed(4.f), BrFloatToFixed(5.f), BrFloatToFixed(6.f))); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-4f), BrFloatToFixed(.9f), BrFixedLength4(BrFloatToFixed(.2f), BrFloatToFixed(.4f), BrFloatToFixed(.5f), BrFloatToFixed(.6f))); +} + +static void test_fixed_BrFixedDiv() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(1.f), BrFixedDiv(BrFloatToFixed(1.f), BrFloatToFixed(1.f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(2.f), BrFixedDiv(BrFloatToFixed(1.f), BrFloatToFixed(.5f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(5.f), BrFixedDiv(BrFloatToFixed(5.f), BrFloatToFixed(1.f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(10.f), BrFixedDiv(BrFloatToFixed(5.f), BrFloatToFixed(.5f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(20.f), BrFixedDiv(BrFloatToFixed(5.f), BrFloatToFixed(.25f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(2.f), BrFixedDiv(BrFloatToFixed(.5f), BrFloatToFixed(.25f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(-5000.f), BrFixedDiv(BrFloatToFixed(20000.f), BrFloatToFixed(-4.f))); + TEST_ASSERT_EQUAL_UINT32(0xfff1b6dc, BrFixedDiv(-100, 7)); +} + +static void test_fixed_BrFixedDivR() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(5.f), BrFixedDivR(BrFloatToFixed(5.f), BrFloatToFixed(1.f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(10.f), BrFixedDivR(BrFloatToFixed(5.f), BrFloatToFixed(.5f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(20.f), BrFixedDivR(BrFloatToFixed(5.f), BrFloatToFixed(.25f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(2.f), BrFixedDivR(BrFloatToFixed(.5f), BrFloatToFixed(.25f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(-5000.f), BrFixedDivR(BrFloatToFixed(20000.f), BrFloatToFixed(-4.f))); + TEST_ASSERT_EQUAL_UINT32(0xfff1db6e, BrFixedDivR(-100, 7)); +} + +static void test_fixed_BrFixedDivF() { + TEST_ASSERT_EQUAL_UINT32(1 << 31, BrFixedDivF(BrFloatToFixed(1.f), BrFloatToFixed(1.f))); + TEST_ASSERT_EQUAL_UINT32(1 << 30, BrFixedDivF(BrFloatToFixed(1.f), BrFloatToFixed(2.f))); +} + +static void test_fixed_BrFixedMulDiv() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(7.5f), BrFixedMulDiv(BrFloatToFixed(3.f), BrFloatToFixed(5.f), + BrFloatToFixed(2.f))); +} + +static void test_fixed_BrFixedMac2Div() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(13.5f), BrFixedMac2Div(BrFloatToFixed(3.f), BrFloatToFixed(5.f), + BrFloatToFixed(2.f), BrFloatToFixed(6.f), + BrFloatToFixed(2.f))); +} + +static void test_fixed_BrFixedMac3Div() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(-18.f), BrFixedMac3Div(BrFloatToFixed(3.f), BrFloatToFixed(5.f), + BrFloatToFixed(2.f), BrFloatToFixed(6.f), + BrFloatToFixed(-7.f), BrFloatToFixed(9.f), + BrFloatToFixed(2.f))); +} + +static void test_fixed_BrFixedMac4Div() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(4.5f), BrFixedMac4Div(BrFloatToFixed(3.f), BrFloatToFixed(5.f), + BrFloatToFixed(2.f), BrFloatToFixed(6.f), + BrFloatToFixed(-7.f), BrFloatToFixed(9.f), + BrFloatToFixed(9.f), BrFloatToFixed(5.f), + BrFloatToFixed(2.f))); +} + +static void test_fixed_BrFixedFMac2() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(2.75f), BrFixedFMac2(BrFloatToFixedFraction(.25f), BrFloatToFixed(5.f), + BrFloatToFixedFraction(.5f), BrFloatToFixed(3.f))); +} + +static void test_fixed_BrFixedFMac3() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(5.75f), BrFixedFMac3(BrFloatToFixedFraction(.25f), BrFloatToFixed(5.f), + BrFloatToFixedFraction(.5f), BrFloatToFixed(3.f), + BrFloatToFixedFraction(.75f), BrFloatToFixed(4.f))); +} + +static void test_fixed_BrFixedFMac4() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(6.625f), BrFixedFMac4(BrFloatToFixedFraction(.25f), BrFloatToFixed(5.f), + BrFloatToFixedFraction(.5f), BrFloatToFixed(3.f), + BrFloatToFixedFraction(.75f), BrFloatToFixed(4.f), + BrFloatToFixedFraction(.125f), BrFloatToFixed(7.f))); +} + +static void test_fixed_BrFixedRcp() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(4.f), BrFixedRcp(BrFloatToFixed(.25f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(.25f), BrFixedRcp(BrFloatToFixed(4.f))); +} + +static void test_fixed_BrFixedSqr() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(.0625f), BrFixedSqr(BrFloatToFixed(.25f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(16.f), BrFixedSqr(BrFloatToFixed(4.f))); +} + +static void test_fixed_BrFixedSqr2() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(1.0625f), BrFixedSqr2(BrFloatToFixed(.25f), BrFloatToFixed(1.f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(20.f), BrFixedSqr2(BrFloatToFixed(4.f), BrFloatToFixed(2.f))); +} + +static void test_fixed_BrFixedSqr3() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(5.0625f), BrFixedSqr3(BrFloatToFixed(.25f), BrFloatToFixed(1.f), BrFloatToFixed(2.f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(29.f), BrFixedSqr3(BrFloatToFixed(4.f), BrFloatToFixed(2.f), BrFloatToFixed(3.f))); +} + +static void test_fixed_BrFixedSqr4() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(14.0625f), BrFixedSqr4(BrFloatToFixed(.25f), BrFloatToFixed(1.f), BrFloatToFixed(2.f), BrFloatToFixed(-3.f))); + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(45.f), BrFixedSqr4(BrFloatToFixed(4.f), BrFloatToFixed(2.f), BrFloatToFixed(3.f), BrFloatToFixed(-4.f))); +} + +static void test_fixed_BrFixedSin() { + TEST_ASSERT_EQUAL_UINT32(BrFloatToFixed(.0f), BrFixedSin(BrRadianToAngle(0.0f * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.5f), BrFixedSin(BrRadianToAngle((1.f/6.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.7071067811865476f), BrFixedSin(BrRadianToAngle((1.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.8660254037844386f), BrFixedSin(BrRadianToAngle((1.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(1.f), BrFixedSin(BrRadianToAngle((1.f/2.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.8660254037844386f), BrFixedSin(BrRadianToAngle((2.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.7071067811865476f), BrFixedSin(BrRadianToAngle((3.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.5f), BrFixedSin(BrRadianToAngle((5.f/6.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.0f), BrFixedSin(BrRadianToAngle(1.0f * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.5f), BrFixedSin(BrRadianToAngle((7.f/6.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.7071067811865476f), BrFixedSin(BrRadianToAngle((5.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.8660254037844386f), BrFixedSin(BrRadianToAngle((4.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-1.f), BrFixedSin(BrRadianToAngle((-1.f/2.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.8660254037844386f), BrFixedSin(BrRadianToAngle((5.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.7071067811865476f), BrFixedSin(BrRadianToAngle((7.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.5f), BrFixedSin(BrRadianToAngle((11.f/6.f) * PI))); +} + +static void test_fixed_BrFixedCos() { + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(1.f), BrFixedCos(BrRadianToAngle(0.0f * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.8660254037844386f), BrFixedCos(BrRadianToAngle((1.f/6.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.7071067811865476f), BrFixedCos(BrRadianToAngle((1.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.5f), BrFixedCos(BrRadianToAngle((1.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(0.f), BrFixedCos(BrRadianToAngle((1.f/2.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.5f), BrFixedCos(BrRadianToAngle((2.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.7071067811865476f), BrFixedCos(BrRadianToAngle((3.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.8660254037844386f), BrFixedCos(BrRadianToAngle((5.f/6.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-1.f), BrFixedCos(BrRadianToAngle(1.0f * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.8660254037844386f), BrFixedCos(BrRadianToAngle((7.f/6.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.7071067811865476f), BrFixedCos(BrRadianToAngle((5.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(-.5f), BrFixedCos(BrRadianToAngle((4.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(0.f), BrFixedCos(BrRadianToAngle((-1.f/2.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.5f), BrFixedCos(BrRadianToAngle((5.f/3.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.7071067811865476f), BrFixedCos(BrRadianToAngle((7.f/4.f) * PI))); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(.8660254037844386f), BrFixedCos(BrRadianToAngle((11.f/6.f) * PI))); +} + +static void test_fixed_BrFixedASin() { + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 3.f / 2.f) * PI), BrFixedASin(BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 5.f / 3.f) * PI), BrFixedASin(BrFloatToFixed(-.8660254037844386f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 7.f / 4.f) * PI), BrFixedASin(BrFloatToFixed(-.7071067811865476f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((11.f / 6.f) * PI), BrFixedASin(BrFloatToFixed(-.5f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 0.0f * PI), BrFixedASin(BrFloatToFixed(.0f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 1.f / 6.f) * PI), BrFixedASin(BrFloatToFixed(.5f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 1.f / 4.f) * PI), BrFixedASin(BrFloatToFixed(.7071067811865476f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 1.f / 3.f) * PI), BrFixedASin(BrFloatToFixed(.8660254037844386f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(( 1.f / 2.f) * PI), BrFixedASin(BrFloatToFixed(1.f))); +} + +static void test_fixed_BrFixedACos() { + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 1.f * PI), BrFixedACos(BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((5.f / 6.f) * PI), BrFixedACos(BrFloatToFixed(-.8660254037844386f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((3.f / 4.f) * PI), BrFixedACos(BrFloatToFixed(-.7071067811865476f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((2.f / 3.f) * PI), BrFixedACos(BrFloatToFixed(-.5f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((1.f / 2.f) * PI), BrFixedACos(BrFloatToFixed(.0f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((1.f / 3.f) * PI), BrFixedACos(BrFloatToFixed(.5f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((1.f / 4.f) * PI), BrFixedACos(BrFloatToFixed(.7071067811865476f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle((1.f / 6.f) * PI), BrFixedACos(BrFloatToFixed(.8660254037844386f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 0.f * PI), BrFixedACos(BrFloatToFixed(1.f))); +} + +static void test_fixed_BrFixedATan2() { + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 0.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(0.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 1.f / 6.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(0.5773502691896258f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 1.f / 4.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 1.f / 3.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 1.f / 2.f * PI), BrFixedATan2(BrFloatToFixed( 0.f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 2.f / 3.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 3.f / 4.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 5.f / 6.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(0.5773502691896258f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 1.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(0.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 7.f / 6.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(-0.5773502691896258f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 5.f / 4.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 4.f / 3.f * PI), BrFixedATan2(BrFloatToFixed(-1.f), BrFloatToFixed(-1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 3.f / 2.f * PI), BrFixedATan2(BrFloatToFixed( 0.f), BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 5.f / 3.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(-1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle( 7.f / 4.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(11.f / 6.f * PI), BrFixedATan2(BrFloatToFixed( 1.f), BrFloatToFixed(-0.5773502691896258f))); + + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(1.f / 2.f * PI), BrFixedATan2(BrFloatToFixed(1.f), BrFloatToFixed(16000.f))); + + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(1.f / 6.f * PI), BrFixedATan2(BrFloatToFixed(1.7320508075688772f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(1.f / 3.f * PI), BrFixedATan2(BrFloatToFixed(0.5773502691896258f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(1.f / 6.f * PI), BrFixedATan2(BrFloatToFixed(1.7320508075688772f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-3f), BrRadianToAngle(1.f / 3.f * PI), BrFixedATan2(BrFloatToFixed(0.5773502691896258f), BrFloatToFixed(1.f))); +} + +static void test_fixed_BrFixedATan2Fast() { + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 0.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(0.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 1.f / 6.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(0.5773502691896258f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 1.f / 4.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 1.f / 3.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 1.f / 2.f * PI), BrFixedATan2Fast(BrFloatToFixed( 0.f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 2.f / 3.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 3.f / 4.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 5.f / 6.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(0.5773502691896258f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 1.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(0.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 7.f / 6.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(-0.5773502691896258f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 5.f / 4.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 4.f / 3.f * PI), BrFixedATan2Fast(BrFloatToFixed(-1.f), BrFloatToFixed(-1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 3.f / 2.f * PI), BrFixedATan2Fast(BrFloatToFixed( 0.f), BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 5.f / 3.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(-1.7320508075688772f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle( 7.f / 4.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(-1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle(11.f / 6.f * PI), BrFixedATan2Fast(BrFloatToFixed( 1.f), BrFloatToFixed(-0.5773502691896258f))); + + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle(1.f / 2.f * PI), BrFixedATan2Fast(BrFloatToFixed(1.f), BrFloatToFixed(30000.f))); + + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle(1.f / 6.f * PI), BrFixedATan2Fast(BrFloatToFixed(1.7320508075688772f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle(1.f / 3.f * PI), BrFixedATan2Fast(BrFloatToFixed(0.5773502691896258f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle(1.f / 6.f * PI), BrFixedATan2Fast(BrFloatToFixed(1.7320508075688772f), BrFloatToFixed(1.f))); + TEST_ASSERT_UINT16_WITHIN(BrRadianToAngle(1e-1f), BrRadianToAngle(1.f / 3.f * PI), BrFixedATan2Fast(BrFloatToFixed(0.5773502691896258f), BrFloatToFixed(1.f))); +} + +static void test_fixed_BrFastSqrt32() { + TEST_ASSERT_UINT16_WITHIN(5, 0, _BrFastSqrt32(0)); + TEST_ASSERT_UINT16_WITHIN(5, 1, _BrFastSqrt32(1)); + TEST_ASSERT_UINT16_WITHIN(5, 1, _BrFastSqrt32(2)); + TEST_ASSERT_UINT16_WITHIN(5, 2, _BrFastSqrt32(4)); + TEST_ASSERT_UINT16_WITHIN(5, 2, _BrFastSqrt32(8)); + TEST_ASSERT_UINT16_WITHIN(5, 3, _BrFastSqrt32(9)); + TEST_ASSERT_UINT16_WITHIN(5, 3, _BrFastSqrt32(15)); + TEST_ASSERT_UINT16_WITHIN(5, 4, _BrFastSqrt32(16)); + TEST_ASSERT_UINT16_WITHIN(5, 4, _BrFastSqrt32(24)); + TEST_ASSERT_UINT16_WITHIN(5, 5, _BrFastSqrt32(25)); + TEST_ASSERT_UINT16_WITHIN(5, 15, _BrFastSqrt32(255)); + TEST_ASSERT_UINT16_WITHIN(5, 16, _BrFastSqrt32(256)); + TEST_ASSERT_UINT16_WITHIN(5, 99, _BrFastSqrt32(9999)); + TEST_ASSERT_UINT16_WITHIN(5, 100, _BrFastSqrt32(10000)); + TEST_ASSERT_UINT16_WITHIN(0x100, 17320, _BrFastSqrt32(300000000)); + TEST_ASSERT_UINT16_WITHIN(0x100, 0xffff, _BrFastSqrt32(0xffffffff)); +} + +static void test_fixed_BrFastRSqrt32() { + TEST_ASSERT_UINT32_WITHIN(0, 0x00000, _BrFastRSqrt32(0)); + TEST_ASSERT_UINT32_WITHIN(1, 0x10000, _BrFastRSqrt32(1)); + TEST_ASSERT_UINT32_WITHIN(1, (uint32_t)(0x10000 / sqrtf(2.f)), _BrFastRSqrt32(2)); + TEST_ASSERT_UINT32_WITHIN(1, 0x08000, _BrFastRSqrt32(4)); + TEST_ASSERT_UINT32_WITHIN(1, (uint32_t)(0x10000 / sqrtf(8.f)), _BrFastRSqrt32(8)); + TEST_ASSERT_UINT32_WITHIN(1, (uint32_t)(0x10000 / sqrtf(9.f)), _BrFastRSqrt32(9)); + TEST_ASSERT_UINT32_WITHIN(1, (uint32_t)(0x10000 / sqrtf(15.f)), _BrFastRSqrt32(15)); + TEST_ASSERT_UINT32_WITHIN(1, 0x04000, _BrFastRSqrt32(16)); + TEST_ASSERT_UINT32_WITHIN(1, (uint32_t)(0x10000 / sqrtf(24.f)), _BrFastRSqrt32(24)); + TEST_ASSERT_UINT32_WITHIN(1, (uint32_t)(0x10000 / sqrtf(25.f)), _BrFastRSqrt32(25)); + TEST_ASSERT_UINT32_WITHIN(10, (uint32_t)(0x10000 / sqrtf(255.f)), _BrFastRSqrt32(255)); + TEST_ASSERT_UINT32_WITHIN(10, 0x01000, _BrFastRSqrt32(256)); + TEST_ASSERT_UINT32_WITHIN(10, 0x00800, _BrFastRSqrt32(1024)); + TEST_ASSERT_UINT32_WITHIN(10, (uint32_t)(0x10000 / sqrtf(9999.f)), _BrFastRSqrt32(9999)); + TEST_ASSERT_UINT32_WITHIN(10, (uint32_t)(0x10000 / sqrtf(10000.f)), _BrFastRSqrt32(10000)); + TEST_ASSERT_UINT32_WITHIN(10, (uint32_t)(0x10000 / sqrtf(300000000.f)), _BrFastRSqrt32(300000000)); + TEST_ASSERT_UINT32_WITHIN(10, (uint32_t)(0x10000 / sqrtf((float)0xffffffff)), _BrFastRSqrt32(0xffffffff)); +} + +static void test_fixed_BrFastRSqrt64() { + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x00000000, _BrFastRSqrt64(0)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-0f), 0xffffffff, _BrFastRSqrt64(1)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-0f), 0x80000000, _BrFastRSqrt64(4)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-0f), 0x40000000, _BrFastRSqrt64(16)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-0f), 0x20000000, _BrFastRSqrt64(64)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-0f), 0x10000000, _BrFastRSqrt64(256)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-1f), 0x08000000, _BrFastRSqrt64(1024)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-2f), 0x1000000, _BrFastRSqrt64(0x00010000ULL)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x000100000, _BrFastRSqrt64(0x01000000ULL)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-1f), BrFloatToFixed(1.f / sqrtf(2.f)), _BrFastRSqrt64(2ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x00008000, _BrFastRSqrt64(4ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(8.f)), _BrFastRSqrt64(8ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(9.f)), _BrFastRSqrt64(9ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(15.f)), _BrFastRSqrt64(15ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x4000, _BrFastRSqrt64(16ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(24.f)), _BrFastRSqrt64(24ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(25.f)), _BrFastRSqrt64(25ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(81.f)), _BrFastRSqrt64(81ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(255.f)), _BrFastRSqrt64(255ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x1000, _BrFastRSqrt64(256ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x00800, _BrFastRSqrt64(1024ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(9999.f)), _BrFastRSqrt64(9999ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(10000.f)), _BrFastRSqrt64(10000ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(300000000.f)), _BrFastRSqrt64(300000000ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf(1600000000000.f)), _BrFastRSqrt64(1600000000000ULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), BrFloatToFixed(1.f / sqrtf((float)0xffffffff)), _BrFastRSqrt64(0xffffffffULL<<32)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x10000, _BrFastRSqrt64(0x100000000)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e-3f), 0x8000, _BrFastRSqrt64(0x400000000)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e1f), BrFloatToFixed(1.f / sqrtf((float)0x1000000000)), _BrFastRSqrt64(0x1000000000ULL)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e1f), BrFloatToFixed(1.f / sqrtf((float)0x100000000000)), _BrFastRSqrt64(0x100000000000ULL)); + TEST_ASSERT_UINT32_WITHIN(BrFloatToFixed(1.e1f), BrFloatToFixed(1.f / sqrtf((float)0xffffffffffffffffULL)), _BrFastRSqrt64(0xffffffffffffffffULL)); +} + +static void test_fixed_BrFixedRLength2() { + TEST_ASSERT_EQUAL_INT32(BrFloatToFixed(.2f), BrFixedRLength2(BrFloatToFixed(3.f), BrFloatToFixed(4.f))); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-2f), BrFloatToFixed(2.f), BrFixedRLength2(BrFloatToFixed(.3f), BrFloatToFixed(.4f))); +} + +static void test_fixed_BrFixedRLength3() { + TEST_ASSERT_EQUAL_INT32(BrFloatToFixed(1/7.f), BrFixedRLength3(BrFloatToFixed(2.f), BrFloatToFixed(3.f), BrFloatToFixed(6.f))); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1.e-2f), BrFloatToFixed(1/.7f), BrFixedRLength3(BrFloatToFixed(.2f), BrFloatToFixed(.3f), BrFloatToFixed(.6f))); +} + +static void test_fixed_BrFixedRLength4() { + TEST_ASSERT_EQUAL_INT32(BrFloatToFixed(1/9.f), BrFixedRLength4(BrFloatToFixed(2.f), BrFloatToFixed(4.f), BrFloatToFixed(5.f), BrFloatToFixed(6.f))); + TEST_ASSERT_INT32_WITHIN(BrFloatToFixed(1e-3f), BrFloatToFixed(1/.9f), BrFixedRLength4(BrFloatToFixed(.2f), BrFloatToFixed(.4f), BrFloatToFixed(.5f), BrFloatToFixed(.6f))); +} + +void test_fixed_suite() { + UnitySetTestFile(__FILE__); + RUN_TEST(test_fixed_conversions); + RUN_TEST(test_fixed_BrFixedAbs); + RUN_TEST(test_fixed_BrFixedMul); + RUN_TEST(test_fixed_BrFixedMac2); + RUN_TEST(test_fixed_BrFixedMac3); + RUN_TEST(test_fixed_BrFixedMac4); + RUN_TEST(test_fixed_BrISqrt32); + RUN_TEST(test_fixed_BrISqrt64); + RUN_TEST(test_fixed_BrFixedLength2); + RUN_TEST(test_fixed_BrFixedLength3); + RUN_TEST(test_fixed_BrFixedLength4); + RUN_TEST(test_fixed_BrFixedDiv); + RUN_TEST(test_fixed_BrFixedDivR); + RUN_TEST(test_fixed_BrFixedDivF); + RUN_TEST(test_fixed_BrFixedMulDiv); + RUN_TEST(test_fixed_BrFixedMac2Div); + RUN_TEST(test_fixed_BrFixedMac3Div); + RUN_TEST(test_fixed_BrFixedMac4Div); + RUN_TEST(test_fixed_BrFixedFMac2); + RUN_TEST(test_fixed_BrFixedFMac3); + RUN_TEST(test_fixed_BrFixedFMac4); + RUN_TEST(test_fixed_BrFixedRcp); + RUN_TEST(test_fixed_BrFixedSqr); + RUN_TEST(test_fixed_BrFixedSqr2); + RUN_TEST(test_fixed_BrFixedSqr3); + RUN_TEST(test_fixed_BrFixedSqr4); + RUN_TEST(test_fixed_BrFixedSin); + RUN_TEST(test_fixed_BrFixedCos); + RUN_TEST(test_fixed_BrFixedASin); + RUN_TEST(test_fixed_BrFixedACos); + RUN_TEST(test_fixed_BrFixedATan2); + RUN_TEST(test_fixed_BrFixedATan2Fast); + RUN_TEST(test_fixed_BrFastSqrt32); + RUN_TEST(test_fixed_BrFastRSqrt32); + RUN_TEST(test_fixed_BrFastRSqrt64); + RUN_TEST(test_fixed_BrFixedRLength2); + RUN_TEST(test_fixed_BrFixedRLength3); + RUN_TEST(test_fixed_BrFixedRLength4); +} diff --git a/test/BRSRC13/test_matrix23.c b/test/BRSRC13/test_matrix23.c index 4c470b2d..67a2520f 100644 --- a/test/BRSRC13/test_matrix23.c +++ b/test/BRSRC13/test_matrix23.c @@ -401,6 +401,7 @@ void test_matrix23_BrMatrix23PostShearY() { } void test_matrix23_suite() { + UnitySetTestFile(__FILE__); RUN_TEST(test_matrix23_BrMatrix23Copy); RUN_TEST(test_matrix23_BrMatrix23Identity); RUN_TEST(test_matrix23_BrMatrix23Rotate); diff --git a/test/BRSRC13/test_matrix34.c b/test/BRSRC13/test_matrix34.c index 9d283c89..c5c50898 100644 --- a/test/BRSRC13/test_matrix34.c +++ b/test/BRSRC13/test_matrix34.c @@ -547,6 +547,7 @@ static void test_matrix34_BrMatrix34PostRotateZ() { } void test_matrix34_suite() { + UnitySetTestFile(__FILE__); RUN_TEST(test_matrix34_BrMatrix34Copy); RUN_TEST(test_matrix34_BrMatrix34Mul); RUN_TEST(test_matrix34_BrMatrix34Identity); diff --git a/test/BRSRC13/test_matrix4.c b/test/BRSRC13/test_matrix4.c index 16b4e048..f0fc2d1e 100644 --- a/test/BRSRC13/test_matrix4.c +++ b/test/BRSRC13/test_matrix4.c @@ -321,6 +321,7 @@ void test_matrix4_BrMatrix4ShearZ() { } void test_matrix4_suite() { + UnitySetTestFile(__FILE__); RUN_TEST(test_matrix4_BrMatrix4Copy); RUN_TEST(test_matrix4_BrMatrix4Mul); RUN_TEST(test_matrix4_BrMatrix4Identity); diff --git a/test/BRSRC13/test_quat.c b/test/BRSRC13/test_quat.c index 06fb905d..ffe0a1cb 100644 --- a/test/BRSRC13/test_quat.c +++ b/test/BRSRC13/test_quat.c @@ -357,6 +357,7 @@ static void test_quat_BrMatrix4ToQuat() { } void test_quat_suite() { + UnitySetTestFile(__FILE__); RUN_TEST(test_quat_BrQuatMul); RUN_TEST(test_quat_BrQuatNormalise); RUN_TEST(test_quat_BrQuatInvert); diff --git a/test/BRSRC13/test_scratch.c b/test/BRSRC13/test_scratch.c new file mode 100644 index 00000000..7026938c --- /dev/null +++ b/test/BRSRC13/test_scratch.c @@ -0,0 +1,100 @@ +#include "CORE/FW/scratch.h" +#include "CORE/FW/fwsetup.h" +#include "tests.h" +#include + +static void test_scratch_BrScratchAllocate_BrScratchFree_BrScratchInquire() { + void *block = NULL; + + TEST_ASSERT_FALSE(fw.scratch_inuse); + + block = BrScratchAllocate(0x100); + + TEST_ASSERT_NOT_NULL(block); + TEST_ASSERT_TRUE(fw.scratch_inuse); + TEST_ASSERT_EQUAL(0x100, fw.scratch_last); + TEST_ASSERT_EQUAL(block, fw.scratch_ptr); + TEST_ASSERT_LESS_OR_EQUAL_size_t(0x100, BrScratchInquire()); + + BrScratchFree(block); + + TEST_ASSERT_EQUAL(block, fw.scratch_ptr); + TEST_ASSERT_FALSE(fw.scratch_inuse); +} + +static void test_scratch_BrScratchFree_NULL() {; + br_size_t scratch_size; + void *block = NULL; + + TEST_ASSERT_FALSE(fw.scratch_inuse); + + block = BrScratchAllocate(0x100); + + TEST_ASSERT_TRUE(fw.scratch_inuse); + + BrScratchFree(block); + block = NULL; + + TEST_ASSERT_FALSE(fw.scratch_inuse); +} + +static void test_scratch_BrScratchFlush() {; + br_size_t scratch_size; + void *block = NULL; + + TEST_ASSERT_FALSE(fw.scratch_inuse); + + block = BrScratchAllocate(0x100); + + TEST_ASSERT_TRUE(fw.scratch_inuse); + TEST_ASSERT_EQUAL(block, fw.scratch_ptr); + + BrScratchFree(block); + + TEST_ASSERT_FALSE(fw.scratch_inuse); + TEST_ASSERT_EQUAL(block, fw.scratch_ptr); + + BrScratchFlush(); + + TEST_ASSERT_FALSE(fw.scratch_inuse); + TEST_ASSERT_EQUAL(NULL, fw.scratch_ptr); +} + +static void test_scratch_BrScratchSize() { + TEST_ASSERT_EQUAL(0x200, BrScratchStringSize()); +} + +static void test_scratch_BrScratchString() { + int i; + char *text1; + char *text2; + + text1 = NULL; + text2 = NULL; + + text1 = BrScratchString(); + + TEST_ASSERT_NOT_NULL(text1); + + for (int i = 0; i < 0x200; i++) { + text1[i] = (char)i; + } + + text2 = BrScratchString(); + + TEST_ASSERT_NOT_NULL(text2); + TEST_ASSERT_EQUAL(text1, text2); + + for (int i = 0; i < 0x200; i++) { + TEST_ASSERT_EQUAL_UINT8(i, text2[i]); + } +} + +void test_scratch_suite() { + UnitySetTestFile(__FILE__); + RUN_TEST(test_scratch_BrScratchAllocate_BrScratchFree_BrScratchInquire); + RUN_TEST(test_scratch_BrScratchFree_NULL); + RUN_TEST(test_scratch_BrScratchFlush); + RUN_TEST(test_scratch_BrScratchSize); + RUN_TEST(test_scratch_BrScratchString); +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 64b7b6f1..704c133e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,15 +34,20 @@ target_sources(dethrace_test PRIVATE BRSRC13/test_actsupt.c BRSRC13/test_brlists.c BRSRC13/test_datafile.c + BRSRC13/test_fixed.c BRSRC13/test_fwsetup.c BRSRC13/test_genclip.c BRSRC13/test_pattern.c BRSRC13/test_pmfile.c BRSRC13/test_quat.c + BRSRC13/test_matrix23.c + BRSRC13/test_matrix34.c + BRSRC13/test_matrix4.c BRSRC13/test_register.c BRSRC13/test_regsupt.c BRSRC13/test_resource.c BRSRC13/test_resreg.c + BRSRC13/test_scratch.c BRSRC13/test_v1dbfile.c DETHRACE/test_controls.c DETHRACE/test_dossys.c diff --git a/test/main.c b/test/main.c index 8315a45c..6aed8704 100644 --- a/test/main.c +++ b/test/main.c @@ -1,3 +1,4 @@ +#include "tests.h" #include "harness/hooks.h" #include #include @@ -43,8 +44,13 @@ extern void test_genclip_suite(); extern void test_datafile_suite(); extern void test_v1dbfile_suite(); extern void test_register_suite(); +extern void test_scratch_suite(); extern void test_pattern_suite(); extern void test_pmfile_suite(); +extern void test_fixed_suite(); +extern void test_matrix23_suite(); +extern void test_matrix34_suite(); +extern void test_matrix4_suite(); extern void test_quat_suite(); extern void test_graphics_suite(); extern void test_regsupt_suite(); @@ -60,6 +66,24 @@ void setUp(void) { void tearDown(void) { } +static const char *temp_folder; +static char temp_folder_buffer[PATH_MAX+1]; + +static void setup_temp_folder() { +#ifdef _WIN32 + DWORD res; + char tmpBuffer[PATH_MAX+1]; + res = GetTempPathA(sizeof(tmpBuffer), tmpBuffer); + if (res == 0) { + abort(); + } + sprintf(temp_folder_buffer, "%s\\dethrace_test_%d", tmpBuffer, GetCurrentProcessId()); +#else + sprintf(temp_folder_buffer, "/tmp/dethrace_test_%d", getpid()); +#endif + temp_folder = temp_folder_buffer; +} + void setup_global_vars() { strcpy(gDir_separator, "/"); @@ -88,6 +112,9 @@ void setup_global_vars() { strcpy(gBasic_car_names[0], "BLKEAGLE.TXT"); + setup_temp_folder(); + printf("INFO: temp folder is \"%s\"\n", temp_folder); + _unittest_do_not_exit = 1; harness_debug_level = 7; harness_game_info.mode = eGame_carmageddon; @@ -111,6 +138,49 @@ void sleep_s(int sec) { #endif } +void create_temp_file(char buffer[PATH_MAX+1], const char *prefix) { +#ifdef _WIN32 + DWORD attributes; + UINT res; + BOOL success; + + attributes = GetFileAttributesA(temp_folder); + if ((attributes == INVALID_FILE_ATTRIBUTES) || ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0)) { + LOG_TRACE("Temporary folder does not exist => creating"); + success = CreateDirectoryA(temp_folder, NULL); + if (success == 0) { + abort(); + } + } + res = GetTempFileNameA(temp_folder, prefix, 0, buffer); + if (res == 0) { + abort(); + } + strcat(buffer, prefix); +#else + int fdres; + struct stat sb; + int res; + + stat(temp_folder, &sb); + if (!S_ISDIR(sb.st_mode)) { + res = mkdir(temp_folder, 0770); + if (res == -1) { + abort(); + } + } + strcpy(buffer, temp_folder); + strcat(buffer, "/"); + strcat(buffer, prefix); + strcat(buffer, "XXXXXX"); + fdres = mkstemp(buffer); + if (fdres == -1) { + abort(); + } + close(fdres); +#endif +} + int main(int argc, char** argv) { UNITY_BEGIN(); @@ -124,6 +194,11 @@ int main(int argc, char** argv) { printf("Completed setup\n"); // BRSRC13 + test_matrix23_suite(); + test_matrix34_suite(); + test_matrix4_suite(); + test_quat_suite(); + test_brlists_suite(); test_fwsetup_suite(); test_resource_suite(); @@ -134,9 +209,10 @@ int main(int argc, char** argv) { test_pattern_suite(); test_pmfile_suite(); - test_quat_suite(); + test_fixed_suite(); test_v1dbfile_suite(); test_regsupt_suite(); + test_scratch_suite(); // DETHRACE test_utility_suite(); diff --git a/test/tests.h b/test/tests.h index 6313f821..28a26a2a 100644 --- a/test/tests.h +++ b/test/tests.h @@ -4,19 +4,25 @@ #include "framework/unity.h" #include "harness/trace.h" +#ifndef PATH_MAX +#define PATH_MAX 300 +#endif +#define HOST_NL "\n" + extern int has_data_directory(); extern void sleep_s(int sec); +void create_temp_file(char buffer[PATH_MAX+1], const char *prefix); #define REQUIRES_DATA_DIRECTORY() \ if (!has_data_directory()) \ TEST_IGNORE(); -#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) { \ +#define TEST_ASSERT_FLOAT_ARRAY_WITHIN(delta, expected, actual, num_elements) do { \ float *priv_expected = (float*)(expected); \ float *priv_actual = (float*)(actual); \ for(int it = (num_elements); it != 0; --it, ++priv_expected, ++priv_actual) { \ TEST_ASSERT_FLOAT_WITHIN((delta), *priv_expected, *priv_actual); \ } \ -} +} while (0) #endif