summaryrefslogtreecommitdiff
path: root/src/pokenav_menu_handler_1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pokenav_menu_handler_1.c')
-rw-r--r--src/pokenav_menu_handler_1.c513
1 files changed, 513 insertions, 0 deletions
diff --git a/src/pokenav_menu_handler_1.c b/src/pokenav_menu_handler_1.c
new file mode 100644
index 000000000..44176176d
--- /dev/null
+++ b/src/pokenav_menu_handler_1.c
@@ -0,0 +1,513 @@
+#include "global.h"
+#include "pokenav.h"
+#include "event_data.h"
+#include "main.h"
+#include "sound.h"
+#include "constants/songs.h"
+
+struct Pokenav1Struct
+{
+ u16 menuType;
+ s16 cursorPos;
+ u16 currMenuItem;
+ u16 helpBarIndex;
+ u32 unk8;
+ u32 (*callback)(struct Pokenav1Struct*);
+};
+
+static bool32 UpdateMenuCursorPos(struct Pokenav1Struct *state);
+static void ReturnToConditionMenu(struct Pokenav1Struct *state);
+static void ReturnToMainMenu(struct Pokenav1Struct *state);
+static u32 sub_81C97BC(struct Pokenav1Struct *state);
+static void sub_81C97B0(struct Pokenav1Struct *state, u32 a1);
+static u32 CB2_ReturnToConditionMenu(struct Pokenav1Struct *state);
+static u32 CB2_ReturnToMainMenu(struct Pokenav1Struct *state);
+static u32 HandleConditionSearchMenuInput(struct Pokenav1Struct *state);
+static u32 HandleConditionMenuInput(struct Pokenav1Struct *state);
+static u32 HandleCantOpenRibbonsInput(struct Pokenav1Struct *state);
+static u32 HandleMainMenuInputEndTutorial(struct Pokenav1Struct *state);
+static u32 HandleMainMenuInputTutorial(struct Pokenav1Struct *state);
+static u32 HandleMainMenuInput(struct Pokenav1Struct *state);
+static u32 (*GetMainMenuInputHandler(void))(struct Pokenav1Struct*);
+static void SetMenuInputHandler(struct Pokenav1Struct *state);
+
+// Number of entries - 1 for that menu type
+static const u8 sLastCursorPositions[] =
+{
+ [POKENAV_MENU_TYPE_DEFAULT] = 2,
+ [POKENAV_MENU_TYPE_UNLOCK_MC] = 3,
+ [POKENAV_MENU_TYPE_UNLOCK_MC_RIBBONS] = 4,
+ [POKENAV_MENU_TYPE_CONDITION] = 2,
+ [POKENAV_MENU_TYPE_CONDITION_SEARCH] = 5
+};
+
+static const u8 sMenuItems[][6] =
+{
+ [POKENAV_MENU_TYPE_DEFAULT] =
+ {
+ POKENAV_MENUITEM_MAP,
+ POKENAV_MENUITEM_CONDITION,
+ [2 ... 5] = POKENAV_MENUITEM_SWITCH_OFF
+ },
+ [POKENAV_MENU_TYPE_UNLOCK_MC] =
+ {
+ POKENAV_MENUITEM_MAP,
+ POKENAV_MENUITEM_CONDITION,
+ POKENAV_MENUITEM_MATCH_CALL,
+ [3 ... 5] = POKENAV_MENUITEM_SWITCH_OFF
+ },
+ [POKENAV_MENU_TYPE_UNLOCK_MC_RIBBONS] =
+ {
+ POKENAV_MENUITEM_MAP,
+ POKENAV_MENUITEM_CONDITION,
+ POKENAV_MENUITEM_MATCH_CALL,
+ POKENAV_MENUITEM_RIBBONS,
+ [4 ... 5] = POKENAV_MENUITEM_SWITCH_OFF
+ },
+ [POKENAV_MENU_TYPE_CONDITION] =
+ {
+ POKENAV_MENUITEM_CONDITION_PARTY,
+ POKENAV_MENUITEM_CONDITION_SEARCH,
+ POKENAV_MENUITEM_CONDITION_CANCEL,
+ [3 ... 5] = POKENAV_MENUITEM_SWITCH_OFF
+ },
+ [POKENAV_MENU_TYPE_CONDITION_SEARCH] =
+ {
+ POKENAV_MENUITEM_CONDITION_SEARCH_COOL,
+ POKENAV_MENUITEM_CONDITION_SEARCH_BEAUTY,
+ POKENAV_MENUITEM_CONDITION_SEARCH_CUTE,
+ POKENAV_MENUITEM_CONDITION_SEARCH_SMART,
+ POKENAV_MENUITEM_CONDITION_SEARCH_TOUGH,
+ POKENAV_MENUITEM_CONDITION_SEARCH_CANCEL
+ },
+};
+
+static u8 GetPokenavMainMenuType(void)
+{
+ u8 menuType = POKENAV_MENU_TYPE_DEFAULT;
+
+ if (FlagGet(FLAG_ADDED_MATCH_CALL_TO_POKENAV))
+ {
+ menuType = POKENAV_MENU_TYPE_UNLOCK_MC;
+
+ if (FlagGet(FLAG_SYS_RIBBON_GET))
+ menuType = POKENAV_MENU_TYPE_UNLOCK_MC_RIBBONS;
+ }
+
+ return menuType;
+}
+
+bool32 PokenavCallback_Init_0(void)
+{
+ struct Pokenav1Struct *state = AllocSubstruct(1, sizeof(struct Pokenav1Struct));
+ if (!state)
+ return FALSE;
+
+ state->menuType = GetPokenavMainMenuType();
+ state->cursorPos = 0;
+ state->currMenuItem = POKENAV_MENUITEM_MAP;
+ state->helpBarIndex = HELPBAR_NONE;
+ SetMenuInputHandler(state);
+ return TRUE;
+}
+
+bool32 PokenavCallback_Init_4(void)
+{
+ struct Pokenav1Struct *state = AllocSubstruct(1, sizeof(struct Pokenav1Struct));
+ if (!state)
+ return FALSE;
+
+ state->menuType = GetPokenavMainMenuType();
+ state->cursorPos = 2;
+ state->currMenuItem = POKENAV_MENUITEM_MATCH_CALL;
+ state->helpBarIndex = HELPBAR_NONE;
+ SetMenuInputHandler(state);
+ return TRUE;
+}
+
+bool32 PokenavCallback_Init_5(void)
+{
+ struct Pokenav1Struct *state = AllocSubstruct(1, sizeof(struct Pokenav1Struct));
+ if (!state)
+ return FALSE;
+
+ state->menuType = GetPokenavMainMenuType();
+ state->cursorPos = 3;
+ state->currMenuItem = POKENAV_MENUITEM_RIBBONS;
+ SetMenuInputHandler(state);
+ return TRUE;
+}
+
+bool32 PokenavCallback_Init_2(void)
+{
+ struct Pokenav1Struct *state = AllocSubstruct(1, sizeof(struct Pokenav1Struct));
+ if (!state)
+ return FALSE;
+
+ state->menuType = POKENAV_MENU_TYPE_CONDITION;
+ state->cursorPos = 0;
+ state->currMenuItem = POKENAV_MENUITEM_CONDITION_PARTY;
+ state->helpBarIndex = HELPBAR_NONE;
+ SetMenuInputHandler(state);
+ return TRUE;
+}
+
+bool32 PokenavCallback_Init_3(void)
+{
+ struct Pokenav1Struct *state = AllocSubstruct(1, sizeof(struct Pokenav1Struct));
+ if (!state)
+ return FALSE;
+
+ state->menuType = POKENAV_MENU_TYPE_CONDITION_SEARCH;
+ state->cursorPos = GetSelectedConditionSearch();
+ state->currMenuItem = state->cursorPos + POKENAV_MENUITEM_CONDITION_SEARCH_COOL;
+ state->helpBarIndex = HELPBAR_NONE;
+ SetMenuInputHandler(state);
+ return TRUE;
+}
+
+static void SetMenuInputHandler(struct Pokenav1Struct *state)
+{
+ switch (state->menuType)
+ {
+ case POKENAV_MENU_TYPE_DEFAULT:
+ SetPokenavMode(POKENAV_MODE_NORMAL);
+ // fallthrough
+ case POKENAV_MENU_TYPE_UNLOCK_MC:
+ case POKENAV_MENU_TYPE_UNLOCK_MC_RIBBONS:
+ state->callback = GetMainMenuInputHandler();
+ break;
+ case POKENAV_MENU_TYPE_CONDITION:
+ state->callback = HandleConditionMenuInput;
+ break;
+ case POKENAV_MENU_TYPE_CONDITION_SEARCH:
+ state->callback = HandleConditionSearchMenuInput;
+ break;
+ }
+}
+
+static u32 (*GetMainMenuInputHandler(void))(struct Pokenav1Struct*)
+{
+ switch (GetPokenavMode())
+ {
+ default:
+ case POKENAV_MODE_NORMAL:
+ return HandleMainMenuInput;
+ case POKENAV_MODE_FORCE_CALL_READY:
+ return HandleMainMenuInputTutorial;
+ case POKENAV_MODE_FORCE_CALL_EXIT:
+ return HandleMainMenuInputEndTutorial;
+ }
+}
+
+u32 sub_81C941C(void)
+{
+ struct Pokenav1Struct *state = GetSubstructPtr(1);
+ return state->callback(state);
+}
+
+void sub_81C9430(void)
+{
+ FreePokenavSubstruct(1);
+}
+
+static u32 HandleMainMenuInput(struct Pokenav1Struct *state)
+{
+ if (UpdateMenuCursorPos(state))
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ switch (sMenuItems[state->menuType][state->cursorPos])
+ {
+ case POKENAV_MENUITEM_MAP:
+ state->helpBarIndex = gSaveBlock2Ptr->regionMapZoom ? HELPBAR_MAP_ZOOMED_IN : HELPBAR_MAP_ZOOMED_OUT;
+ sub_81C97B0(state, POKENAV_MENU_6);
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ case POKENAV_MENUITEM_CONDITION:
+ state->menuType = POKENAV_MENU_TYPE_CONDITION;
+ state->cursorPos = 0;
+ state->currMenuItem = sMenuItems[POKENAV_MENU_TYPE_CONDITION][0];
+ state->callback = HandleConditionMenuInput;
+ return POKENAV_MENU_FUNC_OPEN_CONDITION;
+ case POKENAV_MENUITEM_MATCH_CALL:
+ state->helpBarIndex = HELPBAR_MC_TRAINER_LIST;
+ sub_81C97B0(state, POKENAV_MENU_B);
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ case POKENAV_MENUITEM_RIBBONS:
+ if (CanViewRibbonsMenu())
+ {
+ state->helpBarIndex = HELPBAR_RIBBONS_MON_LIST;
+ sub_81C97B0(state, POKENAV_MENU_C);
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ }
+ else
+ {
+ state->callback = HandleCantOpenRibbonsInput;
+ return POKENAV_MENU_FUNC_NO_RIBBON_WINNERS;
+ }
+ case POKENAV_MENUITEM_SWITCH_OFF:
+ return -1;
+ }
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ return -1;
+
+ return POKENAV_MENU_FUNC_NONE;
+}
+
+// Force the player to select Match Call during the call Mr. Stone pokenav tutorial
+static u32 HandleMainMenuInputTutorial(struct Pokenav1Struct *state)
+{
+ if (UpdateMenuCursorPos(state))
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ if (sMenuItems[state->menuType][state->cursorPos] == POKENAV_MENUITEM_MATCH_CALL)
+ {
+ state->helpBarIndex = HELPBAR_MC_TRAINER_LIST;
+ sub_81C97B0(state, POKENAV_MENU_B);
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ }
+ else
+ {
+ PlaySE(SE_HAZURE);
+ return POKENAV_MENU_FUNC_NONE;
+ }
+ }
+
+ if (gMain.newKeys & B_BUTTON)
+ {
+ PlaySE(SE_HAZURE);
+ return POKENAV_MENU_FUNC_NONE;
+ }
+
+ return POKENAV_MENU_FUNC_NONE;
+}
+
+// After calling Mr. Stone during the pokenav tutorial, force player to exit or use Match Call again
+static u32 HandleMainMenuInputEndTutorial(struct Pokenav1Struct *state)
+{
+ if (UpdateMenuCursorPos(state))
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ u32 menuItem = sMenuItems[state->menuType][state->cursorPos];
+ if (menuItem != POKENAV_MENUITEM_MATCH_CALL && menuItem != POKENAV_MENUITEM_SWITCH_OFF)
+ {
+ PlaySE(SE_HAZURE);
+ return POKENAV_MENU_FUNC_NONE;
+ }
+ else if (menuItem == POKENAV_MENUITEM_MATCH_CALL)
+ {
+ state->helpBarIndex = HELPBAR_MC_TRAINER_LIST;
+ sub_81C97B0(state, POKENAV_MENU_B);
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ else if (gMain.newKeys & B_BUTTON)
+ {
+ return -1;
+ }
+ return POKENAV_MENU_FUNC_NONE;
+}
+
+// Handles input after selecting Ribbons when there are no ribbon winners left
+// Selecting it again just reprints the Ribbon description to replace the "No Ribbon winners" message
+static u32 HandleCantOpenRibbonsInput(struct Pokenav1Struct *state)
+{
+ if (UpdateMenuCursorPos(state))
+ {
+ state->callback = GetMainMenuInputHandler();
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+ }
+
+ if (gMain.newKeys & (A_BUTTON | B_BUTTON))
+ {
+ state->callback = GetMainMenuInputHandler();
+ return POKENAV_MENU_FUNC_RESHOW_DESCRIPTION;
+ }
+
+ return POKENAV_MENU_FUNC_NONE;
+}
+
+static u32 HandleConditionMenuInput(struct Pokenav1Struct *state)
+{
+ if (UpdateMenuCursorPos(state))
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ switch (sMenuItems[state->menuType][state->cursorPos])
+ {
+ case POKENAV_MENUITEM_CONDITION_SEARCH:
+ state->menuType = POKENAV_MENU_TYPE_CONDITION_SEARCH;
+ state->cursorPos = 0;
+ state->currMenuItem = sMenuItems[POKENAV_MENU_TYPE_CONDITION_SEARCH][0];
+ state->callback = HandleConditionSearchMenuInput;
+ return POKENAV_MENU_FUNC_OPEN_CONDITION_SEARCH;
+ case POKENAV_MENUITEM_CONDITION_PARTY:
+ state->helpBarIndex = 0;
+ sub_81C97B0(state, POKENAV_MENU_7);
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ case POKENAV_MENUITEM_CONDITION_CANCEL:
+ PlaySE(SE_SELECT);
+ ReturnToMainMenu(state);
+ return POKENAV_MENU_FUNC_RETURN_TO_MAIN;
+ }
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ if (state->cursorPos != sLastCursorPositions[state->menuType])
+ {
+ state->cursorPos = sLastCursorPositions[state->menuType];
+ state->callback = CB2_ReturnToMainMenu;
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ ReturnToMainMenu(state);
+ return POKENAV_MENU_FUNC_RETURN_TO_MAIN;
+ }
+ }
+
+ return POKENAV_MENU_FUNC_NONE;
+}
+
+static u32 HandleConditionSearchMenuInput(struct Pokenav1Struct *state)
+{
+ if (UpdateMenuCursorPos(state))
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+
+ if (gMain.newKeys & A_BUTTON)
+ {
+ u8 menuItem = sMenuItems[state->menuType][state->cursorPos];
+ if (menuItem != POKENAV_MENUITEM_CONDITION_SEARCH_CANCEL)
+ {
+ SetSelectedConditionSearch(menuItem - POKENAV_MENUITEM_CONDITION_SEARCH_COOL);
+ sub_81C97B0(state, POKENAV_MENU_8);
+ state->helpBarIndex = HELPBAR_CONDITION_MON_LIST;
+ return POKENAV_MENU_FUNC_OPEN_FEATURE;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ ReturnToConditionMenu(state);
+ return POKENAV_MENU_FUNC_RETURN_TO_CONDITION;
+ }
+ }
+ if (gMain.newKeys & B_BUTTON)
+ {
+ if (state->cursorPos != sLastCursorPositions[state->menuType])
+ {
+ state->cursorPos = sLastCursorPositions[state->menuType];
+ state->callback = CB2_ReturnToConditionMenu;
+ return POKENAV_MENU_FUNC_MOVE_CURSOR;
+ }
+ else
+ {
+ PlaySE(SE_SELECT);
+ ReturnToConditionMenu(state);
+ return POKENAV_MENU_FUNC_RETURN_TO_CONDITION;
+ }
+ }
+ return POKENAV_MENU_FUNC_NONE;
+}
+
+static u32 CB2_ReturnToMainMenu(struct Pokenav1Struct *state)
+{
+ ReturnToMainMenu(state);
+ return POKENAV_MENU_FUNC_RETURN_TO_MAIN;
+}
+
+static u32 CB2_ReturnToConditionMenu(struct Pokenav1Struct *state)
+{
+ ReturnToConditionMenu(state);
+ return POKENAV_MENU_FUNC_RETURN_TO_CONDITION;
+}
+
+static void sub_81C97B0(struct Pokenav1Struct *state, u32 a1)
+{
+ state->unk8 = a1;
+ state->callback = sub_81C97BC;
+}
+
+static u32 sub_81C97BC(struct Pokenav1Struct *state)
+{
+ return state->unk8;
+}
+
+static void ReturnToMainMenu(struct Pokenav1Struct *state)
+{
+ state->menuType = GetPokenavMainMenuType();
+ state->cursorPos = 1;
+ state->currMenuItem = sMenuItems[state->menuType][state->cursorPos];
+ state->callback = HandleMainMenuInput;
+}
+
+static void ReturnToConditionMenu(struct Pokenav1Struct *state)
+{
+ state->menuType = POKENAV_MENU_TYPE_CONDITION;
+ state->cursorPos = 1;
+ state->currMenuItem = sMenuItems[POKENAV_MENU_TYPE_CONDITION][1];
+ state->callback = HandleConditionMenuInput;
+}
+
+static bool32 UpdateMenuCursorPos(struct Pokenav1Struct *state)
+{
+ if (gMain.newKeys & DPAD_UP)
+ {
+ if (--state->cursorPos < 0)
+ state->cursorPos = sLastCursorPositions[state->menuType];
+
+ state->currMenuItem = sMenuItems[state->menuType][state->cursorPos];
+ return TRUE;
+ }
+ else if (gMain.newKeys & DPAD_DOWN)
+ {
+ state->cursorPos++;
+ if (state->cursorPos > sLastCursorPositions[state->menuType])
+ state->cursorPos = 0;
+
+ state->currMenuItem = sMenuItems[state->menuType][state->cursorPos];
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+int GetPokenavMenuType(void)
+{
+ struct Pokenav1Struct *state = GetSubstructPtr(1);
+ return state->menuType;
+}
+
+// Position of cursor relative to number of current menu options
+int GetPokenavCursorPos(void)
+{
+ struct Pokenav1Struct *state = GetSubstructPtr(1);
+ return state->cursorPos;
+}
+
+// ID of menu item the cursor is currently on
+int GetCurrentMenuItemId(void)
+{
+ struct Pokenav1Struct *state = GetSubstructPtr(1);
+ return state->currMenuItem;
+}
+
+u16 GetHelpBarTextId(void)
+{
+ struct Pokenav1Struct *state = GetSubstructPtr(1);
+ return state->helpBarIndex;
+}