summaryrefslogtreecommitdiff
path: root/src/engine/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/menu.c')
-rw-r--r--src/engine/menu.c871
1 files changed, 871 insertions, 0 deletions
diff --git a/src/engine/menu.c b/src/engine/menu.c
new file mode 100644
index 000000000..ef458124b
--- /dev/null
+++ b/src/engine/menu.c
@@ -0,0 +1,871 @@
+#include "global.h"
+#include "menu.h"
+#include "main.h"
+#include "map_obj_lock.h"
+#include "menu_cursor.h"
+#include "script.h"
+#include "songs.h"
+#include "sound.h"
+#include "strings.h"
+#include "text.h"
+#include "text_window.h"
+#include "string_util.h"
+
+struct Menu
+{
+ u8 left;
+ u8 top;
+ s8 cursorPos;
+ s8 minCursorPos;
+ s8 maxCursorPos;
+ u8 width;
+ u8 height;
+ u8 menu_field_7;
+ u8 columnXCoords[8];
+};
+
+static void MultistepInitMenuWindowInternal(const struct WindowConfig *, u16);
+static void InitMenuWindowInternal(const struct WindowConfig *, u16);
+static bool8 sub_80723D4(void);
+static u8 sub_8072484(u8, u8, u8, u8, u8, u8, u32);
+static u8 sub_80724F4(u8, u8, u8, const struct MenuAction[], u8);
+static void sub_8072620(u8, u8, u8, const struct MenuAction[], u8);
+static void sub_8072D18(u8, u8);
+
+static struct Menu gMenu;
+
+EWRAM_DATA struct Window gMenuWindow = {0};
+EWRAM_DATA u8 gFiller_202E908[0x90] = {0};
+EWRAM_DATA struct Window *gMenuWindowPtr = NULL;
+EWRAM_DATA u8 gMenuMultistepInitState = 0;
+EWRAM_DATA u16 gMenuTextTileOffset = 0;
+EWRAM_DATA u16 gMenuTextWindowTileOffset = 0;
+EWRAM_DATA u16 gMenuTextWindowContentTileOffset = 0;
+EWRAM_DATA u16 gMenuMessageBoxContentTileOffset = 0;
+
+const struct MenuAction gMenuYesNoItems[] =
+{
+ { OtherText_Yes, NULL },
+ { OtherText_No, NULL },
+};
+
+void CloseMenu(void)
+{
+ PlaySE(SE_SELECT);
+ MenuZeroFillScreen();
+ sub_8064E2C();
+ ScriptContext2_Disable();
+ HandleDestroyMenuCursors();
+}
+
+void AppendToList(u8 *list, u8 *pindex, u32 value)
+{
+ list[*pindex] = value;
+ (*pindex)++;
+}
+
+void InitMenuWindow(const struct WindowConfig *winConfig)
+{
+ InitMenuWindowInternal(winConfig, 1);
+}
+
+void MultistepInitMenuWindowBegin(const struct WindowConfig *winConfig)
+{
+ MultistepInitMenuWindowInternal(winConfig, 1);
+}
+
+static void MultistepInitMenuWindowInternal(const struct WindowConfig *winConfig, u16 tileOffset)
+{
+ gMenuMultistepInitState = 0;
+ gMenuTextTileOffset = tileOffset;
+ gMenuWindowPtr = &gMenuWindow;
+ InitWindowFromConfig(&gMenuWindow, winConfig);
+}
+
+bool32 MultistepInitMenuWindowContinue(void)
+{
+ switch (gMenuMultistepInitState)
+ {
+ case 0:
+ gMenuMultistepInitState++;
+ return 0;
+ case 1:
+ gMenuTextWindowTileOffset = MultistepInitWindowTileData(gMenuWindowPtr, gMenuTextTileOffset);
+ goto next;
+ case 2:
+ if (!MultistepLoadFont())
+ goto fail;
+ goto next;
+ case 3:
+ gMenuTextWindowContentTileOffset = SetTextWindowBaseTileNum(gMenuTextWindowTileOffset);
+ next:
+ gMenuMultistepInitState++;
+ return 0;
+ case 4:
+ LoadTextWindowGraphics(gMenuWindowPtr);
+ gMenuMessageBoxContentTileOffset = SetMessageBoxBaseTileNum(gMenuTextWindowContentTileOffset);
+ return 1;
+ default:
+ fail:
+ return 0;
+ }
+}
+
+static void InitMenuWindowInternal(const struct WindowConfig *winConfig, u16 tileOffset)
+{
+ gMenuWindowPtr = &gMenuWindow;
+ InitWindowFromConfig(&gMenuWindow, winConfig);
+ gMenuTextTileOffset = tileOffset;
+ gMenuTextWindowTileOffset = InitWindowTileData(gMenuWindowPtr, gMenuTextTileOffset);
+ gMenuTextWindowContentTileOffset = SetTextWindowBaseTileNum(gMenuTextWindowTileOffset);
+ LoadTextWindowGraphics(gMenuWindowPtr);
+ gMenuMessageBoxContentTileOffset = SetMessageBoxBaseTileNum(gMenuTextWindowContentTileOffset);
+}
+
+void unref_sub_8071DA4(struct WindowConfig *winConfig, u16 tileOffset)
+{
+ gMenuWindowPtr = &gMenuWindow;
+ InitWindowFromConfig(&gMenuWindow, winConfig);
+ gMenuTextWindowTileOffset = tileOffset;
+ gMenuTextWindowContentTileOffset = SetTextWindowBaseTileNum(gMenuTextWindowTileOffset);
+ LoadTextWindowGraphics(gMenuWindowPtr);
+ gMenuTextTileOffset = SetMessageBoxBaseTileNum(gMenuTextWindowContentTileOffset);
+ gMenuMessageBoxContentTileOffset = InitWindowTileData(gMenuWindowPtr, gMenuTextTileOffset);
+}
+
+void MenuLoadTextWindowGraphics_OverrideFrameType(u8 frameType)
+{
+ LoadTextWindowGraphics_OverrideFrameType(gMenuWindowPtr, frameType);
+}
+
+void MenuLoadTextWindowGraphics(void)
+{
+ LoadTextWindowGraphics(gMenuWindowPtr);
+}
+
+void BasicInitMenuWindow(const struct WindowConfig *winConfig)
+{
+ InitWindowFromConfig(gMenuWindowPtr, winConfig);
+ gMenuWindowPtr->tileDataStartOffset = gMenuTextTileOffset;
+}
+
+void MenuPrint(const u8 *str, u8 left, u8 top)
+{
+ sub_8003460(gMenuWindowPtr, str, gMenuTextTileOffset, left, top);
+}
+
+void MenuZeroFillWindowRect(u8 a1, u8 a2, u8 a3, u8 a4)
+{
+ ZeroFillWindowRect(gMenuWindowPtr, a1, a2, a3, a4);
+}
+
+void MenuFillWindowRectWithBlankTile(u8 left, u8 top, u8 right, u8 bottom)
+{
+ FillWindowRectWithBlankTile(gMenuWindowPtr, left, top, right, bottom);
+}
+
+void MenuZeroFillScreen(void)
+{
+ MenuZeroFillWindowRect(0, 0, 29, 19);
+}
+
+void MenuDrawTextWindow(u8 left, u8 top, u8 right, u8 bottom)
+{
+ DrawTextWindow(gMenuWindowPtr, left, top, right, bottom);
+}
+
+void sub_8071F40(const u8 *str)
+{
+ MenuDrawTextWindow(2, 14, 28, 19);
+ MenuPrint(str, 3, 15);
+}
+
+void sub_8071F60(u8 a1, u8 a2, u8 a3)
+{
+ sub_8003490(gMenuWindowPtr, a1, gMenuTextTileOffset, a2, a3);
+}
+
+u16 unref_sub_8071F98(u8 x, u8 y)
+{
+ return GetWindowTilemapEntry(gMenuWindowPtr, x, y);
+}
+
+void unref_sub_8071FBC(u16 a1, u8 a2, u8 a3, u8 a4, u8 a5)
+{
+ DrawWindowRect(gMenuWindowPtr, a1, a2, a3, a4, a5);
+}
+
+void MenuDisplayMessageBox(void)
+{
+ DisplayMessageBox(gMenuWindowPtr);
+}
+
+void MenuPrintMessage(const u8 *str, u8 left, u8 top)
+{
+ sub_8002EB0(gMenuWindowPtr, str, gMenuTextTileOffset, left, top);
+}
+
+void sub_8072044(const u8 *str)
+{
+ sub_8002EB0(gMenuWindowPtr, str, gMenuTextTileOffset, 2, 15);
+}
+
+void MenuSetText(const u8 *str)
+{
+ sub_8002E90(gMenuWindowPtr, str);
+}
+
+u8 MenuUpdateWindowText(void)
+{
+ return sub_80035AC(gMenuWindowPtr);
+}
+
+u8 unref_sub_8072098(void)
+{
+ return sub_8003418(gMenuWindowPtr);
+}
+
+void sub_80720B0(void)
+{
+ ClearWindowTextLines(gMenuWindowPtr);
+}
+
+u8 MoveMenuCursor(s8 delta)
+{
+ s32 newPos = gMenu.cursorPos + delta;
+
+ if (newPos < gMenu.minCursorPos)
+ gMenu.cursorPos = gMenu.maxCursorPos;
+ else if (newPos > gMenu.maxCursorPos)
+ gMenu.cursorPos = gMenu.minCursorPos;
+ else
+ gMenu.cursorPos += delta;
+
+ RedrawMenuCursor(gMenu.left, 2 * gMenu.cursorPos + gMenu.top);
+ return gMenu.cursorPos;
+}
+
+u8 MoveMenuCursorNoWrap(s8 delta)
+{
+ s32 newPos = gMenu.cursorPos + delta;
+
+ if (newPos < gMenu.minCursorPos)
+ gMenu.cursorPos = gMenu.minCursorPos;
+ else if (newPos > gMenu.maxCursorPos)
+ gMenu.cursorPos = gMenu.maxCursorPos;
+ else
+ gMenu.cursorPos += delta;
+
+ RedrawMenuCursor(gMenu.left, 2 * gMenu.cursorPos + gMenu.top);
+ return gMenu.cursorPos;
+}
+
+u8 GetMenuCursorPos(void)
+{
+ return gMenu.cursorPos;
+}
+
+s8 ProcessMenuInput(void)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (gMenu.menu_field_7)
+ HandleDestroyMenuCursors();
+ return gMenu.cursorPos;
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ if (gMenu.menu_field_7)
+ HandleDestroyMenuCursors();
+ return -1;
+ }
+
+ if (gMain.newKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(-1);
+ return -2;
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor(1);
+ return -2;
+ }
+
+ return -2;
+}
+
+s8 ProcessMenuInputNoWrap(void)
+{
+ u8 cursorPos = gMenu.cursorPos;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ if (gMenu.menu_field_7)
+ HandleDestroyMenuCursors();
+ return gMenu.cursorPos;
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ if (gMenu.menu_field_7)
+ HandleDestroyMenuCursors();
+ return -1;
+ }
+
+ if (gMain.newKeys & DPAD_UP)
+ {
+ if (cursorPos != MoveMenuCursorNoWrap(-1))
+ PlaySE(SE_SELECT);
+ return -2;
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ if (cursorPos != MoveMenuCursorNoWrap(1))
+ PlaySE(SE_SELECT);
+ return -2;
+ }
+
+ MoveMenuCursorNoWrap(0);
+ return -2;
+}
+
+u8 MoveMenuCursor3(s8 delta)
+{
+ u8 menuHeight = (gMenu.maxCursorPos + 1) >> 1;
+ s32 newPos = gMenu.cursorPos + delta;
+
+ if (newPos < gMenu.minCursorPos)
+ gMenu.cursorPos = gMenu.maxCursorPos;
+ else if (newPos > gMenu.maxCursorPos)
+ gMenu.cursorPos = gMenu.minCursorPos;
+ else
+ gMenu.cursorPos += delta;
+
+ RedrawMenuCursor(
+ 6 * (gMenu.cursorPos / menuHeight) + gMenu.left,
+ 2 * (gMenu.cursorPos % menuHeight) + gMenu.top);
+
+ return gMenu.cursorPos;
+}
+
+u8 MoveMenuCursor4(s8 delta)
+{
+ if (gMenu.cursorPos + delta <= gMenu.maxCursorPos)
+ {
+ if (sub_80723D4() == TRUE)
+ return gMenu.cursorPos;
+ }
+ else
+ {
+ return gMenu.cursorPos;
+ }
+
+ gMenu.cursorPos += delta;
+
+ if ((gMenu.maxCursorPos + 1) / gMenu.width == 0)
+ RedrawMenuCursor(
+ gMenu.left + gMenu.columnXCoords[gMenu.cursorPos % gMenu.width],
+ 2 * ((gMenu.cursorPos / gMenu.width) % gMenu.height) + gMenu.top);
+ else
+ RedrawMenuCursor(
+ gMenu.left + gMenu.columnXCoords[gMenu.cursorPos % gMenu.width],
+ 2 * (gMenu.cursorPos / gMenu.width) + gMenu.top);
+
+ return gMenu.cursorPos;
+}
+
+static bool8 sub_80723D4(void)
+{
+ if ((gMain.newKeys & DPAD_UP) && gMenu.cursorPos < gMenu.width)
+ return TRUE;
+
+ if ((gMain.newKeys & DPAD_DOWN) && gMenu.cursorPos >= (gMenu.maxCursorPos + 1) - gMenu.width)
+ return TRUE;
+
+ if ((gMain.newKeys & DPAD_LEFT)
+ && ((gMenu.cursorPos - (gMenu.cursorPos % gMenu.width)) % gMenu.width == 1 // always false
+ || gMenu.cursorPos == 0
+ || gMenu.cursorPos % gMenu.width == 0))
+ return TRUE;
+
+ if ((gMain.newKeys & DPAD_RIGHT) && gMenu.cursorPos % gMenu.width == gMenu.width - 1)
+ return TRUE;
+
+ return FALSE;
+}
+
+static u8 sub_8072484(u8 a1, u8 a2, u8 menuItemCount, u8 a4, u8 width, u8 a6, u32 a7)
+{
+ u8 v7;
+
+ gMenu.width = width;
+ gMenu.height = menuItemCount / width;
+ InitMenu(0, a1, a2, menuItemCount, a4, a6);
+ v7 = 0;
+ if (a7)
+ v7 = -1;
+ gMenu.menu_field_7 = v7;
+ return a4;
+}
+
+static u8 sub_80724F4(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], u8 columnCount)
+{
+ u8 i;
+ u8 maxWidth;
+ s32 height;
+
+ for (i = 0; i < 7; i++)
+ gMenu.columnXCoords[i] = 0;
+
+ maxWidth = 0;
+ for (i = 0; i < menuItemCount; i++)
+ {
+ u8 width = (sub_8072CA4(menuItems[i].text) + 7) / 8;
+
+ if (width > maxWidth)
+ maxWidth = width;
+ }
+
+ for (i = 1; i <= columnCount; i++)
+ gMenu.columnXCoords[i] = maxWidth;
+
+ for (i = 1; i <= columnCount; i++)
+ gMenu.columnXCoords[i] += 1 + gMenu.columnXCoords[i - 1];
+
+ gMenu.columnXCoords[columnCount]--;
+
+ if (!((menuItemCount / 2) < columnCount || (menuItemCount % 2 != 0))
+ || columnCount == 1
+ || columnCount == menuItemCount)
+ {
+ height = 2 * (menuItemCount / columnCount) + 1;
+ }
+ else
+ {
+ height = 2 * ((menuItemCount / columnCount) + 1) + 1;
+ }
+
+ {
+ // TODO: Make this code less hideous but still match the original asm.
+ u8 right;
+ u8 bottom;
+ u32 totalWidth;
+ register s32 val asm("r1");
+
+ val = (s8)top + height;
+ val = val << 24;
+ asm("" ::: "r3");
+ bottom = val >> 24;
+
+ totalWidth = (gMenu.columnXCoords[columnCount] + 1);
+ right = left + totalWidth;
+
+ MenuDrawTextWindow(left, top, right, bottom);
+ }
+
+ return maxWidth;
+}
+
+static void sub_8072620(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], u8 columnCount)
+{
+ u8 i;
+ u8 maxWidth;
+
+ for (i = 0; i < 7; i++)
+ gMenu.columnXCoords[i] = 0;
+
+ maxWidth = 0;
+ for (i = 0; i < menuItemCount; i++)
+ {
+ u8 width = (sub_8072CA4(menuItems[i].text) + 7) / 8;
+
+ if (width > maxWidth)
+ maxWidth = width;
+ }
+
+ for (i = 1; i <= columnCount; i++)
+ gMenu.columnXCoords[i] = maxWidth;
+
+ for (i = 1; i <= columnCount; i++)
+ gMenu.columnXCoords[i] += 1 + gMenu.columnXCoords[i - 1];
+
+ gMenu.columnXCoords[columnCount]--;
+
+ for (i = 0; i < columnCount; i++)
+ {
+ u8 row = 0;
+ u8 j;
+ for (j = 0; i + j < menuItemCount; j += columnCount, row++)
+ MenuPrint(menuItems[i + j].text, left + gMenu.columnXCoords[i % columnCount], top + 2 * row);
+ }
+}
+
+void sub_807274C(u8 left, u8 top, u8 menuItemCount, u8 a4, const struct MenuAction menuItems[], u8 columnCount, u32 a7)
+{
+ u8 maxWidth = sub_80724F4(left, top, menuItemCount, menuItems, columnCount);
+
+ sub_8072484(left + 1, top + 1, menuItemCount, a4, columnCount, maxWidth, a7);
+ sub_8072620(left + 1, top + 1, menuItemCount, menuItems, columnCount);
+}
+
+s8 sub_80727CC(void)
+{
+ if (gMain.newKeys & A_BUTTON)
+ {
+ if (gMenu.menu_field_7)
+ HandleDestroyMenuCursors();
+ PlaySE(SE_SELECT);
+ return GetMenuCursorPos();
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ if (gMenu.menu_field_7)
+ HandleDestroyMenuCursors();
+ return -1;
+ }
+
+ if (gMain.newKeys & DPAD_UP)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor4(-gMenu.width);
+ return -2;
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor4(gMenu.width);
+ return -2;
+ }
+ else if (gMain.newKeys & DPAD_LEFT)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor4(-1);
+ return -2;
+ }
+ else if (gMain.newKeys & DPAD_RIGHT)
+ {
+ PlaySE(SE_SELECT);
+ MoveMenuCursor4(1);
+ return -2;
+ }
+
+ return -2;
+}
+
+u8 sub_807288C(u8 column)
+{
+ return gMenu.columnXCoords[column];
+}
+
+void PrintMenuItems(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[])
+{
+ u8 i;
+
+ for (i = 0; i < menuItemCount; i++)
+ MenuPrint(menuItems[i].text, left, top + 2 * i);
+}
+
+void PrintMenuItemsReordered(u8 left, u8 top, u8 menuItemCount, const struct MenuAction menuItems[], const u8 *order)
+{
+ u8 i;
+
+ for (i = 0; i < menuItemCount; i++)
+ MenuPrint(menuItems[order[i]].text, left, top + 2 * i);
+}
+
+void InitYesNoMenu(u8 left, u8 top, u8 a3)
+{
+ PrintMenuItems(left + 1, top + 1, 2, gMenuYesNoItems);
+ InitMenu(0, left + 1, top + 1, 2, 0, a3);
+}
+
+void DisplayYesNoMenu(u8 left, u8 top, u32 a3)
+{
+ MenuDrawTextWindow(left, top, left + 6, top + 5);
+ InitYesNoMenu(left, top, 5);
+ gMenu.menu_field_7 = a3 ? -1 : 0;
+}
+
+s8 ProcessMenuInputNoWrap_(void)
+{
+ return ProcessMenuInputNoWrap();
+}
+
+u8 MenuPrint_PixelCoords(const u8 *text, u8 left, u16 top, u8 a4)
+{
+ return sub_8004D04(gMenuWindowPtr, text, gMenuTextTileOffset, left, top, a4);
+}
+
+u8 sub_8072A18(const u8 *text, u8 left, u16 top, u8 width, u32 a5)
+{
+ return sub_8004FD0(gMenuWindowPtr, 0, text, gMenuTextTileOffset, left, top, width, a5);
+}
+
+u8 unref_sub_8072A5C(u8 *dest, u8 *src, u8 left, u16 top, u8 width, u32 a6)
+{
+ return sub_8004FD0(gMenuWindowPtr, dest, src, gMenuTextTileOffset, left, top, width, a6);
+}
+
+#if ENGLISH
+int sub_8072AB0(const u8 *str, u8 left, u16 top, u8 width, u8 height, u32 a6)
+{
+ u8 newlineCount = sub_8004FD0(gMenuWindowPtr, NULL, str, gMenuTextTileOffset, left, top, width, a6);
+
+ left /= 8;
+ top /= 8;
+ width = (width + 7) / 8;
+ height = (height + 7) / 8;
+
+ if (newlineCount < height)
+ MenuFillWindowRectWithBlankTile(left, top + 2 * newlineCount, left + width - 1, height + top - 1);
+}
+#elif GERMAN
+__attribute__((naked))
+int sub_8072AB0(const u8 *str, u8 left, u16 top, u8 width, u8 height, u32 a6)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ sub sp, 0x10\n\
+ mov r12, r0\n\
+ ldr r0, [sp, 0x24]\n\
+ ldr r4, [sp, 0x28]\n\
+ str r4, [sp, 0xC]\n\
+ lsls r1, 24\n\
+ lsrs r5, r1, 24\n\
+ lsls r2, 16\n\
+ lsrs r4, r2, 16\n\
+ lsls r3, 24\n\
+ lsrs r6, r3, 24\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+ ldr r0, _08072AF8 @ =gMenuWindowPtr\n\
+ ldr r0, [r0]\n\
+ ldr r1, _08072AFC @ =gMenuTextTileOffset\n\
+ ldrh r3, [r1]\n\
+ str r5, [sp]\n\
+ str r4, [sp, 0x4]\n\
+ str r6, [sp, 0x8]\n\
+ movs r1, 0\n\
+ mov r2, r12\n\
+ bl sub_8004FD0\n\
+ adds r1, r0, 0\n\
+ lsls r1, 24\n\
+ lsrs r2, r1, 24\n\
+ movs r3, 0x7\n\
+ ands r3, r5\n\
+ cmp r3, 0\n\
+ bne _08072B00\n\
+ adds r1, r6, 0x7\n\
+ asrs r1, 3\n\
+ subs r1, 0x1\n\
+ b _08072B0C\n\
+ .align 2, 0\n\
+_08072AF8: .4byte gMenuWindowPtr\n\
+_08072AFC: .4byte gMenuTextTileOffset\n\
+_08072B00:\n\
+ adds r3, r6, r3\n\
+ subs r1, r3, 0x1\n\
+ cmp r1, 0\n\
+ bge _08072B0A\n\
+ adds r1, r3, 0x6\n\
+_08072B0A:\n\
+ asrs r1, 3\n\
+_08072B0C:\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ adds r6, r1, 0\n\
+ lsrs r5, 3\n\
+ adds r1, r7, 0x7\n\
+ asrs r1, 3\n\
+ lsls r1, 24\n\
+ lsrs r7, r1, 24\n\
+ lsrs r4, 3\n\
+ cmp r2, r7\n\
+ bcs _08072B3E\n\
+ lsls r1, r2, 1\n\
+ adds r1, r4, r1\n\
+ lsls r1, 24\n\
+ lsrs r1, 24\n\
+ adds r2, r5, r6\n\
+ lsls r2, 24\n\
+ lsrs r2, 24\n\
+ adds r3, r7, r4\n\
+ subs r3, 0x1\n\
+ lsls r3, 24\n\
+ lsrs r3, 24\n\
+ adds r0, r5, 0\n\
+ bl MenuFillWindowRectWithBlankTile\n\
+_08072B3E:\n\
+ add sp, 0x10\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .syntax divided\n");
+}
+#endif
+
+void MenuPrint_RightAligned(const u8 *str, u8 left, u8 top)
+{
+ sub_8004D38(gMenuWindowPtr, str, gMenuTextTileOffset, left, top);
+}
+
+void sub_8072B80(const u8 *a1, u8 a2, u8 a3, const u8 *a4)
+{
+ u8 buffer[64];
+ u8 width = GetStringWidth(gMenuWindowPtr, a4);
+ AlignString(gMenuWindowPtr, buffer, a1, width, 1);
+ sub_8003460(gMenuWindowPtr, buffer, gMenuTextTileOffset, a2, a3);
+}
+
+void sub_8072BD8(const u8 *a1, u8 a2, u8 a3, u16 a4)
+{
+ sub_8004DB0(gMenuWindowPtr, a1, gMenuTextTileOffset, a2, a3, a4);
+}
+
+u8 *sub_8072C14(u8 *a1, s32 a2, u8 a3, u8 a4)
+{
+ return AlignInt1(gMenuWindowPtr, a1, a2, a3, a4);
+}
+
+u8 *sub_8072C44(u8 *a1, s32 a2, u8 a3, u8 a4)
+{
+ return AlignInt2(gMenuWindowPtr, a1, a2, a3, a4);
+}
+
+u8 *sub_8072C74(u8 *a1, const u8 *a2, u8 a3, u8 a4)
+{
+ return AlignString(gMenuWindowPtr, a1, a2, a3, a4);
+}
+
+u8 sub_8072CA4(const u8 *str)
+{
+ return GetStringWidth(gMenuWindowPtr, str);
+}
+
+u8 sub_8072CBC()
+{
+ return sub_8004E24(gMenuWindowPtr);
+}
+
+void sub_8072CD4(u8 *a1, u8 *a2, u8 *a3)
+{
+ sub_8004E28(gMenuWindowPtr, a1, a2, a3);
+}
+
+u32 MenuUpdateWindowText_OverrideLineLength(u8 lineLength)
+{
+ return sub_80037C8(gMenuWindowPtr, lineLength);
+}
+
+struct Window *unref_sub_8072D0C(void)
+{
+ return gMenuWindowPtr;
+}
+
+static void sub_8072D18(u8 a1, u8 a2)
+{
+ sub_814A5C0(a1, 0xFFFF, 12, 11679, 8 * a2);
+}
+
+u8 InitMenu(u8 cursorSubpriority, u8 left, u8 top, u8 numChoices, u8 cursorPos, u8 cursorWidth)
+{
+ s32 pos;
+
+ if (cursorWidth)
+ sub_8072D18(cursorSubpriority, cursorWidth);
+
+ gMenu.left = left - 1;
+ gMenu.top = top;
+ gMenu.minCursorPos = 0;
+ gMenu.maxCursorPos = numChoices - 1;
+ gMenu.menu_field_7 = 0;
+
+ pos = cursorPos;
+
+ if (pos < 0 || pos > gMenu.maxCursorPos)
+ pos = 0;
+
+ gMenu.cursorPos = pos;
+ MoveMenuCursor(0);
+
+ return pos;
+}
+
+void RedrawMenuCursor(u8 a1, u8 a2)
+{
+ sub_814A880((a1 + 1) * 8, 8 * a2);
+}
+
+void unref_sub_8072DC0()
+{
+ sub_814A904();
+}
+
+void sub_8072DCC(u8 a1)
+{
+ sub_814A958(a1);
+}
+
+void sub_8072DDC(u8 a1)
+{
+ sub_8072DCC(8 * a1);
+}
+
+void HandleDestroyMenuCursors(void)
+{
+ DestroyMenuCursor();
+}
+
+#if GERMAN
+void de_sub_8073110(u8 * buffer, u8 * name) {
+ u8 * ptr, *ptr2, *ptr3;
+
+ ptr2 = buffer;
+ ptr = &gStringVar1[1 + StringLengthN(gStringVar1, 256)];
+ ptr3 = ptr;
+
+ for (;;)
+ {
+ if (*ptr2 == EOS)
+ break;
+
+ if (*ptr2 == 0xFD)
+ {
+
+ *ptr3 = EOS;
+ ptr2 += 2;
+
+ StringAppend(ptr, name);
+ StringAppend(ptr, ptr2);
+
+ buffer[0] = EOS;
+ StringAppend(buffer, ptr);
+ break;
+ }
+
+ *ptr3 = *ptr2;
+ ptr2 += 1;
+ ptr3 += 1;
+ }
+}
+
+u8 *de_sub_8073174(u8 *name, const u8 *format) {
+ u32 offset;
+ u8 *ptr;
+
+ offset = StringLengthN(gStringVar2, 0x100);
+ ptr = &gStringVar2[1 + offset];
+
+ StringCopy(ptr, format);
+
+ de_sub_8073110(ptr, name);
+
+ return StringCopy(name, ptr);
+}
+#endif