From 0d083f9153c713a53cec57d698c94074571631f6 Mon Sep 17 00:00:00 2001 From: Gynt Date: Wed, 14 Oct 2026 23:39:12 +0200 Subject: [PATCH 1/7] reimplement: PathFindingState methods that are 100% --- AGENTS.md | 22 +- .../Constructor_PathFindingState.cpp | 36 +++ .../PathFindingState/LinkageNeighbourAsm.hpp | 216 ++++++++++++++++++ .../bindPathPlanToAlgorithmStateAndReset.cpp | 2 +- .../clearActiveClimbDataOfType6And7.cpp | 37 +++ .../PathFindingState/clearAllClimbData.cpp | 2 +- .../PathFindingState/clearClimbData.cpp | 3 +- .../clearPathFindingTileMaps.cpp | 34 +++ .../computeAttackVectorsBasedOnXAndY.cpp | 54 +++++ .../getComputationalTileIndex.cpp | 2 +- .../PathFindingState/getTileInSearchQueue.cpp | 2 +- .../getYSmallerThanYLimit.cpp | 3 +- .../retraceAndCommitPathPlan.cpp | 2 +- ...hLinkageLayerForEachBuildingAtEachTile.cpp | 2 +- status/addresses-SHC-3BB0A8C1.txt | 212 ++++++++--------- 15 files changed, 512 insertions(+), 117 deletions(-) create mode 100644 src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp create mode 100644 src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp create mode 100644 src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp create mode 100644 src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp create mode 100644 src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp diff --git a/AGENTS.md b/AGENTS.md index 187d9a0ba..c2626a4a9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -151,8 +151,19 @@ restyling anything large: `__asm` block rather than C++. Functions are never `__declspec(naked)`: write a normal function, keep the compiler-generated statements as C++, and refer to parameters, locals and `this` by name. Prettify offsets with MSVC's struct-member asm syntax (`mov esi, dword ptr [eax]TileMapState.ptr_LogicLayer`) - `::` is not parseable in an - asm operand, so a resolver global cannot be named there. -- a frame pointer plus a `this` spill - the original was built without optimisation. Add `#pragma optimize(, off)` + asm operand, so a resolver global cannot be named there. Where the handwritten block reaches a *global* layer rather + than a `this` field, give it a C++ pointer local and name that local in the asm; the original caches the same bases in + stack slots anyway, so the inner loop still matches. `mov eax, 0` followed by `mov ax, word ptr [..]` is the giveaway + in its own right - that is a hand-rolled `movzx`, which the compiler always emits as one instruction. + Such a block is usually a **macro**: the same instruction stream appears verbatim in several functions and never as a + call, so it belongs in a hand-written `*Asm.hpp` beside them (`NeighbourFlagsAsm.hpp`, `LinkageNeighbourAsm.hpp`). + This has been worth ~45 points per function, three times over. +- a frame pointer plus a `this` spill - the original was built without optimisation, **unless the same function also + reports `mov reg, 0`**. MSVC keeps `ebp` in any function containing an `__asm` block, so for a function with + handwritten assembly the frame pointer says nothing about the optimisation level: reimplement the handwritten part as + inline asm and leave the rest at `/O2`. Checking the prologue settles it - values kept in registers across the entry + tests mean `/O2`. Taking the `/Od` reading instead took `findLinkageBasedPathOrWalkRadius` from 5.1% to 2.8%, where + the same body without the pragma reaches 49.2%. When it really is `/Od`, add `#pragma optimize(, off)` around the function; inline asm alone does not disable optimisation. Then match the reported **frame size** exactly, which is usually the single biggest win, because every local displacement shifts otherwise. Merge locals that share a slot and reproduce dead stores. At `/Od` prefer a nested `if` over an early `continue` (the original inverts the test @@ -234,6 +245,13 @@ of the switch leaving the value it should have set uninitialised. Fixing them wa suspicious dead store is worth decompiling for rather than deleting. Note this is the opposite of the duplicate-tail pattern below, where our shared block should have been two separate branches - check the predecessor count either way. +Duplicating a `LAB_*` is correct C++ but not automatically a better match, so **measure every `goto` removal**. A +`goto` in the decompiler output usually marks a block the original compiler emitted once and jumped to, and writing +the block out twice makes MSVC emit it twice: duplicating the single shared tail in +`setClimbBasedOnClosestClimbData` - two `if` arms that set a coordinate pair and then share the distance test - was +semantically identical and cost **35 points**. Keep the `goto` where the measurement says the original shared the +block, and record that in the commit remark rather than trading match for style. + Diff patterns that were reliable (more in the cheat sheet): - Absolute `DAT_*` addresses in the original asm where the source uses `this->` mean the original accessed the global instance. diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp new file mode 100644 index 000000000..b4eac3e66 --- /dev/null +++ b/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp @@ -0,0 +1,36 @@ +#include "../PathFindingState.func.hpp" + +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" + +namespace OpenSHC { +namespace Map { + namespace Navigation { + + /* + decompilerscript: committed: 2025-01-30 21:57:43.216000 + */ + // FUNCTION: STRONGHOLDCRUSADER 0x004A9760 + PathFindingState* PathFindingState::Constructor_PathFindingState() + { + this->field40_0x70 = 0; + this->field41_0x74 = 0; + this->DAT_lWys = 0; + this->notAllAssassinsUnk = 0; + this->DAT_Easy = 0; + this->DAT_Hard = 0; + this->DAT_Test_likely = 0; + this->DAT_Test_gatehouse = 0; + this->searchNonmatchCount = 0; + this->searchMatchCounter = 0; + this->DAT_Ass = 0; + this->calculations = 0; + this->DAT_Mini_spreads = 0; + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearPathFindingTileMaps, this)(); + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearAllClimbData, this)(); + this->searchGeneration = 1; + return this; + } + + } +} +} diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp b/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp new file mode 100644 index 000000000..258744835 --- /dev/null +++ b/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp @@ -0,0 +1,216 @@ +/** + HAND WRITTEN - not generated. + + path: 'OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp' + + The inner loop of the PathLinkageLayer searches - pushing the eight neighbours of the tile just + taken off the queue - is handwritten assembly in the original, and it is a MACRO: the identical + instruction stream appears verbatim inside findLinkageBasedPathOrWalkRadius (0x00497740), + findSuitableSpawnLocationUnk (0x00497B80) and updateSeparateAreaTileMap (0x004995E0), never as a + call. It is recognisable by + + - "mov eax, 0" followed by "mov ax, word ptr [..]", a zero extension no compiler writes that way + (MSVC emits movzx), + - the search generation and the distance kept in 16-bit registers and compared with "cmp ax, cx" + rather than widened to int, + - every layer base reloaded from its own stack slot before each use instead of being held in a + register across the block. + + Do NOT add "#pragma optimize("", off)" to the enclosing functions. orig_asm.py --stats reports a + frame pointer for all three, but that is caused by the inline assembly itself - MSVC keeps ebp in + any function containing an __asm block - not by a missing /O2. Their prologues are plainly + optimised (the bounds check runs out of registers, "this" stays in esi), and forcing /Od costs + about half of the match. + + PathLinkageLayer bits: 0x01 north, 0x02 north-east, 0x04 east, 0x08 south-east, + 0x10 south, 0x20 south-west, 0x40 west, 0x80 north-west. + + Cardinal neighbours are entered at distance + 1 and diagonal ones at distance + 2; the north and + south rows are reached by adding directionTranslationMatrix[y][0] and [y][4] to the tile. + + The macro expects these locals in the enclosing function, by these names: + + short* _walkLayer, _certainPath the two adjacent short layers + int* _tilesQueue this->searchQueue.tilesQueue + short* _yQueue this->searchQueue.yQueue + int* _dirMatrix directionTranslationMatrix, as a flat int array + int _tile, _cY, _cLink + short _curGen, _cCardinalDistance + + and takes the queue end as the WRITEIDX macro argument, which it advances. It clobbers eax, ebx, ecx, edx, esi and edi. + + ID must be unique within the enclosing function; it exists only to keep the assembler labels of two + expansions apart. + + The original reaches the layers through the global instance's absolute address; we load them from + locals because MSVC inline assembly cannot name DAT_TileMapState::instance ("::" is not parseable + in an asm operand). That costs the initial "mov esi, _" instructions and nothing else - the + original reloads from a stack slot at exactly those points anyway. +*/ + +#pragma once + +#include "OpenSHC/Map/TileMapState.hpp" + +// clang-format off + +// One neighbour: OFF is the byte offset on the short layers (-2, 0 or +2), BIT the linkage bit, +// DIST the distance instruction (none for a cardinal step, "add ax, 1" for a diagonal one), +// TILE the tile-delta instruction and YADJ the row-delta instruction. +#define MACRO_LINKAGE_PUSH(ID, N, WRITEIDX, OFF, BIT, DIST, TILE, YADJ) \ + __asm mov ax, word ptr [edi + edx*2 + OFF] \ + __asm cmp ax, word ptr _curGen \ + __asm je push_done_##ID##_##N \ + __asm test bl, BIT \ + __asm je push_done_##ID##_##N \ + __asm mov esi, _certainPath \ + __asm mov ax, word ptr _cCardinalDistance \ + DIST \ + __asm mov cx, word ptr _curGen \ + __asm mov word ptr [esi + edx*2 + OFF], ax \ + __asm mov word ptr [edi + edx*2 + OFF], cx \ + __asm mov ecx, WRITEIDX \ + __asm mov esi, _tilesQueue \ + __asm mov eax, edx \ + TILE \ + __asm mov dword ptr [esi + ecx*4], eax \ + __asm mov eax, _cY \ + YADJ \ + __asm mov esi, _yQueue \ + __asm mov word ptr [esi + ecx*2], ax \ + __asm add WRITEIDX, 1 \ + __asm push_done_##ID##_##N: + +#define MACRO_ASM_SAME +#define MACRO_ASM_INC __asm add eax, 1 +#define MACRO_ASM_DEC __asm sub eax, 1 +#define MACRO_ASM_DIAGONAL __asm add ax, 1 + +// The whole eight-neighbour expansion, in the original's order: west, east, then the north row +// (north, north-west, north-east) and the south row (south, south-west, south-east). +#define MACRO_LINKAGE_EXPAND_NEIGHBOURS(ID, WRITEIDX) \ + __asm mov edx, _tile \ + __asm mov edi, _walkLayer \ + __asm mov ebx, _cLink \ + MACRO_LINKAGE_PUSH(ID, w, WRITEIDX, -2, 0x40, MACRO_ASM_SAME, MACRO_ASM_DEC, MACRO_ASM_SAME) \ + MACRO_LINKAGE_PUSH(ID, e, WRITEIDX, +2, 0x04, MACRO_ASM_SAME, MACRO_ASM_INC, MACRO_ASM_SAME) \ + __asm mov eax, _cY \ + __asm shl eax, 3 \ + __asm mov esi, _dirMatrix \ + __asm add edx, dword ptr [esi + eax*4] \ + MACRO_LINKAGE_PUSH(ID, n, WRITEIDX, 0, 0x01, MACRO_ASM_SAME, MACRO_ASM_SAME, MACRO_ASM_DEC) \ + MACRO_LINKAGE_PUSH(ID, nw, WRITEIDX, -2, 0x80, MACRO_ASM_DIAGONAL, MACRO_ASM_DEC, MACRO_ASM_DEC) \ + MACRO_LINKAGE_PUSH(ID, ne, WRITEIDX, +2, 0x02, MACRO_ASM_DIAGONAL, MACRO_ASM_INC, MACRO_ASM_DEC) \ + __asm mov edx, _tile \ + __asm mov eax, _cY \ + __asm shl eax, 3 \ + __asm add eax, 4 \ + __asm mov esi, _dirMatrix \ + __asm add edx, dword ptr [esi + eax*4] \ + MACRO_LINKAGE_PUSH(ID, s, WRITEIDX, 0, 0x10, MACRO_ASM_SAME, MACRO_ASM_SAME, MACRO_ASM_INC) \ + MACRO_LINKAGE_PUSH(ID, sw, WRITEIDX, -2, 0x20, MACRO_ASM_DIAGONAL, MACRO_ASM_DEC, MACRO_ASM_INC) \ + MACRO_LINKAGE_PUSH(ID, se, WRITEIDX, +2, 0x08, MACRO_ASM_DIAGONAL, MACRO_ASM_INC, MACRO_ASM_INC) + +// The same neighbour, but only entered when OccupancyLayer says the tile is free. TOFF is the +// neighbour's offset in tiles (the occupancy layer holds one byte per tile, so it is not scaled +// like OFF is on the short layers). Needs one more local, "uchar* _occupancy". +#define MACRO_LINKAGE_PUSH_FREE(ID, N, WRITEIDX, OFF, TOFF, BIT, DIST, TILE, YADJ) \ + __asm mov ax, word ptr [edi + edx*2 + OFF] \ + __asm cmp ax, word ptr _curGen \ + __asm je push_done_##ID##_##N \ + __asm test bl, BIT \ + __asm je push_done_##ID##_##N \ + __asm mov esi, _occupancy \ + __asm mov cl, byte ptr [esi + edx + TOFF] \ + __asm cmp cl, 0 \ + __asm jne push_done_##ID##_##N \ + __asm mov esi, _certainPath \ + __asm mov ax, word ptr _cCardinalDistance \ + DIST \ + __asm mov cx, word ptr _curGen \ + __asm mov word ptr [esi + edx*2 + OFF], ax \ + __asm mov word ptr [edi + edx*2 + OFF], cx \ + __asm mov ecx, WRITEIDX \ + __asm mov esi, _tilesQueue \ + __asm mov eax, edx \ + TILE \ + __asm mov dword ptr [esi + ecx*4], eax \ + __asm mov eax, _cY \ + YADJ \ + __asm mov esi, _yQueue \ + __asm mov word ptr [esi + ecx*2], ax \ + __asm add WRITEIDX, 1 \ + __asm push_done_##ID##_##N: + +#define MACRO_LINKAGE_EXPAND_FREE_NEIGHBOURS(ID, WRITEIDX) \ + __asm mov edx, _tile \ + __asm mov edi, _walkLayer \ + __asm mov ebx, _cLink \ + MACRO_LINKAGE_PUSH_FREE(ID, w, WRITEIDX, -2, -1, 0x40, MACRO_ASM_SAME, MACRO_ASM_DEC, MACRO_ASM_SAME) \ + MACRO_LINKAGE_PUSH_FREE(ID, e, WRITEIDX, +2, +1, 0x04, MACRO_ASM_SAME, MACRO_ASM_INC, MACRO_ASM_SAME) \ + __asm mov eax, _cY \ + __asm shl eax, 3 \ + __asm mov esi, _dirMatrix \ + __asm add edx, dword ptr [esi + eax*4] \ + MACRO_LINKAGE_PUSH_FREE(ID, n, WRITEIDX, 0, 0, 0x01, MACRO_ASM_SAME, MACRO_ASM_SAME, MACRO_ASM_DEC) \ + MACRO_LINKAGE_PUSH_FREE(ID, nw, WRITEIDX, -2, -1, 0x80, MACRO_ASM_DIAGONAL, MACRO_ASM_DEC, MACRO_ASM_DEC) \ + MACRO_LINKAGE_PUSH_FREE(ID, ne, WRITEIDX, +2, +1, 0x02, MACRO_ASM_DIAGONAL, MACRO_ASM_INC, MACRO_ASM_DEC) \ + __asm mov edx, _tile \ + __asm mov eax, _cY \ + __asm shl eax, 3 \ + __asm add eax, 4 \ + __asm mov esi, _dirMatrix \ + __asm add edx, dword ptr [esi + eax*4] \ + MACRO_LINKAGE_PUSH_FREE(ID, s, WRITEIDX, 0, 0, 0x10, MACRO_ASM_SAME, MACRO_ASM_SAME, MACRO_ASM_INC) \ + MACRO_LINKAGE_PUSH_FREE(ID, sw, WRITEIDX, -2, -1, 0x20, MACRO_ASM_DIAGONAL, MACRO_ASM_DEC, MACRO_ASM_INC) \ + MACRO_LINKAGE_PUSH_FREE(ID, se, WRITEIDX, +2, +1, 0x08, MACRO_ASM_DIAGONAL, MACRO_ASM_INC, MACRO_ASM_INC) + +// The area flood-fill variant: no distance and no search generation, just "this neighbour has no +// area yet, give it mine". It tests the linkage bit first and walks the north and south rows +// west-to-east, both the other way round from the two search variants above. Needs the locals +// "ushort* _areaLayer" (PathConnectionLayer) and "short _areaID" in place of the layer pair. +#define MACRO_LINKAGE_PUSH_AREA(ID, N, WRITEIDX, OFF, BIT, TILE, YADJ) \ + __asm test bl, BIT \ + __asm je push_done_##ID##_##N \ + __asm mov ax, word ptr [edi + edx*2 + OFF] \ + __asm cmp ax, 0 \ + __asm jne push_done_##ID##_##N \ + __asm mov ax, word ptr _areaID \ + __asm mov word ptr [edi + edx*2 + OFF], ax \ + __asm mov ecx, WRITEIDX \ + __asm mov esi, _tilesQueue \ + __asm mov eax, edx \ + TILE \ + __asm mov dword ptr [esi + ecx*4], eax \ + __asm mov eax, _cY \ + YADJ \ + __asm mov esi, _yQueue \ + __asm mov word ptr [esi + ecx*2], ax \ + __asm add WRITEIDX, 1 \ + __asm push_done_##ID##_##N: + +#define MACRO_LINKAGE_EXPAND_AREA_NEIGHBOURS(ID, WRITEIDX) \ + __asm mov edx, _tile \ + __asm mov edi, _areaLayer \ + __asm mov ebx, _cLink \ + MACRO_LINKAGE_PUSH_AREA(ID, w, WRITEIDX, -2, 0x40, MACRO_ASM_DEC, MACRO_ASM_SAME) \ + MACRO_LINKAGE_PUSH_AREA(ID, e, WRITEIDX, +2, 0x04, MACRO_ASM_INC, MACRO_ASM_SAME) \ + __asm mov edx, _tile \ + __asm mov eax, _cY \ + __asm shl eax, 3 \ + __asm mov esi, _dirMatrix \ + __asm add edx, dword ptr [esi + eax*4] \ + MACRO_LINKAGE_PUSH_AREA(ID, nw, WRITEIDX, -2, 0x80, MACRO_ASM_DEC, MACRO_ASM_DEC) \ + MACRO_LINKAGE_PUSH_AREA(ID, n, WRITEIDX, 0, 0x01, MACRO_ASM_SAME, MACRO_ASM_DEC) \ + MACRO_LINKAGE_PUSH_AREA(ID, ne, WRITEIDX, +2, 0x02, MACRO_ASM_INC, MACRO_ASM_DEC) \ + __asm mov edx, _tile \ + __asm mov eax, _cY \ + __asm shl eax, 3 \ + __asm add eax, 4 \ + __asm mov esi, _dirMatrix \ + __asm add edx, dword ptr [esi + eax*4] \ + MACRO_LINKAGE_PUSH_AREA(ID, sw, WRITEIDX, -2, 0x20, MACRO_ASM_DEC, MACRO_ASM_INC) \ + MACRO_LINKAGE_PUSH_AREA(ID, s, WRITEIDX, 0, 0x10, MACRO_ASM_SAME, MACRO_ASM_INC) \ + MACRO_LINKAGE_PUSH_AREA(ID, se, WRITEIDX, +2, 0x08, MACRO_ASM_INC, MACRO_ASM_INC) + +// clang-format on diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/bindPathPlanToAlgorithmStateAndReset.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/bindPathPlanToAlgorithmStateAndReset.cpp index def1d655f..aebd50bd6 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/bindPathPlanToAlgorithmStateAndReset.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/bindPathPlanToAlgorithmStateAndReset.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "../PathFindingState.func.hpp" namespace OpenSHC { namespace Map { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp new file mode 100644 index 000000000..08ca1960f --- /dev/null +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp @@ -0,0 +1,37 @@ +#include "../PathFindingState.func.hpp" + +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" + +namespace OpenSHC { +namespace Map { + namespace Navigation { + + /* + Iterates all climb data entries (1 to maxClimbDataCount) and calls clearLaddermanWalledData on any entry + that is active (canBeUsed != 0) and has type 6 or 7. The semantics of types 6 and 7 are not yet fully known; + this is likely called during a siege reset or wall state change. renamed by: Claude Sonnet 4.6 + */ + // FUNCTION: STRONGHOLDCRUSADER 0x004A52D0 + void PathFindingState::clearActiveClimbDataOfType6And7() + { + int* piVar2; + int iVar1 = 1; + piVar2 = &this->climbData[1].type; + do { + if (((ClimbData*)(piVar2 + -1))->canBeUsed != 0) { + if (*piVar2 == 6) { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearClimbData, this)(iVar1); + } + if (*piVar2 == 7) { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearClimbData, this)(iVar1); + } + } + iVar1 = iVar1 + 1; + piVar2 = piVar2 + 0x81; + } while (iVar1 < 200); + return; + } + + } +} +} diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearAllClimbData.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearAllClimbData.cpp index 80fbfda87..0c129f361 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/clearAllClimbData.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearAllClimbData.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "../PathFindingState.func.hpp" namespace OpenSHC { namespace Map { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearClimbData.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearClimbData.cpp index 693e80c9d..567520e82 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/clearClimbData.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearClimbData.cpp @@ -1,5 +1,6 @@ +#include "../PathFindingState.func.hpp" + #include "OpenSHC/IO/LowLevelMemory.func.hpp" -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" #include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp new file mode 100644 index 000000000..2d6d4522d --- /dev/null +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp @@ -0,0 +1,34 @@ +#include "../PathFindingState.func.hpp" + +#include "OpenSHC/IO/LowLevelMemory.func.hpp" + +#include "OpenSHC/Globals/DAT_LowLevelMemory.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" + +namespace OpenSHC { +namespace Map { + namespace Navigation { + + /* + WARNING: Enum "MappersEnum": Some values do not have unique names + */ + /* + decompilerscript: committed: 2025-01-30 21:57:43.216000 + */ + // FUNCTION: STRONGHOLDCRUSADER 0x00496E40 + void PathFindingState::clearPathFindingTileMaps() + { + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 0x27420, '\0', (void*)((int)(DAT_TileMapState::instance.PathConnectionLayer))); + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 0x13a10, '\0', (void*)((int)(DAT_TileMapState::instance.PathLinkageLayer))); + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 0x27420, '\0', (void*)((int)(DAT_TileMapState::instance.CertainPathLayer))); + MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( + 0x27420, '\0', (void*)((int)(DAT_TileMapState::instance.WalkLayer))); + return; + } + + } +} +} diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp new file mode 100644 index 000000000..19de23dd2 --- /dev/null +++ b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp @@ -0,0 +1,54 @@ +#include "../PathFindingState.func.hpp" + +#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" + +#include "OpenSHC/Globals/DAT_GameState.hpp" +#include "OpenSHC/Globals/DAT_TileMapState.hpp" +#include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" + +namespace OpenSHC { +namespace Map { + namespace Navigation { + + /* + WARNING: Enum "MappersEnum": Some values do not have unique names + */ + /* + decompilerscript: committed: 2025-01-30 21:57:43.216000 + */ + // FUNCTION: STRONGHOLDCRUSADER 0x004A69F0 + void PathFindingState::computeAttackVectorsBasedOnXAndY(int playerID) + { + this->calculations = this->calculations + 1; + int _index = 0; + this->searchQueue.readIndex = 0; + if (this->searchQueue.writeIndex != 0) { + do { + uint y = (uint)this->searchQueue.yQueue[this->searchQueue.readIndex]; + int iVar1 = this->searchQueue.tilesQueue[this->searchQueue.readIndex]; + uint x = iVar1 - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + if (DAT_TileMapState::instance.CertainPathLayer[iVar1] != 100) { + MACRO_CALL_MEMBER( + OpenSHC::Map::Navigation::PathFindingState_Func::budgetFloodFillOnCertainPathLayer, this)( + x, y, 100, 100); + DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].x = x; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].y = y; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].tribeUIDUnk = 0; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].tribeID = 0; + _index = _index + 1; + } + if (_index >= 50) { + return; + } + this->searchQueue.readIndex = this->searchQueue.readIndex + 1; + if (0x13a10 <= (int)this->searchQueue.readIndex) { + this->searchQueue.readIndex = 0; + } + } while (this->searchQueue.readIndex != this->searchQueue.writeIndex); + } + return; + } + + } +} +} diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp index b5329ac1f..617aa511e 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.hpp" +#include "../PathFindingState.func.hpp" namespace OpenSHC { namespace Map { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/getTileInSearchQueue.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/getTileInSearchQueue.cpp index 1b76cae82..fc5f97064 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/getTileInSearchQueue.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/getTileInSearchQueue.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "../PathFindingState.func.hpp" namespace OpenSHC { namespace Map { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/getYSmallerThanYLimit.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/getYSmallerThanYLimit.cpp index 7e1e89c5a..98cfd4f13 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/getYSmallerThanYLimit.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/getYSmallerThanYLimit.cpp @@ -1,5 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" -#include "OpenSHC/WindowsHelper/Enums/BOOLEnum.hpp" +#include "../PathFindingState.func.hpp" namespace OpenSHC { namespace Map { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/retraceAndCommitPathPlan.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/retraceAndCommitPathPlan.cpp index 592967e90..b264a3e20 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/retraceAndCommitPathPlan.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/retraceAndCommitPathPlan.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "../PathFindingState.func.hpp" namespace OpenSHC { namespace Map { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp index 4d656c28f..6e5712ada 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp @@ -1,4 +1,4 @@ -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" +#include "../PathFindingState.func.hpp" #include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index f6e47278b..33114c519 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -24347,103 +24347,103 @@ SHC_3BB0A8C1_0x00496E20 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00496E30 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00496E40 | 0.0% | Pending +SHC_3BB0A8C1_0x00496E40 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00496EA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00496EC0 | 0.0% | Pending +SHC_3BB0A8C1_0x00496EC0 | 47.5% | Style pass, asm differs -SHC_3BB0A8C1_0x00496F90 | 0.0% | Pending +SHC_3BB0A8C1_0x00496F90 | 20.0% | Style pass, asm differs -SHC_3BB0A8C1_0x00497080 | 0.0% | Pending +SHC_3BB0A8C1_0x00497080 | 34.0% | Style pass, asm differs -SHC_3BB0A8C1_0x00497180 | 0.0% | Pending +SHC_3BB0A8C1_0x00497180 | 29.4% | Style pass, asm differs -SHC_3BB0A8C1_0x00497280 | 0.0% | Pending +SHC_3BB0A8C1_0x00497280 | 48.9% | Style pass, asm differs -SHC_3BB0A8C1_0x004974D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004974D0 | 30.8% | Style pass, asm differs -SHC_3BB0A8C1_0x00497690 | 0.0% | Pending +SHC_3BB0A8C1_0x00497690 | 13.6% | Style pass, asm differs -SHC_3BB0A8C1_0x00497740 | 0.0% | Pending +SHC_3BB0A8C1_0x00497740 | 49.2% | Style pass, asm differs -SHC_3BB0A8C1_0x00497B80 | 0.0% | Pending +SHC_3BB0A8C1_0x00497B80 | 51.7% | Style pass, asm differs -SHC_3BB0A8C1_0x00498020 | 0.0% | Pending +SHC_3BB0A8C1_0x00498020 | 54.8% | Style pass, asm differs SHC_3BB0A8C1_0x00498170 | 0.0% | Pending -SHC_3BB0A8C1_0x00498400 | 0.0% | Pending +SHC_3BB0A8C1_0x00498400 | 41.2% | Style pass, asm differs SHC_3BB0A8C1_0x004985D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00498A40 | 0.0% | Pending +SHC_3BB0A8C1_0x00498A40 | 78.3% | Style pass, asm differs SHC_3BB0A8C1_0x00498B70 | 0.0% | Pending -SHC_3BB0A8C1_0x00498FD0 | 0.0% | Pending +SHC_3BB0A8C1_0x00498FD0 | 12.1% | Style pass, asm differs SHC_3BB0A8C1_0x004990F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004995E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004995E0 | 49.3% | Style pass, asm differs SHC_3BB0A8C1_0x00499970 | 0.0% | Pending -SHC_3BB0A8C1_0x004999C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004999C0 | 23.7% | Style pass, asm differs -SHC_3BB0A8C1_0x00499DC0 | 0.0% | Pending +SHC_3BB0A8C1_0x00499DC0 | 42.9% | Style pass, asm differs -SHC_3BB0A8C1_0x00499FA0 | 0.0% | Pending +SHC_3BB0A8C1_0x00499FA0 | 24.4% | Style pass, asm differs -SHC_3BB0A8C1_0x0049A1C0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049A1C0 | 48.3% | Style pass, asm differs -SHC_3BB0A8C1_0x0049A2E0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049A2E0 | 25.9% | Style pass, asm differs -SHC_3BB0A8C1_0x0049A370 | 0.0% | Pending +SHC_3BB0A8C1_0x0049A370 | 8.5% | Style pass, asm differs -SHC_3BB0A8C1_0x0049A5E0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049A5E0 | 78.3% | Style pass, asm differs SHC_3BB0A8C1_0x0049A610 | 0.0% | Pending -SHC_3BB0A8C1_0x0049A6D0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049A6D0 | 72.5% | Style pass, asm differs SHC_3BB0A8C1_0x0049A800 | 0.0% | Pending -SHC_3BB0A8C1_0x0049AAD0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049AAD0 | 72.8% | Style pass, asm differs SHC_3BB0A8C1_0x0049AC80 | 0.0% | Pending -SHC_3BB0A8C1_0x0049AF50 | 0.0% | Pending +SHC_3BB0A8C1_0x0049AF50 | 12.9% | Style pass, asm differs SHC_3BB0A8C1_0x0049B000 | 0.0% | Pending SHC_3BB0A8C1_0x0049B1C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0049B1D0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049B1D0 | 86.2% | Style pass, asm differs SHC_3BB0A8C1_0x0049B2B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049B5B0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049B5B0 | 66.9% | Style pass, asm differs SHC_3BB0A8C1_0x0049B6B0 | 0.0% | Pending SHC_3BB0A8C1_0x0049B8C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049B940 | 0.0% | Pending +SHC_3BB0A8C1_0x0049B940 | 70.3% | Style pass, asm differs SHC_3BB0A8C1_0x0049BA30 | 0.0% | Pending SHC_3BB0A8C1_0x0049BA90 | 0.0% | Pending -SHC_3BB0A8C1_0x0049BBF0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049BBF0 | 49.0% | Style pass, asm differs SHC_3BB0A8C1_0x0049BCD0 | 0.0% | Pending SHC_3BB0A8C1_0x0049BD40 | 0.0% | Pending -SHC_3BB0A8C1_0x0049BE60 | 0.0% | Pending +SHC_3BB0A8C1_0x0049BE60 | 48.0% | Style pass, asm differs -SHC_3BB0A8C1_0x0049C020 | 0.0% | Pending +SHC_3BB0A8C1_0x0049C020 | 61.0% | Style pass, asm differs SHC_3BB0A8C1_0x0049C100 | 0.0% | Pending @@ -24655,93 +24655,93 @@ SHC_3BB0A8C1_0x0049C360 | 0.0% | Pending SHC_3BB0A8C1_0x0049C361 | 0.0% | Pending -SHC_3BB0A8C1_0x0049C370 | 0.0% | Pending +SHC_3BB0A8C1_0x0049C370 | 44.0% | Style pass, asm differs SHC_3BB0A8C1_0x0049C4A0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049C5C0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049C5C0 | 37.6% | Style pass, asm differs -SHC_3BB0A8C1_0x0049C690 | 0.0% | Pending +SHC_3BB0A8C1_0x0049C690 | 71.9% | Style pass, asm differs SHC_3BB0A8C1_0x0049C730 | 0.0% | Pending -SHC_3BB0A8C1_0x0049CB00 | 0.0% | Pending +SHC_3BB0A8C1_0x0049CB00 | 51.1% | Style pass, asm differs SHC_3BB0A8C1_0x0049CBE0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049CD60 | 0.0% | Pending +SHC_3BB0A8C1_0x0049CD60 | 29.2% | Style pass, asm differs SHC_3BB0A8C1_0x0049CDB0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049CE40 | 0.0% | Pending +SHC_3BB0A8C1_0x0049CE40 | 51.1% | Style pass, asm differs SHC_3BB0A8C1_0x0049CF30 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D0E0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049D0E0 | 52.7% | Style pass, asm differs SHC_3BB0A8C1_0x0049D240 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D340 | 0.0% | Pending +SHC_3BB0A8C1_0x0049D340 | 64.6% | Style pass, asm differs SHC_3BB0A8C1_0x0049D470 | 0.0% | Pending SHC_3BB0A8C1_0x0049D520 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D640 | 0.0% | Pending +SHC_3BB0A8C1_0x0049D640 | 77.1% | Style pass, asm differs -SHC_3BB0A8C1_0x0049D880 | 0.0% | Pending +SHC_3BB0A8C1_0x0049D880 | 52.4% | Style pass, asm differs SHC_3BB0A8C1_0x0049D970 | 0.0% | Pending -SHC_3BB0A8C1_0x0049DB30 | 0.0% | Pending +SHC_3BB0A8C1_0x0049DB30 | 78.1% | Style pass, asm differs -SHC_3BB0A8C1_0x0049DDC0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049DDC0 | 35.7% | Style pass, asm differs -SHC_3BB0A8C1_0x0049E0D0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049E0D0 | 86.5% | Style pass, asm differs -SHC_3BB0A8C1_0x0049E510 | 0.0% | Pending +SHC_3BB0A8C1_0x0049E510 | 90.8% | Style pass, asm differs -SHC_3BB0A8C1_0x0049E9E0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049E9E0 | 69.4% | Style pass, asm differs SHC_3BB0A8C1_0x0049EB00 | 0.0% | Pending -SHC_3BB0A8C1_0x0049EDF0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049EDF0 | 62.5% | Style pass, asm differs SHC_3BB0A8C1_0x0049EED0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049F040 | 0.0% | Pending +SHC_3BB0A8C1_0x0049F040 | 79.5% | Style pass, asm differs -SHC_3BB0A8C1_0x0049F2D0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049F2D0 | 78.7% | Style pass, asm differs -SHC_3BB0A8C1_0x0049F540 | 0.0% | Pending +SHC_3BB0A8C1_0x0049F540 | 78.8% | Style pass, asm differs -SHC_3BB0A8C1_0x0049F7D0 | 0.0% | Pending +SHC_3BB0A8C1_0x0049F7D0 | 19.7% | Style pass, asm differs SHC_3BB0A8C1_0x0049F9B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049FC00 | 0.0% | Pending +SHC_3BB0A8C1_0x0049FC00 | 56.5% | Style pass, asm differs SHC_3BB0A8C1_0x0049FD10 | 0.0% | Pending SHC_3BB0A8C1_0x0049FD70 | 0.0% | Pending -SHC_3BB0A8C1_0x0049FF20 | 0.0% | Pending +SHC_3BB0A8C1_0x0049FF20 | 65.3% | Style pass, asm differs SHC_3BB0A8C1_0x004A0050 | 0.0% | Pending -SHC_3BB0A8C1_0x004A01D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A01D0 | 54.6% | Style pass, asm differs SHC_3BB0A8C1_0x004A0300 | 0.0% | Pending -SHC_3BB0A8C1_0x004A0460 | 0.0% | Pending +SHC_3BB0A8C1_0x004A0460 | 66.7% | Style pass, asm differs -SHC_3BB0A8C1_0x004A06B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A06B0 | 60.1% | Style pass, asm differs SHC_3BB0A8C1_0x004A07C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A08E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A08E0 | 84.5% | Style pass, asm differs -SHC_3BB0A8C1_0x004A0B20 | 0.0% | Pending +SHC_3BB0A8C1_0x004A0B20 | 65.2% | Style pass, asm differs SHC_3BB0A8C1_0x004A0BD0 | 0.0% | Pending @@ -24875,9 +24875,9 @@ SHC_3BB0A8C1_0x004A0E4A | 0.0% | Pending SHC_3BB0A8C1_0x004A0E4B | 0.0% | Pending -SHC_3BB0A8C1_0x004A0E50 | 0.0% | Pending +SHC_3BB0A8C1_0x004A0E50 | 93.1% | Style pass, asm differs -SHC_3BB0A8C1_0x004A1230 | 0.0% | Pending +SHC_3BB0A8C1_0x004A1230 | 59.4% | Style pass, asm differs SHC_3BB0A8C1_0x004A1568 | 0.0% | Pending @@ -25011,9 +25011,9 @@ SHC_3BB0A8C1_0x004A15AE | 0.0% | Pending SHC_3BB0A8C1_0x004A15AF | 0.0% | Pending -SHC_3BB0A8C1_0x004A15B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A15B0 | 28.4% | Style pass, asm differs -SHC_3BB0A8C1_0x004A16C0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A16C0 | 90.0% | Style pass, asm differs SHC_3BB0A8C1_0x004A1800 | 0.0% | Pending @@ -25163,29 +25163,29 @@ SHC_3BB0A8C1_0x004A19AD | 0.0% | Pending SHC_3BB0A8C1_0x004A19AE | 0.0% | Pending -SHC_3BB0A8C1_0x004A19B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A19B0 | 57.2% | Style pass, asm differs SHC_3BB0A8C1_0x004A1AF0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A1C40 | 0.0% | Pending +SHC_3BB0A8C1_0x004A1C40 | 74.3% | Style pass, asm differs SHC_3BB0A8C1_0x004A1CC0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A1D30 | 0.0% | Pending +SHC_3BB0A8C1_0x004A1D30 | 65.7% | Style pass, asm differs SHC_3BB0A8C1_0x004A1E10 | 0.0% | Pending -SHC_3BB0A8C1_0x004A21B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A21B0 | 57.9% | Style pass, asm differs SHC_3BB0A8C1_0x004A22C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A2650 | 0.0% | Pending +SHC_3BB0A8C1_0x004A2650 | 64.8% | Style pass, asm differs SHC_3BB0A8C1_0x004A2740 | 0.0% | Pending SHC_3BB0A8C1_0x004A27D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A2A90 | 0.0% | Pending +SHC_3BB0A8C1_0x004A2A90 | 54.4% | Style pass, asm differs SHC_3BB0A8C1_0x004A2B70 | 0.0% | Pending @@ -25201,27 +25201,27 @@ SHC_3BB0A8C1_0x004A2DC4 | 0.0% | Pending SHC_3BB0A8C1_0x004A2DC8 | 0.0% | Pending -SHC_3BB0A8C1_0x004A2DD0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A2DD0 | 75.3% | Style pass, asm differs SHC_3BB0A8C1_0x004A2F00 | 0.0% | Pending SHC_3BB0A8C1_0x004A31D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A3220 | 0.0% | Pending +SHC_3BB0A8C1_0x004A3220 | 63.8% | Style pass, asm differs -SHC_3BB0A8C1_0x004A36B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A36B0 | 40.9% | Style pass, asm differs SHC_3BB0A8C1_0x004A37D0 | 0.0% | Pending SHC_3BB0A8C1_0x004A3860 | 0.0% | Pending -SHC_3BB0A8C1_0x004A3B20 | 0.0% | Pending +SHC_3BB0A8C1_0x004A3B20 | 33.8% | Style pass, asm differs SHC_3BB0A8C1_0x004A3E80 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4140 | 0.0% | Pending +SHC_3BB0A8C1_0x004A4140 | 83.9% | Style pass, asm differs -SHC_3BB0A8C1_0x004A4470 | 0.0% | Pending +SHC_3BB0A8C1_0x004A4470 | 47.1% | Style pass, asm differs SHC_3BB0A8C1_0x004A4500 | 0.0% | Pending @@ -25229,15 +25229,15 @@ SHC_3BB0A8C1_0x004A4550 | 0.0% | Pending SHC_3BB0A8C1_0x004A46C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4930 | 0.0% | Pending +SHC_3BB0A8C1_0x004A4930 | 65.8% | ClimbData stride bug fixed -SHC_3BB0A8C1_0x004A4B30 | 0.0% | Pending +SHC_3BB0A8C1_0x004A4B30 | 79.0% | Style pass, asm differs SHC_3BB0A8C1_0x004A4B80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A4BB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A4BB0 | 24.4% | Style pass, asm differs -SHC_3BB0A8C1_0x004A4C70 | 0.0% | Pending +SHC_3BB0A8C1_0x004A4C70 | 89.8% | Style pass, asm differs SHC_3BB0A8C1_0x004A4D60 | 0.0% | Pending @@ -25249,61 +25249,61 @@ SHC_3BB0A8C1_0x004A50E0 | 0.0% | Pending SHC_3BB0A8C1_0x004A5230 | 0.0% | Pending -SHC_3BB0A8C1_0x004A52D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A52D0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A5320 | 0.0% | Pending +SHC_3BB0A8C1_0x004A5320 | 16.1% | Style pass, asm differs SHC_3BB0A8C1_0x004A5420 | 0.0% | Pending SHC_3BB0A8C1_0x004A5770 | 0.0% | Pending -SHC_3BB0A8C1_0x004A58A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A58A0 | 14.6% | Style pass, asm differs SHC_3BB0A8C1_0x004A5980 | 0.0% | Pending SHC_3BB0A8C1_0x004A5A30 | 0.0% | Pending -SHC_3BB0A8C1_0x004A5B00 | 0.0% | Pending +SHC_3BB0A8C1_0x004A5B00 | 57.4% | Style pass, asm differs -SHC_3BB0A8C1_0x004A5DA0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A5DA0 | 76.0% | Style pass, asm differs SHC_3BB0A8C1_0x004A5F60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A5F90 | 0.0% | Pending +SHC_3BB0A8C1_0x004A5F90 | 82.9% | Style pass, asm differs -SHC_3BB0A8C1_0x004A6010 | 0.0% | Pending +SHC_3BB0A8C1_0x004A6010 | 37.0% | Style pass, asm differs SHC_3BB0A8C1_0x004A6120 | 0.0% | Pending -SHC_3BB0A8C1_0x004A6520 | 0.0% | Pending +SHC_3BB0A8C1_0x004A6520 | 95.7% | Style pass, asm differs -SHC_3BB0A8C1_0x004A65E0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A65E0 | 68.8% | Style pass, asm differs -SHC_3BB0A8C1_0x004A66D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A66D0 | 83.1% | Style pass, asm differs -SHC_3BB0A8C1_0x004A67D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A67D0 | 72.1% | Style pass, asm differs SHC_3BB0A8C1_0x004A6940 | 0.0% | Pending -SHC_3BB0A8C1_0x004A69F0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A69F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A6AB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A6AB0 | 27.8% | Style pass, asm differs SHC_3BB0A8C1_0x004A6BE0 | 0.0% | Pending SHC_3BB0A8C1_0x004A6C40 | 0.0% | Pending -SHC_3BB0A8C1_0x004A6DF0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A6DF0 | 78.8% | Style pass, asm differs SHC_3BB0A8C1_0x004A6ED0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A7090 | 0.0% | Pending +SHC_3BB0A8C1_0x004A7090 | 89.9% | Style pass, asm differs -SHC_3BB0A8C1_0x004A75B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A75B0 | 24.4% | Style pass, asm differs -SHC_3BB0A8C1_0x004A79A0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A79A0 | 37.8% | Style pass, asm differs -SHC_3BB0A8C1_0x004A7F50 | 0.0% | Pending +SHC_3BB0A8C1_0x004A7F50 | 49.5% | Style pass, asm differs SHC_3BB0A8C1_0x004A80B0 | 0.0% | Pending @@ -25311,15 +25311,15 @@ SHC_3BB0A8C1_0x004A8220 | 0.0% | Pending SHC_3BB0A8C1_0x004A8340 | 0.0% | Pending -SHC_3BB0A8C1_0x004A83B0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A83B0 | 60.4% | Style pass, asm differs -SHC_3BB0A8C1_0x004A8780 | 0.0% | Pending +SHC_3BB0A8C1_0x004A8780 | 40.8% | Style pass, asm differs -SHC_3BB0A8C1_0x004A8860 | 0.0% | Pending +SHC_3BB0A8C1_0x004A8860 | 34.7% | Style pass, asm differs SHC_3BB0A8C1_0x004A8900 | 0.0% | Pending -SHC_3BB0A8C1_0x004A8AB0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A8AB0 | 58.3% | Style pass, asm differs SHC_3BB0A8C1_0x004A91B0 | 0.0% | Pending @@ -25453,23 +25453,23 @@ SHC_3BB0A8C1_0x004A91F6 | 0.0% | Pending SHC_3BB0A8C1_0x004A91F7 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9200 | 0.0% | Pending +SHC_3BB0A8C1_0x004A9200 | 43.3% | Style pass, asm differs SHC_3BB0A8C1_0x004A94E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A9510 | 0.0% | Pending +SHC_3BB0A8C1_0x004A9510 | 54.0% | Style pass, asm differs -SHC_3BB0A8C1_0x004A9680 | 0.0% | Pending +SHC_3BB0A8C1_0x004A9680 | 84.5% | Style pass, asm differs SHC_3BB0A8C1_0x004A96B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9760 | 0.0% | Pending +SHC_3BB0A8C1_0x004A9760 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A97D0 | 0.0% | Pending +SHC_3BB0A8C1_0x004A97D0 | 20.0% | Style pass, asm differs SHC_3BB0A8C1_0x004A98C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9B20 | 0.0% | Pending +SHC_3BB0A8C1_0x004A9B20 | 31.5% | Style pass, asm differs SHC_3BB0A8C1_0x004A9DD0 | 100.0% | Reimplemented From ddb641996cdbb50e0387dd97d5cef4820d0aa866 Mon Sep 17 00:00:00 2001 From: Gynt Date: Wed, 14 Oct 2026 23:43:26 +0200 Subject: [PATCH 2/7] restyle asm macro file --- .../Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp b/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp index 258744835..0d64d5578 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/LinkageNeighbourAsm.hpp @@ -37,7 +37,8 @@ int _tile, _cY, _cLink short _curGen, _cCardinalDistance - and takes the queue end as the WRITEIDX macro argument, which it advances. It clobbers eax, ebx, ecx, edx, esi and edi. + and takes the queue end as the WRITEIDX macro argument, which it advances. It clobbers eax, ebx, ecx, edx, esi and + edi. ID must be unique within the enclosing function; it exists only to keep the assembler labels of two expansions apart. From d97f2aa32a4c69ff72a8c59cdb32d7bae37751d3 Mon Sep 17 00:00:00 2001 From: Gynt Date: Fri, 16 Oct 2026 22:23:52 +0200 Subject: [PATCH 3/7] style: restyle the 100% PathFindingState reimplementations Bring the twelve PathFindingState .cpp files that already match the original binary to the style used on main, and verify every one of them still matches: - drop the decompiler's comment blocks (decompilerscript, WARNING: Enum) and the duplicate include of the file's own .func.hpp - clearActiveClimbDataOfType6And7: the two lockstep pointers over climbData become a counted for loop over named fields, the trailing return goes - clearPathFindingTileMaps: sizeof(layer) instead of 0x27420/0x13a10, and the layer passed straight through instead of (void*)((int)(...)) - computeAttackVectorsBasedOnXAndY: iVar1/_index named, += 1 instead of x = x + 1, 80400 instead of 0x13a10, de-yoda'd bound test - reflow the clearActiveClimbDataOfType6And7 doc comment reccmp before and after: all twelve at 100.0%, normalized 100.0%. Co-Authored-By: Claude Opus 5 --- .../Constructor_PathFindingState.cpp | 5 --- .../clearActiveClimbDataOfType6And7.cpp | 33 ++++++++--------- .../clearPathFindingTileMaps.cpp | 16 +++------ .../computeAttackVectorsBasedOnXAndY.cpp | 35 +++++++------------ 4 files changed, 33 insertions(+), 56 deletions(-) diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp index b4eac3e66..b4bc9d9cb 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/Constructor_PathFindingState.cpp @@ -1,14 +1,9 @@ #include "../PathFindingState.func.hpp" -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" - namespace OpenSHC { namespace Map { namespace Navigation { - /* - decompilerscript: committed: 2025-01-30 21:57:43.216000 - */ // FUNCTION: STRONGHOLDCRUSADER 0x004A9760 PathFindingState* PathFindingState::Constructor_PathFindingState() { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp index 08ca1960f..9d5494267 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp @@ -1,35 +1,32 @@ #include "../PathFindingState.func.hpp" -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" - namespace OpenSHC { namespace Map { namespace Navigation { /* - Iterates all climb data entries (1 to maxClimbDataCount) and calls clearLaddermanWalledData on any entry - that is active (canBeUsed != 0) and has type 6 or 7. The semantics of types 6 and 7 are not yet fully known; - this is likely called during a siege reset or wall state change. renamed by: Claude Sonnet 4.6 + Iterates all climb data entries (1 to maxClimbDataCount) and calls clearLaddermanWalledData on + any entry that is active (canBeUsed != 0) and has type 6 or 7. The semantics of types 6 and 7 + are not yet fully known; this is likely called during a siege reset or wall state change. + + renamed by: Claude Sonnet 4.6 */ + // FUNCTION: STRONGHOLDCRUSADER 0x004A52D0 void PathFindingState::clearActiveClimbDataOfType6And7() { - int* piVar2; - int iVar1 = 1; - piVar2 = &this->climbData[1].type; - do { - if (((ClimbData*)(piVar2 + -1))->canBeUsed != 0) { - if (*piVar2 == 6) { - MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearClimbData, this)(iVar1); + for (int climbID = 1; climbID < 200; ++climbID) { + if (this->climbData[climbID].canBeUsed != 0) { + if (this->climbData[climbID].type == 6) { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearClimbData, this)( + climbID); } - if (*piVar2 == 7) { - MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearClimbData, this)(iVar1); + if (this->climbData[climbID].type == 7) { + MACRO_CALL_MEMBER(OpenSHC::Map::Navigation::PathFindingState_Func::clearClimbData, this)( + climbID); } } - iVar1 = iVar1 + 1; - piVar2 = piVar2 + 0x81; - } while (iVar1 < 200); - return; + } } } diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp index 2d6d4522d..a775184be 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearPathFindingTileMaps.cpp @@ -9,24 +9,18 @@ namespace OpenSHC { namespace Map { namespace Navigation { - /* - WARNING: Enum "MappersEnum": Some values do not have unique names - */ - /* - decompilerscript: committed: 2025-01-30 21:57:43.216000 - */ // FUNCTION: STRONGHOLDCRUSADER 0x00496E40 void PathFindingState::clearPathFindingTileMaps() { MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( - 0x27420, '\0', (void*)((int)(DAT_TileMapState::instance.PathConnectionLayer))); + sizeof(DAT_TileMapState::instance.PathConnectionLayer), 0, + DAT_TileMapState::instance.PathConnectionLayer); MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( - 0x13a10, '\0', (void*)((int)(DAT_TileMapState::instance.PathLinkageLayer))); + sizeof(DAT_TileMapState::instance.PathLinkageLayer), 0, DAT_TileMapState::instance.PathLinkageLayer); MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( - 0x27420, '\0', (void*)((int)(DAT_TileMapState::instance.CertainPathLayer))); + sizeof(DAT_TileMapState::instance.CertainPathLayer), 0, DAT_TileMapState::instance.CertainPathLayer); MACRO_CALL_MEMBER(OpenSHC::IO::LowLevelMemory_Func::fillMemory_ByteValue, DAT_LowLevelMemory::ptr)( - 0x27420, '\0', (void*)((int)(DAT_TileMapState::instance.WalkLayer))); - return; + sizeof(DAT_TileMapState::instance.WalkLayer), 0, DAT_TileMapState::instance.WalkLayer); } } diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp index 19de23dd2..870c07faf 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp @@ -1,7 +1,5 @@ #include "../PathFindingState.func.hpp" -#include "OpenSHC/Map/Navigation/PathFindingState.func.hpp" - #include "OpenSHC/Globals/DAT_GameState.hpp" #include "OpenSHC/Globals/DAT_TileMapState.hpp" #include "OpenSHC/Globals/DAT_ViewportRenderState.hpp" @@ -10,43 +8,36 @@ namespace OpenSHC { namespace Map { namespace Navigation { - /* - WARNING: Enum "MappersEnum": Some values do not have unique names - */ - /* - decompilerscript: committed: 2025-01-30 21:57:43.216000 - */ // FUNCTION: STRONGHOLDCRUSADER 0x004A69F0 void PathFindingState::computeAttackVectorsBasedOnXAndY(int playerID) { - this->calculations = this->calculations + 1; - int _index = 0; + this->calculations += 1; + int attackVectorIndex = 0; this->searchQueue.readIndex = 0; if (this->searchQueue.writeIndex != 0) { do { uint y = (uint)this->searchQueue.yQueue[this->searchQueue.readIndex]; - int iVar1 = this->searchQueue.tilesQueue[this->searchQueue.readIndex]; - uint x = iVar1 - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; - if (DAT_TileMapState::instance.CertainPathLayer[iVar1] != 100) { + int tile = this->searchQueue.tilesQueue[this->searchQueue.readIndex]; + uint x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + if (DAT_TileMapState::instance.CertainPathLayer[tile] != 100) { MACRO_CALL_MEMBER( OpenSHC::Map::Navigation::PathFindingState_Func::budgetFloodFillOnCertainPathLayer, this)( x, y, 100, 100); - DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].x = x; - DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].y = y; - DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].tribeUIDUnk = 0; - DAT_GameState::instance.mapAndTime.attackVectors[playerID][_index].tribeID = 0; - _index = _index + 1; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].x = x; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].y = y; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].tribeUIDUnk = 0; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].tribeID = 0; + attackVectorIndex += 1; } - if (_index >= 50) { + if (attackVectorIndex >= 50) { return; } - this->searchQueue.readIndex = this->searchQueue.readIndex + 1; - if (0x13a10 <= (int)this->searchQueue.readIndex) { + this->searchQueue.readIndex += 1; + if ((int)this->searchQueue.readIndex >= 80400) { this->searchQueue.readIndex = 0; } } while (this->searchQueue.readIndex != this->searchQueue.writeIndex); } - return; } } From c99ba91153e29d65907b8284daa8b9380ccfa9b5 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sat, 17 Oct 2026 23:57:21 +0200 Subject: [PATCH 4/7] improve style, improve while loop, remove comments --- .../clearActiveClimbDataOfType6And7.cpp | 8 ---- .../computeAttackVectorsBasedOnXAndY.cpp | 44 +++++++++---------- .../getComputationalTileIndex.cpp | 6 +-- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp index 9d5494267..a14ce50dd 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/clearActiveClimbDataOfType6And7.cpp @@ -4,14 +4,6 @@ namespace OpenSHC { namespace Map { namespace Navigation { - /* - Iterates all climb data entries (1 to maxClimbDataCount) and calls clearLaddermanWalledData on - any entry that is active (canBeUsed != 0) and has type 6 or 7. The semantics of types 6 and 7 - are not yet fully known; this is likely called during a siege reset or wall state change. - - renamed by: Claude Sonnet 4.6 - */ - // FUNCTION: STRONGHOLDCRUSADER 0x004A52D0 void PathFindingState::clearActiveClimbDataOfType6And7() { diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp index 870c07faf..557b2d84e 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp @@ -14,29 +14,27 @@ namespace Map { this->calculations += 1; int attackVectorIndex = 0; this->searchQueue.readIndex = 0; - if (this->searchQueue.writeIndex != 0) { - do { - uint y = (uint)this->searchQueue.yQueue[this->searchQueue.readIndex]; - int tile = this->searchQueue.tilesQueue[this->searchQueue.readIndex]; - uint x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; - if (DAT_TileMapState::instance.CertainPathLayer[tile] != 100) { - MACRO_CALL_MEMBER( - OpenSHC::Map::Navigation::PathFindingState_Func::budgetFloodFillOnCertainPathLayer, this)( - x, y, 100, 100); - DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].x = x; - DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].y = y; - DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].tribeUIDUnk = 0; - DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].tribeID = 0; - attackVectorIndex += 1; - } - if (attackVectorIndex >= 50) { - return; - } - this->searchQueue.readIndex += 1; - if ((int)this->searchQueue.readIndex >= 80400) { - this->searchQueue.readIndex = 0; - } - } while (this->searchQueue.readIndex != this->searchQueue.writeIndex); + while (this->searchQueue.readIndex != this->searchQueue.writeIndex) { + uint y = (uint)this->searchQueue.yQueue[this->searchQueue.readIndex]; + int tile = this->searchQueue.tilesQueue[this->searchQueue.readIndex]; + uint x = tile - DAT_ViewportRenderState::instance.translationMatrix[y].addXgetTile; + if (DAT_TileMapState::instance.CertainPathLayer[tile] != 100) { + MACRO_CALL_MEMBER( + OpenSHC::Map::Navigation::PathFindingState_Func::budgetFloodFillOnCertainPathLayer, this)( + x, y, 100, 100); + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].x = x; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].y = y; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].tribeUIDUnk = 0; + DAT_GameState::instance.mapAndTime.attackVectors[playerID][attackVectorIndex].tribeID = 0; + attackVectorIndex += 1; + } + if (attackVectorIndex >= 50) { + return; + } + this->searchQueue.readIndex += 1; + if ((int)this->searchQueue.readIndex >= 80400) { + this->searchQueue.readIndex = 0; + } } } diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp index 617aa511e..84f0c75fe 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/getComputationalTileIndex.cpp @@ -7,6 +7,6 @@ namespace Map { // FUNCTION: STRONGHOLDCRUSADER 0x00496E20 undefined4 PathFindingState::getComputationalTileIndex() { return this->searchQueue.writeIndex; } - } // namespace Navigation -} // namespace Map -} // namespace OpenSHC + } +} +} From 6fefa7d10e1649e47fd69a8c006be946d8d72178 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 23:07:07 +0200 Subject: [PATCH 5/7] Remove /Od and pragma optimize references everywhere --- AGENTS.md | 10 +--------- tools/mcp/AGENTS.md | 2 +- tools/reimplementation-helper/batch/README.md | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c2626a4a9..504cf3cfb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -161,13 +161,7 @@ restyling anything large: - a frame pointer plus a `this` spill - the original was built without optimisation, **unless the same function also reports `mov reg, 0`**. MSVC keeps `ebp` in any function containing an `__asm` block, so for a function with handwritten assembly the frame pointer says nothing about the optimisation level: reimplement the handwritten part as - inline asm and leave the rest at `/O2`. Checking the prologue settles it - values kept in registers across the entry - tests mean `/O2`. Taking the `/Od` reading instead took `findLinkageBasedPathOrWalkRadius` from 5.1% to 2.8%, where - the same body without the pragma reaches 49.2%. When it really is `/Od`, add `#pragma optimize(, off)` - around the function; inline asm alone does not disable optimisation. Then match the reported **frame size** exactly, - which is usually the single biggest win, because every local displacement shifts otherwise. Merge locals that share a - slot and reproduce dead stores. At `/Od` prefer a nested `if` over an early `continue` (the original inverts the test - and jumps to the loop's continue trampoline), and declare locals together at the top of the function. + inline asm. - a jump table - Ghidra usually renders the dispatch as a call through an unnamed pointer array and drops the arms, so rebuild the `switch` from the byte and jump tables instead of restyling the decompiler output. @@ -327,8 +321,6 @@ Diff patterns that were reliable (more in the cheat sheet): - Trust the asm over the decompilation for constants and their sign. Ghidra rendered `2400 / n + 40` where the binary has `sub eax, 0x28`, so the formula is `- 40`; the function reached 100% once corrected (`diff_types.py` finds these). A `(longlong)` in a Ghidra division is usually spurious too - it emits `_alldiv` where the original has a plain `idiv`. -- MSVC1400 at `/O2` never unrolls a loop, so a body repeated N times in the asm means the source was written out N - times. A plain loop where the original is unrolled has cost 80 points on its own. - A flag stored with `mov dword ptr [..], 0/1` is an `int`, not a `bool`, which stores a byte. - Tentative, one clear case so far: where two arms of a condition share a tail, the nested `if/else` shape the decompiler emits can beat the early returns the style list above asks for, because it decides *which* arm holds the diff --git a/tools/mcp/AGENTS.md b/tools/mcp/AGENTS.md index d32335882..a440b9452 100644 --- a/tools/mcp/AGENTS.md +++ b/tools/mcp/AGENTS.md @@ -27,7 +27,7 @@ We want to generate assembly that matches the original binary. Each function has 1. Use `read_cpp_code_for_function` to take in the current reimplemented code for a function, which are always specified by their full namespace name, e.g. `OpenSHC::Rendering::ViewportRenderState::xyAreValid`. 2. Use `compile_cpp_code_for_function` to write the reimplemented code to the cpp file and compile the project. If there are compilation problems, try to address them. - The project is compiled using `MSVC1400` with the /Zi and /O2 flags. Use `#pragma optimize()` variations in case of issues with byte matches. + The project is compiled using `MSVC1400` with the /Zi and /O2 flags. Don't use `#pragma optimize()` variations in case of issues with byte matches, they never lead to productive matches. The project's layout is like so: methods starting with a non-capital letter are class methods. The include file for a namespace `A::B::C` is `A/B/C.hpp`. Namespaces usually need to be referred to explicitly in the case of enum constants for example. Globals usually start with three or more capital letters, like `DAT_` and can be found in `OpenSHC/Globals/.hpp`. So if global GreatGlobal is missing, find it here `OpenSHC/Globals/GreatGlobal.hpp`. These globals need to be accessed with `::ptr`, like `DAT_Example::ptr` to get a pointer. `DAT_ExampleArray[100]` becomes `(*DAT_ExampleArray::ptr)[100]`. diff --git a/tools/reimplementation-helper/batch/README.md b/tools/reimplementation-helper/batch/README.md index 7f93f6164..e46210bf6 100644 --- a/tools/reimplementation-helper/batch/README.md +++ b/tools/reimplementation-helper/batch/README.md @@ -15,7 +15,7 @@ rewrite sources, because the Visual Studio bundled one is too old for `.clang-fo | `build_quiet.py [--keep-going]` | `build.bat RelWithDebInfo OpenSHC.dll`, prints only errors and `BUILD_OK`/`BUILD_FAIL` (build.bat exits 0 even on errors). Retries once on a PDB server error, see the note below. | | `syntax_check.py [substr...]` | `cl /Zs` every (matching) list file serially; finds all compile errors in one pass without linking. | | `reccmp_report.py [--run] pct\|save\|cmp\|diff` | Match % and *normalized* % (call/tail-jump targets and resolver addresses ignored) per function, snapshots, before/after comparison, compact asm diffs. | -| `orig_asm.py NAME [--both\|--stats]` | The **original** instruction stream of one function (not the interleaved diff), in address order; `--stats` reports the tells that decide how to reimplement it: `mov reg, 0` (handwritten asm), frame pointer (built /Od), frame size, jump tables. | +| `orig_asm.py NAME [--both\|--stats]` | The **original** instruction stream of one function (not the interleaved diff), in address order; `--stats` reports the tells that decide how to reimplement it: `mov reg, 0` (handwritten asm), frame pointer, frame size, jump tables. | | `show_functions.py PREFIX [--skip-100]` | Print function bodies under `src/OpenSHC/PREFIX` with their percentages, in the block format `splice_functions.py` reads. | | `splice_functions.py BLOCKS.txt` | Replace many function bodies at once (keeps the `// FUNCTION:` line, can add includes/usings), then clang-format. | | `commit_progress_batch.py PREFIX... [Name=remark]` | One `reimplement:` commit per changed function with its status line, like `commit_progress`. | From 0a554eed845501024726cfb9c9f78538bafa4d80 Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 23:10:41 +0200 Subject: [PATCH 6/7] Change 80400 to map constants --- .../PathFindingState/computeAttackVectorsBasedOnXAndY.cpp | 2 +- .../updatePathLinkageLayerForEachBuildingAtEachTile.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp index 557b2d84e..9bc5c4a60 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/computeAttackVectorsBasedOnXAndY.cpp @@ -32,7 +32,7 @@ namespace Map { return; } this->searchQueue.readIndex += 1; - if ((int)this->searchQueue.readIndex >= 80400) { + if ((int)this->searchQueue.readIndex >= Map::MC_MAP_TILES_COUNT) { this->searchQueue.readIndex = 0; } } diff --git a/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp b/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp index 6e5712ada..e5117e7a5 100644 --- a/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp +++ b/src/OpenSHC/Map/Navigation/PathFindingState/updatePathLinkageLayerForEachBuildingAtEachTile.cpp @@ -9,7 +9,7 @@ namespace Map { // FUNCTION: STRONGHOLDCRUSADER 0x004A5F60 void PathFindingState::updatePathLinkageLayerForEachBuildingAtEachTile() { - for (int tileIndex = 0; tileIndex < 80400; ++tileIndex) { + for (int tileIndex = 0; tileIndex < Map::MC_MAP_TILES_COUNT; ++tileIndex) { MACRO_CALL_MEMBER( OpenSHC::Map::Navigation::PathFindingState_Func::updatePathLinkageLayerBasedOnBuildingsUnk, this)( DAT_ViewportRenderState::instance.tileTranslationMatrix_YComponent[tileIndex], tileIndex); From 037fa0500e9937300b1934a63eb4d9f8f1a034ea Mon Sep 17 00:00:00 2001 From: Gynt Date: Sun, 18 Oct 2026 23:56:19 +0200 Subject: [PATCH 7/7] Limit status file changes to functions touched in this branch Revert the 102 unrelated percentage/status updates in status/addresses-SHC-3BB0A8C1.txt back to main, keeping only the four addresses whose .cpp files are added or modified in this branch. Co-Authored-By: Claude Opus 5 (1M context) --- status/addresses-SHC-3BB0A8C1.txt | 204 +++++++++++++++--------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/status/addresses-SHC-3BB0A8C1.txt b/status/addresses-SHC-3BB0A8C1.txt index d8d2dbd2d..08355a44b 100644 --- a/status/addresses-SHC-3BB0A8C1.txt +++ b/status/addresses-SHC-3BB0A8C1.txt @@ -24351,99 +24351,99 @@ SHC_3BB0A8C1_0x00496E40 | 100.0% | Reimplemented SHC_3BB0A8C1_0x00496EA0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x00496EC0 | 47.5% | Style pass, asm differs +SHC_3BB0A8C1_0x00496EC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00496F90 | 20.0% | Style pass, asm differs +SHC_3BB0A8C1_0x00496F90 | 0.0% | Pending -SHC_3BB0A8C1_0x00497080 | 34.0% | Style pass, asm differs +SHC_3BB0A8C1_0x00497080 | 0.0% | Pending -SHC_3BB0A8C1_0x00497180 | 29.4% | Style pass, asm differs +SHC_3BB0A8C1_0x00497180 | 0.0% | Pending -SHC_3BB0A8C1_0x00497280 | 48.9% | Style pass, asm differs +SHC_3BB0A8C1_0x00497280 | 0.0% | Pending -SHC_3BB0A8C1_0x004974D0 | 30.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004974D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00497690 | 13.6% | Style pass, asm differs +SHC_3BB0A8C1_0x00497690 | 0.0% | Pending -SHC_3BB0A8C1_0x00497740 | 49.2% | Style pass, asm differs +SHC_3BB0A8C1_0x00497740 | 0.0% | Pending -SHC_3BB0A8C1_0x00497B80 | 51.7% | Style pass, asm differs +SHC_3BB0A8C1_0x00497B80 | 0.0% | Pending -SHC_3BB0A8C1_0x00498020 | 54.8% | Style pass, asm differs +SHC_3BB0A8C1_0x00498020 | 0.0% | Pending SHC_3BB0A8C1_0x00498170 | 0.0% | Pending -SHC_3BB0A8C1_0x00498400 | 41.2% | Style pass, asm differs +SHC_3BB0A8C1_0x00498400 | 0.0% | Pending SHC_3BB0A8C1_0x004985D0 | 0.0% | Pending -SHC_3BB0A8C1_0x00498A40 | 78.3% | Style pass, asm differs +SHC_3BB0A8C1_0x00498A40 | 0.0% | Pending SHC_3BB0A8C1_0x00498B70 | 0.0% | Pending -SHC_3BB0A8C1_0x00498FD0 | 12.1% | Style pass, asm differs +SHC_3BB0A8C1_0x00498FD0 | 0.0% | Pending SHC_3BB0A8C1_0x004990F0 | 0.0% | Pending -SHC_3BB0A8C1_0x004995E0 | 49.3% | Style pass, asm differs +SHC_3BB0A8C1_0x004995E0 | 0.0% | Pending SHC_3BB0A8C1_0x00499970 | 0.0% | Pending -SHC_3BB0A8C1_0x004999C0 | 23.7% | Style pass, asm differs +SHC_3BB0A8C1_0x004999C0 | 0.0% | Pending -SHC_3BB0A8C1_0x00499DC0 | 42.9% | Style pass, asm differs +SHC_3BB0A8C1_0x00499DC0 | 0.0% | Pending -SHC_3BB0A8C1_0x00499FA0 | 24.4% | Style pass, asm differs +SHC_3BB0A8C1_0x00499FA0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049A1C0 | 48.3% | Style pass, asm differs +SHC_3BB0A8C1_0x0049A1C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049A2E0 | 25.9% | Style pass, asm differs +SHC_3BB0A8C1_0x0049A2E0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049A370 | 8.5% | Style pass, asm differs +SHC_3BB0A8C1_0x0049A370 | 0.0% | Pending -SHC_3BB0A8C1_0x0049A5E0 | 78.3% | Style pass, asm differs +SHC_3BB0A8C1_0x0049A5E0 | 0.0% | Pending SHC_3BB0A8C1_0x0049A610 | 0.0% | Pending -SHC_3BB0A8C1_0x0049A6D0 | 72.5% | Style pass, asm differs +SHC_3BB0A8C1_0x0049A6D0 | 0.0% | Pending SHC_3BB0A8C1_0x0049A800 | 0.0% | Pending -SHC_3BB0A8C1_0x0049AAD0 | 72.8% | Style pass, asm differs +SHC_3BB0A8C1_0x0049AAD0 | 0.0% | Pending SHC_3BB0A8C1_0x0049AC80 | 0.0% | Pending -SHC_3BB0A8C1_0x0049AF50 | 12.9% | Style pass, asm differs +SHC_3BB0A8C1_0x0049AF50 | 0.0% | Pending SHC_3BB0A8C1_0x0049B000 | 0.0% | Pending SHC_3BB0A8C1_0x0049B1C0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x0049B1D0 | 86.2% | Style pass, asm differs +SHC_3BB0A8C1_0x0049B1D0 | 0.0% | Pending SHC_3BB0A8C1_0x0049B2B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049B5B0 | 66.9% | Style pass, asm differs +SHC_3BB0A8C1_0x0049B5B0 | 0.0% | Pending SHC_3BB0A8C1_0x0049B6B0 | 0.0% | Pending SHC_3BB0A8C1_0x0049B8C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049B940 | 70.3% | Style pass, asm differs +SHC_3BB0A8C1_0x0049B940 | 0.0% | Pending SHC_3BB0A8C1_0x0049BA30 | 0.0% | Pending SHC_3BB0A8C1_0x0049BA90 | 0.0% | Pending -SHC_3BB0A8C1_0x0049BBF0 | 49.0% | Style pass, asm differs +SHC_3BB0A8C1_0x0049BBF0 | 0.0% | Pending SHC_3BB0A8C1_0x0049BCD0 | 0.0% | Pending SHC_3BB0A8C1_0x0049BD40 | 0.0% | Pending -SHC_3BB0A8C1_0x0049BE60 | 48.0% | Style pass, asm differs +SHC_3BB0A8C1_0x0049BE60 | 0.0% | Pending -SHC_3BB0A8C1_0x0049C020 | 61.0% | Style pass, asm differs +SHC_3BB0A8C1_0x0049C020 | 0.0% | Pending SHC_3BB0A8C1_0x0049C100 | 0.0% | Pending @@ -24655,93 +24655,93 @@ SHC_3BB0A8C1_0x0049C360 | 0.0% | Pending SHC_3BB0A8C1_0x0049C361 | 0.0% | Pending -SHC_3BB0A8C1_0x0049C370 | 44.0% | Style pass, asm differs +SHC_3BB0A8C1_0x0049C370 | 0.0% | Pending SHC_3BB0A8C1_0x0049C4A0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049C5C0 | 37.6% | Style pass, asm differs +SHC_3BB0A8C1_0x0049C5C0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049C690 | 71.9% | Style pass, asm differs +SHC_3BB0A8C1_0x0049C690 | 0.0% | Pending SHC_3BB0A8C1_0x0049C730 | 0.0% | Pending -SHC_3BB0A8C1_0x0049CB00 | 51.1% | Style pass, asm differs +SHC_3BB0A8C1_0x0049CB00 | 0.0% | Pending SHC_3BB0A8C1_0x0049CBE0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049CD60 | 29.2% | Style pass, asm differs +SHC_3BB0A8C1_0x0049CD60 | 0.0% | Pending SHC_3BB0A8C1_0x0049CDB0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049CE40 | 51.1% | Style pass, asm differs +SHC_3BB0A8C1_0x0049CE40 | 0.0% | Pending SHC_3BB0A8C1_0x0049CF30 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D0E0 | 52.7% | Style pass, asm differs +SHC_3BB0A8C1_0x0049D0E0 | 0.0% | Pending SHC_3BB0A8C1_0x0049D240 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D340 | 64.6% | Style pass, asm differs +SHC_3BB0A8C1_0x0049D340 | 0.0% | Pending SHC_3BB0A8C1_0x0049D470 | 0.0% | Pending SHC_3BB0A8C1_0x0049D520 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D640 | 77.1% | Style pass, asm differs +SHC_3BB0A8C1_0x0049D640 | 0.0% | Pending -SHC_3BB0A8C1_0x0049D880 | 52.4% | Style pass, asm differs +SHC_3BB0A8C1_0x0049D880 | 0.0% | Pending SHC_3BB0A8C1_0x0049D970 | 0.0% | Pending -SHC_3BB0A8C1_0x0049DB30 | 78.1% | Style pass, asm differs +SHC_3BB0A8C1_0x0049DB30 | 0.0% | Pending -SHC_3BB0A8C1_0x0049DDC0 | 35.7% | Style pass, asm differs +SHC_3BB0A8C1_0x0049DDC0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049E0D0 | 86.5% | Style pass, asm differs +SHC_3BB0A8C1_0x0049E0D0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049E510 | 90.8% | Style pass, asm differs +SHC_3BB0A8C1_0x0049E510 | 0.0% | Pending -SHC_3BB0A8C1_0x0049E9E0 | 69.4% | Style pass, asm differs +SHC_3BB0A8C1_0x0049E9E0 | 0.0% | Pending SHC_3BB0A8C1_0x0049EB00 | 0.0% | Pending -SHC_3BB0A8C1_0x0049EDF0 | 62.5% | Style pass, asm differs +SHC_3BB0A8C1_0x0049EDF0 | 0.0% | Pending SHC_3BB0A8C1_0x0049EED0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049F040 | 79.5% | Style pass, asm differs +SHC_3BB0A8C1_0x0049F040 | 0.0% | Pending -SHC_3BB0A8C1_0x0049F2D0 | 78.7% | Style pass, asm differs +SHC_3BB0A8C1_0x0049F2D0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049F540 | 78.8% | Style pass, asm differs +SHC_3BB0A8C1_0x0049F540 | 0.0% | Pending -SHC_3BB0A8C1_0x0049F7D0 | 19.7% | Style pass, asm differs +SHC_3BB0A8C1_0x0049F7D0 | 0.0% | Pending SHC_3BB0A8C1_0x0049F9B0 | 0.0% | Pending -SHC_3BB0A8C1_0x0049FC00 | 56.5% | Style pass, asm differs +SHC_3BB0A8C1_0x0049FC00 | 0.0% | Pending SHC_3BB0A8C1_0x0049FD10 | 0.0% | Pending SHC_3BB0A8C1_0x0049FD70 | 0.0% | Pending -SHC_3BB0A8C1_0x0049FF20 | 65.3% | Style pass, asm differs +SHC_3BB0A8C1_0x0049FF20 | 0.0% | Pending SHC_3BB0A8C1_0x004A0050 | 0.0% | Pending -SHC_3BB0A8C1_0x004A01D0 | 54.6% | Style pass, asm differs +SHC_3BB0A8C1_0x004A01D0 | 0.0% | Pending SHC_3BB0A8C1_0x004A0300 | 0.0% | Pending -SHC_3BB0A8C1_0x004A0460 | 66.7% | Style pass, asm differs +SHC_3BB0A8C1_0x004A0460 | 0.0% | Pending -SHC_3BB0A8C1_0x004A06B0 | 60.1% | Style pass, asm differs +SHC_3BB0A8C1_0x004A06B0 | 0.0% | Pending SHC_3BB0A8C1_0x004A07C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A08E0 | 84.5% | Style pass, asm differs +SHC_3BB0A8C1_0x004A08E0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A0B20 | 65.2% | Style pass, asm differs +SHC_3BB0A8C1_0x004A0B20 | 0.0% | Pending SHC_3BB0A8C1_0x004A0BD0 | 0.0% | Pending @@ -24875,9 +24875,9 @@ SHC_3BB0A8C1_0x004A0E4A | 0.0% | Pending SHC_3BB0A8C1_0x004A0E4B | 0.0% | Pending -SHC_3BB0A8C1_0x004A0E50 | 93.1% | Style pass, asm differs +SHC_3BB0A8C1_0x004A0E50 | 0.0% | Pending -SHC_3BB0A8C1_0x004A1230 | 59.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A1230 | 0.0% | Pending SHC_3BB0A8C1_0x004A1568 | 0.0% | Pending @@ -25011,9 +25011,9 @@ SHC_3BB0A8C1_0x004A15AE | 0.0% | Pending SHC_3BB0A8C1_0x004A15AF | 0.0% | Pending -SHC_3BB0A8C1_0x004A15B0 | 28.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A15B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A16C0 | 90.0% | Style pass, asm differs +SHC_3BB0A8C1_0x004A16C0 | 0.0% | Pending SHC_3BB0A8C1_0x004A1800 | 0.0% | Pending @@ -25163,29 +25163,29 @@ SHC_3BB0A8C1_0x004A19AD | 0.0% | Pending SHC_3BB0A8C1_0x004A19AE | 0.0% | Pending -SHC_3BB0A8C1_0x004A19B0 | 57.2% | Style pass, asm differs +SHC_3BB0A8C1_0x004A19B0 | 0.0% | Pending SHC_3BB0A8C1_0x004A1AF0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A1C40 | 74.3% | Style pass, asm differs +SHC_3BB0A8C1_0x004A1C40 | 0.0% | Pending SHC_3BB0A8C1_0x004A1CC0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A1D30 | 65.7% | Style pass, asm differs +SHC_3BB0A8C1_0x004A1D30 | 0.0% | Pending SHC_3BB0A8C1_0x004A1E10 | 0.0% | Pending -SHC_3BB0A8C1_0x004A21B0 | 57.9% | Style pass, asm differs +SHC_3BB0A8C1_0x004A21B0 | 0.0% | Pending SHC_3BB0A8C1_0x004A22C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A2650 | 64.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A2650 | 0.0% | Pending SHC_3BB0A8C1_0x004A2740 | 0.0% | Pending SHC_3BB0A8C1_0x004A27D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A2A90 | 54.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A2A90 | 0.0% | Pending SHC_3BB0A8C1_0x004A2B70 | 0.0% | Pending @@ -25201,27 +25201,27 @@ SHC_3BB0A8C1_0x004A2DC4 | 0.0% | Pending SHC_3BB0A8C1_0x004A2DC8 | 0.0% | Pending -SHC_3BB0A8C1_0x004A2DD0 | 75.3% | Style pass, asm differs +SHC_3BB0A8C1_0x004A2DD0 | 0.0% | Pending SHC_3BB0A8C1_0x004A2F00 | 0.0% | Pending SHC_3BB0A8C1_0x004A31D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A3220 | 63.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A3220 | 0.0% | Pending -SHC_3BB0A8C1_0x004A36B0 | 40.9% | Style pass, asm differs +SHC_3BB0A8C1_0x004A36B0 | 0.0% | Pending SHC_3BB0A8C1_0x004A37D0 | 0.0% | Pending SHC_3BB0A8C1_0x004A3860 | 0.0% | Pending -SHC_3BB0A8C1_0x004A3B20 | 33.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A3B20 | 0.0% | Pending SHC_3BB0A8C1_0x004A3E80 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4140 | 83.9% | Style pass, asm differs +SHC_3BB0A8C1_0x004A4140 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4470 | 47.1% | Style pass, asm differs +SHC_3BB0A8C1_0x004A4470 | 0.0% | Pending SHC_3BB0A8C1_0x004A4500 | 0.0% | Pending @@ -25229,15 +25229,15 @@ SHC_3BB0A8C1_0x004A4550 | 0.0% | Pending SHC_3BB0A8C1_0x004A46C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4930 | 65.8% | ClimbData stride bug fixed +SHC_3BB0A8C1_0x004A4930 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4B30 | 79.0% | Style pass, asm differs +SHC_3BB0A8C1_0x004A4B30 | 0.0% | Pending SHC_3BB0A8C1_0x004A4B80 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A4BB0 | 24.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A4BB0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A4C70 | 89.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A4C70 | 0.0% | Pending SHC_3BB0A8C1_0x004A4D60 | 0.0% | Pending @@ -25251,59 +25251,59 @@ SHC_3BB0A8C1_0x004A5230 | 0.0% | Pending SHC_3BB0A8C1_0x004A52D0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A5320 | 16.1% | Style pass, asm differs +SHC_3BB0A8C1_0x004A5320 | 0.0% | Pending SHC_3BB0A8C1_0x004A5420 | 0.0% | Pending SHC_3BB0A8C1_0x004A5770 | 0.0% | Pending -SHC_3BB0A8C1_0x004A58A0 | 14.6% | Style pass, asm differs +SHC_3BB0A8C1_0x004A58A0 | 0.0% | Pending SHC_3BB0A8C1_0x004A5980 | 0.0% | Pending SHC_3BB0A8C1_0x004A5A30 | 0.0% | Pending -SHC_3BB0A8C1_0x004A5B00 | 57.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A5B00 | 0.0% | Pending -SHC_3BB0A8C1_0x004A5DA0 | 76.0% | Style pass, asm differs +SHC_3BB0A8C1_0x004A5DA0 | 0.0% | Pending SHC_3BB0A8C1_0x004A5F60 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A5F90 | 82.9% | Style pass, asm differs +SHC_3BB0A8C1_0x004A5F90 | 0.0% | Pending -SHC_3BB0A8C1_0x004A6010 | 37.0% | Style pass, asm differs +SHC_3BB0A8C1_0x004A6010 | 0.0% | Pending SHC_3BB0A8C1_0x004A6120 | 0.0% | Pending -SHC_3BB0A8C1_0x004A6520 | 95.7% | Style pass, asm differs +SHC_3BB0A8C1_0x004A6520 | 0.0% | Pending -SHC_3BB0A8C1_0x004A65E0 | 68.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A65E0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A66D0 | 83.1% | Style pass, asm differs +SHC_3BB0A8C1_0x004A66D0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A67D0 | 72.1% | Style pass, asm differs +SHC_3BB0A8C1_0x004A67D0 | 0.0% | Pending SHC_3BB0A8C1_0x004A6940 | 0.0% | Pending SHC_3BB0A8C1_0x004A69F0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A6AB0 | 27.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A6AB0 | 0.0% | Pending SHC_3BB0A8C1_0x004A6BE0 | 0.0% | Pending SHC_3BB0A8C1_0x004A6C40 | 0.0% | Pending -SHC_3BB0A8C1_0x004A6DF0 | 78.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A6DF0 | 0.0% | Pending SHC_3BB0A8C1_0x004A6ED0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A7090 | 89.9% | Style pass, asm differs +SHC_3BB0A8C1_0x004A7090 | 0.0% | Pending -SHC_3BB0A8C1_0x004A75B0 | 24.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A75B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A79A0 | 37.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A79A0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A7F50 | 49.5% | Style pass, asm differs +SHC_3BB0A8C1_0x004A7F50 | 0.0% | Pending SHC_3BB0A8C1_0x004A80B0 | 0.0% | Pending @@ -25311,15 +25311,15 @@ SHC_3BB0A8C1_0x004A8220 | 0.0% | Pending SHC_3BB0A8C1_0x004A8340 | 0.0% | Pending -SHC_3BB0A8C1_0x004A83B0 | 60.4% | Style pass, asm differs +SHC_3BB0A8C1_0x004A83B0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A8780 | 40.8% | Style pass, asm differs +SHC_3BB0A8C1_0x004A8780 | 0.0% | Pending -SHC_3BB0A8C1_0x004A8860 | 34.7% | Style pass, asm differs +SHC_3BB0A8C1_0x004A8860 | 0.0% | Pending SHC_3BB0A8C1_0x004A8900 | 0.0% | Pending -SHC_3BB0A8C1_0x004A8AB0 | 58.3% | Style pass, asm differs +SHC_3BB0A8C1_0x004A8AB0 | 0.0% | Pending SHC_3BB0A8C1_0x004A91B0 | 0.0% | Pending @@ -25453,23 +25453,23 @@ SHC_3BB0A8C1_0x004A91F6 | 0.0% | Pending SHC_3BB0A8C1_0x004A91F7 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9200 | 43.3% | Style pass, asm differs +SHC_3BB0A8C1_0x004A9200 | 0.0% | Pending SHC_3BB0A8C1_0x004A94E0 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A9510 | 54.0% | Style pass, asm differs +SHC_3BB0A8C1_0x004A9510 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9680 | 84.5% | Style pass, asm differs +SHC_3BB0A8C1_0x004A9680 | 0.0% | Pending SHC_3BB0A8C1_0x004A96B0 | 0.0% | Pending SHC_3BB0A8C1_0x004A9760 | 100.0% | Reimplemented -SHC_3BB0A8C1_0x004A97D0 | 20.0% | Style pass, asm differs +SHC_3BB0A8C1_0x004A97D0 | 0.0% | Pending SHC_3BB0A8C1_0x004A98C0 | 0.0% | Pending -SHC_3BB0A8C1_0x004A9B20 | 31.5% | Style pass, asm differs +SHC_3BB0A8C1_0x004A9B20 | 0.0% | Pending SHC_3BB0A8C1_0x004A9DD0 | 100.0% | Reimplemented