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() })
def __init__(self, rom: Rom, table_offset: int, table_size: int, base_event_id=0): self._base_event_id = base_event_id self._lut = list(rom.get_lut(table_offset, table_size))
def __init__(self, rom: Rom): self._maps = [] self.dummy_chests = [] self._map_lut = rom.get_lut(0x1E4F40, 124) for map_id, map_addr in enumerate(self._map_lut): map_stream = rom.get_stream(Rom.pointer_to_offset(map_addr), bytearray.fromhex("ffff")) map = MapFeatures(map_id, map_stream) self._maps.append(map) # Collect the dummy chests together self.dummy_chests += map.dummy_chests
class TestRom(unittest.TestCase): def setUp(self): self.rom = Rom(data=bytearray([ # String (0x0) 0x82, 0x66, 0x82, 0x8f, 0x82, 0x82, 0x82, 0x8c, 0x82, 0x89, 0x82, 0x8e, 0x00, 0x00, 0x00, 0x00, # LUT (0x10) 0x34, 0x12, 0x00, 0x08, 0x78, 0x56, 0x00, 0x08, 0xbc, 0x9a, 0x00, 0x08, 0xf0, 0xde, 0x00, 0x08 ])) def test_open_bytestream(self): stream = self.rom.open_bytestream(0x0, 0x4) self.assertEqual(stream.size(), 4) self.assertEqual(stream.get_u16(), 0x6682) def test_open_bytestream_out_of_bounds(self): with self.assertRaises(RuntimeError): stream = self.rom.open_bytestream(0x100, 0x4) def test_get_lut(self): lut = self.rom.get_lut(0x10, 4) self.assertEqual(len(lut), 4) addressses = [ 0x8001234, 0x8005678, 0x8009abc, 0x800def0, ] for index, address in enumerate(lut): self.assertEqual(address, addressses[index]) def test_get_lut_misaligned(self): with self.assertRaises(RuntimeError): lut = self.rom.get_lut(0x12, 2) def test_get_string(self): a_str = self.rom.get_string(0x0) self.assertEqual(len(a_str), 0xd) def test_patch(self): patch = OutputStream() patch.put_u32(0x12345678) patched = self.rom.apply_patch(0x0, patch.get_buffer()) confirm = patched.open_bytestream(0x0, 0x4) self.assertEqual(confirm.get_u32(), 0x12345678) def test_patches(self): patch = OutputStream() patch.put_u32(0x12345678) patched = self.rom.apply_patches({ 0x0: patch.get_buffer(), 0x10: patch.get_buffer() }) confirm = patched.open_bytestream(0x0, 0x4) self.assertEqual(confirm.get_u32(), 0x12345678) confirm = patched.open_bytestream(0x10, 0x4) self.assertEqual(confirm.get_u32(), 0x12345678) def test_overlap_patch(self): patch = OutputStream() patch.put_u32(0x12345678) patch.put_u32(0x12345678) with self.assertRaises(RuntimeError): patched = self.rom.apply_patches({ 0x0: patch.get_buffer(), 0x4: patch.get_buffer() }) self.assertNotEqual(patched, patched)
def __init__(self, rom: Rom, lut_offset: int, count: int): self.lut_offset = lut_offset self.lut = list(rom.get_lut(lut_offset, count)) self.strings = [] for addr in self.lut: self.strings.append(rom.get_string(Rom.pointer_to_offset(addr)))