def add_pet_custom_info(game: 'ROMGame'): software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata) #Usage strings in pet_rom: #Requires BASIC 2 (works on pet2001n). Enter 'SYS 37000' to run #SYS38000 keyboard = input_metadata.Keyboard() keyboard.keys = 74 game.metadata.input_info.add_option(keyboard) #Don't know about joysticks and I know of no software that uses them for tag in game.filename_tags: #(2001, 3008, 3016, 3032, 3032B, 4016, 4032, 4032B, 8032, 8096, 8296, SuperPET) if (tag[0] == '(' and tag[-1] == ')') or (tag[0] == '[' and tag[-1] == ']'): tag = tag[1:-1] for model in ('3008', '3016', '3032', '3032B', '4016', '4032', '4032B', '8032', '8096', '8296', 'SuperPET'): if tag in (model, 'CBM %s' % model, 'CBM%s' % model, 'PET %s' % model, 'PET%s' % model): game.metadata.specific_info['Machine'] = model continue if tag in {'PET 2001', 'PET2001', 'CBM 2001', 'CBM2001'}: #We don't search for just "(2001)" in case that's used to denote the year game.metadata.specific_info['Machine'] = '2001' continue for ram in (8, 16, 32, 96, 128): if tag.lower() in ('%dk ram' % ram, '%dkb ram' % ram): game.metadata.specific_info['Minimum RAM'] = ram continue
def add_commodore_64_custom_info(game: 'ROMGame'): header = cast(FileROM, game.rom).read(amount=64) magic = header[:16] if magic == b'C64 CARTRIDGE ': headered = True game.metadata.specific_info['Header Format'] = 'CCS64' cart_type = int.from_bytes(header[22:24], 'big') #I'm just gonna call it a mapper for consistency, even though that could be argued to be the wrong terminology, but... eh game.metadata.specific_info['Mapper Number'] = cart_type game.metadata.specific_info['Mapper'] = ccs64_cart_types.get( cart_type, 'CCS64 type %d' % cart_type) try: cartridge_name = header[0x20:0x3f].decode('ascii').strip('\0') if cartridge_name: game.metadata.specific_info['Header Title'] = cartridge_name except UnicodeDecodeError: pass else: headered = False game.metadata.specific_info['Headered?'] = headered software = get_commodore_64_software(game, headered) if software: add_generic_software_info(software, game.metadata)
def add_virtual_boy_software_info(software: 'Software', metadata: 'Metadata'): add_generic_software_info(software, metadata) #We won't need to get serial here I guess has_save_hardware = software.has_data_area( 'eeprom') or software.has_data_area( 'sram') or software.get_part_feature('battery') #I am making assumptions about how saving works and I could be wrong metadata.save_type = SaveType.Cart if has_save_hardware else SaveType.Nothing
def add_dreamcast_custom_info(game: 'ROMGame'): if game.rom.extension == 'gdi' and isinstance(game.rom, FileROM): add_dreamcast_rom_info(game.rom, game.metadata) try: software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata) except NotImplementedError: pass
def add_ps1_custom_info(game: 'ROMGame'): try: software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata) except NotImplementedError: pass if game.metadata.product_code: add_info_from_product_code(game.metadata.product_code, game.metadata)
def _add_platform_specific_metadata(game: 'ROMGame'): software = None custom_info_func = custom_info_funcs.get(game.platform.name) if custom_info_func: custom_info_func(game) software = game.metadata.specific_info.get( 'MAME Software') #This shouldn't be here else: #For anything else, use this one to just get basic software list info. #This would only work for optical discs if they are in .chd format though. Also see MAME GitHub issue #2517, which makes a lot of newly created CHDs invalid with older softlists static_info_func = static_info_funcs.get(game.platform.name) if static_info_func: static_info_func(game.metadata) #We should always run rom_file_info_func before software_info_func if it's there, as that means we can get our product code/alt names and then use get_software_by_name and get_software_by_product_code if isinstance(game.rom, FileROM): #TODO: This is where we would call subroms if that's relevant #TODO: Hmm, how would we do that, actually, with m3u and .cue and related rom_file_info_func = rom_file_info_funcs.get(game.platform.name) if rom_file_info_func: rom_file_info_func(game.rom, game.metadata) try: software = game.get_software_list_entry() except NotImplementedError: pass if software: software_info_func = software_info_funcs.get(game.platform.name) if software_info_func: software_info_func(software, game.metadata) else: add_generic_software_info(software, game.metadata) arcade_equivalent_finder = arcade_machine_finders.get(game.platform.name) #TODO: This could just go in ROMGame, potentially, if that doesn't cause a circular import by importing arcade_machine_finders? equivalent_arcade = None if arcade_equivalent_finder: if software: equivalent_arcade = arcade_equivalent_finder(software.description) if not equivalent_arcade and software.parent_name: software_parent = software.parent assert software_parent, 'This is impossible, software.parent_name is set but software list has no parent' equivalent_arcade = arcade_equivalent_finder( software_parent.description) if not equivalent_arcade: equivalent_arcade = arcade_equivalent_finder(game.name) if not equivalent_arcade and main_config.find_equivalent_arcade_games: if software: equivalent_arcade = find_equivalent_arcade_game( game.name, game.metadata.names.values(), software) if equivalent_arcade: game.metadata.specific_info['Equivalent Arcade'] = equivalent_arcade
def add_vic10_custom_info(game: 'ROMGame'): #Input info: Keyboard or joystick rom = cast(FileROM, game.rom) has_header = False if game.metadata.media_type == MediaType.Cartridge and (rom.size % 256) == 2: has_header = True rom.header_length_for_crc_calculation = 2 game.metadata.specific_info['Headered?'] = has_header software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata)
def add_lynx_custom_info(game: 'ROMGame'): add_lynx_info(game.metadata) rom = cast(FileROM, game.rom) magic = rom.read(amount=4) is_headered = magic == b'LYNX' game.metadata.specific_info['Headered?'] = is_headered if is_headered: header = rom.read(amount=64) add_info_from_lynx_header(header, game.metadata) rom.header_length_for_crc_calculation = 64 software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata)
def add_uzebox_custom_info(game: 'ROMGame'): #Save type: ???? header = cast(FileROM, game.rom).read(amount=512) magic = header[0:6] if magic != b'UZEBOX': has_header = False else: has_header = True add_info_from_uze_header(header, game.metadata) game.metadata.specific_info['Headered?'] = has_header software = game.get_software_list_entry(512 if has_header else 0) if software: add_generic_software_info(software, game.metadata) if game.metadata.publisher == 'Belogic': #Belogic just make the console itself, but don't actually make games necessarily game.metadata.publisher = game.metadata.developer
def add_ibm_pcjr_custom_info(game: 'ROMGame'): #Input info: Keyboard or joystick rom = cast(FileROM, game.rom) magic = rom.read(amount=32) header_length = 0 if magic[:25] == b'PCjr Cartridge image file': game.metadata.specific_info['Headered?'] = True #.jrc files just have a comment from 49:549 (null terminated ASCII I guess) for the most part so that might not be interesting to poke into game.metadata.specific_info['Header Format'] = 'JRipCart' header_length = 512 elif magic[:10] == b'Filename: ' and magic[0x14:0x1d] == b'Created: ': #Fields here are more plain texty, but otherwise there's just like... a filename and creation date, which is meaningless, and a generic description field, and also a start address game.metadata.specific_info['Headered?'] = True game.metadata.specific_info['Header Format'] = 'PCJrCart' header_length = 128 software = game.get_software_list_entry(header_length) if software: add_generic_software_info(software, game.metadata)
def add_n64_custom_info(game: 'ROMGame'): entire_rom = cast(FileROM, game.rom).read() magic = entire_rom[:4] is_byteswapped = False if magic == b'\x80\x37\x12\x40': game.metadata.specific_info['ROM Format'] = 'Z64' elif magic == b'\x37\x80\x40\x12': is_byteswapped = True game.metadata.specific_info['ROM Format'] = 'V64' else: game.metadata.specific_info['ROM Format'] = 'Unknown' return header = entire_rom[:64] if is_byteswapped: header = byteswap(header) parse_n64_header(game.metadata, header) normal_controller = input_metadata.NormalController() normal_controller.face_buttons = 6 #A, B, 4 * C normal_controller.shoulder_buttons = 3 #L, R, and I guess Z will have to be counted as a shoulder button normal_controller.analog_sticks = 1 normal_controller.dpads = 1 game.metadata.input_info.add_option(normal_controller) database = _get_mupen64plus_database() if database: rom_md5 = hashlib.md5(entire_rom).hexdigest().upper() database_entry = database.get(rom_md5) if database_entry: add_info_from_database_entry(game.metadata, database_entry) software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata)
def add_saturn_custom_info(game: 'ROMGame'): if game.rom.extension == 'cue': first_track_and_sector_size = get_first_data_cue_track(game.rom.path) if not first_track_and_sector_size: print(game.rom.path, 'has invalid cuesheet') return first_track, sector_size = first_track_and_sector_size if not first_track.is_file(): print(game.rom.path, 'has invalid cuesheet') return try: header = read_mode_1_cd(first_track, sector_size, seek_to=0, amount=256) except NotImplementedError: return elif game.rom.extension == 'ccd': img_file = game.rom.path.with_suffix('.img') #I thiiiiiiiiink .ccd/.img always has 2352-byte sectors? try: header = read_mode_1_cd(img_file, 2352, seek_to=0, amount=256) except NotImplementedError: return elif game.rom.extension == 'iso': header = cast(FileROM, game.rom).read(seek_to=0, amount=256) else: return add_saturn_info(str(game.rom.path), game.metadata, header) try: software = game.get_software_list_entry() if software: add_generic_software_info(software, game.metadata) except NotImplementedError: pass
def add_megadrive_software_list_metadata(software: 'Software', metadata: Metadata): add_generic_software_info(software, metadata) if software.get_shared_feature('addon') == 'SVP': metadata.specific_info['Expansion Chip'] = 'SVP' if software.get_shared_feature('incompatibility') == 'TMSS': metadata.specific_info['Bad TMSS?'] = True slot = software.get_part_feature('slot') if slot == 'rom_eeprom' or software.has_data_area('sram'): metadata.save_type = SaveType.Cart elif metadata.platform == 'Mega Drive': metadata.save_type = SaveType.Nothing if software.name == 'aqlian': #This is naughty, but this bootleg game doesn't run on some stuff so I want to be able to detect it metadata.specific_info['Mapper'] = 'aqlian' else: if slot: if slot not in ('rom_sram', 'rom_fram'): mapper = slot[4:] if slot.startswith('rom_') else slot if mapper in { 'eeprom', 'nbajam_alt', 'nbajamte', 'nflqb96', 'cslam', 'nhlpa', 'blara', 'eeprom_mode1' }: metadata.specific_info['Mapper'] = 'EEPROM' elif mapper == 'jcart': metadata.specific_info['Mapper'] = 'J-Cart' elif mapper in {'codemast', 'mm96'}: metadata.specific_info['Mapper'] = 'J-Cart + EEPROM' else: #https://github.com/mamedev/mame/blob/master/src/devices/bus/megadrive/md_carts.cpp metadata.specific_info['Mapper'] = mapper if software.name == 'pokemon' and software.software_list_name == 'megadriv': #This is also a bit naughty, but Pocket Monsters has different compatibility compared to other games with rom_kof99 metadata.specific_info['Mapper'] = slot[4:] + '_pokemon'
def add_super_cassette_vision_software_info(software: 'Software', metadata: 'Metadata'): add_generic_software_info(software, metadata) metadata.specific_info['Has Extra RAM?'] = software.has_data_area( 'ram') #Or feature "slot" ends with "_ram"