mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-28 10:59:16 -04:00
03e4d6be56
The first live run aligned on the game's periodic Getstat poll -- every 30 frames, identical everywhere -- and reported a fork between native mid-scene and the oracle still at boot (its tail showed lbas 304, 2864, 12422: boot loads; the scene had not been played there yet). Anchor on Setlocs into the palette file's LBA range instead, compare the two LBA request sequences positionally, and print each side's full command window around the file with the first diverged request marked. A side with no palette-file Setlocs in its history is told to play the scene there rather than diffed against unrelated traffic. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
"""Tests for the cross-emulator CD command stream diff."""
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
import cd_diff as cd # noqa: E402
|
|
|
|
|
|
def setloc(lba, frame=1):
|
|
t = lba + 150
|
|
m, s, f = t // 4500, (t // 75) % 60, t % 75
|
|
|
|
def b2(v):
|
|
return ((v // 10) << 4) | (v % 10)
|
|
return {"cmd": "0x02", "frame": frame,
|
|
"params": [f"0x{b2(m):02X}", f"0x{b2(s):02X}", f"0x{b2(f):02X}"]}
|
|
|
|
|
|
def readn(frame=1):
|
|
return {"cmd": "0x06", "params": [], "frame": frame}
|
|
|
|
|
|
class NormaliseTest(unittest.TestCase):
|
|
def test_setloc_decoded(self):
|
|
r = cd.normalise([setloc(125112)])
|
|
self.assertEqual(r[0]["lba"], 125112)
|
|
|
|
def test_hex_and_int_params_both_accepted(self):
|
|
r = cd.normalise([{"cmd": 0x06, "params": [1, 2], "frame": 3}])
|
|
self.assertEqual(r[0]["cmd"], "ReadN")
|
|
self.assertEqual(r[0]["params"], [1, 2])
|
|
|
|
|
|
class ForkTest(unittest.TestCase):
|
|
def test_finds_the_lom_fork(self):
|
|
"""Native requests 111 where the oracle requests a different tail."""
|
|
common = [setloc(125105), readn(), setloc(125106), readn(),
|
|
setloc(125107), readn()]
|
|
nat = cd.normalise(common + [setloc(125111), readn(),
|
|
setloc(125113), readn()])
|
|
orc = cd.normalise(common + [setloc(125110), readn(),
|
|
setloc(125111), readn()])
|
|
f = cd.find_fork(nat, orc, 4)
|
|
self.assertIsNotNone(f)
|
|
self.assertEqual(nat[f["a_fork"]]["lba"], 125111)
|
|
self.assertEqual(orc[f["b_fork"]]["lba"], 125110)
|
|
|
|
def test_identical_streams_fork_at_the_end(self):
|
|
rows = cd.normalise([setloc(1), readn(), setloc(2), readn()])
|
|
f = cd.find_fork(rows, rows, 2)
|
|
self.assertEqual(f["a_fork"], len(rows))
|
|
|
|
def test_offset_alignment(self):
|
|
"""The oracle's capture may include extra leading traffic."""
|
|
common = [setloc(50), readn(), setloc(51), readn(), setloc(52),
|
|
readn()]
|
|
nat = cd.normalise(common)
|
|
orc = cd.normalise([setloc(9), readn()] + common)
|
|
f = cd.find_fork(nat, orc, 3)
|
|
self.assertEqual(f["a_start"], 0)
|
|
self.assertEqual(f["b_start"], 2)
|
|
|
|
def test_no_overlap_returns_none(self):
|
|
a = cd.normalise([setloc(1), readn()])
|
|
b = cd.normalise([setloc(9), readn()])
|
|
self.assertIsNone(cd.find_fork(a, b, 2))
|
|
|
|
|
|
class LbaAnchorTest(unittest.TestCase):
|
|
"""Alignment must anchor on the palette file's own Setlocs.
|
|
|
|
Generic longest-common-run alignment latched onto the periodic Getstat
|
|
heartbeat -- identical everywhere -- and reported a fork between two
|
|
unrelated journey points (native mid-scene vs oracle at boot)."""
|
|
|
|
def test_sequence_extraction(self):
|
|
rows = cd.normalise([setloc(304), readn(), setloc(125105), readn(),
|
|
setloc(125111), readn()])
|
|
self.assertEqual(cd.lba_sequence(rows, 125000, 125200),
|
|
[125105, 125111])
|
|
|
|
def test_boot_loads_excluded(self):
|
|
rows = cd.normalise([setloc(304), setloc(2864), setloc(12422)])
|
|
self.assertEqual(cd.lba_sequence(rows, 125000, 125200), [])
|
|
|
|
def test_fork_index_by_position(self):
|
|
nat = [125105, 125106, 125111, 125113]
|
|
orc = [125105, 125106, 125110, 125111]
|
|
fork = next((k for k in range(min(len(nat), len(orc)))
|
|
if nat[k] != orc[k]), None)
|
|
self.assertEqual(fork, 2)
|