def __setitem__(self, index, value): if self._oam_entries[index][2] == value: return palette_updated = False if _gbio.is_color() and self._oam_indices[index] is not None: attributes = self._oam_entries[index][3] old_palette_index = attributes & 0x7 new_palette = tile_to_colors[value] pt = self._gb._sprite_palettes new_palette_index = pt.get(new_palette) if new_palette_index == 0xff or old_palette_index != new_palette_index: if old_palette_index < 0xff: pt.free(old_palette_index) new_palette_index = pt.alloc(new_palette) self._oam_entries[index][3] = (attributes & 0xf8) | new_palette_index palette_updated = True print("map index set", self._oam_indices, index, value) self._oam_entries[index][2] = value if self._oam_indices[index] is not None: offset = self._compute_oam_address(index) + 2 self._gb[offset] = value if palette_updated: self._gb[offset + 1] = self._oam_entries[index][3]
def _hide(self): for i in range(self._width * self._height): oam_address = self._compute_oam_address(i) if _gbio.is_color(): old_palette_index = self._oam_entries[i][3] & 0x7 self._gb._sprite_palettes.free(old_palette_index) self._gb[oam_address:oam_address + 4] = b"\x00\x00\x00\x00" self._free_indices.add(self._oam_indices[i]) self._oam_indices[i] = None
def _show(self, free_indices): if len(free_indices) < self._width * self._height: raise RuntimeError("Not enough sprites available") self._free_indices = free_indices for i in range(self._width * self._height): self._oam_indices[i] = free_indices.pop() oam_address = self._compute_oam_address(i) if _gbio.is_color(): attributes = self._oam_entries[i][3] new_palette = tile_to_colors[self._oam_entries[i][2]] pt = self._gb._sprite_palettes new_palette_index = pt.alloc(new_palette) self._oam_entries[i][3] = (attributes & 0xf8) | new_palette_index self._gb[oam_address:oam_address + 4] = self._oam_entries[i]
def __setitem__(self, index, value): if isinstance(index, tuple): index = index[0] * 32 + index[1] if _gbio.is_color(): current_palette = self._tile_to_palette[index] palette = tile_to_colors[value] new_palette = self._palette_tracker.get(palette) if new_palette == 0xff or current_palette != new_palette: if current_palette < 0xff: self._palette_tracker.free(current_palette) new_palette = self._palette_tracker.alloc(palette) self._tile_to_palette[index] = new_palette # Set the background tile options to it self._gb[0xff4f] = 0x1 # Set vram bank to 1 self._gb[0x9800 + index] = new_palette self._gb[0xff4f] = 0x0 # Set vram bank to 0 #print("swap palette", index, new_palette) #print("map index set", index, value, new_palette, palette) self._gb[0x9800 + index] = value
def __init__(self): _gbio.reset_gameboy() self._byte_buf = bytearray(6) self._byte_buf[0] = 0x00 # Noop to sync DMA to GB clock self._byte_buf[1] = 0x0e # Load next value into C # Value into C self._byte_buf[3] = 0x3e # Load next value into A # Value into A self._byte_buf[5] = 0xe2 # Load A into 0xff00 + C self._full_address = bytearray(6) self._full_address[0] = 0x21 # Load next value into HL # Value into C self._full_address[3] = 0x3e # Load next value into A # Value into A self._full_address[5] = 0x22 # Load A into HL's address self._slice_buffer = bytearray(200) self.background = Background(self) self.tiles = Tiles(self) self._sprite_allocation = set() self._sprite_palettes = PaletteTracker(self, True) self._queued_oam_dma = False # DMA routine self[0xff80:0xff8b] = ( b"\x3e\xc0" # Load 0xc0 into A b"\xe0\x46" # Trigger dma by writing A to DMA b"\x3e\x28" # Load delay length (0x28) into A b"\x3d" # Decrement a b"\xc2\x86\xff" # Jump back to decrement if not zero b"\xc9") # Return # Clear the OAM for i in range(40): oam_address = 0xfe00 + 4 * i self[oam_address:oam_address + 4] = b"\x00\x00\x00\x00" self._color = _gbio.is_color() if self._color: # Set vram bank to 1 self[0xff4f] = 0x1 blank = b"\x00" * 32 for i in range(32): start = 0x9800 + 32 * i self[start:start + 32] = blank # Set vram bank to 0 self[0xff4f] = 0x0 else: # Set the background palette self[0xff47] = 0b00011110 # Set object palette 0 self[0xff48] = 0b00011110 self[0xff47] = 0b10001101 _gbio.set_lcdc(0b10010011) self._group = None
import _gbio class _SpeedStub: def __init__(self): self.x = 0 self.y = 0 if _gbio.is_color(): tile_to_colors = None TO_GBC = ( b"\x00\x00" # 0 - 0x000000, b"\xa3\x28" # 1 - 0x1d2b53, b"\x8f\x28" # 2 - 0x7e2553, b"\x00\x2a" # 3 - 0x008751, b"\x55\x19" # 4 - 0xab5236, b"\x4b\x25" # 5 - 0x5f574f, b"\x18\x63" # 6 - 0xc2c3c7, b"\xdf\x77" # 7 - 0xfff1e8, b"\x1f\x24" # 8 - 0xff004d, b"\x9f\x02" # 9 - 0xffa300, b"\xbf\x13" # 10 - 0xffec27, b"\x80\x1b" # 11 - 0x00e436, b"\xa5\x7e" # 12 - 0x29adff, b"\xd0\x4d" # 13 - 0x83769c, b"\xdf\x55" # 14 - 0xff77a8, b"\x3f\x57" # 15 - 0xffccaa )