Added a few more comments. Changed rt_hash to return an enum record_type rather than an enum record_type_hash. Modified rfs and rfs_refr to suit.
This commit is contained in:
@@ -31,8 +31,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Flag fields are 32 bits, so there are 32 flags
|
||||||
#define RFS_INNER_SIZE 32
|
#define RFS_INNER_SIZE 32
|
||||||
|
|
||||||
|
// There are 127 record types + a NONE type used for sanity checks
|
||||||
#define RT_SIZE 128
|
#define RT_SIZE 128
|
||||||
|
|
||||||
/* RT hash seed was externally calculated s.t. the fourcc codes perfectly hash
|
/* RT hash seed was externally calculated s.t. the fourcc codes perfectly hash
|
||||||
@@ -48,9 +50,12 @@ extern "C" {
|
|||||||
#define RT_HASH_BITS 9
|
#define RT_HASH_BITS 9
|
||||||
#define RT_HASH_SEED 131261257
|
#define RT_HASH_SEED 131261257
|
||||||
|
|
||||||
|
// Used for identifying records that are compressed
|
||||||
#define COMPRESSED_FLAG (((uint32_t)1) << 18)
|
#define COMPRESSED_FLAG (((uint32_t)1) << 18)
|
||||||
|
|
||||||
|
// Top level group order, there are 118 top level groups
|
||||||
#define GO_SIZE 118
|
#define GO_SIZE 118
|
||||||
|
// There are 10 Group Types
|
||||||
#define GTS_SIZE 10
|
#define GTS_SIZE 10
|
||||||
|
|
||||||
|
|
||||||
@@ -68,15 +73,17 @@ extern "C" {
|
|||||||
// === SIMPLE TYPES ===
|
// === SIMPLE TYPES ===
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// 3 byte ID, upper byte is determined at run time and is used to reference
|
||||||
|
// across esp/esm files
|
||||||
typedef uint32_t formid;
|
typedef uint32_t formid;
|
||||||
|
|
||||||
// char[4] with uint32_t access
|
// char[4] with uint32_t access, used to access fourcc values
|
||||||
union type4 {
|
union type4 {
|
||||||
char bytes[4];
|
char bytes[4];
|
||||||
uint32_t uint;
|
uint32_t uint;
|
||||||
};
|
};
|
||||||
|
|
||||||
// indexed by flag bit
|
// Inner type for Record Flag String LUT. Indexed by flag bit.
|
||||||
typedef const char *const rfs_inner[RFS_INNER_SIZE];
|
typedef const char *const rfs_inner[RFS_INNER_SIZE];
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -84,7 +91,7 @@ extern "C" {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// Tag for generic node tagged union
|
// Tag for generic node tagged union
|
||||||
enum node_type { // NT_ prefix
|
enum node_type {
|
||||||
NT_GROUP,
|
NT_GROUP,
|
||||||
NT_RECORD,
|
NT_RECORD,
|
||||||
};
|
};
|
||||||
@@ -116,8 +123,8 @@ extern "C" {
|
|||||||
WTHR,
|
WTHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
// GRUP type values
|
// Group type enum
|
||||||
enum group_type { // GT_ prefix
|
enum group_type {
|
||||||
GT_TOP = 0,
|
GT_TOP = 0,
|
||||||
GT_WORLD_CHILDREN = 1,
|
GT_WORLD_CHILDREN = 1,
|
||||||
GT_INTERIOR_CELL_BLOCK = 2,
|
GT_INTERIOR_CELL_BLOCK = 2,
|
||||||
@@ -134,7 +141,7 @@ extern "C" {
|
|||||||
// === COMPOSITE TYPES ===
|
// === COMPOSITE TYPES ===
|
||||||
//
|
//
|
||||||
|
|
||||||
// Generic node
|
// Generic node in the esp/esm tree
|
||||||
typedef struct node Node;
|
typedef struct node Node;
|
||||||
struct node {
|
struct node {
|
||||||
union {
|
union {
|
||||||
@@ -146,13 +153,24 @@ extern "C" {
|
|||||||
uint32_t _pad;
|
uint32_t _pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
// calculated timestamp
|
// Used for passing around parsed timestamps
|
||||||
struct timestamp {
|
struct timestamp {
|
||||||
uint16_t year;
|
uint16_t year;
|
||||||
uint8_t month;
|
uint8_t month;
|
||||||
uint8_t day;
|
uint8_t day;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Given to espr_walk.
|
||||||
|
*
|
||||||
|
* pre is called before the children of the current node have been walked
|
||||||
|
* post is called after the children of the current node have been walked
|
||||||
|
*
|
||||||
|
* carry_out and carry_in is a pointer to a void * on the stack that can be
|
||||||
|
* used for passing data between pre and post for a node.
|
||||||
|
*
|
||||||
|
* data is a pointer that the user can supply when calling espr_walk that
|
||||||
|
* will be passed to pre and post when they are called.
|
||||||
|
*/
|
||||||
struct walker_callbacks {
|
struct walker_callbacks {
|
||||||
void (*pre)(Node n, void *data, void **carry_out);
|
void (*pre)(Node n, void *data, void **carry_out);
|
||||||
void (*post)(Node n, void *data, void **carry_in);
|
void (*post)(Node n, void *data, void **carry_in);
|
||||||
@@ -215,9 +233,8 @@ extern "C" {
|
|||||||
// type -> flag mappings
|
// type -> flag mappings
|
||||||
// NULL table pointers indicate no flags
|
// NULL table pointers indicate no flags
|
||||||
// NULL string pointers indicate invalid flag
|
// NULL string pointers indicate invalid flag
|
||||||
extern rfs_inner *const rfs[RT_HASH_SIZE];
|
extern rfs_inner *const rfs[RT_SIZE];
|
||||||
|
extern rfs_inner *const rfs_refr[RT_SIZE];
|
||||||
extern rfs_inner *const rfs_refr[RT_HASH_SIZE];
|
|
||||||
|
|
||||||
// Expected (probably) order of top level groups in an esp/esm
|
// Expected (probably) order of top level groups in an esp/esm
|
||||||
extern const enum record_type group_order[GO_SIZE];
|
extern const enum record_type group_order[GO_SIZE];
|
||||||
@@ -229,9 +246,9 @@ extern "C" {
|
|||||||
// === FUNCTIONS ===
|
// === FUNCTIONS ===
|
||||||
//
|
//
|
||||||
|
|
||||||
// hashes type value into RT_ hash value
|
// hashes type value into a record type enum value
|
||||||
inline uint32_t rt_hash(uint32_t type) {
|
inline uint32_t rt_hash(uint32_t type) {
|
||||||
return uint32_t_msh(type, RT_HASH_BITS, RT_HASH_SEED);
|
return rth2rt[uint32_t_msh(type, RT_HASH_BITS, RT_HASH_SEED)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* `espr_walk` walks through the tree structure of the esp/esm binary data
|
/* `espr_walk` walks through the tree structure of the esp/esm binary data
|
||||||
|
|||||||
@@ -10,11 +10,32 @@
|
|||||||
typedef struct meta_node MetaNode;
|
typedef struct meta_node MetaNode;
|
||||||
|
|
||||||
/* Meta Nodes are used for constructing a more flexible tree structure
|
/* Meta Nodes are used for constructing a more flexible tree structure
|
||||||
* on top of
|
* on top of the natural structure of ESP/ESM files.
|
||||||
|
*
|
||||||
|
* Meta Nodes do not create a pure tree structure, rather they have pointers to
|
||||||
|
* their parent and first child, and children have pointers backwards and
|
||||||
|
* forward through a linked list of all of the children of the parent node.
|
||||||
|
*
|
||||||
|
* There is no root node as such, rather there is a root linked list for which
|
||||||
|
* all of the Meta Nodes have no parents.
|
||||||
|
*
|
||||||
|
* While the ESP/ESM buffer can be modified in-place, any modification that
|
||||||
|
* changes the size of the stored data cannot be directly written to the buffer
|
||||||
|
* without first shifting all of the data after the point of modification.
|
||||||
|
*
|
||||||
|
* Modifications that change data size are:
|
||||||
|
* - Adding or deleting a group or record
|
||||||
|
* - Adding or deleting a field in a record
|
||||||
|
* - Changing a variable length field with data of different length
|
||||||
|
*
|
||||||
|
* With a Meta Node you can instead allocate new, arbitrarily sized memory for
|
||||||
|
* the node data. The Meta Node tree can then be walked to reconstruct a
|
||||||
|
* contiguous view of discontiguous memory.
|
||||||
*/
|
*/
|
||||||
struct meta_node {
|
struct meta_node {
|
||||||
Node n;
|
Node n;
|
||||||
MetaNode *parent;
|
MetaNode *parent;
|
||||||
|
MetaNode *child;
|
||||||
MetaNode *prev;
|
MetaNode *prev;
|
||||||
MetaNode *next;
|
MetaNode *next;
|
||||||
};
|
};
|
||||||
|
|||||||
176
espReader/LUT.c
176
espReader/LUT.c
@@ -476,50 +476,50 @@ rfs_inner wrld = {
|
|||||||
[19] = "Can't Wait",
|
[19] = "Can't Wait",
|
||||||
};
|
};
|
||||||
|
|
||||||
rfs_inner *const rfs[RT_HASH_SIZE] = {
|
rfs_inner *const rfs[RT_SIZE] = {
|
||||||
[RT_AACT] = CP(NULL),[RT_ACHR] = CP(achr),[RT_ACTI] = CP(acti),
|
[AACT] = CP(NULL),[ACHR] = CP(achr),[ACTI] = CP(acti),
|
||||||
[RT_ADDN] = CP(NULL),[RT_ALCH] = CP(alch),[RT_AMMO] = CP(ammo),
|
[ADDN] = CP(NULL),[ALCH] = CP(alch),[AMMO] = CP(ammo),
|
||||||
[RT_ANIO] = CP(anio),[RT_APPA] = CP(NULL),[RT_ARMA] = CP(NULL),
|
[ANIO] = CP(anio),[APPA] = CP(NULL),[ARMA] = CP(NULL),
|
||||||
[RT_ARMO] = CP(armo),[RT_ARTO] = CP(NULL),[RT_ASPC] = CP(NULL),
|
[ARMO] = CP(armo),[ARTO] = CP(NULL),[ASPC] = CP(NULL),
|
||||||
[RT_ASTP] = CP(NULL),[RT_AVIF] = CP(NULL),[RT_BOOK] = CP(NULL),
|
[ASTP] = CP(NULL),[AVIF] = CP(NULL),[BOOK] = CP(NULL),
|
||||||
[RT_BPTD] = CP(NULL),[RT_CAMS] = CP(NULL),[RT_CELL] = CP(cell),
|
[BPTD] = CP(NULL),[CAMS] = CP(NULL),[CELL] = CP(cell),
|
||||||
[RT_CLAS] = CP(NULL),[RT_CLDC] = CP(NULL),[RT_CLFM] = CP(clfm),
|
[CLAS] = CP(NULL),[CLDC] = CP(NULL),[CLFM] = CP(clfm),
|
||||||
[RT_CLMT] = CP(NULL),[RT_COBJ] = CP(NULL),[RT_COLL] = CP(NULL),
|
[CLMT] = CP(NULL),[COBJ] = CP(NULL),[COLL] = CP(NULL),
|
||||||
[RT_CONT] = CP(cont),[RT_CPTH] = CP(NULL),[RT_CSTY] = CP(csty),
|
[CONT] = CP(cont),[CPTH] = CP(NULL),[CSTY] = CP(csty),
|
||||||
[RT_DEBR] = CP(NULL),[RT_DIAL] = CP(NULL),[RT_DLBR] = CP(NULL),
|
[DEBR] = CP(NULL),[DIAL] = CP(NULL),[DLBR] = CP(NULL),
|
||||||
[RT_DLVW] = CP(NULL),[RT_DOBJ] = CP(NULL),[RT_DOOR] = CP(door),
|
[DLVW] = CP(NULL),[DOBJ] = CP(NULL),[DOOR] = CP(door),
|
||||||
[RT_DUAL] = CP(NULL),[RT_ECZN] = CP(NULL),[RT_EFSH] = CP(NULL),
|
[DUAL] = CP(NULL),[ECZN] = CP(NULL),[EFSH] = CP(NULL),
|
||||||
[RT_ENCH] = CP(NULL),[RT_EQUP] = CP(NULL),[RT_EXPL] = CP(NULL),
|
[ENCH] = CP(NULL),[EQUP] = CP(NULL),[EXPL] = CP(NULL),
|
||||||
[RT_EYES] = CP(eyes),[RT_FACT] = CP(NULL),[RT_FLOR] = CP(NULL),
|
[EYES] = CP(eyes),[FACT] = CP(NULL),[FLOR] = CP(NULL),
|
||||||
[RT_FLST] = CP(NULL),[RT_FSTP] = CP(NULL),[RT_FSTS] = CP(NULL),
|
[FLST] = CP(NULL),[FSTP] = CP(NULL),[FSTS] = CP(NULL),
|
||||||
[RT_FURN] = CP(furn),[RT_GLOB] = CP(glob),[RT_GMST] = CP(NULL),
|
[FURN] = CP(furn),[GLOB] = CP(glob),[GMST] = CP(NULL),
|
||||||
[RT_GRAS] = CP(NULL),[RT_GRUP] = CP(NULL),[RT_HAIR] = CP(NULL),
|
[GRAS] = CP(NULL),[GRUP] = CP(NULL),[HAIR] = CP(NULL),
|
||||||
[RT_HAZD] = CP(NULL),[RT_HDPT] = CP(hdpt),[RT_IDLE] = CP(NULL),
|
[HAZD] = CP(NULL),[HDPT] = CP(hdpt),[IDLE] = CP(NULL),
|
||||||
[RT_IDLM] = CP(idlm),[RT_IMAD] = CP(NULL),[RT_IMGS] = CP(NULL),
|
[IDLM] = CP(idlm),[IMAD] = CP(NULL),[IMGS] = CP(NULL),
|
||||||
[RT_INFO] = CP(info),[RT_INGR] = CP(NULL),[RT_IPCT] = CP(NULL),
|
[INFO] = CP(info),[INGR] = CP(NULL),[IPCT] = CP(NULL),
|
||||||
[RT_IPDS] = CP(NULL),[RT_KEYM] = CP(keym),[RT_KYWD] = CP(NULL),
|
[IPDS] = CP(NULL),[KEYM] = CP(keym),[KYWD] = CP(NULL),
|
||||||
[RT_LAND] = CP(land),[RT_LCRT] = CP(NULL),[RT_LCTN] = CP(NULL),
|
[LAND] = CP(land),[LCRT] = CP(NULL),[LCTN] = CP(NULL),
|
||||||
[RT_LGTM] = CP(NULL),[RT_LIGH] = CP(ligh),[RT_LSCR] = CP(lscr),
|
[LGTM] = CP(NULL),[LIGH] = CP(ligh),[LSCR] = CP(lscr),
|
||||||
[RT_LTEX] = CP(NULL),[RT_LVLI] = CP(NULL),[RT_LVLN] = CP(NULL),
|
[LTEX] = CP(NULL),[LVLI] = CP(NULL),[LVLN] = CP(NULL),
|
||||||
[RT_LVSP] = CP(NULL),[RT_MATO] = CP(NULL),[RT_MATT] = CP(NULL),
|
[LVSP] = CP(NULL),[MATO] = CP(NULL),[MATT] = CP(NULL),
|
||||||
[RT_MESG] = CP(NULL),[RT_MGEF] = CP(NULL),[RT_MISC] = CP(misc),
|
[MESG] = CP(NULL),[MGEF] = CP(NULL),[MISC] = CP(misc),
|
||||||
[RT_MOVT] = CP(NULL),[RT_MSTT] = CP(mstt),[RT_MUSC] = CP(NULL),
|
[MOVT] = CP(NULL),[MSTT] = CP(mstt),[MUSC] = CP(NULL),
|
||||||
[RT_MUST] = CP(NULL),[RT_NAVI] = CP(NULL),[RT_NAVM] = CP(navm),
|
[MUST] = CP(NULL),[NAVI] = CP(NULL),[NAVM] = CP(navm),
|
||||||
[RT_NOTE] = CP(NULL),[RT_NPC_] = CP(npc_),[RT_OTFT] = CP(NULL),
|
[NOTE] = CP(NULL),[NPC_] = CP(npc_),[OTFT] = CP(NULL),
|
||||||
[RT_PACK] = CP(NULL),[RT_PERK] = CP(perk),[RT_PGRE] = CP(pgre),
|
[PACK] = CP(NULL),[PERK] = CP(perk),[PGRE] = CP(pgre),
|
||||||
[RT_PHZD] = CP(phzd),[RT_PROJ] = CP(NULL),[RT_PWAT] = CP(NULL),
|
[PHZD] = CP(phzd),[PROJ] = CP(NULL),[PWAT] = CP(NULL),
|
||||||
[RT_QUST] = CP(NULL),[RT_RACE] = CP(race),[RT_REFR] = CP(refr),
|
[QUST] = CP(NULL),[RACE] = CP(race),[REFR] = CP(refr),
|
||||||
[RT_REGN] = CP(regn),[RT_RELA] = CP(rela),[RT_REVB] = CP(NULL),
|
[REGN] = CP(regn),[RELA] = CP(rela),[REVB] = CP(NULL),
|
||||||
[RT_RFCT] = CP(NULL),[RT_RGDL] = CP(NULL),[RT_SCEN] = CP(NULL),
|
[RFCT] = CP(NULL),[RGDL] = CP(NULL),[SCEN] = CP(NULL),
|
||||||
[RT_SCOL] = CP(NULL),[RT_SCPT] = CP(NULL),[RT_SCRL] = CP(NULL),
|
[SCOL] = CP(NULL),[SCPT] = CP(NULL),[SCRL] = CP(NULL),
|
||||||
[RT_SHOU] = CP(shou),[RT_SLGM] = CP(slgm),[RT_SMBN] = CP(NULL),
|
[SHOU] = CP(shou),[SLGM] = CP(slgm),[SMBN] = CP(NULL),
|
||||||
[RT_SMEN] = CP(NULL),[RT_SMQN] = CP(NULL),[RT_SNCT] = CP(NULL),
|
[SMEN] = CP(NULL),[SMQN] = CP(NULL),[SNCT] = CP(NULL),
|
||||||
[RT_SNDR] = CP(NULL),[RT_SOPM] = CP(NULL),[RT_SOUN] = CP(NULL),
|
[SNDR] = CP(NULL),[SOPM] = CP(NULL),[SOUN] = CP(NULL),
|
||||||
[RT_SPEL] = CP(NULL),[RT_SPGD] = CP(NULL),[RT_STAT] = CP(stat),
|
[SPEL] = CP(NULL),[SPGD] = CP(NULL),[STAT] = CP(stat),
|
||||||
[RT_TACT] = CP(tact),[RT_TES4] = CP(tes4),[RT_TREE] = CP(tree),
|
[TACT] = CP(tact),[TES4] = CP(tes4),[TREE] = CP(tree),
|
||||||
[RT_TXST] = CP(NULL),[RT_VTYP] = CP(NULL),[RT_WATR] = CP(NULL),
|
[TXST] = CP(NULL),[VTYP] = CP(NULL),[WATR] = CP(NULL),
|
||||||
[RT_WEAP] = CP(weap),[RT_WOOP] = CP(NULL),[RT_WRLD] = CP(wrld),
|
[WEAP] = CP(weap),[WOOP] = CP(NULL),[WRLD] = CP(wrld),
|
||||||
[RT_WTHR] = CP(NULL),
|
[WTHR] = CP(NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
// REFR flags depend on what its NAME field references
|
// REFR flags depend on what its NAME field references
|
||||||
@@ -630,49 +630,49 @@ rfs_inner r_misc = REFR_GROUP2;
|
|||||||
rfs_inner r_slgm = REFR_GROUP2;
|
rfs_inner r_slgm = REFR_GROUP2;
|
||||||
rfs_inner r_weap = REFR_GROUP2;
|
rfs_inner r_weap = REFR_GROUP2;
|
||||||
|
|
||||||
rfs_inner *const rfs_r[RT_HASH_SIZE] = {
|
rfs_inner *const rfs_r[RT_SIZE] = {
|
||||||
[RT_AACT] = CP(NULL ),[RT_ACHR] = CP(NULL ),[RT_ACTI] = CP(r_acti),
|
[AACT] = CP(NULL ),[ACHR] = CP(NULL ),[ACTI] = CP(r_acti),
|
||||||
[RT_ADDN] = CP(r_addn),[RT_ALCH] = CP(r_alch),[RT_AMMO] = CP(r_ammo),
|
[ADDN] = CP(r_addn),[ALCH] = CP(r_alch),[AMMO] = CP(r_ammo),
|
||||||
[RT_ANIO] = CP(NULL ),[RT_APPA] = CP(NULL ),[RT_ARMA] = CP(NULL ),
|
[ANIO] = CP(NULL ),[APPA] = CP(NULL ),[ARMA] = CP(NULL ),
|
||||||
[RT_ARMO] = CP(r_armo),[RT_ARTO] = CP(NULL ),[RT_ASPC] = CP(NULL ),
|
[ARMO] = CP(r_armo),[ARTO] = CP(NULL ),[ASPC] = CP(NULL ),
|
||||||
[RT_ASTP] = CP(NULL ),[RT_AVIF] = CP(NULL ),[RT_BOOK] = CP(NULL ),
|
[ASTP] = CP(NULL ),[AVIF] = CP(NULL ),[BOOK] = CP(NULL ),
|
||||||
[RT_BPTD] = CP(NULL ),[RT_CAMS] = CP(NULL ),[RT_CELL] = CP(NULL ),
|
[BPTD] = CP(NULL ),[CAMS] = CP(NULL ),[CELL] = CP(NULL ),
|
||||||
[RT_CLAS] = CP(NULL ),[RT_CLDC] = CP(NULL ),[RT_CLFM] = CP(NULL ),
|
[CLAS] = CP(NULL ),[CLDC] = CP(NULL ),[CLFM] = CP(NULL ),
|
||||||
[RT_CLMT] = CP(NULL ),[RT_COBJ] = CP(NULL ),[RT_COLL] = CP(NULL ),
|
[CLMT] = CP(NULL ),[COBJ] = CP(NULL ),[COLL] = CP(NULL ),
|
||||||
[RT_CONT] = CP(r_cont),[RT_CPTH] = CP(NULL ),[RT_CSTY] = CP(NULL ),
|
[CONT] = CP(r_cont),[CPTH] = CP(NULL ),[CSTY] = CP(NULL ),
|
||||||
[RT_DEBR] = CP(NULL ),[RT_DIAL] = CP(NULL ),[RT_DLBR] = CP(NULL ),
|
[DEBR] = CP(NULL ),[DIAL] = CP(NULL ),[DLBR] = CP(NULL ),
|
||||||
[RT_DLVW] = CP(NULL ),[RT_DOBJ] = CP(NULL ),[RT_DOOR] = CP(r_door),
|
[DLVW] = CP(NULL ),[DOBJ] = CP(NULL ),[DOOR] = CP(r_door),
|
||||||
[RT_DUAL] = CP(NULL ),[RT_ECZN] = CP(NULL ),[RT_EFSH] = CP(NULL ),
|
[DUAL] = CP(NULL ),[ECZN] = CP(NULL ),[EFSH] = CP(NULL ),
|
||||||
[RT_ENCH] = CP(NULL ),[RT_EQUP] = CP(NULL ),[RT_EXPL] = CP(NULL ),
|
[ENCH] = CP(NULL ),[EQUP] = CP(NULL ),[EXPL] = CP(NULL ),
|
||||||
[RT_EYES] = CP(NULL ),[RT_FACT] = CP(NULL ),[RT_FLOR] = CP(r_flor),
|
[EYES] = CP(NULL ),[FACT] = CP(NULL ),[FLOR] = CP(r_flor),
|
||||||
[RT_FLST] = CP(NULL ),[RT_FSTP] = CP(NULL ),[RT_FSTS] = CP(NULL ),
|
[FLST] = CP(NULL ),[FSTP] = CP(NULL ),[FSTS] = CP(NULL ),
|
||||||
[RT_FURN] = CP(NULL ),[RT_GLOB] = CP(NULL ),[RT_GMST] = CP(NULL ),
|
[FURN] = CP(NULL ),[GLOB] = CP(NULL ),[GMST] = CP(NULL ),
|
||||||
[RT_GRAS] = CP(NULL ),[RT_GRUP] = CP(NULL ),[RT_HAIR] = CP(NULL ),
|
[GRAS] = CP(NULL ),[GRUP] = CP(NULL ),[HAIR] = CP(NULL ),
|
||||||
[RT_HAZD] = CP(NULL ),[RT_HDPT] = CP(NULL ),[RT_IDLE] = CP(NULL ),
|
[HAZD] = CP(NULL ),[HDPT] = CP(NULL ),[IDLE] = CP(NULL ),
|
||||||
[RT_IDLM] = CP(NULL ),[RT_IMAD] = CP(NULL ),[RT_IMGS] = CP(NULL ),
|
[IDLM] = CP(NULL ),[IMAD] = CP(NULL ),[IMGS] = CP(NULL ),
|
||||||
[RT_INFO] = CP(NULL ),[RT_INGR] = CP(r_ingr),[RT_IPCT] = CP(NULL ),
|
[INFO] = CP(NULL ),[INGR] = CP(r_ingr),[IPCT] = CP(NULL ),
|
||||||
[RT_IPDS] = CP(NULL ),[RT_KEYM] = CP(r_keym),[RT_KYWD] = CP(NULL ),
|
[IPDS] = CP(NULL ),[KEYM] = CP(r_keym),[KYWD] = CP(NULL ),
|
||||||
[RT_LAND] = CP(NULL ),[RT_LCRT] = CP(NULL ),[RT_LCTN] = CP(NULL ),
|
[LAND] = CP(NULL ),[LCRT] = CP(NULL ),[LCTN] = CP(NULL ),
|
||||||
[RT_LGTM] = CP(NULL ),[RT_LIGH] = CP(r_ligh),[RT_LSCR] = CP(NULL ),
|
[LGTM] = CP(NULL ),[LIGH] = CP(r_ligh),[LSCR] = CP(NULL ),
|
||||||
[RT_LTEX] = CP(NULL ),[RT_LVLI] = CP(NULL ),[RT_LVLN] = CP(NULL ),
|
[LTEX] = CP(NULL ),[LVLI] = CP(NULL ),[LVLN] = CP(NULL ),
|
||||||
[RT_LVSP] = CP(NULL ),[RT_MATO] = CP(NULL ),[RT_MATT] = CP(NULL ),
|
[LVSP] = CP(NULL ),[MATO] = CP(NULL ),[MATT] = CP(NULL ),
|
||||||
[RT_MESG] = CP(NULL ),[RT_MGEF] = CP(NULL ),[RT_MISC] = CP(r_misc),
|
[MESG] = CP(NULL ),[MGEF] = CP(NULL ),[MISC] = CP(r_misc),
|
||||||
[RT_MOVT] = CP(NULL ),[RT_MSTT] = CP(r_mstt),[RT_MUSC] = CP(NULL ),
|
[MOVT] = CP(NULL ),[MSTT] = CP(r_mstt),[MUSC] = CP(NULL ),
|
||||||
[RT_MUST] = CP(NULL ),[RT_NAVI] = CP(NULL ),[RT_NAVM] = CP(NULL ),
|
[MUST] = CP(NULL ),[NAVI] = CP(NULL ),[NAVM] = CP(NULL ),
|
||||||
[RT_NOTE] = CP(NULL ),[RT_NPC_] = CP(NULL ),[RT_OTFT] = CP(NULL ),
|
[NOTE] = CP(NULL ),[NPC_] = CP(NULL ),[OTFT] = CP(NULL ),
|
||||||
[RT_PACK] = CP(NULL ),[RT_PERK] = CP(NULL ),[RT_PGRE] = CP(NULL ),
|
[PACK] = CP(NULL ),[PERK] = CP(NULL ),[PGRE] = CP(NULL ),
|
||||||
[RT_PHZD] = CP(NULL ),[RT_PROJ] = CP(NULL ),[RT_PWAT] = CP(NULL ),
|
[PHZD] = CP(NULL ),[PROJ] = CP(NULL ),[PWAT] = CP(NULL ),
|
||||||
[RT_QUST] = CP(NULL ),[RT_RACE] = CP(NULL ),[RT_REFR] = CP(NULL ),
|
[QUST] = CP(NULL ),[RACE] = CP(NULL ),[REFR] = CP(NULL ),
|
||||||
[RT_REGN] = CP(NULL ),[RT_RELA] = CP(NULL ),[RT_REVB] = CP(NULL ),
|
[REGN] = CP(NULL ),[RELA] = CP(NULL ),[REVB] = CP(NULL ),
|
||||||
[RT_RFCT] = CP(NULL ),[RT_RGDL] = CP(NULL ),[RT_SCEN] = CP(NULL ),
|
[RFCT] = CP(NULL ),[RGDL] = CP(NULL ),[SCEN] = CP(NULL ),
|
||||||
[RT_SCOL] = CP(NULL ),[RT_SCPT] = CP(NULL ),[RT_SCRL] = CP(r_scrl),
|
[SCOL] = CP(NULL ),[SCPT] = CP(NULL ),[SCRL] = CP(r_scrl),
|
||||||
[RT_SHOU] = CP(NULL ),[RT_SLGM] = CP(r_slgm),[RT_SMBN] = CP(NULL ),
|
[SHOU] = CP(NULL ),[SLGM] = CP(r_slgm),[SMBN] = CP(NULL ),
|
||||||
[RT_SMEN] = CP(NULL ),[RT_SMQN] = CP(NULL ),[RT_SNCT] = CP(NULL ),
|
[SMEN] = CP(NULL ),[SMQN] = CP(NULL ),[SNCT] = CP(NULL ),
|
||||||
[RT_SNDR] = CP(NULL ),[RT_SOPM] = CP(NULL ),[RT_SOUN] = CP(NULL ),
|
[SNDR] = CP(NULL ),[SOPM] = CP(NULL ),[SOUN] = CP(NULL ),
|
||||||
[RT_SPEL] = CP(NULL ),[RT_SPGD] = CP(NULL ),[RT_STAT] = CP(r_stat),
|
[SPEL] = CP(NULL ),[SPGD] = CP(NULL ),[STAT] = CP(r_stat),
|
||||||
[RT_TACT] = CP(NULL ),[RT_TES4] = CP(NULL ),[RT_TREE] = CP(r_tree),
|
[TACT] = CP(NULL ),[TES4] = CP(NULL ),[TREE] = CP(r_tree),
|
||||||
[RT_TXST] = CP(NULL ),[RT_VTYP] = CP(NULL ),[RT_WATR] = CP(NULL ),
|
[TXST] = CP(NULL ),[VTYP] = CP(NULL ),[WATR] = CP(NULL ),
|
||||||
[RT_WEAP] = CP(r_weap),[RT_WOOP] = CP(NULL ),[RT_WRLD] = CP(NULL ),
|
[WEAP] = CP(r_weap),[WOOP] = CP(NULL ),[WRLD] = CP(NULL ),
|
||||||
[RT_WTHR] = CP(NULL ),
|
[WTHR] = CP(NULL ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ char *walk_concat(char *data, size_t size, struct walker_callbacks cb) {
|
|||||||
const Type4 *type = (Type4 *)data;
|
const Type4 *type = (Type4 *)data;
|
||||||
|
|
||||||
// check valid type
|
// check valid type
|
||||||
assert(rt[rth2rt[rt_hash(type->uint)]] == type->uint);
|
assert(rt[rt_hash(type->uint)] == type->uint);
|
||||||
|
|
||||||
// only need to distinguish between groups and records
|
// only need to distinguish between groups and records
|
||||||
if (type->uint == rt[GRUP])
|
if (type->uint == rt[GRUP])
|
||||||
|
|||||||
Reference in New Issue
Block a user