mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
	
	
		
			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)) |