aboutsummaryrefslogtreecommitdiffstats
path: root/tools/warp.py
blob: 71e4a1c30ae20e5b7d5de7f94cfc5da014200202 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python3
"""warp.py <sock> <mapid_hex> — Phase-A RAM-poke fly-warp to any map id.
Sets wDestinationMap + BIT_FLY_WARP, then releases the music-fade spin-wait by
zeroing wAudioFadeOutControl until the map actually changes."""
import socket, sys, time

WDEST=0xD719; WFLAGS=0xD731; WAUDIO=0xCFC6; WCURMAP=0xD35D

def main():
    sock=sys.argv[1]; dest=int(sys.argv[2],16)
    c=socket.socket(socket.AF_UNIX,socket.SOCK_STREAM);c.settimeout(4);c.connect(sock);c.recv(200)
    def cmd(l):
        c.sendall((l+"\n").encode()); b=b""
        while b"\n" not in b: b+=c.recv(65536)
        return b.split(b"\n",1)[0].decode()
    rd=lambda a:int(cmd(f"read 0x{a:04X} 1").split()[-1],16)
    before=rd(WCURMAP)
    cmd(f"write 0x{WDEST:04X} {dest:02X}")
    cmd(f"write 0x{WFLAGS:04X} {rd(WFLAGS)|0x08:02X}")
    ok=False
    for _ in range(25):
        cmd(f"write 0x{WAUDIO:04X} 00")      # release spin-wait if the game entered it
        time.sleep(0.25)
        if rd(WCURMAP)!=before: ok=True; break
    time.sleep(1.2)
    m=rd(WCURMAP); y=rd(0xD360); x=rd(0xD361)
    print(f"warp -> map 0x{m:02X} pos ({y},{x})  {'OK' if ok and m==dest else 'CHECK'}")

if __name__=="__main__": main()