diff --git a/pyboy/core/cartridge/base_mbc.pxd b/pyboy/core/cartridge/base_mbc.pxd index 7bfc6fc2a..66155cb8a 100644 --- a/pyboy/core/cartridge/base_mbc.pxd +++ b/pyboy/core/cartridge/base_mbc.pxd @@ -3,16 +3,17 @@ # GitHub: https://github.com/Baekalfen/PyBoy # -from pyboy.utils cimport IntIOInterface -from pyboy.core.cartridge.rtc cimport RTC from libc.stdint cimport uint8_t, uint16_t, uint32_t +from pyboy.core.cartridge.rtc cimport RTC +from pyboy.utils cimport IntIOInterface + + cdef class BaseMBC: cdef str filename cdef str gamename cdef uint8_t[:, :] rombanks - # 16 is absoulte max. 8KB in each bank - cdef uint8_t[16][8 * 1024] rambanks + cdef uint8_t[:,:] rambanks cdef uint8_t carttype cdef bint battery cdef bint rtc_enabled diff --git a/pyboy/core/cartridge/base_mbc.py b/pyboy/core/cartridge/base_mbc.py index 74609a110..5c98fb1b9 100644 --- a/pyboy/core/cartridge/base_mbc.py +++ b/pyboy/core/cartridge/base_mbc.py @@ -78,7 +78,7 @@ def save_ram(self, f): for bank in range(self.external_ram_count): for byte in range(8 * 1024): - f.write(self.rambanks[bank][byte]) + f.write(self.rambanks[bank, byte]) logger.debug("RAM saved.") @@ -89,7 +89,7 @@ def load_ram(self, f): for bank in range(self.external_ram_count): for byte in range(8 * 1024): - self.rambanks[bank][byte] = f.read() + self.rambanks[bank, byte] = f.read() logger.debug("RAM loaded.") @@ -97,10 +97,10 @@ def init_rambanks(self, n): self.rambank_initialized = True # In real life the values in RAM are scrambled on initialization. # Allocating the maximum, as it is easier in Cython. And it's just 128KB... - self.rambanks = [array.array("B", [0] * (8*1024)) for _ in range(16)] + self.rambanks = memoryview(array.array("B", [0] * (8*1024*16))).cast("B", shape=(16, 8 * 1024)) def getgamename(self, rombanks): - return "".join([chr(x) for x in rombanks[0][0x0134:0x0142]]).split("\0")[0] + return "".join([chr(rombanks[0, x]) for x in range(0x0134, 0x0142)]).split("\0")[0] def setitem(self, address, value): raise Exception("Cannot set item in MBC") @@ -109,17 +109,17 @@ def overrideitem(self, rom_bank, address, value): if 0x0000 <= address < 0x4000: logger.debug( "Performing overwrite on address: %s:%s. New value: %s Old value: %s" % - (hex(rom_bank), hex(address), hex(value), self.rombanks[rom_bank][address]) + (hex(rom_bank), hex(address), hex(value), self.rombanks[rom_bank, address]) ) - self.rombanks[rom_bank][address] = value + self.rombanks[rom_bank, address] = value else: logger.error("Invalid override address: %s" % hex(address)) def getitem(self, address): if 0x0000 <= address < 0x4000: - return self.rombanks[0][address] + return self.rombanks[0, address] elif 0x4000 <= address < 0x8000: - return self.rombanks[self.rombank_selected][address - 0x4000] + return self.rombanks[self.rombank_selected, address - 0x4000] elif 0xA000 <= address < 0xC000: # if not self.rambank_initialized: # logger.error("RAM banks not initialized: %s" % hex(address)) @@ -130,7 +130,7 @@ def getitem(self, address): if self.rtc_enabled and 0x08 <= self.rambank_selected <= 0x0C: return self.rtc.getregister(self.rambank_selected) else: - return self.rambanks[self.rambank_selected][address - 0xA000] + return self.rambanks[self.rambank_selected, address - 0xA000] # else: # logger.error("Reading address invalid: %s" % address) @@ -139,7 +139,7 @@ def __repr__(self): "Cartridge:", "Filename: %s" % self.filename, "Game name: %s" % self.gamename, - "GB Color: %s" % str(self.ROMBanks[0][0x143] == 0x80), + "GB Color: %s" % str(self.ROMBanks[0, 0x143] == 0x80), "Cartridge type: %s" % hex(self.cartType), "Number of ROM banks: %s" % self.external_rom_count, "Active ROM bank: %s" % self.rombank_selected, @@ -159,6 +159,6 @@ def setitem(self, address, value): self.rombank_selected = (value & 0b1) logger.debug("Switching bank 0x%0.4x, 0x%0.2x" % (address, value)) elif 0xA000 <= address < 0xC000: - self.rambanks[self.rambank_selected][address - 0xA000] = value + self.rambanks[self.rambank_selected, address - 0xA000] = value # else: - # logger.debug("Unexpected write to 0x%0.4x, value: 0x%0.2x" % (address, value)) \ No newline at end of file + # logger.debug("Unexpected write to 0x%0.4x, value: 0x%0.2x" % (address, value)) diff --git a/pyboy/core/cartridge/cartridge.py b/pyboy/core/cartridge/cartridge.py index fc7532a60..3bb111bfe 100644 --- a/pyboy/core/cartridge/cartridge.py +++ b/pyboy/core/cartridge/cartridge.py @@ -14,12 +14,6 @@ logger = logging.getLogger(__name__) -try: - from cython import compiled - cythonmode = compiled -except ImportError: - cythonmode = False - def load_cartridge(filename): rombanks = load_romfile(filename) @@ -27,9 +21,9 @@ def load_cartridge(filename): raise Exception("Cartridge header checksum mismatch!") # WARN: The following table doesn't work for MBC2! See Pan Docs - external_ram_count = int(EXTERNAL_RAM_TABLE[rombanks[0][0x0149]]) + external_ram_count = int(EXTERNAL_RAM_TABLE[rombanks[0, 0x0149]]) - carttype = rombanks[0][0x0147] + carttype = rombanks[0, 0x0147] cartinfo = CARTRIDGE_TABLE.get(carttype, None) if cartinfo is None: raise Exception("Catridge type invalid: %s" % carttype) @@ -47,9 +41,9 @@ def load_cartridge(filename): def validate_checksum(rombanks): x = 0 for m in range(0x134, 0x14D): - x = x - rombanks[0][m] - 1 + x = x - rombanks[0, m] - 1 x &= 0xff - return rombanks[0][0x14D] == x + return rombanks[0, 0x14D] == x def load_romfile(filename): @@ -66,11 +60,7 @@ def load_romfile(filename): logger.error("Unexpected ROM file length") raise Exception("Bad ROM file size") - if cythonmode: - return memoryview(romdata).cast("B", shape=(len(romdata) // banksize, banksize)) - else: - v = memoryview(romdata) - return [v[i:i + banksize] for i in range(0, len(romdata), banksize)] + return memoryview(romdata).cast("B", shape=(len(romdata) // banksize, banksize)) # yapf: disable diff --git a/pyboy/core/cartridge/mbc1.py b/pyboy/core/cartridge/mbc1.py index bf65a3a42..4769da473 100644 --- a/pyboy/core/cartridge/mbc1.py +++ b/pyboy/core/cartridge/mbc1.py @@ -33,7 +33,7 @@ def setitem(self, address, value): elif 0xA000 <= address < 0xC000: if self.rambank_enabled: self.rambank_selected = self.bank_select_register2 if self.memorymodel == 1 else 0 - self.rambanks[self.rambank_selected % self.external_ram_count][address - 0xA000] = value + self.rambanks[self.rambank_selected % self.external_ram_count, address - 0xA000] = value # else: # logger.error("Invalid writing address: %0.4x", address) @@ -43,11 +43,11 @@ def getitem(self, address): self.rombank_selected = (self.bank_select_register2 << 5) % self.external_rom_count else: self.rombank_selected = 0 - return self.rombanks[self.rombank_selected][address] + return self.rombanks[self.rombank_selected, address] elif 0x4000 <= address < 0x8000: self.rombank_selected = \ ((self.bank_select_register2 << 5) | self.bank_select_register1) % self.external_rom_count - return self.rombanks[self.rombank_selected][address - 0x4000] + return self.rombanks[self.rombank_selected, address - 0x4000] elif 0xA000 <= address < 0xC000: if not self.rambank_initialized: logger.error("RAM banks not initialized: %s" % hex(address)) @@ -59,7 +59,7 @@ def getitem(self, address): self.rambank_selected = self.bank_select_register2 % self.external_ram_count else: self.rambank_selected = 0 - return self.rambanks[self.rambank_selected][address - 0xA000] + return self.rambanks[self.rambank_selected, address - 0xA000] # else: # logger.error("Reading address invalid: %0.4x", address) diff --git a/pyboy/core/cartridge/mbc2.py b/pyboy/core/cartridge/mbc2.py index bbf44744c..5e1aec6ff 100644 --- a/pyboy/core/cartridge/mbc2.py +++ b/pyboy/core/cartridge/mbc2.py @@ -23,15 +23,15 @@ def setitem(self, address, value): elif 0xA000 <= address < 0xC000: if self.rambank_enabled: # MBC2 includes built-in RAM of 512 x 4 bits (Only the 4 LSBs are used) - self.rambanks[0][address % 512] = value | 0b11110000 + self.rambanks[0, address % 512] = value | 0b11110000 # else: # logger.debug("Unexpected write to 0x%0.4x, value: 0x%0.2x", address, value) def getitem(self, address): if 0x0000 <= address < 0x4000: - return self.rombanks[0][address] + return self.rombanks[0, address] elif 0x4000 <= address < 0x8000: - return self.rombanks[self.rombank_selected][address - 0x4000] + return self.rombanks[self.rombank_selected, address - 0x4000] elif 0xA000 <= address < 0xC000: if not self.rambank_initialized: logger.error("RAM banks not initialized: %s" % hex(address)) @@ -40,6 +40,6 @@ def getitem(self, address): return 0xFF else: - return self.rambanks[0][address % 512] | 0b11110000 + return self.rambanks[0, address % 512] | 0b11110000 # else: # logger.error("Reading address invalid: %0.4x", address) diff --git a/pyboy/core/cartridge/mbc3.py b/pyboy/core/cartridge/mbc3.py index 5ff252fd1..953ef631e 100644 --- a/pyboy/core/cartridge/mbc3.py +++ b/pyboy/core/cartridge/mbc3.py @@ -40,7 +40,7 @@ def setitem(self, address, value): elif 0xA000 <= address < 0xC000: if self.rambank_enabled: if self.rambank_selected <= 0x03: - self.rambanks[self.rambank_selected][address - 0xA000] = value + self.rambanks[self.rambank_selected, address - 0xA000] = value elif 0x08 <= self.rambank_selected <= 0x0C: self.rtc.setregister(self.rambank_selected, value) # else: diff --git a/pyboy/core/cartridge/mbc5.py b/pyboy/core/cartridge/mbc5.py index 6f2a50184..f485af0e5 100644 --- a/pyboy/core/cartridge/mbc5.py +++ b/pyboy/core/cartridge/mbc5.py @@ -25,6 +25,6 @@ def setitem(self, address, value): self.rambank_selected = (value & 0xF) % self.external_ram_count elif 0xA000 <= address < 0xC000: if self.rambank_enabled: - self.rambanks[self.rambank_selected][address - 0xA000] = value + self.rambanks[self.rambank_selected, address - 0xA000] = value else: logger.debug("Unexpected write to 0x%0.4x, value: 0x%0.2x" % (address, value)) diff --git a/pyboy/core/lcd.py b/pyboy/core/lcd.py index a82f15b57..9ae1feaad 100644 --- a/pyboy/core/lcd.py +++ b/pyboy/core/lcd.py @@ -394,30 +394,13 @@ def __init__(self, cgb): self._spritecache1_state = array("B", [0] * TILES) self.clear_cache() - if cythonmode: - self._screenbuffer = memoryview(self._screenbuffer_raw).cast("I", shape=(ROWS, COLS)) - self._tilecache0 = memoryview(self._tilecache0_raw).cast("I", shape=(TILES * 8, 8)) - # OBP0 palette - self._spritecache0 = memoryview(self._spritecache0_raw).cast("I", shape=(TILES * 8, 8)) - # OBP1 palette - self._spritecache1 = memoryview(self._spritecache1_raw).cast("I", shape=(TILES * 8, 8)) - self._screenbuffer_ptr = c_void_p(self._screenbuffer_raw.buffer_info()[0]) - else: - stride = TILES * 8 * 8 - - v = memoryview(self._screenbuffer_raw).cast("I") - self._screenbuffer = [v[i:i + COLS] for i in range(0, COLS * ROWS, COLS)] - self._screenbuffer_ptr = c_void_p(self._screenbuffer_raw.buffer_info()[0]) - - v = memoryview(self._tilecache0_raw).cast("I") - self._tilecache0 = [v[i:i + 8] for i in range(0, stride, 8)] - v = memoryview(self._spritecache0_raw).cast("I") - # VRAM Bank 0 - self._spritecache0 = [v[i:i + 8] for i in range(0, stride, 8)] - - v = memoryview(self._spritecache1_raw).cast("I") - # VRAM Bank 1 - self._spritecache1 = [v[i:i + 8] for i in range(0, stride, 8)] + self._screenbuffer = memoryview(self._screenbuffer_raw).cast("I", shape=(ROWS, COLS)) + self._tilecache0 = memoryview(self._tilecache0_raw).cast("I", shape=(TILES * 8, 8)) + # OBP0 palette + self._spritecache0 = memoryview(self._spritecache0_raw).cast("I", shape=(TILES * 8, 8)) + # OBP1 palette + self._spritecache1 = memoryview(self._spritecache1_raw).cast("I", shape=(TILES * 8, 8)) + self._screenbuffer_ptr = c_void_p(self._screenbuffer_raw.buffer_info()[0]) self._scanlineparameters = [[0, 0, 0, 0, 0] for _ in range(ROWS)] self.ly_window = 0 @@ -483,7 +466,7 @@ def scanline(self, lcd, y): xx = (7 - ((x-wx) % 8)) if horiflip else ((x-wx) % 8) yy = (8*wt + (7 - (self.ly_window) % 8)) if vertflip else (8*wt + (self.ly_window) % 8) - pixel = lcd.bcpd.getcolor(palette, tilecache[yy][xx]) + pixel = lcd.bcpd.getcolor(palette, tilecache[yy, xx]) if bg_priority: # We hide extra rendering information in the lower 8 bits (A) of the 32-bit RGBA format bg_priority_apply = BG_PRIORITY_FLAG @@ -491,9 +474,9 @@ def scanline(self, lcd, y): self.update_tilecache0(lcd, wt, 0) xx = (x-wx) % 8 yy = 8*wt + (self.ly_window) % 8 - pixel = lcd.BGP.getcolor(self._tilecache0[yy][xx]) + pixel = lcd.BGP.getcolor(self._tilecache0[yy, xx]) - self._screenbuffer[y][x] = pixel | bg_priority_apply + self._screenbuffer[y, x] = pixel | bg_priority_apply # background_enable doesn't exist for CGB. It works as master priority instead elif (not self.cgb and lcd._LCDC.background_enable) or self.cgb: tile_addr = background_offset + (y+by) // 8 * 32 % 0x400 + (x+bx) // 8 % 32 @@ -519,7 +502,7 @@ def scanline(self, lcd, y): xx = (7 - ((x+offset) % 8)) if horiflip else ((x+offset) % 8) yy = (8*bt + (7 - (y+by) % 8)) if vertflip else (8*bt + (y+by) % 8) - pixel = lcd.bcpd.getcolor(palette, tilecache[yy][xx]) + pixel = lcd.bcpd.getcolor(palette, tilecache[yy, xx]) if bg_priority: # We hide extra rendering information in the lower 8 bits (A) of the 32-bit RGBA format bg_priority_apply = BG_PRIORITY_FLAG @@ -527,12 +510,12 @@ def scanline(self, lcd, y): self.update_tilecache0(lcd, bt, 0) xx = (x+offset) % 8 yy = 8*bt + (y+by) % 8 - pixel = lcd.BGP.getcolor(self._tilecache0[yy][xx]) + pixel = lcd.BGP.getcolor(self._tilecache0[yy, xx]) - self._screenbuffer[y][x] = pixel | bg_priority_apply + self._screenbuffer[y, x] = pixel | bg_priority_apply else: # If background is disabled, it becomes white - self._screenbuffer[y][x] = lcd.BGP.getcolor(0) + self._screenbuffer[y, x] = lcd.BGP.getcolor(0) if y == 143: # Reset at the end of a frame. We set it to -1, so it will be 0 after the first increment @@ -631,23 +614,23 @@ def scanline_sprites(self, lcd, ly, buffer, ignore_priority): for dx in range(8): xx = 7 - dx if xflip else dx - color_code = spritecache[8*tileindex + yy][xx] + color_code = spritecache[8*tileindex + yy, xx] if 0 <= x < COLS and not color_code == 0: # If pixel is not transparent if self.cgb: pixel = lcd.ocpd.getcolor(palette, color_code) - bgmappriority = buffer[ly][x] & BG_PRIORITY_FLAG + bgmappriority = buffer[ly, x] & BG_PRIORITY_FLAG if lcd._LCDC.cgb_master_priority: # If 0, sprites are always on top, if 1 follow priorities if bgmappriority: # If 0, use spritepriority, if 1 take priority - if buffer[ly][x] & COL0_FLAG: - buffer[ly][x] = pixel + if buffer[ly, x] & COL0_FLAG: + buffer[ly, x] = pixel elif spritepriority: # If 1, sprite is behind bg/window. Color 0 of window/bg is transparent - if buffer[ly][x] & COL0_FLAG: - buffer[ly][x] = pixel + if buffer[ly, x] & COL0_FLAG: + buffer[ly, x] = pixel else: - buffer[ly][x] = pixel + buffer[ly, x] = pixel else: - buffer[ly][x] = pixel + buffer[ly, x] = pixel else: # TODO: Unify with CGB if attributes & 0b10000: @@ -656,10 +639,10 @@ def scanline_sprites(self, lcd, ly, buffer, ignore_priority): pixel = lcd.OBP0.getcolor(color_code) if spritepriority: # If 1, sprite is behind bg/window. Color 0 of window/bg is transparent - if buffer[ly][x] & COL0_FLAG: # if BG pixel is transparent - buffer[ly][x] = pixel + if buffer[ly, x] & COL0_FLAG: # if BG pixel is transparent + buffer[ly, x] = pixel else: - buffer[ly][x] = pixel + buffer[ly, x] = pixel x += 1 x -= 8 @@ -707,7 +690,7 @@ def update_tilecache0(self, lcd, t, bank): for x in range(8): colorcode = utils.color_code(byte1, byte2, 7 - x) - self._tilecache0[y][x] = colorcode + self._tilecache0[y, x] = colorcode self._tilecache0_state[t] = 1 @@ -725,7 +708,7 @@ def update_spritecache0(self, lcd, t, bank): for x in range(8): colorcode = utils.color_code(byte1, byte2, 7 - x) - self._spritecache0[y][x] = colorcode + self._spritecache0[y, x] = colorcode self._spritecache0_state[t] = 1 @@ -740,7 +723,7 @@ def update_spritecache1(self, lcd, t, bank): for x in range(8): colorcode = utils.color_code(byte1, byte2, 7 - x) - self._spritecache1[y][x] = colorcode + self._spritecache1[y, x] = colorcode self._spritecache1_state[t] = 1 @@ -748,7 +731,7 @@ def blank_screen(self, lcd): # If the screen is off, fill it with a color. for y in range(ROWS): for x in range(COLS): - self._screenbuffer[y][x] = lcd.BGP.getcolor(0) + self._screenbuffer[y, x] = lcd.BGP.getcolor(0) def save_state(self, f): for y in range(ROWS): @@ -761,7 +744,7 @@ def save_state(self, f): for y in range(ROWS): for x in range(COLS): - f.write_32bit(self._screenbuffer[y][x]) + f.write_32bit(self._screenbuffer[y, x]) def load_state(self, f, state_version): if state_version >= 2: @@ -777,7 +760,7 @@ def load_state(self, f, state_version): if state_version >= 6: for y in range(ROWS): for x in range(COLS): - self._screenbuffer[y][x] = f.read_32bit() + self._screenbuffer[y, x] = f.read_32bit() self.clear_cache() @@ -811,12 +794,7 @@ def __init__(self): self._tilecache1_raw = array("B", [0xFF] * (TILES*8*8*4)) - if cythonmode: - self._tilecache1 = memoryview(self._tilecache1_raw).cast("I", shape=(TILES * 8, 8)) - else: - v = memoryview(self._tilecache1_raw).cast("I") - self._tilecache1 = [v[i:i + 8] for i in range(0, TILES * 8 * 8, 8)] - + self._tilecache1 = memoryview(self._tilecache1_raw).cast("I", shape=(TILES * 8, 8)) self._tilecache1_state = array("B", [0] * TILES) self.clear_cache() @@ -846,7 +824,7 @@ def update_tilecache0(self, lcd, t, bank): y = (t*16 + k) // 2 for x in range(8): - self._tilecache0[y][x] = utils.color_code(byte1, byte2, 7 - x) + self._tilecache0[y, x] = utils.color_code(byte1, byte2, 7 - x) self._tilecache0_state[t] = 1 @@ -864,7 +842,7 @@ def update_tilecache1(self, lcd, t, bank): y = (t*16 + k) // 2 for x in range(8): - self._tilecache1[y][x] = utils.color_code(byte1, byte2, 7 - x) + self._tilecache1[y, x] = utils.color_code(byte1, byte2, 7 - x) self._tilecache1_state[t] = 1 @@ -882,7 +860,7 @@ def update_spritecache0(self, lcd, t, bank): y = (t*16 + k) // 2 for x in range(8): - self._spritecache0[y][x] = utils.color_code(byte1, byte2, 7 - x) + self._spritecache0[y, x] = utils.color_code(byte1, byte2, 7 - x) self._spritecache0_state[t] = 1 @@ -900,7 +878,7 @@ def update_spritecache1(self, lcd, t, bank): y = (t*16 + k) // 2 for x in range(8): - self._spritecache1[y][x] = utils.color_code(byte1, byte2, 7 - x) + self._spritecache1[y, x] = utils.color_code(byte1, byte2, 7 - x) self._spritecache1_state[t] = 1 diff --git a/pyboy/plugins/base_plugin.py b/pyboy/plugins/base_plugin.py index 1e134b965..a2869d02a 100644 --- a/pyboy/plugins/base_plugin.py +++ b/pyboy/plugins/base_plugin.py @@ -17,6 +17,7 @@ from array import array import numpy as np + from pyboy.botsupport.sprite import Sprite logger = logging.getLogger(__name__) @@ -114,11 +115,7 @@ def __init__(self, *args, game_area_section=(0, 0, 32, 32), game_area_wrap_aroun self.saved_state = io.BytesIO() - if cythonmode: - self._cached_game_area_tiles = memoryview(self._cached_game_area_tiles_raw).cast("I", shape=(width, height)) - else: - v = memoryview(self._cached_game_area_tiles_raw).cast("I") - self._cached_game_area_tiles = [v[i:i + height] for i in range(0, height * width, height)] + self._cached_game_area_tiles = memoryview(self._cached_game_area_tiles_raw).cast("I", shape=(width, height)) def enabled(self): return self.pyboy_argv.get("game_wrapper") and self.pyboy.cartridge_title() == self.cartridge_title @@ -197,9 +194,9 @@ def _game_area_tiles(self): _x = (xx+x+SCX) % 32 _y = (yy+y+SCY) % 32 if self.tilemap_use_background: - self._cached_game_area_tiles[y][x] = self.tilemap_background.tile_identifier(_x, _y) + self._cached_game_area_tiles[y, x] = self.tilemap_background.tile_identifier(_x, _y) else: - self._cached_game_area_tiles[y][x] = self.tilemap_window.tile_identifier(_x, _y) + self._cached_game_area_tiles[y, x] = self.tilemap_window.tile_identifier(_x, _y) else: if self.tilemap_use_background: self._cached_game_area_tiles = np.asarray( diff --git a/pyboy/plugins/debug.py b/pyboy/plugins/debug.py index 30d7eebed..a5cdeb9a0 100644 --- a/pyboy/plugins/debug.py +++ b/pyboy/plugins/debug.py @@ -356,11 +356,7 @@ def handle_breakpoint(self): def make_buffer(w, h): buf = array("B", [0x55] * (w*h*4)) - if cythonmode: - buf0 = memoryview(buf).cast("I", shape=(h, w)) - else: - view = memoryview(buf).cast("I") - buf0 = [view[i:i + w] for i in range(0, w * h, w)] + buf0 = memoryview(buf).cast("I", shape=(h, w)) buf_p = c_void_p(buf.buffer_info()[0]) return buf, buf0, buf_p @@ -421,7 +417,7 @@ def copy_tile(self, from_buffer, t, xx, yy, to_buffer, hflip, vflip, palette): _y = 7 - y if vflip else y for x in range(8): _x = 7 - x if hflip else x - to_buffer[yy + y][xx + x] = palette[from_buffer[_y + t*8][_x]] + to_buffer[yy + y, xx + x] = palette[from_buffer[_y + t*8][_x]] def mark_tile(self, x, y, color, height, width, grid): tw = width # Tile width @@ -437,7 +433,7 @@ def mark_tile(self, x, y, color, height, width, grid): self.buf0[yy + i][xx] = color for i in range(tw): if 0 <= (yy) < self.height and 0 <= xx + i < self.width: - self.buf0[yy][xx + i] = color + self.buf0[yy, xx + i] = color for i in range(tw): if 0 <= (yy + th - 1) < self.height and 0 <= xx + i < self.width: self.buf0[yy + th - 1][xx + i] = color @@ -565,14 +561,14 @@ def draw_overlay(self): if yy + y == 0 or y == constants.ROWS - 1: # Draw top/bottom bar for x in range(constants.COLS): if 0 <= xx + x < constants.COLS: - self.buf0[yy + y][xx + x] = COLOR + self.buf0[yy + y, xx + x] = COLOR else: # Draw body if 0 <= yy + y: self.buf0[yy + y][max(xx, 0)] = COLOR for x in range(constants.COLS): if 0 <= xx + x < constants.COLS: - self.buf0[yy + y][xx + x] &= self.color - self.buf0[yy + y][xx + constants.COLS] = COLOR + self.buf0[yy + y, xx + x] &= self.color + self.buf0[yy + y, xx + constants.COLS] = COLOR # Mark selected tiles for t, match in zip( @@ -758,7 +754,7 @@ class SpriteViewWindow(BaseDebugWindow): def post_tick(self): for y in range(constants.ROWS): for x in range(constants.COLS): - self.buf0[y][x] = SPRITE_BACKGROUND + self.buf0[y, x] = SPRITE_BACKGROUND for ly in range(144): self.mb.lcd.renderer.scanline_sprites(self.mb.lcd, ly, self.buf0, True) @@ -794,12 +790,7 @@ def __init__(self, *args, **kwargs): self.fg_color = [0x00, 0x00, 0x00] self._text_buffer_raw = array("B", [0x20] * (self.NROWS * self.NCOLS)) - if cythonmode: - self.text_buffer = memoryview(self._text_buffer_raw).cast("B", shape=(self.NROWS, self.NCOLS)) - else: - view = memoryview(self._text_buffer_raw) - self.text_buffer = [view[i:i + self.NCOLS] for i in range(0, self.NROWS * self.NCOLS, self.NCOLS)] - # self.text_buffer = [bytearray([0x20]*self.NCOLS) for _ in range(self.NROWS)] + self.text_buffer = memoryview(self._text_buffer_raw).cast("B", shape=(self.NROWS, self.NCOLS)) self.write_border() self.write_addresses() @@ -812,7 +803,7 @@ def __init__(self, *args, **kwargs): self.fbuf, self.fbuf0, self.fbuf_p = make_buffer(8, 16 * 256) for y, b in enumerate(font_bytes): for x in range(8): - self.fbuf0[y][x] = 0xFFFFFFFF if ((0x80 >> x) & b) else 0x00000000 + self.fbuf0[y, x] = 0xFFFFFFFF if ((0x80 >> x) & b) else 0x00000000 self.font_texture = sdl2.SDL_CreateTexture( self._sdlrenderer, sdl2.SDL_PIXELFORMAT_RGBA32, sdl2.SDL_TEXTUREACCESS_STATIC, 8, 16 * 256 @@ -852,30 +843,22 @@ def write_border(self): self.text_buffer[self.NROWS - 1][self.NCOLS - 1] = 0xBC def write_addresses(self): - header = (f"Memory from 0x{self.start_address:04X} " f"to 0x{self.start_address+0x3FF:04X}").encode("cp437") - if cythonmode: - for x in range(28): - self.text_buffer[1][x + 2] = header[x] - else: - self.text_buffer[1][2:30] = header + header = (f"Memory from 0x{self.start_address:04X} " + f"to 0x{self.start_address+0x3FF:04X}").encode("cp437") + for x in range(28): + self.text_buffer[1][x + 2] = header[x] for y in range(32): addr = f"0x{self.start_address + (0x20*y):04X}".encode("cp437") - if cythonmode: - for x in range(6): - self.text_buffer[y + 3][x + 2] = addr[x] - else: - self.text_buffer[y + 3][2:8] = addr + for x in range(6): + self.text_buffer[y + 3][x + 2] = addr[x] def write_memory(self): for y in range(32): for x in range(16): mem = self.mb.getitem(self.start_address + 16*y + x) - if cythonmode: - a = hex(mem)[2:].zfill(2).encode("cp437") - self.text_buffer[y + 3][3*x + 11] = a[0] - self.text_buffer[y + 3][3*x + 12] = a[1] - else: - self.text_buffer[y + 3][3*x + 11:3*x + 13] = bytes([mem]).hex().encode("cp437") + a = hex(mem)[2:].zfill(2).encode("cp437") + self.text_buffer[y + 3][3*x + 11] = a[0] + self.text_buffer[y + 3][3*x + 12] = a[1] def render_text(self): for y in range(self.NROWS): diff --git a/pyboy/plugins/game_wrapper_kirby_dream_land.py b/pyboy/plugins/game_wrapper_kirby_dream_land.py index 470b8bb4b..782862a78 100644 --- a/pyboy/plugins/game_wrapper_kirby_dream_land.py +++ b/pyboy/plugins/game_wrapper_kirby_dream_land.py @@ -15,12 +15,6 @@ logger = logging.getLogger(__name__) -try: - from cython import compiled - cythonmode = compiled -except ImportError: - cythonmode = False - class GameWrapperKirbyDreamLand(PyBoyGameWrapper): """ @@ -57,7 +51,7 @@ def post_tick(self): self.score = 0 score_digits = 5 for n in range(score_digits): - self.score += self.pyboy.get_memory_value(0xD06F + n) * 10**(score_digits-n) + self.score += self.pyboy.get_memory_value(0xD06F + n) * 10**(score_digits - n) # Check if game is over prev_health = self.health diff --git a/pyboy/plugins/game_wrapper_pokemon_gen1.py b/pyboy/plugins/game_wrapper_pokemon_gen1.py index 1bf9a6c31..e9c5b47eb 100644 --- a/pyboy/plugins/game_wrapper_pokemon_gen1.py +++ b/pyboy/plugins/game_wrapper_pokemon_gen1.py @@ -17,12 +17,6 @@ logger = logging.getLogger(__name__) -try: - from cython import compiled - cythonmode = compiled -except ImportError: - cythonmode = False - class GameWrapperPokemonGen1(PyBoyGameWrapper): """ diff --git a/pyboy/plugins/game_wrapper_super_mario_land.py b/pyboy/plugins/game_wrapper_super_mario_land.py index d632454dd..6dee26b3a 100644 --- a/pyboy/plugins/game_wrapper_super_mario_land.py +++ b/pyboy/plugins/game_wrapper_super_mario_land.py @@ -10,18 +10,13 @@ import logging import numpy as np + from pyboy.utils import WindowEvent from .base_plugin import PyBoyGameWrapper logger = logging.getLogger(__name__) -try: - from cython import compiled - cythonmode = compiled -except ImportError: - cythonmode = False - # Mario and Daisy base_scripts = list(range(81)) plane = list(range(99, 110)) diff --git a/pyboy/plugins/game_wrapper_tetris.py b/pyboy/plugins/game_wrapper_tetris.py index f0b657f04..383d09ba7 100644 --- a/pyboy/plugins/game_wrapper_tetris.py +++ b/pyboy/plugins/game_wrapper_tetris.py @@ -11,18 +11,13 @@ from array import array import numpy as np + from pyboy.utils import WindowEvent from .base_plugin import PyBoyGameWrapper logger = logging.getLogger(__name__) -try: - from cython import compiled - cythonmode = compiled -except ImportError: - cythonmode = False - # Table for translating game-representation of Tetromino types (8-bit int) to string tetromino_table = { "L": 0, @@ -84,12 +79,7 @@ def __init__(self, *args, **kwargs): ROWS, COLS = self.shape self._cached_game_area_tiles_raw = array("B", [0xFF] * (ROWS*COLS*4)) - - if cythonmode: - self._cached_game_area_tiles = memoryview(self._cached_game_area_tiles_raw).cast("I", shape=(ROWS, COLS)) - else: - v = memoryview(self._cached_game_area_tiles_raw).cast("I") - self._cached_game_area_tiles = [v[i:i + COLS] for i in range(0, COLS * ROWS, COLS)] + self._cached_game_area_tiles = memoryview(self._cached_game_area_tiles_raw).cast("I", shape=(ROWS, COLS)) super().__init__(*args, game_area_section=(2, 0) + self.shape, game_area_wrap_around=True, **kwargs)