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:
2022-09-07 10:09:25 +10:00
parent 86d2c1a002
commit de1a27e337
4 changed files with 140 additions and 102 deletions

View File

@@ -31,8 +31,10 @@
extern "C" {
#endif
// Flag fields are 32 bits, so there are 32 flags
#define RFS_INNER_SIZE 32
// There are 127 record types + a NONE type used for sanity checks
#define RT_SIZE 128
/* 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_SEED 131261257
// Used for identifying records that are compressed
#define COMPRESSED_FLAG (((uint32_t)1) << 18)
// Top level group order, there are 118 top level groups
#define GO_SIZE 118
// There are 10 Group Types
#define GTS_SIZE 10
@@ -68,15 +73,17 @@ extern "C" {
// === 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;
// char[4] with uint32_t access
// char[4] with uint32_t access, used to access fourcc values
union type4 {
char bytes[4];
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];
//
@@ -84,7 +91,7 @@ extern "C" {
//
// Tag for generic node tagged union
enum node_type { // NT_ prefix
enum node_type {
NT_GROUP,
NT_RECORD,
};
@@ -116,8 +123,8 @@ extern "C" {
WTHR,
};
// GRUP type values
enum group_type { // GT_ prefix
// Group type enum
enum group_type {
GT_TOP = 0,
GT_WORLD_CHILDREN = 1,
GT_INTERIOR_CELL_BLOCK = 2,
@@ -134,7 +141,7 @@ extern "C" {
// === COMPOSITE TYPES ===
//
// Generic node
// Generic node in the esp/esm tree
typedef struct node Node;
struct node {
union {
@@ -146,13 +153,24 @@ extern "C" {
uint32_t _pad;
};
// calculated timestamp
// Used for passing around parsed timestamps
struct timestamp {
uint16_t year;
uint8_t month;
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 {
void (*pre)(Node n, void *data, void **carry_out);
void (*post)(Node n, void *data, void **carry_in);
@@ -215,9 +233,8 @@ extern "C" {
// 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[RT_SIZE];
extern rfs_inner *const rfs_refr[RT_SIZE];
// Expected (probably) order of top level groups in an esp/esm
extern const enum record_type group_order[GO_SIZE];
@@ -229,9 +246,9 @@ extern "C" {
// === 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) {
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