Welcome, Guest |
You have to register before you can post on our site.
|
Online Users |
There are currently 94 online users. » 0 Member(s) | 91 Guest(s) Bing, Google, Yandex
|
Latest Threads |
Show Ice Cube on Online P...
Forum: Online Non-Item
Last Post: _Ro
1 hour ago
» Replies: 0
» Views: 12
|
CPU Control Cycler [Ro]
Forum: Offline Non-Item
Last Post: _Ro
2 hours ago
» Replies: 7
» Views: 986
|
Thunder Cloud Effect Modi...
Forum: Offline; Item
Last Post: JerryHatrick
10 hours ago
» Replies: 11
» Views: 1,059
|
MKW Coder/Developer of th...
Forum: Coding & Hacking General Discussion
Last Post: Vega
Yesterday, 09:10 PM
» Replies: 10
» Views: 13,813
|
Make it to 10,000
Forum: General Discussion
Last Post: Vega
Yesterday, 08:15 PM
» Replies: 7,338
» Views: 5,669,309
|
Miniturbos and Inside Dri...
Forum: Coding & Hacking General Discussion
Last Post: JerryHatrick
Yesterday, 09:54 AM
» Replies: 1
» Views: 856
|
Code request???
Forum: Code Support / Help / Requests
Last Post: DrTap
01-09-2025, 06:06 PM
» Replies: 3
» Views: 4,949
|
CPUs/Online Players Have ...
Forum: Visual & Sound Effects
Last Post: Zeraora
01-09-2025, 02:26 AM
» Replies: 2
» Views: 501
|
Offline Hide and Seek
Forum: Code Support / Help / Requests
Last Post: FelX
01-08-2025, 03:43 PM
» Replies: 11
» Views: 730
|
Show Nametags During Coun...
Forum: Visual & Sound Effects
Last Post: _Ro
01-08-2025, 07:48 AM
» Replies: 1
» Views: 666
|
|
|
Guide For Calling Functions in ASM Codes |
Posted by: Vega - 01-27-2019, 06:15 PM - Forum: PowerPC Assembly
- Replies (6)
|
|
Guide For Calling Functions in ASM Codes
Chapter 1: Intro / What is a Function?
This guide will teach your how to call (execute) functions for use in Gecko ASM Cheat Codes. This is a hefty tutorial, so please take your time and read thoroughly.
What is a function? A function is a subroutine of code that accepts input(s), processes the inputs to preform a task(s), and returns back with output(s) depending on how the task(s) went. Of course, this is very general. Some functions don't take an input (task preformed is always the same), some functions don't give out an output(s), and some functions don't even return back at all.
To execute a function, you "call" it. This means you have to setup the proper inputs, if necessary, beforehand. Once the inputs have been set, you can call the function. In general, functions are very large and contain complex tasks that should not be "handwritten". The C/C++ library has many built-in functions such as printf, memcpy, memmove, etc. Since every Wii game is mostly coded in C++, these functions will be present in memory.
You can of course write your own functions for custom tasks, but when I speak of functions, it's for the very complex ones that should *not* be handwritten, and are already present in the Wii Game. Regarding Wii Games, they contain 3 different category of functions.
- C/C++ Library (printf, scanf, memcpy, etc etc)
- Wii Library (functions that are specific to the Wii that are found in most games, i.e. ISFS functions for file handling)
- Game Specific Functions (this would be something like an Item Box related function in MKWii)
Video Game Developers use what is called a symbol map as a reference of where all the functions are located in memory. Most Wii games will have their symbol maps scrubbed before being released, meaning there is no file/information in the game that will tell us the names of the functions and where they are located at in memory. Luckily various devs/coders in the MKWii community have worked on a custom symbol map which you can find HERE
Another symbol map that has is very detailed (but only has a small list of commonly used functions), can also be found HERE
Chapter 2: Prologue, Epilogue, and understanding the Linking Mechanism
All functions reside in static memory (mem80 for MKWii). The majority of functions will start with a Prologue. A Prologue is simply a list of instructions that will create some stack space and backup some key registers onto that space.
Template of a Prologue
Code: stwu sp, -0xZZZZ (sp)
mflr r0
stw r0, 0xZZZZ (sp)
stmw/stw rX, 0xZZZZ (sp)
Most prologues appear in this fashion. There are exceptions of course and some prologues may not look exactly like this. Also, some functions may not start with a prologue due to said functions being simple enough to not require backing up registers. Functions that do contain a prologue will always end in an Epilogue.
Template of an Epilogue
Code: lmw/lwz rX, 0xZZZZ (sp)
lwz r0, 0xZZZZ (sp)
mtlr r0
addi sp, sp, 0xZZZZ
blr
Of course there are exceptions, not all epilogues look like this, but most do. Take note of the 'blr' instruction at the very end. All functions end with a 'blr' instruction.
We won't go over all the instructions within the prologue and epilogue (some you should know already ofc) because calling/using functions within an ASM code is different than what you would find in a conventional PPC program/application. We do need to discuss the 'bl' and 'blr' instructions.
Branch & Link
bl label
This is just like a normal branch instruction, except the address of the instruction that's directly below the branch-link instruction is placed in the Link Register.
Example:
Code: bl somewhere
add r3, r4, r5
In the above example, once the bl instruction executes, the CPU will jump to the location of "somewhere", and then the Link Register will be written with the address of the location of the add instruction. Let's say the "bl somewhere" instruction resides in memory at address 0x804200F0. When it gets executed, the address value of 0x804200F4 (where the add instruction resides at) will be placed into the Link Register.
This "linking mechanism" is important to understand because this is how functions can return back from where ever they were called from. As you saw earlier, the Epilogue always ends in the blr instruction
Branch to Link Register:
blr
The blr instruction is just an unconditional branch, but it branches to the Memory Address in the Link Register. It's that simple.
Chapter 3: How to Call a Function in your ASM Codes
Calling functions for use in ASM Codes differs a little bit than how a Wii game or a conventional PPC program does it. First, to call a function, you need to know its memory address (where does the function reside at in Memory). Once you have that address, you need a way to 'jump' to it. Let's go over a basic function that requires zero inputs and does **not** return back to us. This function is __OSShutdownToSBY. It does one job and that is to shut down the Wii. Now to call functions in your ASM Codes, there are two different methods.
1. Use the Link Register (LR) or..
2. Use the Count Register (CTR)
Calling a function via the LR:
Let's look at a snippet of code that will call the __OSShutdownToSBY function. It's important to note that the location of a function within a Wii Game will differ per region (most of the time). The address of __OSShutdownToSBY for PAL MKWIi is 0x801AB960. By the way, this function is a Wii Library function and is present in all Wii Games, not just MKWii.
Code: lis r12, 0x801A #Place address of _OSShutdownToSBY in r12
ori r12, r12, 0xB960
mtlr r12 #Copy address to Link Register
blr #Call it
You should be aware of how the blr instruction operates from reading the previous chapter. Once the blr instruction has executed, you will be sent to address 0x801AB960 and start executing the following ASM instructions that are located there. The instructions within this function will perform all the necessary tasks that is required to force the Wii to shutdown. In real time, the shutdown is instant.
Calling a function via the CTR:
As mentioned earlier, you also have the option to use the Count Register. Here's that same source from above but using the Count Register instead of the Link Register.
Code: lis r12, 0x801A #Place address of _OSShutdownToSBY in r12
ori r12, r12, 0xB960
mtctr r12 #Copy address to Count Register
bctr #Call it
The bctr instruction simply causes the execution of the CPU to jump to the address that's in the Count Register.
Unlike __OSShutdownToSBY, most functions will return back to where they were called from. Therefore, when we call these types of functions, we need to supply the function the proper address to return back to. If not, your code will cause a crash or undefined behavior in the Game will occur.
There are two instructions that you can choose from to make a function return back.,,
- blrl #Branch to Link Register and Link
- bctrl #Branch to Count Register and Link
You can think of blrl as the combination of bl + blr. The blrl instruction will jump to whatever address is currently in the Link Register. Afterwards (this is IMPORTANT), the address of the instruction directly below blrl is placed into the Link Register.
Example:
Pretend that the address's of the blrl and add instructions is 0x80501CC0 and 0x80501CC4 respectively. When the blrl gets executed, the CPU will jump to the address that's currently in the LR. Afterwards, the CPU is executing some function, and the address (value) in the Link Register gets replaced with 0x80501CC4. That way when the function needs to return back, it knows how to come back to us.
Example snippet of source (unfilled function address) using the LR and r12
Code: lis r12, 0xXXXX
ori r12, r12, 0xXXXX
mtlr r12
blrl #Call the function and have it return back once it's done
Example snippet of source (unfilled function address) using the CTR and r12
Code: lis r12, 0xXXXX
ori r12, r12, 0xXXXX
mtctr r12
bctrl #Call the function and have it return back once it's done
Chapter 4: Arguments
You may be wondering at this point, why r12 is shown in the above snippet of sources in Chapter 3. This is because certain functions need 'arguments' (aka inputs) established before being called and certain specific registers must be used for these 'arguments'. If these arguments are not set in the correct registers and/or the registers are filled with invalid values, then the function will fail or cause your game to halt.
Here's the structure of how arguments are set in the registers
Code: r3 = 1st arg
r4 = 2nd arg
r5 = 3rd arg
...
r10 = 8th arg
f1 = 1st arg that's a float value
f2 = 2nd arg
...
f8 = 8th arg
r0, sp (r1), rtoc (r2), and r11 thru r31 are never used for args. FPR's f0, and f9 thru f31 are also never used for float-value args. Most coders prefer to use r12 as the register to place the function's address in the LR/CTR before calling it. That is why r12 was used in the sources shown in Chapter 3.
Let's take a look at the function NETCalcCRC (PAL address 0x801D1CA0). It's a function that is used to generate a 32-bit checksum on a desired block of data. NETCalcCRC requires two integer (non-float) args...
- r3 (1st arg) - Memory Address that points to the start of Data that will be checksummed
- r4 (2nd arg) - Size of the Data (in bytes)
Here's an example of a snippet of source setting up the two args and then calling NETCalcCRC
Code: lis r3, 0x8056
ori r3, r3, 0xEE00 #Let's pretend this is where our data starts at
li r4, 100 #Let's pretend that data is 100 bytes in size
lis r12, 0x801D
ori r12, r12, 0x1CA0 #Place NETCalcCRC (PAL) address in r12
mtlr r12 #Copy r12 to the Link Register
blrl #Call the function via the LR and have it return back to us
Chapter 5: Return Values
Referencing the above snippet of source from Chapter 4, NETCalcCRC will return to us with our 32-bit checksum value. Almost all functions (that are designed to be returned back from) will return a value in r3. A few functions will return values in both r3 and r4, and/or return a value in f1.
Once NETCalcCRC has completed, r3 will now contain the 32-bit checksum value. NETCalcCRC returns 0 in r3 if a checksum could not be generated.
Here's our source from Chapter 4, but it now has new instructions to verify what's in r3.
Code: lis r3, 0x8056
ori r3, r3, 0xEE00 #Let's pretend this is where our data starts at
li r4, 100 #Let's pretend that data is 100 bytes in size
lis r12, 0x801D
ori r12, r12, 0x1CA0 #Place NETCalcCRC (PAL) address in r12
mtlr r12 #Copy r12 to the Link Register
blrl #Call the function via the LR and have it return back to us
cmpwi r3, 0 #Check if r3 is 0
beq- error_occurred #If r0 was zero, the checksum could not be generated, take the branch to a spot in our source that will handle errors
Please note that while NetCalcCRC returns 0 for an error, most functions will return negative values (i.e. 0xFFFFFFFC) for errors.
Chapter 6: Terminology, Caller vs Callee
Now would be a good time to go over some of the nicknames for various registers. You may have come across these names in some of my other tutorials before.
- r0, r3 thru r12, and f0 thru f13 are part of the group that is known as the Volatile Registers.
- r14 thru r31, and f14 thru f31 are part of the group that is known as the Non-Volatile Registers or also known as the Global Variable Registers.
The Volatile Registers are the Caller-Saved Registers. This means that if there is data in them that needs to be preserved/saved, it must be done *before* you call a function.
The Non-Volatile Registers are the Callee-Saved Registers. This means the Callee saves the data of these registers (not all, just the registers that will be utilized) during the Prologue of a function. The Caller can place data in these registers and know the data will be safe throughout a function call. Therefore, once the function call completes and return back, all the data is intact. THIS IS IMPORTANT. More on this in Chapter 8.
Caller? Callee? What the heck does the even mean?
Let's say you have a code and it calls a function. The portion of the code which sets the inputs, calls the function, and process the outputs, is known as the CALLER.
The CALLEE is the instructions within the function itself, which ofc includes the prologue and epilogue.
Keep in mind the Callee can become a new Caller. If a function contains a function within itself, this becomes the case. The function that calls the new function becomes the new Caller. The new function itself is the new Callee.
The Caller is responsible for...
- Setting up any Input Values
- Backing up data in the volatile registers before calling the function
- Calling the function (i.e. blrl/bctrl)
- Processing/Verifying the return values given back from the function
The Callee is responsible for...
- Prologue
- Save the inputs in the non-volatile registers; thus the older values in these registers must be saved before being used by the Callee, this occurs in the prologue
- Epilogue
- Return back to caller (blr; part of the Epilogue)
An alternative name for Caller is Parent. And for Callee is Child.
Chapter 7: Register Safety
Since we are calling functions within an ASM code, and not from a conventional program/application, we can use a modified version of the "Push/Pop the Stack" Method that will give us plenty of registers to freely use without over-complicating things. Here is the modified version~
Code: ##Default instruction could reside here##
stwu sp,-0x80 (sp) #Push stack, make space for 29 registers
stmw r3, 0x8 (sp)
##Contents of your ASM code and your function call(s) will reside here##
lmw r3, 0x8 (sp)
addi sp, sp, 0x80 #Pop stack
##Default instruction could reside here##
As you can see, this will backup registers r3 thru r31 for us, and then retrieve them once our code and function call(s) are complete. Therefore, you are 100% free to use these registers. Now depending on your ASM code, you may need to backup the following...
- r0
- Link Register
- Count Register
Which ones do I backup?
This all depends on your code. At your Code's Address in Dolphin's Code View, take a look at some instructions that are further ahead, if you see any of the 3 registers being used, you will need to back them up. The Count Register rarely needs to be backed up.
Here's a snippet of code to put before pushing the stack if you need to backup the LR and r0...
Code: mr r11, r0 #Copy r0's value to r11
mflr r12 #Copy LR's value to r12
And a snippet of code to put after popping the stack...
Code: mtlr r12 #Restore LR's value
mr r0, r11 #Restore r0's value
Chapter 8: Non-Volatile Registers
Back in Chapter 6, I've mention that the Non-Volatile registers are preserved throughout function calls. Trying to save data to a place like the Exception Vector Area before a function call, and then loading the data back from said Area after a function call may not be necessary. You can throw the data into the non-volatile registers instead.
A good example use for the Non-Volatile Registers is for the ISFS based function calls. The ISFS family of function calls are responsible for reading and/or modifying of files on the Wii's NAND. To open a file you use the ISFS_Open function. It has arguments like most functions do, but what's important here is that ISFS_Open returns what is known as a File Descriptor (fd) as a byte value in r3. You need this File Descriptor value for all other ISFS based functions. All other ISFS based function calls require this fd as part of their arguments. So it would make sense to do something such as...
Code: mr r31, r3 #Backup fd to a Non-Volatile Register
At some point after calling ISFS_Open and before calling any other ISFS based function. Since r31 is a Non-Volatile, it's value will be safe throughout other function calls.
Remember that since you are using the modified "Push/Pop the Stack" Method, you have r14 thru r31 at your disposal to backup data in. Even though the Push/Pop Stack Method backups r3 thru r13 as well, you *CANNOT* use these specific registers as a way to preserve data throughout a function call(s).
Chapter 9: Stepping Thru Functions on Dolphin
Most functions simply have too many instructions for you to step thru when debugging. So to get around this problem you can use Instruction Breakpoints. When stepping through your code, right before your function gets called (via execution of blrl/bctrl), set an Instruction Breakpoint on the instruction that's immediately after the blrl/bctrl. You can set Instruction BPs very quickly by just left clicking on the address of the desired instruction in Code View. A grey dot will appear next to the address indicating an Instruction BP has been set. Like so...
Once that Instruction BP has been set, simply press the play button or Dolphin (or use your Hotkey) to let the emulation play normally. After a split moment, you will then be on the instruction immediately after your blrl/bctrl. You can then take a look at r3 to verify your return value if desired. Also remember to check your arguments before the function was called. Happy coding!
|
|
|
No Invincibility Frames [RoGamer] |
Posted by: Vega - 01-27-2019, 04:15 PM - Forum: Online Non-Item
- No Replies
|
|
No Invincibility Frames [RoGamer]
This code removes the Invincibility Frames, meaning that when you get hit, you won't be invincible while being damaged. While using item hack, you can drop a lot of items at once because the effect of the code.
NTSC-U
04563418 60000000
PAL
04567798 60000000
NTSC-J
04567118 60000000
NTSC-K
045557F0 60000000
Original Value = 2C05FFFF
Code creator: RoGamer
|
|
|
Growing Dropped Star [RoGamer] |
Posted by: Vega - 01-26-2019, 08:00 PM - Forum: Offline; Item
- Replies (1)
|
|
Growing Dropped Star [RoGamer]
This code makes a star that is dropped grow bigger, depending in the value you put. Both the visuals and hitbox are effected. If the value is smaller than original, the star won't change. Changing the value too high might cause lag or problems to see the track.
NTSC-U
049BE968 XXXXXXXX
PAL
049C3160 XXXXXXXX
NTSC-J
049C21C0 XXXXXXXX
NTSC-K
048C0B00 XXXXXXXX
XXXXXXXX = Star Size
Example Value (very large size): 41200000
Original value: 40200000
Code creator: RoGamer
|
|
|
Initial Size of Dropped Star Modifier [RoGamer] |
Posted by: Vega - 01-26-2019, 07:59 PM - Forum: Offline; Item
- Replies (2)
|
|
Initial Size of Dropped Star Modifier [RoGamer]
This code changes the star size when dropped, if the value is smaller than original, the star will spawn with the correct value, if the value is bigger than normal, the star will spawn with the correct value, however, the effect will be permanent. Both the visuals and hitbox are effected.
NTSC-U
049BE964 XXXXXXXX
PAL
049C315C XXXXXXXX
NTSC-J
048C0AFC XXXXXXXX
NTSC-K
048C0AFC XXXXXXXX
XXXXXXXX = Star Size
Example Values
(medium-large): 3FA00000
(large): 40E00000
Original value: 3F800000
Code creator: RoGamer
|
|
|
Crazy Bomb Spin [RoGamer] |
Posted by: Vega - 01-26-2019, 07:57 PM - Forum: Offline; Item
- No Replies
|
|
Crazy Bomb Spin [RoGamer]
This code will make you spin like crazy when you get damaged by a bomb. This code is very simple.
NTSC-U
0488D1B8 C9000000
PAL
04891600 C9000000
NTSC-J
04890C50 C9000000
NTSCK
0487FA08 C9000000
Original Value = 41B00000
Code creator: RoGamer
|
|
|
Always Crushed [RoGamer] |
Posted by: Vega - 01-26-2019, 07:56 PM - Forum: Offline Non-Item
- No Replies
|
|
Always Crushed [RoGamer]
This code will force your character to always be crushed. The player speed will be normal, but the crush-to-normal sound will be there, looping.
A cool effect of this code is that you can use items while being damaged, and drive normally when you are being damaged, similar to Toyota Moving Speed code.
NTSC-U
04597E3C 9703000A
PAL
045A2E74 9703000A
NTSC-J
045A27F4 9703000A
NTSC-K
04590ECC 9703000A
Original Value = 80030008
Code creator: RoGamer
|
|
|
Speed-O-Meter; TTs Only [mdmwii] |
Posted by: Vega - 01-25-2019, 08:20 PM - Forum: Incomplete & Outdated Codes
- No Replies
|
|
Speed-O-Meter; TTs Only [mdmwii]
NOTE: Outdated by Speed-O-Meter code in main codes forum, the one in main forum works everywhere
For Time Trials Mode only. Only works for Solo Racing.
This code will tell you your speed of your vehicle in the milliseconds section of the timer. Only works in TT mode (solo race only). Works for all character/vehicle combos. Reverse speed also works. All speed measurements are rounded to their nearest whole number shown on the timer. This will get rid of the '96/97' issue with Funky Kong/Flame runner (codes that don't fix this issue will show 96 for both Daisy/Mach and Funky/Flame runner at max wheelie speed).
NTSC-U
C25743CB 00000002
3D808000 D00C1660
D01D0020 00000000
0653108C 00000010
3D808000 C00C1660
FC000210 FC00001C
PAL
C257AC2C 00000002
3D808000 D00C1660
D01D0020 00000000
06535BD4 00000010
3D808000 C00C1660
FC000210 FC00001C
NTSC-J
C257A5AC 00000002
3D808000 D00C1660
D01D0020 00000000
06535554 00000010
3D808000 C00C1660
FC000210 FC00001C
NTSC-K
C2568C84 00000002
3D808000 D00C1660
D01D0020 00000000
06523C2C 00000010
3D808000 C00C1660
FC000210 FC00001C
List of Sources:
Source for ASM
lis r12, 0x8000 #Load 0x8000 into upper 16 bits of r12, lower 16 bits are cleared
stfs f0, 0x1660(r12) #Store the float (single precision) to address 0x80001660
stfs f0, 0x0020 (r29) #Default ASM; Store the float (single precision) to address of r29 plus offset 0x0020
Source for Gecko String Write
3D808000 (lis r12, 0x8000) #Load 0x8000 into upper 16 bits of r12, lower 16 bits are cleared
C00C1660 (lfs f0, 0x1660 (r12)) #Load the float (single precision) from 0x80001660 into FPR 0
FC000210 (fabs f0, f0) #The value of FPR 0 is converted to its absolute value, stored back into FPR 0; this resolves the reverse issue
FC00001C (fctiw f0, f0) #The value in FPR 0 is converted to the integer, but it is NOT rounded to zero; this resolves the funky kong 96/97 issue
#After the string write is done, the default instructions ahead will store the float (double precision) to the stack, then load the integer from the lower 32 bits that was in f0 into r5. r5 contains integer value of converted float which will be used to display in the milliseconds#
Code creator: mdmwii
Code credits: Vega (improvements to source, fixed rounding, enabled correct reverse speed output)
|
|
|
TAS Code [Vega] |
Posted by: Vega - 01-22-2019, 10:28 PM - Forum: Incomplete & Outdated Codes
- Replies (5)
|
|
TAS Code [Vega]
This works for ALL controllers!
TAS Code (Tool Assisted Speed Run) is simply the Live Replay code with the ability to activate or deactivate at any time. A good code to have for Dolphin TASers. For more information about Live Replay, visit the Live Replay Code Thread - HERE.
This code has configured the activator and dectivator to be part of the Assembly Code. Thus, this allows the code to also work in Dolphin without any tweaking needed in Dolphin settings/config.
XXXX = Controller Address
ZZZZ = Button To Press to Activate Live Replay
zzzz = Button To Press to Deactivate Live Replay
Go to this thread HERE for a list of XXXX/ZZZZ values.
Important Note: This code makes use of memory address 0x8000164E. Make sure no other codes in your GCT File or Cheat Manager are using that memory address!
NTSC-U
C21AA91C 0000000A
3D808034 618CXXXX
A18C0000 3960ZZZZ
3880zzzz 7D805838
7C005800 41820014
7D802038 7C002000
41820014 4800001C
3D808000 39600001
4800000C 3D808000
39600000 996C164E
7C0802A6 00000000
C251C8BC 00000005
981E0014 3D808000
898C164E 2C0C0001
40A20014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
PAL
C21AA9BC 0000000A
3D808034 618CXXXX
A18C0000 3960ZZZZ
3880zzzz 7D805838
7C005800 41820014
7D802038 7C002000
41820014 4800001C
3D808000 39600001
4800000C 3D808000
39600000 996C164E
7C0802A6 00000000
C2520D30 00000005
981E0014 3D808000
898C164E 2C0C0001
40A20014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
NTSC-J
C21AA8DC 0000000A
3D808034 618CXXXX
A18C0000 3960ZZZZ
3880zzzz 7D805838
7C005800 41820014
7D802038 7C002000
41820014 4800001C
3D808000 39600001
4800000C 3D808000
39600000 996C164E
7C0802A6 00000000
C25206B0 00000005
981E0014 3D808000
898C164E 2C0C0001
40A20014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
NTSC-K
C21AAD18 0000000A
3D808033 618CXXXX
A18C0000 3960ZZZZ
3880zzzz 7D805838
7C005800 41820014
7D802038 7C002000
41820014 4800001C
3D808000 39600001
4800000C 3D808000
39600000 996C164E
7C0802A6 00000000
C250ED54 00000005
981E0014 3D808000
898C164E 2C0C0001
40A20014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
List of Sources:
SOURCE FOR FULL ASM ACTIVATOR/DEACTIVATOR CODE (NTSC-K):
####################
###START ASSEMBLY###
####################
#
##########################
##Set Controller Address##
##########################
lis r12, 0x8033 #Set 1st half address for Korean Controller
ori r12, r12, 0xXXXX #Set 2nd half address (XXXX) for specific Korean Controller
##############################################
##Load Current Halfword of Button(s) Pressed##
##############################################
lhz r12, 0x0 (r12) #Load Halfword from specific Korean Controller Address
########################
##Set User Act & Deact##
########################
li r11, 0xZZZZ #Load Activator value into r11
li r4, 0xzzzz #Load De-Activator value into r4
###########################
##Check if Act is Pressed##
###########################
and r0, r12, r11 #Logically AND the contents of buttons being pressed versus your activator. If activator is at least pressed, r0 will equal 11.
cmpw r0, r11
beq- set_act #If equal (activator pressed), jump to set_act label
#############################
##Check if Deact is Pressed##
#############################
and r0, r12, r4 #Logically AND the contents of buttons being pressed versus your deactivator. If second activator is at least pressed, r0 will equal r4.
cmpw r0, r4
beq- set_deact #If equal (other activator preseed), jump to set_deact label
###########################################
##Jump to End (Act nor Deact were Pressed##
###########################################
b the_end #If ZZZZ nor zzzz wasn't pressed, jump to the_end label
#################
##Set_Act Label##
#################
set_act:
lis r12, 0x8000 #Set first half address for code activation status number
li r11, 1 #Load code activation status number in r11
b store_byte #Jump to store_byte label
###################
##Set_Deact Label##
###################
set_deact:
lis r12, 0x8000 #Set first half address for code deactivation status number
li r11, 0 #Load code deactivation status number in r11
####################
##Store_Byte Label##
####################
store_byte:
stb r11, 0x15F0 (r12) #Store code deactivation status number to mem location 0x800015F0
#################
##The_End Label##
#################
the_end:
mflr r0 #Default ASM
#############################################
##Notes about Using r0 & r4 w/o Restoration##
#############################################
##r0 gets written to later on by a mflr 0, and r4 gets written to after a BL during a rlwinm function##
##Thus, they are safe to use w/o restoring original values##
#
##################
###END ASSEMBLY###
##################
SOURCE FOR TAS CODE:
#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Register Safety NOTES #
# r27 thru r31 safe for use #
# Two steps ahead is a BL instruction #
# After the BL, r27 thru r31 are written to #
# So they are safe for use #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# INPUT FIELDS #
# 1st Input Field - Halfword - Ghost: 0x0004 (r30) You (GCN/WiiMote): -0x364/-0x27E4 (r30) #Halfword at 0x0006 (r30) is never written to #
# 2nd Input Field - Float Single - Ghost: 0x0008 (r30) You (GCN/WiiMote): -0x360/-0x27E0 (r30) #
# 3rd Input Field - Float Single - Ghost: 0x000C (r30) You (GCN/WiiMote): -0x35C/-0x27DC (r30) #
# 4th Input Field - Byte - Ghost: 0x0010 (r30) You (GCN/WiiMote): -0x358/-0x27D8 (r30) #
# 5th Input Field - Byte - Ghost: 0x0011 (r30) You (GCN/WiiMote): -0x357/-0x27D7 (r30) #
# 6th Input Field - Byte - Ghost: 0x0012 (r30) You (GCN/WiiMote): -0x356/-0x27D6 (r30) #
# 7th Input Field - Byte - Ghost: 0x0013 (r30) You (GCN/WiiMote): -0x355/-0x27D5 (r30) #
# 8th Input Field - Byte - Ghost: 0x0014 (r30) You (GCN/WiiMote): -0x354/-0x27D4 (r30) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~#
stb r0, 0x0014 (r30) #Store the byte of r0 to address of r30 plus offset of 0x0014
#~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load Status Byte, & Check #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~#
lis r12, 0x8000 #Load 0x8000 into upper 16 bits of r12, lower 16 bits are cleared
lbz r12, 0x164E (r12) #Load the byte from address 0x8000164E back into r12
cmpwi r12, 0x1 #Compare r12 to the value of 0x1
bne+ de_activate_tas #If r12 is NOT equal to one, we know the activator has not been pressed, jump to de_activate_tas label
#If equal to one, then code will continue proceeding as normal, Live Replay is executed#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Backup Register 30 due to upcoming LWM & STWM instructions #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
mr r12, r30 #Copy value of r30 to r12
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load All Ghost Input Fields #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
lmw r28, 0x4 (r12) #Load consecutive words starting at address of r12 offset 0x4 into r28 thru r31
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store All Ghost Input Fields To Your Own GCN Fields #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
stmw r28, -0x0364 (r12) #Store words of r28 thru r31 to address of r12 offset -0x364 (For GCN Input Field)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store All Ghost Input Fields To Your WiiMote Fields #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
stmw r28, -0x27E4 (r12) #Store words of r28 thru r31 to address of r12 offset -27E4 (For Wii Remote Field)
#~~~~~~~~~~~~~~~~~~~~~~~#
# de_activate_tas Label #
#~~~~~~~~~~~~~~~~~~~~~~~#
de_activate_tas: #Label name set to force navigation to end of code, no label contents needed
#
#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#
Code creator: Vega
Code credits: Megazig (OSSleepThread subroutine); Bully (original Wiimote Live Replay); Mdmwii (original GCN Live Replay)
|
|
|
Live Replay [Vega] |
Posted by: Vega - 01-22-2019, 10:25 PM - Forum: Incomplete & Outdated Codes
- Replies (1)
|
|
Live Replay [Vega]
This works for ALL controllers!
This code will auto-drive your character to exactly mimic all the inputs/movements of a selected ghost. Can be any type of ghost (rival, personal record, staff). This is for Time Trials Mode Only
Select the ghost you want to mimic and start the TT. You will mimic the ghost entirely. Lap Margins will be all zeros. By default this code will preform a 'half-win' celebration at the end...
A 'half-win' celebration will cause you to NOT set a PR, but the time will be placed in the top 5 (2nd place). If you want to have a 'full-win' celebration (have a new PR recorded), then add Diamond's Ghost Always Save Code which is HERE. If you instead want to have a 'lose' celebration, then add Mdmwii's No Ghost Saving Code which is HERE.
If you don't want to see the lap margins, do this..
1. Select the ghost you want to mimic, start the race against the ghost.
2. Allow the race to start, and let yourself mimic the ghost for at least a split second.
3. Pause the game, and go back to course selection.
4. This time, select Solo.
5. You will now auto-drive to the ghost's input but in Solo TT (no more appearance of lap margins).
NTSC-U
C251C8BC 00000003
981E0014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
PAL
C2520D30 00000003
981E0014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
NTSC-J
C25206B0 00000003
981E0014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
NTSC-K
C250ED54 00000003
981E0014 7FCCF378
BB8C0004 BF8CFC9C
BF8CD81C 00000000
Source:
#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Register Safety NOTES #
# r27 thru r31 safe for use #
# Two steps ahead is a BL instruction #
# After the BL, r27 thru r31 are written to #
# So they are safe for use #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# INPUT FIELDS #
# 1st Input Field - Halfword - Ghost: 0x0004 (r30) You (GCN/WiiMote): -0x364/-0x27E4 (r30) #Halfword at 0x0006 (r30) is never written to #
# 2nd Input Field - Float Single - Ghost: 0x0008 (r30) You (GCN/WiiMote): -0x360/-0x27E0 (r30) #
# 3rd Input Field - Float Single - Ghost: 0x000C (r30) You (GCN/WiiMote): -0x35C/-0x27DC (r30) #
# 4th Input Field - Byte - Ghost: 0x0010 (r30) You (GCN/WiiMote): -0x358/-0x27D8 (r30) #
# 5th Input Field - Byte - Ghost: 0x0011 (r30) You (GCN/WiiMote): -0x357/-0x27D7 (r30) #
# 6th Input Field - Byte - Ghost: 0x0012 (r30) You (GCN/WiiMote): -0x356/-0x27D6 (r30) #
# 7th Input Field - Byte - Ghost: 0x0013 (r30) You (GCN/WiiMote): -0x355/-0x27D5 (r30) #
# 8th Input Field - Byte - Ghost: 0x0014 (r30) You (GCN/WiiMote): -0x354/-0x27D4 (r30) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~#
stb r0, 0x0014 (r30) #Store the byte of r0 to address of r30 plus offset of 0x0014
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Backup Register 30 due to upcoming LWM & STWM instructions #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
mr r12, r30 #Copy value of r30 to r12
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load All Ghost Input Fields #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
lmw r28, 0x4 (r12) #Load consecutive words starting at address of r12 offset 0x4 into r28 thru r31
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store All Ghost Input Fields To Your Own GCN Fields #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
stmw r28, -0x0364 (r12) #Store words of r28 thru r31 to address of r12 offset -0x364 (For GCN Input Field)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store All Ghost Input Fields To Your WiiMote Fields #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
stmw r28, -0x27E4 (r12) #Store words of r28 thru r31 to address of r12 offset -27E4 (For Wii Remote Field)
#
#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#
Code creator: Vega
Code credits: Bully (original Wii Remote Live Replay); Mdmwii (original GCN Live Replay)
|
|
|
|