Add project files.
This commit is contained in:
634
espReader/Derived.c
Normal file
634
espReader/Derived.c
Normal file
@@ -0,0 +1,634 @@
|
||||
#include "ESPReader.h"
|
||||
|
||||
#define LE(x) (((x >> 24) & 0x000000ffu) | ((x >> 8) & 0x0000ff00u) | \
|
||||
((x << 8) & 0x00ff0000u) | ((x << 24) & 0xff000000u))
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
// 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'),
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
// Non-REFR flags
|
||||
rfs_inner _achr = {
|
||||
[9] = "Starts Dead",
|
||||
[10] = "Persistent",
|
||||
[11] = "Initially Disabled",
|
||||
[25] = "No AI Acquire",
|
||||
[29] = "Don't Havok Settle",
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
rfs_inner _tact = {
|
||||
[9] = "Hidden From Local Map",
|
||||
[16] = "Random Anim Start",
|
||||
[17] = "Radio Station",
|
||||
};
|
||||
|
||||
rfs_inner _alch = {
|
||||
[29] = "Medicine",
|
||||
};
|
||||
|
||||
rfs_inner _ammo = {
|
||||
[2] = "Non-Playable",
|
||||
};
|
||||
|
||||
rfs_inner _anio = {
|
||||
[9] = "ANIO Unknown 9",
|
||||
};
|
||||
|
||||
rfs_inner _armo = {
|
||||
[2] = "Non-Playable",
|
||||
[6] = "Shield",
|
||||
[10] = "ARMO Unknown 10",
|
||||
[15] = "ARMO Unknown 15",
|
||||
};
|
||||
|
||||
#define REFERENCE_RECORD { \
|
||||
[7] = "Turn Off Fire", \
|
||||
[10] = "Persistent", \
|
||||
[11] = "Initially Disabled", \
|
||||
[28] = "Reflected by Auto Water", \
|
||||
[30] = "No Respawn", \
|
||||
}
|
||||
|
||||
rfs_inner _parw = REFERENCE_RECORD;
|
||||
rfs_inner _pbar = REFERENCE_RECORD;
|
||||
rfs_inner _pbea = REFERENCE_RECORD;
|
||||
rfs_inner _pcon = REFERENCE_RECORD;
|
||||
rfs_inner _pfla = REFERENCE_RECORD;
|
||||
rfs_inner _pgre = REFERENCE_RECORD;
|
||||
rfs_inner _phzd = REFERENCE_RECORD;
|
||||
rfs_inner _pmis = REFERENCE_RECORD;
|
||||
|
||||
#undef REFERENCE_RECORD
|
||||
|
||||
rfs_inner _cell = {
|
||||
[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",
|
||||
};
|
||||
|
||||
rfs_inner _csty = {
|
||||
[19] = "Allow Dual Wielding",
|
||||
};
|
||||
|
||||
rfs_inner _door = {
|
||||
[15] = "Has Distant LOD",
|
||||
[16] = "Random Anim Start",
|
||||
[23] = "Is Marker",
|
||||
};
|
||||
|
||||
rfs_inner _eyes = {
|
||||
[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",
|
||||
};
|
||||
|
||||
rfs_inner _glob = {
|
||||
[6] = "Constant",
|
||||
};
|
||||
|
||||
rfs_inner _hdpt = {
|
||||
[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",
|
||||
};
|
||||
|
||||
rfs_inner _idlm = {
|
||||
[29] = "Child Can Use",
|
||||
};
|
||||
|
||||
rfs_inner _slgm = {
|
||||
[17] = "Can Hold NPC Soul",
|
||||
};
|
||||
|
||||
rfs_inner _navm = {
|
||||
[18] = "Compressed",
|
||||
[26] = "AutoGen",
|
||||
[31] = "NavmeshGenCell",
|
||||
};
|
||||
|
||||
rfs_inner _perk = {
|
||||
[2] = "Non-Playable",
|
||||
};
|
||||
|
||||
rfs_inner _shou = {
|
||||
[7] = "Treat Spells As Powers",
|
||||
};
|
||||
|
||||
rfs_inner _rela = {
|
||||
[6] = "Secret",
|
||||
};
|
||||
|
||||
rfs_inner _clfm = {
|
||||
[2] = "Non-Playable",
|
||||
};
|
||||
|
||||
rfs_inner _info = {
|
||||
[13] = "Actor Changed",
|
||||
};
|
||||
|
||||
rfs_inner _keym = {
|
||||
[2] = "Non-Playable",
|
||||
};
|
||||
|
||||
rfs_inner _land = {
|
||||
[18] = "Compressed",
|
||||
};
|
||||
|
||||
rfs_inner _ligh = {
|
||||
[16] = "Random Anim Start",
|
||||
[17] = "Portal-strict",
|
||||
[25] = "Obstacle",
|
||||
};
|
||||
|
||||
rfs_inner _lscr = {
|
||||
[10] = "Displays In Main Menu",
|
||||
};
|
||||
|
||||
rfs_inner _misc = {
|
||||
[2] = "Non-Playable",
|
||||
};
|
||||
|
||||
rfs_inner _npc_ = {
|
||||
[10] = "NPC_ Unknown 10",
|
||||
[18] = "Compressed",
|
||||
[19] = "NPC_ Unknown 19",
|
||||
[29] = "Bleedout Override",
|
||||
};
|
||||
|
||||
rfs_inner _race = {
|
||||
[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",
|
||||
};
|
||||
|
||||
rfs_inner _regn = {
|
||||
[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",
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
rfs_inner _tree = {
|
||||
[15] = "Has Distant LOD",
|
||||
};
|
||||
|
||||
rfs_inner _weap = {
|
||||
[2] = "Non-Playable",
|
||||
};
|
||||
|
||||
rfs_inner _wrld = {
|
||||
[19] = "Can't Wait",
|
||||
};
|
||||
|
||||
rfs_inner *const rfs[RT_HASH_SIZE] = {
|
||||
[RT_AACT] = NULL, [RT_ACHR] = _achr, [RT_ACTI] = _acti,
|
||||
[RT_ADDN] = NULL, [RT_ALCH] = _alch, [RT_AMMO] = _ammo,
|
||||
[RT_ANIO] = _anio, [RT_APPA] = NULL, [RT_ARMA] = NULL,
|
||||
[RT_ARMO] = _armo, [RT_ARTO] = NULL, [RT_ASPC] = NULL,
|
||||
[RT_ASTP] = NULL, [RT_AVIF] = NULL, [RT_BOOK] = NULL,
|
||||
[RT_BPTD] = NULL, [RT_CAMS] = NULL, [RT_CELL] = _cell,
|
||||
[RT_CLAS] = NULL, [RT_CLDC] = NULL, [RT_CLFM] = _clfm,
|
||||
[RT_CLMT] = NULL, [RT_COBJ] = NULL, [RT_COLL] = NULL,
|
||||
[RT_CONT] = _cont, [RT_CPTH] = NULL, [RT_CSTY] = _csty,
|
||||
[RT_DEBR] = NULL, [RT_DIAL] = NULL, [RT_DLBR] = NULL,
|
||||
[RT_DLVW] = NULL, [RT_DOBJ] = NULL, [RT_DOOR] = _door,
|
||||
[RT_DUAL] = NULL, [RT_ECZN] = NULL, [RT_EFSH] = NULL,
|
||||
[RT_ENCH] = NULL, [RT_EQUP] = NULL, [RT_EXPL] = NULL,
|
||||
[RT_EYES] = _eyes, [RT_FACT] = NULL, [RT_FLOR] = NULL,
|
||||
[RT_FLST] = NULL, [RT_FSTP] = NULL, [RT_FSTS] = NULL,
|
||||
[RT_FURN] = _furn, [RT_GLOB] = _glob, [RT_GMST] = NULL,
|
||||
[RT_GRAS] = NULL, [RT_GRUP] = NULL, [RT_HAIR] = NULL,
|
||||
[RT_HAZD] = NULL, [RT_HDPT] = _hdpt, [RT_IDLE] = NULL,
|
||||
[RT_IDLM] = _idlm, [RT_IMAD] = NULL, [RT_IMGS] = NULL,
|
||||
[RT_INFO] = _info, [RT_INGR] = NULL, [RT_IPCT] = NULL,
|
||||
[RT_IPDS] = NULL, [RT_KEYM] = _keym, [RT_KYWD] = NULL,
|
||||
[RT_LAND] = _land, [RT_LCRT] = NULL, [RT_LCTN] = NULL,
|
||||
[RT_LGTM] = NULL, [RT_LIGH] = _ligh, [RT_LSCR] = _lscr,
|
||||
[RT_LTEX] = NULL, [RT_LVLI] = NULL, [RT_LVLN] = NULL,
|
||||
[RT_LVSP] = NULL, [RT_MATO] = NULL, [RT_MATT] = NULL,
|
||||
[RT_MESG] = NULL, [RT_MGEF] = NULL, [RT_MISC] = _misc,
|
||||
[RT_MOVT] = NULL, [RT_MSTT] = _mstt, [RT_MUSC] = NULL,
|
||||
[RT_MUST] = NULL, [RT_NAVI] = NULL, [RT_NAVM] = _navm,
|
||||
[RT_NOTE] = NULL, [RT_NPC_] = _npc_, [RT_OTFT] = NULL,
|
||||
[RT_PACK] = NULL, [RT_PERK] = _perk, [RT_PGRE] = _pgre,
|
||||
[RT_PHZD] = _phzd, [RT_PROJ] = NULL, [RT_PWAT] = NULL,
|
||||
[RT_QUST] = NULL, [RT_RACE] = _race, [RT_REFR] = _refr,
|
||||
[RT_REGN] = _regn, [RT_RELA] = _rela, [RT_REVB] = NULL,
|
||||
[RT_RFCT] = NULL, [RT_RGDL] = NULL, [RT_SCEN] = NULL,
|
||||
[RT_SCOL] = NULL, [RT_SCPT] = NULL, [RT_SCRL] = NULL,
|
||||
[RT_SHOU] = _shou, [RT_SLGM] = _slgm, [RT_SMBN] = NULL,
|
||||
[RT_SMEN] = NULL, [RT_SMQN] = NULL, [RT_SNCT] = NULL,
|
||||
[RT_SNDR] = NULL, [RT_SOPM] = NULL, [RT_SOUN] = NULL,
|
||||
[RT_SPEL] = NULL, [RT_SPGD] = NULL, [RT_STAT] = _stat,
|
||||
[RT_TACT] = _tact, [RT_TES4] = _tes4, [RT_TREE] = _tree,
|
||||
[RT_TXST] = NULL, [RT_VTYP] = NULL, [RT_WATR] = NULL,
|
||||
[RT_WEAP] = _weap, [RT_WOOP] = NULL, [RT_WRLD] = _wrld,
|
||||
[RT_WTHR] = NULL,
|
||||
};
|
||||
|
||||
// REFR flags depend on what its NAME field references
|
||||
#define REFR_GROUP1 { \
|
||||
[9] = "Hidden From Local Map", \
|
||||
[10] = "Persistent", \
|
||||
[11] = "Initially Disabled", \
|
||||
[13] = "Sky Marker", \
|
||||
[15] = "Visible When Distant", \
|
||||
[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_acti = REFR_GROUP1;
|
||||
rfs_inner _refr_stat = 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",
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
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",
|
||||
};
|
||||
|
||||
#define REFR_GROUP2 { \
|
||||
[10] = "Persistent", \
|
||||
[11] = "Initially Disabled", \
|
||||
[16] = "Is Full LOD", \
|
||||
[25] = "No AI Acquire", \
|
||||
[28] = "Reflected By Auto Water", \
|
||||
[29] = "Don't Havok Settle", \
|
||||
[30] = "No Respawn", \
|
||||
[31] = "Multibound", \
|
||||
}
|
||||
|
||||
rfs_inner _refr_alch = REFR_GROUP2;
|
||||
rfs_inner _refr_scrl = REFR_GROUP2;
|
||||
rfs_inner _refr_ammo = REFR_GROUP2;
|
||||
rfs_inner _refr_armo = REFR_GROUP2;
|
||||
rfs_inner _refr_ingr = REFR_GROUP2;
|
||||
rfs_inner _refr_keym = REFR_GROUP2;
|
||||
rfs_inner _refr_misc = REFR_GROUP2;
|
||||
rfs_inner _refr_slgm = REFR_GROUP2;
|
||||
rfs_inner _refr_weap = REFR_GROUP2;
|
||||
|
||||
rfs_inner *const rfs_refr[] = {
|
||||
[RT_AACT] = NULL ,[RT_ACHR] = NULL ,[RT_ACTI] = _refr_acti,
|
||||
[RT_ADDN] = _refr_addn,[RT_ALCH] = _refr_alch,[RT_AMMO] = _refr_ammo,
|
||||
[RT_ANIO] = NULL ,[RT_APPA] = NULL ,[RT_ARMA] = NULL ,
|
||||
[RT_ARMO] = _refr_armo,[RT_ARTO] = NULL ,[RT_ASPC] = NULL ,
|
||||
[RT_ASTP] = NULL ,[RT_AVIF] = NULL ,[RT_BOOK] = NULL ,
|
||||
[RT_BPTD] = NULL ,[RT_CAMS] = NULL ,[RT_CELL] = NULL ,
|
||||
[RT_CLAS] = NULL ,[RT_CLDC] = NULL ,[RT_CLFM] = NULL ,
|
||||
[RT_CLMT] = NULL ,[RT_COBJ] = NULL ,[RT_COLL] = NULL ,
|
||||
[RT_CONT] = _refr_cont,[RT_CPTH] = NULL ,[RT_CSTY] = NULL ,
|
||||
[RT_DEBR] = NULL ,[RT_DIAL] = NULL ,[RT_DLBR] = NULL ,
|
||||
[RT_DLVW] = NULL ,[RT_DOBJ] = NULL ,[RT_DOOR] = _refr_door,
|
||||
[RT_DUAL] = NULL ,[RT_ECZN] = NULL ,[RT_EFSH] = NULL ,
|
||||
[RT_ENCH] = NULL ,[RT_EQUP] = NULL ,[RT_EXPL] = NULL ,
|
||||
[RT_EYES] = NULL ,[RT_FACT] = NULL ,[RT_FLOR] = _refr_flor,
|
||||
[RT_FLST] = NULL ,[RT_FSTP] = NULL ,[RT_FSTS] = NULL ,
|
||||
[RT_FURN] = NULL ,[RT_GLOB] = NULL ,[RT_GMST] = NULL ,
|
||||
[RT_GRAS] = NULL ,[RT_GRUP] = NULL ,[RT_HAIR] = NULL ,
|
||||
[RT_HAZD] = NULL ,[RT_HDPT] = NULL ,[RT_IDLE] = NULL ,
|
||||
[RT_IDLM] = NULL ,[RT_IMAD] = NULL ,[RT_IMGS] = NULL ,
|
||||
[RT_INFO] = NULL ,[RT_INGR] = _refr_ingr,[RT_IPCT] = NULL ,
|
||||
[RT_IPDS] = NULL ,[RT_KEYM] = _refr_keym,[RT_KYWD] = NULL ,
|
||||
[RT_LAND] = NULL ,[RT_LCRT] = NULL ,[RT_LCTN] = NULL ,
|
||||
[RT_LGTM] = NULL ,[RT_LIGH] = _refr_ligh,[RT_LSCR] = NULL ,
|
||||
[RT_LTEX] = NULL ,[RT_LVLI] = NULL ,[RT_LVLN] = NULL ,
|
||||
[RT_LVSP] = NULL ,[RT_MATO] = NULL ,[RT_MATT] = NULL ,
|
||||
[RT_MESG] = NULL ,[RT_MGEF] = NULL ,[RT_MISC] = _refr_misc,
|
||||
[RT_MOVT] = NULL ,[RT_MSTT] = _refr_mstt,[RT_MUSC] = NULL ,
|
||||
[RT_MUST] = NULL ,[RT_NAVI] = NULL ,[RT_NAVM] = NULL ,
|
||||
[RT_NOTE] = NULL ,[RT_NPC_] = NULL ,[RT_OTFT] = NULL ,
|
||||
[RT_PACK] = NULL ,[RT_PERK] = NULL ,[RT_PGRE] = NULL ,
|
||||
[RT_PHZD] = NULL ,[RT_PROJ] = NULL ,[RT_PWAT] = NULL ,
|
||||
[RT_QUST] = NULL ,[RT_RACE] = NULL ,[RT_REFR] = NULL ,
|
||||
[RT_REGN] = NULL ,[RT_RELA] = NULL ,[RT_REVB] = NULL ,
|
||||
[RT_RFCT] = NULL ,[RT_RGDL] = NULL ,[RT_SCEN] = NULL ,
|
||||
[RT_SCOL] = NULL ,[RT_SCPT] = NULL ,[RT_SCRL] = _refr_scrl,
|
||||
[RT_SHOU] = NULL ,[RT_SLGM] = _refr_slgm,[RT_SMBN] = NULL ,
|
||||
[RT_SMEN] = NULL ,[RT_SMQN] = NULL ,[RT_SNCT] = NULL ,
|
||||
[RT_SNDR] = NULL ,[RT_SOPM] = NULL ,[RT_SOUN] = NULL ,
|
||||
[RT_SPEL] = NULL ,[RT_SPGD] = NULL ,[RT_STAT] = _refr_stat,
|
||||
[RT_TACT] = NULL ,[RT_TES4] = NULL ,[RT_TREE] = _refr_tree,
|
||||
[RT_TXST] = NULL ,[RT_VTYP] = NULL ,[RT_WATR] = NULL ,
|
||||
[RT_WEAP] = _refr_weap,[RT_WOOP] = NULL ,[RT_WRLD] = NULL ,
|
||||
[RT_WTHR] = NULL ,
|
||||
};
|
||||
|
||||
263
espReader/ESPReader.h
Normal file
263
espReader/ESPReader.h
Normal file
@@ -0,0 +1,263 @@
|
||||
#pragma once
|
||||
|
||||
/* For reading structured data out of Creation Engine esp/esm files.
|
||||
* Based on information from:
|
||||
* https://en.uesp.net/wiki/Skyrim_Mod:Mod_File_Format
|
||||
*
|
||||
* esp/esm files generally have a tree-like structure where:
|
||||
* - top level is a a TES4 record concatenated with each of the top-level groups
|
||||
* - groups contain a concatenation of 0 or more groups or records
|
||||
* - records contain a concatenation of 0 or more fields
|
||||
* - fields contain a structure of statically or dynamically sized data
|
||||
* - groups, records, and fields all have headers
|
||||
*
|
||||
* === NOTE ===
|
||||
* Assumptions:
|
||||
* - Little endian system
|
||||
* - Compiled with MSVC
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "msh.h"
|
||||
|
||||
// Guards for C++ usage
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RFS_INNER_SIZE 32
|
||||
|
||||
#define RT_SIZE 128
|
||||
|
||||
#define RT_HASH_SIZE 512
|
||||
#define RT_HASH_BITS 9
|
||||
#define RT_HASH_SEED 131261257
|
||||
|
||||
#define COMPRESSED_FLAG (((uint32_t)1) << 18)
|
||||
|
||||
#define GO_SIZE 118
|
||||
#define GTS_SIZE 10
|
||||
|
||||
|
||||
//
|
||||
// === FORWARD DEFS ===
|
||||
//
|
||||
|
||||
typedef union type4 Type4;
|
||||
typedef struct timestamp Timestamp;
|
||||
typedef const struct group Group;
|
||||
typedef const struct record Record;
|
||||
typedef const struct field Field;
|
||||
|
||||
//
|
||||
// === SIMPLE TYPES ===
|
||||
//
|
||||
|
||||
// Basic types
|
||||
typedef uint32_t formid;
|
||||
|
||||
// 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];
|
||||
|
||||
//
|
||||
// === ENUMS ===
|
||||
//
|
||||
|
||||
// Tag for generic node tagged union
|
||||
enum node_type { // NT_ prefix
|
||||
NT_GROUP,
|
||||
NT_RECORD,
|
||||
NT_FIELD
|
||||
};
|
||||
|
||||
// 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,
|
||||
};
|
||||
|
||||
// Enums of perfect hash values for
|
||||
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,
|
||||
};
|
||||
|
||||
// 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 ===
|
||||
//
|
||||
|
||||
// Generic node
|
||||
typedef const struct node Node;
|
||||
struct node {
|
||||
const union {
|
||||
Group *const group;
|
||||
Record *const record;
|
||||
Field *const field;
|
||||
};
|
||||
const char *const data;
|
||||
const enum node_type type;
|
||||
const uint32_t _pad;
|
||||
};
|
||||
|
||||
// calculated timestamp
|
||||
struct timestamp {
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
};
|
||||
|
||||
//
|
||||
// === BINARY DATA OVERLAYS ===
|
||||
//
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Group header overlay
|
||||
struct group {
|
||||
const Type4 grup; // always RT_GRUP
|
||||
const uint32_t size; // uncludes the 24 byte group header
|
||||
const union {
|
||||
const Type4 type; // this may be mangled and should not be relied on
|
||||
const formid formid;
|
||||
const int32_t number;
|
||||
const int16_t coord[2];
|
||||
} label; // access determined by the `type` below
|
||||
const int32_t type; // group_type enum
|
||||
const uint16_t timestamp;
|
||||
const uint16_t vcinfo;
|
||||
const uint32_t unknown;
|
||||
};
|
||||
|
||||
// Record header overlay
|
||||
struct record {
|
||||
const Type4 type;
|
||||
const uint32_t size;
|
||||
const uint32_t flags;
|
||||
const uint32_t formid;
|
||||
const uint16_t timestamp;
|
||||
const uint16_t vcinfo;
|
||||
const uint16_t version;
|
||||
const uint16_t unknown;
|
||||
};
|
||||
|
||||
// Field header overlay
|
||||
struct field {
|
||||
const Type4 type;
|
||||
const uint16_t size;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//
|
||||
// === LUTs ===
|
||||
//
|
||||
|
||||
// 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];
|
||||
|
||||
// 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];
|
||||
|
||||
// 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];
|
||||
|
||||
|
||||
//
|
||||
// === 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);
|
||||
}
|
||||
|
||||
// Walks the nodes of the esp/esm structured data at `data`
|
||||
void walk(const char *data, size_t size);
|
||||
|
||||
// End C++ guard
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
252
espReader/Reader.c
Normal file
252
espReader/Reader.c
Normal file
@@ -0,0 +1,252 @@
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <intrin.h>
|
||||
|
||||
#include "zlib.h"
|
||||
|
||||
#include "ESPReader.h"
|
||||
|
||||
//
|
||||
// === CONSTANTS ===
|
||||
//
|
||||
|
||||
// timestamp field access
|
||||
const uint16_t day_mask = 0x1F;
|
||||
const uint16_t month_mask = 0xF;
|
||||
const uint16_t year_mask = 0x7F;
|
||||
const int month_offset = 5;
|
||||
const int year_offset = 9;
|
||||
|
||||
//
|
||||
// === FORWARD DECLARATIONS ===
|
||||
//
|
||||
|
||||
void dynamic_asserts(void);
|
||||
|
||||
// tree walkers
|
||||
const char *walk_group(const char *data);
|
||||
const char *walk_unknown_data(const char *start, size_t size);
|
||||
const char *walk_record(const char *data);
|
||||
const char *walk_field(const char *data);
|
||||
|
||||
// header printers
|
||||
void print_group_header(Group *const header);
|
||||
void print_record_header(Record *const header);
|
||||
void print_field_header(Field *const header);
|
||||
|
||||
// print helpers
|
||||
void print_group_label(Group *const header);
|
||||
void print_record_flags(Record *const header);
|
||||
void print_timestamp(uint16_t ts);
|
||||
void print_type(Type4 type);
|
||||
void print_type4(Type4 val);
|
||||
|
||||
// utilities
|
||||
Timestamp convert_ts(uint16_t ts);
|
||||
|
||||
//
|
||||
// === FUNCTIONS ===
|
||||
//
|
||||
|
||||
void dynamic_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
|
||||
}
|
||||
|
||||
void walk(const char *data, size_t size) {
|
||||
// check assertions that cannot be checked at compile time
|
||||
dynamic_asserts();
|
||||
|
||||
// check that we are at the start of the file
|
||||
const Type4 type = *(const Type4 *)data;
|
||||
assert(type.uint == rt[TES4]);
|
||||
|
||||
const char *start = data;
|
||||
// walk the TES4 record
|
||||
data = walk_record(data);
|
||||
|
||||
data = walk_unknown_data(data, size - (size_t)(data - start));
|
||||
}
|
||||
|
||||
const char *walk_unknown_data(const char *data, size_t size) {
|
||||
|
||||
const char *end = data + size;
|
||||
while (data != end) {
|
||||
assert(data < end);
|
||||
|
||||
const Type4 *type = (Type4 *)data;
|
||||
|
||||
// check valid type
|
||||
assert(rt[rth2rt[rt_hash(type->uint)]] == type->uint);
|
||||
|
||||
if (type->uint == rt[GRUP])
|
||||
data = walk_group(data);
|
||||
else
|
||||
data = walk_record(data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
const char *walk_group(const char *data) {
|
||||
Group *const header = (Group *const)data;
|
||||
print_group_header(header);
|
||||
|
||||
// NB: group sizes include the header
|
||||
|
||||
const char *const start = data + sizeof(Group);
|
||||
const char *const end = data + header->size;
|
||||
|
||||
// walk through the groups/records inside the group
|
||||
data = walk_unknown_data(start, header->size);
|
||||
assert(data == end);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
const char *walk_record(const char *data) {
|
||||
Record *const header = (Record *const)data;
|
||||
assert(header->type.uint != rt[GRUP]);
|
||||
print_record_header(header);
|
||||
|
||||
// update data location to next node and return
|
||||
// record sizes do not include the header
|
||||
data += sizeof(Record) + header->size;
|
||||
return data;
|
||||
}
|
||||
|
||||
const char *walk_field(const char *data) {
|
||||
Field *const header = (Field *const)data;
|
||||
print_field_header(header);
|
||||
|
||||
// update data location to next node and return
|
||||
// field sizes do not include the header
|
||||
data += sizeof(Field) + header->size;
|
||||
return data;
|
||||
}
|
||||
|
||||
void print_group_header(Group *const 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);
|
||||
}
|
||||
|
||||
void print_record_header(Record *const 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);
|
||||
}
|
||||
|
||||
void print_field_header(Field *const header) {
|
||||
printf("--- HEADER: FIELD ---\n");
|
||||
print_type(header->type);
|
||||
printf("Size: %u\n", header->size);
|
||||
}
|
||||
|
||||
void print_group_label(Group *const 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");
|
||||
}
|
||||
|
||||
void print_record_flags(Record *const header) {
|
||||
printf("Flags:\n");
|
||||
|
||||
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
|
||||
size_t highest = 31 - __lzcnt(flags);
|
||||
const char *const str = (*flag_lut)[highest];
|
||||
if (str) {
|
||||
printf(" - %s\n", str);
|
||||
flags -= ((uint32_t)1) << highest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void print_type(Type4 type) {
|
||||
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]);
|
||||
}
|
||||
|
||||
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 = 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 };
|
||||
}
|
||||
|
||||
158
espReader/espReader.vcxproj
Normal file
158
espReader/espReader.vcxproj
Normal file
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{c403cba2-86ae-4442-87cf-26b283a549c2}</ProjectGuid>
|
||||
<RootNamespace>espReader</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>ESPReader</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<AdditionalIncludeDirectories>..\zlib</AdditionalIncludeDirectories>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<AdditionalIncludeDirectories>..\zlib</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ESPReader.h" />
|
||||
<ClInclude Include="msh.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Derived.c" />
|
||||
<ClCompile Include="Reader.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\zlib\contrib\vstudio\vc14\zlibstat.vcxproj">
|
||||
<Project>{745dec58-ebb3-47a9-a9b8-4c6627c01bf8}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
33
espReader/espReader.vcxproj.filters
Normal file
33
espReader/espReader.vcxproj.filters
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ESPReader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="msh.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Reader.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Derived.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
19
espReader/msh.h
Normal file
19
espReader/msh.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CAT2(x, y) x##y
|
||||
#define CAT(x, y) CAT2(x, y)
|
||||
|
||||
// hashes in universally into l (<= num bits in TYPE) bits using odd seed
|
||||
#define MSH(TYPE) \
|
||||
inline TYPE CAT(TYPE, _msh) (TYPE in, TYPE bits, TYPE seed) { \
|
||||
return (seed * in) >> ((sizeof( TYPE ) * 8) - bits); \
|
||||
}
|
||||
|
||||
// hashes for all of the standard sizes
|
||||
MSH(uint8_t)
|
||||
MSH(uint16_t)
|
||||
MSH(uint32_t)
|
||||
MSH(uint64_t)
|
||||
|
||||
Reference in New Issue
Block a user