def patch_spirit_temple_mq_room_6(rom: LocalRom, room_addr): cur = room_addr actor_list_addr = 0 cmd_actors_offset = 0 # scan for actor list and header end code = rom.read_byte(cur) while code != 0x14: #terminator if code == 0x01: # actors actor_list_addr = rom.read_int32(cur + 4) cmd_actors_offset = cur - room_addr cur += 8 code = rom.read_byte(cur) cur += 8 # original header size header_size = cur - room_addr # set alternate header data location alt_data_off = header_size + 8 # set new alternate header offset alt_header_off = align16(alt_data_off + (4 * 3)) # alt header record size * num records # write alternate header data # the first 3 words are mandatory. the last 3 are just to make the binary # cleaner to read rom.write_int32s(room_addr + alt_data_off, [0, get_segment_address(3, alt_header_off), 0, 0, 0, 0]) # clone header a_start = room_addr a_end = a_start + header_size b_start = room_addr + alt_header_off b_end = b_start + header_size rom.buffer[b_start:b_end] = rom.buffer[a_start:a_end] # make the child header skip the first actor, # which avoids the spawning of the block while in the hole cmd_addr = room_addr + cmd_actors_offset actor_list_addr += 0x10 actors = rom.read_byte(cmd_addr + 1) rom.write_byte(cmd_addr + 1, actors - 1) rom.write_int32(cmd_addr + 4, actor_list_addr) # move header rom.buffer[a_start + 8:a_end + 8] = rom.buffer[a_start:a_end] # write alternate header command seg = get_segment_address(3, alt_data_off) rom.write_int32s(room_addr, [0x18000000, seg])
def write_map_data(self, rom: LocalRom): if self.id >= 10: return # write floormap floormap_indices = 0xB6C934 floormap_vrom = 0xBC7E00 floormap_index = rom.read_int16(floormap_indices + (self.id * 2)) floormap_index //= 2 # game uses texture index, where two textures are used per floor cur = floormap_vrom + (floormap_index * 0x1EC) for floormap in self.floormaps: for icon in floormap: Icon.write_to_floormap(icon, rom, cur) cur += 0xA4 # fixes jabu jabu floor B1 having no chest data if self.id == 2: cur = floormap_vrom + (0x08 * 0x1EC + 4) kaleido_scope_chest_verts = 0x803A3DA0 # hax, should be vram 0x8082EA00 rom.write_int32s(cur, [0x17, kaleido_scope_chest_verts, 0x04]) # write minimaps map_mark_vrom = 0xBF40D0 map_mark_vram = 0x808567F0 map_mark_array_vram = 0x8085D2DC # ptr array in map_mark_data to minimap "marks" array_vrom = map_mark_array_vram - map_mark_vram + map_mark_vrom map_mark_scene_vram = rom.read_int32(self.id * 4 + array_vrom) mark_vrom = map_mark_scene_vram - map_mark_vram + map_mark_vrom cur = mark_vrom for minimap in self.minimaps: for icon in minimap: Icon.write_to_minimap(icon, rom, cur) cur += 0x26
def __init__(self, rom: LocalRom, start, offset): self.offset = offset self.poly_addr = rom.read_int32(start + offset + 0x18) self.polytypes_addr = rom.read_int32(start + offset + 0x1C) self.camera_data_addr = rom.read_int32(start + offset + 0x20) self.polytypes = (self.poly_addr - self.polytypes_addr) // 8
def patch_mesh(self, rom: LocalRom, mesh: CollisionMesh): start = self.file.start final_cams = [] # build final camera data for cam in self.coldelta.cams: data = cam['Data'] pos = cam['PositionIndex'] if pos < 0: final_cams.append((data, 0)) else: addr = start + (mesh.camera_data_addr & 0xFFFFFF) seg_off = rom.read_int32(addr + (pos * 8) + 4) final_cams.append((data, seg_off)) types_move_addr = 0 # if data can't fit within the old mesh space, append camera data if self.coldelta.is_larger: types_move_addr = mesh.camera_data_addr # append to end of file self.write_cam_data(rom, self.file.end, final_cams) mesh.camera_data_addr = get_segment_address( 2, self.file.end - self.file.start) self.file.end += len(final_cams) * 8 else: types_move_addr = mesh.camera_data_addr + (len(final_cams) * 8) # append in place addr = self.file.start + (mesh.camera_data_addr & 0xFFFFFF) self.write_cam_data(rom, addr, final_cams) # if polytypes needs to be moved, do so if (types_move_addr != mesh.polytypes_addr): a_start = self.file.start + (mesh.polytypes_addr & 0xFFFFFF) b_start = self.file.start + (types_move_addr & 0xFFFFFF) size = mesh.polytypes * 8 rom.buffer[b_start:b_start + size] = rom.buffer[a_start:a_start + size] mesh.polytypes_addr = types_move_addr # patch polytypes for item in self.coldelta.polytypes: id = item['Id'] high = item['High'] low = item['Low'] addr = self.file.start + (mesh.polytypes_addr & 0xFFFFFF) + (id * 8) rom.write_int32s(addr, [high, low]) # patch poly data for item in self.coldelta.polys: id = item['Id'] t = item['Type'] flags = item['Flags'] addr = self.file.start + (mesh.poly_addr & 0xFFFFFF) + (id * 0x10) vert_bit = rom.read_byte(addr + 0x02) & 0x1F # VertexA id data rom.write_int16(addr, t) rom.write_byte(addr + 0x02, (flags << 5) + vert_bit) # Write Mesh to Scene mesh.write_to_scene(rom, self.file.start)