1102 lines
No EOL
35 KiB
JSON
1102 lines
No EOL
35 KiB
JSON
{
|
|
"_schema": "facts about Sword of the Stars.exe (GOG 1.8.1, build 19833). rva = file address - 0x00400000. Runtime address = GetModuleHandle(NULL) + rva (exe is ASLR-relocated). Prototypes marked 'unverified' are best current reading; a Ghidra round confirms them.",
|
|
"image_base": "0x00400000",
|
|
"entries": [
|
|
{
|
|
"name": "Mars_Application_Initialize",
|
|
"addr": "0x008a0e50",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (Application* this, AppStartup* startup) /* ONE stack arg, RET 4, returns AL; EDX unused. startup = {HINSTANCE hInst; std::vector<std::string> args; ...; int nShow; const char* wndClass; int iconId} built in WinMain */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#application"
|
|
},
|
|
{
|
|
"name": "Mars_Application_Run",
|
|
"addr": "0x0089f5b0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (Application* this) /* no stack args, plain RET, EDX not an input, EAX = last PumpMessages result (ignore) */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#application"
|
|
},
|
|
{
|
|
"name": "Process_PinAffinity",
|
|
"addr": "0x0089ee70",
|
|
"convention": "cdecl",
|
|
"prototype": "void (int coreIndex)",
|
|
"status": "unverified",
|
|
"source": "findings/objects/ghidra-recon.md"
|
|
},
|
|
{
|
|
"name": "CfgVar_RegisterKey",
|
|
"addr": "0x008b76a0",
|
|
"convention": "thiscall",
|
|
"prototype": "GlobalConst* (GlobalConst* this, void* storage, const char* key, ParseFn parser, const char* file) // RET 0x10",
|
|
"status": "verified",
|
|
"source": "findings/subsystems/loader-prototypes.md"
|
|
},
|
|
{
|
|
"name": "DemoApp_OnTick",
|
|
"addr": "0x0089a640",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (DemoApp* this) /* no stack args; returns 0 when quitting (this+0x1b2), else 1 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#application"
|
|
},
|
|
{
|
|
"name": "StrategyClient_EndTurn",
|
|
"addr": "0x00783be0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StrategyClient* this)",
|
|
"status": "unverified",
|
|
"source": "findings/control-flow/turn-spine.md"
|
|
},
|
|
{
|
|
"name": "StrategyServer_BeginProcessTurn",
|
|
"addr": "0x007d98e0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StrategyServer* this)",
|
|
"status": "unverified",
|
|
"source": "findings/control-flow/turn-spine.md"
|
|
},
|
|
{
|
|
"name": "StrategyServer_ProcessTurn",
|
|
"addr": "0x007dc6c0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StrategyServer* this)",
|
|
"status": "unverified",
|
|
"source": "findings/control-flow/turn-spine.md"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_ComputeBudget",
|
|
"addr": "0x00863030",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this, int out[25], bool projected)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q5"
|
|
},
|
|
{
|
|
"name": "TechTree_ProcessResearch",
|
|
"addr": "0x005876c0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (TechTree* this, ?, vector<{node,int}>* alloc, int* overbudget) /* decay loop hits current target */",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q8"
|
|
},
|
|
{
|
|
"name": "ServerSystem_Read",
|
|
"addr": "0x0075d4b0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerSystem* this /*+8 IStreamable*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "ServerSystem_Write",
|
|
"addr": "0x00749630",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerSystem* this /*+8*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_Read",
|
|
"addr": "0x008804d0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this /*+0x3a0*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_Write",
|
|
"addr": "0x008563e0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this /*+0x3a0*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "StarFleet_Read",
|
|
"addr": "0x00702470",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StarFleet* this /*+8*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "StarFleet_Write",
|
|
"addr": "0x00701070",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StarFleet* this /*+8*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "StarShip_Read",
|
|
"addr": "0x00853fa0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StarShip* this /*+8*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "StarShip_Write",
|
|
"addr": "0x008291f0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StarShip* this /*+8*/, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "StrategyServer_Read",
|
|
"addr": "0x007d27a0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StrategyServer* this, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "StrategyServer_Write",
|
|
"addr": "0x0079fa70",
|
|
"convention": "thiscall",
|
|
"prototype": "void (StrategyServer* this, Stream* s)",
|
|
"status": "verified-by-save",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "Stream_WriteNetworkObjectId",
|
|
"addr": "0x00816490",
|
|
"convention": "thiscall",
|
|
"prototype": "void (Stream* this, const char* tag, NetworkObject* obj)",
|
|
"status": "unverified",
|
|
"source": "findings/objects/struct-recovery.md"
|
|
},
|
|
{
|
|
"name": "RNG_Twist",
|
|
"addr": "0x00426e00",
|
|
"convention": "thiscall",
|
|
"prototype": "void (RNG* this) // this in ECX, no stack args, RET 0; 227/396 split",
|
|
"status": "verified",
|
|
"source": "own Ghidra pass 2026-09-08 (RngSig)"
|
|
},
|
|
{
|
|
"name": "RNG_Seed",
|
|
"addr": "0x0049fdf0",
|
|
"convention": "thiscall",
|
|
"prototype": "RNG* (RNG* this, uint32_t seed) // RET 4; MT19937 init mt[i]=(mt[i-1]^(mt[i-1]>>30))*0x6c078965+i for i=1..623, then twists. this: vftable@0, mt[624]@+4, left@+0x9c4",
|
|
"status": "verified",
|
|
"source": "own Ghidra pass 2026-09-08 (RngSig)"
|
|
},
|
|
{
|
|
"name": "RNG_NextFloat",
|
|
"addr": "0x0047d830",
|
|
"convention": "thiscall",
|
|
"prototype": "float (RNG* this) // returns via x87 (float10 in decompile) -- FLOAT PARITY RISK; lazy twist: if (left==0) Twist()",
|
|
"status": "verified",
|
|
"source": "own Ghidra pass 2026-09-08 (RngSig)"
|
|
},
|
|
{
|
|
"name": "RNG_NextInt",
|
|
"addr": "0x004271c0",
|
|
"convention": "thiscall",
|
|
"prototype": "uint32_t (RNG* this)",
|
|
"status": "unverified",
|
|
"source": "findings/subsystems/strategic-turn-internals.md#rng"
|
|
},
|
|
{
|
|
"name": "Mars_Application_MountModules",
|
|
"addr": "0x008a0a20",
|
|
"convention": "cdecl",
|
|
"prototype": "void (void) /* sots.ini [Modules] Mount<N> -> gobio::Init */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "Game_GetDefaultMounts",
|
|
"addr": "0x008991c0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (int* count, const char*** table) /* count 3 @0x00b2d514, table @0x00a35e98 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ctor",
|
|
"addr": "0x008b76a0",
|
|
"convention": "thiscall",
|
|
"prototype": "GlobalConst* (GlobalConst* this, void* storage, const char* key, GlobalConstParseFn parser, const char* file) /* RET 0x10; static-init stub call. GlobalConst 0x10 bytes: {+0 void* storage (int/float/float[4]), +4 const char* key, +8 parser, +c const char* file} */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConst_Register",
|
|
"addr": "0x008b7610",
|
|
"convention": "cdecl",
|
|
"prototype": "void (GlobalConst* g)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseInt",
|
|
"addr": "0x008b7000",
|
|
"convention": "cdecl",
|
|
"prototype": "void (int* storage, const char* text)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseFloat",
|
|
"addr": "0x008b7020",
|
|
"convention": "cdecl",
|
|
"prototype": "void (float* storage, const char* text)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseFloatScaled",
|
|
"addr": "0x008b70e0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (float* storage, const char* text) /* sscanf(%f) into *storage, then *storage = (float)((double)*storage * *(double*)0x00af5210) */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseColour",
|
|
"addr": "0x008b7110",
|
|
"convention": "cdecl",
|
|
"prototype": "void (float rgba[4], const char* text) /* '%d %d %d %d', defaults 255, /255, clamp 0..1 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseRect",
|
|
"addr": "0x008b7040",
|
|
"convention": "cdecl",
|
|
"prototype": "void (int rect[4], const char* text) /* '%d %d %d %d' (x y w h); 2 keys (COMBATSETUP_CARD_*_RECT); layout inferred from the M1 trace, int vs float unconfirmed */",
|
|
"status": "verified-by-trace",
|
|
"source": "sots-engine docs/M1.md"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseVec3",
|
|
"addr": "0x008b7080",
|
|
"convention": "cdecl",
|
|
"prototype": "void (float xyz[3], const char* text) /* '%f %f %f'; 5 keys (HIVER_SPAWN_*_GATE_HEIGHT / _SHIP_OFFSET ...); inferred from the M1 trace */",
|
|
"status": "verified-by-trace",
|
|
"source": "sots-engine docs/M1.md"
|
|
},
|
|
{
|
|
"name": "GlobalConst_ParseString",
|
|
"addr": "0x008b7670",
|
|
"convention": "cdecl",
|
|
"prototype": "void (std::string* storage, const char* text) /* *storage = text; MSVC2010 std::string 0x18 bytes {+0 char buf[16] | char* ptr when capacity > 15, +0x10 size, +0x14 capacity}; 146 keys (*_NAME, *_SOUND, *_TEXTURENAME, DERELICT_SECTION_nn ...); seen in the M1 trace */",
|
|
"status": "verified-by-trace",
|
|
"source": "sots-engine docs/M1.md"
|
|
},
|
|
{
|
|
"name": "GlobalConsts_LoadAll",
|
|
"addr": "0x008b76d0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (void) /* called once from Application::Initialize; sets g_GlobalConstsLoaded */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "GlobalConsts_LoadFile",
|
|
"addr": "0x008b73c0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (const char* file, GlobalConstMap* consts) /* consts = std::map<const char*,GlobalConst*,stricmp> of the keys registered for this file; MSVC2010 layout: map {+4 head node, +8 size}; node {+0 left, +4 parent, +8 right, +0xc const char* key, +0x10 GlobalConst*, +0x14 color, +0x15 isnil}; head: isnil=1, parent=root. Consumed keys are erased from the map. Hook this for the file-level read */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "g_GlobalConstsLoaded",
|
|
"addr": "0x00b2d740",
|
|
"convention": "data",
|
|
"prototype": "bool",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "g_GlobalConstRegistry",
|
|
"addr": "0x00b2d744",
|
|
"convention": "data",
|
|
"prototype": "std::map<const char*,GlobalConst*,stricmp_less> /* +4 (0x00b2d748) = header node pointer */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "g_GlobalConstFloatScale",
|
|
"addr": "0x00af5210",
|
|
"convention": "data",
|
|
"prototype": "double /* pi/180 as a DOUBLE (0x3f91df46a2529d39); GlobalConst_ParseFloatScaled does float word *= this in x87 and stores float */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m1"
|
|
},
|
|
{
|
|
"name": "Script_ctor",
|
|
"addr": "0x008cd700",
|
|
"convention": "thiscall",
|
|
"prototype": "Script* (Script* this) /* sizeof(Script) = 0x28 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_dtor",
|
|
"addr": "0x008cd720",
|
|
"convention": "thiscall",
|
|
"prototype": "void (Script* this)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_Open",
|
|
"addr": "0x008cd7d0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (Script* this, const char* path) /* gobio::ReadFile into this->buf */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_Close",
|
|
"addr": "0x008cd6c0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (Script* this)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_ReadToken",
|
|
"addr": "0x008cd2f0",
|
|
"convention": "thiscall",
|
|
"prototype": "int (Script* this, char* out, uint outMax) /* 0 token, 1 no buffer/past end, 2 reached end */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_Next",
|
|
"addr": "0x008cd3e0",
|
|
"convention": "thiscall",
|
|
"prototype": "int (Script* this, ScriptToken* tok) /* tok: {int type; char key[1024]; char value[1024]}; type 1 kv, 2 block open, 3 '}' */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_SkipBlock",
|
|
"addr": "0x008cd4b0",
|
|
"convention": "thiscall",
|
|
"prototype": "int (Script* this, int depth) /* 0 ok, nonzero EOF */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Script_ScanToken",
|
|
"addr": "0x008cd1f0",
|
|
"convention": "custom",
|
|
"prototype": "/* EAX=cursor, ECX="edFlag, EDX=out; stack: end, outEnd, &len \u2014 internal, do not hook */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "ConfigParser_ParseFile",
|
|
"addr": "0x008cd820",
|
|
"convention": "cdecl",
|
|
"prototype": "void (IConfigCallback* cb, const char* path, const char* blockName, bool* found) /* cb->vft[1](Script*) per matching block */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "RefCounted_Release",
|
|
"addr": "0x008a7230",
|
|
"convention": "fastcall",
|
|
"prototype": "int (IBuffer* obj) /* ECX=obj; --refcount, vft[0](1) at 0 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "WeaponDictionary_Init",
|
|
"addr": "0x0059a4c0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (WeaponDictionary* this) /* reads Weapons/_weapons.txt manifest */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "WeaponDictionary_LoadWeapon",
|
|
"addr": "0x0059a230",
|
|
"convention": "thiscall",
|
|
"prototype": "void (WeaponDictionary* this, const char* path, int id, WeaponDef** out)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "WeaponDictionary_FindByName",
|
|
"addr": "0x00590a10",
|
|
"convention": "thiscall",
|
|
"prototype": "WeaponDef* (WeaponDictionary* this, const char* name) /* _stricmp over def->name @+0x40 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "WeaponDictionary_FindByNameSorted",
|
|
"addr": "0x00591e30",
|
|
"convention": "thiscall",
|
|
"prototype": "WeaponDef* (WeaponDictionary* this, const char* name) /* 'Weapon not found: \"%s\" - Was it added to the index file?' */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "WeaponDef_ctor",
|
|
"addr": "0x00598a20",
|
|
"convention": "thiscall",
|
|
"prototype": "WeaponDef* (WeaponDef* this, int index, int id, const char* path) /* sizeof 0x278 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "WeaponDef_ParseScript",
|
|
"addr": "0x00599070",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (WeaponDef* this, Script* script, int* rc, TechTree* tree)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "SectionDictionary_ctor",
|
|
"addr": "0x00576f40",
|
|
"convention": "thiscall",
|
|
"prototype": "SectionDictionary* (SectionDictionary* this, TechTree* tree) /* reads Species/<Race>/_shipsections.txt for species 0..6 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "SectionDictionary_LoadSection",
|
|
"addr": "0x00576cd0",
|
|
"convention": "thiscall",
|
|
"prototype": "SectionDef* (SectionDictionary* this, const char* path, int species, int id)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "SectionDef_ctor",
|
|
"addr": "0x00574020",
|
|
"convention": "thiscall",
|
|
"prototype": "SectionDef* (SectionDef* this, int index, int species, int id) /* sizeof 0x3d8 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "SectionDef_ParseScript",
|
|
"addr": "0x005744e0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (SectionDef* this, Script* script, int* rc, TechTree* tree)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "Species_GetDirName",
|
|
"addr": "0x00545ec0",
|
|
"convention": "cdecl",
|
|
"prototype": "const char* (uint species)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "MasterTechTree_ctor",
|
|
"addr": "0x0058b870",
|
|
"convention": "thiscall",
|
|
"prototype": "MasterTechTree* (MasterTechTree* this) /* TechTree/MasterTechList.tech */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "MasterTechTree_LoadTechFile",
|
|
"addr": "0x0058b770",
|
|
"convention": "thiscall",
|
|
"prototype": "void (MasterTechTree* this, const char* path, int flag)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "MasterTechTree_ParseTech",
|
|
"addr": "0x0058b050",
|
|
"convention": "thiscall",
|
|
"prototype": "void (MasterTechTree* this, Script* script, int flag) /* one tech{} block */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m3"
|
|
},
|
|
{
|
|
"name": "DemoApp_LoadGameData",
|
|
"addr": "0x00899280",
|
|
"convention": "thiscall",
|
|
"prototype": "void (DemoApp* this) /* MasterTechTree -> +0x110, WeaponDictionary -> +0x118, SectionDictionary -> +0x114 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "DemoApp_EnsureGameData",
|
|
"addr": "0x00899870",
|
|
"convention": "thiscall",
|
|
"prototype": "void (DemoApp* this) /* once, from OnTick when this+0x10c is set */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m2"
|
|
},
|
|
{
|
|
"name": "gobio_Init",
|
|
"addr": "0x008d7010",
|
|
"convention": "cdecl",
|
|
"prototype": "void (std::vector<std::string>* mountPaths)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_FileSystemSet_ctor",
|
|
"addr": "0x008d6d60",
|
|
"convention": "thiscall",
|
|
"prototype": "FileSystemSet* (FileSystemSet* this, std::vector<std::string>* mounts)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_FileSystemSet_Open",
|
|
"addr": "0x008d5060",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (FileSystemSet* this, const char* path)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_FileSystemSet_ListFiles",
|
|
"addr": "0x008d7090",
|
|
"convention": "thiscall",
|
|
"prototype": "void (FileSystemSet* this, const char* pattern, std::vector<std::string>* out)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_ReadFile",
|
|
"addr": "0x008d5140",
|
|
"convention": "cdecl",
|
|
"prototype": "bool (const char* path, IBuffer** out) /* whole file by relative path; THE hook point for M4 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Open",
|
|
"addr": "0x008d50d0",
|
|
"convention": "cdecl",
|
|
"prototype": "bool (const char* path)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Close",
|
|
"addr": "0x008d4d20",
|
|
"convention": "cdecl",
|
|
"prototype": "void (void)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Size",
|
|
"addr": "0x008d4d50",
|
|
"convention": "cdecl",
|
|
"prototype": "uint (void)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Read",
|
|
"addr": "0x008d4d80",
|
|
"convention": "cdecl",
|
|
"prototype": "uint (void* dst, uint n)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Exists",
|
|
"addr": "0x008d50f0",
|
|
"convention": "cdecl",
|
|
"prototype": "bool (const char* path)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_ListFiles",
|
|
"addr": "0x008d71d0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (const char* pattern, std::vector<std::string>* out)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Buffer_Create",
|
|
"addr": "0x008d4c90",
|
|
"convention": "custom",
|
|
"prototype": "/* size in EBX, IBuffer** out on stack \u2014 internal, do not hook */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Buffer_Data",
|
|
"addr": "0x00682d50",
|
|
"convention": "thiscall",
|
|
"prototype": "void* (IBuffer* this) /* vft[1] and vft[2]; = this+8 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_Buffer_Size",
|
|
"addr": "0x008d4c80",
|
|
"convention": "thiscall",
|
|
"prototype": "uint (IBuffer* this) /* vft[3]; = this+0xc */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_NativeFileSystem_ctor",
|
|
"addr": "0x008d57a0",
|
|
"convention": "thiscall",
|
|
"prototype": "NativeFileSystem* (NativeFileSystem* this, const char* root) /* sizeof 0x28; vtable 0x00a398ac */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_NativeFileSystem_Open",
|
|
"addr": "0x008d4ef0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (NativeFileSystem* this, const char* path) /* vft[1] fopen(root+path,'rb') */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_NativeFileSystem_Read",
|
|
"addr": "0x008d4c30",
|
|
"convention": "thiscall",
|
|
"prototype": "uint (NativeFileSystem* this, void* dst, uint n) /* vft[4] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_ZipFileSystem_ctor",
|
|
"addr": "0x008d6c40",
|
|
"convention": "thiscall",
|
|
"prototype": "ZipFileSystem* (ZipFileSystem* this, const char* zipPath) /* sizeof 0x34; vtable 0x00a39934 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_ZipFileSystem_Open",
|
|
"addr": "0x008d56a0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (ZipFileSystem* this, const char* path) /* vft[1]; case- and slash-insensitive */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "gobio_ZipFileSystem_Read",
|
|
"addr": "0x008d4b40",
|
|
"convention": "thiscall",
|
|
"prototype": "uint (ZipFileSystem* this, void* dst, uint n) /* vft[4] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "g_gobio",
|
|
"addr": "0x00b2e270",
|
|
"convention": "data",
|
|
"prototype": "FileSystemSet* /* -> 0x00b2e274 after gobio::Init */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "g_DefaultMountTable",
|
|
"addr": "0x00a35e98",
|
|
"convention": "data",
|
|
"prototype": "const char*[3] /* used when sots.ini has no [Modules] Mount<N>; contains sots_local_en.gob, sots.gob */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#m4"
|
|
},
|
|
{
|
|
"name": "Stream_OpenFile",
|
|
"addr": "0x008cfcb0",
|
|
"convention": "cdecl",
|
|
"prototype": "Stream* (const char* path) /* sniffs 'TXT' magic, returns a TextFileStream (0x420 bytes) opened for read */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_ctor",
|
|
"addr": "0x0091e460",
|
|
"convention": "thiscall",
|
|
"prototype": "TextFileStream* (TextFileStream* this) /* vtable 0x00a428c0 */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_Open",
|
|
"addr": "0x008cfb90",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (TextFileStream* this, const char* path, int mode /*1*/)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "FileStream_ReadLine",
|
|
"addr": "0x008cfa30",
|
|
"convention": "thiscall",
|
|
"prototype": "uint (Stream* this, char* out, int max)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_MatchLabel",
|
|
"addr": "0x0091e760",
|
|
"convention": "thiscall",
|
|
"prototype": "const char* (TextFileStream* this, const char* line, const char* label) /* NULL on END/mismatch */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_ReadString",
|
|
"addr": "0x0091ec90",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (TextFileStream* this, const char* label, char* out, int outMax) /* vft[1] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_ReadBool",
|
|
"addr": "0x0091eba0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (TextFileStream* this, const char* label, bool* out) /* vft[2] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_ReadFloat",
|
|
"addr": "0x0091eb30",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (TextFileStream* this, const char* label, float* out) /* vft[3] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_ReadInt",
|
|
"addr": "0x0091eab0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (TextFileStream* this, const char* label, int* out, int dflt) /* vft[4] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "TextFileStream_ReadNested",
|
|
"addr": "0x0091e8e0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (TextFileStream* this, const char* label, IStreamable* obj /*NULL=skip*/) /* vft[5]; BEGIN..END */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "ParticleSystem_Read",
|
|
"addr": "0x008db650",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ParticleSystem* this, Stream* s) /* .effect body */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "ParticleSystem_Write",
|
|
"addr": "0x008dad60",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ParticleSystem* this, Stream* s)",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "EffectDictionary_Load",
|
|
"addr": "0x008b42b0",
|
|
"convention": "thiscall",
|
|
"prototype": "void* (EffectDictionary* this, const char* name) /* 'effects/' + name; Stream::OpenFile; 0x1c0-byte effect */",
|
|
"status": "unverified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "Stream_ReadString",
|
|
"addr": "0x008b9d90",
|
|
"convention": "cdecl",
|
|
"prototype": "void (Stream* s, const char* label, std::string* out, int flag) /* wrapper over vft[1] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "Stream_ReadInt",
|
|
"addr": "0x008b9d20",
|
|
"convention": "cdecl",
|
|
"prototype": "void (Stream* s, const char* label, int* out, int dflt) /* wrapper over vft[4] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "Stream_ReadBool",
|
|
"addr": "0x008b9c00",
|
|
"convention": "cdecl",
|
|
"prototype": "void (Stream* s, const char* label, bool* out) /* wrapper over vft[2] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "Stream_ReadFloat",
|
|
"addr": "0x008b9bc0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (Stream* s, const char* label, float* out, int flag) /* wrapper over vft[3] */",
|
|
"status": "verified",
|
|
"source": "handoff/loader-prototypes.md#effect"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_OnTechResearched",
|
|
"addr": "0x00891790",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this, TechDef* def, bool silent) /* vft slot 4 of 0x00a327a4; hard-coded tech effects */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
},
|
|
{
|
|
"name": "MasterTechTree_IsTech",
|
|
"addr": "0x0057d5d0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (MasterTechTree* this, TechDef* def, int techId) /* techId = 10000+index into g_TechIdNames; 0xc5 = none */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "MasterTechTree_GetTechDef",
|
|
"addr": "0x0057d610",
|
|
"convention": "thiscall",
|
|
"prototype": "TechDef* (MasterTechTree* this, int techId)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "TechTree_HasResearched",
|
|
"addr": "0x0057d810",
|
|
"convention": "thiscall",
|
|
"prototype": "bool (TechTree* this, int techId)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "MasterTechTree_ResolveTechIds",
|
|
"addr": "0x00581c10",
|
|
"convention": "thiscall",
|
|
"prototype": "void (MasterTechTree* this) /* fills TechDef*[196] at this+0 from g_TechIdNames */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "IsCombatTechName",
|
|
"addr": "0x006965c0",
|
|
"convention": "cdecl",
|
|
"prototype": "int (std::string* name) /* membership in g_CombatTechNames (116) */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_RebuildSpeciesTechFlags",
|
|
"addr": "0x0082bf10",
|
|
"convention": "fastcall",
|
|
"prototype": "void (ServerPlayer* this) /* flags[7] at +0x348 from SpeciesDef xnc tech ids */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_ApplyAITechBonus",
|
|
"addr": "0x0080e330",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this, TechDef* def)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_SetAIBenefit",
|
|
"addr": "0x008186b0",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this, bool on)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
},
|
|
{
|
|
"name": "TechDef_GetPlagueCureMask",
|
|
"addr": "0x00537240",
|
|
"convention": "cdecl",
|
|
"prototype": "bool (TechDef* def, uint* maskOut)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
},
|
|
{
|
|
"name": "ComputeTechBitmasks",
|
|
"addr": "0x004d7960",
|
|
"convention": "cdecl",
|
|
"prototype": "uint* (uint out[2], TechTree* tree) /* EBX-passed tree in caller; tables 0x00adf378 / 0x00adf478 */",
|
|
"status": "unverified",
|
|
"source": "handoff/tech-effects.md#3"
|
|
},
|
|
{
|
|
"name": "SpeciesDef_Get",
|
|
"addr": "0x00545cc0",
|
|
"convention": "cdecl",
|
|
"prototype": "SpeciesDef* (uint species) /* 0x00b10a00 + i*0x184 */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#4"
|
|
},
|
|
{
|
|
"name": "SpeciesDef_InitTable",
|
|
"addr": "0x005453a0",
|
|
"convention": "cdecl",
|
|
"prototype": "void (void)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#4"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_UpdateBankruptcyLimits",
|
|
"addr": "0x00818600",
|
|
"convention": "fastcall",
|
|
"prototype": "void (ServerPlayer* this)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q1"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_SetBankruptcyState",
|
|
"addr": "0x0080e260",
|
|
"convention": "thiscall",
|
|
"prototype": "void (ServerPlayer* this, int level)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q1"
|
|
},
|
|
{
|
|
"name": "ServerPlayer_BankruptcyLevel",
|
|
"addr": "0x0080db10",
|
|
"convention": "fastcall",
|
|
"prototype": "int (ServerPlayer* this)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q1"
|
|
},
|
|
{
|
|
"name": "ServerSystem_HazardMod",
|
|
"addr": "0x00747ae0",
|
|
"convention": "cdecl",
|
|
"prototype": "double (double suit, double ideal, double tol) /* clamp01(1-|suit-ideal|/(tol+0.1)) */",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q2"
|
|
},
|
|
{
|
|
"name": "ServerSystem_TradePointsToMoney",
|
|
"addr": "0x007505b0",
|
|
"convention": "thiscall",
|
|
"prototype": "double (ServerSystem* this, double tradePoints) /* RET 8 */",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q3"
|
|
},
|
|
{
|
|
"name": "ServerSystem_CalcSuitMod",
|
|
"addr": "0x007484d0",
|
|
"convention": "thiscall",
|
|
"prototype": "double (ServerSystem* this, int species)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q3"
|
|
},
|
|
{
|
|
"name": "ServerSystem_AccrueSystemBonus",
|
|
"addr": "0x0074d4f0",
|
|
"convention": "fastcall",
|
|
"prototype": "void (ServerSystem* this)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q4"
|
|
},
|
|
{
|
|
"name": "ServerSystem_SystemBonusPopTarget",
|
|
"addr": "0x0074b5a0",
|
|
"convention": "thiscall",
|
|
"prototype": "int (ServerSystem* this, float frac)",
|
|
"status": "verified",
|
|
"source": "handoff/formula-gaps.md#q4"
|
|
},
|
|
{
|
|
"name": "NodeLine_Step",
|
|
"addr": "0x00705510",
|
|
"convention": "cdecl",
|
|
"prototype": "void (Vector3* posOut, bool* arrivedOut, float nodespeed, float dt, void* lines, Vector3* from, Vector3* to)",
|
|
"status": "unverified",
|
|
"source": "handoff/formula-gaps.md#q7"
|
|
},
|
|
{
|
|
"name": "NodeLine_BuildStutterSegments",
|
|
"addr": "0x00705280",
|
|
"convention": "cdecl",
|
|
"prototype": "void (vector* segsOut, vector* systems, Vector3* from, Vector3* to)",
|
|
"status": "unverified",
|
|
"source": "handoff/formula-gaps.md#q7"
|
|
},
|
|
{
|
|
"name": "g_TechIdNames",
|
|
"addr": "0x009ff9e4",
|
|
"convention": "data",
|
|
"prototype": "struct { const char* name; int x; }[196] /* TechId = 10000+i */",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "g_CombatTechNames",
|
|
"addr": "0x00a19718",
|
|
"convention": "data",
|
|
"prototype": "const char*[116]",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#0"
|
|
},
|
|
{
|
|
"name": "g_SpeciesDefTable",
|
|
"addr": "0x00b10a00",
|
|
"convention": "data",
|
|
"prototype": "SpeciesDef[7] (0x184 B each, .bss, filled by SpeciesDef_InitTable)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#4"
|
|
},
|
|
{
|
|
"name": "g_TechBitmaskTableA",
|
|
"addr": "0x00adf378",
|
|
"convention": "data",
|
|
"prototype": "struct { int techId; uint bit; }[32]",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#3"
|
|
},
|
|
{
|
|
"name": "g_TechBitmaskTableB",
|
|
"addr": "0x00adf478",
|
|
"convention": "data",
|
|
"prototype": "struct { int techId; uint bit; }[29]",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#3"
|
|
},
|
|
{
|
|
"name": "g_AITechValueTable",
|
|
"addr": "0x00a17888",
|
|
"convention": "data",
|
|
"prototype": "struct { int techId; int a; float value; }[6] /* values not dumped */",
|
|
"status": "unverified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
},
|
|
{
|
|
"name": "g_PERGATETRAFFIC_DRV_TpGate",
|
|
"addr": "0x00b23e2c",
|
|
"convention": "data",
|
|
"prototype": "int (config storage; PTR slot 0x00aedfe0)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
},
|
|
{
|
|
"name": "g_PERGATETRAFFIC_DRV_GatAmp",
|
|
"addr": "0x00b23e30",
|
|
"convention": "data",
|
|
"prototype": "int (config storage; PTR slot 0x00aedfe4)",
|
|
"status": "verified",
|
|
"source": "handoff/tech-effects.md#1"
|
|
}
|
|
]
|
|
} |