Continue documenting Quest Log

This commit is contained in:
GriffinR
2022-11-30 15:34:52 -05:00
parent 66e279611b
commit c39f3161d2
9 changed files with 664 additions and 620 deletions
+2 -2
View File
@@ -193,7 +193,7 @@ void SetQuestLogEvent(u16, const u16 *);
void SetQLPlayedTheSlots(void); void SetQLPlayedTheSlots(void);
void QuestLog_RecordEnteredMap(u16); void QuestLog_RecordEnteredMap(u16);
u8 sub_8112CAC(void); u8 sub_8112CAC(void);
bool8 QuestLog_SchedulePlaybackCB(void (*func)(void)); bool8 QL_AvoidDisplay(void (*func)(void));
void QuestLog_BackUpPalette(u16 offset, u16 size); void QuestLog_BackUpPalette(u16 offset, u16 size);
void CommitQuestLogWindow1(void); void CommitQuestLogWindow1(void);
void QuestLog_DrawPreviouslyOnQuestHeaderIfInPlaybackMode(void); void QuestLog_DrawPreviouslyOnQuestHeaderIfInPlaybackMode(void);
@@ -220,7 +220,7 @@ void QuestLogRecordPlayerStepWithDuration(u8 movementActionId, u8 duration);
void QuestLogRecordNPCStepWithDuration(u8 localId, u8 mapNum, u8 mapGroup, u8 movementActionId, u8 duration); void QuestLogRecordNPCStepWithDuration(u8 localId, u8 mapNum, u8 mapGroup, u8 movementActionId, u8 duration);
void QL_AfterRecordFishActionSuccessful(void); void QL_AfterRecordFishActionSuccessful(void);
void sub_8110920(void); void sub_8110920(void);
void sub_8111708(void); void QL_RestoreMapLayoutId(void);
void sub_81127F8(struct FieldInput * a0); void sub_81127F8(struct FieldInput * a0);
void sub_8112B3C(void); void sub_8112B3C(void);
void RunQuestLogCB(void); void RunQuestLogCB(void);
+1 -1
View File
@@ -14,7 +14,7 @@ bool8 CreatePCMenu(void);
void ScriptMenu_DisplayPCStartupPrompt(void); void ScriptMenu_DisplayPCStartupPrompt(void);
bool8 (*ScriptMenu_HidePokemonPic(void))(void); bool8 (*ScriptMenu_HidePokemonPic(void))(void);
void QLPlaybackCB_DestroyScriptMenuMonPicSprites(void); void QL_DestroyAbortedDisplay(void);
void PicboxCancel(void); void PicboxCancel(void);
#endif //GUARD_SCRIPT_MENU_H #endif //GUARD_SCRIPT_MENU_H
+9 -9
View File
@@ -113,15 +113,15 @@ void DisplayBerryPowderVendorMenu(void)
{ {
struct WindowTemplate template; struct WindowTemplate template;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE) if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
{ return;
template = SetWindowTemplateFields(0, 1, 1, 8, 3, 15, 32);
sBerryPowderVendorWindowId = AddWindow(&template); template = SetWindowTemplateFields(0, 1, 1, 8, 3, 15, 32);
FillWindowPixelBuffer(sBerryPowderVendorWindowId, 0); sBerryPowderVendorWindowId = AddWindow(&template);
PutWindowTilemap(sBerryPowderVendorWindowId); FillWindowPixelBuffer(sBerryPowderVendorWindowId, 0);
LoadStdWindowGfx(sBerryPowderVendorWindowId, 0x21D, 0xD0); PutWindowTilemap(sBerryPowderVendorWindowId);
DrawPlayerPowderAmount(sBerryPowderVendorWindowId, 0x21D, 0xD, GetBerryPowder()); LoadStdWindowGfx(sBerryPowderVendorWindowId, 0x21D, 0xD0);
} DrawPlayerPowderAmount(sBerryPowderVendorWindowId, 0x21D, 0xD, GetBerryPowder());
} }
void RemoveBerryPowderVendorMenu(void) void RemoveBerryPowderVendorMenu(void)
+98 -96
View File
@@ -1095,18 +1095,19 @@ void DrawElevatorCurrentFloorWindow(void)
{ {
const u8 *floorname; const u8 *floorname;
u32 strwidth; u32 strwidth;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE)
{ if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
sElevatorCurrentFloorWindowId = AddWindow(&sElevatorCurrentFloorWindowTemplate); return;
LoadStdWindowGfx(sElevatorCurrentFloorWindowId, 0x21D, 0xD0);
DrawStdFrameWithCustomTileAndPalette(sElevatorCurrentFloorWindowId, FALSE, 0x21D, 0xD); sElevatorCurrentFloorWindowId = AddWindow(&sElevatorCurrentFloorWindowTemplate);
AddTextPrinterParameterized(sElevatorCurrentFloorWindowId, FONT_NORMAL, gText_NowOn, 0, 2, 0xFF, NULL); LoadStdWindowGfx(sElevatorCurrentFloorWindowId, 0x21D, 0xD0);
floorname = sFloorNamePointers[gSpecialVar_0x8005]; DrawStdFrameWithCustomTileAndPalette(sElevatorCurrentFloorWindowId, FALSE, 0x21D, 0xD);
strwidth = GetStringWidth(FONT_NORMAL, floorname, 0); AddTextPrinterParameterized(sElevatorCurrentFloorWindowId, FONT_NORMAL, gText_NowOn, 0, 2, 0xFF, NULL);
AddTextPrinterParameterized(sElevatorCurrentFloorWindowId, FONT_NORMAL, floorname, 56 - strwidth, 16, 0xFF, NULL); floorname = sFloorNamePointers[gSpecialVar_0x8005];
PutWindowTilemap(sElevatorCurrentFloorWindowId); strwidth = GetStringWidth(FONT_NORMAL, floorname, 0);
CopyWindowToVram(sElevatorCurrentFloorWindowId, COPYWIN_FULL); AddTextPrinterParameterized(sElevatorCurrentFloorWindowId, FONT_NORMAL, floorname, 56 - strwidth, 16, 0xFF, NULL);
} PutWindowTilemap(sElevatorCurrentFloorWindowId);
CopyWindowToVram(sElevatorCurrentFloorWindowId, COPYWIN_FULL);
} }
void CloseElevatorCurrentFloorWindow(void) void CloseElevatorCurrentFloorWindow(void)
@@ -1164,91 +1165,92 @@ void ListMenu(void)
{ {
u8 taskId; u8 taskId;
struct Task *task; struct Task *task;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE)
if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
return;
taskId = CreateTask(Task_CreateScriptListMenu, 8);
task = &gTasks[taskId];
switch (gSpecialVar_0x8004)
{ {
taskId = CreateTask(Task_CreateScriptListMenu, 8); case LISTMENU_BADGES:
task = &gTasks[taskId]; task->data[0] = 4;
switch (gSpecialVar_0x8004) task->data[1] = 9;
{ task->data[2] = 1;
case LISTMENU_BADGES: task->data[3] = 1;
task->data[0] = 4; task->data[4] = 12;
task->data[1] = 9; task->data[5] = 7;
task->data[2] = 1; task->data[6] = 1;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 12; break;
task->data[5] = 7; case LISTMENU_SILPHCO_FLOORS:
task->data[6] = 1; task->data[0] = 7;
task->data[15] = taskId; task->data[1] = 12;
break; task->data[2] = 1;
case LISTMENU_SILPHCO_FLOORS: task->data[3] = 1;
task->data[0] = 7; task->data[4] = 8;
task->data[1] = 12; task->data[5] = 12;
task->data[2] = 1; task->data[6] = 0;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 8; task->data[7] = sElevatorScroll;
task->data[5] = 12; task->data[8] = sElevatorCursorPos;
task->data[6] = 0; break;
task->data[15] = taskId; case LISTMENU_ROCKET_HIDEOUT_FLOORS: // Multichoice used instead
task->data[7] = sElevatorScroll; task->data[0] = 4;
task->data[8] = sElevatorCursorPos; task->data[1] = 4;
break; task->data[2] = 1;
case LISTMENU_ROCKET_HIDEOUT_FLOORS: // Multichoice used instead task->data[3] = 1;
task->data[0] = 4; task->data[4] = 8;
task->data[1] = 4; task->data[5] = 8;
task->data[2] = 1; task->data[6] = 0;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 8; break;
task->data[5] = 8; case LISTMENU_DEPT_STORE_FLOORS: // Multichoice used instead
task->data[6] = 0; task->data[0] = 4;
task->data[15] = taskId; task->data[1] = 6;
break; task->data[2] = 1;
case LISTMENU_DEPT_STORE_FLOORS: // Multichoice used instead task->data[3] = 1;
task->data[0] = 4; task->data[4] = 8;
task->data[1] = 6; task->data[5] = 8;
task->data[2] = 1; task->data[6] = 0;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 8; break;
task->data[5] = 8; case LISTMENU_WIRELESS_LECTURE_HEADERS: // Multichoice used instead
task->data[6] = 0; task->data[0] = 4;
task->data[15] = taskId; task->data[1] = 4;
break; task->data[2] = 1;
case LISTMENU_WIRELESS_LECTURE_HEADERS: // Multichoice used instead task->data[3] = 1;
task->data[0] = 4; task->data[4] = 17;
task->data[1] = 4; task->data[5] = 8;
task->data[2] = 1; task->data[6] = 1;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 17; break;
task->data[5] = 8; case LISTMENU_BERRY_POWDER:
task->data[6] = 1; task->data[0] = 7;
task->data[15] = taskId; task->data[1] = 12;
break; task->data[2] = 16;
case LISTMENU_BERRY_POWDER: task->data[3] = 1;
task->data[0] = 7; task->data[4] = 17;
task->data[1] = 12; task->data[5] = 12;
task->data[2] = 16; task->data[6] = 0;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 17; break;
task->data[5] = 12; case LISTMENU_TRAINER_TOWER_FLOORS: // Mulitchoice used instead
task->data[6] = 0; task->data[0] = 3;
task->data[15] = taskId; task->data[1] = 3;
break; task->data[2] = 1;
case LISTMENU_TRAINER_TOWER_FLOORS: // Mulitchoice used instead task->data[3] = 1;
task->data[0] = 3; task->data[4] = 8;
task->data[1] = 3; task->data[5] = 6;
task->data[2] = 1; task->data[6] = 0;
task->data[3] = 1; task->data[15] = taskId;
task->data[4] = 8; break;
task->data[5] = 6; case 99:
task->data[6] = 0; break;
task->data[15] = taskId; default:
break; gSpecialVar_Result = 0x7F;
case 99: DestroyTask(taskId);
break; break;
default:
gSpecialVar_Result = 0x7F;
DestroyTask(taskId);
break;
}
} }
} }
+1 -1
View File
@@ -819,7 +819,7 @@ static void QL_LoadMapNormal(void)
ChooseAmbientCrySpecies(); ChooseAmbientCrySpecies();
SetDefaultFlashLevel(); SetDefaultFlashLevel();
sub_8110920(); sub_8110920();
sub_8111708(); QL_RestoreMapLayoutId();
LoadSaveblockMapHeader(); LoadSaveblockMapHeader();
InitMap(); InitMap();
} }
+112 -77
View File
@@ -69,11 +69,17 @@ enum {
// sQuestLogActionRecordBuffer should be large enough to fill a scene's script with the maximum number of actions // sQuestLogActionRecordBuffer should be large enough to fill a scene's script with the maximum number of actions
#define SCRIPT_BUFFER_SIZE (sizeof(gSaveBlock1Ptr->questLog[0].script) / sizeof(struct QuestLogAction)) #define SCRIPT_BUFFER_SIZE (sizeof(gSaveBlock1Ptr->questLog[0].script) / sizeof(struct QuestLogAction))
enum {
END_MODE_NONE,
END_MODE_FINISH,
END_MODE_SCENE,
};
struct PlaybackControl struct PlaybackControl
{ {
u8 state:4; u8 state:4;
u8 playingEvent:2; u8 playingEvent:2;
u8 sceneEndMode:2; u8 endMode:2;
u8 cursor; u8 cursor;
u8 timer; u8 timer;
u8 overlapTimer; u8 overlapTimer;
@@ -118,8 +124,8 @@ static void QLogCB_Playback(void);
static void SetPlayerInitialCoordsAtScene(u8); static void SetPlayerInitialCoordsAtScene(u8);
static void SetNPCInitialCoordsAtScene(u8); static void SetNPCInitialCoordsAtScene(u8);
static void RecordSceneEnd(void); static void RecordSceneEnd(void);
static void BackUpTrainerRematchesToVars(void); static void BackUpTrainerRematches(void);
static void BackUpMapLayoutToVar(void); static void BackUpMapLayout(void);
static void SetGameStateAtScene(u8); static void SetGameStateAtScene(u8);
static u8 TryRecordActionSequence(struct QuestLogAction *); static u8 TryRecordActionSequence(struct QuestLogAction *);
static void Task_BeginQuestLogPlayback(u8); static void Task_BeginQuestLogPlayback(u8);
@@ -128,19 +134,19 @@ static void QLPlayback_InitOverworldState(void);
static void SetPokemonCounts(void); static void SetPokemonCounts(void);
static u16 QuestLog_GetPartyCount(void); static u16 QuestLog_GetPartyCount(void);
static u16 QuestLog_GetBoxMonCount(void); static u16 QuestLog_GetBoxMonCount(void);
static void sub_8111688(void); static void RestoreTrainerRematches(void);
static void ReadQuestLogScriptFromSav1(u8, struct QuestLogAction *); static void ReadQuestLogScriptFromSav1(u8, struct QuestLogAction *);
static void QuestLog_BeginFadeAtEndOfScene(s8 delay); static void DoSceneEndTransition(s8 delay);
static void DoSkipToEndTransition(s8 delay);
static void QuestLog_AdvancePlayhead(void); static void QuestLog_AdvancePlayhead(void);
static void QuestLog_StartFinalScene(void); static void QuestLog_StartFinalScene(void);
static void Task_RunPlaybackCB(u8); static void Task_AvoidDisplay(u8);
static void QuestLog_PlayCurrentEvent(void); static void QuestLog_PlayCurrentEvent(void);
static void HandleShowQuestLogMessage(void); static void HandleShowQuestLogMessage(void);
static u8 GetQuestLogTextDisplayDuration(void); static u8 GetQuestLogTextDisplayDuration(void);
static void DrawSceneDescription(void); static void DrawSceneDescription(void);
static void CopyDescriptionWindowTiles(u8); static void CopyDescriptionWindowTiles(u8);
static void QuestLog_CloseTextWindow(void); static void QuestLog_CloseTextWindow(void);
static void QuestLog_SkipToEndOfPlayback(s8 delay);
static void QuestLog_WaitFadeAndCancelPlayback(void); static void QuestLog_WaitFadeAndCancelPlayback(void);
static bool8 FieldCB2_FinalScene(void); static bool8 FieldCB2_FinalScene(void);
static void Task_FinalScene_WaitFade(u8); static void Task_FinalScene_WaitFade(u8);
@@ -205,7 +211,7 @@ void SetQuestLogRecordAndPlaybackPointers(void *oldPointer)
if (gQuestLogState == QL_STATE_PLAYBACK) if (gQuestLogState == QL_STATE_PLAYBACK)
{ {
int r3; int r3;
for (r3 = 0; r3 < (int)NELEMS(gUnknown_203AE0C); r3++) for (r3 = 0; r3 < (int)ARRAY_COUNT(gUnknown_203AE0C); r3++)
if (gUnknown_203AE0C[r3]) if (gUnknown_203AE0C[r3])
gUnknown_203AE0C[r3] = (void *)gUnknown_203AE0C[r3] + offset; gUnknown_203AE0C[r3] = (void *)gUnknown_203AE0C[r3] + offset;
} }
@@ -287,18 +293,18 @@ static void QLogCB_Playback(void)
if (sPlaybackControl.state == 2) if (sPlaybackControl.state == 2)
sPlaybackControl.state = 0; sPlaybackControl.state = 0;
if (sPlaybackControl.sceneEndMode == 0) if (sPlaybackControl.endMode == END_MODE_NONE)
{ {
if (gQuestLogPlaybackState != QL_PLAYBACK_STATE_0 if (gQuestLogPlaybackState != QL_PLAYBACK_STATE_0
|| sPlaybackControl.state == 1 || sPlaybackControl.state == 1
|| (sPlaybackControl.cursor < NELEMS(gUnknown_203AE0C) || (sPlaybackControl.cursor < ARRAY_COUNT(gUnknown_203AE0C)
&& gUnknown_203AE0C[sPlaybackControl.cursor] != NULL)) && gUnknown_203AE0C[sPlaybackControl.cursor] != NULL))
QuestLog_PlayCurrentEvent(); QuestLog_PlayCurrentEvent();
else else
{ {
sPlaybackControl.sceneEndMode = 2; sPlaybackControl.endMode = END_MODE_SCENE;
LockPlayerFieldControls(); LockPlayerFieldControls();
QuestLog_BeginFadeAtEndOfScene(0); DoSceneEndTransition(0);
} }
} }
} }
@@ -328,8 +334,8 @@ void StartRecordingQuestLogAction(u16 eventId)
SetPokemonCounts(); SetPokemonCounts();
SetPlayerInitialCoordsAtScene(sCurrentSceneNum); SetPlayerInitialCoordsAtScene(sCurrentSceneNum);
SetNPCInitialCoordsAtScene(sCurrentSceneNum); SetNPCInitialCoordsAtScene(sCurrentSceneNum);
BackUpTrainerRematchesToVars(); BackUpTrainerRematches();
BackUpMapLayoutToVar(); BackUpMapLayout();
SetGameStateAtScene(sCurrentSceneNum); SetGameStateAtScene(sCurrentSceneNum);
gUnknown_203ADFC = 0; gUnknown_203ADFC = 0;
SetUpQuestLogAction(2, sQuestLogActionRecordBuffer, sizeof(sQuestLogActionRecordBuffer)); SetUpQuestLogAction(2, sQuestLogActionRecordBuffer, sizeof(sQuestLogActionRecordBuffer));
@@ -389,26 +395,32 @@ static void SetGameStateAtScene(u8 sceneNum)
CpuCopy16(gSaveBlock1Ptr->vars, questLog->vars, sizeof(gSaveBlock1Ptr->vars)); CpuCopy16(gSaveBlock1Ptr->vars, questLog->vars, sizeof(gSaveBlock1Ptr->vars));
} }
static void BackUpTrainerRematchesToVars(void) static void BackUpTrainerRematches(void)
{ {
u16 i, j; u16 i, j;
u16 sp0[4]; u16 vars[4];
for (i = 0; i < 4; i++) // Save the contents of gSaveBlock1Ptr->trainerRematches to the 4 saveblock
// vars starting at VAR_QLBAK_TRAINER_REMATCHES. The rematch array is 100 bytes
// long, but each byte is only ever 0 or 1 to indicate that a rematch is available.
// They're compressed into single bits across 4 u16 save vars, which is only enough
// to save 64 elements of gSaveBlock1Ptr->trainerRematches. 64 however is the maximum
// that could ever be used, as its the maximum number of NPCs per map (OBJECT_EVENT_TEMPLATES_COUNT).
for (i = 0; i < ARRAY_COUNT(vars); i++)
{ {
sp0[i] = 0; vars[i] = 0;
// 16 bits per var
for (j = 0; j < 16; j++) for (j = 0; j < 16; j++)
{ {
if (gSaveBlock1Ptr->trainerRematches[16 * i + j]) if (gSaveBlock1Ptr->trainerRematches[16 * i + j])
{ vars[i] += (1 << j);
sp0[i] += (1 << j);
}
} }
VarSet(VAR_QLBAK_TRAINER_REMATCHES + i, sp0[i]); VarSet(VAR_QLBAK_TRAINER_REMATCHES + i, vars[i]);
} }
} }
static void BackUpMapLayoutToVar(void) static void BackUpMapLayout(void)
{ {
VarSet(VAR_QLBAK_MAP_LAYOUT, gSaveBlock1Ptr->mapLayoutId); VarSet(VAR_QLBAK_MAP_LAYOUT, gSaveBlock1Ptr->mapLayoutId);
} }
@@ -623,7 +635,7 @@ void sub_81113E4(void)
CpuCopy16(questLog->flags, gSaveBlock1Ptr->flags, sizeof(gSaveBlock1Ptr->flags)); CpuCopy16(questLog->flags, gSaveBlock1Ptr->flags, sizeof(gSaveBlock1Ptr->flags));
CpuCopy16(questLog->vars, gSaveBlock1Ptr->vars, sizeof(gSaveBlock1Ptr->vars)); CpuCopy16(questLog->vars, gSaveBlock1Ptr->vars, sizeof(gSaveBlock1Ptr->vars));
sub_8111688(); RestoreTrainerRematches();
} }
struct PokemonAndSomethingElse struct PokemonAndSomethingElse
@@ -735,35 +747,36 @@ static u16 QuestLog_GetBoxMonCount(void)
return count; return count;
} }
static void sub_8111688(void) // Inverse of BackUpTrainerRematches
static void RestoreTrainerRematches(void)
{ {
u16 i, j; u16 i, j;
u16 sp0[4]; u16 vars[4];
for (i = 0; i < 4; i++) for (i = 0; i < ARRAY_COUNT(vars); i++)
{ {
sp0[i] = VarGet(VAR_QLBAK_TRAINER_REMATCHES + i); vars[i] = VarGet(VAR_QLBAK_TRAINER_REMATCHES + i);
// 16 bits per var
for (j = 0; j < 16; j++) for (j = 0; j < 16; j++)
{ {
if (sp0[i] & 1) if (vars[i] & 1)
gSaveBlock1Ptr->trainerRematches[16 * i + j] = 30; gSaveBlock1Ptr->trainerRematches[16 * i + j] = 30;
else else
gSaveBlock1Ptr->trainerRematches[16 * i + j] = 0; gSaveBlock1Ptr->trainerRematches[16 * i + j] = 0;
sp0[i] >>= 1; vars[i] >>= 1;
} }
} }
} }
void sub_8111708(void) // Inverse of BackUpMapLayout
void QL_RestoreMapLayoutId(void)
{ {
struct MapHeader sp0;
gSaveBlock1Ptr->mapLayoutId = VarGet(VAR_QLBAK_MAP_LAYOUT); gSaveBlock1Ptr->mapLayoutId = VarGet(VAR_QLBAK_MAP_LAYOUT);
if (gSaveBlock1Ptr->mapLayoutId == 0) if (gSaveBlock1Ptr->mapLayoutId == 0)
{ {
sp0 = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); struct MapHeader header = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
gSaveBlock1Ptr->mapLayoutId = sp0.mapLayoutId; gSaveBlock1Ptr->mapLayoutId = header.mapLayoutId;
} }
} }
@@ -775,7 +788,7 @@ static void ReadQuestLogScriptFromSav1(u8 sceneNum, struct QuestLogAction * a1)
u16 r9 = 0; u16 r9 = 0;
memset(a1, 0, 32 * sizeof(struct QuestLogAction)); memset(a1, 0, 32 * sizeof(struct QuestLogAction));
for (i = 0; i < NELEMS(gUnknown_203AE0C); i++) for (i = 0; i < ARRAY_COUNT(gUnknown_203AE0C); i++)
{ {
gUnknown_203AE0C[i] = NULL; gUnknown_203AE0C[i] = NULL;
} }
@@ -814,7 +827,7 @@ static void ReadQuestLogScriptFromSav1(u8 sceneNum, struct QuestLogAction * a1)
} }
} }
static void QuestLog_BeginFadeAtEndOfScene(s8 delay) static void DoSceneEndTransition(s8 delay)
{ {
FadeScreen(FADE_TO_BLACK, delay); FadeScreen(FADE_TO_BLACK, delay);
sQuestLogCB = QuestLog_AdvancePlayhead; sQuestLogCB = QuestLog_AdvancePlayhead;
@@ -822,19 +835,19 @@ static void QuestLog_BeginFadeAtEndOfScene(s8 delay)
static void QuestLog_AdvancePlayhead(void) static void QuestLog_AdvancePlayhead(void)
{ {
if (!gPaletteFade.active) if (gPaletteFade.active)
return;
LockPlayerFieldControls();
if (++sCurrentSceneNum < QUEST_LOG_SCENE_COUNT && gSaveBlock1Ptr->questLog[sCurrentSceneNum].startType != 0)
{ {
LockPlayerFieldControls(); sNumScenes--;
if (++sCurrentSceneNum < QUEST_LOG_SCENE_COUNT && gSaveBlock1Ptr->questLog[sCurrentSceneNum].startType != 0) QLPlayback_InitOverworldState();
{ }
sNumScenes--; else
QLPlayback_InitOverworldState(); {
} gQuestLogPlaybackState = QL_PLAYBACK_STATE_0;
else QuestLog_StartFinalScene();
{
gQuestLogPlaybackState = QL_PLAYBACK_STATE_0;
QuestLog_StartFinalScene();
}
} }
} }
@@ -855,48 +868,62 @@ void QuestLog_AdvancePlayhead_(void)
QuestLog_AdvancePlayhead(); QuestLog_AdvancePlayhead();
} }
bool8 QuestLog_SchedulePlaybackCB(void (*callback)(void)) #define tTimer data[0]
#define tState data[1]
#define DATA_IDX_CALLBACK 14 // data[14] and data[15]
// This is used to avoid recording or displaying certain windows or images, like a shop menu.
// During playback it returns TRUE (meaning the action should be avoided) and calls the
// provided callback, which would be used to e.g. destroy any resources that were set up to do
// whatever is being avoided. In all cases the provided callback will be QL_DestroyAbortedDisplay.
// If we are not currently in playback return FALSE (meaning allow the action to occur) and
// stop recording (if we are currently).
bool8 QL_AvoidDisplay(void (*callback)(void))
{ {
u8 taskId; u8 taskId;
switch (gQuestLogState) switch (gQuestLogState)
{ {
case QL_STATE_RECORDING: case QL_STATE_RECORDING:
QuestLog_CutRecording(); QuestLog_CutRecording();
break; break;
case QL_STATE_PLAYBACK: case QL_STATE_PLAYBACK:
gQuestLogPlaybackState = QL_PLAYBACK_STATE_3; gQuestLogPlaybackState = QL_PLAYBACK_STATE_3;
taskId = CreateTask(Task_RunPlaybackCB, 80); taskId = CreateTask(Task_AvoidDisplay, 80);
gTasks[taskId].data[0] = 0; gTasks[taskId].tTimer = 0;
gTasks[taskId].data[1] = 0; gTasks[taskId].tState = 0;
SetWordTaskArg(taskId, 14, (uintptr_t)callback); SetWordTaskArg(taskId, DATA_IDX_CALLBACK, (uintptr_t)callback);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
static void Task_RunPlaybackCB(u8 taskId) static void Task_AvoidDisplay(u8 taskId)
{ {
void (*routine)(void); void (*routine)(void);
s16 *data = gTasks[taskId].data; s16 *data = gTasks[taskId].data;
switch (data[1]) switch (tState)
{ {
case 0: case 0:
if (++data[0] == 0x7F) // Instead of displaying anything, wait and then end the scene.
if (++tTimer == 127)
{ {
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, 0); BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, 0);
sPlaybackControl.sceneEndMode = 2; sPlaybackControl.endMode = END_MODE_SCENE;
data[1]++; tState++;
} }
break; break;
case 1: case 1:
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
gQuestLogPlaybackState = QL_PLAYBACK_STATE_0; gQuestLogPlaybackState = QL_PLAYBACK_STATE_0;
routine = (void (*)(void)) GetWordTaskArg(taskId, 14);
// Call the provided function (if any). In practice this is always QL_DestroyAbortedDisplay
routine = (void (*)(void)) GetWordTaskArg(taskId, DATA_IDX_CALLBACK);
if (routine != NULL) if (routine != NULL)
routine(); routine();
DestroyTask(taskId); DestroyTask(taskId);
sQuestLogCB = QuestLog_AdvancePlayhead; sQuestLogCB = QuestLog_AdvancePlayhead;
} }
@@ -904,6 +931,9 @@ static void Task_RunPlaybackCB(u8 taskId)
} }
} }
#undef tTimer
#undef tState
static void QuestLog_PlayCurrentEvent(void) static void QuestLog_PlayCurrentEvent(void)
{ {
if (sPlaybackControl.state == 1) if (sPlaybackControl.state == 1)
@@ -924,7 +954,7 @@ static void QuestLog_PlayCurrentEvent(void)
sPlaybackControl.overlapTimer = 0; sPlaybackControl.overlapTimer = 0;
} }
} }
if (sPlaybackControl.cursor < NELEMS(gUnknown_203AE0C)) if (sPlaybackControl.cursor < ARRAY_COUNT(gUnknown_203AE0C))
{ {
if (sub_8113B44(gUnknown_203AE0C[sPlaybackControl.cursor]) == 1) if (sub_8113B44(gUnknown_203AE0C[sPlaybackControl.cursor]) == 1)
HandleShowQuestLogMessage(); HandleShowQuestLogMessage();
@@ -981,26 +1011,29 @@ bool8 sub_8111C2C(void)
void HandleQuestLogInput(void) void HandleQuestLogInput(void)
{ {
if (sPlaybackControl.sceneEndMode != 0) // Ignore input if we're currently ending a scene/playback
if (sPlaybackControl.endMode != END_MODE_NONE)
return; return;
if (JOY_NEW(A_BUTTON)) if (JOY_NEW(A_BUTTON))
{ {
sPlaybackControl.sceneEndMode = 2; // Pressed A, skip to next scene
sPlaybackControl.endMode = END_MODE_SCENE;
gQuestLogPlaybackState = QL_PLAYBACK_STATE_0; gQuestLogPlaybackState = QL_PLAYBACK_STATE_0;
QuestLog_BeginFadeAtEndOfScene(-3); DoSceneEndTransition(-3);
} }
else if (JOY_NEW(B_BUTTON)) else if (JOY_NEW(B_BUTTON))
{ {
sPlaybackControl.sceneEndMode = 1; // Pressed B, end playback
sPlaybackControl.endMode = END_MODE_FINISH;
gQuestLogPlaybackState = QL_PLAYBACK_STATE_0; gQuestLogPlaybackState = QL_PLAYBACK_STATE_0;
QuestLog_SkipToEndOfPlayback(-3); DoSkipToEndTransition(-3);
} }
} }
bool8 QuestLogScenePlaybackIsEnding(void) bool8 QuestLogScenePlaybackIsEnding(void)
{ {
if (sPlaybackControl.sceneEndMode != 0) if (sPlaybackControl.endMode != END_MODE_NONE)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@@ -1072,7 +1105,7 @@ static void QuestLog_CloseTextWindow(void)
CopyWindowToVram(sWindowIds[WIN_BOTTOM_BAR], COPYWIN_MAP); CopyWindowToVram(sWindowIds[WIN_BOTTOM_BAR], COPYWIN_MAP);
} }
static void QuestLog_SkipToEndOfPlayback(s8 delay) static void DoSkipToEndTransition(s8 delay)
{ {
FadeScreen(FADE_TO_BLACK, delay); FadeScreen(FADE_TO_BLACK, delay);
sQuestLogCB = QuestLog_WaitFadeAndCancelPlayback; sQuestLogCB = QuestLog_WaitFadeAndCancelPlayback;
@@ -1134,7 +1167,7 @@ static void Task_QuestLogScene_SavedGame(u8 taskId)
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
if (sPlaybackControl.sceneEndMode != 1) if (sPlaybackControl.endMode != END_MODE_FINISH)
{ {
GetMapNameGeneric(gStringVar1, gMapHeader.regionMapSectionId); GetMapNameGeneric(gStringVar1, gMapHeader.regionMapSectionId);
StringExpandPlaceholders(gStringVar4, gText_QuestLog_SavedGameAtLocation); StringExpandPlaceholders(gStringVar4, gText_QuestLog_SavedGameAtLocation);
@@ -1154,7 +1187,7 @@ static void Task_WaitAtEndOfQuestLog(u8 taskId)
{ {
struct Task *task = &gTasks[taskId]; struct Task *task = &gTasks[taskId];
if (JOY_NEW(A_BUTTON | B_BUTTON) || task->tTimer >= 127 || sPlaybackControl.sceneEndMode == 1) if (JOY_NEW(A_BUTTON | B_BUTTON) || task->tTimer >= 127 || sPlaybackControl.endMode == END_MODE_FINISH)
{ {
QuestLog_CloseTextWindow(); QuestLog_CloseTextWindow();
task->tTimer = 0; task->tTimer = 0;
@@ -1207,7 +1240,7 @@ static void Task_EndQuestLog(u8 taskId)
tState++; tState++;
break; break;
default: default:
if (sPlaybackControl.sceneEndMode == 1) if (sPlaybackControl.endMode == END_MODE_FINISH)
ShowMapNamePopup(TRUE); ShowMapNamePopup(TRUE);
CpuCopy16(sPalettesBackup, gPlttBufferUnfaded, PLTT_SIZE); CpuCopy16(sPalettesBackup, gPlttBufferUnfaded, PLTT_SIZE);
Free(sPalettesBackup); Free(sPalettesBackup);
@@ -1618,6 +1651,8 @@ void sub_8112B3C(void)
gQuestLogPlaybackState = QL_PLAYBACK_STATE_3; gQuestLogPlaybackState = QL_PLAYBACK_STATE_3;
break; break;
case QL_ACTION_WAIT: case QL_ACTION_WAIT:
// Nothing. The wait action uses sNextActionDelay to add a pause to playback.
// When the counter is finished and this is reached there's nothing else that needs to be done.
break; break;
case QL_ACTION_SCENE_END: case QL_ACTION_SCENE_END:
gQuestLogPlaybackState = QL_PLAYBACK_STATE_0; gQuestLogPlaybackState = QL_PLAYBACK_STATE_0;
+2 -2
View File
@@ -1818,7 +1818,7 @@ bool8 ScrCmd_showmoneybox(struct ScriptContext * ctx)
u8 y = ScriptReadByte(ctx); u8 y = ScriptReadByte(ctx);
u8 ignore = ScriptReadByte(ctx); u8 ignore = ScriptReadByte(ctx);
if (!ignore && QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE) if (!ignore && QL_AvoidDisplay(QL_DestroyAbortedDisplay) != TRUE)
DrawMoneyBox(GetMoney(&gSaveBlock1Ptr->money), x, y); DrawMoneyBox(GetMoney(&gSaveBlock1Ptr->money), x, y);
return FALSE; return FALSE;
} }
@@ -1848,7 +1848,7 @@ bool8 ScrCmd_showcoinsbox(struct ScriptContext * ctx)
u8 x = ScriptReadByte(ctx); u8 x = ScriptReadByte(ctx);
u8 y = ScriptReadByte(ctx); u8 y = ScriptReadByte(ctx);
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE) if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) != TRUE)
ShowCoinsWindow(GetCoins(), x, y); ShowCoinsWindow(GetCoins(), x, y);
return FALSE; return FALSE;
} }
+64 -60
View File
@@ -711,7 +711,7 @@ static void DrawVerticalMultichoiceMenu(u8 left, u8 top, u8 mcId, u8 ignoreBpres
u8 windowId; u8 windowId;
const struct MenuAction * list; const struct MenuAction * list;
if ((ignoreBpress & 2) || QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE) if ((ignoreBpress & 2) || QL_AvoidDisplay(QL_DestroyAbortedDisplay) != TRUE)
{ {
ignoreBpress &= 1; ignoreBpress &= 1;
count = gScriptMultiChoiceMenus[mcId].count; count = gScriptMultiChoiceMenus[mcId].count;
@@ -729,7 +729,7 @@ static void DrawVerticalMultichoiceMenu(u8 left, u8 top, u8 mcId, u8 ignoreBpres
height = GetMCWindowHeight(count); height = GetMCWindowHeight(count);
windowId = CreateWindowFromRect(left, top, width, height); windowId = CreateWindowFromRect(left, top, width, height);
SetStdWindowBorderStyle(windowId, FALSE); SetStdWindowBorderStyle(windowId, FALSE);
if (mcId == 30 || mcId == 13 || mcId == 41) if (mcId == MULTICHOICE_GAME_CORNER_TMPRIZES || mcId == MULTICHOICE_BIKE_SHOP || mcId == MULTICHOICE_GAME_CORNER_BATTLE_ITEM_PRIZES)
MultichoiceList_PrintItems(windowId, FONT_NORMAL, 8, 2, 14, count, list, 0, 2); MultichoiceList_PrintItems(windowId, FONT_NORMAL, 8, 2, 14, count, list, 0, 2);
else else
MultichoiceList_PrintItems(windowId, FONT_NORMAL, 8, 2, 14, count, list, 0, 2); MultichoiceList_PrintItems(windowId, FONT_NORMAL, 8, 2, 14, count, list, 0, 2);
@@ -769,7 +769,7 @@ static u8 GetMCWindowHeight(u8 count)
static void CreateMCMenuInputHandlerTask(u8 ignoreBpress, u8 count, u8 windowId, u8 mcId) static void CreateMCMenuInputHandlerTask(u8 ignoreBpress, u8 count, u8 windowId, u8 mcId)
{ {
u8 taskId; u8 taskId;
if (mcId == 39 || mcId == 47 || mcId == 50) if (mcId == MULTICHOICE_TRADE_CENTER_COLOSSEUM || mcId == MULTICHOICE_TRADE_COLOSSEUM_CRUSH || mcId == MULTICHOICE_TRADE_COLOSSEUM_2)
sDelay = 12; sDelay = 12;
else else
sDelay = 0; sDelay = 0;
@@ -845,11 +845,12 @@ bool8 ScriptMenu_YesNo(u8 unused, u8 stuff)
if (FuncIsActiveTask(Task_YesNoMenu_HandleInput) == TRUE) if (FuncIsActiveTask(Task_YesNoMenu_HandleInput) == TRUE)
return FALSE; return FALSE;
gSpecialVar_Result = SCR_MENU_UNSET; gSpecialVar_Result = SCR_MENU_UNSET;
if (!QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites))
{ if (QL_AvoidDisplay(QL_DestroyAbortedDisplay))
DisplayYesNoMenuDefaultYes(); return TRUE;
CreateTask(Task_YesNoMenu_HandleInput, 80);
} DisplayYesNoMenuDefaultYes();
CreateTask(Task_YesNoMenu_HandleInput, 80);
return TRUE; return TRUE;
} }
@@ -900,20 +901,22 @@ bool8 ScriptMenu_MultichoiceGrid(u8 left, u8 top, u8 multichoiceId, u8 a4, u8 co
if (FuncIsActiveTask(Hask_MultichoiceGridMenu_HandleInput) == TRUE) if (FuncIsActiveTask(Hask_MultichoiceGridMenu_HandleInput) == TRUE)
return FALSE; return FALSE;
gSpecialVar_Result = SCR_MENU_UNSET; gSpecialVar_Result = SCR_MENU_UNSET;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE)
{ if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
list = gScriptMultiChoiceMenus[multichoiceId].list; return TRUE;
count = gScriptMultiChoiceMenus[multichoiceId].count;
width = GetMenuWidthFromList(list, count) + 1; list = gScriptMultiChoiceMenus[multichoiceId].list;
rowCount = count / columnCount; count = gScriptMultiChoiceMenus[multichoiceId].count;
taskId = CreateTask(Hask_MultichoiceGridMenu_HandleInput, 80); width = GetMenuWidthFromList(list, count) + 1;
gTasks[taskId].data[4] = a4; rowCount = count / columnCount;
gTasks[taskId].data[6] = CreateWindowFromRect(left, top, width * columnCount, rowCount * 2); taskId = CreateTask(Hask_MultichoiceGridMenu_HandleInput, 80);
SetStdWindowBorderStyle(gTasks[taskId].data[6], FALSE); gTasks[taskId].data[4] = a4;
MultichoiceGrid_PrintItems(gTasks[taskId].data[6], FONT_NORMAL_COPY_1, width * 8, 16, columnCount, rowCount, list); gTasks[taskId].data[6] = CreateWindowFromRect(left, top, width * columnCount, rowCount * 2);
MultichoiceGrid_InitCursor(gTasks[taskId].data[6], FONT_NORMAL_COPY_1, 0, 1, width * 8, columnCount, rowCount, 0); SetStdWindowBorderStyle(gTasks[taskId].data[6], FALSE);
ScheduleBgCopyTilemapToVram(0); MultichoiceGrid_PrintItems(gTasks[taskId].data[6], FONT_NORMAL_COPY_1, width * 8, 16, columnCount, rowCount, list);
} MultichoiceGrid_InitCursor(gTasks[taskId].data[6], FONT_NORMAL_COPY_1, 0, 1, width * 8, columnCount, rowCount, 0);
ScheduleBgCopyTilemapToVram(0);
return TRUE; return TRUE;
} }
@@ -1032,7 +1035,7 @@ bool8 ScriptMenu_ShowPokemonPic(u16 species, u8 x, u8 y)
{ {
u8 spriteId; u8 spriteId;
u8 taskId; u8 taskId;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) == TRUE) if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
return TRUE; return TRUE;
if (FindTaskIdByFunc(Task_ScriptShowMonPic) != 0xFF) if (FindTaskIdByFunc(Task_ScriptShowMonPic) != 0xFF)
return FALSE; return FALSE;
@@ -1116,7 +1119,7 @@ bool8 OpenMuseumFossilPic(void)
{ {
u8 spriteId; u8 spriteId;
u8 taskId; u8 taskId;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) == TRUE) if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
return TRUE; return TRUE;
if (FindTaskIdByFunc(Task_WaitMuseumFossilPic) != 0xFF) if (FindTaskIdByFunc(Task_WaitMuseumFossilPic) != 0xFF)
return FALSE; return FALSE;
@@ -1169,7 +1172,7 @@ static void DestroyScriptMenuWindow(u8 windowId)
RemoveWindow(windowId); RemoveWindow(windowId);
} }
void QLPlaybackCB_DestroyScriptMenuMonPicSprites(void) void QL_DestroyAbortedDisplay(void)
{ {
u8 taskId; u8 taskId;
s16 *data; s16 *data;
@@ -1205,44 +1208,45 @@ void DrawSeagallopDestinationMenu(void)
u8 windowId; u8 windowId;
u8 i; u8 i;
gSpecialVar_Result = SCR_MENU_UNSET; gSpecialVar_Result = SCR_MENU_UNSET;
if (QuestLog_SchedulePlaybackCB(QLPlaybackCB_DestroyScriptMenuMonPicSprites) != TRUE)
if (QL_AvoidDisplay(QL_DestroyAbortedDisplay) == TRUE)
return;
if (gSpecialVar_0x8005 == 1)
{ {
if (gSpecialVar_0x8005 == 1) if (gSpecialVar_0x8004 < SEAGALLOP_FIVE_ISLAND)
{ r4 = SEAGALLOP_FIVE_ISLAND;
if (gSpecialVar_0x8004 < SEAGALLOP_FIVE_ISLAND)
r4 = SEAGALLOP_FIVE_ISLAND;
else
r4 = SEAGALLOP_FOUR_ISLAND;
nitems = 5;
top = 2;
}
else else
{ r4 = SEAGALLOP_FOUR_ISLAND;
r4 = SEAGALLOP_VERMILION_CITY; nitems = 5;
nitems = 6; top = 2;
top = 0;
}
cursorWidth = GetMenuCursorDimensionByFont(FONT_NORMAL, 0);
fontHeight = GetFontAttribute(FONT_NORMAL, FONTATTR_MAX_LETTER_HEIGHT);
windowId = CreateWindowFromRect(17, top, 11, nitems * 2);
SetStdWindowBorderStyle(windowId, FALSE);
for (i = 0; i < nitems - 2; i++)
{
if (r4 != gSpecialVar_0x8004)
AddTextPrinterParameterized(windowId, FONT_NORMAL, sSeagallopDestStrings[r4], cursorWidth, i * 16 + 2, 0xFF, NULL);
else
i--;
r4++;
if (r4 == SEAGALLOP_CINNABAR_ISLAND)
r4 = SEAGALLOP_VERMILION_CITY;
}
AddTextPrinterParameterized(windowId, FONT_NORMAL, gText_Other, cursorWidth, i * 16 + 2, 0xFF, NULL);
i++;
AddTextPrinterParameterized(windowId, FONT_NORMAL, gOtherText_Exit, cursorWidth, i * 16 + 2, 0xFF, NULL);
Menu_InitCursor(windowId, FONT_NORMAL, 0, 2, 16, nitems, 0);
CreateMCMenuInputHandlerTask(FALSE, nitems, windowId, 0xFF);
ScheduleBgCopyTilemapToVram(0);
} }
else
{
r4 = SEAGALLOP_VERMILION_CITY;
nitems = 6;
top = 0;
}
cursorWidth = GetMenuCursorDimensionByFont(FONT_NORMAL, 0);
fontHeight = GetFontAttribute(FONT_NORMAL, FONTATTR_MAX_LETTER_HEIGHT);
windowId = CreateWindowFromRect(17, top, 11, nitems * 2);
SetStdWindowBorderStyle(windowId, FALSE);
for (i = 0; i < nitems - 2; i++)
{
if (r4 != gSpecialVar_0x8004)
AddTextPrinterParameterized(windowId, FONT_NORMAL, sSeagallopDestStrings[r4], cursorWidth, i * 16 + 2, 0xFF, NULL);
else
i--;
r4++;
if (r4 == SEAGALLOP_CINNABAR_ISLAND)
r4 = SEAGALLOP_VERMILION_CITY;
}
AddTextPrinterParameterized(windowId, FONT_NORMAL, gText_Other, cursorWidth, i * 16 + 2, 0xFF, NULL);
i++;
AddTextPrinterParameterized(windowId, FONT_NORMAL, gOtherText_Exit, cursorWidth, i * 16 + 2, 0xFF, NULL);
Menu_InitCursor(windowId, FONT_NORMAL, 0, 2, 16, nitems, 0);
CreateMCMenuInputHandlerTask(FALSE, nitems, windowId, 0xFF);
ScheduleBgCopyTilemapToVram(0);
} }
u16 GetSelectedSeagallopDestination(void) u16 GetSelectedSeagallopDestination(void)
+375 -372
View File
File diff suppressed because it is too large Load Diff