Rehost selected-year bucket scalar ladder
This commit is contained in:
parent
95215d836e
commit
f9b3cf8571
10 changed files with 295 additions and 9 deletions
54
tools/py/extract_selected_year_bucket_ladder.py
Normal file
54
tools/py/extract_selected_year_bucket_ladder.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
IMAGE_BASE = 0x400000
|
||||
PAIRED_YEAR_VALUE_TABLE_VA = 0x005F3980
|
||||
PAIR_COUNT = 21
|
||||
TERMINAL_SCALAR_VA = 0x005F3A24
|
||||
|
||||
|
||||
def read_u32_table(blob: bytes, va: int, count: int) -> list[int]:
|
||||
offset = va - IMAGE_BASE
|
||||
data = blob[offset : offset + count * 4]
|
||||
if len(data) != count * 4:
|
||||
raise ValueError(f"table at {va:#x} truncated")
|
||||
return [struct.unpack("<I", data[i : i + 4])[0] for i in range(0, len(data), 4)]
|
||||
|
||||
|
||||
def build_artifact(exe_bytes: bytes) -> dict[str, object]:
|
||||
raw_pairs = read_u32_table(exe_bytes, PAIRED_YEAR_VALUE_TABLE_VA, PAIR_COUNT * 2)
|
||||
terminal_scalar_raw = read_u32_table(exe_bytes, TERMINAL_SCALAR_VA, 1)[0]
|
||||
entries = []
|
||||
for year, value in zip(raw_pairs[::2], raw_pairs[1::2]):
|
||||
entries.append({"year": year, "value": float(value)})
|
||||
return {
|
||||
"source_kind": "rt3.exe-static-table",
|
||||
"reader_family": "world_refresh_selected_year_bucket_scalar_band",
|
||||
"table_virtual_address": f"0x{PAIRED_YEAR_VALUE_TABLE_VA:08x}",
|
||||
"pair_count": PAIR_COUNT,
|
||||
"terminal_scalar_virtual_address": f"0x{TERMINAL_SCALAR_VA:08x}",
|
||||
"terminal_scalar_value": float(terminal_scalar_raw),
|
||||
"entries": entries,
|
||||
}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Extract the selected-year bucket ladder used by RT3 world year refresh."
|
||||
)
|
||||
parser.add_argument("exe", type=Path, help="Path to RT3.exe")
|
||||
parser.add_argument("output", type=Path, help="Output JSON path")
|
||||
args = parser.parse_args()
|
||||
|
||||
artifact = build_artifact(args.exe.read_bytes())
|
||||
args.output.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue