def write(self, rom: Rom) -> Rom: # Since there's a LUT and the data that it points to, create two output streams. # This should work because both are continuous. data_lut_stream = OutputStream() shop_inventory = OutputStream() next_shop_addr = self.shop_data_pointers[0].pointer start_size = 0 for index in range(51): new_shop_length = self.shop_inventories[index].write( shop_inventory) sdp = self.shop_data_pointers[index] sdp.contents = ( (sdp.shop_graphic << 4) & 0xf0) | (new_shop_length & 0x0f) sdp.pointer = next_shop_addr sdp.write(data_lut_stream) # Because the size of the data varies by shop, we have to keep track of how # large the output buffer was and move the pointer up by the difference. next_shop_addr += (shop_inventory.size() - start_size) start_size = shop_inventory.size() # Make a dictionary for the two parts so we only have to write the new Rom once. patches = { 0x1E070C: data_lut_stream.get_buffer(), Rom.pointer_to_offset(self.shop_data_pointers[0].pointer): shop_inventory.get_buffer() } return rom.apply_patches(patches)
def add_credits(rom: Rom) -> Rom: credits_lut = rom.get_lut(0x1D871C, 128) base_addr = credits_lut[0] new_lut = OutputStream() data_stream = OutputStream() for index, line in enumerate(CREDITS_TEXT.splitlines()[1:]): line = line.strip() if len(line) > 0: encoded = TextBlock.encode_text(line) new_lut.put_u32(base_addr + data_stream.size()) data_stream.put_bytes(encoded) else: new_lut.put_u32(0x0) # And EOF marker new_lut.put_u32(0xffffffff) # Change the duration so it doesn't take so long to scroll duration = OutputStream() duration.put_u16(60 * 60) return rom.apply_patches({ 0x016848: duration.get_buffer(), 0x1D871C: new_lut.get_buffer(), Rom.pointer_to_offset(base_addr): data_stream.get_buffer() })