From 5471bcf1027ddc1ee7c5536f5cc624104c2402de Mon Sep 17 00:00:00 2001 From: William Miles Date: Tue, 6 Sep 2022 18:45:31 +1000 Subject: [PATCH] Reformatting. --- NavmeshList/main.c | 46 +-- espReader/ESPReader.h | 357 +++++++++-------- espReader/LUT.c | 892 +++++++++++++++++++++--------------------- espReader/Reader.c | 522 ++++++++++++------------ mph_gen/main.c | 98 ++--- 5 files changed, 960 insertions(+), 955 deletions(-) diff --git a/NavmeshList/main.c b/NavmeshList/main.c index 5c55984..1cd852a 100644 --- a/NavmeshList/main.c +++ b/NavmeshList/main.c @@ -11,38 +11,38 @@ #include int main(void) { - FILE *fp; - errno_t ret = fopen_s(&fp, "Skyrim.esm", "rb"); + FILE *fp; + errno_t ret = fopen_s(&fp, "Skyrim.esm", "rb"); - if (ret || !fp) - return ret; + if (ret || !fp) + return ret; - fseek(fp, 0L, SEEK_END); - size_t size = ftell(fp); - rewind(fp); + fseek(fp, 0L, SEEK_END); + size_t size = ftell(fp); + rewind(fp); - char *buffer = malloc(size); - if (!buffer) - return errno; + char *buffer = malloc(size); + if (!buffer) + return errno; - size_t read = fread(buffer, sizeof(char), size, fp); - assert(read == size); + size_t read = fread(buffer, sizeof(char), size, fp); + assert(read == size); - size_t dc_size = espr_decompressed_size(buffer, size); - - char *decompressed = malloc(dc_size); - if (!decompressed) - return errno; + size_t dc_size = espr_decompressed_size(buffer, size); - espr_decompress(buffer, size, decompressed, dc_size); + char *decompressed = malloc(dc_size); + if (!decompressed) + return errno; - free(buffer); + espr_decompress(buffer, size, decompressed, dc_size); - size_t formid_count = espr_formid_count(decompressed, dc_size); + free(buffer); - printf("FormID Count: %zu\n", formid_count); + size_t formid_count = espr_formid_count(decompressed, dc_size); - free(decompressed); + printf("FormID Count: %zu\n", formid_count); - return 0; + free(decompressed); + + return 0; } diff --git a/espReader/ESPReader.h b/espReader/ESPReader.h index 00ead5e..3a78fd1 100644 --- a/espReader/ESPReader.h +++ b/espReader/ESPReader.h @@ -26,7 +26,7 @@ #include #include "msh.h" - // Guards for C++ usage +// Guards for C++ usage #ifdef __cplusplus extern "C" { #endif @@ -38,7 +38,7 @@ extern "C" { /* RT hash seed was externally calculated s.t. the fourcc codes perfectly hash into * indices between 0 and 511. That is, there are no hashing collisions. This allows * for hard coded lookup tables for the fourcc codes in a relatively small space. - * + * * A minimal perfect hash is also possible with an intermediate seed table, though * I'm not sure which is faster, if it's worth trying to speed this up, etc. */ @@ -52,219 +52,216 @@ extern "C" { #define GTS_SIZE 10 -// -// === FORWARD DEFS === -// + // + // === FORWARD DEFS === + // - typedef union type4 Type4; - typedef struct timestamp Timestamp; - typedef struct group Group; - typedef struct record Record; - typedef struct field Field; + typedef union type4 Type4; + typedef struct timestamp Timestamp; + typedef struct group Group; + typedef struct record Record; + typedef struct field Field; -// -// === SIMPLE TYPES === -// + // + // === SIMPLE TYPES === + // - // Basic types - typedef uint32_t formid; + typedef uint32_t formid; - // char[4] with uint32_t access - union type4 { - char bytes[4]; - uint32_t uint; - }; + // char[4] with uint32_t access + union type4 { + char bytes[4]; + uint32_t uint; + }; - // indexed by flag bit - typedef const char *const rfs_inner[RFS_INNER_SIZE]; + // indexed by flag bit + typedef const char *const rfs_inner[RFS_INNER_SIZE]; -// -// === ENUMS === -// + // + // === ENUMS === + // - // Tag for generic node tagged union - enum node_type { // NT_ prefix - NT_GROUP, - NT_RECORD, - }; + // Tag for generic node tagged union + enum node_type { // NT_ prefix + NT_GROUP, + NT_RECORD, + }; - // Record type enum - enum record_type { - _NONE, - AACT, ACHR, ACTI, ADDN, ALCH, AMMO, - ANIO, APPA, ARMA, ARMO, ARTO, ASPC, - ASTP, AVIF, BOOK, BPTD, CAMS, CELL, - CLAS, CLDC, CLFM, CLMT, COBJ, COLL, - CONT, CPTH, CSTY, DEBR, DIAL, DLBR, - DLVW, DOBJ, DOOR, DUAL, ECZN, EFSH, - ENCH, EQUP, EXPL, EYES, FACT, FLOR, - FLST, FSTP, FSTS, FURN, GLOB, GMST, - GRAS, GRUP, HAIR, HAZD, HDPT, IDLE, - IDLM, IMAD, IMGS, INFO, INGR, IPCT, - IPDS, KEYM, KYWD, LAND, LCRT, LCTN, - LGTM, LIGH, LSCR, LTEX, LVLI, LVLN, - LVSP, MATO, MATT, MESG, MGEF, MISC, - MOVT, MSTT, MUSC, MUST, NAVI, NAVM, - NOTE, NPC_, OTFT, PACK, PERK, PGRE, - PHZD, PROJ, PWAT, QUST, RACE, REFR, - REGN, RELA, REVB, RFCT, RGDL, SCEN, - SCOL, SCPT, SCRL, SHOU, SLGM, SMBN, - SMEN, SMQN, SNCT, SNDR, SOPM, SOUN, - SPEL, SPGD, STAT, TACT, TES4, TREE, - TXST, VTYP, WATR, WEAP, WOOP, WRLD, - WTHR, - }; + // Record type enum + enum record_type { + AACT, ACHR, ACTI, ADDN, ALCH, AMMO, + ANIO, APPA, ARMA, ARMO, ARTO, ASPC, + ASTP, AVIF, BOOK, BPTD, CAMS, CELL, + CLAS, CLDC, CLFM, CLMT, COBJ, COLL, + CONT, CPTH, CSTY, DEBR, DIAL, DLBR, + DLVW, DOBJ, DOOR, DUAL, ECZN, EFSH, + ENCH, EQUP, EXPL, EYES, FACT, FLOR, + FLST, FSTP, FSTS, FURN, GLOB, GMST, + GRAS, GRUP, HAIR, HAZD, HDPT, IDLE, + IDLM, IMAD, IMGS, INFO, INGR, IPCT, + IPDS, KEYM, KYWD, LAND, LCRT, LCTN, + LGTM, LIGH, LSCR, LTEX, LVLI, LVLN, + LVSP, MATO, MATT, MESG, MGEF, MISC, + MOVT, MSTT, MUSC, MUST, NAVI, NAVM, + NOTE, NPC_, OTFT, PACK, PERK, PGRE, + PHZD, PROJ, PWAT, QUST, RACE, REFR, + REGN, RELA, REVB, RFCT, RGDL, SCEN, + SCOL, SCPT, SCRL, SHOU, SLGM, SMBN, + SMEN, SMQN, SNCT, SNDR, SOPM, SOUN, + SPEL, SPGD, STAT, TACT, TES4, TREE, + TXST, VTYP, WATR, WEAP, WOOP, WRLD, + WTHR, + }; - // GRUP type values - enum group_type { // GT_ prefix - GT_TOP = 0, - GT_WORLD_CHILDREN = 1, - GT_INTERIOR_CELL_BLOCK = 2, - GT_INTERIOR_CELL_SUBBLOCK = 3, - GT_EXTERIOR_CELL_BLOCK = 4, - GT_EXTERIOR_CELL_SUBBLOCK = 5, - GT_CELL_CHILDREN = 6, - GT_TOPIC_CHILDREN = 7, - GT_CELL_PERSISTENT_CHILDREN = 8, - GT_CELL_TEMPORARY_CHILDREN = 9, - }; + // GRUP type values + enum group_type { // GT_ prefix + GT_TOP = 0, + GT_WORLD_CHILDREN = 1, + GT_INTERIOR_CELL_BLOCK = 2, + GT_INTERIOR_CELL_SUBBLOCK = 3, + GT_EXTERIOR_CELL_BLOCK = 4, + GT_EXTERIOR_CELL_SUBBLOCK = 5, + GT_CELL_CHILDREN = 6, + GT_TOPIC_CHILDREN = 7, + GT_CELL_PERSISTENT_CHILDREN = 8, + GT_CELL_TEMPORARY_CHILDREN = 9, + }; -// -// === COMPOSITE TYPES === -// + // + // === COMPOSITE TYPES === + // - // Generic node - typedef struct node Node; - struct node { - union { - Group *group; - Record *record; - } header; - char *const data; - enum node_type type; - uint32_t _pad; - }; + // Generic node + typedef struct node Node; + struct node { + union { + Group *group; + Record *record; + } header; + char *const data; + enum node_type type; + uint32_t _pad; + }; - // calculated timestamp - struct timestamp { - uint16_t year; - uint8_t month; - uint8_t day; - }; + // calculated timestamp + struct timestamp { + uint16_t year; + uint8_t month; + uint8_t day; + }; - struct walker_callbacks { - void (*pre)(Node n, void *data, void **carry_out); - void (*post)(Node n, void *data, void **carry_in); - void *data; - }; + struct walker_callbacks { + void (*pre)(Node n, void *data, void **carry_out); + void (*post)(Node n, void *data, void **carry_in); + void *data; + }; -// -// === BINARY DATA OVERLAYS === -// + // + // === BINARY DATA OVERLAYS === + // #pragma pack(push, 1) - // Group header overlay - struct group { - Type4 grup; // always RT_GRUP - uint32_t size; // uncludes the 24 byte group header - union { - Type4 type; // this may be mangled and should not be relied on - formid formid; - int32_t number; - int16_t coord[2]; - } label; // access determined by the `type` below - int32_t type; // group_type enum - uint16_t timestamp; - uint16_t vcinfo; - uint32_t unknown; - }; + // Group header overlay + struct group { + Type4 grup; // always RT_GRUP + uint32_t size; // uncludes the 24 byte group header + union { + Type4 type; // this may be mangled and should not be relied on + formid formid; + int32_t number; + int16_t coord[2]; + } label; // access determined by the `type` below + int32_t type; // group_type enum + uint16_t timestamp; + uint16_t vcinfo; + uint32_t unknown; + }; - // Record header overlay - struct record { - Type4 type; - uint32_t size; - uint32_t flags; - uint32_t formid; - uint16_t timestamp; - uint16_t vcinfo; - uint16_t version; - uint16_t unknown; - }; + // Record header overlay + struct record { + Type4 type; + uint32_t size; + uint32_t flags; + uint32_t formid; + uint16_t timestamp; + uint16_t vcinfo; + uint16_t version; + uint16_t unknown; + }; - // Field header overlay - struct field { - Type4 type; - uint16_t size; - }; + // Field header overlay + struct field { + Type4 type; + uint16_t size; + }; #pragma pack(pop) -// -// === LUTs === -// + // + // === LUTs === + // - // record type enum to fourcc value - extern const uint32_t rt[RT_SIZE]; + // record type enum to fourcc value + extern const uint32_t rt[RT_SIZE]; - // for converting between record_type and record_type_hash enums - extern const uint16_t rt2rth[RT_SIZE]; - extern const uint8_t rth2rt[RT_HASH_SIZE]; + // for converting between record_type and record_type_hash enums + extern const uint16_t rt2rth[RT_SIZE]; + extern const uint8_t rth2rt[RT_HASH_SIZE]; - // type -> flag mappings - // NULL table pointers indicate no flags - // NULL string pointers indicate invalid flag - extern rfs_inner *const rfs[RT_HASH_SIZE]; + // type -> flag mappings + // NULL table pointers indicate no flags + // NULL string pointers indicate invalid flag + extern rfs_inner *const rfs[RT_HASH_SIZE]; - extern rfs_inner *const rfs_refr[RT_HASH_SIZE]; + extern rfs_inner *const rfs_refr[RT_HASH_SIZE]; - // Expected (probably) order of top level groups in an esp/esm - extern const enum record_type group_order[GO_SIZE]; + // Expected (probably) order of top level groups in an esp/esm + extern const enum record_type group_order[GO_SIZE]; - // Printable strings for group types - extern const char *const group_type_strings[GTS_SIZE]; + // Printable strings for group types + extern const char *const group_type_strings[GTS_SIZE]; + // + // === FUNCTIONS === + // -// -// === FUNCTIONS === -// + // hashes type value into RT_ hash value + inline uint32_t rt_hash(uint32_t type) { + return uint32_t_msh(type, RT_HASH_BITS, RT_HASH_SEED); + } - // hashes type value into RT_ hash value - inline uint32_t rt_hash(uint32_t type) { - return uint32_t_msh(type, RT_HASH_BITS, RT_HASH_SEED); - } + /* `espr_walk` walks through the tree structure of the esp/esm binary data + * starting at `data` of `size` bytes. + * + * `cb` is a callback that takes a `Node` to process. `pt` is a pointer to + * arbitrary data that is passed on to `cb` whenever it is called. + * + * Data is walked sequentially. Nodes passed to `cb` will be strictly increasing + * in terms of memory location within the buffer. + */ + void espr_walk(char *data, size_t size, struct walker_callbacks cb); - /* `espr_walk` walks through the tree structure of the esp/esm binary data - * starting at `data` of `size` bytes. - * - * `cb` is a callback that takes a `Node` to process. `pt` is a pointer to - * arbitrary data that is passed on to `cb` whenever it is called. - * - * Data is walked sequentially. Nodes passed to `cb` will be strictly increasing - * in terms of memory location within the buffer. - */ - void espr_walk(char *data, size_t size, struct walker_callbacks cb); + /* `espr_print` prints the header of every group and record in the given + * esp/esm binary data. + */ + void espr_print(char *data, size_t size); - /* `espr_print` prints the header of every group and record in the given - * esp/esm binary data. - */ - void espr_print(char *data, size_t size); + /* Calculates the size of the esp data if all of the compressed records are + * decompressed. + */ + size_t espr_decompressed_size(char *data, size_t size); - /* Calculates the size of the esp data if all of the compressed records are - * decompressed. - */ - size_t espr_decompressed_size(char *data, size_t size); + /* Counts the number of formids present in the esp/esm data. This should be + * equal to the number of records. + */ + size_t espr_formid_count(char *data, size_t size); - /* Counts the number of formids present in the esp/esm data. This should be - * equal to the number of records. - */ - size_t espr_formid_count(char *data, size_t size); - - /* Copies the data from `data` to `buf` decompressing compressed fields as - * it does so. buf_size should be the value returned from `espr_decompressed_size`, - * and `buf` should be at least of that size. - */ - void espr_decompress(char *data, size_t size, char *buf, size_t buf_size); + /* Copies the data from `data` to `buf` decompressing compressed fields as + * it does so. buf_size should be the value returned from `espr_decompressed_size`, + * and `buf` should be at least of that size. + */ + void espr_decompress(char *data, size_t size, char *buf, size_t buf_size); // End C++ guard #ifdef __cplusplus diff --git a/espReader/LUT.c b/espReader/LUT.c index 5c9df2e..43c47a7 100644 --- a/espReader/LUT.c +++ b/espReader/LUT.c @@ -12,265 +12,265 @@ const enum record_type group_order[GO_SIZE] = { - GMST, KYWD, LCRT, AACT, TXST, GLOB, - CLAS, FACT, HDPT, HAIR, EYES, RACE, - SOUN, ASPC, MGEF, SCPT, LTEX, ENCH, - SPEL, SCRL, ACTI, TACT, ARMO, BOOK, - CONT, DOOR, INGR, LIGH, MISC, APPA, - STAT, SCOL, MSTT, PWAT, GRAS, TREE, - CLDC, FLOR, FURN, WEAP, AMMO, NPC_, - LVLN, KEYM, ALCH, IDLM, COBJ, PROJ, - HAZD, SLGM, LVLI, WTHR, CLMT, SPGD, - RFCT, REGN, NAVI, CELL, WRLD, DIAL, - QUST, IDLE, PACK, CSTY, LSCR, LVSP, - ANIO, WATR, EFSH, EXPL, DEBR, IMGS, - IMAD, FLST, PERK, BPTD, ADDN, AVIF, - CAMS, CPTH, VTYP, MATT, IPCT, IPDS, - ARMA, ECZN, LCTN, MESG, RGDL, DOBJ, - LGTM, MUSC, FSTP, FSTS, SMBN, SMQN, - SMEN, DLBR, MUST, DLVW, WOOP, SHOU, - EQUP, RELA, SCEN, ASTP, OTFT, ARTO, - MATO, MOVT, HAZD, SNDR, DUAL, SNCT, - SOPM, COLL, CLFM, REVB + GMST, KYWD, LCRT, AACT, TXST, GLOB, + CLAS, FACT, HDPT, HAIR, EYES, RACE, + SOUN, ASPC, MGEF, SCPT, LTEX, ENCH, + SPEL, SCRL, ACTI, TACT, ARMO, BOOK, + CONT, DOOR, INGR, LIGH, MISC, APPA, + STAT, SCOL, MSTT, PWAT, GRAS, TREE, + CLDC, FLOR, FURN, WEAP, AMMO, NPC_, + LVLN, KEYM, ALCH, IDLM, COBJ, PROJ, + HAZD, SLGM, LVLI, WTHR, CLMT, SPGD, + RFCT, REGN, NAVI, CELL, WRLD, DIAL, + QUST, IDLE, PACK, CSTY, LSCR, LVSP, + ANIO, WATR, EFSH, EXPL, DEBR, IMGS, + IMAD, FLST, PERK, BPTD, ADDN, AVIF, + CAMS, CPTH, VTYP, MATT, IPCT, IPDS, + ARMA, ECZN, LCTN, MESG, RGDL, DOBJ, + LGTM, MUSC, FSTP, FSTS, SMBN, SMQN, + SMEN, DLBR, MUST, DLVW, WOOP, SHOU, + EQUP, RELA, SCEN, ASTP, OTFT, ARTO, + MATO, MOVT, HAZD, SNDR, DUAL, SNCT, + SOPM, COLL, CLFM, REVB }; // record type to record type value const uint32_t rt[RT_SIZE] = { - [AACT] = LE('AACT'), [ACHR] = LE('ACHR'), [ACTI] = LE('ACTI'), - [ADDN] = LE('ADDN'), [ALCH] = LE('ALCH'), [AMMO] = LE('AMMO'), - [ANIO] = LE('ANIO'), [APPA] = LE('APPA'), [ARMA] = LE('ARMA'), - [ARMO] = LE('ARMO'), [ARTO] = LE('ARTO'), [ASPC] = LE('ASPC'), - [ASTP] = LE('ASTP'), [AVIF] = LE('AVIF'), [BOOK] = LE('BOOK'), - [BPTD] = LE('BPTD'), [CAMS] = LE('CAMS'), [CELL] = LE('CELL'), - [CLAS] = LE('CLAS'), [CLDC] = LE('CLDC'), [CLFM] = LE('CLFM'), - [CLMT] = LE('CLMT'), [COBJ] = LE('COBJ'), [COLL] = LE('COLL'), - [CONT] = LE('CONT'), [CPTH] = LE('CPTH'), [CSTY] = LE('CSTY'), - [DEBR] = LE('DEBR'), [DIAL] = LE('DIAL'), [DLBR] = LE('DLBR'), - [DLVW] = LE('DLVW'), [DOBJ] = LE('DOBJ'), [DOOR] = LE('DOOR'), - [DUAL] = LE('DUAL'), [ECZN] = LE('ECZN'), [EFSH] = LE('EFSH'), - [ENCH] = LE('ENCH'), [EQUP] = LE('EQUP'), [EXPL] = LE('EXPL'), - [EYES] = LE('EYES'), [FACT] = LE('FACT'), [FLOR] = LE('FLOR'), - [FLST] = LE('FLST'), [FSTP] = LE('FSTP'), [FSTS] = LE('FSTS'), - [FURN] = LE('FURN'), [GLOB] = LE('GLOB'), [GMST] = LE('GMST'), - [GRAS] = LE('GRAS'), [GRUP] = LE('GRUP'), [HAIR] = LE('HAIR'), - [HAZD] = LE('HAZD'), [HDPT] = LE('HDPT'), [IDLE] = LE('IDLE'), - [IDLM] = LE('IDLM'), [IMAD] = LE('IMAD'), [IMGS] = LE('IMGS'), - [INFO] = LE('INFO'), [INGR] = LE('INGR'), [IPCT] = LE('IPCT'), - [IPDS] = LE('IPDS'), [KEYM] = LE('KEYM'), [KYWD] = LE('KYWD'), - [LAND] = LE('LAND'), [LCRT] = LE('LCRT'), [LCTN] = LE('LCTN'), - [LGTM] = LE('LGTM'), [LIGH] = LE('LIGH'), [LSCR] = LE('LSCR'), - [LTEX] = LE('LTEX'), [LVLI] = LE('LVLI'), [LVLN] = LE('LVLN'), - [LVSP] = LE('LVSP'), [MATO] = LE('MATO'), [MATT] = LE('MATT'), - [MESG] = LE('MESG'), [MGEF] = LE('MGEF'), [MISC] = LE('MISC'), - [MOVT] = LE('MOVT'), [MSTT] = LE('MSTT'), [MUSC] = LE('MUSC'), - [MUST] = LE('MUST'), [NAVI] = LE('NAVI'), [NAVM] = LE('NAVM'), - [NOTE] = LE('NOTE'), [NPC_] = LE('NPC_'), [OTFT] = LE('OTFT'), - [PACK] = LE('PACK'), [PERK] = LE('PERK'), [PGRE] = LE('PGRE'), - [PHZD] = LE('PHZD'), [PROJ] = LE('PROJ'), [PWAT] = LE('PWAT'), - [QUST] = LE('QUST'), [RACE] = LE('RACE'), [REFR] = LE('REFR'), - [REGN] = LE('REGN'), [RELA] = LE('RELA'), [REVB] = LE('REVB'), - [RFCT] = LE('RFCT'), [RGDL] = LE('RGDL'), [SCEN] = LE('SCEN'), - [SCOL] = LE('SCOL'), [SCPT] = LE('SCPT'), [SCRL] = LE('SCRL'), - [SHOU] = LE('SHOU'), [SLGM] = LE('SLGM'), [SMBN] = LE('SMBN'), - [SMEN] = LE('SMEN'), [SMQN] = LE('SMQN'), [SNCT] = LE('SNCT'), - [SNDR] = LE('SNDR'), [SOPM] = LE('SOPM'), [SOUN] = LE('SOUN'), - [SPEL] = LE('SPEL'), [SPGD] = LE('SPGD'), [STAT] = LE('STAT'), - [TACT] = LE('TACT'), [TES4] = LE('TES4'), [TREE] = LE('TREE'), - [TXST] = LE('TXST'), [VTYP] = LE('VTYP'), [WATR] = LE('WATR'), - [WEAP] = LE('WEAP'), [WOOP] = LE('WOOP'), [WRLD] = LE('WRLD'), - [WTHR] = LE('WTHR'), + [AACT] = LE('AACT'),[ACHR] = LE('ACHR'),[ACTI] = LE('ACTI'), + [ADDN] = LE('ADDN'),[ALCH] = LE('ALCH'),[AMMO] = LE('AMMO'), + [ANIO] = LE('ANIO'),[APPA] = LE('APPA'),[ARMA] = LE('ARMA'), + [ARMO] = LE('ARMO'),[ARTO] = LE('ARTO'),[ASPC] = LE('ASPC'), + [ASTP] = LE('ASTP'),[AVIF] = LE('AVIF'),[BOOK] = LE('BOOK'), + [BPTD] = LE('BPTD'),[CAMS] = LE('CAMS'),[CELL] = LE('CELL'), + [CLAS] = LE('CLAS'),[CLDC] = LE('CLDC'),[CLFM] = LE('CLFM'), + [CLMT] = LE('CLMT'),[COBJ] = LE('COBJ'),[COLL] = LE('COLL'), + [CONT] = LE('CONT'),[CPTH] = LE('CPTH'),[CSTY] = LE('CSTY'), + [DEBR] = LE('DEBR'),[DIAL] = LE('DIAL'),[DLBR] = LE('DLBR'), + [DLVW] = LE('DLVW'),[DOBJ] = LE('DOBJ'),[DOOR] = LE('DOOR'), + [DUAL] = LE('DUAL'),[ECZN] = LE('ECZN'),[EFSH] = LE('EFSH'), + [ENCH] = LE('ENCH'),[EQUP] = LE('EQUP'),[EXPL] = LE('EXPL'), + [EYES] = LE('EYES'),[FACT] = LE('FACT'),[FLOR] = LE('FLOR'), + [FLST] = LE('FLST'),[FSTP] = LE('FSTP'),[FSTS] = LE('FSTS'), + [FURN] = LE('FURN'),[GLOB] = LE('GLOB'),[GMST] = LE('GMST'), + [GRAS] = LE('GRAS'),[GRUP] = LE('GRUP'),[HAIR] = LE('HAIR'), + [HAZD] = LE('HAZD'),[HDPT] = LE('HDPT'),[IDLE] = LE('IDLE'), + [IDLM] = LE('IDLM'),[IMAD] = LE('IMAD'),[IMGS] = LE('IMGS'), + [INFO] = LE('INFO'),[INGR] = LE('INGR'),[IPCT] = LE('IPCT'), + [IPDS] = LE('IPDS'),[KEYM] = LE('KEYM'),[KYWD] = LE('KYWD'), + [LAND] = LE('LAND'),[LCRT] = LE('LCRT'),[LCTN] = LE('LCTN'), + [LGTM] = LE('LGTM'),[LIGH] = LE('LIGH'),[LSCR] = LE('LSCR'), + [LTEX] = LE('LTEX'),[LVLI] = LE('LVLI'),[LVLN] = LE('LVLN'), + [LVSP] = LE('LVSP'),[MATO] = LE('MATO'),[MATT] = LE('MATT'), + [MESG] = LE('MESG'),[MGEF] = LE('MGEF'),[MISC] = LE('MISC'), + [MOVT] = LE('MOVT'),[MSTT] = LE('MSTT'),[MUSC] = LE('MUSC'), + [MUST] = LE('MUST'),[NAVI] = LE('NAVI'),[NAVM] = LE('NAVM'), + [NOTE] = LE('NOTE'),[NPC_] = LE('NPC_'),[OTFT] = LE('OTFT'), + [PACK] = LE('PACK'),[PERK] = LE('PERK'),[PGRE] = LE('PGRE'), + [PHZD] = LE('PHZD'),[PROJ] = LE('PROJ'),[PWAT] = LE('PWAT'), + [QUST] = LE('QUST'),[RACE] = LE('RACE'),[REFR] = LE('REFR'), + [REGN] = LE('REGN'),[RELA] = LE('RELA'),[REVB] = LE('REVB'), + [RFCT] = LE('RFCT'),[RGDL] = LE('RGDL'),[SCEN] = LE('SCEN'), + [SCOL] = LE('SCOL'),[SCPT] = LE('SCPT'),[SCRL] = LE('SCRL'), + [SHOU] = LE('SHOU'),[SLGM] = LE('SLGM'),[SMBN] = LE('SMBN'), + [SMEN] = LE('SMEN'),[SMQN] = LE('SMQN'),[SNCT] = LE('SNCT'), + [SNDR] = LE('SNDR'),[SOPM] = LE('SOPM'),[SOUN] = LE('SOUN'), + [SPEL] = LE('SPEL'),[SPGD] = LE('SPGD'),[STAT] = LE('STAT'), + [TACT] = LE('TACT'),[TES4] = LE('TES4'),[TREE] = LE('TREE'), + [TXST] = LE('TXST'),[VTYP] = LE('VTYP'),[WATR] = LE('WATR'), + [WEAP] = LE('WEAP'),[WOOP] = LE('WOOP'),[WRLD] = LE('WRLD'), + [WTHR] = LE('WTHR'), }; // Enums of perfect hash values enum record_type_hash { - RT_AACT = 496, RT_ACHR = 249, RT_ACTI = 293, RT_ADDN = 316, - RT_ALCH = 312, RT_AMMO = 157, RT_ANIO = 297, RT_APPA = 230, - RT_ARMA = 222, RT_ARMO = 218, RT_ARTO = 328, RT_ASPC = 252, - RT_ASTP = 384, RT_AVIF = 309, RT_BOOK = 318, RT_BPTD = 454, - RT_CAMS = 319, RT_CELL = 18, RT_CLAS = 16, RT_CLDC = 68, - RT_CLFM = 389, RT_CLMT = 497, RT_COBJ = 422, RT_COLL = 140, - RT_CONT = 169, RT_CPTH = 30, RT_CSTY = 193, RT_DEBR = 460, - RT_DIAL = 304, RT_DLBR = 340, RT_DLVW = 434, RT_DOBJ = 437, - RT_DOOR = 347, RT_DUAL = 246, RT_ECZN = 229, RT_EFSH = 509, - RT_ENCH = 194, RT_EQUP = 57, RT_EXPL = 153, RT_EYES = 181, - RT_FACT = 62, RT_FLOR = 137, RT_FLST = 199, RT_FSTP = 462, - RT_FSTS = 388, RT_FURN = 105, RT_GLOB = 376, RT_GMST = 125, - RT_GRAS = 49, RT_GRUP = 511, RT_HAIR = 481, RT_HAZD = 21, - RT_HDPT = 100, RT_IDLE = 204, RT_IDLM = 348, RT_IMAD = 390, - RT_IMGS = 187, RT_INFO = 82, RT_INGR = 463, RT_IPCT = 292, - RT_IPDS = 89, RT_KEYM = 54, RT_KYWD = 123, RT_LAND = 261, - RT_LCRT = 138, RT_LCTN = 172, RT_LGTM = 177, RT_LIGH = 13, - RT_LSCR = 288, RT_LTEX = 447, RT_LVLI = 235, RT_LVLN = 453, - RT_LVSP = 343, RT_MATO = 2, RT_MATT = 220, RT_MESG = 66, - RT_MGEF = 32, RT_MISC = 145, RT_MOVT = 378, RT_MSTT = 132, - RT_MUSC = 87, RT_MUST = 9, RT_NAVI = 50, RT_NAVM = 122, - RT_NOTE = 366, RT_NPC_ = 440, RT_OTFT = 365, RT_PACK = 441, - RT_PERK = 243, RT_PGRE = 210, RT_PHZD = 26, RT_PROJ = 120, - RT_PWAT = 397, RT_QUST = 71, RT_RACE = 108, RT_REFR = 449, - RT_REGN = 320, RT_RELA = 182, RT_REVB = 266, RT_RFCT = 311, - RT_RGDL = 19, RT_SCEN = 119, RT_SCOL = 276, RT_SCPT = 363, - RT_SCRL = 104, RT_SHOU = 115, RT_SLGM = 70, RT_SMBN = 413, - RT_SMEN = 240, RT_SMQN = 63, RT_SNCT = 117, RT_SNDR = 280, - RT_SOPM = 306, RT_SOUN = 165, RT_SPEL = 190, RT_SPGD = 443, - RT_STAT = 202, RT_TACT = 282, RT_TES4 = 474, RT_TREE = 27, - RT_TXST = 359, RT_VTYP = 335, RT_WATR = 84, RT_WEAP = 10, - RT_WOOP = 352, RT_WRLD = 38, RT_WTHR = 83, + RT_AACT = 496, RT_ACHR = 249, RT_ACTI = 293, RT_ADDN = 316, + RT_ALCH = 312, RT_AMMO = 157, RT_ANIO = 297, RT_APPA = 230, + RT_ARMA = 222, RT_ARMO = 218, RT_ARTO = 328, RT_ASPC = 252, + RT_ASTP = 384, RT_AVIF = 309, RT_BOOK = 318, RT_BPTD = 454, + RT_CAMS = 319, RT_CELL = 18, RT_CLAS = 16, RT_CLDC = 68, + RT_CLFM = 389, RT_CLMT = 497, RT_COBJ = 422, RT_COLL = 140, + RT_CONT = 169, RT_CPTH = 30, RT_CSTY = 193, RT_DEBR = 460, + RT_DIAL = 304, RT_DLBR = 340, RT_DLVW = 434, RT_DOBJ = 437, + RT_DOOR = 347, RT_DUAL = 246, RT_ECZN = 229, RT_EFSH = 509, + RT_ENCH = 194, RT_EQUP = 57, RT_EXPL = 153, RT_EYES = 181, + RT_FACT = 62, RT_FLOR = 137, RT_FLST = 199, RT_FSTP = 462, + RT_FSTS = 388, RT_FURN = 105, RT_GLOB = 376, RT_GMST = 125, + RT_GRAS = 49, RT_GRUP = 511, RT_HAIR = 481, RT_HAZD = 21, + RT_HDPT = 100, RT_IDLE = 204, RT_IDLM = 348, RT_IMAD = 390, + RT_IMGS = 187, RT_INFO = 82, RT_INGR = 463, RT_IPCT = 292, + RT_IPDS = 89, RT_KEYM = 54, RT_KYWD = 123, RT_LAND = 261, + RT_LCRT = 138, RT_LCTN = 172, RT_LGTM = 177, RT_LIGH = 13, + RT_LSCR = 288, RT_LTEX = 447, RT_LVLI = 235, RT_LVLN = 453, + RT_LVSP = 343, RT_MATO = 2, RT_MATT = 220, RT_MESG = 66, + RT_MGEF = 32, RT_MISC = 145, RT_MOVT = 378, RT_MSTT = 132, + RT_MUSC = 87, RT_MUST = 9, RT_NAVI = 50, RT_NAVM = 122, + RT_NOTE = 366, RT_NPC_ = 440, RT_OTFT = 365, RT_PACK = 441, + RT_PERK = 243, RT_PGRE = 210, RT_PHZD = 26, RT_PROJ = 120, + RT_PWAT = 397, RT_QUST = 71, RT_RACE = 108, RT_REFR = 449, + RT_REGN = 320, RT_RELA = 182, RT_REVB = 266, RT_RFCT = 311, + RT_RGDL = 19, RT_SCEN = 119, RT_SCOL = 276, RT_SCPT = 363, + RT_SCRL = 104, RT_SHOU = 115, RT_SLGM = 70, RT_SMBN = 413, + RT_SMEN = 240, RT_SMQN = 63, RT_SNCT = 117, RT_SNDR = 280, + RT_SOPM = 306, RT_SOUN = 165, RT_SPEL = 190, RT_SPGD = 443, + RT_STAT = 202, RT_TACT = 282, RT_TES4 = 474, RT_TREE = 27, + RT_TXST = 359, RT_VTYP = 335, RT_WATR = 84, RT_WEAP = 10, + RT_WOOP = 352, RT_WRLD = 38, RT_WTHR = 83, }; const uint16_t rt2rth[RT_SIZE] = { - [AACT] = RT_AACT,[ACHR] = RT_ACHR,[ACTI] = RT_ACTI, - [ADDN] = RT_ADDN,[ALCH] = RT_ALCH,[AMMO] = RT_AMMO, - [ANIO] = RT_ANIO,[APPA] = RT_APPA,[ARMA] = RT_ARMA, - [ARMO] = RT_ARMO,[ARTO] = RT_ARTO,[ASPC] = RT_ASPC, - [ASTP] = RT_ASTP,[AVIF] = RT_AVIF,[BOOK] = RT_BOOK, - [BPTD] = RT_BPTD,[CAMS] = RT_CAMS,[CELL] = RT_CELL, - [CLAS] = RT_CLAS,[CLDC] = RT_CLDC,[CLFM] = RT_CLFM, - [CLMT] = RT_CLMT,[COBJ] = RT_COBJ,[COLL] = RT_COLL, - [CONT] = RT_CONT,[CPTH] = RT_CPTH,[CSTY] = RT_CSTY, - [DEBR] = RT_DEBR,[DIAL] = RT_DIAL,[DLBR] = RT_DLBR, - [DLVW] = RT_DLVW,[DOBJ] = RT_DOBJ,[DOOR] = RT_DOOR, - [DUAL] = RT_DUAL,[ECZN] = RT_ECZN,[EFSH] = RT_EFSH, - [ENCH] = RT_ENCH,[EQUP] = RT_EQUP,[EXPL] = RT_EXPL, - [EYES] = RT_EYES,[FACT] = RT_FACT,[FLOR] = RT_FLOR, - [FLST] = RT_FLST,[FSTP] = RT_FSTP,[FSTS] = RT_FSTS, - [FURN] = RT_FURN,[GLOB] = RT_GLOB,[GMST] = RT_GMST, - [GRAS] = RT_GRAS,[GRUP] = RT_GRUP,[HAIR] = RT_HAIR, - [HAZD] = RT_HAZD,[HDPT] = RT_HDPT,[IDLE] = RT_IDLE, - [IDLM] = RT_IDLM,[IMAD] = RT_IMAD,[IMGS] = RT_IMGS, - [INFO] = RT_INFO,[INGR] = RT_INGR,[IPCT] = RT_IPCT, - [IPDS] = RT_IPDS,[KEYM] = RT_KEYM,[KYWD] = RT_KYWD, - [LAND] = RT_LAND,[LCRT] = RT_LCRT,[LCTN] = RT_LCTN, - [LGTM] = RT_LGTM,[LIGH] = RT_LIGH,[LSCR] = RT_LSCR, - [LTEX] = RT_LTEX,[LVLI] = RT_LVLI,[LVLN] = RT_LVLN, - [LVSP] = RT_LVSP,[MATO] = RT_MATO,[MATT] = RT_MATT, - [MESG] = RT_MESG,[MGEF] = RT_MGEF,[MISC] = RT_MISC, - [MOVT] = RT_MOVT,[MSTT] = RT_MSTT,[MUSC] = RT_MUSC, - [MUST] = RT_MUST,[NAVI] = RT_NAVI,[NAVM] = RT_NAVM, - [NOTE] = RT_NOTE,[NPC_] = RT_NPC_,[OTFT] = RT_OTFT, - [PACK] = RT_PACK,[PERK] = RT_PERK,[PGRE] = RT_PGRE, - [PHZD] = RT_PHZD,[PROJ] = RT_PROJ,[PWAT] = RT_PWAT, - [QUST] = RT_QUST,[RACE] = RT_RACE,[REFR] = RT_REFR, - [REGN] = RT_REGN,[RELA] = RT_RELA,[REVB] = RT_REVB, - [RFCT] = RT_RFCT,[RGDL] = RT_RGDL,[SCEN] = RT_SCEN, - [SCOL] = RT_SCOL,[SCPT] = RT_SCPT,[SCRL] = RT_SCRL, - [SHOU] = RT_SHOU,[SLGM] = RT_SLGM,[SMBN] = RT_SMBN, - [SMEN] = RT_SMEN,[SMQN] = RT_SMQN,[SNCT] = RT_SNCT, - [SNDR] = RT_SNDR,[SOPM] = RT_SOPM,[SOUN] = RT_SOUN, - [SPEL] = RT_SPEL,[SPGD] = RT_SPGD,[STAT] = RT_STAT, - [TACT] = RT_TACT,[TES4] = RT_TES4,[TREE] = RT_TREE, - [TXST] = RT_TXST,[VTYP] = RT_VTYP,[WATR] = RT_WATR, - [WEAP] = RT_WEAP,[WOOP] = RT_WOOP,[WRLD] = RT_WRLD, - [WTHR] = RT_WTHR, + [AACT] = RT_AACT,[ACHR] = RT_ACHR,[ACTI] = RT_ACTI, + [ADDN] = RT_ADDN,[ALCH] = RT_ALCH,[AMMO] = RT_AMMO, + [ANIO] = RT_ANIO,[APPA] = RT_APPA,[ARMA] = RT_ARMA, + [ARMO] = RT_ARMO,[ARTO] = RT_ARTO,[ASPC] = RT_ASPC, + [ASTP] = RT_ASTP,[AVIF] = RT_AVIF,[BOOK] = RT_BOOK, + [BPTD] = RT_BPTD,[CAMS] = RT_CAMS,[CELL] = RT_CELL, + [CLAS] = RT_CLAS,[CLDC] = RT_CLDC,[CLFM] = RT_CLFM, + [CLMT] = RT_CLMT,[COBJ] = RT_COBJ,[COLL] = RT_COLL, + [CONT] = RT_CONT,[CPTH] = RT_CPTH,[CSTY] = RT_CSTY, + [DEBR] = RT_DEBR,[DIAL] = RT_DIAL,[DLBR] = RT_DLBR, + [DLVW] = RT_DLVW,[DOBJ] = RT_DOBJ,[DOOR] = RT_DOOR, + [DUAL] = RT_DUAL,[ECZN] = RT_ECZN,[EFSH] = RT_EFSH, + [ENCH] = RT_ENCH,[EQUP] = RT_EQUP,[EXPL] = RT_EXPL, + [EYES] = RT_EYES,[FACT] = RT_FACT,[FLOR] = RT_FLOR, + [FLST] = RT_FLST,[FSTP] = RT_FSTP,[FSTS] = RT_FSTS, + [FURN] = RT_FURN,[GLOB] = RT_GLOB,[GMST] = RT_GMST, + [GRAS] = RT_GRAS,[GRUP] = RT_GRUP,[HAIR] = RT_HAIR, + [HAZD] = RT_HAZD,[HDPT] = RT_HDPT,[IDLE] = RT_IDLE, + [IDLM] = RT_IDLM,[IMAD] = RT_IMAD,[IMGS] = RT_IMGS, + [INFO] = RT_INFO,[INGR] = RT_INGR,[IPCT] = RT_IPCT, + [IPDS] = RT_IPDS,[KEYM] = RT_KEYM,[KYWD] = RT_KYWD, + [LAND] = RT_LAND,[LCRT] = RT_LCRT,[LCTN] = RT_LCTN, + [LGTM] = RT_LGTM,[LIGH] = RT_LIGH,[LSCR] = RT_LSCR, + [LTEX] = RT_LTEX,[LVLI] = RT_LVLI,[LVLN] = RT_LVLN, + [LVSP] = RT_LVSP,[MATO] = RT_MATO,[MATT] = RT_MATT, + [MESG] = RT_MESG,[MGEF] = RT_MGEF,[MISC] = RT_MISC, + [MOVT] = RT_MOVT,[MSTT] = RT_MSTT,[MUSC] = RT_MUSC, + [MUST] = RT_MUST,[NAVI] = RT_NAVI,[NAVM] = RT_NAVM, + [NOTE] = RT_NOTE,[NPC_] = RT_NPC_,[OTFT] = RT_OTFT, + [PACK] = RT_PACK,[PERK] = RT_PERK,[PGRE] = RT_PGRE, + [PHZD] = RT_PHZD,[PROJ] = RT_PROJ,[PWAT] = RT_PWAT, + [QUST] = RT_QUST,[RACE] = RT_RACE,[REFR] = RT_REFR, + [REGN] = RT_REGN,[RELA] = RT_RELA,[REVB] = RT_REVB, + [RFCT] = RT_RFCT,[RGDL] = RT_RGDL,[SCEN] = RT_SCEN, + [SCOL] = RT_SCOL,[SCPT] = RT_SCPT,[SCRL] = RT_SCRL, + [SHOU] = RT_SHOU,[SLGM] = RT_SLGM,[SMBN] = RT_SMBN, + [SMEN] = RT_SMEN,[SMQN] = RT_SMQN,[SNCT] = RT_SNCT, + [SNDR] = RT_SNDR,[SOPM] = RT_SOPM,[SOUN] = RT_SOUN, + [SPEL] = RT_SPEL,[SPGD] = RT_SPGD,[STAT] = RT_STAT, + [TACT] = RT_TACT,[TES4] = RT_TES4,[TREE] = RT_TREE, + [TXST] = RT_TXST,[VTYP] = RT_VTYP,[WATR] = RT_WATR, + [WEAP] = RT_WEAP,[WOOP] = RT_WOOP,[WRLD] = RT_WRLD, + [WTHR] = RT_WTHR, }; const uint8_t rth2rt[RT_HASH_SIZE] = { - [RT_AACT] = AACT,[RT_ACHR] = ACHR,[RT_ACTI] = ACTI, - [RT_ADDN] = ADDN,[RT_ALCH] = ALCH,[RT_AMMO] = AMMO, - [RT_ANIO] = ANIO,[RT_APPA] = APPA,[RT_ARMA] = ARMA, - [RT_ARMO] = ARMO,[RT_ARTO] = ARTO,[RT_ASPC] = ASPC, - [RT_ASTP] = ASTP,[RT_AVIF] = AVIF,[RT_BOOK] = BOOK, - [RT_BPTD] = BPTD,[RT_CAMS] = CAMS,[RT_CELL] = CELL, - [RT_CLAS] = CLAS,[RT_CLDC] = CLDC,[RT_CLFM] = CLFM, - [RT_CLMT] = CLMT,[RT_COBJ] = COBJ,[RT_COLL] = COLL, - [RT_CONT] = CONT,[RT_CPTH] = CPTH,[RT_CSTY] = CSTY, - [RT_DEBR] = DEBR,[RT_DIAL] = DIAL,[RT_DLBR] = DLBR, - [RT_DLVW] = DLVW,[RT_DOBJ] = DOBJ,[RT_DOOR] = DOOR, - [RT_DUAL] = DUAL,[RT_ECZN] = ECZN,[RT_EFSH] = EFSH, - [RT_ENCH] = ENCH,[RT_EQUP] = EQUP,[RT_EXPL] = EXPL, - [RT_EYES] = EYES,[RT_FACT] = FACT,[RT_FLOR] = FLOR, - [RT_FLST] = FLST,[RT_FSTP] = FSTP,[RT_FSTS] = FSTS, - [RT_FURN] = FURN,[RT_GLOB] = GLOB,[RT_GMST] = GMST, - [RT_GRAS] = GRAS,[RT_GRUP] = GRUP,[RT_HAIR] = HAIR, - [RT_HAZD] = HAZD,[RT_HDPT] = HDPT,[RT_IDLE] = IDLE, - [RT_IDLM] = IDLM,[RT_IMAD] = IMAD,[RT_IMGS] = IMGS, - [RT_INFO] = INFO,[RT_INGR] = INGR,[RT_IPCT] = IPCT, - [RT_IPDS] = IPDS,[RT_KEYM] = KEYM,[RT_KYWD] = KYWD, - [RT_LAND] = LAND,[RT_LCRT] = LCRT,[RT_LCTN] = LCTN, - [RT_LGTM] = LGTM,[RT_LIGH] = LIGH,[RT_LSCR] = LSCR, - [RT_LTEX] = LTEX,[RT_LVLI] = LVLI,[RT_LVLN] = LVLN, - [RT_LVSP] = LVSP,[RT_MATO] = MATO,[RT_MATT] = MATT, - [RT_MESG] = MESG,[RT_MGEF] = MGEF,[RT_MISC] = MISC, - [RT_MOVT] = MOVT,[RT_MSTT] = MSTT,[RT_MUSC] = MUSC, - [RT_MUST] = MUST,[RT_NAVI] = NAVI,[RT_NAVM] = NAVM, - [RT_NOTE] = NOTE,[RT_NPC_] = NPC_,[RT_OTFT] = OTFT, - [RT_PACK] = PACK,[RT_PERK] = PERK,[RT_PGRE] = PGRE, - [RT_PHZD] = PHZD,[RT_PROJ] = PROJ,[RT_PWAT] = PWAT, - [RT_QUST] = QUST,[RT_RACE] = RACE,[RT_REFR] = REFR, - [RT_REGN] = REGN,[RT_RELA] = RELA,[RT_REVB] = REVB, - [RT_RFCT] = RFCT,[RT_RGDL] = RGDL,[RT_SCEN] = SCEN, - [RT_SCOL] = SCOL,[RT_SCPT] = SCPT,[RT_SCRL] = SCRL, - [RT_SHOU] = SHOU,[RT_SLGM] = SLGM,[RT_SMBN] = SMBN, - [RT_SMEN] = SMEN,[RT_SMQN] = SMQN,[RT_SNCT] = SNCT, - [RT_SNDR] = SNDR,[RT_SOPM] = SOPM,[RT_SOUN] = SOUN, - [RT_SPEL] = SPEL,[RT_SPGD] = SPGD,[RT_STAT] = STAT, - [RT_TACT] = TACT,[RT_TES4] = TES4,[RT_TREE] = TREE, - [RT_TXST] = TXST,[RT_VTYP] = VTYP,[RT_WATR] = WATR, - [RT_WEAP] = WEAP,[RT_WOOP] = WOOP,[RT_WRLD] = WRLD, - [RT_WTHR] = WTHR, + [RT_AACT] = AACT,[RT_ACHR] = ACHR,[RT_ACTI] = ACTI, + [RT_ADDN] = ADDN,[RT_ALCH] = ALCH,[RT_AMMO] = AMMO, + [RT_ANIO] = ANIO,[RT_APPA] = APPA,[RT_ARMA] = ARMA, + [RT_ARMO] = ARMO,[RT_ARTO] = ARTO,[RT_ASPC] = ASPC, + [RT_ASTP] = ASTP,[RT_AVIF] = AVIF,[RT_BOOK] = BOOK, + [RT_BPTD] = BPTD,[RT_CAMS] = CAMS,[RT_CELL] = CELL, + [RT_CLAS] = CLAS,[RT_CLDC] = CLDC,[RT_CLFM] = CLFM, + [RT_CLMT] = CLMT,[RT_COBJ] = COBJ,[RT_COLL] = COLL, + [RT_CONT] = CONT,[RT_CPTH] = CPTH,[RT_CSTY] = CSTY, + [RT_DEBR] = DEBR,[RT_DIAL] = DIAL,[RT_DLBR] = DLBR, + [RT_DLVW] = DLVW,[RT_DOBJ] = DOBJ,[RT_DOOR] = DOOR, + [RT_DUAL] = DUAL,[RT_ECZN] = ECZN,[RT_EFSH] = EFSH, + [RT_ENCH] = ENCH,[RT_EQUP] = EQUP,[RT_EXPL] = EXPL, + [RT_EYES] = EYES,[RT_FACT] = FACT,[RT_FLOR] = FLOR, + [RT_FLST] = FLST,[RT_FSTP] = FSTP,[RT_FSTS] = FSTS, + [RT_FURN] = FURN,[RT_GLOB] = GLOB,[RT_GMST] = GMST, + [RT_GRAS] = GRAS,[RT_GRUP] = GRUP,[RT_HAIR] = HAIR, + [RT_HAZD] = HAZD,[RT_HDPT] = HDPT,[RT_IDLE] = IDLE, + [RT_IDLM] = IDLM,[RT_IMAD] = IMAD,[RT_IMGS] = IMGS, + [RT_INFO] = INFO,[RT_INGR] = INGR,[RT_IPCT] = IPCT, + [RT_IPDS] = IPDS,[RT_KEYM] = KEYM,[RT_KYWD] = KYWD, + [RT_LAND] = LAND,[RT_LCRT] = LCRT,[RT_LCTN] = LCTN, + [RT_LGTM] = LGTM,[RT_LIGH] = LIGH,[RT_LSCR] = LSCR, + [RT_LTEX] = LTEX,[RT_LVLI] = LVLI,[RT_LVLN] = LVLN, + [RT_LVSP] = LVSP,[RT_MATO] = MATO,[RT_MATT] = MATT, + [RT_MESG] = MESG,[RT_MGEF] = MGEF,[RT_MISC] = MISC, + [RT_MOVT] = MOVT,[RT_MSTT] = MSTT,[RT_MUSC] = MUSC, + [RT_MUST] = MUST,[RT_NAVI] = NAVI,[RT_NAVM] = NAVM, + [RT_NOTE] = NOTE,[RT_NPC_] = NPC_,[RT_OTFT] = OTFT, + [RT_PACK] = PACK,[RT_PERK] = PERK,[RT_PGRE] = PGRE, + [RT_PHZD] = PHZD,[RT_PROJ] = PROJ,[RT_PWAT] = PWAT, + [RT_QUST] = QUST,[RT_RACE] = RACE,[RT_REFR] = REFR, + [RT_REGN] = REGN,[RT_RELA] = RELA,[RT_REVB] = REVB, + [RT_RFCT] = RFCT,[RT_RGDL] = RGDL,[RT_SCEN] = SCEN, + [RT_SCOL] = SCOL,[RT_SCPT] = SCPT,[RT_SCRL] = SCRL, + [RT_SHOU] = SHOU,[RT_SLGM] = SLGM,[RT_SMBN] = SMBN, + [RT_SMEN] = SMEN,[RT_SMQN] = SMQN,[RT_SNCT] = SNCT, + [RT_SNDR] = SNDR,[RT_SOPM] = SOPM,[RT_SOUN] = SOUN, + [RT_SPEL] = SPEL,[RT_SPGD] = SPGD,[RT_STAT] = STAT, + [RT_TACT] = TACT,[RT_TES4] = TES4,[RT_TREE] = TREE, + [RT_TXST] = TXST,[RT_VTYP] = VTYP,[RT_WATR] = WATR, + [RT_WEAP] = WEAP,[RT_WOOP] = WOOP,[RT_WRLD] = WRLD, + [RT_WTHR] = WTHR, }; const char *const group_type_strings[GTS_SIZE] = { - "Top Type", - "World Children", - "Interior Cell Block", - "Interior Cell Sub-Block", - "Exterior Cell", - "Exterior Cell Sub-Block", - "Cell Children", - "Topic Children", - "Cell Persistent Children", - "Cell Temporary Children", + "Top Type", + "World Children", + "Interior Cell Block", + "Interior Cell Sub-Block", + "Exterior Cell", + "Exterior Cell Sub-Block", + "Cell Children", + "Topic Children", + "Cell Persistent Children", + "Cell Temporary Children", }; // Non-REFR flags rfs_inner _achr = { - [9] = "Starts Dead", - [10] = "Persistent", - [11] = "Initially Disabled", - [25] = "No AI Acquire", - [29] = "Don't Havok Settle", - [30] = "ACHR Unknown 30", + [9] = "Starts Dead", + [10] = "Persistent", + [11] = "Initially Disabled", + [25] = "No AI Acquire", + [29] = "Don't Havok Settle", + [30] = "ACHR Unknown 30", }; rfs_inner _acti = { - [6] = "Has Tree LOD", - [8] = "Must Update Anims", - [9] = "Hidden From Local Map", - [15] = "Has Distant LOD", - [16] = "Random Anim Start", - [17] = "Dangerous", - [20] = "Ignore Object Interaction", - [23] = "Is Marker", - [25] = "Obstacle", - [26] = "NavMesh Generation - Filter", - [27] = "NavMesh Generation - Bounding Box", - [29] = "Child Can Use", - [30] = "NavMesh Generation - Ground", + [6] = "Has Tree LOD", + [8] = "Must Update Anims", + [9] = "Hidden From Local Map", + [15] = "Has Distant LOD", + [16] = "Random Anim Start", + [17] = "Dangerous", + [20] = "Ignore Object Interaction", + [23] = "Is Marker", + [25] = "Obstacle", + [26] = "NavMesh Generation - Filter", + [27] = "NavMesh Generation - Bounding Box", + [29] = "Child Can Use", + [30] = "NavMesh Generation - Ground", }; rfs_inner _tact = { - [9] = "Hidden From Local Map", - [16] = "Random Anim Start", - [17] = "Radio Station", + [9] = "Hidden From Local Map", + [16] = "Random Anim Start", + [17] = "Radio Station", }; rfs_inner _alch = { - [29] = "Medicine", + [29] = "Medicine", }; rfs_inner _ammo = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _anio = { - [9] = "ANIO Unknown 9", + [9] = "ANIO Unknown 9", }; rfs_inner _armo = { - [2] = "Non-Playable", - [6] = "Shield", - [10] = "ARMO Unknown 10", - [15] = "ARMO Unknown 15", + [2] = "Non-Playable", + [6] = "Shield", + [10] = "ARMO Unknown 10", + [15] = "ARMO Unknown 15", }; #define REFERENCE_RECORD { \ @@ -293,233 +293,233 @@ rfs_inner _pmis = REFERENCE_RECORD; #undef REFERENCE_RECORD rfs_inner _cell = { - [10] = "Persistent", - [17] = "Off Limits", - [18] = "Compressed", - [19] = "Can't Wait", + [10] = "Persistent", + [17] = "Off Limits", + [18] = "Compressed", + [19] = "Can't Wait", }; rfs_inner _cont = { - [15] = "Has Distant LOD", - [16] = "Random Anim Start", - [25] = "Obstacle", - [26] = "NavMesh Generation - Filter", - [27] = "NavMesh Generation - Bounding Box", - [30] = "NavMesh Generation - Ground", + [15] = "Has Distant LOD", + [16] = "Random Anim Start", + [25] = "Obstacle", + [26] = "NavMesh Generation - Filter", + [27] = "NavMesh Generation - Bounding Box", + [30] = "NavMesh Generation - Ground", }; rfs_inner _csty = { - [19] = "Allow Dual Wielding", + [19] = "Allow Dual Wielding", }; rfs_inner _door = { - [15] = "Has Distant LOD", - [16] = "Random Anim Start", - [23] = "Is Marker", + [15] = "Has Distant LOD", + [16] = "Random Anim Start", + [23] = "Is Marker", }; rfs_inner _eyes = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _furn = { - [7] = "Is Perch", - [16] = "Has Distant LOD", - [23] = "Is Marker", - [28] = "Must Exit To Talk", - [29] = "Child Can Use", + [7] = "Is Perch", + [16] = "Has Distant LOD", + [23] = "Is Marker", + [28] = "Must Exit To Talk", + [29] = "Child Can Use", }; rfs_inner _glob = { - [6] = "Constant", + [6] = "Constant", }; rfs_inner _hdpt = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _mstt = { - [8] = "Must Update Anims", - [9] = "Hidden From Local Map", - [15] = "Has Distant LOD", - [16] = "Random Anim Start", - [19] = "Has Currents", - [25] = "Obstacle", - [26] = "NavMesh Generation - Filter", - [27] = "NavMesh Generation - Bounding Box", - [30] = "NavMesh Generation - Ground", + [8] = "Must Update Anims", + [9] = "Hidden From Local Map", + [15] = "Has Distant LOD", + [16] = "Random Anim Start", + [19] = "Has Currents", + [25] = "Obstacle", + [26] = "NavMesh Generation - Filter", + [27] = "NavMesh Generation - Bounding Box", + [30] = "NavMesh Generation - Ground", }; rfs_inner _idlm = { - [29] = "Child Can Use", + [29] = "Child Can Use", }; rfs_inner _slgm = { - [17] = "Can Hold NPC Soul", + [17] = "Can Hold NPC Soul", }; rfs_inner _navm = { - [18] = "Compressed", - [26] = "AutoGen", - [31] = "NavmeshGenCell", + [18] = "Compressed", + [26] = "AutoGen", + [31] = "NavmeshGenCell", }; rfs_inner _perk = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _shou = { - [7] = "Treat Spells As Powers", + [7] = "Treat Spells As Powers", }; rfs_inner _rela = { - [6] = "Secret", + [6] = "Secret", }; rfs_inner _clfm = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _info = { - [13] = "Actor Changed", + [13] = "Actor Changed", }; rfs_inner _keym = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _land = { - [18] = "Compressed", + [18] = "Compressed", }; rfs_inner _ligh = { - [16] = "Random Anim Start", - [17] = "Portal-strict", - [25] = "Obstacle", + [16] = "Random Anim Start", + [17] = "Portal-strict", + [25] = "Obstacle", }; rfs_inner _lscr = { - [10] = "Displays In Main Menu", + [10] = "Displays In Main Menu", }; rfs_inner _misc = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _npc_ = { - [10] = "NPC_ Unknown 10", - [18] = "Compressed", - [19] = "NPC_ Unknown 19", - [29] = "Bleedout Override", + [10] = "NPC_ Unknown 10", + [18] = "Compressed", + [19] = "NPC_ Unknown 19", + [29] = "Bleedout Override", }; rfs_inner _race = { - [19] = "Critter (?)", + [19] = "Critter (?)", }; // these are generic refr flags for any reference type not handled by the refr // specific flag lut rfs_inner _refr = { - [10] = "Persistent", - [11] = "Initially Disabled", - [16] = "Is Full LOD", - [26] = "Filter (Collision Geometry)", - [27] = "Bounding Box (Collision Geometry)", - [30] = "Ground", - [31] = "Multibound", + [10] = "Persistent", + [11] = "Initially Disabled", + [16] = "Is Full LOD", + [26] = "Filter (Collision Geometry)", + [27] = "Bounding Box (Collision Geometry)", + [30] = "Ground", + [31] = "Multibound", }; rfs_inner _regn = { - [6] = "Border Region", + [6] = "Border Region", }; rfs_inner _stat = { - [2] = "Never Fades", - [5] = "Deleted", - [6] = "Has Tree LOD", - [7] = "Add-On LOD Object", - [9] = "Hidden From Local Map", - [11] = "STAT Unknown 11", - [15] = "Has Distant LOD", - [16] = "STAT Unknown 16", - [17] = "Uses HD LOD Texture", - [19] = "Has Currents", - [23] = "Is Marker", - [25] = "Obstacle", - [26] = "NavMesh Generation - Filter", - [27] = "NavMesh Generation - Bounding Box", - [28] = "Show In World Map", - [30] = "NavMesh Generation - Ground", + [2] = "Never Fades", + [5] = "Deleted", + [6] = "Has Tree LOD", + [7] = "Add-On LOD Object", + [9] = "Hidden From Local Map", + [11] = "STAT Unknown 11", + [15] = "Has Distant LOD", + [16] = "STAT Unknown 16", + [17] = "Uses HD LOD Texture", + [19] = "Has Currents", + [23] = "Is Marker", + [25] = "Obstacle", + [26] = "NavMesh Generation - Filter", + [27] = "NavMesh Generation - Bounding Box", + [28] = "Show In World Map", + [30] = "NavMesh Generation - Ground", }; rfs_inner _tes4 = { - [0] = "ESM", - [1] = "Altered", - [2] = "Checked", - [3] = "Active", - [4] = "Optimized File", - [5] = "Temp ID Owner", - [7] = "Localized", - [8] = "Precalc Data Only", - [9] = "ESL", + [0] = "ESM", + [1] = "Altered", + [2] = "Checked", + [3] = "Active", + [4] = "Optimized File", + [5] = "Temp ID Owner", + [7] = "Localized", + [8] = "Precalc Data Only", + [9] = "ESL", }; rfs_inner _tree = { - [15] = "Has Distant LOD", + [15] = "Has Distant LOD", }; rfs_inner _weap = { - [2] = "Non-Playable", + [2] = "Non-Playable", }; rfs_inner _wrld = { - [19] = "Can't Wait", + [19] = "Can't Wait", }; rfs_inner *const rfs[RT_HASH_SIZE] = { - [RT_AACT] = CP( NULL), [RT_ACHR] = CP(_achr), [RT_ACTI] = CP(_acti), - [RT_ADDN] = CP( NULL), [RT_ALCH] = CP(_alch), [RT_AMMO] = CP(_ammo), - [RT_ANIO] = CP(_anio), [RT_APPA] = CP( NULL), [RT_ARMA] = CP( NULL), - [RT_ARMO] = CP(_armo), [RT_ARTO] = CP( NULL), [RT_ASPC] = CP( NULL), - [RT_ASTP] = CP( NULL), [RT_AVIF] = CP( NULL), [RT_BOOK] = CP( NULL), - [RT_BPTD] = CP( NULL), [RT_CAMS] = CP( NULL), [RT_CELL] = CP(_cell), - [RT_CLAS] = CP( NULL), [RT_CLDC] = CP( NULL), [RT_CLFM] = CP(_clfm), - [RT_CLMT] = CP( NULL), [RT_COBJ] = CP( NULL), [RT_COLL] = CP( NULL), - [RT_CONT] = CP(_cont), [RT_CPTH] = CP( NULL), [RT_CSTY] = CP(_csty), - [RT_DEBR] = CP( NULL), [RT_DIAL] = CP( NULL), [RT_DLBR] = CP( NULL), - [RT_DLVW] = CP( NULL), [RT_DOBJ] = CP( NULL), [RT_DOOR] = CP(_door), - [RT_DUAL] = CP( NULL), [RT_ECZN] = CP( NULL), [RT_EFSH] = CP( NULL), - [RT_ENCH] = CP( NULL), [RT_EQUP] = CP( NULL), [RT_EXPL] = CP( NULL), - [RT_EYES] = CP(_eyes), [RT_FACT] = CP( NULL), [RT_FLOR] = CP( NULL), - [RT_FLST] = CP( NULL), [RT_FSTP] = CP( NULL), [RT_FSTS] = CP( NULL), - [RT_FURN] = CP(_furn), [RT_GLOB] = CP(_glob), [RT_GMST] = CP( NULL), - [RT_GRAS] = CP( NULL), [RT_GRUP] = CP( NULL), [RT_HAIR] = CP( NULL), - [RT_HAZD] = CP( NULL), [RT_HDPT] = CP(_hdpt), [RT_IDLE] = CP( NULL), - [RT_IDLM] = CP(_idlm), [RT_IMAD] = CP( NULL), [RT_IMGS] = CP( NULL), - [RT_INFO] = CP(_info), [RT_INGR] = CP( NULL), [RT_IPCT] = CP( NULL), - [RT_IPDS] = CP( NULL), [RT_KEYM] = CP(_keym), [RT_KYWD] = CP( NULL), - [RT_LAND] = CP(_land), [RT_LCRT] = CP( NULL), [RT_LCTN] = CP( NULL), - [RT_LGTM] = CP( NULL), [RT_LIGH] = CP(_ligh), [RT_LSCR] = CP(_lscr), - [RT_LTEX] = CP( NULL), [RT_LVLI] = CP( NULL), [RT_LVLN] = CP( NULL), - [RT_LVSP] = CP( NULL), [RT_MATO] = CP( NULL), [RT_MATT] = CP( NULL), - [RT_MESG] = CP( NULL), [RT_MGEF] = CP( NULL), [RT_MISC] = CP(_misc), - [RT_MOVT] = CP( NULL), [RT_MSTT] = CP(_mstt), [RT_MUSC] = CP( NULL), - [RT_MUST] = CP( NULL), [RT_NAVI] = CP( NULL), [RT_NAVM] = CP(_navm), - [RT_NOTE] = CP( NULL), [RT_NPC_] = CP(_npc_), [RT_OTFT] = CP( NULL), - [RT_PACK] = CP( NULL), [RT_PERK] = CP(_perk), [RT_PGRE] = CP(_pgre), - [RT_PHZD] = CP(_phzd), [RT_PROJ] = CP( NULL), [RT_PWAT] = CP( NULL), - [RT_QUST] = CP( NULL), [RT_RACE] = CP(_race), [RT_REFR] = CP(_refr), - [RT_REGN] = CP(_regn), [RT_RELA] = CP(_rela), [RT_REVB] = CP( NULL), - [RT_RFCT] = CP( NULL), [RT_RGDL] = CP( NULL), [RT_SCEN] = CP( NULL), - [RT_SCOL] = CP( NULL), [RT_SCPT] = CP( NULL), [RT_SCRL] = CP( NULL), - [RT_SHOU] = CP(_shou), [RT_SLGM] = CP(_slgm), [RT_SMBN] = CP( NULL), - [RT_SMEN] = CP( NULL), [RT_SMQN] = CP( NULL), [RT_SNCT] = CP( NULL), - [RT_SNDR] = CP( NULL), [RT_SOPM] = CP( NULL), [RT_SOUN] = CP( NULL), - [RT_SPEL] = CP( NULL), [RT_SPGD] = CP( NULL), [RT_STAT] = CP(_stat), - [RT_TACT] = CP(_tact), [RT_TES4] = CP(_tes4), [RT_TREE] = CP(_tree), - [RT_TXST] = CP( NULL), [RT_VTYP] = CP( NULL), [RT_WATR] = CP( NULL), - [RT_WEAP] = CP(_weap), [RT_WOOP] = CP( NULL), [RT_WRLD] = CP(_wrld), - [RT_WTHR] = CP( NULL), + [RT_AACT] = CP(NULL ),[RT_ACHR] = CP(_achr),[RT_ACTI] = CP(_acti), + [RT_ADDN] = CP(NULL ),[RT_ALCH] = CP(_alch),[RT_AMMO] = CP(_ammo), + [RT_ANIO] = CP(_anio),[RT_APPA] = CP(NULL ),[RT_ARMA] = CP(NULL ), + [RT_ARMO] = CP(_armo),[RT_ARTO] = CP(NULL ),[RT_ASPC] = CP(NULL ), + [RT_ASTP] = CP(NULL ),[RT_AVIF] = CP(NULL ),[RT_BOOK] = CP(NULL ), + [RT_BPTD] = CP(NULL ),[RT_CAMS] = CP(NULL ),[RT_CELL] = CP(_cell), + [RT_CLAS] = CP(NULL ),[RT_CLDC] = CP(NULL ),[RT_CLFM] = CP(_clfm), + [RT_CLMT] = CP(NULL ),[RT_COBJ] = CP(NULL ),[RT_COLL] = CP(NULL ), + [RT_CONT] = CP(_cont),[RT_CPTH] = CP(NULL ),[RT_CSTY] = CP(_csty), + [RT_DEBR] = CP(NULL ),[RT_DIAL] = CP(NULL ),[RT_DLBR] = CP(NULL ), + [RT_DLVW] = CP(NULL ),[RT_DOBJ] = CP(NULL ),[RT_DOOR] = CP(_door), + [RT_DUAL] = CP(NULL ),[RT_ECZN] = CP(NULL ),[RT_EFSH] = CP(NULL ), + [RT_ENCH] = CP(NULL ),[RT_EQUP] = CP(NULL ),[RT_EXPL] = CP(NULL ), + [RT_EYES] = CP(_eyes),[RT_FACT] = CP(NULL ),[RT_FLOR] = CP(NULL ), + [RT_FLST] = CP(NULL ),[RT_FSTP] = CP(NULL ),[RT_FSTS] = CP(NULL ), + [RT_FURN] = CP(_furn),[RT_GLOB] = CP(_glob),[RT_GMST] = CP(NULL ), + [RT_GRAS] = CP(NULL ),[RT_GRUP] = CP(NULL ),[RT_HAIR] = CP(NULL ), + [RT_HAZD] = CP(NULL ),[RT_HDPT] = CP(_hdpt),[RT_IDLE] = CP(NULL ), + [RT_IDLM] = CP(_idlm),[RT_IMAD] = CP(NULL ),[RT_IMGS] = CP(NULL ), + [RT_INFO] = CP(_info),[RT_INGR] = CP(NULL ),[RT_IPCT] = CP(NULL ), + [RT_IPDS] = CP(NULL ),[RT_KEYM] = CP(_keym),[RT_KYWD] = CP(NULL ), + [RT_LAND] = CP(_land),[RT_LCRT] = CP(NULL ),[RT_LCTN] = CP(NULL ), + [RT_LGTM] = CP(NULL ),[RT_LIGH] = CP(_ligh),[RT_LSCR] = CP(_lscr), + [RT_LTEX] = CP(NULL ),[RT_LVLI] = CP(NULL ),[RT_LVLN] = CP(NULL ), + [RT_LVSP] = CP(NULL ),[RT_MATO] = CP(NULL ),[RT_MATT] = CP(NULL ), + [RT_MESG] = CP(NULL ),[RT_MGEF] = CP(NULL ),[RT_MISC] = CP(_misc), + [RT_MOVT] = CP(NULL ),[RT_MSTT] = CP(_mstt),[RT_MUSC] = CP(NULL ), + [RT_MUST] = CP(NULL ),[RT_NAVI] = CP(NULL ),[RT_NAVM] = CP(_navm), + [RT_NOTE] = CP(NULL ),[RT_NPC_] = CP(_npc_),[RT_OTFT] = CP(NULL ), + [RT_PACK] = CP(NULL ),[RT_PERK] = CP(_perk),[RT_PGRE] = CP(_pgre), + [RT_PHZD] = CP(_phzd),[RT_PROJ] = CP(NULL ),[RT_PWAT] = CP(NULL ), + [RT_QUST] = CP(NULL ),[RT_RACE] = CP(_race),[RT_REFR] = CP(_refr), + [RT_REGN] = CP(_regn),[RT_RELA] = CP(_rela),[RT_REVB] = CP(NULL ), + [RT_RFCT] = CP(NULL ),[RT_RGDL] = CP(NULL ),[RT_SCEN] = CP(NULL ), + [RT_SCOL] = CP(NULL ),[RT_SCPT] = CP(NULL ),[RT_SCRL] = CP(NULL ), + [RT_SHOU] = CP(_shou),[RT_SLGM] = CP(_slgm),[RT_SMBN] = CP(NULL ), + [RT_SMEN] = CP(NULL ),[RT_SMQN] = CP(NULL ),[RT_SNCT] = CP(NULL ), + [RT_SNDR] = CP(NULL ),[RT_SOPM] = CP(NULL ),[RT_SOUN] = CP(NULL ), + [RT_SPEL] = CP(NULL ),[RT_SPGD] = CP(NULL ),[RT_STAT] = CP(_stat), + [RT_TACT] = CP(_tact),[RT_TES4] = CP(_tes4),[RT_TREE] = CP(_tree), + [RT_TXST] = CP(NULL ),[RT_VTYP] = CP(NULL ),[RT_WATR] = CP(NULL ), + [RT_WEAP] = CP(_weap),[RT_WOOP] = CP(NULL ),[RT_WRLD] = CP(_wrld), + [RT_WTHR] = CP(NULL ), }; // REFR flags depend on what its NAME field references @@ -540,73 +540,73 @@ rfs_inner *const rfs[RT_HASH_SIZE] = { rfs_inner _refr_acti = REFR_GROUP1; rfs_inner _refr_stat = REFR_GROUP1; -rfs_inner _refr_tree = REFR_GROUP1; -rfs_inner _refr_flor = REFR_GROUP1; +rfs_inner _refr_tree = REFR_GROUP1; +rfs_inner _refr_flor = REFR_GROUP1; #undef REFR_GROUP1 rfs_inner _refr_cont = { - [10] = "Persistent", - [11] = "Initially Disabled", - [16] = "Is Full LOD", - [25] = "No AI Acquire", - [26] = "Filter (Collision Geometry)", - [27] = "Bounding Box (Collision Geometry)", - [28] = "Reflected By Auto Water", - [29] = "Don't Havok Settle", - [30] = "Ground", - [31] = "Multibound", + [10] = "Persistent", + [11] = "Initially Disabled", + [16] = "Is Full LOD", + [25] = "No AI Acquire", + [26] = "Filter (Collision Geometry)", + [27] = "Bounding Box (Collision Geometry)", + [28] = "Reflected By Auto Water", + [29] = "Don't Havok Settle", + [30] = "Ground", + [31] = "Multibound", }; rfs_inner _refr_door = { - [6] = "Hidden From Local Map", - [8] = "Inaccessible", - [10] = "Persistent", - [11] = "Initially Disabled", - [16] = "Is Full LOD", - [26] = "Filter (Collision Geometry)", - [27] = "Bounding Box (Collision Geometry)", - [28] = "Reflected By Auto Water", - [29] = "Don't Havok Settle", - [30] = "No Respawn", - [31] = "Multibound", + [6] = "Hidden From Local Map", + [8] = "Inaccessible", + [10] = "Persistent", + [11] = "Initially Disabled", + [16] = "Is Full LOD", + [26] = "Filter (Collision Geometry)", + [27] = "Bounding Box (Collision Geometry)", + [28] = "Reflected By Auto Water", + [29] = "Don't Havok Settle", + [30] = "No Respawn", + [31] = "Multibound", }; rfs_inner _refr_ligh = { - [8] = "Doesn't Light Water", - [9] = "Casts Shadows", - [10] = "Persistent", - [11] = "Initially Disabled", - [16] = "Never Fades", - [17] = "Doesn't Light Landscape", - [25] = "No AI Acquire", - [28] = "Reflected By Auto Water", - [29] = "Don't Havok Settle", - [30] = "No Respawn", - [31] = "Multibound", + [8] = "Doesn't Light Water", + [9] = "Casts Shadows", + [10] = "Persistent", + [11] = "Initially Disabled", + [16] = "Never Fades", + [17] = "Doesn't Light Landscape", + [25] = "No AI Acquire", + [28] = "Reflected By Auto Water", + [29] = "Don't Havok Settle", + [30] = "No Respawn", + [31] = "Multibound", }; rfs_inner _refr_mstt = { - [9] = "Motion Blur", - [10] = "Persistent", - [11] = "Initially Disabled", - [16] = "Is Full LOD", - [26] = "Filter (Collision Geometry)", - [27] = "Bounding Box (Collision Geometry)", - [28] = "Reflected By Auto Water", - [29] = "Don't Havok Settle", - [30] = "No Respawn", - [31] = "Multibound", + [9] = "Motion Blur", + [10] = "Persistent", + [11] = "Initially Disabled", + [16] = "Is Full LOD", + [26] = "Filter (Collision Geometry)", + [27] = "Bounding Box (Collision Geometry)", + [28] = "Reflected By Auto Water", + [29] = "Don't Havok Settle", + [30] = "No Respawn", + [31] = "Multibound", }; rfs_inner _refr_addn = { - [10] = "Persistent", - [11] = "Initially Disabled", - [16] = "Is Full LOD", - [28] = "Reflected By Auto Water", - [29] = "Don't Havok Settle", - [30] = "No Respawn", - [31] = "Multibound", + [10] = "Persistent", + [11] = "Initially Disabled", + [16] = "Is Full LOD", + [28] = "Reflected By Auto Water", + [29] = "Don't Havok Settle", + [30] = "No Respawn", + [31] = "Multibound", }; #define REFR_GROUP2 { \ @@ -631,48 +631,48 @@ rfs_inner _refr_slgm = REFR_GROUP2; rfs_inner _refr_weap = REFR_GROUP2; rfs_inner *const rfs_refr[RT_HASH_SIZE] = { - [RT_AACT] = CP(NULL ), [RT_ACHR] = CP(NULL ), [RT_ACTI] = CP(_refr_acti), - [RT_ADDN] = CP(_refr_addn), [RT_ALCH] = CP(_refr_alch), [RT_AMMO] = CP(_refr_ammo), - [RT_ANIO] = CP(NULL ), [RT_APPA] = CP(NULL ), [RT_ARMA] = CP(NULL ), - [RT_ARMO] = CP(_refr_armo), [RT_ARTO] = CP(NULL ), [RT_ASPC] = CP(NULL ), - [RT_ASTP] = CP(NULL ), [RT_AVIF] = CP(NULL ), [RT_BOOK] = CP(NULL ), - [RT_BPTD] = CP(NULL ), [RT_CAMS] = CP(NULL ), [RT_CELL] = CP(NULL ), - [RT_CLAS] = CP(NULL ), [RT_CLDC] = CP(NULL ), [RT_CLFM] = CP(NULL ), - [RT_CLMT] = CP(NULL ), [RT_COBJ] = CP(NULL ), [RT_COLL] = CP(NULL ), - [RT_CONT] = CP(_refr_cont), [RT_CPTH] = CP(NULL ), [RT_CSTY] = CP(NULL ), - [RT_DEBR] = CP(NULL ), [RT_DIAL] = CP(NULL ), [RT_DLBR] = CP(NULL ), - [RT_DLVW] = CP(NULL ), [RT_DOBJ] = CP(NULL ), [RT_DOOR] = CP(_refr_door), - [RT_DUAL] = CP(NULL ), [RT_ECZN] = CP(NULL ), [RT_EFSH] = CP(NULL ), - [RT_ENCH] = CP(NULL ), [RT_EQUP] = CP(NULL ), [RT_EXPL] = CP(NULL ), - [RT_EYES] = CP(NULL ), [RT_FACT] = CP(NULL ), [RT_FLOR] = CP(_refr_flor), - [RT_FLST] = CP(NULL ), [RT_FSTP] = CP(NULL ), [RT_FSTS] = CP(NULL ), - [RT_FURN] = CP(NULL ), [RT_GLOB] = CP(NULL ), [RT_GMST] = CP(NULL ), - [RT_GRAS] = CP(NULL ), [RT_GRUP] = CP(NULL ), [RT_HAIR] = CP(NULL ), - [RT_HAZD] = CP(NULL ), [RT_HDPT] = CP(NULL ), [RT_IDLE] = CP(NULL ), - [RT_IDLM] = CP(NULL ), [RT_IMAD] = CP(NULL ), [RT_IMGS] = CP(NULL ), - [RT_INFO] = CP(NULL ), [RT_INGR] = CP(_refr_ingr), [RT_IPCT] = CP(NULL ), - [RT_IPDS] = CP(NULL ), [RT_KEYM] = CP(_refr_keym), [RT_KYWD] = CP(NULL ), - [RT_LAND] = CP(NULL ), [RT_LCRT] = CP(NULL ), [RT_LCTN] = CP(NULL ), - [RT_LGTM] = CP(NULL ), [RT_LIGH] = CP(_refr_ligh), [RT_LSCR] = CP(NULL ), - [RT_LTEX] = CP(NULL ), [RT_LVLI] = CP(NULL ), [RT_LVLN] = CP(NULL ), - [RT_LVSP] = CP(NULL ), [RT_MATO] = CP(NULL ), [RT_MATT] = CP(NULL ), - [RT_MESG] = CP(NULL ), [RT_MGEF] = CP(NULL ), [RT_MISC] = CP(_refr_misc), - [RT_MOVT] = CP(NULL ), [RT_MSTT] = CP(_refr_mstt), [RT_MUSC] = CP(NULL ), - [RT_MUST] = CP(NULL ), [RT_NAVI] = CP(NULL ), [RT_NAVM] = CP(NULL ), - [RT_NOTE] = CP(NULL ), [RT_NPC_] = CP(NULL ), [RT_OTFT] = CP(NULL ), - [RT_PACK] = CP(NULL ), [RT_PERK] = CP(NULL ), [RT_PGRE] = CP(NULL ), - [RT_PHZD] = CP(NULL ), [RT_PROJ] = CP(NULL ), [RT_PWAT] = CP(NULL ), - [RT_QUST] = CP(NULL ), [RT_RACE] = CP(NULL ), [RT_REFR] = CP(NULL ), - [RT_REGN] = CP(NULL ), [RT_RELA] = CP(NULL ), [RT_REVB] = CP(NULL ), - [RT_RFCT] = CP(NULL ), [RT_RGDL] = CP(NULL ), [RT_SCEN] = CP(NULL ), - [RT_SCOL] = CP(NULL ), [RT_SCPT] = CP(NULL ), [RT_SCRL] = CP(_refr_scrl), - [RT_SHOU] = CP(NULL ), [RT_SLGM] = CP(_refr_slgm), [RT_SMBN] = CP(NULL ), - [RT_SMEN] = CP(NULL ), [RT_SMQN] = CP(NULL ), [RT_SNCT] = CP(NULL ), - [RT_SNDR] = CP(NULL ), [RT_SOPM] = CP(NULL ), [RT_SOUN] = CP(NULL ), - [RT_SPEL] = CP(NULL ), [RT_SPGD] = CP(NULL ), [RT_STAT] = CP(_refr_stat), - [RT_TACT] = CP(NULL ), [RT_TES4] = CP(NULL ), [RT_TREE] = CP(_refr_tree), - [RT_TXST] = CP(NULL ), [RT_VTYP] = CP(NULL ), [RT_WATR] = CP(NULL ), - [RT_WEAP] = CP(_refr_weap), [RT_WOOP] = CP(NULL ), [RT_WRLD] = CP(NULL ), - [RT_WTHR] = CP(NULL ), + [RT_AACT] = CP(NULL ),[RT_ACHR] = CP(NULL ),[RT_ACTI] = CP(_refr_acti), + [RT_ADDN] = CP(_refr_addn),[RT_ALCH] = CP(_refr_alch),[RT_AMMO] = CP(_refr_ammo), + [RT_ANIO] = CP(NULL ),[RT_APPA] = CP(NULL ),[RT_ARMA] = CP(NULL ), + [RT_ARMO] = CP(_refr_armo),[RT_ARTO] = CP(NULL ),[RT_ASPC] = CP(NULL ), + [RT_ASTP] = CP(NULL ),[RT_AVIF] = CP(NULL ),[RT_BOOK] = CP(NULL ), + [RT_BPTD] = CP(NULL ),[RT_CAMS] = CP(NULL ),[RT_CELL] = CP(NULL ), + [RT_CLAS] = CP(NULL ),[RT_CLDC] = CP(NULL ),[RT_CLFM] = CP(NULL ), + [RT_CLMT] = CP(NULL ),[RT_COBJ] = CP(NULL ),[RT_COLL] = CP(NULL ), + [RT_CONT] = CP(_refr_cont),[RT_CPTH] = CP(NULL ),[RT_CSTY] = CP(NULL ), + [RT_DEBR] = CP(NULL ),[RT_DIAL] = CP(NULL ),[RT_DLBR] = CP(NULL ), + [RT_DLVW] = CP(NULL ),[RT_DOBJ] = CP(NULL ),[RT_DOOR] = CP(_refr_door), + [RT_DUAL] = CP(NULL ),[RT_ECZN] = CP(NULL ),[RT_EFSH] = CP(NULL ), + [RT_ENCH] = CP(NULL ),[RT_EQUP] = CP(NULL ),[RT_EXPL] = CP(NULL ), + [RT_EYES] = CP(NULL ),[RT_FACT] = CP(NULL ),[RT_FLOR] = CP(_refr_flor), + [RT_FLST] = CP(NULL ),[RT_FSTP] = CP(NULL ),[RT_FSTS] = CP(NULL ), + [RT_FURN] = CP(NULL ),[RT_GLOB] = CP(NULL ),[RT_GMST] = CP(NULL ), + [RT_GRAS] = CP(NULL ),[RT_GRUP] = CP(NULL ),[RT_HAIR] = CP(NULL ), + [RT_HAZD] = CP(NULL ),[RT_HDPT] = CP(NULL ),[RT_IDLE] = CP(NULL ), + [RT_IDLM] = CP(NULL ),[RT_IMAD] = CP(NULL ),[RT_IMGS] = CP(NULL ), + [RT_INFO] = CP(NULL ),[RT_INGR] = CP(_refr_ingr),[RT_IPCT] = CP(NULL ), + [RT_IPDS] = CP(NULL ),[RT_KEYM] = CP(_refr_keym),[RT_KYWD] = CP(NULL ), + [RT_LAND] = CP(NULL ),[RT_LCRT] = CP(NULL ),[RT_LCTN] = CP(NULL ), + [RT_LGTM] = CP(NULL ),[RT_LIGH] = CP(_refr_ligh),[RT_LSCR] = CP(NULL ), + [RT_LTEX] = CP(NULL ),[RT_LVLI] = CP(NULL ),[RT_LVLN] = CP(NULL ), + [RT_LVSP] = CP(NULL ),[RT_MATO] = CP(NULL ),[RT_MATT] = CP(NULL ), + [RT_MESG] = CP(NULL ),[RT_MGEF] = CP(NULL ),[RT_MISC] = CP(_refr_misc), + [RT_MOVT] = CP(NULL ),[RT_MSTT] = CP(_refr_mstt),[RT_MUSC] = CP(NULL ), + [RT_MUST] = CP(NULL ),[RT_NAVI] = CP(NULL ),[RT_NAVM] = CP(NULL ), + [RT_NOTE] = CP(NULL ),[RT_NPC_] = CP(NULL ),[RT_OTFT] = CP(NULL ), + [RT_PACK] = CP(NULL ),[RT_PERK] = CP(NULL ),[RT_PGRE] = CP(NULL ), + [RT_PHZD] = CP(NULL ),[RT_PROJ] = CP(NULL ),[RT_PWAT] = CP(NULL ), + [RT_QUST] = CP(NULL ),[RT_RACE] = CP(NULL ),[RT_REFR] = CP(NULL ), + [RT_REGN] = CP(NULL ),[RT_RELA] = CP(NULL ),[RT_REVB] = CP(NULL ), + [RT_RFCT] = CP(NULL ),[RT_RGDL] = CP(NULL ),[RT_SCEN] = CP(NULL ), + [RT_SCOL] = CP(NULL ),[RT_SCPT] = CP(NULL ),[RT_SCRL] = CP(_refr_scrl), + [RT_SHOU] = CP(NULL ),[RT_SLGM] = CP(_refr_slgm),[RT_SMBN] = CP(NULL ), + [RT_SMEN] = CP(NULL ),[RT_SMQN] = CP(NULL ),[RT_SNCT] = CP(NULL ), + [RT_SNDR] = CP(NULL ),[RT_SOPM] = CP(NULL ),[RT_SOUN] = CP(NULL ), + [RT_SPEL] = CP(NULL ),[RT_SPGD] = CP(NULL ),[RT_STAT] = CP(_refr_stat), + [RT_TACT] = CP(NULL ),[RT_TES4] = CP(NULL ),[RT_TREE] = CP(_refr_tree), + [RT_TXST] = CP(NULL ),[RT_VTYP] = CP(NULL ),[RT_WATR] = CP(NULL ), + [RT_WEAP] = CP(_refr_weap),[RT_WOOP] = CP(NULL ),[RT_WRLD] = CP(NULL ), + [RT_WTHR] = CP(NULL ), }; diff --git a/espReader/Reader.c b/espReader/Reader.c index c51bf4a..91713ac 100644 --- a/espReader/Reader.c +++ b/espReader/Reader.c @@ -60,83 +60,87 @@ void decompress_post(Node n, void *data, void **carry_in); // void asserts(void) { - // binary overlay size checks - assert(sizeof(Record) == 24); // Record struct incorrect size - assert(sizeof(Group) == 24); // Group struct incorrect size - assert(sizeof((Group) { 0 }.label) == 4); // Label union in group struct incorrect size - assert(sizeof(Field) == 6); // Field struct incorrect size - assert(sizeof(uLongf) == sizeof(uint32_t)); // zlib compatability + // binary overlay size checks + assert(sizeof(Record) == 24); // Record struct incorrect size + assert(sizeof(Group) == 24); // Group struct incorrect size + assert(sizeof((Group) { 0 }.label) == 4); // Label union in group struct incorrect size + assert(sizeof(Field) == 6); // Field struct incorrect size + + // zlib compatability + assert(sizeof(uLongf) == sizeof(uint32_t)); + assert(sizeof(Bytef) == sizeof(char)); } void espr_walk(char *data, size_t size, struct walker_callbacks cb) { - // check assertions that cannot be checked at compile time - asserts(); + // check assertions that cannot be checked at compile time + asserts(); - char *data_start = data; + char *data_start = data; - // check that we are at the start of the file - const Type4 type = *(const Type4 *)data; - assert(type.uint == rt[TES4]); + // check that we are at the start of the file + const Type4 type = *(const Type4 *)data; + assert(type.uint == rt[TES4]); - data = walk_concat(data, size, cb); - assert(data == data_start + size); + data = walk_concat(data, size, cb); + assert(data == data_start + size); } void espr_print(char *data, size_t size) { - struct walker_callbacks cb = { .pre = print_callback }; - espr_walk(data, size, cb); + struct walker_callbacks cb = { .pre = print_callback }; + espr_walk(data, size, cb); } void print_callback(Node n, void *data, void **carry_out) { - (void)data; - (void)carry_out; - switch (n.type) { - case NT_GROUP: - print_group_header(n.header.group); - break; - case NT_RECORD: - print_record_header(n.header.record); - break; - default: - assert(false); // invalid node type - } + (void)data; + (void)carry_out; + switch (n.type) { + case NT_GROUP: + print_group_header(n.header.group); + break; + case NT_RECORD: + print_record_header(n.header.record); + break; + default: + assert(false); // invalid node type + } } size_t espr_decompressed_size(char *data, size_t size) { - size_t dc_size = 0; - struct walker_callbacks cb = { .pre = dc_size_cb, .data = &dc_size }; - espr_walk(data, size, cb); - return dc_size; + size_t dc_size = 0; + struct walker_callbacks cb = { .pre = dc_size_cb, .data = &dc_size }; + espr_walk(data, size, cb); + return dc_size; } // Adds the size of every node up, reading decompressed size from compressed records. void dc_size_cb(Node n, void *data, void **carry_out) { - (void)carry_out; - size_t *dc_size = data; - switch (n.type) { - case NT_GROUP: - // Only add header size for groups, internals will be walked - *dc_size += sizeof(Group); - break; - case NT_RECORD: - // Add the whole record and header, records are leaf-ish - *dc_size += sizeof(Record); - if (n.header.record->flags & COMPRESSED_FLAG) { - // Read decompressed size - *dc_size += *((uint32_t *)n.data); - } else - *dc_size += n.header.record->size; - break; - default: - assert(false); // invalid node type - } + (void)carry_out; + size_t *dc_size = data; + switch (n.type) { + case NT_GROUP: + // Only add header size for groups, internals will be walked + *dc_size += sizeof(Group); + break; + case NT_RECORD: + // Add the whole record and header, records are leaf-ish + *dc_size += sizeof(Record); + if (n.header.record->flags & COMPRESSED_FLAG) { + // Read decompressed size + *dc_size += *((uint32_t *)n.data); + } + else + *dc_size += n.header.record->size; + break; + default: + assert(false); // invalid node type + } } size_t espr_formid_count(char *data, size_t size) { - size_t count = 0; - struct walker_callbacks cb = { .pre = formid_count_cb, .data = &count }; - espr_walk(data, size, cb); - return count; + size_t count = 0; + struct walker_callbacks cb = { .pre = formid_count_cb, .data = &count }; + espr_walk(data, size, cb); + return count; } /* FormID <-> Record relationship should be bijective. I do not believe @@ -144,97 +148,97 @@ size_t espr_formid_count(char *data, size_t size) { * otherwise there would be clashes in the id space. */ void formid_count_cb(Node n, void *data, void **carry_out) { - (void)carry_out; - size_t *count = data; - if (n.type == NT_RECORD) { - (*count)++; - } + (void)carry_out; + size_t *count = data; + if (n.type == NT_RECORD) { + (*count)++; + } } struct decom { - char *buf; - size_t remaining; + char *buf; + size_t remaining; }; void espr_decompress(char *data, size_t size, char *buf, size_t buf_size) { - struct decom s = { .buf = buf, .remaining = buf_size }; - struct walker_callbacks cb = { .pre = decompress_pre, .post = decompress_post, .data = &s }; - espr_walk(data, size, cb); + struct decom s = { .buf = buf, .remaining = buf_size }; + struct walker_callbacks cb = { .pre = decompress_pre, .post = decompress_post, .data = &s }; + espr_walk(data, size, cb); } void decompress_pre(Node n, void *decom_ptr, void **carry_out) { - struct decom *d = decom_ptr; + struct decom *d = decom_ptr; - switch (n.type) { - case NT_RECORD: - // compressed record - if (n.header.record->flags & COMPRESSED_FLAG) { - // copy header - memcpy(d->buf, n.header.record, sizeof(Record)); + switch (n.type) { + case NT_RECORD: + // compressed record + if (n.header.record->flags & COMPRESSED_FLAG) { + // copy header + memcpy(d->buf, n.header.record, sizeof(Record)); - // copied header reference - Record *header = (Record *)d->buf; + // copied header reference + Record *header = (Record *)d->buf; - // update decom struct - d->remaining -= sizeof(Record); - d->buf += sizeof(Record); + // update decom struct + d->remaining -= sizeof(Record); + d->buf += sizeof(Record); - // decompress directly into buffer - // first 4 bytes are the decompressed size - const uint32_t dc_size = *((uint32_t *)n.data); - uint32_t to_copy = dc_size; - uint32_t cur_size = n.header.record->size - sizeof(uint32_t); - char *data_start = n.data + sizeof(uint32_t); - int ret = uncompress((Bytef *)d->buf, (uLongf *)&to_copy, (Bytef *)data_start, (uLong)cur_size); - assert(ret == Z_OK); - assert(to_copy == dc_size); + // decompress directly into buffer + // first 4 bytes are the decompressed size + const uint32_t dc_size = *((uint32_t *)n.data); + uint32_t to_copy = dc_size; + uint32_t cur_size = n.header.record->size - sizeof(uint32_t); + char *data_start = n.data + sizeof(uint32_t); + int ret = uncompress((Bytef *)d->buf, (uLongf *)&to_copy, (Bytef *)data_start, (uLong)cur_size); + assert(ret == Z_OK); + assert(to_copy == dc_size); - // update decom struct - d->remaining -= dc_size; - d->buf += dc_size; + // update decom struct + d->remaining -= dc_size; + d->buf += dc_size; - // update header data size - header->size = dc_size; + // update header data size + header->size = dc_size; - // unset compressed flag - header->flags &= ~COMPRESSED_FLAG; - } - else { - // copy record - size_t record_size = sizeof(Record) + n.header.record->size; - memcpy(d->buf, n.header.record, record_size); + // unset compressed flag + header->flags &= ~COMPRESSED_FLAG; + } + else { + // copy record + size_t record_size = sizeof(Record) + n.header.record->size; + memcpy(d->buf, n.header.record, record_size); - // update decom - d->remaining -= record_size; - d->buf += record_size; - } - break; - case NT_GROUP: - // copy header, contents will be copied while walking - memcpy(d->buf, n.header.group, sizeof(Group)); + // update decom + d->remaining -= record_size; + d->buf += record_size; + } + break; + case NT_GROUP: + // copy header, contents will be copied while walking + memcpy(d->buf, n.header.group, sizeof(Group)); - // save copied header location for post-walk group size recalc - *carry_out = (void *)d->buf; + // save copied header location for post-walk group size recalc + *carry_out = (void *)d->buf; - // update decom - d->buf += sizeof(Group); - d->remaining -= sizeof(Group); + // update decom + d->buf += sizeof(Group); + d->remaining -= sizeof(Group); - break; - default: - assert(false); // invalid node type - } + break; + default: + assert(false); // invalid node type + } } void decompress_post(Node n, void *decom_ptr, void **carry_in) { - struct decom *d = decom_ptr; + struct decom *d = decom_ptr; - // only need to handle group resize - if (n.type == NT_GROUP) { - Group *g = (Group *)(*carry_in); - uint32_t new_size = (uint32_t)((char *)d->buf - (char *)g); - g->size = new_size; - } + // only need to handle group resize + if (n.type == NT_GROUP) { + Group *g = (Group *)(*carry_in); + uint32_t new_size = (uint32_t)((char *)d->buf - (char *)g); + g->size = new_size; + } } /* Unknown data will be some concatenation of groups and records. @@ -243,196 +247,198 @@ void decompress_post(Node n, void *decom_ptr, void **carry_in) { * for each segment of unknown data in this concatenation. */ char *walk_concat(char *data, size_t size, struct walker_callbacks cb) { - const char *end = data + size; - while (data != end) { - assert(data < end); + const char *end = data + size; + while (data != end) { + assert(data < end); - const Type4 *type = (Type4 *)data; + const Type4 *type = (Type4 *)data; - // check valid type - assert(rt[rth2rt[rt_hash(type->uint)]] == type->uint); + // check valid type + assert(rt[rth2rt[rt_hash(type->uint)]] == type->uint); - // only need to distinguish between groups and records - if (type->uint == rt[GRUP]) - data = walk_group(data, cb); - else - data = walk_record(data, cb); - } - return data; + // only need to distinguish between groups and records + if (type->uint == rt[GRUP]) + data = walk_group(data, cb); + else + data = walk_record(data, cb); + } + return data; } -/* Walk a group record. Group records are containers for any other type of record, +/* Walk a group record. Group records are containers for any other type of record, * including other group records. - * + * * This function will also call `cb` with the node constructed from this group record. */ char *walk_group(char *data, struct walker_callbacks cb) { - Group *const header = (Group *const)data; + Group *const header = (Group *const)data; - // The size in the group header includes the size of the header - char *data_start = data + sizeof(Group); - char *data_end = data + header->size; - size_t data_size = data_end - data_start; + // The size in the group header includes the size of the header + char *data_start = data + sizeof(Group); + char *data_end = data + header->size; + size_t data_size = data_end - data_start; - Node n = { .header.group = header, .data = data_start, .type = NT_GROUP }; - void *carry; + Node n = { .header.group = header, .data = data_start, .type = NT_GROUP }; + void *carry; - // Pre-walk callback - if (cb.pre) - cb.pre(n, cb.data, &carry); + // Pre-walk callback + if (cb.pre) + cb.pre(n, cb.data, &carry); - // Walk through the concatenation of data inside the group. - data = walk_concat(data_start, data_size, cb); - assert(data == data_end); + // Walk through the concatenation of data inside the group. + data = walk_concat(data_start, data_size, cb); + assert(data == data_end); - // Post-walk callback - if (cb.post) - cb.post(n, cb.data, &carry); + // Post-walk callback + if (cb.post) + cb.post(n, cb.data, &carry); - return data; + return data; } char *walk_record(char *data, struct walker_callbacks cb) { - Record *header = (Record *)data; - assert(header->type.uint != rt[GRUP]); + Record *header = (Record *)data; + assert(header->type.uint != rt[GRUP]); - char *data_start = data + sizeof(Record); + char *data_start = data + sizeof(Record); - Node n = { .header.record = header, .data = data_start, .type = NT_RECORD }; - void *carry; + Node n = { .header.record = header, .data = data_start, .type = NT_RECORD }; + void *carry; - /* Pre and post walk callbacks make less sense for record walking as records - * are leaf-ish, will still call both here for now as field walking may be - * added in the future. - */ + /* Pre and post walk callbacks make less sense for record walking as records + * are leaf-ish, will still call both here for now as field walking may be + * added in the future. + */ - // Pre-walk callback - if (cb.pre) - cb.pre(n, cb.data, &carry); + // Pre-walk callback + if (cb.pre) + cb.pre(n, cb.data, &carry); - // Update data ptr based on record size. - data += sizeof(Record) + header->size; + // Update data ptr based on record size. + data += sizeof(Record) + header->size; - // Post-walk callback - if (cb.post) - cb.post(n, cb.data, &carry); + // Post-walk callback + if (cb.post) + cb.post(n, cb.data, &carry); - return data; + return data; } void print_group_header(Group *header) { - printf("--- HEADER: GROUP ---\n"); - print_type(header->grup); - printf("Size: %u\n", header->size); - print_group_label(header); - assert(header->type < GTS_SIZE); - printf("Group type: %s\n", group_type_strings[header->type]); - print_timestamp(header->timestamp); - printf("Version Control Info: %04x\n", header->vcinfo); - printf("Unknown: %08x\n", header->unknown); + printf("--- HEADER: GROUP ---\n"); + print_type(header->grup); + printf("Size: %u\n", header->size); + print_group_label(header); + assert(header->type < GTS_SIZE); + printf("Group type: %s\n", group_type_strings[header->type]); + print_timestamp(header->timestamp); + printf("Version Control Info: %04x\n", header->vcinfo); + printf("Unknown: %08x\n", header->unknown); } void print_record_header(Record *header) { - printf("--- HEADER: RECORD ---\n"); - print_type(header->type); - print_record_flags(header); - printf("FormID: %x\n", header->formid); - print_timestamp(header->timestamp); - printf("Version Control Info: %04x\n", header->vcinfo); - printf("Version: %u\n", header->version); - printf("Unknown: %08x\n", header->unknown); + printf("--- HEADER: RECORD ---\n"); + print_type(header->type); + print_record_flags(header); + printf("FormID: %x\n", header->formid); + print_timestamp(header->timestamp); + printf("Version Control Info: %04x\n", header->vcinfo); + printf("Version: %u\n", header->version); + printf("Unknown: %08x\n", header->unknown); } void print_group_label(Group *header) { - printf("Label: "); - switch (header->type) { - case GT_TOP: - print_type4(header->label.type); - break; - case GT_INTERIOR_CELL_BLOCK: - case GT_INTERIOR_CELL_SUBBLOCK: - printf("%d", header->label.number); - case GT_EXTERIOR_CELL_BLOCK: - case GT_EXTERIOR_CELL_SUBBLOCK: - printf("X: %d, Y: %d", header->label.coord[1], header->label.coord[0]); - case GT_WORLD_CHILDREN: - case GT_CELL_CHILDREN: - case GT_TOPIC_CHILDREN: - case GT_CELL_PERSISTENT_CHILDREN: - case GT_CELL_TEMPORARY_CHILDREN: - printf("FormID[%x]", header->label.formid); - break; - default: - assert(false); // invalid group type - } - printf("\n"); + printf("Label: "); + switch (header->type) { + case GT_TOP: + print_type4(header->label.type); + break; + case GT_INTERIOR_CELL_BLOCK: + case GT_INTERIOR_CELL_SUBBLOCK: + printf("%d", header->label.number); + case GT_EXTERIOR_CELL_BLOCK: + case GT_EXTERIOR_CELL_SUBBLOCK: + printf("X: %d, Y: %d", header->label.coord[1], header->label.coord[0]); + case GT_WORLD_CHILDREN: + case GT_CELL_CHILDREN: + case GT_TOPIC_CHILDREN: + case GT_CELL_PERSISTENT_CHILDREN: + case GT_CELL_TEMPORARY_CHILDREN: + printf("FormID[%x]", header->label.formid); + break; + default: + assert(false); // invalid group type + } + printf("\n"); } void print_record_flags(Record *header) { - printf("Flags:\n"); + printf("Flags:\n"); - uint32_t flags = header->flags; - const uint32_t type = header->type.uint; + uint32_t flags = header->flags; + const uint32_t type = header->type.uint; - // print flags - if (type == rt[REFR]) { - // TODO - // REFR requires FormID lookup - flags = 0; - } else { - rfs_inner *const flag_lut = rfs[rt_hash(type)]; - if (flag_lut) { - while (flags != 0) { - // will always be >= 0 as flags is not 0 - int highest = 31 - __lzcnt(flags); - assert(highest >= 0); - const char *const str = (*flag_lut)[highest]; - if (str) { - printf(" - %s\n", str); - flags -= ((uint32_t)1) << highest; - } else - break; - } - } - } + // print flags + if (type == rt[REFR]) { + // TODO + // REFR requires FormID lookup + flags = 0; + } + else { + rfs_inner *const flag_lut = rfs[rt_hash(type)]; + if (flag_lut) { + while (flags != 0) { + // will always be >= 0 as flags is not 0 + int highest = 31 - __lzcnt(flags); + assert(highest >= 0); + const char *const str = (*flag_lut)[highest]; + if (str) { + printf(" - %s\n", str); + flags -= ((uint32_t)1) << highest; + } + else + break; + } + } + } - if (flags != 0) { - printf("\n\nOriginal flags: %08x\n", header->flags); - printf("Unhandled flags: %08x\n", flags); - assert(false); // unhandled flags - } + if (flags != 0) { + printf("\n\nOriginal flags: %08x\n", header->flags); + printf("Unhandled flags: %08x\n", flags); + assert(false); // unhandled flags + } } // This is the Skyrim SE timestamp format void print_timestamp(uint16_t _ts) { - Timestamp ts = convert_ts(_ts); - printf("Timestamp: 20x%u-%02u-%02u\n", ts.year, ts.month, ts.day); + Timestamp ts = convert_ts(_ts); + printf("Timestamp: 20x%u-%02u-%02u\n", ts.year, ts.month, ts.day); } void print_type(Type4 type) { - printf("Type: "); - print_type4(type); - printf("\n"); + printf("Type: "); + print_type4(type); + printf("\n"); } void print_type4(Type4 val) { - // invariant: printed i characters from val.bytes - for (size_t i = 0; i != 4; i++) - printf("%c", val.bytes[i]); + // invariant: printed i characters from val.bytes + for (size_t i = 0; i != 4; i++) + printf("%c", val.bytes[i]); } Timestamp convert_ts(uint16_t ts) { - /* - const uint8_t day = (uint8_t)(ts & day_mask); - const uint8_t month = (uint8_t)((ts >> month_offset) & month_mask); - const uint16_t year = (ts >> year_offset) & year_mask; - */ + /* + const uint8_t day = (uint8_t)(ts & day_mask); + const uint8_t month = (uint8_t)((ts >> month_offset) & month_mask); + const uint16_t year = (ts >> year_offset) & year_mask; + */ - const uint8_t day = ts & 0xff; - const uint8_t hb = (ts >> 8) & 0xff; - const uint8_t month = ((hb - 1) % 12) + 1; - const uint8_t year = ((hb - 1) / 12 + 3) % 10; + const uint8_t day = ts & 0xff; + const uint8_t hb = (ts >> 8) & 0xff; + const uint8_t month = ((hb - 1) % 12) + 1; + const uint8_t year = ((hb - 1) / 12 + 3) % 10; - return (Timestamp){ year, month, day }; + return (Timestamp) { year, month, day }; } diff --git a/mph_gen/main.c b/mph_gen/main.c index 91f3c7e..9ae1d53 100644 --- a/mph_gen/main.c +++ b/mph_gen/main.c @@ -25,58 +25,60 @@ bool buf[NUM]; int main() { - uint32_t seed = 1; - bool clash; - size_t max = 0; - do { - if ((seed - 1) % 1000000 == 0) - printf("Checked up to: %u\r", seed - 1); + uint32_t seed = 1; + bool clash; + size_t max = 0; + do { + if ((seed - 1) % 1000000 == 0) + printf("Checked up to: %u\r", seed - 1); - // reset for test - memset(buf, 0, sizeof(bool) * NUM); - clash = false; + // reset for test + memset(buf, 0, sizeof(bool) * NUM); + clash = false; - // check for collisions - for (size_t i = 0; i != RT_SIZE; i++) { - uint32_t index = uint32_t_msh(rt[i], BITS, seed); - if (buf[index]) { - if (i > max) { - // printf("\nMax: %llu\n", i); - max = i; - } - clash = true; - break; - } else { - buf[index] = true; - } - } + // check for collisions + for (size_t i = 0; i != RT_SIZE; i++) { + uint32_t index = uint32_t_msh(rt[i], BITS, seed); + if (buf[index]) { + if (i > max) { + // printf("\nMax: %llu\n", i); + max = i; + } + clash = true; + break; + } + else { + buf[index] = true; + } + } - // exit if non-clashing seed found - if (!clash) { - break; - } - - // seed must be odd - seed += 2; - } while (seed != UINT32_MAX); // is odd, so will be hit + // exit if non-clashing seed found + if (!clash) { + break; + } - if (!clash) { - printf("\nSeed found: %u", seed); - for (size_t i = 0; i != RT_SIZE; i++) { - char name[5]; - memcpy(name, &rt[i], sizeof(uint32_t)); - name[4] = '\0'; - uint32_t index = uint32_t_msh(rt[i], BITS, seed); - if (i % PER_LINE == 0) - printf("\n"); - else - printf(" "); - printf("RT_%s = %3u,", name, index); - } - } else { - printf("Seed not found. Max: %llu\n", max); - } + // seed must be odd + seed += 2; + } while (seed != UINT32_MAX); // is odd, so will be hit - return 0; + if (!clash) { + printf("\nSeed found: %u", seed); + for (size_t i = 0; i != RT_SIZE; i++) { + char name[5]; + memcpy(name, &rt[i], sizeof(uint32_t)); + name[4] = '\0'; + uint32_t index = uint32_t_msh(rt[i], BITS, seed); + if (i % PER_LINE == 0) + printf("\n"); + else + printf(" "); + printf("RT_%s = %3u,", name, index); + } + } + else { + printf("Seed not found. Max: %llu\n", max); + } + + return 0; }