sots-re/ghidra/addresses.d/lane-n.json

173 lines
No EOL
11 KiB
JSON

{
"entries": [
{
"name": "ServerSystem_ComputeTotalOutput",
"addr": "0x00750480",
"convention": "thiscall",
"prototype": "double (ServerSystem* sys, double overHarvestRate) // `ret 8`, real end 0x007505a5. Returns 0 when the system has no owner (+0x100) or rbfl (+0x1dc) is non-zero. Otherwise the SUM of three terms -- the over-harvest demand x SpeciesDef+0x50, (TRes + available resources) x StripMineFraction x 0.9, and the population output of groups 0, 1 and 2 -- multiplied in one uninterrupted 80-bit chain by player OutMod, sys.OutMod, player +0x224, RebOutMod, ScOutMod, and finally by ADDICTION_OUTPUT_MOD when the addiction phase is >= 3. SIDE-EFFECT FREE: it and all seven callees were checked for stores to the game state (0x0074a6d0's only writes are through its int64 out-parameters), which is why this and not ComputeOutputFromRates is the compare target -- that one repairs ships in orbit",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_GroupOutput",
"addr": "0x0074b7a0",
"convention": "thiscall",
"prototype": "double (ServerSystem* sys, int groupType, int species, double count) // `ret 0x10`, real end 0x0074b871. THE population -> output term: returns 0 for count <= 0, else max(0, POPTYPE[groupType].outputMod x (stationFactor x 1.8) x moraleMod x (count / 500000)). stationFactor is 1 + stations x STATION_BONUS_IMPERIAL_OUTPUT and applies to groupType 0 of an owned system only (and only while that constant is > 0); moraleMod applies to groupType 1 only. So output points per head are typeOutputMod x 1.8 / 500000 -- exactly 3.6e-6 for an imperial population with no stations",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_PopOutput",
"addr": "0x0074d8f0",
"convention": "thiscall",
"prototype": "double (ServerSystem* sys, int groupType) // `ret 4`, real end 0x0074da01. Sums GroupOutput over species 0..6 using GroupPopulation(groupType, species). For groupType 1 and the owner's own species on a non-independent system it first adds a capacity surplus: two calls to 0x0074a6d0 with the int64 out-pointer in argument slot 4 and then in slot 6, surplus = max(0, B - A). The income analogue is 0x0074d760",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_SlaveOutput",
"addr": "0x0074b880",
"convention": "thiscall",
"prototype": "double (ServerSystem* sys) // real end 0x0074b901. Sums over species 0..6: max(0, POPTYPE[2].outputMod x 1.8 x (slaves / 500000)). Does NOT go through GroupOutput, so it carries neither the station factor nor the morale multiplier. Slave counts come from 0x0074b610",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_StripMineFraction",
"addr": "0x00747d30",
"convention": "thiscall",
"prototype": "float (ServerSystem* sys) // real end 0x00747ddd. R = clamp01(signed_cbrt((pbon + Pop) / 100) x 0.01); if 0.0001 + R >= 1 the infrastructure term SUBSTITUTES it outright (R := float32(ibon + Infra)); returns float32(min(R, float32(ibon + Infra))). The substitution is not a clamp: a colony with a pending infrastructure bonus can return a fraction above 1",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_OverHarvestDemand",
"addr": "0x007483b0",
"convention": "thiscall",
"prototype": "double (ServerSystem* sys, double overHarvestRate) // `ret 8`, real end 0x007484c4. CORRECTS strategic-turn-internals.md 3.3, which called this the population base-output term: its population is the RESOURCE stock (Res, plus MRes + ARes2 when the owner strip-mines), and the species constant at +0x4c is ADDED, not a cap -- the cap is the resource stock. B = rate > 0 ? max(rate x available x clamp01((pbon + Pop) x 1e-5), 1.0) : 0; return min(available, max(speciesBaseDemand + B, 0)). Called twice per output pass: once inside ComputeTotalOutput and once by ComputeOutputFromRates as the resource ledger's strip-mine demand",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_GroupPopulation",
"addr": "0x00747ba0",
"convention": "thiscall",
"prototype": "int64 (ServerSystem* sys, int groupType, int species) // groupType 0 returns (pbon + Pop) sign-extended, but ONLY for the system's effective species (indi->+4 when independent, else owner->Species) and 0 for every other; otherwise Population::Count(pbon2) + Population::Count(Pop2) for that (type, species)",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerSystem_MoraleOutputMod",
"addr": "0x00746910",
"convention": "thiscall",
"prototype": "double (ServerSystem* sys, int species) // `ret 4`. Returns 1.0 when the system has no owner, is independent, or its Morale int[7] entry for the species is exactly 0 -- the zero guard matters, because 0 <= MORALE_DECREASE_OUTPUT would otherwise apply the penalty to every species with no record. Otherwise m >= MORALE_INCREASE_OUTPUT -> MORALE_INCREASE_OUTPUT_MOD, m <= MORALE_DECREASE_OUTPUT -> MORALE_DECREASE_OUTPUT_MOD, each used only when strictly positive, else 1.0",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "PopTypeRow",
"addr": "0x00535e00",
"convention": "cdecl",
"prototype": "PopTypeRow* (int groupType) // table base 0x00b104e8, stride 0x30, three rows; groupType > 2 falls back to a lazily-initialised sentinel row at 0x00b10578 that no caller reaches. Row fields used here: +0x10 output modifier, +0x14 income modifier, +8 maximum population",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "InitPopTypeTable",
"addr": "0x00535ca0",
"convention": "cdecl",
"prototype": "void () // builds the three-row population-type table IN CODE from x87 literals, rotating six values with fxch rather than storing them. Imperial {+4 1.0, maxpop 50000000, out 1.0, income 1.0, +0x18 1.0, +0x1c 1.0, +0x20 1.0}; civilian {+4 0.25, maxpop 20000000, out 0.33, income 0.33, +0x18 1.0, +0x1c 0.5, +0x20 2.0}; slaves {+4 0.0, maxpop 0, out SLAVES_OUTPUT_MOD, income SLAVES_INCOME_MOD, +0x18 SLAVES_REPAIR_MOD, +0x1c 0.0}. So the whole population -> output law is carried by the executable except the three slave modifiers",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GroupIncome",
"addr": "0x00535e80",
"convention": "cdecl",
"prototype": "int (int groupType, int64 count) // ftol(POPTYPE[groupType].incomeModifier x (count / 14000.0)). The income analogue of GroupOutput; note the divisor is 14000, not the output law's 500000, and there is no 1.8 factor",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "SignedCubeRoot",
"addr": "0x008e5680",
"convention": "cdecl",
"prototype": "double (double x) // x >= 0 ? pow(x, 1/3) : -pow(-x, 1/3), with the exponent taken from the double 0.3333333333333333 at 0x00a3a7c8. Used by StripMineFraction",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "ServerPlayer_off_ScOutMod",
"offset": "0x12c",
"prototype": "offset float ScOutMod -- the last of the five output multipliers ComputeTotalOutput applies, and the innermost in the x87 chain",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)",
"convention": "offset"
},
{
"name": "ServerPlayer_off_SetupOutputMult",
"offset": "0x224",
"prototype": "offset float -- the game-setup handicap OUTPUT multiplier, the sibling of SetupIncomeMult (+0x228) and SetupResearchMult (+0x22c). Read by ComputeTotalOutput as the third of its five multipliers",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)",
"convention": "offset"
},
{
"name": "PopTypeTable_base",
"addr": "0x00b104e8",
"convention": "data",
"prototype": "PopTypeRow[3] -- .bss, filled by InitPopTypeTable at startup. Stride 0x30",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GlobalConst_slot_STATION_BONUS_IMPERIAL_OUTPUT",
"addr": "0x00af08f4",
"convention": "data",
"prototype": "float** -- pointer slot; storage 0x00af08f0, which unusually carries a value (0.1f) in the file image rather than being .bss",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GlobalConst_slot_MORALE_INCREASE_OUTPUT",
"addr": "0x00aec784",
"convention": "data",
"prototype": "int** -- pointer slot read by MoraleOutputMod; the threshold is an INT compared against the Morale int[7] entry",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GlobalConst_slot_MORALE_INCREASE_OUTPUT_MOD",
"addr": "0x00aec78c",
"convention": "data",
"prototype": "float** -- pointer slot read by MoraleOutputMod",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GlobalConst_slot_MORALE_DECREASE_OUTPUT",
"addr": "0x00aec794",
"convention": "data",
"prototype": "int** -- pointer slot read by MoraleOutputMod",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GlobalConst_slot_MORALE_DECREASE_OUTPUT_MOD",
"addr": "0x00aec79c",
"convention": "data",
"prototype": "float** -- pointer slot read by MoraleOutputMod",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
},
{
"name": "GlobalConst_storage_SLAVES_OUTPUT_MOD",
"addr": "0x00b0e9b0",
"convention": "data",
"prototype": "float -- .bss storage reached through the slot at 0x00ae2e88; the output modifier of the slave row of the population-type table. SLAVES_INCOME_MOD is 0x00b0e9ac (slot 0x00ae2e84) and SLAVES_REPAIR_MOD is 0x00b0e9b4 (slot 0x00ae2e8c)",
"status": "verified",
"source": "findings/subsystems/output-term.md (lane N 2026-09-08)"
}
],
"_note": "Dropped 2026-09-08 as same-address duplicates, agreement recorded: SpeciesDefTable_Get -> SpeciesDef_Get (addresses.json); SpeciesDefTable_base -> g_SpeciesDefTable (addresses.json)."
}