• Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!

    You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!

Custom Debug Submenu Engine (for devs only)

Joined
Oct 10, 2011
Messages
1,126
Location
Boise, ID
NNID
dansalvato
This is how Achilles and I create our own debug menus in our respective mods. Rather than try to form-fit our menus to existing areas and functions in memory, this code lets us store arbitrary menus anywhere in memory and load them with a simple pointer.
Relevant and also useful is my debug menu documentation, found here.

Document

 

ssknight7

Smash Apprentice
Joined
Oct 8, 2014
Messages
136
I was actually thinking of writing a C# application that lets you build out the menu visually and outputs the corresponding code. This would probably be a big help.
 

_glook

Got a Passion for Smashin'
Joined
Sep 30, 2005
Messages
802
Location
Not UC Berkeley anymore
So when you guys make your toggles, say to "Stage Striking", are you basically doing this?
  • Set up a type 2 menu item, with string list for "Off" or "On"
  • Have a word in memory that holds the currently selected item (aka: The value of the currently-selected left/right item (points to a word, not a byte)). Let's say this memory address is 0x80555555.
  • Set 0x10 of that menu item (aka: Pointer to the value of the currently-selected left/right item (points to a word, not a byte)) to 0x80555555. We'll say that "Off" is 0 and "On" is 1.
  • Apply the Stage Striking DOL mod, except at the beginning of the ASM part (after the code already run is repeated), you read the value at 0x80555555. Insert a cmpwi on that for "0". beq to the end of the ASM part (effectively disabling stage striking if the value was set to "Off").
 

CeLL

Smash Lord
Joined
Jan 26, 2014
Messages
1,026
Location
Washington
So when you guys make your toggles, say to "Stage Striking", are you basically doing this?
  • Set up a type 2 menu item, with string list for "Off" or "On"
  • Have a word in memory that holds the currently selected item (aka: The value of the currently-selected left/right item (points to a word, not a byte)). Let's say this memory address is 0x80555555.
  • Set 0x10 of that menu item (aka: Pointer to the value of the currently-selected left/right item (points to a word, not a byte)) to 0x80555555. We'll say that "Off" is 0 and "On" is 1.
  • Apply the Stage Striking DOL mod, except at the beginning of the ASM part (after the code already run is repeated), you read the value at 0x80555555. Insert a cmpwi on that for "0". beq to the end of the ASM part (effectively disabling stage striking if the value was set to "Off").
When I made the MNCB debug menu I injected a function inside the function that leaves the debug menu that changed words in the RAM based on the toggle values. So using your example, I would inject the mod as normal, no modification, except leave the branch to the function out (unless you want it to be on by default, then add the branch). Then every time you leave the debug menu, it would check the word at 0x80555555, and if it is 0, write 981c0014 (the original code line) to 0x8025910C, and if it is 1, write 4BDA9824 (Sham Rock's branch) to 0x8025910C.

Sometimes this doesn't work in Dolphin, like the issue with 20XX (so I assume Achilles is doing the same method), so you'll have to add the flush cache on scene change code that Dan wrote and it should fix it.
 
Last edited:

Cyjorg

tiny.cc/19XXTE
Joined
Nov 18, 2013
Messages
686
Location
Purdue University
When I made the MNCB debug menu I injected a function inside the function that leaves the debug menu that changed words in the RAM based on the toggle values. So using your example, I would inject the mod as normal, no modification, except leave the branch to the function out (unless you want it to be on by default, then add the branch). Then every time you leave the debug menu, it would check the word at 0x80555555, and if it is 0, write 981c0014 (the original code line) to 0x8025910C, and if it is 1, write 4BDA9824 (Sham Rock's branch) to 0x8025910C.

Sometimes this doesn't work in Dolphin, like the issue with 20XX (so I assume Achilles is doing the same method), so you'll have to add the flush cache on scene change code that Dan wrote and it should fix it.
This is what I do as well and it works great
 

_glook

Got a Passion for Smashin'
Joined
Sep 30, 2005
Messages
802
Location
Not UC Berkeley anymore
Thanks, that works, but I was messing around, and it seems like the function pointer, which is 0x4 in the menu item, runs every time the item is changed, which is how the Language option is changed in debug main menu. Am I wrong about that? Because it seems that might be a little cleaner to manage, unless it's actually not easier to manage.
 
Joined
Oct 10, 2011
Messages
1,126
Location
Boise, ID
NNID
dansalvato
Thanks, that works, but I was messing around, and it seems like the function pointer, which is 0x4 in the menu item, runs every time the item is changed, which is how the Language option is changed in debug main menu. Am I wrong about that? Because it seems that might be a little cleaner to manage, unless it's actually not easier to manage.
It's usually not easier. It requires you to write an ASM function for every menu item that you want to have an effect, when usually all it takes is a 3-line Gecko code (If this address = 1, run this 04 code and endif)

If you want to disable that behavior of functions triggering when entering and changing menu items, I'm pretty sure this code does the trick.

Code:
Prevent button-press menu functions from running when entering menus
04302e00 4e800020
 

_glook

Got a Passion for Smashin'
Joined
Sep 30, 2005
Messages
802
Location
Not UC Berkeley anymore
It's usually not easier. It requires you to write an ASM function for every menu item that you want to have an effect, when usually all it takes is a 3-line Gecko code (If this address = 1, run this 04 code and endif)

If you want to disable that behavior of functions triggering when entering and changing menu items, I'm pretty sure this code does the trick.

Code:
Prevent button-press menu functions from running when entering menus
04302e00 4e800020
I see what you mean, you can just keep adding to one big function instead of creating a new function for each item.

Also, I don't know if you guys ran into this, but it seems to crash in Nintendont on Wii. I had to change the code to this to get it to work:
Code:
mflr r0
cmpwi r4, 0
bgt RETURN
lwz r4,0x14(r4)
stw r0,0x4(sp)
stwu sp,-0x8(sp)
lis r5,0x8030
ori r5,r5,0x1c80
lis r12,0x802f
ori r12,r12,0xfd94
mtctr r12
bctrl
lwz r0,0xc(sp)
addi sp,sp,8
mtlr r0
RETURN:
li r3,0
blr
Which gives me a hexcode of:
Code:
7C0802A6 2C040000 41810034 80840014
90010004 9421FFF8 3CA08030 60A51C80
3D80802F 618CFD94 7D8903A6 4E800421
8001000C 38210008 7C0803A6 38600000
4E800020
Looking at it now, I could probably move the mflr below the bgt to make it one instruction more efficient when r4 is 0x80000000 or greater.
 

Achilles1515

Smash Master
Joined
Jun 18, 2007
Messages
3,211
Location
Cincinnati / Columbus OH
I see what you mean, you can just keep adding to one big function instead of creating a new function for each item.

Also, I don't know if you guys ran into this, but it seems to crash in Nintendont on Wii. I had to change the code to this to get it to work:
Code:
mflr r0
cmpwi r4, 0
bgt RETURN
lwz r4,0x14(r4)
stw r0,0x4(sp)
stwu sp,-0x8(sp)
lis r5,0x8030
ori r5,r5,0x1c80
lis r12,0x802f
ori r12,r12,0xfd94
mtctr r12
bctrl
lwz r0,0xc(sp)
addi sp,sp,8
mtlr r0
RETURN:
li r3,0
blr
Which gives me a hexcode of:
Code:
7C0802A6 2C040000 41810034 80840014
90010004 9421FFF8 3CA08030 60A51C80
3D80802F 618CFD94 7D8903A6 4E800421
8001000C 38210008 7C0803A6 38600000
4E800020
Looking at it now, I could probably move the mflr below the bgt to make it one instruction more efficient when r4 is 0x80000000 or greater.
Interesting. Are you using the disable button press function from running on menu load code that Dan posted? I think I found out awhile back that the custom submenu code did not work on console without it (mainly returning to menus).

Still to this day there is a debug menu bug that surfaces sometimes that I have never figured out. It bugs the absolute living crap out of me.

So my menus are working perfectly and then I modify one of them and add a new item. Sure. Well then I go back into the debug menu and go into that menu and it looks great. But when I go back to the main menu and into a different set of submenus, after trying to go like 2 deep it will freeze when opening a menu.

The most annoying part is the way I fix the problem. If I go back into the menu I edited and delete a random line out of it, like a string line item of just spaces, then the entire menu system will work normal again. I just don’t understand it at all. I know there is nothing syntactically wrong with the edit I made to the menu because it shows up great, but somehow it affects the functioning of other menus.
 
Joined
Oct 10, 2011
Messages
1,126
Location
Boise, ID
NNID
dansalvato
Still to this day there is a debug menu bug that surfaces sometimes that I have never figured out. It bugs the absolute living crap out of me.

So my menus are working perfectly and then I modify one of them and add a new item. Sure. Well then I go back into the debug menu and go into that menu and it looks great. But when I go back to the main menu and into a different set of submenus, after trying to go like 2 deep it will freeze when opening a menu.

The most annoying part is the way I fix the problem. If I go back into the menu I edited and delete a random line out of it, like a string line item of just spaces, then the entire menu system will work normal again. I just don’t understand it at all. I know there is nothing syntactically wrong with the edit I made to the menu because it shows up great, but somehow it affects the functioning of other menus.
I have personally never run into this bug.
 

Achilles1515

Smash Master
Joined
Jun 18, 2007
Messages
3,211
Location
Cincinnati / Columbus OH
My gut instinct tells me it is just a general limitation/bug in the the way the Debug Menu is coded.

I was just messing with it.
My submenu was 21 items long. Trying to open a menu that leads to 3 more submenus caused the game to freeze. When it was 20 items long, everything worked fine.

I extended the length of the submenu in question to 26 lines. The 5 additional lines were strings of one character in length, a space (so a blank line on screen).

Now the menu works. It's so stupid.
 
Last edited:
Joined
Oct 10, 2011
Messages
1,126
Location
Boise, ID
NNID
dansalvato
I see. I don't have any submenus nearly that long, so that's probably a part of it. But I don't understand why it would work fine if you make the submenu longer, rather than shorter.
 

_glook

Got a Passion for Smashin'
Joined
Sep 30, 2005
Messages
802
Location
Not UC Berkeley anymore
Dunno if this is super useful but for peeps trying to do v1.00 debug menu shenanigans:

All "Data" in v1.00 is -0x1E90 from the v1.02 addresses.
All "Functions" in v1.00 is -0x189C from the v1.02 addresses.

The following code seems to work in v1.00 to load your own submenus:
Code:
mflr r0
cmpwi r4, 0
bgt RETURN
lwz r4,0x14(r4)
stw r0,0x4(sp)
stwu sp,-0x8(sp)

lis r5,0x8030
ori r5,r5,0x03e4

lis r12,0x802F
ori r12,r12,0xE4F8

mtctr r12
bctrl
lwz r0,0xc(sp)
addi sp,sp,8
mtlr r0
RETURN:
li r3,0
blr
 

flieskiller

Smash Journeyman
Joined
Jan 3, 2013
Messages
426
Is there an efficient way to have a debug menu page that only shows texts? I'd like to have a page that shows what changes I've added that isn't visible/obvious.
 

_glook

Got a Passion for Smashin'
Joined
Sep 30, 2005
Messages
802
Location
Not UC Berkeley anymore
Is there an efficient way to have a debug menu page that only shows texts? I'd like to have a page that shows what changes I've added that isn't visible/obvious.
It depends on what you mean by efficient. AFAIK, newlines don't work, so I just end up having one menu item per line of text, with the type set to 0.
 
Top Bottom