pokeemerald/src/pokenav.c

593 lines
17 KiB
C
Raw Normal View History

2019-02-11 20:59:44 +01:00
#include "global.h"
#include "malloc.h"
2019-02-11 20:59:44 +01:00
#include "task.h"
#include "main.h"
#include "overworld.h"
2019-02-12 07:39:27 +01:00
#include "field_weather.h"
2019-02-12 08:23:08 +01:00
#include "palette.h"
2019-02-12 09:48:32 +01:00
#include "pokemon_storage_system.h"
#include "pokenav.h"
2019-02-12 08:23:08 +01:00
2019-04-06 22:15:52 +02:00
#define LOOPED_TASK_DECODE_STATE(action) (action - 5)
#define LOOPED_TASK_ID(primary, secondary) (((secondary) << 16) |(primary))
#define LOOPED_TASK_PRIMARY_ID(taskId) (taskId & 0xFFFF)
#define LOOPED_TASK_SECONDARY_ID(taskId) (taskId >> 16)
struct PokenavResources
2019-02-15 06:07:57 +01:00
{
u32 (*currentMenuCb1)(void);
u32 currentMenuIndex;
2019-02-23 13:34:01 +01:00
u16 mode;
2020-02-01 06:25:50 +01:00
u16 conditionSearchId;
2019-02-23 13:34:01 +01:00
bool32 hasAnyRibbons;
2020-10-11 00:17:34 +02:00
void *substructPtrs[POKENAV_SUBSTRUCT_COUNT];
2019-02-13 04:35:07 +01:00
};
2020-02-05 08:47:32 +01:00
struct PokenavCallbacks
{
2020-02-05 08:47:32 +01:00
bool32 (*init)(void);
u32 (*callback)(void);
bool32 (*open)(void);
void (*createLoopTask)(s32);
bool32 (*isLoopTaskActive)(void);
void (*free1)(void);
void (*free2)(void);
};
2020-02-05 08:47:32 +01:00
static u32 GetCurrentMenuCB(void);
2020-10-11 00:17:34 +02:00
static u32 IsActiveMenuLoopTaskActive_(void);
2019-04-13 22:54:05 +02:00
static bool32 SetActivePokenavMenu(u32 menuId);
2019-02-23 13:34:01 +01:00
static bool32 AnyMonHasRibbon(void);
static void InitPokenavResources(struct PokenavResources *a0);
2019-02-23 13:34:01 +01:00
static void InitKeys_(void);
static void FreePokenavResources(void);
2019-04-06 22:15:52 +02:00
static void VBlankCB_Pokenav(void);
2019-03-02 09:18:08 +01:00
static void CB2_Pokenav(void);
2019-08-06 02:23:56 +02:00
static void Task_RunLoopedTask_LinkMode(u8 a0);
static void Task_RunLoopedTask(u8 taskId);
2019-11-05 20:05:29 +01:00
static void Task_Pokenav(u8 taskId);
static void CB2_InitPokenavForTutorial(void);
2019-02-23 13:34:01 +01:00
2020-02-05 08:47:32 +01:00
// TODO: Use MENU ids
const struct PokenavCallbacks PokenavMenuCallbacks[15] =
{
[POKENAV_MAIN_MENU - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_MainMenuCursorOnMap,
.callback = GetMenuHandlerCallback,
.open = OpenPokenavMenuInitial,
.createLoopTask = CreateMenuHandlerLoopedTask,
.isLoopTaskActive = IsMenuHandlerLoopedTaskActive,
.free1 = FreeMenuHandlerSubstruct1,
.free2 = FreeMenuHandlerSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_MAIN_MENU_CURSOR_ON_MAP - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_MainMenuCursorOnMap,
.callback = GetMenuHandlerCallback,
.open = OpenPokenavMenuNotInitial,
.createLoopTask = CreateMenuHandlerLoopedTask,
.isLoopTaskActive = IsMenuHandlerLoopedTaskActive,
.free1 = FreeMenuHandlerSubstruct1,
.free2 = FreeMenuHandlerSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_CONDITION_MENU - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_ConditionMenu,
.callback = GetMenuHandlerCallback,
.open = OpenPokenavMenuNotInitial,
.createLoopTask = CreateMenuHandlerLoopedTask,
.isLoopTaskActive = IsMenuHandlerLoopedTaskActive,
.free1 = FreeMenuHandlerSubstruct1,
.free2 = FreeMenuHandlerSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_CONDITION_SEARCH_MENU - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_ConditionSearchMenu,
.callback = GetMenuHandlerCallback,
.open = OpenPokenavMenuNotInitial,
.createLoopTask = CreateMenuHandlerLoopedTask,
.isLoopTaskActive = IsMenuHandlerLoopedTaskActive,
.free1 = FreeMenuHandlerSubstruct1,
.free2 = FreeMenuHandlerSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_MAIN_MENU_CURSOR_ON_MATCH_CALL - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_MainMenuCursorOnMatchCall,
.callback = GetMenuHandlerCallback,
.open = OpenPokenavMenuNotInitial,
.createLoopTask = CreateMenuHandlerLoopedTask,
.isLoopTaskActive = IsMenuHandlerLoopedTaskActive,
.free1 = FreeMenuHandlerSubstruct1,
.free2 = FreeMenuHandlerSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_MAIN_MENU_CURSOR_ON_RIBBONS - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_MainMenuCursorOnRibbons,
.callback = GetMenuHandlerCallback,
.open = OpenPokenavMenuNotInitial,
.createLoopTask = CreateMenuHandlerLoopedTask,
.isLoopTaskActive = IsMenuHandlerLoopedTaskActive,
.free1 = FreeMenuHandlerSubstruct1,
.free2 = FreeMenuHandlerSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_REGION_MAP - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_RegionMap,
.callback = GetRegionMapCallback,
.open = OpenPokenavRegionMap,
.createLoopTask = CreateRegionMapLoopedTask,
.isLoopTaskActive = IsRegionMapLoopedTaskActive,
.free1 = FreeRegionMapSubstruct1,
.free2 = FreeRegionMapSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_CONDITION_PARTY - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_PartyCondition,
.callback = GetPartyConditionCallback,
.open = OpenPartyConditionMenu,
.createLoopTask = CreatePartyConditionLoopedTask,
.isLoopTaskActive = IsPartyConditionLoopedTaskActive,
.free1 = FreePartyConditionSubstruct1,
.free2 = FreePartyConditionSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_CONDITION_SEARCH_RESULTS - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_ConditionSearch,
.callback = GetConditionSearchResultsCallback,
.open = OpenConditionSearchResults,
.createLoopTask = CreateSearchResultsLoopedTask,
.isLoopTaskActive = IsSearchResultLoopedTaskActive,
.free1 = FreeSearchResultSubstruct1,
.free2 = FreeSearchResultSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_CONDITION_GRAPH_FROM_SEARCH - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_ConditionGraphFromSearch,
.callback = GetPartyConditionCallback,
.open = OpenPartyConditionMenu,
.createLoopTask = CreatePartyConditionLoopedTask,
.isLoopTaskActive = IsPartyConditionLoopedTaskActive,
.free1 = FreePartyConditionSubstruct1,
.free2 = FreePartyConditionSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_RETURN_CONDITION_SEARCH - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_ReturnToMonSearchList,
.callback = GetConditionSearchResultsCallback,
.open = OpenConditionSearchListFromGraph,
.createLoopTask = CreateSearchResultsLoopedTask,
.isLoopTaskActive = IsSearchResultLoopedTaskActive,
.free1 = FreeSearchResultSubstruct1,
.free2 = FreeSearchResultSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_MATCH_CALL - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
.init = PokenavCallback_Init_MatchCall,
.callback = GetMatchCallCallback,
.open = OpenMatchCall,
.createLoopTask = CreateMatchCallLoopedTask,
.isLoopTaskActive = IsMatchCallLoopedTaskActive,
.free1 = FreeMatchCallSubstruct1,
.free2 = FreeMatchCallSubstruct2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_RIBBONS_MON_LIST - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_MonRibbonList,
.callback = GetRibbonsMonListCallback,
.open = OpenRibbonsMonList,
.createLoopTask = CreateRibbonsMonListLoopedTask,
.isLoopTaskActive = IsRibbonsMonListLoopedTaskActive,
2021-11-09 18:50:35 +01:00
.free1 = FreeRibbonsMonList,
.free2 = FreeRibbonsMonMenu,
2019-02-15 06:29:32 +01:00
},
[POKENAV_RIBBONS_SUMMARY_SCREEN - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_RibbonsSummaryMenu,
.callback = GetRibbonsSummaryMenuCallback,
.open = OpenRibbonsSummaryMenu,
.createLoopTask = CreateRibbonsSummaryLoopedTask,
.isLoopTaskActive = IsRibbonsSummaryLoopedTaskActive,
.free1 = FreeRibbonsSummaryScreen1,
.free2 = FreeRibbonsSummaryScreen2,
2019-02-15 06:29:32 +01:00
},
[POKENAV_RIBBONS_RETURN_TO_MON_LIST - POKENAV_MENU_IDS_START] =
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
.init = PokenavCallback_Init_RibbonsMonListFromSummary,
.callback = GetRibbonsMonListCallback,
.open = OpenRibbonsMonListFromRibbonsSummary,
.createLoopTask = CreateRibbonsMonListLoopedTask,
.isLoopTaskActive = IsRibbonsMonListLoopedTaskActive,
2021-11-09 18:50:35 +01:00
.free1 = FreeRibbonsMonList,
.free2 = FreeRibbonsMonMenu,
2019-02-15 06:29:32 +01:00
},
};
2019-04-06 22:15:52 +02:00
EWRAM_DATA u8 gNextLoopedTaskId = 0;
EWRAM_DATA struct PokenavResources *gPokenavResources = NULL;
2019-03-16 00:33:30 +01:00
2019-02-23 13:34:01 +01:00
// code
2019-04-06 22:15:52 +02:00
u32 CreateLoopedTask(LoopedTask loopedTask, u32 priority)
2019-02-11 20:59:44 +01:00
{
u16 taskId;
if (!IsOverworldLinkActive())
2019-04-06 22:15:52 +02:00
taskId = CreateTask(Task_RunLoopedTask, priority);
2019-02-15 06:29:32 +01:00
else
2019-04-06 22:15:52 +02:00
taskId = CreateTask(Task_RunLoopedTask_LinkMode, priority);
2019-02-11 20:59:44 +01:00
2019-04-06 22:15:52 +02:00
SetWordTaskArg(taskId, 1, (u32)loopedTask);
2019-02-11 20:59:44 +01:00
2019-04-06 22:15:52 +02:00
gTasks[taskId].data[3] = gNextLoopedTaskId;
return LOOPED_TASK_ID(taskId, gNextLoopedTaskId++);
2019-02-11 20:59:44 +01:00
}
2019-04-06 22:15:52 +02:00
bool32 IsLoopedTaskActive(u32 taskId)
2019-02-11 22:35:02 +01:00
{
2019-04-06 22:15:52 +02:00
u32 primaryId = LOOPED_TASK_PRIMARY_ID(taskId);
u32 secondaryId = LOOPED_TASK_SECONDARY_ID(taskId);
2019-02-23 13:34:01 +01:00
2019-04-06 22:15:52 +02:00
if (gTasks[primaryId].isActive
&& (gTasks[primaryId].func == Task_RunLoopedTask || gTasks[primaryId].func == Task_RunLoopedTask_LinkMode)
&& gTasks[primaryId].data[3] == secondaryId)
2019-02-15 06:29:32 +01:00
return TRUE;
else
return FALSE;
2019-02-11 22:06:46 +01:00
}
2019-04-06 22:15:52 +02:00
bool32 FuncIsActiveLoopedTask(LoopedTask func)
2019-02-11 22:35:02 +01:00
{
2019-04-13 22:54:05 +02:00
int i;
2019-02-23 13:34:01 +01:00
for (i = 0; i < NUM_TASKS; i++)
2019-02-15 06:29:32 +01:00
{
if (gTasks[i].isActive
2019-04-06 22:15:52 +02:00
&& (gTasks[i].func == Task_RunLoopedTask || gTasks[i].func == Task_RunLoopedTask_LinkMode)
&& (LoopedTask)GetWordTaskArg(i, 1) == func)
2019-02-23 13:34:01 +01:00
return TRUE;
2019-02-15 06:29:32 +01:00
}
return FALSE;
2019-02-12 06:51:54 +01:00
}
2019-08-06 02:23:56 +02:00
static void Task_RunLoopedTask(u8 taskId)
2019-02-12 06:51:54 +01:00
{
2019-04-06 22:15:52 +02:00
LoopedTask loopedTask = (LoopedTask)GetWordTaskArg(taskId, 1);
s16 *state = &gTasks[taskId].data[0];
2019-02-23 13:34:01 +01:00
bool32 exitLoop = FALSE;
2019-02-15 06:29:32 +01:00
while (!exitLoop)
{
2019-04-06 22:15:52 +02:00
u32 action = loopedTask(*state);
switch (action)
2019-02-16 18:09:27 +01:00
{
2019-04-06 22:15:52 +02:00
case LT_INC_AND_CONTINUE:
(*state)++;
2019-02-15 06:29:32 +01:00
break;
case LT_INC_AND_PAUSE:
2019-04-06 22:15:52 +02:00
(*state)++;
2019-02-15 06:29:32 +01:00
return;
2019-04-06 22:15:52 +02:00
case LT_FINISH:
2019-02-15 06:29:32 +01:00
DestroyTask(taskId);
return;
2019-04-06 22:15:52 +02:00
// case LT_SET_STATE:
2019-02-15 06:29:32 +01:00
default:
2019-04-06 22:15:52 +02:00
*state = LOOPED_TASK_DECODE_STATE(action);
2019-02-15 06:29:32 +01:00
break;
2019-04-06 22:15:52 +02:00
case LT_CONTINUE:
2019-02-15 06:29:32 +01:00
break;
case LT_PAUSE:
2019-02-15 06:29:32 +01:00
return;
}
}
2019-02-12 07:30:39 +01:00
}
// Every "Continue" action pauses instead.
2019-08-06 02:23:56 +02:00
static void Task_RunLoopedTask_LinkMode(u8 taskId)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
LoopedTask task;
s16 *state;
u32 action;
2019-02-15 06:29:32 +01:00
if (Overworld_IsRecvQueueAtMax())
2019-02-15 06:29:32 +01:00
return;
2019-07-25 21:41:02 +02:00
2019-04-06 22:15:52 +02:00
task = (LoopedTask)GetWordTaskArg(taskId, 1);
state = &gTasks[taskId].data[0];
action = task(*state);
switch (action)
{
case LT_INC_AND_PAUSE:
2019-04-06 22:15:52 +02:00
case LT_INC_AND_CONTINUE:
(*state)++;
2019-02-16 18:09:27 +01:00
break;
2019-04-06 22:15:52 +02:00
case LT_FINISH:
2019-02-16 18:09:27 +01:00
DestroyTask(taskId);
break;
2019-04-06 22:15:52 +02:00
// case: LT_SET_STATE:
2019-02-16 18:09:27 +01:00
default:
2019-04-06 22:15:52 +02:00
*state = LOOPED_TASK_DECODE_STATE(action);
2019-02-16 18:09:27 +01:00
break;
case LT_PAUSE:
2019-04-06 22:15:52 +02:00
case LT_CONTINUE:
break;
2019-02-15 06:29:32 +01:00
}
2019-02-12 07:34:43 +01:00
}
2019-03-02 09:18:08 +01:00
void CB2_InitPokeNav(void)
2019-02-12 07:34:43 +01:00
{
gPokenavResources = Alloc(sizeof(*gPokenavResources));
2019-04-06 22:15:52 +02:00
if (gPokenavResources == NULL)
{
2019-02-12 07:34:43 +01:00
SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
}
2019-02-16 18:09:27 +01:00
else
{
InitPokenavResources(gPokenavResources);
2019-02-12 07:34:43 +01:00
ResetTasks();
SetVBlankCallback(NULL);
2019-11-05 20:05:29 +01:00
CreateTask(Task_Pokenav, 0);
2019-03-02 09:18:08 +01:00
SetMainCallback2(CB2_Pokenav);
2019-04-06 22:15:52 +02:00
SetVBlankCallback(VBlankCB_Pokenav);
2019-02-12 07:34:43 +01:00
}
2019-02-12 07:39:27 +01:00
}
2019-11-05 20:05:29 +01:00
void OpenPokenavForTutorial(void)
2019-02-15 06:07:57 +01:00
{
2019-11-05 20:05:29 +01:00
SetMainCallback2(CB2_InitPokenavForTutorial);
2019-12-15 17:42:50 +01:00
FadeScreen(FADE_TO_BLACK, 0);
2019-02-12 08:23:08 +01:00
}
2019-11-05 20:05:29 +01:00
static void CB2_InitPokenavForTutorial(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
UpdatePaletteFade();
2019-02-23 13:34:01 +01:00
if (gPaletteFade.active)
return;
gPokenavResources = Alloc(sizeof(*gPokenavResources));
2019-04-06 22:15:52 +02:00
if (gPokenavResources == NULL)
2019-02-15 06:29:32 +01:00
{
2019-02-23 13:34:01 +01:00
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else
{
InitPokenavResources(gPokenavResources);
2019-12-05 21:33:36 +01:00
gPokenavResources->mode = POKENAV_MODE_FORCE_CALL_READY;
2019-02-23 13:34:01 +01:00
ResetTasks();
ResetSpriteData();
FreeAllSpritePalettes();
SetVBlankCallback(NULL);
2019-11-05 20:05:29 +01:00
CreateTask(Task_Pokenav, 0);
2019-03-02 09:18:08 +01:00
SetMainCallback2(CB2_Pokenav);
2019-04-06 22:15:52 +02:00
SetVBlankCallback(VBlankCB_Pokenav);
2019-02-15 06:29:32 +01:00
}
2019-02-12 08:28:46 +01:00
}
static void FreePokenavResources(void)
2019-02-15 06:07:57 +01:00
{
2019-04-13 22:54:05 +02:00
int i;
2019-02-12 08:28:46 +01:00
2020-10-11 00:17:34 +02:00
for (i = 0; i < POKENAV_SUBSTRUCT_COUNT; i++)
FreePokenavSubstruct(i);
2019-02-23 13:34:01 +01:00
2019-04-06 22:15:52 +02:00
FREE_AND_SET_NULL(gPokenavResources);
2019-02-15 06:29:32 +01:00
InitKeys();
2019-02-12 08:59:17 +01:00
}
2020-10-11 00:17:34 +02:00
static void InitPokenavResources(struct PokenavResources *resources)
2019-02-15 06:07:57 +01:00
{
2019-04-13 22:54:05 +02:00
int i;
2019-02-15 06:29:32 +01:00
2020-10-11 00:17:34 +02:00
for (i = 0; i < POKENAV_SUBSTRUCT_COUNT; i++)
resources->substructPtrs[i] = NULL;
2019-02-23 13:34:01 +01:00
2020-10-11 00:17:34 +02:00
resources->mode = POKENAV_MODE_NORMAL;
resources->currentMenuIndex = 0;
resources->hasAnyRibbons = AnyMonHasRibbon();
resources->currentMenuCb1 = NULL;
2019-02-12 09:48:32 +01:00
}
2019-02-23 13:34:01 +01:00
static bool32 AnyMonHasRibbon(void)
2019-02-15 06:07:57 +01:00
{
2019-04-13 22:54:05 +02:00
int i, j;
2019-02-15 06:29:32 +01:00
for (i = 0; i < PARTY_SIZE; i++)
2019-02-15 06:29:32 +01:00
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_HAS_SPECIES)
&& !GetMonData(&gPlayerParty[i], MON_DATA_SANITY_IS_EGG)
&& GetMonData(&gPlayerParty[i], MON_DATA_RIBBON_COUNT) != 0)
{
return TRUE;
}
}
for (j = 0; j < TOTAL_BOXES_COUNT; j++)
2019-02-15 06:29:32 +01:00
{
2019-02-23 13:34:01 +01:00
for (i = 0; i < IN_BOX_COUNT; i++)
2019-02-15 06:29:32 +01:00
{
if (CheckBoxMonSanityAt(j, i)
&& GetBoxMonDataAt(j, i, MON_DATA_RIBBON_COUNT) != 0)
{
return TRUE;
}
}
}
return FALSE;
2019-02-12 09:51:48 +01:00
}
2019-03-02 09:18:08 +01:00
static void CB2_Pokenav(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
RunTasks();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
2019-02-12 09:54:35 +01:00
}
2019-04-06 22:15:52 +02:00
static void VBlankCB_Pokenav(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
TransferPlttBuffer();
LoadOam();
ProcessSpriteCopyRequests();
2019-02-13 02:20:15 +01:00
}
2020-02-05 08:47:32 +01:00
#define tState data[0]
2019-11-05 20:05:29 +01:00
static void Task_Pokenav(u8 taskId)
2019-02-15 06:07:57 +01:00
{
2020-02-05 08:47:32 +01:00
u32 menuId;
2019-02-23 13:34:01 +01:00
s16 *data = gTasks[taskId].data;
2019-02-15 06:29:32 +01:00
2020-02-05 08:47:32 +01:00
switch (tState)
2019-02-15 06:29:32 +01:00
{
case 0:
InitPokenavMainMenu();
2020-02-05 08:47:32 +01:00
tState = 1;
2019-02-15 06:29:32 +01:00
break;
case 1:
// Wait for LoopedTask_InitPokenavMenu to finish
if (PokenavMainMenuLoopedTaskIsActive())
2019-02-15 06:29:32 +01:00
break;
2020-02-05 08:47:32 +01:00
SetActivePokenavMenu(POKENAV_MAIN_MENU);
tState = 4;
2019-02-15 06:29:32 +01:00
break;
case 2:
2020-10-11 00:17:34 +02:00
if (IsActiveMenuLoopTaskActive())
2019-02-15 06:29:32 +01:00
break;
2020-02-05 08:47:32 +01:00
tState = 3;
2019-02-15 06:29:32 +01:00
case 3:
2020-02-05 08:47:32 +01:00
menuId = GetCurrentMenuCB();
2020-10-11 00:17:34 +02:00
if (menuId == POKENAV_MENU_FUNC_EXIT)
2019-02-15 06:29:32 +01:00
{
ShutdownPokenav();
2020-02-05 08:47:32 +01:00
tState = 5;
2019-02-15 06:29:32 +01:00
}
2020-02-05 08:47:32 +01:00
else if (menuId >= POKENAV_MENU_IDS_START)
2019-02-15 06:29:32 +01:00
{
2020-02-05 08:47:32 +01:00
PokenavMenuCallbacks[gPokenavResources->currentMenuIndex].free2();
PokenavMenuCallbacks[gPokenavResources->currentMenuIndex].free1();
if (SetActivePokenavMenu(menuId))
{
2020-02-05 08:47:32 +01:00
tState = 4;
}
2019-02-15 06:29:32 +01:00
else
{
ShutdownPokenav();
2020-02-05 08:47:32 +01:00
tState = 5;
2019-02-15 06:29:32 +01:00
}
}
2020-02-05 08:47:32 +01:00
else if (menuId != 0)
2019-02-15 06:29:32 +01:00
{
2020-10-11 00:17:34 +02:00
RunMainMenuLoopedTask(menuId);
if (IsActiveMenuLoopTaskActive())
2020-02-05 08:47:32 +01:00
tState = 2;
2019-02-15 06:29:32 +01:00
}
break;
case 4:
2020-10-11 00:17:34 +02:00
if (!IsActiveMenuLoopTaskActive_())
2020-02-05 08:47:32 +01:00
tState = 3;
2019-02-15 06:29:32 +01:00
break;
case 5:
if (!WaitForPokenavShutdownFade())
2019-02-15 06:29:32 +01:00
{
2019-04-13 22:54:05 +02:00
bool32 calledFromScript = (gPokenavResources->mode != POKENAV_MODE_NORMAL);
2019-02-23 13:34:01 +01:00
2020-02-05 08:47:32 +01:00
FreeMenuHandlerSubstruct1();
FreePokenavResources();
2019-02-23 13:34:01 +01:00
if (calledFromScript)
2019-02-15 06:29:32 +01:00
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
else
SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
}
break;
2019-02-15 06:29:32 +01:00
}
}
2020-02-05 08:47:32 +01:00
#undef tState
2019-04-13 22:54:05 +02:00
static bool32 SetActivePokenavMenu(u32 menuId)
2019-02-15 06:07:57 +01:00
{
2019-04-13 22:54:05 +02:00
u32 index = menuId - POKENAV_MENU_IDS_START;
2019-02-15 06:29:32 +01:00
2019-02-23 13:34:01 +01:00
InitKeys_();
2020-02-05 08:47:32 +01:00
if (!PokenavMenuCallbacks[index].init())
2019-02-15 06:29:32 +01:00
return FALSE;
2020-02-05 08:47:32 +01:00
if (!PokenavMenuCallbacks[index].open())
2019-02-15 06:29:32 +01:00
return FALSE;
2019-02-23 13:34:01 +01:00
2020-10-11 00:17:34 +02:00
SetActiveMenuLoopTasks(PokenavMenuCallbacks[index].createLoopTask, PokenavMenuCallbacks[index].isLoopTaskActive);
2020-02-05 08:47:32 +01:00
gPokenavResources->currentMenuCb1 = PokenavMenuCallbacks[index].callback;
gPokenavResources->currentMenuIndex = index;
2019-02-15 06:29:32 +01:00
return TRUE;
2019-02-13 03:33:15 +01:00
}
2020-10-11 00:17:34 +02:00
static u32 IsActiveMenuLoopTaskActive_(void)
2019-02-15 06:07:57 +01:00
{
2020-10-11 00:17:34 +02:00
return IsActiveMenuLoopTaskActive();
2019-02-13 03:33:15 +01:00
}
2020-02-05 08:47:32 +01:00
static u32 GetCurrentMenuCB(void)
2019-02-15 06:07:57 +01:00
{
return gPokenavResources->currentMenuCb1();
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
static void InitKeys_(void)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
InitKeys();
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
void SetVBlankCallback_(IntrCallback callback)
2019-02-15 06:07:57 +01:00
{
2019-02-15 06:29:32 +01:00
SetVBlankCallback(callback);
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
void SetPokenavVBlankCallback(void)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
SetVBlankCallback(VBlankCB_Pokenav);
2019-02-13 03:33:15 +01:00
}
2019-02-23 13:34:01 +01:00
void *AllocSubstruct(u32 index, u32 size)
2019-02-15 06:07:57 +01:00
{
2020-10-11 00:17:34 +02:00
gPokenavResources->substructPtrs[index] = Alloc(size);
return gPokenavResources->substructPtrs[index];
2019-02-13 04:18:12 +01:00
}
void *GetSubstructPtr(u32 index)
2019-02-15 06:07:57 +01:00
{
2020-10-11 00:17:34 +02:00
return gPokenavResources->substructPtrs[index];
2019-02-13 04:18:12 +01:00
}
void FreePokenavSubstruct(u32 index)
2019-02-15 06:07:57 +01:00
{
2020-10-11 00:17:34 +02:00
if (gPokenavResources->substructPtrs[index] != NULL)
FREE_AND_SET_NULL(gPokenavResources->substructPtrs[index]);
2019-02-13 04:18:12 +01:00
}
u32 GetPokenavMode(void)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->mode;
2019-02-13 04:18:12 +01:00
}
2019-02-23 13:34:01 +01:00
void SetPokenavMode(u16 mode)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
gPokenavResources->mode = mode;
2019-02-13 04:18:12 +01:00
}
2020-02-01 06:25:50 +01:00
void SetSelectedConditionSearch(u32 cursorPos)
2019-02-15 06:07:57 +01:00
{
2020-02-01 06:25:50 +01:00
u32 searchId = cursorPos;
2019-02-23 13:34:01 +01:00
2020-02-01 06:25:50 +01:00
if (searchId > POKENAV_MENUITEM_CONDITION_SEARCH_TOUGH - POKENAV_MENUITEM_CONDITION_SEARCH_COOL)
searchId = 0;
gPokenavResources->conditionSearchId = searchId;
2019-02-13 04:18:12 +01:00
}
2020-02-01 06:25:50 +01:00
u32 GetSelectedConditionSearch(void)
2019-02-15 06:07:57 +01:00
{
2020-02-01 06:25:50 +01:00
return gPokenavResources->conditionSearchId;
2019-02-13 04:18:12 +01:00
}
2019-02-23 13:34:01 +01:00
bool32 CanViewRibbonsMenu(void)
2019-02-15 06:07:57 +01:00
{
2019-04-06 22:15:52 +02:00
return gPokenavResources->hasAnyRibbons;
2019-02-13 04:18:12 +01:00
}