Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 544
» Latest member: CorvoPSY
» Forum threads: 1,664
» Forum posts: 11,957

Full Statistics

Online Users
There are currently 106 online users.
» 0 Member(s) | 101 Guest(s)
Applebot, Bing, Facebook, Google, Yandex

Latest Threads
Make it to 10,000
Forum: General Discussion
Last Post: Cealgair
34 minutes ago
» Replies: 5,692
» Views: 4,198,747
Custom Kart Working on Do...
Forum: Code Support / Help / Requests
Last Post: CorvoPSY
Yesterday, 01:14 PM
» Replies: 1
» Views: 57
Boot into TT cup selectio...
Forum: Misc/Other
Last Post: Vega
04-26-2024, 08:27 PM
» Replies: 3
» Views: 2,888
Request: Custom brsars pe...
Forum: Code Support / Help / Requests
Last Post: lschlick
04-25-2024, 05:45 PM
» Replies: 0
» Views: 41
E-mails not working on th...
Forum: General Discussion
Last Post: Fifty
04-19-2024, 04:56 AM
» Replies: 3
» Views: 273
More missing info from Br...
Forum: Coding & Hacking General Discussion
Last Post: Vega
04-15-2024, 10:04 PM
» Replies: 0
» Views: 197
Request: Custom music vol...
Forum: Code Support / Help / Requests
Last Post: lschlick
04-15-2024, 06:13 PM
» Replies: 0
» Views: 199
Request: Additional sound...
Forum: Code Support / Help / Requests
Last Post: _Ro
04-15-2024, 01:50 AM
» Replies: 6
» Views: 245
Mistake in the Broadway M...
Forum: Coding & Hacking General Discussion
Last Post: Vega
04-14-2024, 11:58 PM
» Replies: 0
» Views: 99
Camera Distance Modifier ...
Forum: Visual & Sound Effects
Last Post: vlonebozo
04-13-2024, 11:05 PM
» Replies: 1
» Views: 6,775

 
  480p Graphics Fix [Leseratte]
Posted by: Leseratte10 - 04-16-2019, 04:10 PM - Forum: Visual & Sound Effects - Replies (1)

480p Graphics Fix [Leseratte]

The user "Extrems" apparently found a bug in the Nintendo SDK that causes 480p graphics to not look as good as they could, and made a patch for libogc (more info: https://shmups.system11.org/viewtopic.ph...8#p1361158 )

I just implemented that patch as a cheat code for Mario Kart Wii, but I don't have a 480p display config ready so I can't test if it works properly. At least it doesn't crash the game. Anyone want to test that cheat code with a 480p config and see if it improves video quality?

EDIT: Apparently the code is only useful on older Wiis, as on newer Wiis and on WiiU Nintendo seems to have fixed their bug in hardware.

NTSC-U
C21BCD3C 00000002
38600003 98610019
60000000 00000000

PAL
C21BCDDC 00000002
38600003 98610019
60000000 00000000

NTSC-J
C21BCCFC 00000002
38600003 98610019
60000000 00000000

NTSC-K
C21BD138 00000002
38600003 98610019
60000000 00000000

Code created by: Leseratte10
Code contributor(s): Extrems (found bug and made libogc patch)

Print this item

  Random Track Selection For Offline [Vega]
Posted by: Vega - 04-14-2019, 02:37 PM - Forum: Offline Non-Item - No Replies

Random Track Selection For Offline [Vega]

Offline only. Does not work in Grand Prix.

This code will give you the ability to have a "random" feature for track selection. Just select any track at the track selection screen. When the Race/TT/Battle begins, it will be a random track that is loaded. For TT's this also effects the loading of the ghost preview screen.

This code makes use of memory addresses 0x8000149E and 0x8000149F. Make sure no other codes in your GCT/Cheat-Manager are using those addresses.

NTSC-U
C0000000 00000009
3D808000 896C149E
280B001F 41A10008
3960001F 396B0001
280B002A 41A00008
39600020 996C149E
896C149F 396B0001
280B0020 41A00008
39600000 996C149F
4E800020 00000000
C2825F74 00000002
3FE08000 8BFF149F
93E31758 00000000
C28529C8 00000002
3F808000 8B9C149E
93861758 00000000

PAL
C0000000 00000009
3D808000 896C149E
280B001F 41A10008
3960001F 396B0001
280B002A 41A00008
39600020 996C149E
896C149F 396B0001
280B0020 41A00008
39600000 996C149F
4E800020 00000000
C28409D4 00000002
3FE08000 8BFF149F
93E31758 00000000
C283D0E8 00000002
3F808000 8B9C149E
93861758 00000000

NTSC-J
C0000000 00000009
3D808000 896C149E
280B001F 41A10008
3960001F 396B0001
280B002A 41A00008
39600020 996C149E
896C149F 396B0001
280B0020 41A00008
39600000 996C149F
4E800020 00000000
C2840040 00000002
3FE08000 8BFF149F
93E31758 00000000
C283C754 00000002
3F808000 8B9C149E
93861758 00000000

NTSC-K
C0000000 00000009
3D808000 896C149E
280B001F 41A10008
3960001F 396B0001
280B002A 41A00008
39600020 996C149E
896C149F 396B0001
280B0020 41A00008
39600000 996C149F
4E800020 00000000
C282ED94 00000002
3FE08000 8BFF149F
93E31758 00000000
C282B4A8 00000002
3F808000 8B9C149E
93861758 00000000



List of Sources-

1st ASM (C0 ASM Track Byte Cycler);

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#  Memory Address & Value Notes  #
# 0x8000149E = Battle Track Byte #
#  0x8000149F = VS Track Byte  #
#  0x00 thru 0x1F = VS Tracks  #
# 0x20 thru 0x29 = Battle Tracks #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                    Register Safety Notes                        #
#        r3 safe for use, gets overwritten next address          #
# r4 safe for use, gets overwritten by default instruction at end #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~#
# Load Battle Track Byte #
#~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8000
lbz r11, 0x149E (r12)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Battle Track Byte 1st Comparsion Check #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmplwi r11, 0x1F
bgt+ _skipinitial #If greater than 0x1F, the battle cycle has already started

li r11, 0x1F #If not greater than 0x1F, begin the start of byte cycle, set value to 0x1F since the next instruction adds 1 to itself, value 0x20 is lowest byte value out of the battle tracks

_skipinitial:
addi r11, r11, 1 #Increment the Battle Byte by 1

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#  Battle Track Byte 2nd Comparison Check  #
# If 0x2A, reset the cycle back down to 0x20 #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmplwi r11, 0x2A
blt+ _dontreset1

li r11, 0x20

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store Updated Battle Byte to Exception Vector Area #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

_dontreset1:
stb r11, 0x149E (r12)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load VS Track Byte, Increment It #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lbz r11, 0x149F (r12)
addi r11, r11, 1

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#  Compare VS Track Byte to 0x20 (first battle track)  #
#                If 0x20, reset the cycle              #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmplwi r11, 0x20
blt+ _dontreset2

li r11, 0

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store Updated Track Byte, Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

_dontreset2:
stb r11, 0x149F (r12)

#blr Uncomment if compiling with WiiRDGUI, adjust compiled code accordingly

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

====

2nd ASM (Load updated VS Track Byte to replace selected Track):

lis r31, 0x8000
lbz r31, 0x149F (r31) #Load Track Byte
stw r31, 0x1758 (r3) #Default Instruction, Store Track Word Value to Memory

====

3rd ASM (Load updated Battle Track Byte to replaced selected Track):

lis r28, 0x8000
lbz r28, 0x149E (r28) #Load Track Byte
stw r28, 0x1758 (r6) #Default Instruction, Store Track Word Value to Memory



Code creator: Vega

Print this item

  List of Certain Functions with Arguments Plus Descriptions
Posted by: Vega - 04-05-2019, 06:23 PM - Forum: Coding & Hacking General Discussion - No Replies

List of Certain Functions with Arguments Plus Descriptions

This is a list of functions I have used in codes I have made or attempted to have made. Arguments, descriptions, and return values are provided. If you are wanting to view a list of many many more functions (not as detailed as this), view this thread HERE. There's no need to have essentially two symbol map type threads in the Resources sub-forum, hence why this thread is in Hacking General sub-forum.




ISFS Specific Return Values (r3)

For any function that has the term ISFS in it, they all have the same return value numbering. Here's a list of those values (shown in decimal form):
-1 = Permission Denied
-2 = File/Directory already exists
-4 = Invalid Register Argument
-6 = File/Directory not found
-8 = Resource busy
-12 = ECC error
-22 = Could not allocate Memory
-101 = Invalid Register Argument
-102 = Permission Denied
-105 = File/Directory already exists
-106 = File/Directory not found
-107 = Too many fds open
-108 = Memory is full
-109 = Too many fds open
-110 = Pathname is too long
-111 = fd already open
-114 = ECC error
-115 = Directory not empty
-116 = Max directory depth exceeded
-118 = Resource busy
-119 = Fatal error




Function: memcpy

Summary: Copies Data from a spot in Memory to another spot; useful for very large amounts of data

Address (region-free):
0x80005F34

Arguments:
r3 = Destination Start Address
r4 = Source Start Address
r5 = Amount of Bytes to Copy Over

Return Value:
r3 = Remains the same

~~~

Function: sprintf

Summary: Formats a String (C/C++ style) and stores string to desired memory location

Addresses:
NTSC-U 0x80010ECC
PAL = 0x80011A2C
NTSC-J = 0x80011950
NTSC-K = 0x80011A94

Arguments:
r3 = Address Pointer where Formatted String ASCii-Hex will be written to
r4 = Address Pointer where non-formatted ASCii-Hex String is located, must end in NULL
r5 thru r10 = Non-Float Values to be formatted
f1 thru f8 = Float Values to be formatted

NOTE: You must use single precision (lfs instruction) if loading floats from memory into FPRs

More NOTES:
If using Float Values ,then this instruction must be required after the lfs (before the function call) - crset 6 (same as creqv 6, 6, 6)

If NOT using Float values, its recommended (not needed) to use this instruction right before the function call - crclr 6 (same as crxor 6, 6, 6); This tells the sprintf function not to backup Floats to the stack since no Floats are used.

Here is a handy page for printf formats - https://alvinalexander.com/programming/p...eat-sheet/

Return Value (r3):
Value matching amount of bytes written to r3 (does not include the auto appended null byte at end) = Success
Any negative value = Error

~~~

Function: sscanf

Summary: Reads data from a Formatted C/C++ String.

Addresses:
NTSC-U too lazy to port lol
PAL = 0x80013040
NTSC-J = too lazy to port lol
NTSC-K = too lazy to port lol

Arguments:
r3 = Address Pointer where Formatted String ASCii-Hex is located at, must end in NULL
r4 = Address Pointer where non-formatted ASCii-Hex String is located, must end in NULL
r5 thru r10 varies depending on how many formatted values you need to read from the Formatted String (i.e. % items)
r5 thru r10 are pointer to where the dump the read data

Example:
r3 = Pointer to memory where the following string is at - "Bob is 25 years old"

For reading the "25" part of the string, set r4 pointer to point to this string "Bob is %d years old"

r5 will then need to be a pointer to dump the "25" to. %d is used because 25 is in decimal form. Let's say r5 is 0x80001500. After sscanf is called, at 0x80001500 will be the word value 0x00000019 (25 in decimal).

Haven't personally tested, but float values (i.e. %3.1f) should not use pointers. They should get placed directly into the FPRs, starting at f1.

NOTE: You must use single precision (lfs instruction) if loading floats from memory into FPRs

More NOTES:
If using Float Values ,then this instruction must be required after the lfs (before the function call) - crset 6 (same as creqv 6, 6, 6)

If NOT using Float values, its recommended (not needed) to use this instruction right before the function call - crclr 6 (same as crxor 6, 6, 6); This tells the sprintf function not to backup Floats to the stack since no Floats are used.

Here is a handy page for printf formats - https://alvinalexander.com/programming/p...eat-sheet/

Return Value (r3):
Items of Data that were successfully read = r3
If r3 = 0, no reading/conversions were done. If r3 is a negative value then r3 or r4 args were incorrect.

~~~

Function: swprintf

Summary: Formats a String (C/C++ style) using 16-bit ASCII (instead of 8 bit) and stores string to desired memory location

Addresses:
NTSC-U 0x80016CB4
PAL = 0x80017814
NTSC-J = 0x80017738
NTSC-K = 0x8001787C

Arguments:
r3 = Address Pointer where wide Formatted String will be written to
r4 = Number of characters to fill in the formatted string that will be written to r3's address, note its pretty hard to calculate this, thus you can just put this as a crazy high number because the function itself will autocap to the max of the formatted string. Thank you Seeky!
r5 = Address Pointer where non-formatted String is located, must end in NULL
r6 thru r10 = Integer Values to be formatted
f1 thru f8 = Float Values to be formatted

NOTE: You must use single precision (lfs instruction) if loading floats from memory into FPRs

More NOTES:
If using Float Values ,then this instruction must be required after the lfs (before the function call) - crset 6 (same as creqv 6, 6, 6)

If NOT using Float values, its recommended (not needed) to use this instruction right before the function call - crclr 6 (same as crxor 6, 6, 6); This tells the swprintf function not to backup Floats to the stack since no Floats are used.

Here is a handy page for printf formats - https://alvinalexander.com/programming/p...eat-sheet/

Return Value (r3):
Positive Value = Success; amount of halfwords written
-1 = Error; r4's value was too low. Formatted string will still be there but the function is letting you know its incomplete

~~~

Function: DirectPrint: SetupFB

Summary: Sets up a Frame Buffer to allow later use of DirectPrint: Printf & DirectPrint: StoreCache

Addresses:
NTSC-U 0x800223E0
PAL 0x80022480
NTSC-J 0x800223A0
NTSC-K 0x800224E0

Arguments:
For r3, 2 instructions must bed used to get the Render Mode of mpVideo from RKSystem, the first instruction slightly differ per region:

NTSC-U = lwz r3, -0x5CA8 (r13)
PAL = lwz r3, -0x5CA0 (r13)
NTSC-J = lwz r3, -0x5CA0 (r13)
NTSC-K = lwz r3, -0x5C80 (r13)

Then execute the 2nd instruction (region-free): lwz r3, 0x0 (r3) 

r3 now contains the RenderMode

Return Value (r3):
Any negative value = Error

~~~

Function: DirectPrint: Printf w/ DirectPrint: StoreCache

Summary: Both functions should be executed back-to-back hence why they are coupled together. These functions will preform a printf-style function that draws on the TV Screen; DirectPrint: SetupFB must already have been called beforehand

Addresses (Printf first, StoreCache second)

NTSC-U = 0x80021DF0, 0x80021DD0
PAL = 0x80021E90, 0x80021E70
NTSC-J = 0x80021DB0, 0x80021D90
NTSC-K = 0x80021EF0, 0x80021ED0

Arguments (for Printf only, StoreCache has no arguments):
r3 = X Coordinate (Starts Far Left)
r4 = Y Coordinate (Starts Very Top)
r5 = 0 for No Text Wrap, 1 for Text Wrap (Wrapping allows the text to enter into a new line if it reaches the edge of the screen)
r6 = Address Pointer to ASCii-Hex String that will be Drawn on Screen
r7 thru r10 = Standard printf format non-float arguments
f1 thru f13 = Standard printf format float arguments

NOTE: You must use single precision (lfs instruction) if loading floats from memory into FPRs
Another NOTE: If using Float Values ,then this instruction must be required after the lfs (before the function call) - crset 4*cr1+eq

Google printf Format for a list of format characters/symbols for use in the ASCii-Hex String.

Return Value (r3):
Any negative value = Error

~~~

Function: ISFS_CreateDir

Summary: Creates a new directory on the NAND

Addresses:
NTSC-U = 80169DD4
PAL = 0x80169E74
NTSC-J = 0x80169D94
NTSC-K = 0x80169F10

Arguments:
r3 = Address that points to the File Path w/ new Directory that will be created
r4 = 0x0 (u8 attributes)
r5 = 0x3 (owner permissions)
r6 = 0x3 (group permissions)
r7 - 0x3 (other permissions)

Return Value (r3):
0 = Success
View ISFS List at top for negative values

##SPECIAL NOTE ABOUT ISFS_CreateDir & DOLPHIN##
Return value -105 will never occur on Dolphin for a Directory that already exists. It will instead return 0.

~~~

Function: ISFS_Delete

Summary: Delete a file or directory (recursively) from the NAND.

Addresses:
NTSC-U = 0x8016A6EC
PAL = 0x8016A78C
NTSC-J = 0x8016A6AC
NTSC-K = 0x8016A828

Arguments:
r3 = Address that points to file path

Return Value (r3):
0 = Success
View ISFS List at top for negative values

~~~

Function: ISFS_CreateFile

Summary: Creates a new file on the NAND, must use a pre-existing directory

Addresses:
NTSC-U = 0x8016ABD4
PAL = 0x8016AC74
NTSC-J = 0x8016AB94
NTSC-K = 0x8016AD10

Arguments:
r3 = Address that points to the File Path w/ new File that will be created
r4 = 0x0 (u8 attributes)
r5 = 0x3 (owner permissions)
r6 = 0x3 (group permissions)
r7 = 0x3 (other permissions)

Return Value (r3):
0 = Success
View ISFS List at top for negative values

~~~

Function: ISFS_Open

Summary: Opens a pre-existing file on the NAND to allow you to later read from it or write to it

Addresses:
NTSC-U = 0x8016ADBC
PAL = 0x8016AE5C
NTSC-J = 0x8016AD7C
NTSC-K = 0x8016AEF8

Arguments:
r3 = Address that points to the File Path
r4 = Permissions (Use 0x1 for Read, or 0x2 for Write)

Return Values (r3):
Success = File Descriptor Value Returned
View ISFS List at top for negative values

~~~

Function: ISFS_GetFileStats

Summary: Gets the file's size (in bytes). Can be useful before calling ISFS_Read if the file size is unknown.

Addresses:
NTSC-U = 0x8016AF3C
PAL = 0x8016AFDC
NTSC-J = 0x8016AEFC
NTSC-K = 0x8016B078

Arguments:
r3 = File Descriptor (value that was returned from ISFS_Open)
r4 = Memory Address to dump file size value (word) to. Address must be 32 byte aligned aka is address divisible by 0x20?)

Return Value (r3):
0 = Success
View ISFS List at top for negative values

~~~

Function: ISFS_Seek

Summary: Only recommended for reading/writing in a particular region of a very large file when not reading/writing at the very beginning of said file. Use after Open, before Read/Write.

Addresses:
NTSC-U = 0x8016B0CC
PAL = 0x8016B16C
NTSC-J = 0x8016B08C
NTSC-K = 0x8016B208

Arguments:
r3 = File Descriptor (value that was returned from ISFS_Open)
r4 = Offset from Location Mode aka where
r5 = Location Mode aka whence; 0x0 for Start of File, 0x1 = Current Spot of File, 0x2 = End of File

Return Value (r3):
0 = Success
View ISFS List at top for negative values

~~~

Function: ISFS_Read

Summary: Read a file on the NAND to dump it's contents to a spot in Memory

Addresses:
NTSC-U = 0x8016B15C
PAL = 0x8016B1FC
NTSC-J = 0x8016B11C
NTSC-K = 0x8016B298

Arguments:
r3 = File Descriptor (value that was returned from ISFS_Open)
r4 = Address that points where the File's data will be dumped to (must be 32 byte aligned aka is address divisible by 0x20?)
r5 = Amount of Bytes of Data to dump from the File

Return Value (r3):
If r3 value's equals r5, then Success.
View ISFS List at top for negative values

~~~

Function: ISFS_Write

Summary: Write to a file on the NAND.

Addresses:
NTSC-U = 0x8016B220
PAL = 0x8016B2C0
NTSC-J = 0x8016B1E0
NTSC-K = 0x8016B35C

Arguments:
r3 = File Descriptor (value that was returned from ISFSOpen)
r4 = Address that points to the string of data that will be used to write to the File (must be 32 byte aligned aka is address divisible by 0x20?)
r5 = Amount of Bytes of Data to write from the string

Return Value (r3):
If r3 value's equals r5, then Success.
View ISFS List at top for negative values

~~~

Function: ISFS_Close

Summary: Close a file after reading from it or writing to it. This function must be done after the read/write.

Addresses:
NTSC-U = 0x8016B2E4
PAL = 0x8016B384
NTSC-J = 0x8016B2A4
NTSC-K = 0x8016B420

Arguments:
r3 = File Descriptor (value that was returned from ISFS_Open)

Return Value (r3):
0 = Success
View ISFS List at top for negative values

~~~

Function: OSFatal

Summary: Stops the game and displays a desired message on the TV screen. BG color, FG color, and text are all modifiable.

Addresses:
NTSC-U = 0x801A4E24
PAL = 0x801A4EC4
NTSC-J = 0x801A4DE4
NTSC-K = 0x801A5220

Arguments:
r3 = Address Pointer to Foreground (text) color
r4 = Address Pointer to Background color
r5 = Address Pointer to String of ASCII Text

Extra Notes:
Color = RRGGBBFF
RR = Red Value, GG = Green Value, BB = Blue Value

Return Value (r3): None ofc...

~~~

Function: OSShutdownSystem

Summary: Standard shutdown of the Wii.

Addresses:
NTSC-U = 0x801A84CC
PAL = 0x801A856C
NTSC-J = 0x801A848C
NTSC-K = 0x801A88C8

Arguments: None

Return Value (r3): None ofc...

~~~

Function: OSRestart

Summary: Reboots the game.

Addresses:
NTSC-U = 0x801A85E8
PAL = 0x801A8688
NTSC-J = 0x801A85A8
NTSC-K = 0x801A89E4

Arguments: None

Return Value (r3): None ofc...

~~~

Function: OSReturnToMenu

Summary: Returns you to the Wii Menu.

Addresses:
NTSC-U = 0x801A87B8
PAL = 0x801A8858
NTSC-J = 0x801A8778
NTSC-K = 0x801A8BB4

Arguments: None

Return Value (r3): None ofc...

~~~

Function: OSGetTime

Summary: Returns a 64 bit Time value base, that you can use later with the function OSTicksToCalendarTime to grab the data&time from the Wii's CPU.

Addresses:
NTSC-U = 0x801AACBC
PAL = 0x801AAD5C
NTSC-J = 0x801AAC7C
NTSC-K = 0x801AB0B8

Arguments: None

Return Values (r3, r4):
r3 = Upper 32 bits of Time Base
r4 = Lower 32 bits of Time Base

~~~

Function: OSTicksToCalendarTime

Summary: After you have executed the OSGetTime function, immediately execute this function to get the date&time.

Arguments:
r3 = Upper Time Base
r4 = Lower Time Base
r5 = Memory Address to Dump Date/Time to (have at least 0x28 space allocated to dump to)

Dumping Locations (all dumped as logical words):
r5 = Seconds
r5+4 = Minutes
r5+8 = Hours
r5+C = Day of Month
r5+10 = Month (read notes below)
r5+14 = Year (read notes below)
r5+18 = Day of Week (read notes below)
r5+1C = Day of Year (read notes below)
r5+20 = Milliseconds
r5+24 = Microseconds

Notes:
For the month, January starts off as 0.
For day of week, Sunday starts off as 0.
For day of year, Jan 1st starts off as 0.

For the year, if you want just the last two digits (2019/0x7E3 -> 19/0x13) use this equation..
Assume Year is placed into r5...
li    r6, 100
divw  r7, r5, r6
mullw  r6, r7, r6
subf  r5, r6, r5

r5 now equals last two digits of Year

Return value (r3): If any negative number, then error.

~~~

Function: _OSShutdownToSBY

Summary: Shuts down the Wii to 'Red' light mode (completely off) even if your Wii is configured to shut down to 'Yellow' light mode

Addresses:
NTSC-U = 0x801AB8C0
PAL = 0x801AB960
NTSC-J = 0x801AB880
NTSC-K = 0x801ABCBC

Arguments: None

Return Value (r3): None ofc...

~~~

Function: _OSHotReset

Summary: Reboots the Wii

Addresses:
NTSC-U = 0x801AB938
PAL = 0x801AB9D8
NTSC-J = 0x801AB8F8
NTSC-K = 0x801ABD34

Arguments: None

Return Value (r3): None ofc...

~~~

Function: _OSLaunchTitle

Summary: Launches desired Wii Channel

NOTE: It CAN load the Homebrew Channel, but CANNOT load the Region Select Channel.

Addresses:
NTSC-U = 0x801AD960
PAL = 0x801ADA00
NTSC-J = 0x801AD920
NTSC-K = 0x801ADD5C

Arguments:
r3 = Upper 32 Bits of Title ID (ASCii-Hex)
r4 = Lower 32 Bits of Title ID

Return Value (r3): None ofc...

~~~

Function: OSLaunchTitleI

Summary: Launches desired Wii Channel

NOTE: Cannot load Homebrew Channel

Addresses:
NTSC-U = 0x801ADEC0
PAL = 0x801ADF60
NTSC-J = 0x801ADE80
NTSC-K = 0x801AE2BC

Arguments:
r3 = Upper 32 Bits of Title ID (ASCii-Hex)
r4 = Lower 32 Bits of Title ID
r5 = 0x03010000
r6 = 0

Return Value (r3): None ofc...

~~~

Function: SCGetSimpleAddr

Summary: This will dump your Country Code, Region Residence Code, and Globe location from SYSCONF to a desired address. You will need at least 0x1008 blocks/bytes of free space.

Addresses:
NTSC-U = 0x801B1FD4
PAL = 0x801B2074
NTSC-J = 0x801B1F94
NTSC-K = 0x801B23D0

Arguments:
r3 = Address Where Country Code byte will be stored to (must be 32 bit aligned)
r3 + 0x1 = Address Where Region Residence byte will be stored to
r3 + 0x1004 = Address Where Globe Location word will be stored to

Return Value (r3):
If r3 = 1, then success. If not, then unable to get Simple Address Data from SYSCONF.

~~~

Function: SCGetProductArea

Summary. This will dump your Console Area (3 Byte Capitalized ASCII) to a speicific address in Memory.

Addresses:
NTSC-U = 0x801B2300
PAL = 0x801B23A0
NTSC-J = 0x801B22C0
NTSC-K = 0x801B26FC

Arguments:
r3 = Address to Dump Console Area too

Return Value (r3):
If r3 = 1, then success. If not, then unable to get Product Area from setting.txt.

~~~

Function: SCGetProductCode

Summary: This will dump the product code at a specific address in Static Memory. Once the product code is dumped, it will stay there until the Game is turned off

Addresses:
NTSC-U = 0x801B2384
PAL = 0x801B2424
NTSC-J = 0x801B2344
NTSC-K = 0x801B2780

Arguments: None

Return Value (r3):
If r3 = 1, then success. If not, then unable to get Product Code from setting.txt.

~~~

Function: SCGetProductSN

Summary: This will dump the Serial Number at a specific address in Dynamic Memory. It will only be there during the DWC process of connecting to Wifi, then it will be cleared.
Addresses:
NTSC-U = 0x801B23C0
PAL = 0x801B2460
NTSC-J = 0x801B2380
NTSC-K = 0x801B27BC

Arguments: None

Return Value (r3):
If r3 = 1, then success. If not, then unable to get SN from setting.txt.

~~~

Function: NCDiGetWirelessMacAddress

Summary: This will dump your MAC Address at a speicific address in Dynamic Memory. It will only be there during the DWC process of connecting to Wifi, then it will be cleared. However, you can change the first argument (r3) to dump it to a different spot if needed and not have it cleared.

Addresses:
NTSC-U = 0x801D0CD0
PAL = 0x801D0D70
NTSC-J = 0x801D0C90
NTSC-K = 0x801D10CC

Arguments: r3 = Address to dump MAC to

Return Value (r3):
If r3 = 0, then success. If not, then error attempting to get MAC from dev/fs.

~~~

Function: NETCalcCRC32

Summary: Calculates a CRC32-bit checksum. This function is required if you are wanting to make a code to modify MKWii's data save file (rksys.dat)

Addresses:
NTSC-U = 0x801D1C00
PAL = 0x801D1CA0
NTSC-J = 0x801D1BC0
NTSC-K = 0x801D1FFC

Arguments (r3, r4):
r3 = Address Pointer to start of Contents in Memory to be used for the CRC32 Calculation
r4 = Amount of Bytes to be used for the CRC32 Calculation

Return Value (r3):
r3 = CRC32-bit checksum calculated from contents (word)

~~~

Function: EGG::Heap::alloc

Summary: Creates a block of empty memory for available use.

Addresses:
NTSC-U = 0x80229490
PAL = 0x80229814
NTSC-J = 0x80229734
NTSC-K = 0x80229B88

Arguments (r3, r4, r5):
r3 = Size of Memory Block in Bytes
r4 = Alignment of Memory Block (if not sure, use 0x20 for 32 bit alignment)

For r5, 2 instructions must be preformed. The first instruction (get pointer from System Heap) will vary per region...
NTSC-U = lwz r5, -0x5CA8 (r13)
PAL = lwz r5, -0x5CA0 (r13)
NTSC-J = lwz r5, -0x5CA0 (r13)
NTSC-K = lwz r5, -0x5C80 (r13)

Second instruction for r5: lwz r5, 0x0024 (r5)

r5 thus has the Heap to allocate memory block in

Return Value (r3):
r3 = Pointer to Beginning of new Heap to use

~~~

Function: EGG::Heap::free

Summary: Free the block of memory that was created from EGG::Heap::alloc

Addresses (r3, r4):
NTSC-U = 0x80229800
PAL = 0x80229B84
NTSC-J = 0x80229AA4
NTSC-K = 0x80229EF8

Arguments:
r3 = Return value from EGG::Heap::alloc (Pointer to Beginning of Heap)

For r4, 2 instructions must be preformed. The first instruction (get pointer from System Heap) will vary per region...
NTSC-U = lwz r4, -0x5CA8 (r13)
PAL = lwz r4, -0x5CA0 (r13)
NTSC-J = lwz r4, -0x5CA0 (r13)
NTSC-K = lwz r4, -0x5C80 (r13)

Second instruction for r4: lwz r4, 0x24 (r4)

Return Value (r3):
If r3 = 1, then Success. Heap is freed. If not, then some sort of error occured.

~~~

Credits:
Megazig
RiiDefi
Bushing
Star

Print this item

  Graphical In-Game Item Spy Online [Vega]
Posted by: Vega - 03-31-2019, 09:12 PM - Forum: Online; Item - No Replies

Graphical In-Game Item Spy Online [Vega]

NOTE: It's recommended to also include this code to eliminate frame flickers -> https://mkwii.com/showthread.php?tid=1530

Works Online only.

This code will place a graphical image on the bottom on your screen. The screen will contain the held items (in inventory) of every player in the race. The listing of the items will be ordered by the player slot number. The items presented will be shown in their hex value...

Hex Item Image Values:
00 - Green Shell / No Player on Slot
01 - Red Shell
02 - Banana
03 - Fib
04 - Shroom
05 - Triple Shrooms
06 - Bomb
07 - Blue Shell
08 - Shock
09 - Star
0A - Golden
0B - Mega
0C - Blooper
0D - Pow
0E - TC
0F - Bill
10 - Triple Greens
11 - Triple Reds
12 - Triple Nanas
14 - No Item / No Item Available

NOTE: This code makes use of the following memory addresses...
0x80001500 thru 0x80001518
0x81660000 thru 0x8166002F
0x81670000 thru 0x81670003

Make sure no other codes in your GCT/Cheat-Manager are using those addresses.

NTSC-U
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009640 0000001D
3D808167 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08166
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C0ECC
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C0ECC
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1DF0
7D8803A6 4E800021
61CC1DD0 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C265EE14 00000003
88030001 1D960004
3D8C8166 900C0000
60000000 00000000
C265EE30 00000004
88100011 1D960004
3D8C8166 900C0000
3D608167 920B0000
60000000 00000000

PAL
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009680 0000001D
3D808167 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08166
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C1A2C
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C1A2C
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1E90
7D8803A6 4E800021
61CC1E70 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C265E18C 00000003
88030001 1D960004
3D8C8166 900C0000
60000000 00000000
C265E1A8 00000004
88100011 1D960004
3D8C8166 900C0000
3D608167 920B0000
60000000 00000000

NTSC-J
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C20095DC 0000001D
3D808167 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08166
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C1950
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C1950
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1DB0
7D8803A6 4E800021
61CC1D90 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C265D7F8 00000003
88030001 1D960004
3D8C8166 900C0000
60000000 00000000
C265D814 00000004
88100011 1D960004
3D8C8166 900C0000
3D608167 920B0000
60000000 00000000

NTSC-K
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009788 0000001D
3D808167 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08166
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C1A94
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C1A94
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1EF0
7D8803A6 4E800021
61CC1ED0 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C264C4A4 00000003
88030001 1D960004
3D8C8166 900C0000
60000000 00000000
C264C4C0 00000004
88100011 1D960004
3D8C8166 900C0000
3D608167 920B0000
60000000 00000000



List of Sources:
1st ASM (When Game loads StaticR.rel, Get Render Mode & Call Direct Print Setup Frame Buffer)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#         r3 = Render Mode           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

2nd ASM Source:

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                  Memory Address Notes:                  #
# 0x80001500 thru 0x80001512 - Formatted 1st Half of String #
# 0x80001512 - Null Byte appended from 1st Call of Sprintf  #
# 0x80001512 thru 0x80001517 - Formatted 2nd Half of String #
# 0x80001518 - Null Byte appneded from 2nd Call of Sprintf  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro call_nw4r address
ori r12, r14, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE

.set sprintf, 0x80010ECC
.set nw4r_db_DirectPrint_Printf, 0x1DF0
.set nw4r_db_DirectPrint_StoreCache, 0x1DD0

.elseif (region == 'P' || region == 'p') # RMCP

.set sprintf, 0x80011A2C
.set nw4r_db_DirectPrint_Printf, 0x1E90
.set nw4r_db_DirectPrint_StoreCache, 0x1E70

.elseif (region == 'J' || region == 'j') # RMCJ

.set sprintf, 0x80011950
.set nw4r_db_DirectPrint_Printf, 0x1DB0
.set nw4r_db_DirectPrint_StoreCache, 0x1D90

.elseif (region == 'K' || region == 'k') # RMCK

.set sprintf, 0x80011A94
.set nw4r_db_DirectPrint_Printf, 0x1EF0
.set nw4r_db_DirectPrint_StoreCache, 0x1ED0

.else # Invalid Region
.err
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Check to See if a Race is Active:      #
#        Load Status Word from Mem 81          #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8167
lwz r12, 0x0 (r12)
cmpwi r12, 0x0
beq- dont_execute

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                      Sprintf #1                      #
#    r3 = Address Pointer to Dump Formatted String    #
# r4 = Address Pointer to String that needs Formatting #
#        r5 thru r10 = Non Float Format Args          #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

bl printf_string

.llong 0x2530325820253032 #1st String for 1st Sprintf - "%02X %02X %02X %02X %02X %02X "
.llong 0x5820253032582025
.llong 0x3032582025303258
.llong 0x2025303258200000

printf_string:
mflr r4
li r5, 0x20
stb r5, 0x1D (r4) #This is needed because the final 0x20 gets nulled out for second sprintf, so we always need to 'recover' it before first sprintf

mr r29, r4 #Backup String Address Pointer to r29

lis r30, 0x8166
lswi r5, r30, 24 #Load the first 6 slot Item Words into r5 - r10

lis r3, 0x8000 #Set Address to Dump String To
ori r3, r3, 0x1500
addi r31, r3, 0x0012 #First Formatted String Ends at 0x80001512 (null), so add 0x18 to r3 for start of 2nd string on 2nd call of sprintf. Put result in r31 for global variable storage thru function calls

call_link sprintf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Check Sprintf #1 Return Value #
#  If negative, error occured  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmpwi r3, 0x0
blt- _error

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                      Sprintf #2                      #
#    r3 = Address Pointer to Dump Formatted String    #
# r4 = Address Pointer to String that needs Formatting #
#        r5 thru r10 = Non Float Format Args          #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

mr r4, r29 #Move backed up string address pointer to r4
li r5, 0x0
stb r5, 0x1D (r4) #The space in the ASCII string near the end is not needed, null it out, string is now ready for 2nd call of sprintf

mr r3, r31 #2nd String will be dumped to exactly where null byte of 1st string of ended at
addi r30, r30, 0x18 #Add 0x18 to r30, now address points to beginning of second half of the 12 player item slot listing
lswi r5, r30, 24 #Load slot's 7 - 12 Item Words into r5 - r10

call_link sprintf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Check Sprintf #2 Return Value #
#  If negative, error occured  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmpwi r3, 0x0
blt- _error

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache              #
#                  Purpose: Draw on Screen                  #
#            r3 = X coordinate (starts far left)            #
#            r4 = Y coordinate (starts at very top)          #
#                  r5 = 0 No Wrap; 1 Wrap                    #
# r6 = Address Pointer to String that will be Drawn on Screen #
#              r7 thru r10 printf format args                #
#          f1 thru f13 printf float format args              #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x30
li r4, 0xDA
li r5, 0x1
addi r6, r31, -0x12 #Make r6 have 0x80001500, beginning of entire formatted string

lis r14, 0x8002 #For nw4r macro

call_nw4r nw4r_db_DirectPrint_Printf
call_nw4r nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety #
#~~~~~~~~~~~~~~~~~~~~~#

_error:
pop_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

3rd ASM Source:
lbz r0, 0x1 (r3) #Default instruction
mulli r12, r22, 0x4 #Multiple Player slot by 4, store in r12. Thus lower 16 bits of r12 will hold second half of mem81 address
addis r12, r12, 0x8166 #Add 0x8166 to upper 16 bits of r12. The player slot will increment/separate the address by 0x4 depending on slot value
stw r0, 0x0 (r12) #Store current read player's item to r12 plus offset 0x0193 (address for that player's item is now finalized)

==========

4th ASM Source:
lbz r0, 0x0011 (r16) #Default instruction
mulli r12, r22, 0x4 #Multiple Player slot by 4, store in r12. Thus lower 16 bits of r12 will hold second half of mem81 address
addis r12, r12, 0x8166 #Add 0x8166 to upper 16 bits of r12. The player slot will increment/separate the address by 0x4 depending on slot value
stw r0, 0x0 (r12) #Store current read player's item to r12 plus offset 0x0193 (address for that player's item is now finalized)
lis r11, 0x8167 #Set 1st Half Address for Race-Status Word Check
stw r16, 0 (r11) #We need anything not zero at 0x81670000, store r16 to that spot



Code creator: Vega
Code credits: Star & RiiDefi (Draw Text to Screen Code); Bully (Both Item Spy ASMs)

Print this item

  Graphical In-Game Item Spy Offline [Vega]
Posted by: Vega - 03-31-2019, 09:10 PM - Forum: Offline; Item - No Replies

Graphical In-Game Item Spy Offline [Vega]

NOTE: It's recommended to also include this code to eliminate frame flickers -> https://mkwii.com/showthread.php?tid=1530

Works Offline only.

This code will place a graphical image on the bottom on your screen. The screen will contain the held items (in inventory) of every player in the race. The listing of the items will be ordered by the player slot number. The items presented will be shown in their hex value...

Hex Item Image Values:
00 - Green Shell / No Player on Slot
01 - Red Shell
02 - Banana
03 - Fib
04 - Shroom
05 - Triple Shrooms
06 - Bomb
07 - Blue Shell
08 - Shock
09 - Star
0A - Golden
0B - Mega
0C - Blooper
0D - Pow
0E - TC
0F - Bill
10 - Triple Greens
11 - Triple Reds
12 - Triple Nanas
14 - No Item / No Item Available

NOTE: This code makes use of the following memory addresses...
0x80001500 thru 0x80001518
0x81500000 thru 0x8150002F
0x81510000 thru 0x81510003

Make sure no other codes in your GCT/Cheat-Manager are using those addresses.

NTSC-U
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009640 0000001D
3D808151 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08150
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C0ECC
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C0ECC
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1DF0
7D8803A6 4E800021
61CC1DD0 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C278EEF8 00000004
801D008C 1D9B0004
3D8C8150 900C0000
3D608151 93AB0000
60000000 00000000


PAL
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009680 0000001D
3D808151 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08150
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C1A2C
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C1A2C
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1E90
7D8803A6 4E800021
61CC1E70 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C2797F04 00000004
801D008C 1D9B0004
3D8C8150 900C0000
3D608151 93AB0000
60000000 00000000


NTSC-J
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C20095DC 0000001D
3D808151 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08150
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C1950
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C1950
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1DB0
7D8803A6 4E800021
61CC1D90 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C2797570 00000004
801D008C 1D9B0004
3D8C8150 900C0000
3D608151 93AB0000
60000000 00000000


NTSC-K
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009788 0000001D
3D808151 818C0000
2C0C0000 418200D0
9421FF80 BC610008
48000025 25303258
20253032 58202530
32582025 30325820
25303258 20253032
58200000 7C8802A6
38A00020 98A4001D
7C9D2378 3FC08150
7CBEC4AA 3C608000
60631500 3BE30012
3D808001 618C1A94
7D8803A6 4E800021
2C030000 41800060
7FA4EB78 38A00000
98A4001D 7FE3FB78
3BDE0018 7CBEC4AA
3D808001 618C1A94
7D8803A6 4E800021
2C030000 41800030
38600030 388000DA
38A00001 38DFFFEE
3DC08002 61CC1EF0
7D8803A6 4E800021
61CC1ED0 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C27862C4 00000004
801D008C 1D9B0004
3D8C8150 900C0000
3D608151 93AB0000
60000000 00000000



List of Sources:
1st ASM (When Game loads StaticR.rel, Get Render Mode & Call Direct Print Setup Frame Buffer)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#         r3 = Render Mode           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

2nd ASM Source:

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                  Memory Address Notes:                  #
# 0x80001500 thru 0x80001512 - Formatted 1st Half of String #
# 0x80001512 - Null Byte appended from 1st Call of Sprintf  #
# 0x80001512 thru 0x80001517 - Formatted 2nd Half of String #
# 0x80001518 - Null Byte appneded from 2nd Call of Sprintf  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro call_nw4r address
ori r12, r14, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE

.set sprintf, 0x80010ECC
.set nw4r_db_DirectPrint_Printf, 0x1DF0
.set nw4r_db_DirectPrint_StoreCache, 0x1DD0

.elseif (region == 'P' || region == 'p') # RMCP

.set sprintf, 0x80011A2C
.set nw4r_db_DirectPrint_Printf, 0x1E90
.set nw4r_db_DirectPrint_StoreCache, 0x1E70

.elseif (region == 'J' || region == 'j') # RMCJ

.set sprintf, 0x80011950
.set nw4r_db_DirectPrint_Printf, 0x1DB0
.set nw4r_db_DirectPrint_StoreCache, 0x1D90

.elseif (region == 'K' || region == 'k') # RMCK

.set sprintf, 0x80011A94
.set nw4r_db_DirectPrint_Printf, 0x1EF0
.set nw4r_db_DirectPrint_StoreCache, 0x1ED0

.else # Invalid Region
.err
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Check to See if a Race is Active:      #
#        Load Status Word from Mem 81          #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8151
lwz r12, 0x0 (r12)
cmpwi r12, 0x0
beq- dont_execute

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                      Sprintf #1                      #
#    r3 = Address Pointer to Dump Formatted String    #
# r4 = Address Pointer to String that needs Formatting #
#        r5 thru r10 = Non Float Format Args          #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

bl printf_string

.llong 0x2530325820253032 #1st String for 1st Sprintf - "%02X %02X %02X %02X %02X %02X "
.llong 0x5820253032582025
.llong 0x3032582025303258
.llong 0x2025303258200000

printf_string:
mflr r4
li r5, 0x20
stb r5, 0x1D (r4) #This is needed because the final 0x20 gets nulled out for second sprintf, so we always need to 'recover' it before first sprintf

mr r29, r4 #Backup String Address Pointer to r29

lis r30, 0x8150
lswi r5, r30, 24 #Load the first 6 slot Item Words into r5 - r10

lis r3, 0x8000 #Set Address to Dump String To
ori r3, r3, 0x1500
addi r31, r3, 0x0012 #First Formatted String Ends at 0x80001512 (null), so add 0x18 to r3 for start of 2nd string on 2nd call of sprintf. Put result in r31 for global variable storage thru function calls

call_link sprintf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Check Sprintf #1 Return Value #
#  If negative, error occured  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmpwi r3, 0x0
blt- _error

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                      Sprintf #2                      #
#    r3 = Address Pointer to Dump Formatted String    #
# r4 = Address Pointer to String that needs Formatting #
#        r5 thru r10 = Non Float Format Args          #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

mr r4, r29 #Move backed up string address pointer to r4
li r5, 0x0
stb r5, 0x1D (r4) #The space in the ASCII string near the end is not needed, null it out, string is now ready for 2nd call of sprintf

mr r3, r31 #2nd String will be dumped to exactly where null byte of 1st string of ended at
addi r30, r30, 0x18 #Add 0x18 to r30, now address points to beginning of second half of the 12 player item slot listing
lswi r5, r30, 24 #Load slot's 7 - 12 Item Words into r5 - r10

call_link sprintf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Check Sprintf #2 Return Value #
#  If negative, error occured  #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmpwi r3, 0x0
blt- _error

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache              #
#                  Purpose: Draw on Screen                  #
#            r3 = X coordinate (starts far left)            #
#            r4 = Y coordinate (starts at very top)          #
#                  r5 = 0 No Wrap; 1 Wrap                    #
# r6 = Address Pointer to String that will be Drawn on Screen #
#              r7 thru r10 printf format args                #
#          f1 thru f13 printf float format args              #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x30
li r4, 0xDA
li r5, 0x1
addi r6, r31, -0x12 #Make r6 have 0x80001500, beginning of entire formatted string

lis r14, 0x8002 #For nw4r macro

call_nw4r nw4r_db_DirectPrint_Printf
call_nw4r nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety #
#~~~~~~~~~~~~~~~~~~~~~#

_error:
pop_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

3rd ASM:
lwz r0, 0x8C (r29) #Default Instruction, r0 holds current Player/CPU's Held Item
mulli r12, r27, 0x4 #Multiple Player Slot value in r27 by 0x4, put result in r12
addis r12, r12, 0x8150 #Add 0x8150 to upper 16 bits of r12. The player slot will increment/separate the address by 0x4 depending on slot value
stw r0, 0x0 (r12) #Store current Player/CPU's Held Item value to address of r12
lis r11, 0x8151 #Set 1st Half Address for Race-Status Word Check
stw r29, 0x0 (r11) #We need anything not zero at 0x81510000, store 29 to that spot



Code creator: Vega
Code credits: Star & RiiDefi (Draw Text to Screen Code); Bully (Item Spy ASM)

Print this item

  Learn PowerPC for Wii Cheat Codes Index
Posted by: Vega - 03-30-2019, 09:23 PM - Forum: PowerPC Assembly - Replies (6)

Learn PowerPC for Wii Cheat Codes Index

This is a gigantic index of threads that will take any absolute beginner and teach them much of the PowerPC Assembly Language for the purpose of creating Wii Cheat Codes. This is NOT a "general" PowerPC tutorial. There are certain concepts that are taught in a different manner that is suited specifically for Wii Codes. However, you can use this to learn PowerPC regardless.

All threads must be read in listed order. This will NOT be something you learn in just a day or two. It will take some time. Be patient and read thoroughly. For most of the threads provided, there are also video links as well. However, some of the video links have become extremely outdated and you should only watch the video(s) if absolutely necessary.

Requirements before you start:

  • Have a modern computer
  • An ISO/WBFS file(s) of whatever games you want to make codes with, on your computer

Even though this is a Mario Kart Wii based site, you can use these tutorials to help you make cheat codes for other Wii games.

You will need what is called the 'Dolphin Emulator' installed on your computer before you begin. You will also need to know a few things about running/playing Dolphin plus installing a program called 'Dolphin-memory-engine'. Here are 3 threads you need to read and complte first...
After you have completed those 3 threads and you can run Dolphin at 60 fps with the Dolphin-memory-engine working, then proceed.

If you have unresolved issues with Dolphin Emulator, it's best to ask on the Dolphin Emu forums - https://forums.dolphin-emu.org If you have unresolved issues with Dolphin-memory-engine, post an issue at this link - https://github.com/aldelaro5/Dolphin-mem...ine/issues

Now let's begin!  Smile



N00b Level Threads

The Basics of Wii Cheat Codes & the Gecko Code Handler
https://mkwii.com/showthread.php?tid=434
Summary: An introduction to cheat codes , the code handler, memory, and various basic cheat code formats
Video - https://www.youtube.com/watch?v=mwuth4rSaTs

Fill in XYZ Values
https://mkwii.com/showthread.php?tid=29
Summary: This is required for codes that require you to 'activate' them or 'deactivate' them
Video - https://www.youtube.com/watch?v=nQHsUEnziHs

Create Activators and Deactivators
https://mkwii.com/showthread.php?tid=68
Summary: Teaches you how to make your own activators and deactivators on a code that doesn't have them
Video - https://youtu.be/VOl8nOHmFyE

Port Codes
https://mkwii.com/showthread.php?tid=113
Summary: Teaches you how to make basic cheat codes work in any 'version'/'region' of Mario Kart Wii
Video - https://www.youtube.com/watch?v=-mHTJtTmtAc



Beginner Level Threads

How to Make your own Cheat Codes
https://mkwii.com/showthread.php?tid=830
Summary: Yep, this is it. How to make your own real codes from scratch!
Video - https://www.youtube.com/watch?v=8mFyLqdT3hQ

Assembly Tutorial
https://mkwii.com/showthread.php?tid=940
Summary: This thread is linked within the 'How to Make Your own Cheat Codes' thread. Scared to learn ASM? Fear not! This thread by far is the best guide anywhere on the web to teach you basic PowerPC Assembly Code for MKWii Coding.
Video - https://www.youtube.com/watch?v=eadIKQltU1I

2nd part of 'How to make your own Cheat Codes' Video - https://www.youtube.com/watch?v=v1Eg2j5iWwc

Register Safety for the Beginner
https://mkwii.com/showthread.php?tid=873
Summary: Proper safety etiquette for ASM Codes
Video - https://www.youtube.com/watch?v=h-f7DCwnWy4

Basic Debugging/Analysis of ASM Codes
https://mkwii.com/showthread.php?tid=1383
Summary: Teaches you how to set certain Dolphin Debug features/shortcuts and how to step-by-step codes. Also includes an introduction to Exceptions (crashes).
Video - https://www.youtube.com/watch?v=voLRpFTw0Ys

Basic GVR Usage in ASM Codes
https://mkwii.com/showthread.php?tid=1962
Summary: Teaches you how to add better features to simple ASM Codes
Video - None



Intermediate Level Threads

ASM Tips n Trix
https://mkwii.com/showthread.php?tid=974
Summary: Still having some trouble writing ASM after learning it? Fear not! Here are some tips to make things easier
Video - https://www.youtube.com/watch?v=aeEUsqrdOWg

Using the Exception Vector Area
https://mkwii.com/showthread.php?tid=1106
Summary: Once your ASM codes get a bit less basic, you may need to store data/values at a unused spot in Memory. This thread will teach you how.
Video - https://www.youtube.com/watch?v=-S6NTN10GbE

More info about Comparisons and Branches
https://mkwii.com/showthread.php?tid=1743
Summary: Clearing the confusion on compare and branch instructions for Beginner Coders
Video - None

Creating Loops
https://mkwii.com/showthread.php?tid=975
Summary: How to create a list of repeating instructions in ASM
Video - https://www.youtube.com/watch?v=49YY9U0StKU



Expert Level Threads

Logical Operations
https://mkwii.com/showthread.php?tid=1824
Summary: Explains binary values within Hexadecimal, and about using PPC instructions to modify binary values
Video - None

Working with Floats
https://mkwii.com/showthread.php?tid=1744
Summary: I hate them, but maybe you will like them. All about floating points and how to use them in codes.
Video (only on Chapter 5) - https://www.youtube.com/watch?v=mlNyQ_gKZQ8

Make Codes Execute on Set Intervals
https://mkwii.com/showthread.php?tid=1385
Summary: Want to modify a code to go off/on automatically per a set timed interval, this thread will teach you how
Video - https://www.youtube.com/watch?v=5Rv0zpwa1I4

Calling Functions
https://mkwii.com/showthread.php?tid=1052
Summary: Call basic static functions within the game using ASM
Video - https://www.youtube.com/watch?v=43QGQHaSYa4

C0 Codetypes
https://mkwii.com/showthread.php?tid=1156
Summary: In depth overview of the C0 (Execute ASM) Codetype.
Video - https://www.youtube.com/watch?v=vrUUYe79zL0

All about Cache
https://mkwii.com/showthread.php?tid=1958
Summary: Attempts to simplfy the complexity of the Cache
Video - None



Pr0 Level Threads

Branch Link (BL) Trick
https://mkwii.com/showthread.php?tid=977
Summary: An optimized way to copy over large amounts of data in Power PC ASM
Video - https://www.youtube.com/watch?v=lnGBQo0UZ34

About Creating Stack Frames
https://mkwii.com/showthread.php?tid=1108
Summary: Create Stack Frames to store registers/data to for backup
Video - https://www.youtube.com/watch?v=hWds-FUB6MY

Using Assembler Directives
https://mkwii.com/showthread.php?tid=1083
Summary: Teaches you the in's & out's of Symbols, Macros, and Statements in an ASM Code's source
Video - https://www.youtube.com/watch?v=m_GusHn7CWI

All About Bit Rotation
https://mkwii.com/showthread.php?tid=1262
Summary: Teaches you the ins & outs of Bit Shifting, Clearing, Rotating, etc.
Video - https://www.youtube.com/watch?v=EbWiS7fjHqY

Utilizing the Condition Register
https://mkwii.com/showthread.php?tid=1959
Summary: A full deep dive into the Condition Register and all of its tricks
Video - None

Paired Singles
https://mkwii.com/showthread.php?tid=1870
Summary: The hardest aspect of PowerPC Assembly to learn in my opinion. Have fun!
Video - None



Conclusion

Welp, there you go. Not many people in this community have the patience to learn all of this.

Best of luck! Thanks for reading!

Print this item

  Graphical SpeedBar [Vega]
Posted by: Vega - 03-23-2019, 02:16 PM - Forum: Time Trials & Battle - No Replies

Graphical SpeedBar [Vega]

NOTE: It's recommended to also include this code to eliminate frame flickers -> https://mkwii.com/showthread.php?tid=1530

Shout outs to Star & RiiDefi for Draw Text To Screen Code!

This code will output your vehicle speed view a graphical image depicting an interactive bar. The bar length will vary depending on your vehicle speed. The bar works in an exponential manner, NOT linear. The higher the speeds, the more the bar will change depending on differences at the higher speeds.

NOTE: This code makes use of the following memory addresses...
0x80001660 thru 0x80001689
0x815F0000 thru 0x815F0003

Make sure no other codes in your GCT/Cheat-Manager are using those addresses!

NTSC-U
06001670 00000010
25336420 6B6D2F68
0A000000 00000000
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009640 00000016
3D80815F 818C0000
2C0C0000 41820098
9421FF80 BC610008
3D808000 816C1660
C1AB0024 FDA06A10
FDA0681C D9AC1664
806C1668 7C671B78
7C6319D6 38800370
7C6323D6 3BA00000
2C030000 41820020
39E0007C 61901678
9DF00001 3463FFFF
4082FFF8 9BB00001
48000008 9BAC1679
38600009 388000D0
38A00001 61861670
3FE08002 63EC1DF0
7D8803A6 4E800021
63EC1DD0 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C27E4C9C 00000007
3D80809C 818CD110
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807FEE20
60000000 00000000

PAL
06001670 00000010
25336420 6B6D2F68
0A000000 00000000
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009680 00000016
3D80815F 818C0000
2C0C0000 41820098
9421FF80 BC610008
3D808000 816C1660
C1AB0024 FDA06A10
FDA0681C D9AC1664
806C1668 7C671B78
7C6319D6 38800370
7C6323D6 3BA00000
2C030000 41820020
39E0007C 61901678
9DF00001 3463FFFF
4082FFF8 9BB00001
48000008 9BAC1679
38600009 388000D0
38A00001 61861670
3FE08002 63EC1E90
7D8803A6 4E800021
63EC1E70 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C27EEFAC 00000007
3D80809C 818C18F8
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F3618
60000000 00000000

NTSC-J
06001670 00000010
25336420 6B6D2F68
0A000000 00000000
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C20095DC 00000016
3D80815F 818C0000
2C0C0000 41820098
9421FF80 BC610008
3D808000 816C1660
C1AB0024 FDA06A10
FDA0681C D9AC1664
806C1668 7C671B78
7C6319D6 38800370
7C6323D6 3BA00000
2C030000 41820020
39E0007C 61901678
9DF00001 3463FFFF
4082FFF8 9BB00001
48000008 9BAC1679
38600009 388000D0
38A00001 61861670
3FE08002 63EC1DB0
7D8803A6 4E800021
63EC1D90 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C27EE618 00000007
3D80809C 818C0958
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F2678
60000000 00000000

NTSC-K
06001670 00000010
25336420 6B6D2F68
0A000000 00000000
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009788 00000016
3D80815F 818C0000
2C0C0000 41820098
9421FF80 BC610008
3D808000 816C1660
C1AB0024 FDA06A10
FDA0681C D9AC1664
806C1668 7C671B78
7C6319D6 38800370
7C6323D6 3BA00000
2C030000 41820020
39E0007C 61901678
9DF00001 3463FFFF
4082FFF8 9BB00001
48000008 9BAC1679
38600009 388000D0
38A00001 61861670
3FE08002 63EC1EF0
7D8803A6 4E800021
63EC1ED0 7D8803A6
4E800021 B8610008
38210080 81830000
60000000 00000000
C27DD36C 00000007
3D80809B 818CFF38
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F1C58
60000000 00000000



List of Sources:
1st ASM (When Game loads StaticR.rel, Get Render Mode & Call Direct Print Setup Frame Buffer)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#         r3 = Render Mode           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

2nd ASM (Convert Speed Float, Calc Bar Length, Write Bar Amtn to Gecko ASCii String, Draw it to Screen)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                                    Mem Address Notes:                                        #
#                              0x80001660 = Speed Float Word                                  #
#                0x80001664 = Converted Hex 1st Word of Double Word Float                    #
#          0x80001668 = Converted Hex 2nd Word of Double Word Float (Speed in Hex)            #
#                0x80001670 = Gecko String ASCii, r6 Arg for Direct Print                    #
#            0x80001678 = 0x0A ASCii byte for Entering into new Line for Speed Bar            #
#                              0x80001679 = Start of Bar                                      #
#                0x80001688 = Last Bar byte at its highest amount possible                    #
#          0x80001689 = Last Null of Bar byte string at its highest amount possible            #
# 0x815F0000 = "Status Word" If not zero, Draw Code will execute, auto clears after every race #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_nw4r address
ori r12, r31, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_Printf, 0x1DF0
.set nw4r_db_DirectPrint_StoreCache, 0x1DD0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_Printf, 0x1E90
.set nw4r_db_DirectPrint_StoreCache, 0x1E70
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_Printf, 0x1DB0
.set nw4r_db_DirectPrint_StoreCache, 0x1D90
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_Printf, 0x1EF0
.set nw4r_db_DirectPrint_StoreCache, 0x1ED0
.else # Invalid Region
.err
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Check to See if a Race is Active:      #
#        Load Status Word from Mem 81          #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F
lwz r12, 0x0 (r12)
cmpwi r12, 0x0
beq- dont_execute

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Load, Float Load, Conversion, Storage #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8000 #Set 1st Half Address of Exception Vector Area
lwz r11, 0x1660 (r12) #Load Pointer
lfs f13, 0x0024 (r11) #Load the Speed Float from the Pointer
fabs f13, f13 #Convert Float to handle negative values approriately; aka fix Reverse Speed reading
fctiw f13, f13 #Convert Float to Word Integer, use Standard Rounding; aka fix Funky Kong 96/97 issue
stfd f13, 0x1664 (r12) #Store the whole converted float to 0x80001664 (using this instead of a li then stfiwx will save us one instruction total)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Calculate Bar Amount to Write to Memory #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lwz r3, 0x1668 (r12) #Load Vehicle Hex Speed Amnt into r3

mr r7, r3 #Copy hex value to r7 for DirectPrintf's 1st format Arg

mullw r3, r3, r3 #Raise Vehicle Hex Speed to the Power of 2

li r4, 0x370 #Load 0x370 into r4 for upcoming divw instruction
divw r3, r3, r4 #Divide Vehicle Hex Speed by 0x370

li r29, 0x0 #Clear out r29 for Bar End or else Bar will never decrease when speed decreases

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Check if Bar Amnt is Zero. If so, we don't need to Write the Bar, skip upcoming Loop #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

cmpwi r3, 0x0
beq- skip_loop

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set ASCii Symbol (divider), Setup Loop Store Address #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r15, 0x7C
ori r16, r12, 0x1678

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                            Loop                              #
# Write Approriate Bar Amount Based on finalized Hex Speed Amnt #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

the_loop:
stbu r15, 0x1 (r16)
subic. r3, r3, 1
bne+ the_loop

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store NULL (Bar End) after last Byte of Bar #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

stb r29, 0x1 (r16)
b draw_toscreen

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Store NULL to what would be first Bar Byte #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

skip_loop:
stb r29, 0x1679 (r12)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache              #
#                Purpose: Draw on Screen                    #
#            r3 = X coordinate (starts far left)            #
#          r4 = Y coordinate (starts at very top)            #
#                r5 = 0 No Wrap; 1 Wrap                      #
# r6 = Address Pointer to String that will be Drawn on Screen #
#              r7 thru r10 printf format args                #
#            f1 thru f13 printf float format args            #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

draw_toscreen:
li r3, 0x9
li r4, 0xD0
li r5, 0x1
ori r6, r12, 0x1670 #Gecko String Write Address

lis r31, 0x8002 #For nw4r macro

call_nw4r nw4r_db_DirectPrint_Printf #r7 already set from earlier
call_nw4r nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety #
#~~~~~~~~~~~~~~~~~~~~~#

pop_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

3rd ASM (Store Memory Pointer)
#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.macro default_instruction
lwz r3, -0x11E0 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0xFFFFD110 (r12)
.endm
.elseif (region == 'P' || region == 'p') # RMCP
.macro default_instruction
lwz r3, 0x3618 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x18F8 (r12)
.endm
.elseif (region == 'J' || region == 'j') # RMCJ
.macro default_instruction
lwz r3, 0x2678 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x0958 (r12)
.endm
.elseif (region == 'K' || region == 'k') # RMCK
.macro default_instruction
lwz r3, 0x1C58 (r31)
.endm
.macro set_playerbase
lis r12, 0x809B
lwz r12, 0xFFFFFF38 (r12)
.endm
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Region-Specific Player-Base #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

set_playerbase

#~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Level Loading #
#~~~~~~~~~~~~~~~~~~~~~~~#

lwz r12, 0x0020 (r12) #Load Word from 1st Level Pointer

slwi r11, r0, 2 #Shift the bits of r0 by 2 to the left, result in r11. This is the same as multiplying by 0x4. r0 is current player slot.

lwzx r12, r12, r11 #Load into 2nd Level Pointer
lwz r12, 0x0010(r12) #Load into 3rd Level Pointer
lwz r12, 0x0010(r12) #Load into 4th Level Pointer

#~~~~~~~~~~~~~~~~~~~~~#
# Store Final Pointer #
#~~~~~~~~~~~~~~~~~~~~~#

lis r11, 0x8000 #Set up 1st Half Address of Exception Vector Area
stw r12, 0x1660 (r11) #Store Pointer Address to 0x80001660

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Status Word in Mem81 for Draw Text ASM #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F #Set up 1st Half Address of dynmaic Mem81
stw r31, 0x0 (r12) #Store r31 to 0x815F0000, we simply need a value not zero to be stored here. This will make the Speed Bar ASM only trigger during races.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction; Region-Specific #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: Vega
Code credits: Star & RiiDefi (Draw Text To Screen Code); Chadderz (source fixes to Mdmwii's OG Speed source), Mdmwii (original Speed-O-Meter)

Print this item

  Graphical Speed/MTC/Air/Boost Meter [Vega]
Posted by: Vega - 03-23-2019, 02:14 PM - Forum: Time Trials & Battle - No Replies

Graphical Speed/MTC/Air/Boost Meter [Vega]

NOTE: It's recommended to also include this code to eliminate frame flickers -> https://mkwii.com/showthread.php?tid=1530

Shout outs to Star & RiiDefi for Draw Text To Screen Code!

This code will display your vehicle speed, air time, mini turbo charge, and shroom/zipper boost as its own graphical image at the bottom of your screen only during the race/battle. The image will not appear if you are not in a race/battle. Works everywhere.

NOTE: This code makes use of the following memory addresses...
0x80001660 thru 0x80001663
0x815F0000 thru 0x815F0003

Make sure no other codes in your GCT/Cheat-Manager are using those addresses.

NTSC-U
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009640 00000017
3D80815F 818C0000
2C0C0000 418200A0
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
A10B021A A12B0110
A0EB0100 2C070000
40820008 A0EB00FE
4800002D 25332E30
66206B6D 2F682C20
25336420 4D54432C
20253364 20416972
2C202533 64204273
74000000 7CC802A6
38600009 388000DC
38A00001 3FE08002
63EC1DF0 7D8803A6
4E800021 63EC1DD0
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27E4C9C 00000007
3D80809C 818CD110
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807FEE20
60000000 00000000

PAL
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009680 00000017
3D80815F 818C0000
2C0C0000 418200A0
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
A10B021A A12B0110
A0EB0100 2C070000
40820008 A0EB00FE
4800002D 25332E30
66206B6D 2F682C20
25336420 4D54432C
20253364 20416972
2C202533 64204273
74000000 7CC802A6
38600009 388000DC
38A00001 3FE08002
63EC1E90 7D8803A6
4E800021 63EC1E70
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27EEFAC 00000007
3D80809C 818C18F8
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F3618
60000000 00000000

NTSC-J
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C20095DC 00000017
3D80815F 818C0000
2C0C0000 418200A0
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
A10B021A A12B0110
A0EB0100 2C070000
40820008 A0EB00FE
4800002D 25332E30
66206B6D 2F682C20
25336420 4D54432C
20253364 20416972
2C202533 64204273
74000000 7CC802A6
38600009 388000DC
38A00001 3FE08002
63EC1DB0 7D8803A6
4E800021 63EC1D90
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27EE618 00000007
3D80809C 818C0958
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F2678
60000000 00000000

NTSC-K
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009788 00000017
3D80815F 818C0000
2C0C0000 418200A0
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
A10B021A A12B0110
A0EB0100 2C070000
40820008 A0EB00FE
4800002D 25332E30
66206B6D 2F682C20
25336420 4D54432C
20253364 20416972
2C202533 64204273
74000000 7CC802A6
38600009 388000DC
38A00001 3FE08002
63EC1EF0 7D8803A6
4E800021 63EC1ED0
7D8803A6 4E800021
B8610010 C8210008
38210090 81830000
60000000 00000000
C27DD36C 00000007
3D80809B 818CFF38
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F1C58
60000000 00000000



List of Sources:
1st ASM (When Game loads StaticR.rel, Get Render Mode & Call Direct Print Setup Frame Buffer)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#         r3 = Render Mode           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

2nd ASM (Take Float Speed, Convert It, Draw it to Screen)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                                  Mem Address Notes:                                        #
#                            0x80001660 Speed Float Word                                    #
# 0x815F0000 "Status Word" If not zero, Draw Code will execute, auto clears after every race #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x90 (r1)
stfd f1, 0x8 (r1)
stmw r3, 0x10 (r1)
.endm

.macro pop_stack
lmw r3, 0x10 (r1)
lfd f1, 0x8 (r1)
addi r1, r1, 0x90
.endm

.macro call_nw4r address
ori r12, r31, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_Printf, 0x1DF0
.set nw4r_db_DirectPrint_StoreCache, 0x1DD0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_Printf, 0x1E90
.set nw4r_db_DirectPrint_StoreCache, 0x1E70
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_Printf, 0x1DB0
.set nw4r_db_DirectPrint_StoreCache, 0x1D90
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_Printf, 0x1EF0
.set nw4r_db_DirectPrint_StoreCache, 0x1ED0
.else # Invalid Region
.err
.endif

.set _speed, 0x24 #Speed Float
.set _mtc, 0xFE #MT Charge
.set _omtc, 0x100 #Kart Only Orange MT Charge
.set _mushb, 0x110 #Mushroom Boost
.set _air, 0x21A #Air Time

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Check to See if a Race is Active:      #
#        Load Status Word from Mem 81          #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F
lwz r12, 0x0 (r12)
cmpwi r12, 0x0
beq- dont_execute

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load Pointer, Load Float #
#~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8000 #Set 1st half address of Exception Vector Area
lwz r11, 0x1660 (r12) #Load the Pointer
lfs f1, _speed (r11) #Load the Single Float into FPR 1 for first float format arg of DirectPrint Printf
fabs f1, f1 #Handle negative values
crset 4*cr1+eq #Set the Condition Register before the Float Arg is used in DirectPrint Printf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load MTC, Air, MTB into appropriate DirectPrintf registers #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lhz r8, _air (r11) #Set 2nd GPR format arg
lhz r9, _mushb (r11) #Set 3rd GPR format arg

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Load MT, do Orange MT Check Calc #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lhz r7, _omtc (r11) #First Load the Orange MT value
cmpwi r7, 0x0
bne- skip_blue #If not zero, we don't need to read Blue MT, follow skip_blue branch

lhz r7, _mtc (r11) #If zero, read Blue MT instead of Orange MT

skip_blue: #1st GPR format arg is set

#~~~~~~~~~~~~~~~~~~~~~#
# Create ASCii String #
#~~~~~~~~~~~~~~~~~~~~~#

bl the_string #Create the C++ string

.llong 0x25332E3066206B6D #Hex for "%3.0f km/h, %3d MTC, %3d Air, %3d Bst"
.llong 0x2F682C2025336420
.llong 0x4D54432C20253364
.llong 0x204169722C202533
.llong 0x6420427374000000

the_string:
mflr r6 #Move C++ string's address location to r4, r5 thru r8 arguments already set

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache              #
#                Purpose: Draw on Screen                    #
#            r3 = X coordinate (starts far left)            #
#          r4 = Y coordinate (starts at very top)            #
#                r5 = 0 No Wrap; 1 Wrap                      #
# r6 = Address Pointer to String that will be Drawn on Screen #
#              r7 thru r10 printf format args                #
#            f1 thru f13 printf float format args            #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x9
li r4, 0xDC
li r5, 0x1

lis r31, 0x8002 #For nw4r macro

call_nw4r nw4r_db_DirectPrint_Printf
call_nw4r nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety #
#~~~~~~~~~~~~~~~~~~~~~#

pop_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

3rd ASM (Store Memory Pointer)
#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.macro default_instruction
lwz r3, -0x11E0 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0xFFFFD110 (r12)
.endm
.elseif (region == 'P' || region == 'p') # RMCP
.macro default_instruction
lwz r3, 0x3618 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x18F8 (r12)
.endm
.elseif (region == 'J' || region == 'j') # RMCJ
.macro default_instruction
lwz r3, 0x2678 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x0958 (r12)
.endm
.elseif (region == 'K' || region == 'k') # RMCK
.macro default_instruction
lwz r3, 0x1C58 (r31)
.endm
.macro set_playerbase
lis r12, 0x809B
lwz r12, 0xFFFFFF38 (r12)
.endm
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Region-Specific Player-Base #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

set_playerbase

#~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Level Loading #
#~~~~~~~~~~~~~~~~~~~~~~~#

lwz r12, 0x0020 (r12) #Load Word from 1st Level Pointer

slwi r11, r0, 2 #Shift the bits of r0 by 2 to the left, result in r11. This is the same as multiplying by 0x4. r0 is current player slot.

lwzx r12, r12, r11 #Load into 2nd Level Pointer
lwz r12, 0x0010(r12) #Load into 3rd Level Pointer
lwz r12, 0x0010(r12) #Load into 4th Level Pointer

#~~~~~~~~~~~~~~~~~~~~~#
# Store Final Pointer #
#~~~~~~~~~~~~~~~~~~~~~#

lis r11, 0x8000 #Set up 1st Half Address of Exception Vector Area
stw r12, 0x1660 (r11) #Store Pointer Address to 0x80001660

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Status Word in Mem81 for Draw Text ASM #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F #Set up 1st Half Address of dynmaic Mem81
stw r31, 0x0 (r12) #Store r31 to 0x815F0000, we simply need a value not zero to be stored here. This will make the Speed Bar ASM only trigger during races.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction; Region-Specific #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: Vega
Code credits: Star & RiiDefi (Draw Text To Screen Code); SwareJonge (Universal Meter code); Chadderz (source fixes to Mdmwii's OG Speed source); Mdmwii (original Speed-O-Meter)

Print this item

  Graphical Speed-O-Meter [Vega]
Posted by: Vega - 03-23-2019, 02:11 PM - Forum: Incomplete & Outdated Codes - Replies (3)

Graphical Speed-O-Meter [Vega]

NOTE: Outdated by SwareJonge's version.

NOTE: It's recommended to also include this code to eliminate frame flickers -> https://mkwii.com/showthread.php?tid=1530

Shout outs to Star & RiiDefi for Draw Text To Screen Code!

This code will display your vehicle speed as its own graphical image on the bottom left of your screen only during the race/battle. The image will not appear if you are not in a race/battle. Works everywhere.

NOTE: This code makes use of the following memory addresses...
0x80001660 thru 0x80001663
0x815F0000 thru 0x815F0003

Make sure no other codes in your GCT/Cheat-Manager are using those addresses.

NTSC-U
C200A3F0 00000007
9421FF80 BC610008
806DA358 80630044
80630000 3D808002
618C23E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009640 00000010
3D80815F 818C0000
2C0C0000 4182006C
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3FE08002 63EC1DF0
7D8803A6 4E800021
63EC1DD0 7D8803A6
4E800021 B8610010
C8210008 38210090
81830000 00000000
C27E4C9C 00000007
3D80809C 818CD110
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807FEE20
60000000 00000000

PAL
C200A430 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C2480 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009680 00000010
3D80815F 818C0000
2C0C0000 4182006C
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3FE08002 63EC1E90
7D8803A6 4E800021
63EC1E70 7D8803A6
4E800021 B8610010
C8210008 38210090
81830000 00000000
C27EEFAC 00000007
3D80809C 818C18F8
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F3618
60000000 00000000

NTSC-J
C200A38C 00000007
9421FF80 BC610008
806DA360 80630044
80630000 3D808002
618C23A0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C20095DC 00000010
3D80815F 818C0000
2C0C0000 4182006C
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3FE08002 63EC1DB0
7D8803A6 4E800021
63EC1D90 7D8803A6
4E800021 B8610010
C8210008 38210090
81830000 00000000
C27EE618 00000007
3D80809C 818C0958
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F2678
60000000 00000000

NTSC-K
C200A538 00000007
9421FF80 BC610008
806DA380 80630044
80630000 3D808002
618C24E0 7D8803A6
4E800021 B8610008
38210080 80010014
60000000 00000000
C2009788 00000010
3D80815F 818C0000
2C0C0000 4182006C
9421FF70 D8210008
BC610010 3D808000
816C1660 C02B0024
FC200A10 4CC63242
48000011 25332E30
66206B6D 2F680000
7CC802A6 38600009
388000DC 38A00001
3FE08002 63EC1EF0
7D8803A6 4E800021
63EC1ED0 7D8803A6
4E800021 B8610010
C8210008 38210090
81830000 00000000
C27DD36C 00000007
3D80809B 818CFF38
818C0020 540B103A
7D8C582E 818C0010
818C0010 3D608000
918B1660 3D80815F
93EC0000 807F1C58
60000000 00000000



List of Sources:
1st ASM (When Game loads StaticR.rel, Get Render Mode & Call Direct Print Setup Frame Buffer)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#       Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x80 (r1)
stmw r3, 0x8 (r1)
.endm

.macro pop_stack
lmw r3, 0x8 (r1)
addi r1, r1, 0x80
.endm

.macro call_link address
lis r12, \address@h
ori r12, r12, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r0, 0x0014 (r1)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_SetupFB, 0x800223E0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_SetupFB, 0x80022480
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_SetupFB, 0x800223A0
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_SetupFB, 0x800224E0
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Get Render Mode (RKSystem->mpVideo()->pRenderMode) #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

.if (region == 'E' || region == 'e') # RMCE
lwz r3, -0x5CA8(r13)
.elseif (region == 'P' || region == 'p') # RMCP
lwz r3, -0x5CA0(r13)
.elseif (region == 'J' || region == 'j') # RMCJ
lwz r3, -0x5CA0(r13)
.elseif (region == 'K' || region == 'k') # RMCK
lwz r3, -0x5C80(r13)
.endif

lwz r3, 0x0044(r3)
lwz r3, 0x0 (r3)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Call nw4r::db: DirectPrint_SetupFB #
#         r3 = Render Mode           #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

call_link nw4r_db_DirectPrint_SetupFB

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

pop_stack
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

2nd ASM (Take Float Speed, Convert It, Draw it to Screen)

#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Register Notes:      #
# No need to backup r0 or LR #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#                                  Mem Address Notes:                                        #
#                            0x80001660 Speed Float Word                                    #
# 0x815F0000 "Status Word" If not zero, Draw Code will execute, auto clears after every race #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.macro push_stack
stwu r1, -0x90 (r1)
stfd f1, 0x8 (r1)
stmw r3, 0x10 (r1)
.endm

.macro pop_stack
lmw r3, 0x10 (r1)
lfd f1, 0x8 (r1)
addi r1, r1, 0x90
.endm

.macro call_nw4r address
ori r12, r31, \address@l
mtlr r12
blrl
.endm

.macro default_instruction
lwz r12, 0x0 (r3)
.endm

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.set nw4r_db_DirectPrint_Printf, 0x1DF0
.set nw4r_db_DirectPrint_StoreCache, 0x1DD0
.elseif (region == 'P' || region == 'p') # RMCP
.set nw4r_db_DirectPrint_Printf, 0x1E90
.set nw4r_db_DirectPrint_StoreCache, 0x1E70
.elseif (region == 'J' || region == 'j') # RMCJ
.set nw4r_db_DirectPrint_Printf, 0x1DB0
.set nw4r_db_DirectPrint_StoreCache, 0x1D90
.elseif (region == 'K' || region == 'k') # RMCK
.set nw4r_db_DirectPrint_Printf, 0x1EF0
.set nw4r_db_DirectPrint_StoreCache, 0x1ED0
.else # Invalid Region
.err
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#      Check to See if a Race is Active:      #
#        Load Status Word from Mem 81          #
# If not zero, we know to execute the Draw Code #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F
lwz r12, 0x0 (r12)
cmpwi r12, 0x0
beq- dont_execute

#~~~~~~~~~~~~~~~~~~~~~~~#
# Start Register Safety #
#~~~~~~~~~~~~~~~~~~~~~~~#

push_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Load; Float Load, Conversion, Storage #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x8000 #Set 1st Half Address of Exception Vector Area
lwz r11, 0x1660 (r12) #Load Pointer into r11
lfs f1, 0x0024 (r11) #Load the Speed Float from Pointer into Float Register 1
fabs f1, f1 #Handle negative values
crset 4*cr1+eq #Set the Condition Register before the Float Arg is used in DirectPrint Printf

#~~~~~~~~~~~~~~~~~~~~~#
# Create ASCII String #
#~~~~~~~~~~~~~~~~~~~~~#

bl the_string #Create the C++ string

.llong 0x25332E3066206B6D #Hex for "%3.0f km/h"
.long 0x2F680000

the_string:
mflr r6 #Set 4th Arg of DirectPrint Printf

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#              DirectPrint Printf & Store Cache              #
#                Purpose: Draw on Screen                    #
#            r3 = X coordinate (starts far left)            #
#          r4 = Y coordinate (starts at very top)            #
#                r5 = 0 No Wrap; 1 Wrap                      #
# r6 = Address Pointer to String that will be Drawn on Screen #
#              r7 thru r10 printf format args                #
#            f1 thru f13 printf float format args            #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

li r3, 0x9
li r4, 0xDC
li r5, 0x1

lis r31, 0x8002 #For nw4r macro

call_nw4r nw4r_db_DirectPrint_Printf
call_nw4r nw4r_db_DirectPrint_StoreCache

#~~~~~~~~~~~~~~~~~~~~~#
# End Register Safety #
#~~~~~~~~~~~~~~~~~~~~~#

pop_stack

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# dont_execute label; Default Instruction #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

dont_execute:
default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#

==========

3rd ASM (Store Memory Pointer)
#~~~~~~~~~~~~~~~~#
# START ASSEMBLY #
#~~~~~~~~~~~~~~~~#

#~~~~~~~~~~~~~~~~~~~~~#
# Macros & Statements #
#~~~~~~~~~~~~~~~~~~~~~#

.set region, '' #Must set region value, or else source will not compile

.if (region == 'E' || region == 'e') # RMCE
.macro default_instruction
lwz r3, -0x11E0 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0xFFFFD110 (r12)
.endm
.elseif (region == 'P' || region == 'p') # RMCP
.macro default_instruction
lwz r3, 0x3618 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x18F8 (f12)
.endm
.elseif (region == 'J' || region == 'j') # RMCJ
.macro default_instruction
lwz r3, 0x2678 (r31)
.endm
.macro set_playerbase
lis r12, 0x809C
lwz r12, 0x0958 (r12)
.endm
.elseif (region == 'K' || region == 'k') # RMCK
.macro default_instruction
lwz r3, 0x1C58 (r31)
.endm
.macro set_playerbase
lis r12, 0x809B
lwz r12, 0xFFFFFF38 (r12)
.endm
.else # Invalid Region
.abort
.endif

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Region-Specific Player-Base #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

set_playerbase

#~~~~~~~~~~~~~~~~~~~~~~~#
# Pointer Level Loading #
#~~~~~~~~~~~~~~~~~~~~~~~#

lwz r12, 0x0020 (r12) #Load Word from 1st Level Pointer

slwi r11, r0, 2 #Shift the bits of r0 by 2 to the left, result in r11. This is the same as multiplying by 0x4. r0 is current player slot.

lwzx r12, r12, r11 #Load into 2nd Level Pointer
lwz r12, 0x0010(r12) #Load into 3rd Level Pointer
lwz r12, 0x0010(r12) #Load into 4th Level Pointer

#~~~~~~~~~~~~~~~~~~~~~#
# Store Final Pointer #
#~~~~~~~~~~~~~~~~~~~~~#

lis r11, 0x8000 #Set up 1st Half Address of Exception Vector Area
stw r12, 0x1660 (r11) #Store Pointer Address to 0x80001660

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Set Status Word in Mem81 for Draw Text ASM #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

lis r12, 0x815F #Set up 1st Half Address of dynmaic Mem81
stw r31, 0x0 (r12) #Store r31 to 0x815F0000, we simply need a value not zero to be stored here. This will make the Speed Bar ASM only trigger during races.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# Default Instruction; Region-Specific #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

default_instruction

#

#~~~~~~~~~~~~~~#
# END ASSEMBLY #
#~~~~~~~~~~~~~~#



Code creator: Vega
Code credits: Star & RiiDefi (Draw Text To Screen Code); Chadderz (source fixes to Mdmwii's OG Speed source); Mdmwii (original Speed-O-Meter)

Print this item

  Mini Turbo Charge Meter [Vega]
Posted by: Vega - 03-21-2019, 11:06 PM - Forum: Time Trials & Battle - No Replies

Mini Turbo Charge Meter [Vega]

Works everywhere.

This code will read the output value of your MT charge (including Orange MT for Karts) on the millisecond section of your timer. Works for all vehicles.

For Bike Usage: A reading of '270' indicates MT is fully charged ready for boost.
For Kart Usage: Once the first/initial reading reaches 270 (blue MT is fully charged), the milliseconds recycle. Then a reading of '300' indicates the Orange MT is fully charged ready for boost.

NTSC-U
C27ED9F8 00000006
3F80809C 839CD110
839C0020 541A103A
7F9CD02E 839C0010
835C0010 A39A0100
2C1C0000 40820008
A39A00FE 00000000

PAL
C27F84F8 00000006
3F80809C 839C18F8
839C0020 541A103A
7F9CD02E 839C0010
835C0010 A39A0100
2C1C0000 40820008
A39A00FE 00000000

NTSC-J
C27F7B64 00000006
3F80809C 839C0958
839C0020 541A103A
7F9CD02E 839C0010
835C0010 A39A0100
2C1C0000 40820008
A39A00FE 00000000

NTSC-K
C27E68B8 00000006
3F80809B 839CFF38
839C0020 541A103A
7F9CD02E 839C0010
835C0010 A39A0100
2C1C0000 40820008
A39A00FE 00000000



Code creator: Vega
Code credits: JoshuaMK (millisecond display modifier that works everywhere), SwareJonge (universal meter), mdmwii (original pointer loads), Chadderz (fixes to mdmwii's original pointer loads)



Source:
#START ASSEMBLY

#Address Ports
#807ED9F8 NTSC-U
#807F84F8 PAL
#807F7B64 NTSC-J
#807E68B8 NTSC-K

#Source Compilation Region
.set region, '' #Use E/P/J/K. Lowercase letters work too.

#Macros & Statements
.if (region == 'E' || region == 'e') # RMCE
.macro set_playerbase
lis r28, 0x809C
lwz r28, 0xFFFFD110 (r28)
.endm
.elseif (region == 'P' || region == 'p') # RMCP
.macro set_playerbase
lis r28, 0x809C
lwz r28, 0x18F8 (r28)
.endm
.elseif (region == 'J' || region == 'j') # RMCJ
.macro set_playerbase
lis r28, 0x809C
lwz r28, 0x0958 (r28)
.endm
.elseif (region == 'K' || region == 'k') # RMCK
.macro set_playerbase
lis r28, 0x809B
lwz r28, 0xFFFFFF38 (r28)
.endm
.else # Invalid Region
.err
.endif

.set _mtc , 0xFE #MT Charge
.set _omtc, 0x100 #Kart Only Orange MT Charge
.set _mtb, 0x102 #Boost from MT Release
.set _ssmtb, 0x10C #Boost from both Stand Still Charge & MT's
.set _mushb, 0x110 #Mushroom/Zipper Boost
.set _trikb, 0x114 #Trick Boost
.set _ssc, 0x14C #Stand Still Charge
.set _air, 0x21A #Air Time

#Register Notes
#r26 = safe
#r28 = safe

#Set Region-Specific Player-Base
set_playerbase

#Pointer Level Loading
lwz r28, 0x0020 (r28) #Load Word from 1st Level Pointer
slwi r26, r0, 2 #Shift the bits of r0 by 2 to the left, result in r11. This is the same as multiplying by 0x4. r0 is current player slot.
lwzx r28, r28, r26 #Load into 2nd Level Pointer
lwz r28, 0x0010 (r28) #Load into 3rd Level Pointer
lwz r26, 0x0010 (r28) #Load into 4th Level Pointer

#Load & Check Orange MT. If Zero, Load Blue MT Instead; Replace Default Instruction (set r28's value to modify timer)
lhz r28, _omtc (r26) #Load Orange MT
cmpwi r28, 0
bne- skip_blue

lhz r28, _mtc (r26) #Load Blue MT

skip_blue:

#END ASSEMBLY

Print this item