def create_templates(self, ow_ptrs_addr): rom_base = self.rom_info.name if os.path.exists("Files/" + rom_base): shutil.rmtree("Files/" + rom_base) # Remove the old folder, if it exists current_dir = os.getcwd() os.chdir("Files") os.mkdir(rom_base) os.chdir(current_dir) # Create the new templates templates = [] for i in range(1, 9): templates.append( open("Files/" + rom_base + "/Template" + str(i), "wb+")) os.chmod("Files/" + rom_base + "/Template" + str(i), 0o777) sts.show("Creating the ROM Templates...") log.info("Creating the Templates for the OW Data Pointers") sizes = [ core.FT16x32, core.FT32x32, core.FT16x16, core.FT64x64, core.FT128x64, core.FT48x48, core.FT88x32, core.FT96x40 ] for i, size in enumerate(sizes): # Search all the OWs in the ROM and copy the OW Data of the first # OW with the specific size. If an OW doesn't exist with this size # then there will be a WARNING in the log. ow = 0 found_ow = None while core.is_ow_data_ptr(ow_ptrs_addr + 4 * ow): ow_data = rom.ptr_to_addr(ow_ptrs_addr + 4 * ow) frame_ptr = rom.ptr_to_addr(ow_data + 0x1C) if rom.read_bytes(frame_ptr + 4, 2) == size: found_ow = ow break ow += 1 if found_ow is not None: log.info("Using OW {} for Template {}, size {}".format( ow, i + 1, conv.HEX_LST(size))) else: log.info("This ROM doesn't have an OW with size: " + conv.HEX_LST(size)) # Write the Template data ow_data = rom.ptr_to_addr(ow_ptrs_addr + 4 * ow) template_bytes = bytearray(rom.read_bytes(ow_data, 0x24)) templates[i].write(template_bytes)
def export_ow_image(ui): tbl, ow = ui.selected_table, ui.selected_ow log.info("Exporting the frames of OW ({}, {})".format(tbl, ow)) image = ui.sprite_manager.make_image_from_rom(ui.selected_ow, ui.selected_table) # For the Palette addr = ui.root.getOW(tbl, ow).ow_data_addr palette_id = core.get_ow_palette_id(addr) palette_addr = ui.sprite_manager.get_palette_addr(palette_id) sprite_palette = img.create_palette_from_gba(rom.ptr_to_addr(palette_addr)) image.putpalette(sprite_palette) name = '/' + str(ui.selected_table) + '_' + str(ui.selected_ow) fn, ext = QtWidgets.QFileDialog.getSaveFileName( ui, 'Export Frames Sheet', ui.paths['EXP_FRMS_PATH'] + name, "PNG File (*.png);;" "BMP File (*.bmp);;" "JPEG File (*.jpg)") if not fn: return ui.paths['EXP_FRMS_PATH'] = os.path.dirname(os.path.realpath(fn)) try: image.save(fn) except ValueError: fn += ext.replace(")", "").split("*")[-1] image.save(fn) sts.show("Saved "+fn)
def set_name(self): name_raw = rom.get_word(0xAC) rom_name = conv.capitalized_hex(name_raw)[2:] # Removes the 0x self.name = conv.hex_to_text(rom_name) # Checks if Rom uses JPAN's Engine if rom.ptr_to_addr(0x160EE0) == 0x1A2000: self.name = "JPAN"
def remove_palette(palette_addr): # Remove the color data rom.fill_with_data(rom.ptr_to_addr(palette_addr), 32, 0xFF) # Move all the other palettes left (the palette to be removed will # be just be replaced) working_addr = palette_addr + 8 while not is_palette_table_end(working_addr): # Move the palette data left rom.move_data(working_addr, working_addr - 8, 8, 0x0) working_addr += 8 rom.move_data(working_addr, working_addr - 8, 8, 0x0)
def __init__(self, root): self.root = root self.table_addr = rom.ptr_to_addr(rom.PAL_TBL_PTRS[0]) self.palette_num = self.get_palette_num() self.max_size = self.get_max_size() self.free_slots = self.max_size - self.palette_num\ if self.free_slots == 0: log.info("The Palette Table can't have new Palettes. " "It will be repointed to have more space") sts.show("Updating the Free Space Address for Palettes") rom.update_free_space(self.palette_num * 10) self.repoint_palette_table() self.set_used_palettes()
def find_rom_offsets(self): # Find OW Offsets self.statusbar.showMessage("Searching for OW Offsets") for addr in range(0, rom.rom.rom_size, 4): if core.is_jpan_ptr(addr): table_ptrs = rom.ptr_to_addr(addr) break elif core.is_orig_table_ptr(addr): table_ptrs = addr log.info("Found the OW Tables Pointers at " + conv.HEX(table_ptrs)) # Find Palette Offsets self.statusbar.showMessage("Searching for Palette Offsets") for addr in range(0, rom.rom.rom_size, 4): # Search for the first Palette Pointer if (rom.is_ptr(addr) and img.is_palette_ptr(rom.ptr_to_addr(addr))): palette_table = rom.ptr_to_addr(addr) palette_table_ptrs = rom.find_ptr_in_rom(palette_table, True) log.info("Found the Palette Table at " + conv.HEX(palette_table)) break return [table_ptrs, palette_table_ptrs]
def get_ow_frame(self, ow_num, table_num, frame_num): ow = self.root.getOW(table_num, ow_num) ow_type = ow.frames.get_type() frames_addr = ow.frames.frames_addr width, height = core.get_frame_dimensions(ow_type) # For the palette palette_id = core.get_ow_palette_id(ow.ow_data_addr) palette_addr = self.get_palette_addr(palette_id) sprite_palette = create_palette_from_gba(rom.ptr_to_addr(palette_addr)) frame_size = core.get_frame_size(ow_type) image = create_image_from_addr((frame_num * frame_size) + frames_addr, width, height) image.putpalette(sprite_palette) return image
def open_analyze(self): dlg = QtWidgets.QFileDialog() fn, _ = dlg.getOpenFileName(dlg, 'Open and Analyze ROM file', self.paths['OPEN_ROM_PATH'], "GBA ROM (*.gba)") if not fn: return self.paths['OPEN_ROM_PATH'] = os.path.dirname(os.path.realpath(fn)) log.info("Opened a new ROM: " + fn) sts.show("Opening ROM: " + fn) rom.rom.load_rom(fn) self.rom_info = RomInfo() rom.rom.rom_path = fn # If a profile with the rom base name exist, create a # profile with different name name = self.rom_info.name if ini.check_if_name_exists(name): i = 0 while ini.check_if_name_exists(name + str(i)): i += 1 name += str(i) self.rom_info.name = name ini.create_profile(name, *self.find_rom_offsets()) self.rom_info.set_info(ini.get_name_line_index(name)) self.create_templates(rom.ptr_to_addr(self.rom_info.ow_table_ptr)) self.statusbar.showMessage("Analysis Finished!") self.load_from_profile(name) self.initProfileComboBox() self.profilesComboBox.setCurrentIndex( self.profilesComboBox.findText(name)) self.romNameLabel.setText(rom.rom.rom_path.split('/')[-1])