11 March 2016 - Forum Rules

Main Menu

Help with Overworld Menu ASM (SMRPG:LotSS)

Started by Yakibomb, April 10, 2016, 04:31:55 PM

Previous topic - Next topic


Hello! I'm new to this community, and I'm looking for some help with ASM hacking. I have some questions, but first let me explain what I'm doing.

I'm trying to understand how the menus are assembled in Super Mario RPG: Legend of the Seven Stars. However, while one of my goals is to document how the menus are assembled, my main goal is to change a certain menu.

This is the menu I want to change:

I want to increase the size of display box for the spells on the right to include 7 spells instead of 6. And if possible, shift the whole menu to increase it further to list 8 spells. However, I've run into some problems.

According to the documentation left by giangurgolo, the author of the main SMRPG editor Lazy Shell, he found where the data is stored for these menus, but not where the pointers are or how it's assembled. I don't know what is what. Here is what his documentation said:
030000 - 033FFF | ASM  | Windowing Assembly
034165 - 0341AA | TXT  | Alphanumeric Text
035000 - 037FFF | ASM  | Windowing Assembly

Here is what I found:
- The game uses its own unique code format for menus (like battle animation scripts do).
- Text and counters are called to be displayed independently of each other, meaning they're both in separate lists. I have yet to find how counters are displayed.
- I found how the text is displayed, though. I think the text is enclosed in a code bracket. It display text in a list, with four bytes designating Xposition, Yposition, Palette, and Text Index. Giangurgolo built in a text editing tool for menu text, making it easy to locate what each text item's index is.
- And one step toward my main goal: I found the byte that controls how many spells are listed! However...

Here is my problem (and why I'm here):
- I don't know how to clear the WRAM to remove the seventh spell's display on the menu. What happens is the seventh spell will stay in the WRAM after it's loaded, which means it stays on the list, forever being displayed on that menu. I don't know what communicates to the WRAM.

What opcodes or instructions should I be looking for? What loads the menus into the RAM? Is there a special code that is the same for all SNES games, or does SMRPG have its own way of clearing/storing it?

Can someone give me some advice, or point me in the right direction? I'll try to provide as much info as I can. I've used Geiger's SNES9x debugger to find what loads when, and where those instructions lead to. Could I post them?

I thought getting help here would be better than trying to do this alone, oh and sorry if this is in the wrong section.

EDIT: I've made some progress, but I still don't know what clears the WRAM. (Or how to move the FP)



Thanks, I'll take a look at those.

EDIT: I found the notes showing the start of where all the pointers and functions are! But nothing on what each thing does, so my search isn't in vain.


Ohhhh I'll have to recheck this.  I had a pretty hefty hacking bit going on with SMRPG.  If I'm remembering right, there should be a function that loads a set of bytes that dictate the height/width of the menu.  I 'cannot' remember if the X/Y coordinates are stated before hand or actually WITH the data, but it should be fairly easy to extend the menus. 


$C3/32D3 64 9D       STZ $9D    [$00:009D]   A:3320 X:3320 Y:0000 P:envMxdIZc
$C3/32D5 9C 4E 09    STZ $094E  [$7E:094E]   A:3320 X:3320 Y:0000 P:envMxdIZc
$C3/32D8 A9 03       LDA #$03                A:3320 X:3320 Y:0000 P:envMxdIZc
$C3/32DA 8D A5 09    STA $09A5  [$7E:09A5]   A:3303 X:3320 Y:0000 P:envMxdIzc
$C3/32DD A2 4D 33    LDX #$334D              A:3303 X:3320 Y:0000 P:envMxdIzc ;Load pointer to Special Menu setup
$C3/32E0 86 60       STX $60    [$00:0060]   A:3303 X:334D Y:0000 P:envMxdIzc
$C3/32E2 20 0A 6F    JSR $6F0A  [$C3:6F0A]   A:3303 X:334D Y:0000 P:envMxdIzc

$C3/6F0A 08          PHP                     A:3303 X:334D Y:0000 P:envMxdIzc
$C3/6F0B E2 20       SEP #$20                A:3303 X:334D Y:0000 P:envMxdIzc
$C3/6F0D A6 60       LDX $60    [$00:0060]   A:3303 X:334D Y:0000 P:envMxdIzc
$C3/6F0F 7B          TDC                     A:3303 X:334D Y:0000 P:envMxdIzc
$C3/6F10 BF 00 00 C3 LDA $C30000,x[$C3:334D] A:0000 X:334D Y:0000 P:envMxdIZc ;Load how many windows on special menu
$C3/6F14 A8          TAY                     A:0003 X:334D Y:0000 P:envMxdIzc  --> PC boxes do NOT count in this selection.
$C3/6F15 E8          INX                     A:0003 X:334D Y:0003 P:envMxdIzc
$C3/6F16 DA          PHX                     A:0003 X:334E Y:0003 P:envMxdIzc
$C3/6F17 5A          PHY                     A:0003 X:334E Y:0003 P:envMxdIzc
$C3/6F18 C2 20       REP #$20                A:0003 X:334E Y:0003 P:envMxdIzc
$C3/6F1A BF 00 00 C3 LDA $C30000,x[$C3:334E] A:0003 X:334E Y:0003 P:envmxdIzc ;Load X/Y coordinates of 'Skill' box
$C3/6F1E 85 60       STA $60    [$00:0060]   A:5860 X:334E Y:0003 P:envmxdIzc
$C3/6F20 E2 20       SEP #$20                A:5860 X:334E Y:0003 P:envmxdIzc
$C3/6F22 BF 02 00 C3 LDA $C30002,x[$C3:3350] A:5860 X:334E Y:0003 P:envMxdIzc ;Load width of 'Skill' box
$C3/6F26 85 70       STA $70    [$00:0070]   A:580F X:334E Y:0003 P:envMxdIzc
$C3/6F28 BF 03 00 C3 LDA $C30003,x[$C3:3351] A:580F X:334E Y:0003 P:envMxdIzc ;Load height of 'Skill' box
$C3/6F2C 85 72       STA $72    [$00:0072]   A:580B X:334E Y:0003 P:envMxdIzc
$C3/6F2E 20 73 6E    JSR $6E73  [$C3:6E73]   A:580B X:334E Y:0003 P:envMxdIzc

This is basically the function for it.  It loads the pointer before hand and gets the data from Bank $C3 + Pointer.

If you're using Geiger's or anything, all you have to do is set an 'execute' breakpoint on C3:6F10 and you'll get the start of whichever boxes you need.  But yeah, I believe that's what you're looking for! 

Edit 2: Woops, you already got that bit.  If you use any kind of debugger, that's your best bet to figure everything out, otherwise you're basically jumping around in the dark at this point.  A lot of it is pretty basic to move around and such.  What exactly are you trying to arrange the menu to be like?  I could probably help further if I had a better outlook on what you're trying to do.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'


Oh, hey justin3009! I PMed you over on SMWC. Didn't even realize you were here on this site (or that you were the one who posted that thread stuffgnome showed me!).

On that ASM you posted, I had no idea the game works like that. How did you find that? I should say I'm still kind of a beginner at this. I literally started using Geiger's debugger not even a full week ago, so I'm sorry if I sound like a newbie.

This is the problem I have:

Selecting Mario views all his spells just fine. However, when I switch over to Toadstool...

The last spell lingers. If another member has 7 spells instead of Mario, that last spell will show the game's first usable ally spell. And switching to different characters does this:

Notice the last spell on the list.

If you want to give it a go yourself, you can enter these cheats to test it out:
C3374607 - Shows up to 7 spells on the list
C3:33510C - Increases width of box

Combine it with one of these:
7FF8107F - Gives Mario all his spells + Therapy (seven spells)
7FF824BF - Gives Toadstool all Mario's spells + Group Hug

Go into the debug room and talk to the Toad on the very left to add Toadstool. Enter these cheats below, start a new game and start walking through some room exits and you'll eventually land in the debug room.

And enter this code to open the overworld menu (alternatively, save the game and reload the file):

For some I can't heal with Therapy if it's the seventh spell right off the bat... For some reason, when I go straight to the Special menu, I can't use it, but when I into the Equip menu then the Special menu, I can use it. No idea why that is...

EDIT: Added codes for debug room and opening the overworld menu.

EDIT2: This is what the debugger spits out when a cursor selects a new ally in the Special ability menu:
$C3/3335 20 19 36    JSR $3619  [$C3:3619]   A:2001 X:0009 Y:44BC P:envMxdIZc

I followed the code after $C3/3338 and it apparently loads the boxes every time the game loads a new spell list? First let me show you what comes after, then I'll show you why I think it loads the boxes every time:
$C3/3335 20 19 36    JSR $3619  [$C3:3619]   A:0001 X:0078 Y:0597 P:envMxdIzc
$C3/3338 20 0C 2D    JSR $2D0C  [$C3:2D0C]   A:0001 X:0078 Y:0597 P:envMxdIzc
$C3/333B 20 64 2C    JSR $2C64  [$C3:2C64]   A:0001 X:0000 Y:10E3 P:envMxdIzC
$C3/333E 20 9A 0D    JSR $0D9A  [$C3:0D9A]   A:0001 X:0078 Y:0597 P:envMxdIzc
$C3/3341 20 11 0E    JSR $0E11  [$C3:0E11]   A:0001 X:0078 Y:0597 P:envMxdIzc
$C3/3344 20 C8 10    JSR $10C8  [$C3:10C8]   A:0001 X:0078 Y:0597 P:envMxdIzc
$C3/3347 20 86 05    JSR $0586  [$C3:0586]   A:0001 X:0078 Y:0597 P:envMxdIzc
***$C3/334A 82 D4 FF    BRL $FFD4  [$3321]      A:0001 X:0078 Y:0597 P:envMxdIzc

***After all the JSR commands, it starts to load the boxes. Observe:

82 D4
FF - New list (boxes)
C3:334D: 03 - Number of boxes
C3:334E-51: 60 58 0F 0B
C3:3352-5: 60 5B 0F 03
C3:3356-9: 20 5C 0F 0B

It continues:

C3:335A: 02 (Number of listed items)
C3:335B-E: A2 45 00 16 ("Flowers Used")
C3:335F-2: 26 46 00 17 ("Mg.Power")
C3:3363: 03 - New items list
C3:3364-7: 04 47 00 1C ("learns a new")
C3:3367-B: 84 47 00 1D ("technique at")
C3:336C-F: 08 48 00 0B ("Level")
C3:3370+: AD 31 09 (???) (I see this often, but I don't know what it does)

It's read like:
Each item uses 4 bytes:
Xpos/Ypos/Palette/Text index

Each counter listed uses 4 bytes:
Xpos/Ypos/Read two bytes/Counter

Each box uses 4 bytes

For whatever reason, the other things that display (Ally's name, number of Flowers/FP on the list, descriptions) show up in rather different places:
C3:32F9-A: A2 44 (xpos, ypox)
C3:32FB-D: 86 62 A9 (unknown, changing changes text index)
C3:32FE: 37 ("Flowers")
C3:32FF: 82 (unknown, changing changes text index)

C3:32F1-2: 22 5D (xpos, ypos)

- Ally Character's Name
C3:35A2-3: 88 46 (xpos,ypos)

- Current/Max FP
C3:35EB-C: B2 44 (xpos, ypos)
- Flower Used Counter
Haven't found it yet
- Mg.Attack Counter
C3:366E-F: 36 46 (xpos, ypos)


Huh, when I was trying to find the Flower Used counter I stumbled upon the code that removes them from view. Yippie! Now I know what I'm looking for.
C3:3633-4: A2 45 (I guess they're for xpos, ypos


C3:3741-2: A2 40 (xpos,ypos)


$C3/36FB A9 06       LDA #$06                A:0000 X:0000 Y:FB80

Setting this to 07 will erase all seven spells on the list when moving to a new character on the screen AND this allows you to use seven spells too!  So now Therapy loads and can be used properly!  :)

If you have any questions on Geiger's or need any help whatsoever on your project, I'll do what I can to help ya out!  You may be new to Geiger's but you're at least showing you're willing to try and you're actually making really good progress right off the bat, so very big kudos to you!

Edit: Also, if you plan to stick around more on as well, I'm far more active on here than SMWCentral.  I check it periodically but not as much as I do with
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'


Yes! Thank you for finding that. I'm so happy it works now! :crazy:

I think I'll post my hack here, it seems like I'll get more feedback + I can get more technical about things I need help with. SMWC is all cozy but it's very isolated.

I'll submit my information about the overworld values to both Just gotta find a few more things and it'll be ready! :)