93 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			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))
 |