mirror of
https://github.com/zeldaret/tmc
synced 2026-05-23 23:05:38 -04:00
285 lines
8.2 KiB
C
285 lines
8.2 KiB
C
/**
|
|
* @file enterPortalSubtask.c
|
|
* @ingroup Subtasks
|
|
*
|
|
* @brief Enter Portal Subtask
|
|
*/
|
|
#include "enterPortalSubtask.h"
|
|
|
|
#include "area.h"
|
|
#include "common.h"
|
|
#include "entity.h"
|
|
#include "fileselect.h"
|
|
#include "functions.h"
|
|
#include "game.h"
|
|
#include "main.h"
|
|
#include "object.h"
|
|
#include "screen.h"
|
|
#include "subtask.h"
|
|
|
|
extern void ClearArmosData(void);
|
|
extern void sub_080300C4(void);
|
|
|
|
bool32 sub_0804AD18(void);
|
|
void sub_0804AD6C(RoomControls*);
|
|
bool32 sub_0804ACA8(void);
|
|
|
|
// Entities spawned inside the portal transition cutscene.
|
|
const EntityData gUnk_080D3E90[] = {
|
|
{ OBJECT, 15, PORTAL_FALLING_PLAYER, 0, 0, 132, 156, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 0, 6, 120, 208, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 1, 1, 132, 160, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 2, 2, 96, 192, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 3, 3, 128, 208, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 5, 0, 120, 104, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 6, 1, 216, 200, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 7, 2, 120, 292, 0 },
|
|
{ OBJECT, 15, PORTAL_MUSHROOM_STALKS, 8, 3, 17, 200, 0 },
|
|
{ 0xff, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
const EntityData gUnk_080D3F30[] = {
|
|
{ OBJECT, 15, PORTAL_FALLING_PLAYER, 0, 0, 132, 156, 0 }, //
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 0, 6, 120, 200, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 1, 3, 132, 160, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 2, 2, 96, 192, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 3, 1, 128, 208, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 5, 0, 120, 104, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 6, 1, 216, 200, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 7, 2, 120, 292, 0 },
|
|
{ OBJECT, 15, MACRO_CRYSTAL, 8, 3, 17, 200, 0 },
|
|
{ 0xff, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
const EntityData gUnk_080D3FD0[] = {
|
|
{ OBJECT, 15, PORTAL_FALLING_PLAYER, 0, 0, 132, 156, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 0, 6, 120, 208, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 1, 1, 132, 160, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 2, 2, 96, 192, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 3, 3, 128, 208, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 5, 0, 120, 104, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 6, 1, 216, 200, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 7, 2, 120, 300, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 8, 3, 17, 200, 0 },
|
|
{ 0xff, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
const EntityData gUnk_080D4070[] = {
|
|
{ OBJECT, 15, PORTAL_FALLING_PLAYER, 0, 0, 132, 156, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 9, 6, 120, 208, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 10, 1, 132, 160, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 11, 2, 96, 192, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 12, 3, 128, 208, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 14, 0, 120, 104, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 15, 1, 216, 200, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 16, 2, 120, 300, 0 },
|
|
{ OBJECT, 15, MACRO_LEAF, 17, 3, 17, 200, 0 },
|
|
{ 0xff, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
const EntityData* const gUnk_080D4110[] = {
|
|
gUnk_080D3E90,
|
|
gUnk_080D3F30,
|
|
gUnk_080D3FD0,
|
|
gUnk_080D4070,
|
|
};
|
|
|
|
void sub_0804AAD4(void);
|
|
void sub_0804AB04(void);
|
|
void sub_0804AB24(void);
|
|
void Subtask_PortalCutscene_0(void);
|
|
void Subtask_PortalCutscene_1(void);
|
|
void Subtask_PortalCutscene_2(void);
|
|
|
|
void (*const gUnk_080D4120[])(void) = {
|
|
sub_0804AAD4,
|
|
sub_0804AB04,
|
|
sub_0804AB24,
|
|
};
|
|
void (*const Subtask_PortalCutscene_Functions[])(void) = {
|
|
Subtask_PortalCutscene_0,
|
|
Subtask_PortalCutscene_1,
|
|
Subtask_PortalCutscene_2,
|
|
};
|
|
|
|
const struct_080D4138 gUnk_080D4138[] = {
|
|
{ 95, 39 },
|
|
{ 96, 40 },
|
|
{ 97, 41 },
|
|
{ 98, 42 },
|
|
};
|
|
|
|
// x, y values. But they cannot be put in a struct matching?
|
|
const s16 gUnk_080D4140[] = {
|
|
0, -22, //
|
|
22, 0, //
|
|
0, 22, //
|
|
-22, 0,
|
|
};
|
|
|
|
bool32 CheckInitPortal(void) {
|
|
if (gArea.portal_in_use) {
|
|
gMain.substate = GAMEMAIN_MINISHPORTAL;
|
|
gArea.filler3[0] = 0;
|
|
gArea.filler3[1] = 0;
|
|
gArea.field_0x10 = 0;
|
|
SetInitializationPriority();
|
|
return TRUE;
|
|
} else {
|
|
gArea.portal_mode = 0;
|
|
gArea.portal_in_use = FALSE;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
void GameMain_MinishPortal(void) {
|
|
gUnk_080D4120[gArea.filler3[0]]();
|
|
}
|
|
|
|
void sub_0804AAD4(void) {
|
|
MemClear(&gUnk_02018EB0, 0x28);
|
|
gUnk_02018EB0.unk_14 = NULL;
|
|
EraseAllEntities();
|
|
CreateObject(MINISH_PORTAL_CLOSEUP, gArea.portal_type, 0);
|
|
gArea.filler3[0]++;
|
|
}
|
|
|
|
void sub_0804AB04(void) {
|
|
UpdateEntities();
|
|
if (gArea.field_0x10 != 0) {
|
|
FlushSprites();
|
|
DrawEntities();
|
|
CopyOAM();
|
|
}
|
|
}
|
|
|
|
void sub_0804AB24(void) {
|
|
if (!gFadeControl.active) {
|
|
gScreen.lcd.displayControl = 0;
|
|
sub_0801E104();
|
|
gArea.filler3[0] = 0;
|
|
MenuFadeIn(6, 0);
|
|
gFadeControl.active = 0;
|
|
}
|
|
}
|
|
|
|
void Subtask_PortalCutscene(void) {
|
|
Subtask_PortalCutscene_Functions[gArea.filler3[0]]();
|
|
}
|
|
void Subtask_PortalCutscene_0(void) {
|
|
const struct_080D4138* ptr;
|
|
RoomControls* controls;
|
|
u32 portalId;
|
|
|
|
DispReset(0);
|
|
gScreen.lcd.displayControl = 0x1240;
|
|
gScreen.bg1.control = 0x9e83;
|
|
controls = &gRoomControls;
|
|
gScreen.bg1.xOffset = 0;
|
|
controls->scroll_x = 0;
|
|
gScreen.bg1.yOffset = 0;
|
|
controls->scroll_y = 0;
|
|
portalId = gArea.portal_type;
|
|
if ((portalId == PT_2) && (gUI.roomControls.area != 2)) {
|
|
portalId = PT_DUNGEON;
|
|
}
|
|
ptr = &gUnk_080D4138[portalId];
|
|
LoadPaletteGroup(ptr->paletteGroup);
|
|
LoadGfxGroup(ptr->gfxGroup);
|
|
MemCopy(gPaletteBuffer + 3 * 16, gPaletteBuffer + 21 * 16, 16 * 2);
|
|
gUsedPalettes |= 1 << 21;
|
|
EraseAllEntities();
|
|
LoadRoomEntityList(gUnk_080D4110[portalId]);
|
|
ClearEventPriority();
|
|
gArea.filler3[0]++;
|
|
SetFade(FADE_INSTANT, 8);
|
|
}
|
|
|
|
void Subtask_PortalCutscene_1(void) {
|
|
s32 tmp;
|
|
|
|
UpdateEntities();
|
|
if (gUnk_02018EB0.unk_14 != NULL) {
|
|
tmp = gRoomControls.scroll_y + 0x50 - gUnk_02018EB0.unk_14->y.HALF.HI - gUnk_02018EB0.unk_14->z.HALF.HI;
|
|
if (tmp != 0) {
|
|
tmp = gRoomControls.scroll_y = gRoomControls.scroll_y - tmp;
|
|
if (tmp * 0x10000 < 0) {
|
|
gRoomControls.scroll_y = 0;
|
|
}
|
|
if (0x9f < gRoomControls.scroll_y) {
|
|
gRoomControls.scroll_y = 0x9f;
|
|
}
|
|
}
|
|
}
|
|
gScreen.bg1.xOffset = gRoomControls.scroll_x;
|
|
gScreen.bg1.yOffset = gRoomControls.scroll_y;
|
|
FlushSprites();
|
|
DrawEntities();
|
|
CopyOAM();
|
|
if ((gUnk_02018EB0.unk_1b != 0) || sub_0804ACA8()) {
|
|
gArea.filler3[0]++;
|
|
SetFade(FADE_IN_OUT | FADE_BLACK_WHITE | FADE_INSTANT, 0x10);
|
|
}
|
|
}
|
|
|
|
bool32 sub_0804ACA8(void) {
|
|
if ((gInput.newKeys & (R_BUTTON | B_BUTTON)) == 0) {
|
|
return 0;
|
|
} else {
|
|
return sub_0804AD18();
|
|
}
|
|
}
|
|
|
|
void Subtask_PortalCutscene_2(void) {
|
|
if (gFadeControl.active == 0) {
|
|
SetGlobalFlag(gArea.portal_type + ENTRANCE_0);
|
|
sub_0804AD6C(&gUI.roomControls);
|
|
sub_080A71F4(NULL);
|
|
}
|
|
}
|
|
|
|
void RespawnAsMinish(void) {
|
|
if (sub_0804AD18()) {
|
|
sub_0804AD6C(&gRoomControls);
|
|
SetInitializationPriority();
|
|
SoundReq(SFX_F8);
|
|
}
|
|
}
|
|
|
|
bool32 sub_0804AD18(void) {
|
|
switch (gArea.portal_type) {
|
|
case PT_TREESTUMP:
|
|
case PT_ROCK:
|
|
case PT_2:
|
|
if (!CheckGlobalFlag(ENTRANCE_0 + gArea.portal_type)) {
|
|
return FALSE;
|
|
}
|
|
// else: return TRUE implicitely, because it's stored in r0. But does not match if returning explicitely.
|
|
break;
|
|
case PT_TOD:
|
|
return FALSE;
|
|
case PT_DUNGEON:
|
|
case PT_JAR:
|
|
case PT_5:
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
void sub_0804AD6C(RoomControls* controls) {
|
|
Area* area;
|
|
gRoomTransition.transitioningOut = 1;
|
|
gRoomTransition.type = 0;
|
|
area = &gArea;
|
|
gRoomTransition.player_status.start_pos_x =
|
|
(area->portal_x + gUnk_080D4140[area->portal_exit_dir * 2]) - controls->origin_x;
|
|
gRoomTransition.player_status.start_pos_y =
|
|
(area->portal_y + gUnk_080D4140[area->portal_exit_dir * 2 + 1]) - controls->origin_y;
|
|
gRoomTransition.player_status.start_anim = area->portal_exit_dir << 1;
|
|
gRoomTransition.player_status.spawn_type = PL_SPAWN_MINISH;
|
|
gRoomTransition.player_status.area_next = controls->area;
|
|
gRoomTransition.player_status.room_next = controls->room;
|
|
gRoomTransition.player_status.layer = 0;
|
|
ClearArmosData();
|
|
sub_080300C4();
|
|
}
|
|
|
|
// TODO end of portal cutscene subtask?
|