From a9a626a8611b95938e96ad203b2f60b0709904fc Mon Sep 17 00:00:00 2001 From: Antonio Roman Date: Sun, 21 Jul 2024 08:40:31 +0400 Subject: [PATCH] added API to get more data from the ROM cartridge --- docs/index.html | 36 +++++++++++++++++++++ pyboy/core/cartridge/base_mbc.pxd | 4 +++ pyboy/core/cartridge/base_mbc.py | 54 ++++++++++++++++++++++++++++++- pyboy/pyboy.pxd | 2 ++ pyboy/pyboy.py | 36 +++++++++++++++++++++ 5 files changed, 131 insertions(+), 1 deletion(-) diff --git a/docs/index.html b/docs/index.html index 175e11905..9f53e5b74 100644 --- a/docs/index.html +++ b/docs/index.html @@ -394,6 +394,42 @@

Kwargs

Game title """ + self.cartridge_title = self.mb.cartridge.gametype + """ + The game type stored on the currently loaded cartridge ROM. Values are: + Game Boy, Game Boy Color, Super Game Boy + + Example: + ```python + >>> pyboy.cartridge_type # Game type of PyBoy's default ROM + 'Game Boy Color' + + ``` + + Returns + ------- + str : + Game type + """ + + self.cartridge_region = self.mb.cartridge.gameregion + """ + The game region stored on the currently loaded cartridge ROM. Example values are: + Europe, USA, Japan, Spain, Germany, World... + + Example: + ```python + >>> pyboy.cartridge_region # Game region of PyBoy's default ROM + 'Europe' + + ``` + + Returns + ------- + str : + Europe + """ + self._hooks = {} self._plugin_manager = PluginManager(self, self.mb, kwargs) diff --git a/pyboy/core/cartridge/base_mbc.pxd b/pyboy/core/cartridge/base_mbc.pxd index 5b8842795..9d404c50e 100644 --- a/pyboy/core/cartridge/base_mbc.pxd +++ b/pyboy/core/cartridge/base_mbc.pxd @@ -15,6 +15,8 @@ cdef Logger logger cdef class BaseMBC: cdef str filename cdef str gamename + cdef srt gametype + cdef str gameregion cdef uint8_t[:, :] rombanks cdef uint8_t[:,:] rambanks cdef uint8_t carttype @@ -37,6 +39,8 @@ cdef class BaseMBC: cdef void load_ram(self, IntIOInterface) noexcept cdef void init_rambanks(self, uint8_t) noexcept cdef str getgamename(self, uint8_t[:,:]) noexcept + cdef str getgametype(self, uint8_t[:,:]) noexcept + cdef str getgameregion(self, uint8_t[:,:]) noexcept cdef uint8_t getitem(self, uint16_t) noexcept nogil cdef void setitem(self, uint16_t, uint8_t) noexcept nogil diff --git a/pyboy/core/cartridge/base_mbc.py b/pyboy/core/cartridge/base_mbc.py index f03bf0fdf..08bc60293 100644 --- a/pyboy/core/cartridge/base_mbc.py +++ b/pyboy/core/cartridge/base_mbc.py @@ -34,6 +34,8 @@ def __init__(self, filename, rombanks, external_ram_count, carttype, sram, batte self.external_ram_count = external_ram_count self.init_rambanks(external_ram_count) self.gamename = self.getgamename(rombanks) + self.gametype = self.getgametype(rombanks) + self.gameregion = self.getgameregion(rombanks) self.memorymodel = 0 self.rambank_enabled = False @@ -103,7 +105,55 @@ def init_rambanks(self, n): self.rambanks = memoryview(array.array("B", [0] * (8*1024*16))).cast("B", shape=(16, 8 * 1024)) def getgamename(self, rombanks): - return "".join([chr(rombanks[0, x]) for x in range(0x0134, 0x0142)]).split("\0")[0] + return "".join([chr(rombanks[0, x]) for x in range(0x0134, 0x0143)]).split("\0")[0] + + def getgametype(self, rombanks): + if rombanks[0, 0x143] == 0x80 or rombanks[0, 0x143] == 0xc0: + return "Game Boy Color" + elif rombanks[0, 0x146] == 0x03: + return "Super Game Boy" + else: + return "Game Boy" + + def getgameregion(self, rombanks): + game_type = self.getgametype(rombanks) + # The region character is only present in GBC/SGB games only; for regular GB games can't be fetched + if game_type == 'Game Boy': + return "Unknown" + else: + # Get the last letter of the sales code that determines the region + region_string = "".join([chr(rombanks[0, x]) for x in range(0x13f, 0x0143)]).split("\0")[0] + if region_string: + region_code = region_string[-1] + else: + return "Unknown" + # Return game region according to the last letter of the serial code + if region_code == 'J': + return "Japan" + elif region_code == 'E': + return "USA" + elif region_code == 'P': + return "Europe" + elif region_code == 'S': + return "Spain" + elif region_code == 'I': + return "Italy" + elif region_code == 'F': + return "France" + elif region_code == 'D': + return "Germany" + elif region_code == 'A': + return "World" + elif region_code == 'X': + return "Europe" + elif region_code == 'Y': + return "Europe" + elif region_code == 'K': + return "Korea" + elif region_code == 'U': + return "Australia" + else: + return "Unknown" def setitem(self, address, value): raise Exception("Cannot set item in MBC") @@ -138,6 +188,8 @@ def __repr__(self): "MBC class: %s" % self.__class__.__name__, "Filename: %s" % self.filename, "Game name: %s" % self.gamename, + "Game type: %s" % self.gametype, + "Game region: %s" % self.gameregion, "GB Color: %s" % str(self.rombanks[0, 0x143] == 0x80), "Cartridge type: %s" % hex(self.carttype), "Number of ROM banks: %s" % self.external_rom_count, diff --git a/pyboy/pyboy.pxd b/pyboy/pyboy.pxd index fec26265d..3353648a1 100644 --- a/pyboy/pyboy.pxd +++ b/pyboy/pyboy.pxd @@ -60,6 +60,8 @@ cdef class PyBoy: cdef readonly object game_wrapper cdef readonly MemoryScanner memory_scanner cdef readonly str cartridge_title + cdef readonly str cartridge_type + cdef readonly str cartridge_region cdef bint limit_emulationspeed cdef int emulationspeed, target_emulationspeed, save_target_emulationspeed diff --git a/pyboy/pyboy.py b/pyboy/pyboy.py index f2c969134..674462521 100644 --- a/pyboy/pyboy.py +++ b/pyboy/pyboy.py @@ -323,6 +323,42 @@ def __init__( Game title """ + self.cartridge_type = self.mb.cartridge.gametype + """ + The game type stored on the currently loaded cartridge ROM. Values are: + Game Boy, Game Boy Color, Super Game Boy + + Example: + ```python + >>> pyboy.cartridge_type # Game type of PyBoy's default ROM + 'Game Boy Color' + + ``` + + Returns + ------- + str : + Game type + """ + + self.cartridge_region = self.mb.cartridge.gameregion + """ + The game region stored on the currently loaded cartridge ROM. Example values are: + Europe, USA, Japan, Spain, Germany, World... + + Example: + ```python + >>> pyboy.cartridge_region # Game region of PyBoy's default ROM + 'Europe' + + ``` + + Returns + ------- + str : + Europe + """ + self._hooks = {} self._plugin_manager = PluginManager(self, self.mb, kwargs)