def extract(args): with open(args.rom, 'rb') as rom: print("INCLUDE \"telefang.inc\"") print("") print("SECTION \"CGB Background Palette Data\", " + format_sectionaddr_rom(args.bg_palette_loc)) print("LCDC_CGB_BGPaletteTable::") bgp_table, bgp_code = rip_palettedata(rom, args.bg_palette_loc, args.bg_palette_len) max_bgp_index = 0 for palette in bgp_table: for index in palette: if index > max_bgp_index: max_bgp_index = index for code in bgp_code: print(" " + code) print("\nSECTION \"CGB Background Color Data\", " + format_sectionaddr_rom(args.bg_color_loc)) print("LCDC_CGB_BGColorTable::") bgc_code = rip_colordata(rom, args.bg_color_loc, max_bgp_index) i = 0 for codeset in bgc_code: print(";Palette {0:X}".format(i)) i += 1 for code in codeset: print(" " + code) print("\nSECTION \"CGB Object Palette Data\", " + format_sectionaddr_rom(args.obj_palette_loc)) print("LCDC_CGB_OBPaletteTable::") obp_table, obp_code = rip_palettedata(rom, args.obj_palette_loc, args.obj_palette_len) max_obp_index = 0 for palette in obp_table: for index in palette: if index > max_obp_index: max_obp_index = index for code in obp_code: print(" " + code) print("\nSECTION \"CGB Object Color Data\", " + format_sectionaddr_rom(args.obj_color_loc)) print("LCDC_CGB_OBColorTable::") obc_code = rip_colordata(rom, args.obj_color_loc, max_obp_index) i = 0 for codeset in obc_code: print(";Palette {0:X}".format(i)) i += 1 for code in codeset: print(" " + code)
def asm(args): """Generate the ASM for string tables. This operation needs to be performed once, plus Generated ASM will be printed to console. This portion of the script is intended to be piped into a file.""" charmap = mainscript_text.parse_charmap(args.charmap) tablenames = parse_tablenames(args.tablenames) for table in tablenames: print('SECTION "' + table["symbol"] + ' Section", ' + mainscript_text.format_sectionaddr_rom(mainscript_text.flat(table["basebank"], table["baseaddr"]))) print(table["symbol"] + '::') print('\tINCBIN "' + os.path.join(args.output, table["objname"]).replace("\\", "/") + '"') print(table["symbol"] + '_END') print('')
def rip_msprite_mtable(rom, offset=0x094D, count=9): """Rip an entire ROM's metasprite data.""" cloc = rom.tell() rom.seek(offset) #The metasprite metatable is oddly organized here. #Banks in one place, pointers in the other. banks = [] ptrs = [] for i in range(0, count): banks.append(CHARA.unpack(rom.read(1))[0]) for i in range(0, count): ptrs.append(PTR.unpack(rom.read(2))[0]) asmsrc = "SECTION \"MetaSprite metatable\", " + format_sectionaddr_rom( offset) + "\n" asmsrc += "MetaspriteBankMetatable::\n" for bank in banks: asmsrc += " db BANK(MetaSprite_" + "{0:x}".format(bank) + ")\n" asmsrc += "MetaspriteAddressMetatable::\n" for bank, ptr in zip(banks, ptrs): asmsrc += " dw MetaSprite_" + "{0:x}".format(bank) + "\n" asmsrc += "\n" files = {} for bank, ptr in zip(banks, ptrs): table_asmsrc, table_files = rip_msprite_table(rom, flat(bank, ptr)) asmsrc += table_asmsrc + "\n" files.update(table_files) return (asmsrc, files)
def asm(args): """Generate an ASM file for the metatables and tables present within the compressed tilemap system. This process needs to be run at least once, to convert the compressed tilemap names into imports that the assembler and linker can use. Changes to that file can be mirrored into the ASM by re-running this command, or manually doing so.""" charmap = mainscript_text.parse_charmap(args.charmap) datas, datas_index, banks, bank_index = parse_mapnames(args.mapnames) with open(args.rom, 'rb') as rom: #Extract the table so we know what order to reference data. metatable = extract_metatable(rom, args.metatable_length, args.metatable_loc) metatable_attribs = extract_metatable(rom, args.metatable_length, args.metatable_loc_attribs) bank_tables = {"tilemap": [], "attrib": []} bank_datas = {"tilemap": [], "attrib": []} for i, bank in enumerate(metatable): this_bank_data, this_bank_table = decompress_bank( rom, 0x4000 * bank) bank_tables["tilemap"].append(this_bank_table) bank_datas["tilemap"].append(this_bank_data) for i, bank in enumerate(metatable_attribs): this_bank_data, this_bank_table = decompress_bank( rom, 0x4000 * bank) bank_tables["attrib"].append(this_bank_table) bank_datas["attrib"].append(this_bank_data) #Generate ASM for the metatables for category_name, category_index in list(datas_index.items()): if category_name == "attrib": print('SECTION "' + category_name + ' Section", ' + mainscript_text.format_sectionaddr_rom( args.metatable_loc_attribs)) print('RLEAttribmapBanks::') elif category_name == "tilemap": print( 'SECTION "' + category_name + ' Section", ' + mainscript_text.format_sectionaddr_rom(args.metatable_loc)) print('RLETilemapBanks::') for bank_id, bank_table_index in list(category_index.items()): bank = banks[bank_index[category_name][bank_id]] print('\tdb BANK(' + bank["symbol"] + ')') print('') print('') #Generate ASM for each individual table. for category_name, category_index in list(datas_index.items()): for bank_id, _ in list(category_index.items()): bank = banks[bank_index[category_name][bank_id]] rom.seek(bank["flataddr"]) print('SECTION "' + category_name + ' Bank {0}'.format(bank_id) + '", ' + mainscript_text.format_sectionaddr_rom(bank["flataddr"])) print(bank["symbol"] + '::') #Print out the table in the order we extracted it from baserom for table_index in bank_tables[category_name][bank_id]: #Detect if a table pointer refers to the end of the table is_junk = False if table_index >= len(datas_index[category_name][bank_id]): data_meta = datas[datas_index[category_name][bank_id][ table_index - 1]] print('\tdw ' + data_meta["symbol"] + "_END") else: data_meta = datas[datas_index[category_name][bank_id] [table_index]] print('\tdw ' + data_meta["symbol"]) print('') #Print out all the data blocks in the table. for tmap_id, _ in enumerate( bank_datas[category_name][bank_id]): #Prevent spitting out nonexistent data here if tmap_id >= len(datas_index[category_name][bank_id]): continue data_meta = datas[datas_index[category_name][bank_id] [tmap_id]] print(data_meta["symbol"] + '::') print('\tincbin "' + os.path.join( args.output, data_meta["objname"]).replace("\\", "/") + '"') print(data_meta["symbol"] + '_END') print('') print('')
def asm(args): """Generate an ASM file for the metatables and tables present within the compressed tilemap system. This process needs to be run at least once, to convert the compressed tilemap names into imports that the assembler and linker can use. Changes to that file can be mirrored into the ASM by re-running this command, or manually doing so.""" charmap = mainscript_text.parse_charmap(args.charmap) datas, datas_index, banks, bank_index = parse_mapnames(args.mapnames) with open(args.rom, 'rb') as rom: #Extract the table so we know what order to reference data. metatable = extract_metatable(rom, args.metatable_length, args.metatable_loc) metatable_attribs = extract_metatable(rom, args.metatable_length, args.metatable_loc_attribs) bank_tables = {"tilemap": [], "attrib": []} bank_datas = {"tilemap": [], "attrib": []} for i, bank in enumerate(metatable): this_bank_data, this_bank_table = decompress_bank(rom, 0x4000 * bank) bank_tables["tilemap"].append(this_bank_table) bank_datas["tilemap"].append(this_bank_data) for i, bank in enumerate(metatable_attribs): this_bank_data, this_bank_table = decompress_bank(rom, 0x4000 * bank) bank_tables["attrib"].append(this_bank_table) bank_datas["attrib"].append(this_bank_data) #Generate ASM for the metatables for category_name, category_index in list(datas_index.items()): if category_name == "attrib": print('SECTION "' + category_name + ' Section", ' + mainscript_text.format_sectionaddr_rom(args.metatable_loc_attribs)) print('RLEAttribmapBanks::') elif category_name == "tilemap": print('SECTION "' + category_name + ' Section", ' + mainscript_text.format_sectionaddr_rom(args.metatable_loc)) print('RLETilemapBanks::') for bank_id, bank_table_index in list(category_index.items()): bank = banks[bank_index[category_name][bank_id]] print('\tdb BANK(' + bank["symbol"] + ')') print('') print('') #Generate ASM for each individual table. for category_name, category_index in list(datas_index.items()): for bank_id, _ in list(category_index.items()): bank = banks[bank_index[category_name][bank_id]] rom.seek(bank["flataddr"]) print('SECTION "' + category_name + ' Bank {0}'.format(bank_id) + '", ' + mainscript_text.format_sectionaddr_rom(bank["flataddr"])) print(bank["symbol"] + '::') #Print out the table in the order we extracted it from baserom for table_index in bank_tables[category_name][bank_id]: #Detect if a table pointer refers to the end of the table is_junk = False if table_index >= len(datas_index[category_name][bank_id]): data_meta = datas[datas_index[category_name][bank_id][table_index - 1]] print('\tdw ' + data_meta["symbol"] + "_END") else: data_meta = datas[datas_index[category_name][bank_id][table_index]] print('\tdw ' + data_meta["symbol"]) print('') #Print out all the data blocks in the table. for tmap_id, _ in enumerate(bank_datas[category_name][bank_id]): #Prevent spitting out nonexistent data here if tmap_id >= len(datas_index[category_name][bank_id]): continue data_meta = datas[datas_index[category_name][bank_id][tmap_id]] print(data_meta["symbol"] + '::') print('\tincbin "' + os.path.join(args.output, data_meta["objname"]).replace("\\", "/") + '"') print(data_meta["symbol"] + '_END') print('') print('')