From eee31e55d8016dce3fa7d20e26ed1d8b13378e14 Mon Sep 17 00:00:00 2001 From: Jacob Babor Date: Sat, 20 Jun 2026 13:53:09 -0500 Subject: [PATCH] Decode route element float fields --- docs/red4ext-logging-shim.md | 44 ++++++++++++++++++++++++++++-- red4ext/EdgeWeightGPS/src/Main.cpp | 15 ++++++++-- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/docs/red4ext-logging-shim.md b/docs/red4ext-logging-shim.md index 1209fb1..72089a9 100644 --- a/docs/red4ext-logging-shim.md +++ b/docs/red4ext-logging-shim.md @@ -190,13 +190,53 @@ Latest route-result findings: cleanly matched the visible routes: side job `12`, Sinnerman `23`, Claire's Garage `18`, and custom pin `17`. - The vector elements are 0x28-byte records, not pointers. `0x41be2c` calls - `0x41be94` with `(data, data + count * 40)`, so the next probe logs each + `0x41be94` with `(data, data + count * 40)`. The active probe logs each route element as a compact 40-byte record tuple: - `h00,u08,u0c,u10,u14,h18,h20`. + `h00,u08hex,u0c,u10,u14,h18,h18lowFloat,h18highFloat,h20`. - A nearby helper at `0x41c508` does iterate an array of 8-byte pointers at offset `+0x28`, but that is a different route-adjacent object type, not the `0x7094b8` output record captured in `outPath`. +Latest route-element decode: + +- User clock `45:37`: Continue on the main menu. +- User clock `46:05`: Space to continue. +- User clock `46:15`: map opened and the usual route-click routine was run. +- The startup/minimap route and the later explicit Claire's Garage map route + produced identical 18-record `ptr28` sequences, so the same solved route + object feeds both HUD startup and deliberate map plotting. +- The four deliberate map routes completed as route result IDs `2` through `5`: + side job `12` records / final span end `68`, Sinnerman `23` records / final + span end `188`, Claire's Garage `18` records / final span end `86`, custom + pin `14` records / final span end `78`. +- Within every route, `u10` and `u14` are monotonically increasing start/end + indexes into a flattened point/span buffer. The final `u14` equals + `gpsResult_u20` for every route. +- `h00` is a stable per-segment handle: common route prefixes share identical + `h00` sequences, and the custom pin and Claire's Garage routes share their + first ten solved segments before diverging. +- `u08` is packed metadata. Values appear byte-structured, for example + `0x00020202`, `0x01020203`, `0x02020103`, and `0x03020003`, rather than a + simple scalar weight. +- `h18` splits into two 32-bit floats. The high half is consistently a sane + road-scale float, often in the `20` to `230` range, and is likely segment + length/cost-like output. The low half is usually zero or a tiny value, with + non-zero values appearing around the start segment. +- `h20` has been zero in all captured full-map GPS result records. + +Current static producer lead: + +- `0x70a908` packages the route endpoints and query settings, then calls + `0x44cc7c`. +- `0x44cc7c` is now the main producer corridor, not merely a generic unknown + helper. It allocates large scratch state, projects the query endpoints, and + calls deeper pathfinding routines that should decide route cost before the + `0x7094b8` fetch/drain path copies final result records. +- Direct xrefs confirm `0x41be94` has only the result-copy caller + `0x41be69`; patching there would alter copied/displayed records after route + choice. The cost patch needs to happen upstream of the `0x44cc7c` result + construction path. + Autodrive finding: - User clock `28:28` and `28:48`: enabling autodrive did not use the full diff --git a/red4ext/EdgeWeightGPS/src/Main.cpp b/red4ext/EdgeWeightGPS/src/Main.cpp index af80ebd..9465fd6 100644 --- a/red4ext/EdgeWeightGPS/src/Main.cpp +++ b/red4ext/EdgeWeightGPS/src/Main.cpp @@ -450,6 +450,13 @@ void AppendHexValue(std::ostringstream& aLine, const char* aLabel, uint64_t aVal aLine << " " << aLabel << "=0x" << std::hex << aValue << std::dec; } +float FloatFromBits(uint32_t aBits) +{ + float value = 0.0f; + std::memcpy(&value, &aBits, sizeof(value)); + return value; +} + void LogHookCall(const char* aName, uint32_t aCount, void* aThis, void* a2, void* a3, void* a4) { std::ostringstream line; @@ -947,8 +954,12 @@ void AppendGpsResultElementArraySummary(std::ostringstream& aLine, const char* a continue; } - aLine << std::hex << h00 << "," << std::dec << u08 << "," << u0c << "," << u10 << "," << u14 << "," - << std::hex << h18 << "," << h20 << std::dec; + const auto h18Lo = static_cast(h18); + const auto h18Hi = static_cast(h18 >> 32); + aLine << std::hex << h00 << ",0x" << std::setw(8) << std::setfill('0') << u08 << std::setfill(fill) + << std::dec << "," << u0c << "," << u10 << "," << u14 << "," << std::hex << h18 << std::dec + << "," << FloatFromBits(h18Lo) << "," << FloatFromBits(h18Hi) << "," << std::hex << h20 + << std::dec; } aLine << "]"; aLine.flags(flags);