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
And here's a hack I wrote to go along with it (and also fix several "issues" with the inventory)
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.
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:
And here's the item IDs so that you can test them out:
RAM Notes:
Glitch Patches:
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.
Last edited 19 Aug 2013, 09:24 by CloudMax.
