diff options
Diffstat (limited to 'src/subtask')
| -rw-r--r-- | src/subtask/subtaskAuxCutscene.c | 157 | ||||
| -rw-r--r-- | src/subtask/subtaskFastTravel.c | 191 | ||||
| -rw-r--r-- | src/subtask/subtaskLocalMapHint.c | 96 | ||||
| -rw-r--r-- | src/subtask/subtaskMapHint.c | 71 | ||||
| -rw-r--r-- | src/subtask/subtaskWorldEvent.c | 103 |
5 files changed, 618 insertions, 0 deletions
diff --git a/src/subtask/subtaskAuxCutscene.c b/src/subtask/subtaskAuxCutscene.c new file mode 100644 index 00000000..f916ae62 --- /dev/null +++ b/src/subtask/subtaskAuxCutscene.c @@ -0,0 +1,157 @@ +/** + * @file subtaskAuxCutscene.c + * + * @brief Aux Cutscene Subtask + */ +#include "area.h" +#include "asm.h" +#include "common.h" +#include "fileselect.h" +#include "flags.h" +#include "functions.h" +#include "game.h" +#include "main.h" +#include "menu.h" +#include "message.h" +#include "room.h" +#include "screen.h" +#include "sound.h" +#include "subtask.h" + +typedef void(AuxCutsceneState)(void); +typedef void(CutsceneMainState)(void); + +static AuxCutsceneState AuxCutscene_Init; +static AuxCutsceneState AuxCutscene_Main; +static AuxCutsceneState AuxCutscene_Exit; + +CutsceneMainState CutsceneMain_Init; +CutsceneMainState CutsceneMain_Update; +CutsceneMainState CutsceneMain_Exit; + +typedef struct { + u8 area; + RoomID room : 8; + u8 _2; + u8 _3; + u16 x; + u16 y; +} CutsceneData; +static const CutsceneData sCutsceneData[]; + +void Subtask_AuxCutscene(void) { + static AuxCutsceneState* const sStates[] = { + AuxCutscene_Init, + AuxCutscene_Main, + AuxCutscene_Exit, + }; + + sStates[gMenu.menuType](); +} + +static void AuxCutscene_Init(void) { + const CutsceneData* p = &sCutsceneData[gUI.field_0x3]; + gRoomControls.area = p->area; + gRoomControls.room = p->room; + LoadGfxGroups(); + gArea.localFlagOffset = GetFlagBankOffset(gRoomControls.area); + SetCurrentRoomPropertyList(p->area, p->room); + LoadAuxiliaryRoom(p->area, p->room); + gRoomControls.scroll_x = gRoomControls.origin_x + p->x; + gRoomControls.scroll_y = gRoomControls.origin_y + p->y; + gMenu.field_0x0 = p->_2; + gMenu.field_0x3 = p->_3 & 0xf; + gMenu.field_0xc = (void*)p; + gMenu.menuType++; + gMenu.overlayType = 0; + gMenu.transitionTimer = 300; + AuxCutscene_Main(); // init +} + +static void AuxCutscene_Main(void) { + static CutsceneMainState* const sStates[] = { + CutsceneMain_Init, + CutsceneMain_Update, + CutsceneMain_Exit, + }; + + sStates[gMenu.field_0x0](); + FlushSprites(); + UpdateEntities(); + DrawEntities(); + CopyOAM(); + UpdateScroll(); + UpdateBgAnimations(); + UpdateManagers(); + UpdateScrollVram(); +} + +static const CutsceneData sCutsceneData[] = { + { AREA_MINISH_WOODS, 0, 0, 0, 336, 528 }, + { AREA_HYRULE_FIELD, 1, 1, 0, 472, 312 }, + { AREA_HYRULE_CASTLE, 2, 1, 1, 16, 16 }, + { AREA_SANCTUARY, 2, 1, 2, 0, 0 }, + { AREA_EZLO_CUTSCENE, 0, 1, 3, 0, 0 }, + { AREA_HOUSE_INTERIORS_2, 16, 1, 4, 0, 0 }, + { AREA_DARK_HYRULE_CASTLE_OUTSIDE, 0, 1, 5, 0, 40 }, + { AREA_FORTRESS_OF_WINDS, 28, 2, 0, 0, 0 }, + { AREA_FORTRESS_OF_WINDS, 29, 2, 1, 0, 0 }, + { AREA_DARK_HYRULE_CASTLE, 14, 2, 2, 16, 16 }, +}; + +static void AuxCutscene_Exit(void) { + u32 flag = sCutsceneData[gUI.field_0x3]._3; + if (flag & 0xF0) { + MenuFadeIn(2, flag >> 4); + } else { + gUI.nextToLoad = 3; // Subtask_FadeOut + SetFadeInverted(0x10); + MessageInitialize(); + } +} + +// end of auxCutscene? + +void sub_08051F78(void) { + u32 idx = gUI.field_0x3; + const CutsceneData* p = &sCutsceneData[idx]; + sub_08051F9C(p->area, p->room, p->x, p->y); +} + +void sub_08051F9C(u32 a1, u32 a2, u32 a3, u32 a4) { + u32 tmp = gScreen.lcd.displayControl & (DISPCNT_WIN0_ON | DISPCNT_WIN1_ON); + sub_08052FF4(a1, a2); + gRoomControls.scroll_x = gRoomControls.origin_x + a3; + gRoomControls.scroll_y = gRoomControls.origin_y + a4; + InitializeCamera(); + gUpdateVisibleTiles = 1; + gUsedPalettes = 0; + gScreen.lcd.displayControl |= tmp; +} + +void sub_08051FF0(void) { + sub_0804B0B0(gMenu.field_0xc[0], gMenu.field_0xc[1]); +} + +void sub_08052004(void) { + gMenu.menuType = 2; +} + +void sub_08052010(void) { + InitSoundPlayingInfo(); + MessageInitialize(); + DispReset(1); + MemClear(gBG1Buffer, sizeof(gBG1Buffer)); + MemClear(gBG2Buffer, sizeof(gBG2Buffer)); + sub_080A4D34(); + LoadPaletteGroup(0xA); + SetColor(0, 0); + LoadGfxGroup(4); + MemClear((void*)0x06000000, 0x20); + MemClear(&gGenericMenu, sizeof(gGenericMenu)); + gScreen.lcd.displayControl |= DISPCNT_OBJ_ON; + gScreen.bg1.control = BGCNT_PRIORITY(1) | BGCNT_SCREENBASE(28) | BGCNT_CHARBASE(0); + gScreen.bg2.control = BGCNT_PRIORITY(1) | BGCNT_SCREENBASE(29) | BGCNT_CHARBASE(1); + gScreen.bg1.updated = 1; + gScreen.bg2.updated = 1; +} diff --git a/src/subtask/subtaskFastTravel.c b/src/subtask/subtaskFastTravel.c new file mode 100644 index 00000000..0f657cb7 --- /dev/null +++ b/src/subtask/subtaskFastTravel.c @@ -0,0 +1,191 @@ +/** + * @file subtaskFastTravel.c + * @ingroup Subtasks + * + * @brief Fast Travel Subtask + */ +#include "subtask.h" +#include "common.h" +#include "menu.h" +#include "functions.h" +#include "message.h" +#include "sound.h" +#include "save.h" + +extern void (*const Subtask_FastTravel_Functions[])(void); +void sub_080A6E70(void); +u32 sub_080A6D74(u32); +void sub_080A6EE0(u32 param_1); + +extern const ScreenTransitionData gUnk_08128024[]; + +void Subtask_FastTravel(void) { + FlushSprites(); + Subtask_FastTravel_Functions[gMenu.menuType](); + if (gMenu.field_0x0 != 0) { + sub_080A6E70(); + } + sub_080A6498(); + CopyOAM(); +} + +void Subtask_FastTravel_0(void) { + sub_080A4D34(); + sub_080A4DB8(0xd); + sub_080A6290(); + gMenu.field_0x3 = sub_080A6D74(0); + SetMenuType(1); + SetFade(FADE_INSTANT, 8); +} + +void Subtask_FastTravel_1(void) { + u32 uVar1; + u32 uVar2; + + if (gFadeControl.active) { + return; + } + + gMenu.field_0x0 = 1; + uVar2 = 0; + + switch (gInput.newKeys) { + case DPAD_LEFT: + case DPAD_UP: + uVar2 = -1; + break; + case DPAD_RIGHT: + case DPAD_DOWN: + uVar2 = 1; + break; + case A_BUTTON: + case START_BUTTON: + gMenu.field_0x0 = 2; + SetMenuType(2); + MessageFromTarget(TEXT_INDEX(TEXT_WINDCRESTS, 0x04)); + break; + case B_BUTTON: + gMenu.field_0x0 = 3; + SetMenuType(3); + break; + } + + if (uVar2) { + uVar1 = sub_080A6D74(uVar2); + if (uVar1 != gMenu.field_0x3) { + gMenu.field_0x3 = uVar1; + SoundReq(SFX_TEXTBOX_CHOICE); + } + } +} + +u32 sub_080A6D74(u32 param_1) { + u32 uVar1; + u32 uVar2; + u32 uVar3; + + uVar3 = gSave.windcrests >> 0x18; + uVar2 = gMenu.field_0x3; + if (param_1 == 0) { + uVar2 = 0; + if ((uVar3 & 1) == 0) { + while (++uVar2 < 8 && ((1 << uVar2) & uVar3) == 0) {} + } + } else if (uVar3 != 0) { + do { + uVar2 = (uVar2 + param_1 + 8) & 7; + } while ((1 << uVar2 & uVar3) == 0); + } + return uVar2 & 7; +} + +void Subtask_FastTravel_2(void) { + u32 tmp; + switch (sub_08056338()) { +#ifdef EU + case 0: + gMenu.field_0x0 = 2; + break; + case 1: + gMenu.field_0x0 = 3; + tmp = 1; + break; + default: + return; + } + + if (tmp) { + SetMenuType(3); + } +#else + case 0: + gMenu.field_0x0 = 2; + tmp = 3; + break; + case 1: + tmp = 1; + break; + default: + return; + } + SetMenuType(tmp); +#endif +} + +void Subtask_FastTravel_3(void) { + if (gMenu.field_0x0 == 2) { + SetMenuType(4); + SetFade(FADE_IN_OUT | FADE_INSTANT, 8); + } else { + ResetPlayerAnimationAndAction(); + sub_080042D0(&gPlayerEntity, (u32)gPlayerEntity.animIndex, gPlayerEntity.spriteIndex); + Subtask_Exit(); + gPauseMenuOptions.disabled = 0; + SoundReq(SFX_MENU_CANCEL); + } +} + +void Subtask_FastTravel_4(void) { + if (gFadeControl.active == 0) { + sub_080A71F4(&gUnk_08128024[gMenu.field_0x3]); + } +} + +void sub_080A6E70(void) { + u32 frameIndex; + u32 i; + + gOamCmd._4 = 0; + gOamCmd._6 = 0; + gOamCmd._8 = 0x400; + gGenericMenu.unk2c++; + sub_080A6EE0(gMenu.field_0x3); + if ((gGenericMenu.unk2c & 0x10) != 0) { + frameIndex = 0x5d; + } else { + frameIndex = 0x5e; + } + + DrawDirect(DRAW_DIRECT_SPRITE_INDEX, frameIndex); + for (i = 0; i < 8; i++) { + if ((gSave.windcrests & (1 << (i + 0x18))) != 0) { + sub_080A6EE0(i); + DrawDirect(DRAW_DIRECT_SPRITE_INDEX, 0x5c); + } + } +} + +void sub_080A6EE0(u32 param_1) { + u32 x; + u32 y; + RoomHeader* roomHeader; + const ScreenTransitionData* ptr = &gUnk_08128024[param_1]; + + x = (u16)ptr->playerXPos; + y = (u16)ptr->playerYPos; + roomHeader = &gAreaRoomHeaders[ptr->area][ptr->room]; + x += roomHeader->map_x; + y += roomHeader->map_y; + gOamCmd.x = (s32)(x * DISPLAY_HEIGHT) / 0xf90 + 0x28; + gOamCmd.y = (s32)(y * DISPLAY_HEIGHT) / 0xf90 + 0xc; +} diff --git a/src/subtask/subtaskLocalMapHint.c b/src/subtask/subtaskLocalMapHint.c new file mode 100644 index 00000000..8f9bb133 --- /dev/null +++ b/src/subtask/subtaskLocalMapHint.c @@ -0,0 +1,96 @@ +/** + * @file subtaskLocalMapHint.c + * @ingroup Subtasks + * + * @brief Local Map Hint Subtask + */ +#include "menu.h" +#include "subtask.h" +#include "kinstone.h" +#include "functions.h" +#include "screen.h" +#include "sound.h" +#include "common.h" + +void Subtask_LocalMapHint() { + extern void (*const gUnk_08128F1C[])(void); + const struct_gUnk_08128E94* ptr; + FlushSprites(); + gUnk_08128F1C[gMenu.menuType](); + ptr = &gUnk_08128E94[gMenu.field_0x3]; + gScreen.bg1.yOffset = -ptr->unk5; + gScreen.bg2.yOffset = gMenu.field_0xa - (s8)ptr->unk6; + CopyOAM(); +} + +void sub_080A6B04(void) { + u32 bVar1; + u32 uVar2; + u32 uVar3; + u32 uVar4; + int uVar6; + u32 uVar7; + const KinstoneWorldEvent* ptr; + const WorldEvent* ptr2; + const struct_gUnk_08128E94* ptr3; + + sub_080A4D34(); + sub_080A4DB8(6); + ptr = &gKinstoneWorldEvents[gFuseInfo.kinstoneId]; + ptr2 = &gWorldEvents[ptr->worldEventId]; + bVar1 = ptr->unk7; + uVar3 = ptr2->_c; + uVar4 = ptr2->_e; + uVar2 = sub_080A6A80(uVar3, uVar4)->_4; + gMenu.field_0x3 = uVar2; + gGenericMenu.unk2b = 1; + sub_080A67C4(uVar2); + sub_080A6FB4(uVar2, 2); + SetColor(0, 0x475f); + SetColor(0x5f, 0x475f); + MemFill16(0x5001, &gBG3Buffer, sizeof(gBG3Buffer)); + if ((gPlayerState.flags & PL_NO_CAP) != 0) { + uVar7 = 101; + } else { + uVar7 = 100; + } + sub_080A698C(gRoomTransition.player_status.overworld_map_x, gRoomTransition.player_status.overworld_map_y, + DRAW_DIRECT_SPRITE_INDEX, uVar7 + 0x100); + sub_080A698C(uVar3, uVar4, DRAW_DIRECT_SPRITE_INDEX, bVar1 + 100); + uVar4 = sub_080A69E0(uVar3, uVar4) >> 0x10; + ptr3 = &gUnk_08128E94[gMenu.field_0x3]; + gMenu.field_0xa = 0; + if (ptr3->unk2 != 0) { + uVar6 = uVar4 - 0x3c; + if (uVar6 > 0) { + if (ptr3->unk2 < uVar6) { + uVar6 = ptr3->unk2; + } + gMenu.field_0xa = uVar6; + } + } + gMenu.transitionTimer = 30; + SetMenuType(1); + SetFade(FADE_INSTANT, 8); +} + +void sub_080A6C1C(void) { + if (!gFadeControl.active) { + switch (gMenu.transitionTimer) { + case 0: + sub_080A66D0(); + switch (gInput.newKeys) { + case A_BUTTON: + case B_BUTTON: + case START_BUTTON: + Subtask_Exit(); + break; + } + return; + case 1: + SoundReq(SFX_103); + break; + } + gMenu.transitionTimer--; + } +} diff --git a/src/subtask/subtaskMapHint.c b/src/subtask/subtaskMapHint.c new file mode 100644 index 00000000..2a802f2b --- /dev/null +++ b/src/subtask/subtaskMapHint.c @@ -0,0 +1,71 @@ +/** + * @file subtask.c + * @ingroup Subtasks + * + * @brief Map Hint Subtask + */ +#include "menu.h" +#include "functions.h" +#include "subtask.h" +#include "common.h" +#include "main.h" +#include "sound.h" +#include "save.h" +#include "flags.h" +#include "fileselect.h" +#include "kinstone.h" +#include "game.h" + +void sub_080A6438(); + +void Subtask_MapHint(void) { + extern void (*const Subtask_MapHint_Functions[])(void); + FlushSprites(); + Subtask_MapHint_Functions[gMenu.menuType](); + if ((gGenericMenu.unk2c & 0x20) != 0) { + sub_080A6438(); + } + sub_080A6498(); + CopyOAM(); +} + +void Subtask_MapHint_0(void) { + extern const u16 gUnk_08128F4C[]; + u32 val; + sub_080A4D34(); + sub_080A4DB8(4); + sub_080A6290(); + gScreen.lcd.displayControl = gScreen.lcd.displayControl & 0xf7ff; + SetColor(0, gPaletteBuffer[0x51]); + val = gUnk_08128F4C[gUI.field_0x3]; + gSave.field_0x20 |= val; + gGenericMenu.unk10.h[1] = val & gGenericMenu.unk10.h[0]; + gGenericMenu.unk10.h[0] = 0; + gMenu.transitionTimer = 60; + SetMenuType(1); + SetFade(FADE_INSTANT, 8); +} + +void Subtask_MapHint_1(void) { + if (!gFadeControl.active) { + gGenericMenu.unk2c++; + switch (gMenu.transitionTimer) { + case 0x1e: + gGenericMenu.unk10.h[0] = gGenericMenu.unk10.h[1]; + gGenericMenu.unk2c = 0x20; + SoundReq(SFX_103); + default: + gMenu.transitionTimer--; + break; + case 0: + switch (gInput.newKeys) { + case A_BUTTON: + case B_BUTTON: + case START_BUTTON: + Subtask_Exit(); + break; + } + break; + } + } +} diff --git a/src/subtask/subtaskWorldEvent.c b/src/subtask/subtaskWorldEvent.c new file mode 100644 index 00000000..bae3e921 --- /dev/null +++ b/src/subtask/subtaskWorldEvent.c @@ -0,0 +1,103 @@ +/** + * @file subtaskWorldEvent.c + * + * @brief World Event Subtask + */ +#include "area.h" +#include "asm.h" +#include "common.h" +#include "flags.h" +#include "functions.h" +#include "game.h" +#include "kinstone.h" +#include "main.h" +#include "menu.h" +#include "message.h" +#include "room.h" +#include "screen.h" +#include "subtask.h" + +void Subtask_WorldEvent_Update(void); + +extern void (*const gUnk_080FE2A0[])(void); +void Subtask_WorldEvent(void) { +#if !(defined(DEMO_USA) || defined(DEMO_JP)) + gUnk_080FE2A0[gMenu.menuType](); +#endif +} + +void Subtask_WorldEvent_Init(void) { + const WorldEvent* ptr = &gWorldEvents[gUI.field_0x3]; + gMenu.field_0x0 = ptr->type; + gMenu.field_0x3 = ptr->entity_idx; + gMenu.field_0x4 = gUI.field_0x3; + gMenu.field_0xc = (u8*)ptr; + gMenu.menuType++; + gMenu.overlayType = 0; + gMenu.transitionTimer = 300; + DispReset(0); + sub_08054974(gUI.field_0x3, 1); + sub_0806F364(); + ClearRoomFlag(0xff); + Subtask_WorldEvent_Update(); +} + +extern void (*const gWorldEventFunctions[])(void); + +void Subtask_WorldEvent_Update(void) { + gWorldEventFunctions[gMenu.field_0x0](); + FlushSprites(); + UpdateEntities(); + DrawEntities(); + CopyOAM(); + UpdateScroll(); + UpdateBgAnimations(); + UpdateScrollVram(); +} + +void Subtask_WorldEvent_End(void) { + MessageInitialize(); + sub_0806F38C(); + if (gKinstoneWorldEvents[gFuseInfo.kinstoneId].unk7 != 0) { + // Show the map hint. + MenuFadeIn(SUBTASK_LOCALMAPHINT, gUI.field_0x3); + } else { + gUI.nextToLoad = 3; // Subtask_FadeOut + SetFade(FADE_IN_OUT | FADE_BLACK_WHITE | FADE_INSTANT, 0x10); + } +} + +void sub_08054968(void) { + gMenu.menuType = 2; +} + +// Controls showing the world event cutscene? +void sub_08054974(u32 worldEventId, bool32 param_2) { + const WorldEvent* ptr = &gWorldEvents[worldEventId]; + SetCurrentRoomPropertyList(ptr->area, ptr->room); + gRoomControls.area = ptr->area; + gRoomControls.room = ptr->room; + LoadGfxGroups(); + gArea.localFlagOffset = GetFlagBankOffset(gRoomControls.area); + if (param_2) { + LoadAuxiliaryRoom(ptr->area, ptr->room); + } else { + sub_08052FF4(ptr->area, ptr->room); + InitializeCamera(); + gUpdateVisibleTiles = 1; + } + gScreen.lcd.displayControl &= 0x1fff; + gRoomControls.scroll_x = gRoomControls.origin_x + ptr->offsetX; + gRoomControls.scroll_y = gRoomControls.origin_y + ptr->offsetY; + if (ptr->area == AREA_HYRULE_TOWN) { + TryLoadPrologueHyruleTown(); + } + sub_08018710(gUI.field_0x3); +} + +void sub_08054A14(s32 worldEventId) { + const WorldEvent* ptr = &gWorldEvents[worldEventId]; + if (ptr->bank < 0xe) { + SetLocalFlagByBank(gLocalFlagBanks[ptr->bank], ptr->flag); + } +} |
