/// <summary> /// Apply all patches for Adult Link mod provided by SkilarsArt. /// </summary> public static void ApplyAdultLinkPatches() { // Overwrite segmented address: 0x0601E244 ReadWriteUtils.WriteU32ToROM(0xC56350, 0x060122C4); // Physical: 0xBA5E70 // ??? ReadWriteUtils.WriteU16ToROM(0xC5637E, 0x02BC); ReadWriteUtils.WriteU16ToROM(0xC56380, 0x0226); ReadWriteUtils.WriteU16ToROM(0xC56382, 0x010E); ReadWriteUtils.WriteU16ToROM(0xC56384, 0x02BC); ReadWriteUtils.WriteU16ToROM(0xC56386, 0x012C); ReadWriteUtils.WriteU16ToROM(0xC5638C, 0x0258); ReadWriteUtils.WriteU16ToROM(0xC56392, 0x024E); ReadWriteUtils.WriteU16ToROM(0xC56398, 0x00C8); ReadWriteUtils.WriteU16ToROM(0xC5639A, 0x0082); // Write chunk of segmented addresses for player model. ReadWriteUtils.WriteToROM(0xC5653C, Resources.models.adult_link_code_segaddrs); // Update sword hitbox? { // Kokiri Sword: 3000.0 => 4000.0 ReadWriteUtils.WriteU32ToROM(0xC572BC, 0x457A0000); // Razor Sword: 3000.0 => 4000.0 ReadWriteUtils.WriteU32ToROM(0xC572C0, 0x457A0000); // Gilded Sword: 4000.0 => 5500.0 ReadWriteUtils.WriteU32ToROM(0xC572C4, 0x45ABE000); // Great Fairy's Sword: 5500.0 => 5500.0 ReadWriteUtils.WriteU32ToROM(0xC572C8, 0x45ABE000); } // Overwrite segmented address: 0x06017818 => 0x0601BE60 ReadWriteUtils.WriteU32ToROM(0xC572D4, 0x0601BE60); // Overwrite function pointer: 0x800B7078 => 0x800B7058 // Last function in function pointer array (length 5) at RDRAM: 0x801DCA58 // Old function: F0 = F2 + 44.0 // New function: F0 = F2 + 68.0 ReadWriteUtils.WriteU32ToROM(0xC72FA8, 0x800B7058); // Physical: 0xBC2AC8 // Patch player_actor. { // Replace floats? Physical: 0xC25D38 ReadWriteUtils.WriteU32ToROM(0xCD6218, 0x42600000); // 40.0 => 56.0 ReadWriteUtils.WriteU32ToROM(0xCD621C, 0x42B40000); // 60.0 => 90.0 ReadWriteUtils.WriteU32ToROM(0xCD6220, 0x3F800000); // 0.647 => 1.0 ReadWriteUtils.WriteU32ToROM(0xCD6224, 0x42DE0000); // 71.0 => 111.0 ReadWriteUtils.WriteU32ToROM(0xCD6228, 0x428C0000); // 50.0 => 70.0 ReadWriteUtils.WriteU32ToROM(0xCD622C, 0x429ECCCD); // 49.0 => 79.4 ReadWriteUtils.WriteU32ToROM(0xCD6230, 0x426C0000); // 39.0 => 59.0 ReadWriteUtils.WriteU32ToROM(0xCD6234, 0x42240000); // 27.0 => 41.0 ReadWriteUtils.WriteU32ToROM(0xCD6238, 0x41980000); // 19.0 ReadWriteUtils.WriteU32ToROM(0xCD623C, 0x42100000); // 22.0 => 36.0 ReadWriteUtils.WriteU32ToROM(0xCD6240, 0x42480000); // 32.4 => 50.0 ReadWriteUtils.WriteU32ToROM(0xCD6244, 0x42600000); // 32.0 => 56.0 ReadWriteUtils.WriteU32ToROM(0xCD6248, 0x42880000); // 48.0 => 68.0 ReadWriteUtils.WriteU32ToROM(0xCD624C, 0x428C0000); // 45.294 => 70.0 ReadWriteUtils.WriteU32ToROM(0xCD6250, 0x41900000); // 14.0 => 18.0 ReadWriteUtils.WriteU32ToROM(0xCD6254, 0x41B80000); // 12.0 => 23.0 ReadWriteUtils.WriteU32ToROM(0xCD6258, 0x428C0000); // 55.0 => 70.0 // Replace unknown data chunk immediately following floats. Physical: 0xC25D7C // This affects Link's voice (child voice to adult voice). ReadWriteUtils.WriteToROM(0xCD625C, Resources.models.adult_link_player_actor_data_1); // Replace segmented addresses following previous chunk. Physical: 0xC25DD8 ReadWriteUtils.WriteToROM(0xCD62B8, Resources.models.adult_link_player_actor_data_2); } // Patch Arms_Hook (Hookshot) actor. { // Update segmented address in code: 0x0602D960 => 0x06029D60 // Old: addiu t0, 0x0602 // addiu t0, t0, 0xD960 // New: addiu t0, 0x0602 // addiu t0, t0, 0x9D60 ReadWriteUtils.WriteU32ToROM(0xD3BC50, 0x25089D60); // Physical: 0xC8B770 } // Patch En_Zog (Mikau) actor. { // Update instruction to use new distance to allow pushing Mikau from: 40.0 => 96.0 // Old: lui at, 0x4220 // New: lui at, 0x42C0 ReadWriteUtils.WriteU32ToROM(0xFFA188, 0x3C0142C0); // Physical: 0xF49CA8 } // Patch vertex data and DLists in gameplay_keep. { // Write vertex buffer (1). ReadWriteUtils.WriteToROM(0x10B0510, Resources.models.adult_link_gameplay_keep_vtx_1); // Physical: 0xFFFFB0 // Write vertex buffer (2). ReadWriteUtils.WriteToROM(0x10B0A90, Resources.models.adult_link_gameplay_keep_vtx_2); // Physical: 0x1000530 // Write vertex buffer (3). ReadWriteUtils.WriteToROM(0x10B1810, Resources.models.adult_link_gameplay_keep_vtx_3); // Physical: 0x10012B0 // Replace DList instruction: G_RDPPIPESYNC => G_DL ReadWriteUtils.WriteU64ToROM(0x10B18F0, 0xDE0000000405A2E0); // gsSPDisplayList(0x0405A2E0); // Write vertex buffer (4). ReadWriteUtils.WriteToROM(0x10E52A0, Resources.models.adult_link_gameplay_keep_vtx_4); // Physical: 0x1034D40 // Replace vertex data with small DList (offset 0x5A2E0). ReadWriteUtils.WriteU64ToROM(0x10E52E0, 0xE700000000000000); // gsDPPipeSync(); ReadWriteUtils.WriteU64ToROM(0x10E52E8, 0xDA3800010405A2A0); // gsSPMatrix(G_MTX_NOPUSH, 0x0405A2A0); ReadWriteUtils.WriteU64ToROM(0x10E52F0, 0xDF00000000000000); // gsSPEndDisplayList(); } // Patch DLists for masks (field models). { // Update Keaton Mask to call gameplay_keep DList: gsDPPipeSync() => gsSPDisplayList(0x0405A2E0) ReadWriteUtils.WriteU64ToROM(0x11B14A8, 0xDE0000000405A2E0); // Physical: 0x10FB618 // Update Bunny Hood to call gameplay_keep DLists. ReadWriteUtils.WriteU64ToROM(0x11B2620, 0xDE0000000405A2E0); // Physical: 0x10FC260 ReadWriteUtils.WriteU64ToROM(0x11B2780, 0xDE0000000405A2E8); // Physical: 0x10FC3C0 ReadWriteUtils.WriteU64ToROM(0x11B27B0, 0xDE0000000405A2E0); // Physical: 0x10FC3F0 ReadWriteUtils.WriteU64ToROM(0x11B2890, 0xDE0000000405A2E8); // Physical: 0x10FC4D0 ReadWriteUtils.WriteU64ToROM(0x11B28C0, 0xDE0000000405A2E0); // Physical: 0x10FC500 // Update Mask of Scents to call gameplay_keep DList: gsDPPipeSync() => gsSPDisplayList(0x0405A2E0) ReadWriteUtils.WriteU64ToROM(0x11D6718, 0xDE0000000405A2E0); // Physical: 0x11175B8 } // Replace En_Horse actor (Epona). ReadWriteUtils.WriteToROM(0xCF5950, Resources.models.adult_en_horse); // Insert player model object. ObjUtils.InsertObj(Resources.models.adult_obj_link, 0x11); // Insert adult Epona model object. ObjUtils.InsertObj(Resources.models.adult_obj_epona, 0x7D); }