Archipelago/worlds/ladx/GpsTracker.py

93 lines
2.2 KiB
Python

import json
roomAddress = 0xFFF6
mapIdAddress = 0xFFF7
indoorFlagAddress = 0xDBA5
entranceRoomOffset = 0xD800
screenCoordAddress = 0xFFFA
mapMap = {
0x00: 0x01,
0x01: 0x01,
0x02: 0x01,
0x03: 0x01,
0x04: 0x01,
0x05: 0x01,
0x06: 0x02,
0x07: 0x02,
0x08: 0x02,
0x09: 0x02,
0x0A: 0x02,
0x0B: 0x02,
0x0C: 0x02,
0x0D: 0x02,
0x0E: 0x02,
0x0F: 0x02,
0x10: 0x02,
0x11: 0x02,
0x12: 0x02,
0x13: 0x02,
0x14: 0x02,
0x15: 0x02,
0x16: 0x02,
0x17: 0x02,
0x18: 0x02,
0x19: 0x02,
0x1D: 0x01,
0x1E: 0x01,
0x1F: 0x01,
0xFF: 0x03,
}
class GpsTracker:
room = None
location_changed = False
screenX = 0
screenY = 0
indoors = None
def __init__(self, gameboy) -> None:
self.gameboy = gameboy
async def read_byte(self, b):
return (await self.gameboy.async_read_memory(b))[0]
async def read_location(self):
indoors = await self.read_byte(indoorFlagAddress)
if indoors != self.indoors and self.indoors != None:
self.indoorsChanged = True
self.indoors = indoors
mapId = await self.read_byte(mapIdAddress)
if mapId not in mapMap:
print(f'Unknown map ID {hex(mapId)}')
return
mapDigit = mapMap[mapId] << 8 if indoors else 0
last_room = self.room
self.room = await self.read_byte(roomAddress) + mapDigit
coords = await self.read_byte(screenCoordAddress)
self.screenX = coords & 0x0F
self.screenY = (coords & 0xF0) >> 4
if (self.room != last_room):
self.location_changed = True
last_message = {}
async def send_location(self, socket, diff=False):
if self.room is None:
return
message = {
"type":"location",
"refresh": True,
"version":"1.0",
"room": f'0x{self.room:02X}',
"x": self.screenX,
"y": self.screenY,
}
if message != self.last_message:
self.last_message = message
await socket.send(json.dumps(message))