Ejemplo n.º 1
0
 def parseBuffer(data):
     for parser in RomInfoParser.getParsers():
         if parser.isValidData(data):
             props = parser.parseBuffer(data)
             if props and any(props):
                 return props
     return {}
Ejemplo n.º 2
0
 def parseBuffer(data):
     for parser in RomInfoParser.getParsers():
         if parser.isValidData(data):
             props = parser.parseBuffer(data)
             if props and any(props):
                 return props
     return {}
Ejemplo n.º 3
0
 def parse(filename):
     ext = None
     for parser in RomInfoParser.getParsers():
         if not ext:
             ext = parser._getExtension(filename)
         if parser.isValidExtension(ext):
             props = parser.parse(filename)
             if props and any(props):
                 return props
     return {}
Ejemplo n.º 4
0
 def parse(filename):
     ext = None
     for parser in RomInfoParser.getParsers():
         if not ext:
             ext = parser._getExtension(filename)
         if parser.isValidExtension(ext):
             props = parser.parse(filename)
             if props and any(props):
                 return props
     return {}
Ejemplo n.º 5
0
        #        Only two values are defined: 00h - Japanese, 01h - Non-Japanese.
        props["destination"] = "Japan" if data[0x14a] == 0x00 else ""

        # 014C - Mask ROM version number of the game, usually 00h
        props["version"] = "%02X" % data[0x14c]

        # 014D - Header checksum, 8 bit checksum across the cartridge header bytes 0134-014C
        props["header_checksum"] = "%02X" % data[0x14d]

        # 014E-014F - Global checksum, 16 bit checksum across the whole cartridge ROM
        props["global_checksum"] = "%04X" % ((data[0x14e] << 8) | data[0x14f])

        return props


RomInfoParser.registerParser(GameboyParser())

gameboy_types = {
    0x00: "ROM",
    0x01: "ROM+MBC1",
    0x02: "ROM+MBC1+RAM",
    0x03: "ROM+MBC1+RAM+BATT",
    0x05: "ROM+MBC2",
    0x06: "ROM+MBC2+BATT",
    0x0b: "ROM+MMM01",
    0x0c: "ROM+MMM01+RAM",
    0x0d: "ROM+MMM01+RAM+BATT",
    0x0f: "ROM+MBC3+TIMER+BATT",
    0x10: "ROM+MBC3+TIMER+RAM+BATT",
    0x11: "ROM+MBC3",
    0x12: "ROM+MBC3+RAM",
Ejemplo n.º 6
0
        return any(data[case[0] : case[0] + len(case[1])] == case[1] for case in edge_cases)

    def getPublisher(self, copyright_str):
        """
        Resolve a copyright string into a publisher name. It SHOULD be 4
        characters after a (C) symbol, but there are variations. When the
        company uses a number as a company code, the copyright usually has
        this format: '(C)T-XX 1988.JUL', where XX is the company code.
        """
        company = copyright_str[3:7]
        if "-" in company:
            company = company[company.rindex("-") + 1 : ]
        company = company.rstrip()
        return gensis_publishers.get(company, "")

RomInfoParser.registerParser(GensisParser())


genesis_devices = {
    "J": "3B Joypad",
    "6": "6B Joypad",
    "K": "Keyboard",
    "P": "Printer",
    "B": "Control Ball",
    "F": "Floppy Drive",
    "L": "Activator",
    "4": "Team Player",
    "0": "MS Joypad",
    "R": "RS232C Serial",
    "T": "Tablet",
    "V": "Paddle",
Ejemplo n.º 7
0
    def makeNativeFormat(self, data):
        """
        Correct for word- and byte-swapping.
        """
        if [b for b in data[:4]] == [0x37, 0x80, 0x40, 0x12]:  # [BADC]
            data[::2], data[1::2] = data[1::2], data[::2]
        elif [b for b in data[:4]] == [0x40, 0x12, 0x37, 0x80]:  # [DCBA]
            data[::4], data[1::4], data[2::4], data[3::4] = data[3::4], data[
                2::4], data[1::4], data[::4]
        elif [b for b in data[:4]] == [0x12, 0x40, 0x80, 0x37]:  # [CDAB]
            data[::4], data[1::4], data[2::4], data[3::4] = data[2::4], data[
                3::4], data[::4], data[1::4]


RomInfoParser.registerParser(Nintendo64Parser())

n64_regions = {
    0x00: "",  # Demo games
    0x37: "",  # Beta games
    0x41: "Japan/USA",
    0x44: "Germany",
    0x45: "USA",
    0x46: "France",
    0x49: "Italy",
    0x4A: "Japan",
    0x50: "Europe",
    0x53: "Spain",
    0x55: "Australia",
    0x59: "Australia",
    # Other PAL European codes
Ejemplo n.º 8
0
            for p_code, p_desc in dc_peripherals.items():
                if peripherals_code & p_code == p_code:
                    peripherals.append(p_desc)
            props['compatible_peripherals'] = tuple(peripherals)
            props['media_info'] = tuple(
                int(x) for x in props['media_info_code'][6:].split('/'))
            props['release_date'] = datetime.date(
                *time.strptime(props['release_date_code'], "%Y%m%d")[:3])
            props['regions'] = tuple(
                dc_regions.get(r) for r in props['region_code'])
        except (KeyError, IndexError, ValueError):
            return {}
        return props


RomInfoParser.registerParser(DreamcastParser())

CDI_V2 = 0x80000004
CDI_V3 = 0x80000005
CDI_V35 = 0x80000006

cdi_track_start_mark = (0, 0, 0x01, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF)
cdi_track_sector_sizes = {
    0: 2048,
    1: 2336,
    2: 2352
}
cdi_track_modes = {
    0: 'audio',
    1: 'mode1',
    2: 'mode2'
Ejemplo n.º 9
0
        props["region_code"] = "%02X" % data[0x3e]

        return props

    def makeNativeFormat(self, data):
        """
        Correct for word- and byte-swapping.
        """
        if [b for b in data[:4]] == [0x37, 0x80, 0x40, 0x12]: # [BADC]
            data[::2], data[1::2] = data[1::2], data[::2]
        elif [b for b in data[:4]] == [0x40, 0x12, 0x37, 0x80]: # [DCBA]
            data[::4], data[1::4], data[2::4], data[3::4] = data[3::4], data[2::4], data[1::4], data[::4]
        elif [b for b in data[:4]] == [0x12, 0x40, 0x80, 0x37]: # [CDAB]
            data[::4], data[1::4], data[2::4], data[3::4] = data[2::4], data[3::4], data[::4], data[1::4]

RomInfoParser.registerParser(Nintendo64Parser())


n64_regions = {
    0x00: "", # Demo games
    0x37: "", # Beta games
    0x41: "Japan/USA",
    0x44: "Germany",
    0x45: "USA",
    0x46: "France",
    0x49: "Italy",
    0x4A: "Japan",
    0x50: "Europe",
    0x53: "Spain",
    0x55: "Australia",
    0x59: "Australia",
Ejemplo n.º 10
0
        # 00A0-00AB - Title, UPPER CASE ASCII, padded with 00h (if less than 12 chars)
        props["title"] = self._sanitize(data[0xa0 : 0xa0 + 12])

        # 00AC-00AF - Code, UPPER CASE ASCII
        # This is the same code as the AGB-UTTD code which is printed on the package
        # and sticker on (commercial) cartridges (excluding the leading "AGB-" part).
        # See http://z9.invisionfree.com/Golden_Sun_Hacking/index.php?showtopic=241
        # for the breakdown of what values U, TT and D can have.
        props["code"] = self._sanitize(data[0xac : 0xac + 4])

        # 00B0-00B1 - Licensee, UPPER CASE ASCII
        pub = data[0xb0 : 0xb0 + 2].decode("ascii", "ignore")
        props["publisher"] = gameboy_publishers.get(pub, "")
        props["publisher_code"] = pub

        # 00B3 - Main unit code, identifies the required hardware (00h for current GBA models)
        props["unit_code"] = "%02X" % data[0xb3]

        # 00BC - Software version of the game, usually zero
        props["version"] = "%02X" % data[0xbc]

        # 00BD - Header checksum, 8 bit checksum across the cartridge header bytes 00A0-00BC
        props["header_checksum"] = "%02X" % data[0xbd]

        props["platform"] = "Game Boy Advance"

        return props

RomInfoParser.registerParser(GBAParser())
Ejemplo n.º 11
0
        # 00A0-00AB - Title, UPPER CASE ASCII, padded with 00h (if less than 12 chars)
        props["title"] = self._sanitize(data[0xa0 : 0xa0 + 12])

        # 00AC-00AF - Code, UPPER CASE ASCII
        # This is the same code as the AGB-UTTD code which is printed on the package
        # and sticker on (commercial) cartridges (excluding the leading "AGB-" part).
        # See http://z9.invisionfree.com/Golden_Sun_Hacking/index.php?showtopic=241
        # for the breakdown of what values U, TT and D can have.
        props["code"] = self._sanitize(data[0xac : 0xac + 4])

        # 00B0-00B1 - Licensee, UPPER CASE ASCII
        pub = data[0xb0 : 0xb0 + 2].decode("ascii", "ignore")
        props["publisher"] = gameboy_publishers.get(pub, "")
        props["publisher_code"] = pub

        # 00B3 - Main unit code, identifies the required hardware (00h for current GBA models)
        props["unit_code"] = "%02X" % data[0xb3]

        # 00BC - Software version of the game, usually zero
        props["version"] = "%02X" % data[0xbc]

        # 00BD - Header checksum, 8 bit checksum across the cartridge header bytes 00A0-00BC
        props["header_checksum"] = "%02X" % data[0xbd]

        props["platform"] = "Game Boy Advance"

        return props

RomInfoParser.registerParser(GBAParser())
Ejemplo n.º 12
0
        return props

    def get_cstr(self, ptr, data):
        """
        Parse a zero-terminated (c-style) string from a bytearray. 0xFFFF and
        0x0000 are invalid ptr values and will return "".
        """
        if ptr != 0xffff and ptr != 0 and ptr < len(data):
            term = ptr
            while term < len(data) and data[term]:
                term += 1
            return self._sanitize(data[ptr : term])
        return ""
        

RomInfoParser.registerParser(MasterSystemParser())


mastersystem_romsize = {
    0xa: "8 KB",
    0xb: "16 KB",
    0xc: "32 KB",
    0xd: "48 KB",
    0xe: "64 KB",
    0xf: "128 KB",
    0x0: "256 KB",
    0x1: "512 KB",
    0x2: "1024 KB",
}
Ejemplo n.º 13
0
            for p_code, p_desc in dc_peripherals.items():
                if peripherals_code & p_code == p_code:
                    peripherals.append(p_desc)
            props['compatible_peripherals'] = tuple(peripherals)
            props['media_info'] = tuple(
                int(x) for x in props['media_info_code'][6:].split('/'))
            props['release_date'] = datetime.date(
                *time.strptime(props['release_date_code'], "%Y%m%d")[:3])
            props['regions'] = tuple(
                dc_regions.get(r) for r in props['region_code'])
        except (KeyError, IndexError, ValueError):
            return {}
        return props


RomInfoParser.registerParser(DreamcastParser())

CDI_V2 = 0x80000004
CDI_V3 = 0x80000005
CDI_V35 = 0x80000006

cdi_track_start_mark = (0, 0, 0x01, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF)
cdi_track_sector_sizes = {0: 2048, 1: 2336, 2: 2352}
cdi_track_modes = {0: 'audio', 1: 'mode1', 2: 'mode2'}

dc_regions = {
    'J': 'Asia',  # Japan, Korea, Asian NTSC
    'U': 'America',  # North American NTSC, Brazilian PAL-M, Argentine PAL-N
    'E': 'Europe'  # European PAL
}
Ejemplo n.º 14
0
                kart = contents[(romType & 0xf) % 3]
        return kart

    def getCompanyCode(self, header):
        companyCode = -1
        if header[0x2a] != 0x33:
            companyCode = ((header[0x2a] >> 4) & 0x0F) * 36 + (header[0x2a] & 0x0F)
        else:
            l = chr(header[0x00]).upper()
            r = chr(header[0x01]).upper()
            l2 = ord(l) - ord('7') if l > '9' else ord(l) - ord('0')
            r2 = ord(r) - ord('7') if r > '9' else ord(r) - ord('0')
            companyCode = l2 * 36 + r2 if l2 >= 0 and r2 >= 0 else -1
        return companyCode

RomInfoParser.registerParser(SNESParser())


# Souce: http://softpixel.com/~cwright/sianse/docs/Snesrom.txt
# Snesrom.txt correction: South Korea should be NTSC
snes_regions = {
    0: "Japan",                       # NTSC
    1: "USA/Canada",                  # NTSC
    2: "Europe/Asia/Oceania",         # PAL
    3: "Sweden",                      # PAL
    4: "Finland",                     # PAL
    5: "Denmark",                     # PAL
    6: "France",                      # PAL
    7: "Holland",                     # PAL
    8: "Spain",                       # PAL
    9: "Germany/Austria/Switzerland", # PAL
Ejemplo n.º 15
0
        # 014A - Destination code, if this version of the game is supposed to be sold in Japan.
        #        Only two values are defined: 00h - Japanese, 01h - Non-Japanese.
        props["destination"] = "Japan" if data[0x14a] == 0x00 else ""

        # 014C - Mask ROM version number of the game, usually 00h
        props["version"] = "%02X" % data[0x14c]

        # 014D - Header checksum, 8 bit checksum across the cartridge header bytes 0134-014C
        props["header_checksum"] = "%02X" % data[0x14d]

        # 014E-014F - Global checksum, 16 bit checksum across the whole cartridge ROM
        props["global_checksum"] = "%04X" % ((data[0x14e] << 8) | data[0x14f])

        return props

RomInfoParser.registerParser(GameboyParser())


gameboy_types = {
    0x00: "ROM",
    0x01: "ROM+MBC1",
    0x02: "ROM+MBC1+RAM",
    0x03: "ROM+MBC1+RAM+BATT",
    0x05: "ROM+MBC2",
    0x06: "ROM+MBC2+BATT",
    0x0b: "ROM+MMM01",
    0x0c: "ROM+MMM01+RAM",
    0x0d: "ROM+MMM01+RAM+BATT",
    0x0f: "ROM+MBC3+TIMER+BATT",
    0x10: "ROM+MBC3+TIMER+RAM+BATT",
    0x11: "ROM+MBC3",
Ejemplo n.º 16
0
            props["video_output"] = ""
            props["title"] = ""

            # Skip the UNIF header (0x20 / 32 bytes) and continue with chunked reads
            data = data[0x20 : ]
            while len(data) > 8:
                size = 0
                sizestr = data[4:8]
                if len(sizestr) == 4:
                    size = sizestr[0] | (sizestr[1] << 8) | (sizestr[2] << 16) | (sizestr[3] << 24)
                if size == 0:
                    continue

                ID = self._sanitize(data[ : 4])
                chunk = data[8 : 8 + size]
                data = data[8 + size : ] # Fast-forward past chunk's data

                if ID == "NAME":
                    props["title"] = self._sanitize(chunk)
                elif ID == "TVCI":
                    props["video_output"] = "NTSC" if chunk[0] == 0x00 else "PAL" if chunk[0] == 0x01 else ""
                elif ID == "BATR":
                    props["battery"] = "yes"
                elif ID == "MIRR":
                    if chunk[0] == 0x04:
                        props["four_screen_vram"] = "yes"

        return props

RomInfoParser.registerParser(NESParser())
Ejemplo n.º 17
0
        return props

    def get_cstr(self, ptr, data):
        """
        Parse a zero-terminated (c-style) string from a bytearray. 0xFFFF and
        0x0000 are invalid ptr values and will return "".
        """
        if ptr != 0xffff and ptr != 0 and ptr < len(data):
            term = ptr
            while term < len(data) and data[term]:
                term += 1
            return self._sanitize(data[ptr : term])
        return ""
        

RomInfoParser.registerParser(MasterSystemParser())


mastersystem_romsize = {
    0xa: "8 KB",
    0xb: "16 KB",
    0xc: "32 KB",
    0xd: "48 KB",
    0xe: "64 KB",
    0xf: "128 KB",
    0x0: "256 KB",
    0x1: "512 KB",
    0x2: "1024 KB",
}