ScrollingMenu
This is the only menu that does scrolling. It doesn't draw any Textbox
around the menu.
Structure:
.MenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 2, 4, SCREEN_WIDTH - 1, 13
dw .MenuData
db 1 ; default option
.MenuData:
db 0 ; flags
db 5, 0 ; rows, columns
db SCROLLINGMENU_ITEMS_NORMAL ; item format
dba Items
dba Function1
dba Function2
dba Function3
wMenuDataFlags
:
7: Select is functional
6: Start is functional
5: Call Function3
4: Show arrows on the right-hand side
3: D-Left is functional
2: D-Right is functional
1: Call Function3 only if [wSwitchItem] is 0
0: Call Function1 to display the cancel entry
If the columns entry in MenuData
of a scrolling menu is 0, Function2
isn't called either. It doesn't affect the position of the arrows.
Call state for functions in MenuData
of ScrollingMenu
:
All of them:
[wMenuSelection] = Current item. -1 is the CANCEL item.
[wMenuSelectionQuantity] = Quantity of the current item.
Function1: Called to display a menu entry.
de = Cursor position in TileMap
Function2: Called to display the quantity of a menu entry.
de = Cursor position in TileMap + columns
Function3: Called to display anything else, whenever the cursor is moved.
There is no register of importance that should be preserved in any of these functions.
The ; item format
entry in each MenuData
changes how the Items
struct looks.
If it's SCROLLINGMENU_ITEMS_NORMAL
(1):
db entries not including cancel
db entry1
db entry2
db -1 ; cancel
...
If it's SCROLLINGMENU_ITEMS_QUANTITY
(2):
db entries not including cancel
db entry1, quantity1
db entry2, quantity2
db -1 ; cancel
...
In case it's 1, [wMenuSelectionQuantity]
will simply contain the next entry.
_2DMenu
This, like is implied by the name, is a 2-dimensional menu, where you can move your cursor in all 4 directions. It's only used for the battle menus as well as Earl's academy.
Structure:
.MenuHeader:
db MENU_BACKUP_TILES ; flags
db 12, 08 ; start coords
db 17, 19 ; end coords
dw .MenuData
db 1 ; default option
.MenuData:
db STATICMENU_CURSOR ; flags
dn 2, 2 ; rows, columns
db 6 ; spacing
dba Strings
dba Function
wMenuDataFlags
:
7: Leave one tile of spacing between the left textbox border and the text, enabling the cursor.
6: Don't leave one tile of spacing between the top textbox border and the text
5: Set bits 4 and 5 in w2DMenuFlags1 (Wrap around horizontally and vertically)
4: Unused
3: Unused
2: Unused
1: Select is functional
0: Disable B button
The bank for the Strings
is generated when you call _2DMenu
, and as such it doesn't really matter what bank you specify there (unless you callba _2DMenu_
directly, of course).
; spacing
is not a misnomer here, it's used to define how much space there is between columns.
Function
is called after printing all the strings. hl
will be pointed at the row below the last in the menu in TileMap
. We don't know of its purpose, since it's never actually used anywhere. Only the bank number is always set to the same bank as the menu, but not used otherwise, since the address is 0.
DoNthMenu
/SetUpMenu
These are like the regular VerticalMenu
, except they allow for creating slightly more "dynamic" menus, where the options aren't predefined, much like the ScrollingMenu
.
Structure:
.MenuHeader:
db MENU_BACKUP_TILES ; flags
menu_coords 0, 0, 10, 7
dw .MenuData
db 1 ; default option
.MenuData:
db STATICMENU_CURSOR | STATICMENU_DISABLE_B ; flags
db 0 ; items
dw Items
dw DisplayFunction
dw StringPointers
wMenuDataFlags
:
7: Unused
6: Unused
5: Set bit 5 in w2DMenuFlags1 (Wrap around vertically)
4: Unused
3: Start is functional
2: D-left and D-right are functional
1: Unused
0: Unused
The ; items
entry should be left empty, as it's autogenerated with the Items
array in GetMenuIndexSet
.
The bottom coord (07
in the example) is autogenerated regardless of what you specify when building the MenuBox in AutomaticGetMenuBottomCoord
, which also calculates the bc
passed to MenuBox, which is useless because it's calculated again by MenuBox in GetMenuBoxDims
.
[wWhichIndexSet]
decides which menu is used through GetMenuIndexSet
. You can define multiple menus at the Items pointer as such:
Items:
db entries not including cancel
db entry1, entry2, entry3
db -1 ; cancel
db entries not including cancel for 2nd menu
db entry1, entry2, entry3, entry4
db -1 ; cancel
This is actively used in MainMenu
.
StringPointers
isn't handled by DoNthMenu
internally. It's handled by different DisplayFunction
s. A custom one could choose to completely ignore it.
StringPointers
struct handled through PlaceNthMenuStrings
as DisplayFunction
and MenuJumptable
:
StringPointers:
dw FunctionToCall, PointerToString ; index 1
dw FunctionToCall, PointerToString ; index 2
...
StringPointers
struct handled through PlaceMenuStrings
:
StringPointers:
db "STRING1@"
db "STRING2@"
...
Call state for DisplayFunction
:
[wMenuSelection] = Current item. -1 is the CANCEL item.
de = Cursor position in TileMap
VerticalMenu
This is the simplest menu. Like, the most boring. Nothing special. Just normal. …nooooooormal…
Structure:
.MenuHeader:
db MENU_SPRITE_ANIMS | MENU_BACKUP_TILES ; flags
menu_coords 12, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
dw .MenuData
db 1 ; default option
.MenuData:
db STATICMENU_CURSOR ; flags
db 2 ; # items
db "GIVE@"
db "TAKE@"
wMenuDataFlags
:
7: Leave one tile of spacing between the left textbox border and the text
6: Don't leave one tile of spacing between the top textbox border and the text
5: Set bit 5 in w2DMenuFlags1 (Wrap around vertically)
4: Place menubox "title". See notes.
3: Unused
2: Unused
1: Select is functional
0: Disable B button
If bit 4 is set, a string at the end of the items array will be put at an offset from the start coord of the menu box. This string is defined like this:
db 2 ; # items
db "GIVE@"
db "TAKE@"
db 2 ; x offset
db "TEST@"
This is used in the menu for selecting the character's name.
MenuHeader
flags (wMenuFlags
):
7: Save a backup of the tiles
6: Save a backup of the tiles
5: Unused
4: Set bit 6 in w2DMenuFlags1 (Enable sprite animations)
3: Disable click sound
2: Unused
1: Unused
0: Call RestoreTileBackup when exiting the menu. This bit depends on whether bit 6 or 7 are set.
w2DMenuFlags1
:
7: Disable checking of wMenuJoypadFilter
6: Enable sprite animations
5: Wrap around vertically
4: Wrap around horizontally
3: Set bit 7 in w2DMenuFlags2 and exit the loop if bit 5 is disabled and we tried to go too far down
2: Set bit 7 in w2DMenuFlags2 and exit the loop if bit 5 is disabled and we tried to go too far up
1: Set bit 7 in w2DMenuFlags2 and exit the loop if bit 4 is disabled and we tried to go too far left
0: Set bit 7 in w2DMenuFlags2 and exit the loop if bit 4 is disabled and we tried to go too far right
w2DMenuFlags2
:
7: ?????
6: ?????
5: ?????
4: ?????
3: ?????
2: ?????
1: ?????
0: ?????