Coding Questions and other Quandaries
#71
Nice work Hackwiz.

Btw for any code where you are simply replacing the old instruction with a new one, you can use the 04 RAM Write instead of a C2 ASM.

Code:
28708D40 00000100
C24DC914 00000001
9883026D 00000000
020003FE 00001000
E0000000 00000000
28708D40 00000200
C24DC914 00000001
8883026D 00000000
E0000000 80008000

becomes...

Code:
28708D40 00000100
044DC914 9883026D
020003FE 00001000
E0000000 00000000
28708D40 00000200
044DC914 8883026D
E0000000 80008000
Reply
#72
(12-26-2021, 10:26 PM)Vega Wrote: Nice work Hackwiz.

Btw for any code where you are simply replacing the old instruction with a new one, you can use the 04 RAM Write instead of a C2 ASM.

Code:
28708D40 00000100
C24DC914 00000001
9883026D 00000000
020003FE 00001000
E0000000 00000000
28708D40 00000200
C24DC914 00000001
8883026D 00000000
E0000000 80008000

becomes...

Code:
28708D40 00000100
044DC914 9883026D
020003FE 00001000
E0000000 00000000
28708D40 00000200
044DC914 8883026D
E0000000 80008000

Even better! Drop a couple more lines.
I know I could have done that, just laziness on my part lol.

A neat mode of gameplay this opens up is something I like to call "Strikes to Spare."
We've played this a couple of times, and it definitely adds another dimension to the standard game.

At the beginning of a game, with a full set of pins (default), press 1 to lock that pin config for the remainder of the game.
Now, if you don't get a strike on your first roll, you must knock all the pins down on the second roll, or you can actually have points subtracted.
Reply
#73
So in regards to the original C0 code, not the random pin C0:

I understand the 06 serial write. Pretty slick.
I'm assuming this would be a great way to replace in game text???

On to the C0 portion:

We used (-) ---> 0x1000 for activator

lis r3, 0x8071 #Get button(s) pressed, check against desired activator---> (I understand)
lhz r0, 0xFFFF8D40 (r3)---> (I understand)
andi. r0, r0, 0x1000 #Your desired button(s)-------> (Here's where you start to lose me. At this point r0 should be holding 0x1000 if pressed)

lis r3, 0x8000 #Before taking the branch, set r3 to its new value, upper 16 bits of EVA---> (I understand)

bne- button_has_been_pressed ----> (If r0 is holding 0x1000, and we AND it with 0x1000 shouldn't this be a beq- button_has_been_pressed?)

???Because they are equal, your code as it's written brings it to the next line:
I understand what the rest of it is doing pretty much, it's just the andi. conditional part and the bne- button_has_been_pressed that has me puzzled???

li r0, 0 #Nothing Pressed, Reset Button Status
stb r0, 0x3FF (r3)
blr #End C0

button_has_been_pressed: #Button Pressed, Adjust Button Status
lbz r0, 0x3FF (r3) #0 = Not Pressed #1 = Pressed
cmpwi r0, 1
beqlr- #End C0
li r0, 1
stb r0, 0x3FF (r3)


lbz r5, 0x03FE (r3) #Update Pin Config tracker
addi r5, r5, 1
cmplwi r5, 10 #Check if we went beyond 9

blt+ store_tracker
li r5, 0 #Reset tracker byte

store_tracker:
stb r5, 0x03FE (r3)


Now I think I understand what the blr's are doing. simply going to the next instruction in the LR, which is the next instruction after the C0 insert, which effectively ends the C0.

Is this correct?

Which btw, when you do a C0, where exactly in memory is it writing the code being inserted? Is this a static place where the code handler stores it?

Another question, right off the bat you begin using r3 and r5? Why those and not r12 and r11?

Thanks for your help!
Got to untie this brain knot.
Reply
#74
(12-28-2021, 08:10 PM)Hackwiz Wrote: I understand the 06 serial write. Pretty slick.
I'm assuming this would be a great way to replace in game text???

Ye you could write over some in-game ASCII using 06 codetype. 06 String Writes can also be used to write over a set of instructions in static memory, or create a lookup table for another code (like in our case with the C0 code using the contents of the 06 code as a lookup table for the Pin Configs)

(12-28-2021, 08:10 PM)Hackwiz Wrote: andi. r0, r0, 0x1000 #Your desired button(s)-------> (Here's where you start to lose me. At this point r0 should be holding 0x1000 if pressed)

lis r3, 0x8000 #Before taking the branch, set r3 to its new value, upper 16 bits of EVA---> (I understand)

bne- button_has_been_pressed ----> (If r0 is holding 0x1000, and we AND it with 0x1000 shouldn't this be a beq- button_has_been_pressed?)

???Because they are equal, your code as it's written brings it to the next line:
I understand what the rest of it is doing pretty much, it's just the andi. conditional part and the bne- button_has_been_pressed that has me puzzled???

To understand why we are using andi. and why we are AND'ing against the vallue 0x1000, you will need to visualize your button activators as binary values (which is what they actually are). Let's go over all the button activator values for Wii-Remote.

0x0001 = Left
0x0002 = Right
0x0004 = Down
0x0008 = Up
0x0010 = +
0x0100 = 2
0x0200 = 1
0x0400 = B
0x0800 = A
0x1000 = -
0x2000 = Z
0x4000 = C
0x8000 = Home

Each of these values represents a bit that is flipped high. No two buttons can use the same single bit, this is how every button activator can have a different hex value. Whenever you press a Button, its bit will be flipped high. If you press multiple Buttons, multiple bits will be flipped high thus creating a new unique Hex value that isn't on the list above.

So a word has 32 total bits. However, for controller activators (buttons) we are using Halfwords instead. Thus we are only working with 16 bits (bits 0 thru 15). Let's convert the Hex values to Binary and view the list now.

Bit 15 = Left
Bit 14 = Right
Bit 13 = Down
Bit 12 = Up
Bit 11 = +
Bit 10 = Not on list (unused)
Bit 9 = Not on list (unused)
Bit 8 = Not on list (unused)
Bit 7 = 2
Bit 6 = 1
Bit 5 = B
Bit 4 = A
Bit 3 = -
Bit 2 = Z
Bit 1 = C
Bit 0 = Home

Broadway uses what is called Big Endian mode. So if you are viewing any value, it's first bit (the most left) is bit 0.

Side note: Little Endian is a nightmare and I thank the overlords every day that Broadway is natively Big Endian  Shy

Anyway getting back on the topic, whenever you press the Minus Button in your Bowling game the Halfword value at address 0x80708D40 gets its Bit 3 flipped high. If you are viewing that Halfword in Dolphin-memory-engine, you will see the value 0x1000 appear. Now if you press 3 buttons at the same time. Let's say C, Minus, and Right. That means Bits 1, 3, and 14 of the Halfword will all be flipped high. This will produce a Hex value of 0x5002. That's because the binary form is 0101 0000 0000 0010. The 0100 converts to the Hex digit 5, and 0010 converts to 2. Any case of 0000 converts to 0 ofc.

What the andi. instruction is doing is checking if Bit 3 of that Halfword (minus button bit) is flipped high. It doesn't matter what else is flipped high (what other buttons are pressed) as we are only concerned with bit 3 (0x1000).

The dot in 'andi.' is a free use of cmpwi rD, 0. Which in this case is - cmpwi r0, 0.

If bit 3 was high, then the result (r0) of the andi. instruction will be a NON-zero value. If it is, we know for 100% fact, the minus button was AT LEAST pressed (we don't care about the other bits/buttons). If the andi. instruction resulted with r0 equaling zero, then we know for 100% fact bit 3 was not high.

(12-28-2021, 08:10 PM)Hackwiz Wrote: Now I think I understand what the blr's are doing. simply going to the next instruction in the LR, which is the next instruction after the C0 insert, which effectively ends the C0.

Is this correct?

Yes.

(12-28-2021, 08:10 PM)Hackwiz Wrote: Which btw, when you do a C0, where exactly in memory is it writing the code being inserted? Is this a static place where the code handler stores it?

This always varies. Depends on how many codes you have equipped, which version of the Code Handler you are using, where the C0 code(s) are in your GCT/Cheat-manager.

(12-28-2021, 08:10 PM)Hackwiz Wrote: Another question, right off the bat you begin using r3 and r5? Why those and not r12 and r11?

C0 Code Safety is much different than C2 Code Safety. Whenever the Gecko Code Handler is executing any C0 code at that moment in time, certain Registers are 100% safe due to how the source of the Handler was written. r0, r3, r5, and r9 thru r12 are all safe for the latest version of the Code Handler (which is what almost all applications use). I prefer to use the lower registers, just because of habit I guess. It may be best if you understood how the Code Handler actually runs. An HBC app (such as USB Loader GX) reads the Hooktype and Ocarina settings of the app. If Ocarina is turned On, then the Code Handler's source (as a binary file) is placed into Memory. It's usually 'injected' at address 0x800018A8. However you need a method to branch to the Code Handler for it to be executed, this is where the Hooktype comes into play.

For example, if you choose GXDraw, the HBC app will find the GXDraw function of the Wii game (every Wii game has one) and will 'hook' the Code Handler to a specific address of the GXDraw function. Think of the Code Handler like a giant C2 code per say. At a certain address in GXDraw a branch instruction is placed there and it will jump to 0x800018A8 to execute the Code handler. Whenever the Code Handler is done is will jump back to GXDraw. The HBC app will also take the GCT contents that are on your SD card (/codes/xxxxXX.gct) and place those into memory (the spot in Memory is 'hardcoded' by the HBC app to comply with what the Code Handler requires, it's usually at 0x80002338).

The Code Handler is first ran whenever the game runs GXDraw for the first time after boot. The Code Handler will look in memory for the GCT contents (that was placed there by the HBC app), it will check for a proper GCT header and format. It will attempt to decipher your codes based on their Gecko Codetypes. The codes are executed in a 'top to bottom' fashion. Whenever the Code Hanlder encounters C0 code(s) the Code Handler will execute those as a subroutine. The Code Handler will place the current C0 code's address into r15 and branch to it like so...

Code:
mtlr r15
blrl

Every time the game calls the GXDraw function, it will re-run the Code handler again. This is why basic  RAM Writes (without the use of any if-statements and terminators) will always rewrite themselves. GXDraw gets called by any Wii Game every frame. Thus GXDraw executes 60 times per second. Therefore the Code Handler executes 60 times per second.

Obviously with any C0 code if you need to use the Link Register, you will need to back it up and restore it at some point in your C0 code. Or else the execution of the CPU/Broadway will not re-route back to the Gecko Code Handler, and your game will crash.

More info on C0's - https://mariokartwii.com/showthread.php?tid=1156
Reply
#75
Excellent explanation. There was apparently much more to the button activators than I thought.

Playing around with 06 code type last night with Pokemon Colosseum (GCN).

Naturally, the addresses where your items are stored changes with each new boot up. So I was using a save state for a playground.

I was trying out the 06 code type with the item list. When you start a new game, you have around 9 items on your list e.g. healing items, weapons etc...
Conveniently, the item and quantity are written as such 0x00XX00YY in one are sequentially.
XX = Item
YY = Quantity

I went through the items one by one and found there are a total of 257 items. There may be more??? Gotta find 'em all right?

So this here code gives you every item in the item list with a quantity of 99. Lol!!!!

0646E58C 00000408
00010063 00020063
00030063 00040063
00050063 00060063
00070063 00080063
00090063 000A0063
000B0063 000C0063
000D0063 000E0063
000F0063 00100063
00110063 00120063
00130063 00140063
00150063 00160063
00170063 00180063
00190063 001A0063
001B0063 001C0063
001D0063 001E0063
001F0063 00200063
00210063 00220063
00230063 00240063
00250063 00260063
00270063 00280063
00290063 002A0063
002B0063 002C0063
002D0063 002E0063
002F0063 00300063
00310063 00320063
00330063 00340063
00350063 00360063
00370063 00380063
00390063 003A0063
003B0063 003C0063
003D0063 003E0063
003F0063 00400063
00410063 00420063
00430063 00440063
00450063 00460063
00470063 00480063
00490063 004A0063
004B0063 004C0063
004D0063 004E0063
004F0063 00500063
00510063 00520063
00530063 00540063
00550063 00560063
00570063 00580063
00590063 005A0063
005B0063 005C0063
005D0063 005E0063
005F0063 00600063
00610063 00620063
00630063 00640063
00650063 00660063
00670063 00680063
00690063 006A0063
006B0063 006C0063
006D0063 006E0063
006F0063 00700063
00710063 00720063
00730063 00740063
00750063 00760063
00770063 00780063
00790063 007A0063
007B0063 007C0063
007D0063 007E0063
007F0063 00800063
00810063 00820063
00830063 00840063
00850063 00860063
00870063 00880063
00890063 008A0063
008B0063 008C0063
008D0063 008E0063
008F0063 00900063
00910063 00920063
00930063 00940063
00950063 00960063
00970063 00980063
00990063 009A0063
009B0063 009C0063
009D0063 009E0063
009F0063 00A00063
00A10063 00A20063
00A30063 00A40063
00A50063 00A60063
00A70063 00A80063
00A90063 00AA0063
00AB0063 00AC0063
00AD0063 00AE0063
00AF0063 00B00063
00B10063 00B20063
00B30063 00B40063
00B50063 00B60063
00B70063 00B80063
00B90063 00BA0063
00BB0063 00BC0063
00BD0063 00BE0063
00BF0063 00C00063
00C10063 00C20063
00C30063 00C40063
00C50063 00C60063
00C70063 00C80063
00C90063 00CA0063
00CB0063 00CC0063
00CD0063 00CE0063
00CF0063 00D00063
00D10063 00D20063
00D30063 00D40063
00D50063 00D60063
00D70063 00D80063
00D90063 00DA0063
00DB0063 00DC0063
00DD0063 00DE0063
00DF0063 00E00063
00E10063 00E20063
00E30063 00E40063
00E50063 00E60063
00E70063 00E80063
00E90063 00EA0063
00EB0063 00EC0063
00ED0063 00EE0063
00EF0063 00F00063
00F10063 00F20063
00F30063 00F40063
00F50063 00F60063
00F70063 00F80063
00F90063 00FA0063
00FB0063 00FC0063
00FD0063 00FE0063
00FF0063 01010063
01020063 00000000
E0000000 80008000

I'm probably going to have ??? in regards to the code handler and that game. It gets mighty pissed off when you tinker with it.
Had to quickly activate/deactivate the above code so it wouldn't bring the game to it's knees. Yes, I know it is constantly writing that string,
But like I said, the game doesn't like playing with the code handler and button activators.

Now to study the button activator explanation you gave above.

Thanks!!!!!!!
Reply
#76
This is why I wasn't getting it. I missed this fine detail:

"The dot in 'andi.' is a free use of cmpwi rD, 0. Which in this case is - cmpwi r0, 0."

Now it makes perfect sense.
Reply
#77
(12-29-2021, 02:00 PM)Hackwiz Wrote: I'm probably going to have ??? in regards to the code handler and that game. It gets mighty pissed off when you tinker with it.
Had to quickly activate/deactivate the above code so it wouldn't bring the game to it's knees. Yes, I know it is constantly writing that string,
But like I said, the game doesn't like playing with the code handler and button activators.

Now to study the button activator explanation you gave above.

Thanks!!!!!!!

Just an fyi: Always make sure your final assumptions & analysis are done on Real Hardware in regards to any Code testing. Dolphin may botch a code that works perfectly fine on Real Hardware.

Addressing your large 06 write, it may be best to write it as a C0 with standard button activation. Like this...

Code:
lis r3, 0xXXXX #Upper 16 bits of Controller Halfword Address
lhz r0, 0xXXXX (r3) #Load the Button Halfword
andi. r0, r0, 0xZZZZ #Check if activator was at least hit
beqlr+ #If activator not hit, end C0. Branch is most likely to occur, hence the plus symbol

#Setup a Loop to write out every Item and its Quantity
lis r3, 0x8046
ori r3, r3, 0xE588 #8046E58C minus 4

#Set the Loop amount
li r0, 0x102
mtctr r0

#Set the Item Quantity (it's the same for every type of Item)
li r5, 0x63 #99; do NOT use r0 as we will be doing addis instruction execution in the upcoming loop

#Loop
#Add Immediate Shift to set the current Item Value, then store ItemValue+Quantity word to its appropriate spot in Memory
loop:
addis r5, r5, 0x0001 #0x00010063 then 0x00020063 then 0x00030063, etc etc
stwu r5, 0x4 (r3)
bdnz+ loop

#All Done; end C0
#blr #Uncomment if NOT compiling with PyiiASMH, adjust compiled code accordingly to make it a working C0 code

Compiled code:
C0000000 00000007
3C60XXXX A003XXXX #XXXXXXXX = Controller button halfword address
7000ZZZZ 4DA20020 #ZZZZ = activator
3C608046 6063E588
38000102 7C0903A6
38A00063 3CA50001
94A30004 4200FFF8
4E800020 00000000

Due to how the source is written and I see that this is a GCN game (thus uses GCN controller), if the activator isn't working (you don't see the updates in Dolphin-memory-engine of items and quantity) be sure the ZZZZ values are the Wavebird ZZZZ values. https://mariokartwii.com/showthread.php?tid=44

XXXXXXXX = The controller button halfword address for Pokemon Colosseum (GCN). No idea what this is personally. So if the lower 16 bits of this address exceed 0x7FFF, be sure to do the sign extend trick

Example of sign extend trick for example address 0x80808CCC #8CCC is > than 7FFF

Code:
lis r3, 0x8081 #Add 1 to upper 16 bits
lhz r0, 0xFFFF8CCC (r3) #Sign extend the lower 16 bits

Btw the C0 code is setup to where if you press the activator, the items+quantities are applied but they are NOT re-applied when you let go of the activator. So if you need to re-update them again (let's say the Game wipes them later), press the activator again.
Reply
#78
I spent quit a bit of time tonight just organizing what can go where in the items menu.
Just writing all the items to memory in one clean sweep isn't really beneficial, as you can only carry so many things.

Took care of the dynamic memory problem:

F6000002 80408041 #Set pointer to beginning of item tables
00160002 000D0005
000E0002 000F0002
E0000000 80008000

Now to organize the serial writes to the acceptable ranges and values.

Then on to the button activator part...because this game is being a dick!
Everything I've done in the past that has worked, is not working here.

Will check out your C0 button code above tomorrow.

For tonight, that's enough!!!!
Reply
#79
Can you explain more about the Button Activator issue?

Is the game not recognizing your code when you press the Activator? Or is it inconsistent? Will the Code activate, but not de-activate?

Did you 'make' the Activators yourself or did you find the values on some other site?
Reply
#80
Sorry for not responding sooner.
I spent the morning organizing the items and their proper placement. i.e. Poke Balls in the Balls folder, Key Items in the Key items folder etc...
Here is the "Good" pointer/serial (F6/16) code:

f6000002 80408041
00160002 000d0005
000e0002 000f0002
16000000 000000d0
00130063 00140063
00150063 001d0063
001e0063 001f0063
00200063 00210063
00220063 00230063
00240063 00250063
00260063 00270063
00280063 00290063
002a0063 002b0063
002c0063 002d0063
01f40063 01f50063
01f60063 01f70063
01f80063 01f90063
01fa0063 01fb0063
01fc0063 01fd0063
01fe0063 01ff0063
02000063 02010063
02020063 02030063
02040063 02050063
02060063 02070063
02080063 02090063
020a0063 020b0063
020c0063 020d0063
020e0063 020f0063
02100063 02110063
02120063 02130063
160000fc 000001f0
00010063 00020063
00030063 00040063
00050063 00060063
00070063 00080063
00090063 000a0063
000b0063 000c0063
00000000 00000000
00000000 00000000
01210063 01220063
01230063 01240063
01250063 01260063
01270063 01280063
01290063 012a0063
012b0063 012c0063
012d0063 012e0063
012f0063 01300063
01310063 01320063
01330063 01340063
01350063 01360063
01370063 01380063
01390063 013a0063
013b0063 013c0063
013d0063 013e0063
013f0063 01400063
01430063 01440063
01450063 01460063
01470063 01480063
01490063 014a0063
014b0063 014c0063
014d0063 014e0063
014f0063 01500063
01510063 01520063
01530063 01540063
01550063 01560063
01570063 01580063
01590063 015a0063
015b0063 015c0063
015d0063 015e0063
015f0063 01600063
01610063 00000000
00850063 00860063
00870063 00880063
00890063 008a0063
008b0063 008c0063
008d0063 008e0063
008f0063 00900063
00910063 00920063
00930063 00940063
00950063 00960063
00970063 00980063
00990063 009a0063
009b0063 009c0063
009d0063 009e0063
009f0063 00a00063
00a10063 00a20063
00a30063 00a40063
00a50063 00a60063
00a70063 00a80063
00a90063 00aa0063
00ab0063 00ac0063
00ad0063 00ae0063
e0000000 80008000

The reason it may be advantageous to do it this way is because there are way more items available than slots for them.
The player may want to create their own item configurations.
The above works great (Dolphin) if you just activate/deactivate the code like I mentioned before.

!!!!!! I love that F6 code. Smile

Which leads to...the button activator.

Ugh!!!!!!!!

I did a half word search for the Z button 0x0010
Found four addresses alternating between 0x0 and 0x10 when z pressed and released.
Created a 28XXXXXX 00000010
And placed it on top of the above code.
Made sure code was active when booting up.
At the Nintendo screen, dolphin may or may not break with an error. I'll click ignore for this session., and
the game continues to boot up.
I know how to find the items memory block in one search, so I can monitor whether the code is working or not
early on.
Pressing the Z button has no effect, and if press enough times will cause dolphin to shut down immediately.
I tried this with all four activator addresses...same thing.
I tried changing endian on the compare...no Bueno.
I ran a search on the button activator address in the dolphin cheat search, and it showed the value for the Z button
to be the same, 0x10.

Apparently I went back to the well one too many times. After dolphin slammed shut one of the times, it apparently corrupted my
cheat manager code file for the game.
On next reboot, all my saved cheats were gone. Grrrrrrrrr!!!

Luckily I'm documenting the good things here to go back to.

So, what have you been up to?

Happy New Year!!!!!!
Reply


Forum Jump:


Users browsing this thread: 6 Guest(s)