CloudMax
Site Editor
Mega Guay
Posts: 579
|
|
« on: August 12, 2013, 07:43:11 AM » |
|
I've started ASM hacking recently. Someone requested that I posted over here at ZSR as well. I have another thread over at https://www.the-gcn.com/topic/2567-cloudmaxs-oot-ntsc-10-stuff/?p=41071 My OoT Hacking Website (this location will ALWAYS be up to date, if it is something relevant): http://cloudmodding.com/oot/Everything is done in NTSC 1.0 Make Slingshot & Bow (+magical arrows) usable by Adult & Child Link #FIX SLING & BOW FUNCTIONALITY FOR ADULT & CHILD #This is the first ASM Hack I wrote. #0x8038AD88 is the address of the instruction that sets T6 to adult/child #If you're adult (T6==0), the game uses the bow, if you're child (T6==1), the game uses slingshot #So we create a function to set T6 to 0 when you're using bow, and 1 when you're using slingshot, instead of using the age. #This ASM Hack will fix the Projectile Model, Ammunition Usage, and Magical Arrows, all in one go. # #I write the ASM Hack to 0x80600000, so you must have 8mb RAM enabled or move it to another location. # #0x801DAB73 stores what item button you last pressed with a value of 0 to 3 (B, C-Left, C-Down, C-Right) # #T0 = Save RAM offset #We can use: T4, T6
.ORG 0x8038AD84 J code #This'll overwrite the T6 = Age instruction .ORG 0x80600000 code: LUI T4, 0x801E #T4 = Used Button Index Offset (upper bits) LW T4, 0xAB73(T4) #T4 = Used Button Index ADDIU T4, T4, 0x0068 #T4 = Used Button Item Index Offset relative to Save RAM ADDU T4, T0, T4 #T4 = Used Button Item Index Offset LB T4, 0x0000(T4) #T4 = Used Item Index ADDIU T6, R0, 0x0006 #T6 = 0x6 (Slingshot) BEQL T4, T6, end #If (Used Item Index == Slingshot) Execute Delay Slot & Branch to End ADDIU T6, R0, 0x0001 #T6 = 1 (Sling) ADDIU T6, R0, 0x0000 #T6 = 0 (Bow) end: J 0x8038AD8C #Jump back to the address after the initial Jumps delay slot NOP
And here's a hack I wrote to go along with it (and also fix several "issues" with the inventory) #Inventory Slot to Item Usability #This ASM Hack will change the Inventory ASM to read from the Item Usability Table instead of the Slot Usability Table. #Normally the inventory uses the Item Usability Table when setting item icon color, and Item Slot Usability Table for equipping, item name color, ammunition color and enlarging icons when they're selected. As a result, if you were to have an item that you can equip, in a slot that you can't use, you wouldn't be able to use the item. #It also makes it possible to equip slingshot, bow & magical arrows as child & adult (to go with my other code) # #I write the ASM Hack to 0x80600100, so you must have 8mb RAM enabled or move it to another location. # #The ASM is injected after the Inventory has been loaded into to the RAM # #Overwrite: #0x8009A074 LUI A0, 0x8010 #0x8009A078 LW A0, 0xE4BC(A0) # #We can use: A0, A1, A3, T0, T9 #T4 + A78 = Item Usability Offset #
.ORG 0x8009A074 J 0x80600100 NOP .ORG 0x80600100 ADDIU T0, T4, 0x0A78 #T0 = Item Usability Offset LUI T9, 0x8012 ADDIU T9, T9, 0xA65C #T9 = Item Offset #CHILD & ADULT ADDIU A0, R0, 0x0009 #A0 = 9 SB A0, 0x0003(T0) #Bow SB A0, 0x0004(T0) #Fire Arrow SB A0, 0x0006(T0) #Sling SB A0, 0x000C(T0) #Ice Arrow SB A0, 0x0012(T0) #Light Arrow SB A0, 0x0038(T0) #Bow + Fire Arrow SB A0, 0x0039(T0) #Bow + Ice Arrow SB A0, 0x003A(T0) #Bow + Light Arrow #REPLACE THE USAGE OF SLOT ID WITH ITEM ID FOR ALL CHECKS LUI A0, 0x8039 #A0 = Check offsets ADDIU A1, R0, 0x0186 #A1 = New Command SB A1, 0xEA61(A0) #Change Ammunition instructions to use Item ID instead of Slot ID ADDIU A1, R0, 0xF13C #A1 = New Command SB A1, 0xEA67(A0) #Change Ammunition instructions Usability RAM offset from Slots to Items ADDIU A1, R0, 0x0059 #A1 = New Command SB A1, 0xFAC1(A0) #Change Icon Enlarge instructions to use Item ID instead of Slot ID ADDIU A1, R0, 0xF13C #A1 = New Command SB A1, 0xFACF(A0) #Change Icon Enlarge instructions Usability RAM offset from Slots to Items ADDIU A1, R0, 0x018F #A1 = New Command SB A1, 0xF609(A0) #Change Name Color instructions Usability RAM offset from Slots to Items ADDIU A1, R0, 0xF13C #A1 = New Command SB A1, 0xF5EF(A0) #Change Name Color instructions to use Item ID instead of Slot ID #END LUI A0, 0x8010 #Restore A0 LW A0, 0xE4BC(A0) #Restore A0 J 0x8009A07C
This one far from done, and do not expect it to be perfectly stable, the location I inject the code at holds other functions while in menues, so there may very well be crashes in menues and such, I haven't experienced any crashes related to the ASM Hack yet though. The ideal way would be to make the hook (or the entire code) into a ROM patch instead. There is a new version with lots of improvements, and various new options, but it's not ready to be released yet. #CloudMax's Custom Action Engine Alpha v1.0 #You do not have to touch anything above the functions section. #I've prepared 2 example actions: #1 for Iron & Hover Boots (Action ID 43 & 44) #This function will equip the specified boots, unless you already have them equipped, if that's the case, you will unequip them. It costs 2 magic to use. #1 for Quiver, Bullet Bag & Bomb Bag (Action ID 45 to 4D) #This function will turn the items into portable bags with ammo for the 3 different items that when used will give you the amount that specific quiver/bag can carry. It will cost 5 rupees to use. # #A basic Action would look something like this: #customaction1: # #Setup Start (Setup is optional, if item doesn't have any requirements, just skip it) # ADDIU T1, R0, 0x0001 #Magic Required: 0x1 (You need at least 1 magic to use the item) # ADDIU T2, R0, 0x0001 #Magic Cost: 0x1 (Using the item will cost you 1 magic) # ADDIU T3, R0, 0x0001 #Ammo Cost: 0x1 (I've not yet implemented this, since actions aren't actually linked to items) # ADDIU T4, R0, 0x0001 #Health Required: 0x1 (You need at least 1 health to use the item) # ADDIU T5, R0, 0x0001 #Rupee Cost: 0x1 (It'll cost you 1 rupee to use the item) # JALR AT, V0 #Run the setup # NOP # #Setup End # ... # ASM Code for the specified Action # ... # J end #Function is over, jump to end # ADDIU A0, R0, 0x0835 #Set sound to play to 0x0835 (Pull out Item) # .org 0x8038CCAC J start NOP mask: LBU T0, 0x014F(A3) #T0 = Current Mask ADDIU T1, A2, 0xFFC7 #T1 = Mask you're Equipping BNEL T0, T1, 0x8038CCC8 #If Current Mask != Mask you're Equipping Execute Delay Slot and Branch to JAL SB T1, 0x014F(A3) #Then Equip Mask SB R0, 0x014F(A3) #Otherwise, Unequip Mask JAL 0x80389284 #Return .org 0x80600300 start: SLTI T0, A2, 0x43 #Set T0 if A2 is less than 0x43 BEQ T0, R0, setup #Branch if action is NOT less than 0x43 NOP J mask #Jump to the Mask function NOP end: JAL 0x800646F0 #Play sound NOP J 0x8038CE9C # LW RA, 0x0014(SP) # unusable: J end #Jump to End ADDIU A0, R0, 0x4806 #Set sound to play to Unusable Item setup: #V1 = 0x8011A5D0 (SRAM Address) #A2 = Action ID #RA = Default Return Address, do not change unless you know what you're doing LI RA, end #Set RA to end so that it can be used at the end of a function. ADDU T1, R0, R0 #Clear T1 for function setups ADDU T2, R0, R0 #Clear T2 for function setups ADDU T3, R0, R0 #Clear T3 for function setups ADDU T4, R0, R0 #Clear T4 for function setups ADDU T5, R0, R0 #Clear T5 for function setups LI V0, verify #Prepare V0 for function setup verification B functions #Jump to functions NOP verify: #AT = Return Address Address to return to after verifying the item. #T1 = Magic Required You need atleast this much magic to use it. #T2 = Magic Cost This is the amount of magic it'll cost when using it. This'll be the required amount if it is higher than T1. #T3 = Ammo Cost (Not added)The amount of Ammo you need to use the item, you'll also loose the same amount. (ONLY WORKS FOR ITEMS WITH AMMO) #T4 = Health Required The amount of health you need to use the item. #T5 = Rupee Cost The amount of rupees it'll cost to use the item. #T8 Used for verification #T9 Used for verification #V1 = 0x8011A5D0 SRAM Address #Check health LH T8, 0x0030(V1) #T8 = Current Health SLT T9, T8, T4 #If (Current Health < Health Required) {T9 = 0x1} Else {T9 = 0x0} BNE T9, R0, unusable #Branch to unusable if you do not have enough health NOP #Check Magic LB T8, 0x0033(V1) #T8 = Current Magic SLT T9, T8, T1 #If (Current Magic < Magic Required) {T9 = 0x1} Else {T9 = 0x0} BNE T9, R0, unusable #Branch to unusable if you do not have enough magic NOP SUB T8, T8, T2 #T8 = T8 - T2 (New Magic) BLTZ T8, unusable #Branch to unusable if you do not have enough magic NOP #Check Rupees LH T9, 0x0034(V1) #T9 = Current Rupees SUB T9, T9, T5 #T9 = T9 - T5 (New Rupees) BLTZ T9, unusable #Branch to unusable if you do not have rupees NOP #Update SB T8, 0x0033(V1) #Current Magic = T8 JAL 0x800721CC #Rupee Modifier Function SUB A0, R0, T5 #Rupees to decrease by LI RA, end #Set RA to end so that it can be used at the end of a function. JR AT #Jump Back NOP functions: SLTI T0, A2, 0x45 #Set T0 if A2 is less than 0x45 BNE T0, R0, boots #Branch to boots if action is less than 0x45 NOP SLTI T0, A2, 0x4E #Set T0 if A2 is less than 0x4E BNE T0, R0, refill #Branch to refill if action is less than 0x4E NOP B end #Branch to end if action doesn't exist NOP boots: #Setup Start JALR AT, V0 #Verify that you can use the item ADDIU T2, R0, 0x0002 #Magic Cost: 0x2 #Setup End ADDIU T0, A2, 0xFFBE #T0 = A2 - 0x42 = New Boots LUI T1, 0x801E #Boot Type Address (Upper Bytes) LB A1, 0xAB6F(T1) #A1 = Current Boots BEQL A1, R0, updatespeed #Execute Delay Slot and Branch if you don't have any boots equipped SB T0, 0xAB6F(T1) #Current Boots = T0 SB R0, 0xAB6F(T1) #Current Boots = None updatespeed: LI A1, 0x801DAA30 #Required Argument JAL 0x80079200 #Movement Speed Update Function NOP J end #Function is over, jump to end ADDIU A0, R0, 0x0835 #Set sound to play to Pull out Item refill: #Setup Start JALR AT, V0 #Verify that you can use the item ADDIU T5, R0, 0x0005 #Rupee Cost: 0x5 #Setup End ADDIU T0, A2, 0xFFBC #T0 = A2 - 0x44 = Type (1 to 9) ADDIU A1, R0, 0x0002 #A1 = 0x2 MULTU T0, A1 #LO = T0 * 0x2 MFLO T1 #T1 = LO (Offset used to get upgrade size) LUI A1, 0x8010 #A1 = 0x800F0000 (Capacity Offset Upper Byte) OR A1, A1, T1 #A1 = Capacity Global Offset SLTIU T1, T0, 0x0004 #If T0 < 0x4 Then T1 = 1 Else T1 = 0 BEQL T1, R0, quiver #Branch Likely if T0 isn't below 0x4 SLTIU T1, T0, 0x0007 #If T0 < 0x7 Then T1 = 1 Else T1 = 0 ADDIU A0, R0, 0x0006 #Slingshot J setammo LH A1, 0x8CF4(A1) #A1 = Bullet Bag Capacity Amount quiver: BEQ T1, R0, bombbag #Branch Likely if T0 isn't below 0x7 ADDIU A0, R0, 0x0003 #Bow J setammo LH A1, 0x8CCC(A1) #A1 = Quiver Capacity Amount bombbag: ADDIU A0, R0, 0x0002 #Bomb LH A1, 0x8CD4(A1) #A1 = Bomb Bag Capacity Amount setammo: JAL 0x800721F4 #Jump to set Item Amount NOP J end #Function is over, jump to end ADDIU A0, R0, 0x0835 #Set sound to play to Pull out Item
The ASM Hack above will only create custom actions, we still need to set items to use these specified actions. Which Action each item will use is located at 0x803AA6FC in the RAM. So if you want to set Iron Boots to use Action 0x43 you'd write 0x43 over address 0x803AA6FC + 0x44 (iron boots ID) For the sake of the example actions I provided, here's a code with all the proper actions set: CheatName8=Set Item Action IDs CheatName8Count=11 CheatName8Code0=803AA741 0043 CheatName8Code1=803AA742 0044 CheatName8Code2=803AA743 0045 CheatName8Code3=803AA744 0046 CheatName8Code4=803AA745 0047 CheatName8Code5=803AA746 0048 CheatName8Code6=803AA747 0049 CheatName8Code7=803AA748 004A CheatName8Code8=803AA749 004B CheatName8Code9=803AA74A 004C CheatName8Code10=803AA74B 004D
And here's the item IDs so that you can test them out: Iron Boots 45 Hover Boots 46 Bullet Bag (Holds 30) 47 Bullet Bag (Holds 40) 48 Bullet Bag (Holds 50) 49 Quiver (Holds 30) 4A Quiver (Holds 40) 4B Quiver (Holds 50) 4C Bomb Bag (Holds 20) 4D Bomb Bag (Holds 30) 4E Bomb Bag (Holds 40) 4F
RAM Notes: ASM: 0x80071A28 ADDIU V0, R0, 0x001 #Egg Hatch Start Button Index. Set it to 0 in order to make eggs on B hatchable 0x80079B1C BNEZ T0, 0x80079B2C #Used to determine if get access to silver & gold gauntlet strength. T0 = Age
While NOT Pausing: 0x80395B00 BEQL T6, R0, 0x80395D68 #Used to determine if you can enter a crawlspace. T6 = Age
Data: 0x801DAB72 (Byte) #Item in Hand (Item ID) 0x801DB263 (Byte) #Is Attacking (Setting this to 1 will activate ISG) 0x8011B9B2 (Byte) #Temp B (Stores your B item when on a horse, fishing, shooting gallery, etc.) 0x803A54F0 (Byte) #Pause Temp B (Temp B is moved here while pausing) 0x801DAB70 (Byte) #Last Pressed Item Button (0-3 from B to C-Right) 0x8011B500 (Word) #Sword Flag (1 = Don't have a sword equipped, changes how the game handles B Button) 0x801DAB7F (Byte) #Currently Equipped Mask (goes from 0 to 8)
Functions: 0x800721F4 Modify Item Amount A0 = Item ID A1 = Amount to add
0x80079200 Update Physics This function runs whenever links physics is altered, when changing boots, entering water, exiting water, etc. A1 = 0x801DAA30
0x800646F0 Play Sound Effect The actual function for calling sound effects seem to be located at 0x800C806C but calling it from the address above has proven to be safer for me. A0 = Sound Effect 0x482F Gain Rupee Repeater (This is the sound that repeats while gaining or losing rupees) 0x4803 Gain Rupee (The main sound that plays when gaining a rupee) 0x4806 Disabled Item 0x4807 Success (Played the correct song at a location, etc.) 0x4808 Change Menu Screen 0x4809 Move Menu Cursor 0x480A Emulator Crash 0x480C Enter Z-Target 0x4824 Pick Up Ammo / Magic 0x0835 Pull out Item
0x800721CC Rupee Modifier The amount of rupees to increase/decrease, it'll be added to the current amount of rupees you're currently getting/loosing A0 = Amount
0x8006FB50 Update Item Icon This will update the item icon of the specified item button. (useful when changing a button Item ID directly) A0 = 0x801C84A0 A1 = Button ID (from 0 to 3) 0x8006FDCC Receive Item The game will give you the item specified, and place it in it's correct slot. This will not update items that are equipped. A0 = 0x801C84A0 A1 = Item ID
0x80071B7C Set Item (Using Button Index) This will change an item using a button index as the argument. A0 = 0x801C84A0 A1 = Item ID A2 = Button Index (B-Button, C-Left, C-Down, C-Right from 0 to 3)
Glitch Patches: ISG (Regular method): Set RAM 0x80079718 to 0xA0800833 (Can be injected at all time) This will overwrite a NOP used in a function that is called in numerous situations (changing item, unpausing, putting away ocarina, dialogs, etc.) to unset the Is Attacking flag.
Being able to open chests under water after using hookshot to land at bottom of water: Set RAM 0x803A73B0 to 0x2401FFFF (Do not inject while in the file select, this address is used by other functions at that time) This will make it so that using hookshot/longshot doesn't remove the flag that prevents you from opening chests under water. There may very well be a reason as to why they remove the flag when using hookshot/longshot in the first palce, so I do not know if there's any side-effects of this.
Bottle Dupe & Ocarina Items (Jump Methods): Set RAM 0x8038CA88 to 0xA0E0069D (Do not inject while in a menu, this address is used by other functions at that time) The reason why Bottle Dupe & Ocarina Item work is because there's a flag telling you to use an action when you land. This flag is not cleared when using other items afterwards while still in the air. If you use another item while in the air and land, the game will still want to perform an action, and the result is the ocarina action. If you press on an item that can't be used, the game will simply change the index of the last used button, and as a result you'll empty the bottle over that button index instead when landing. The code I provided will remove the flag mentioned earlier whenever you use an item in midair and it runs the main item action function.
Golden Scale Early: Set RAM 0x80022BE8 to 0x3C010038 The glitch works because of collection delay. When you climb up on a ledge from water with Z-Targeting, there's a flag that i temporarily set while climbing. However, if you exit water on a shore (a perfect transition from water to ground) while Z-Targeting, this flag is not unset after exiting water. This is one of the flags that aren't allowed to be set while collecting an item, causing the game to delay the collection. Now, the programmers of the game really messed up and made it so that when you delay the reward in the fishing pond, the game always store Golden Scale, and not the item you're actually supposed to get. So I simply fixed Golden Scale early by making it so that the flag in question doesn't cause collection delay, you're allowed to pick up items even when it is set.
I've also tried to fix the Pause and Shield Swipe method of Bottle Dupe, but haven't succeeded yet.
|