mirror of https://github.com/zeldaret/mm.git
1411 lines
42 KiB
C
1411 lines
42 KiB
C
#include "global.h"
|
|
#include "overlays/gamestates/ovl_daytelop/z_daytelop.h"
|
|
#include "overlays/gamestates/ovl_opening/z_opening.h"
|
|
|
|
s32 gDbgCamEnabled = false;
|
|
u8 D_801D0D54 = 0;
|
|
|
|
// bss
|
|
extern s16 D_801F6C10;
|
|
extern Input D_801F6C18;
|
|
extern FbDemoStruct D_801F6C30;
|
|
extern u16* D_801F6D0C;
|
|
extern s32 D_801F6D10;
|
|
extern VisMono D_801F6D18;
|
|
extern Color_RGBA8 D_801F6D30;
|
|
extern Struct_80140E80 D_801F6D38;
|
|
extern Struct_80140E80* D_801F6D4C;
|
|
extern HiresoStruct D_801F6D50;
|
|
extern u8 D_801F6DFC;
|
|
extern u8 D_801F6DFD;
|
|
|
|
void func_80165460(PlayState* this) {
|
|
GraphicsContext* gfxCtx = this->state.gfxCtx;
|
|
s32 alpha;
|
|
Gfx* gfx;
|
|
Gfx* dlistHead;
|
|
|
|
if (SREG(93) != 0) {
|
|
alpha = SREG(92);
|
|
|
|
if (D_801F6DFD == 0) {
|
|
D_801F6DFD = 1;
|
|
}
|
|
} else if (SREG(91) != 0) {
|
|
alpha = SREG(90);
|
|
|
|
if (D_801F6DFD == 0) {
|
|
D_801F6DFD = 1;
|
|
}
|
|
} else {
|
|
alpha = 0;
|
|
D_801F6DFD = 0;
|
|
}
|
|
|
|
if (D_801F6DFD != 0) {
|
|
OPEN_DISPS(gfxCtx);
|
|
|
|
dlistHead = POLY_OPA_DISP;
|
|
gfx = Graph_GfxPlusOne(dlistHead);
|
|
|
|
gSPDisplayList(OVERLAY_DISP++, gfx);
|
|
|
|
this->pauseBgPreRender.fbuf = gfxCtx->curFrameBuffer;
|
|
this->pauseBgPreRender.fbufSave = this->unk_18E64;
|
|
|
|
if (D_801F6DFD == 2) {
|
|
func_80170AE0(&this->pauseBgPreRender, &gfx, alpha);
|
|
} else {
|
|
D_801F6DFD = 2;
|
|
}
|
|
|
|
func_801705B4(&this->pauseBgPreRender, &gfx);
|
|
|
|
gSPEndDisplayList(gfx++);
|
|
|
|
Graph_BranchDlist(dlistHead, gfx);
|
|
|
|
POLY_OPA_DISP = gfx;
|
|
|
|
CLOSE_DISPS(gfxCtx);
|
|
}
|
|
}
|
|
|
|
void func_80165608(void) {
|
|
SREG(91) = 0;
|
|
SREG(93) = 0;
|
|
D_801F6DFD = 0;
|
|
}
|
|
|
|
void func_80165630(void) {
|
|
SREG(91) = 0;
|
|
SREG(93) = 0;
|
|
D_801F6DFD = 0;
|
|
}
|
|
|
|
void func_80165658(u32 arg0) {
|
|
SREG(90) = arg0;
|
|
}
|
|
|
|
void func_8016566C(u32 arg0) {
|
|
SREG(90) = arg0;
|
|
SREG(91) = 1;
|
|
}
|
|
|
|
void func_80165690(void) {
|
|
SREG(91) = 0;
|
|
}
|
|
|
|
void func_801656A4(u8* arg0, u16* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7);
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801656A4.s")
|
|
|
|
void func_80165DB8(s32 arg0) {
|
|
SREG(92) = arg0;
|
|
}
|
|
|
|
void func_80165DCC(s32 arg0) {
|
|
SREG(92) = arg0;
|
|
SREG(93) = 1;
|
|
}
|
|
|
|
void func_80165DF0(void) {
|
|
SREG(93) = 0;
|
|
}
|
|
|
|
void func_80165E04(void) {
|
|
SREG(89) = 1;
|
|
}
|
|
|
|
void func_80165E1C(PreRender* prerender) {
|
|
PreRender_ApplyFilters(prerender);
|
|
func_801656A4(D_80780000, prerender->fbufSave, 0x140, 0x50, 0x40, 0xEF, 0xAF, 8);
|
|
}
|
|
|
|
s32 func_80165E7C(PlayState* this, s32 arg1) {
|
|
s32 phi_v1 = arg1;
|
|
|
|
if (arg1 == TRANS_TYPE_20) {
|
|
if (!gSaveContext.save.isNight) {
|
|
phi_v1 = TRANS_TYPE_03;
|
|
} else {
|
|
phi_v1 = TRANS_TYPE_02;
|
|
}
|
|
}
|
|
if (phi_v1 != arg1) {
|
|
this->transitionType = phi_v1;
|
|
}
|
|
return phi_v1;
|
|
}
|
|
|
|
void func_80165EC0(PlayState* this, s32 arg1) {
|
|
PlayStruct_18BF0* ptr = &this->unk_18BF0;
|
|
s32 sp20;
|
|
|
|
bzero(ptr, sizeof(this->unk_18BF0));
|
|
|
|
sp20 = -1;
|
|
if (arg1 & 0x40) {
|
|
sp20 = 3;
|
|
} else if ((arg1 & 0x78) == 0x20) {
|
|
sp20 = 4;
|
|
} else if (!(arg1 & 0x60)) {
|
|
switch (arg1) {
|
|
case 1:
|
|
sp20 = 1;
|
|
break;
|
|
case 0:
|
|
case 8:
|
|
sp20 = 2;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
case 13:
|
|
case 17:
|
|
case 18:
|
|
case 19:
|
|
sp20 = 0;
|
|
break;
|
|
case 9:
|
|
case 10:
|
|
this->transitionMode = TRANS_MODE_04;
|
|
break;
|
|
case 11:
|
|
this->transitionMode = TRANS_MODE_10;
|
|
break;
|
|
case 12:
|
|
this->transitionMode = TRANS_MODE_07;
|
|
break;
|
|
case 14:
|
|
this->transitionMode = TRANS_MODE_12;
|
|
break;
|
|
case 15:
|
|
this->transitionMode = TRANS_MODE_14;
|
|
break;
|
|
case 16:
|
|
this->transitionMode = TRANS_MODE_16;
|
|
break;
|
|
case 21:
|
|
sp20 = 5;
|
|
break;
|
|
case 22:
|
|
sp20 = 6;
|
|
break;
|
|
default:
|
|
sp20 = -1;
|
|
__assert("../z_play.c", 1420);
|
|
}
|
|
} else {
|
|
sp20 = -1;
|
|
__assert("../z_play.c", 1423);
|
|
}
|
|
|
|
ptr->unk_00 = arg1;
|
|
ptr->unk_02 = sp20;
|
|
if (sp20 != -1) {
|
|
func_80163C90(ptr);
|
|
}
|
|
}
|
|
|
|
const char D_801DFA18[] = "来た!!!!!!!!!!!!!!!!!!!!!";
|
|
const char D_801DFA34[] = "all";
|
|
const char D_801DFA38[] = "a";
|
|
const char D_801DFA3C[] = "a";
|
|
const char D_801DFA40[] = "b";
|
|
const char D_801DFA44[] = "b";
|
|
const char D_801DFA48[] = "c";
|
|
const char D_801DFA4C[] = "c";
|
|
const char D_801DFA50[] = "d";
|
|
const char D_801DFA54[] = "d";
|
|
const char D_801DFA58[] = "e";
|
|
const char D_801DFA5C[] = "e";
|
|
const char D_801DFA60[] = "f";
|
|
const char D_801DFA64[] = "fa";
|
|
const char D_801DFA68[] = "fa";
|
|
const char D_801DFA6C[] = "fb";
|
|
const char D_801DFA70[] = "fb";
|
|
const char D_801DFA74[] = "fc";
|
|
const char D_801DFA78[] = "fc";
|
|
const char D_801DFA7C[] = "fd";
|
|
const char D_801DFA80[] = "fd";
|
|
const char D_801DFA84[] = "fe";
|
|
const char D_801DFA88[] = "fe";
|
|
const char D_801DFA8C[] = "fg";
|
|
const char D_801DFA90[] = "fg";
|
|
const char D_801DFA94[] = "fh";
|
|
const char D_801DFA98[] = "fh";
|
|
const char D_801DFA9C[] = "fi";
|
|
const char D_801DFAA0[] = "fi";
|
|
const char D_801DFAA4[] = "fj";
|
|
const char D_801DFAA8[] = "fj";
|
|
const char D_801DFAAC[] = "fk";
|
|
const char D_801DFAB0[] = "fk";
|
|
const char D_801DFAB4[] = "f";
|
|
const char D_801DFAB8[] = "g";
|
|
const char D_801DFABC[] = "g";
|
|
const char D_801DFAC0[] = "h";
|
|
const char D_801DFAC4[] = "h";
|
|
const char D_801DFAC8[] = "i";
|
|
const char D_801DFACC[] = "i";
|
|
const char D_801DFAD0[] = "all";
|
|
const char D_801DFAD4[] = "all";
|
|
const char D_801DFAD8[] = "a";
|
|
const char D_801DFADC[] = "b";
|
|
const char D_801DFAE0[] = "c";
|
|
const char D_801DFAE4[] = "d";
|
|
const char D_801DFAE8[] = "e";
|
|
const char D_801DFAEC[] = "f";
|
|
const char D_801DFAF0[] = "g";
|
|
const char D_801DFAF4[] = "h";
|
|
const char D_801DFAF8[] = "i";
|
|
const char D_801DFAFC[] = "f";
|
|
const char D_801DFB00[] = "fa";
|
|
const char D_801DFB04[] = "fb";
|
|
const char D_801DFB08[] = "fc";
|
|
const char D_801DFB0C[] = "fd";
|
|
const char D_801DFB10[] = "fe";
|
|
const char D_801DFB14[] = "ff";
|
|
const char D_801DFB18[] = "fg";
|
|
const char D_801DFB1C[] = "fh";
|
|
const char D_801DFB20[] = "fi";
|
|
const char D_801DFB24[] = "fj";
|
|
const char D_801DFB28[] = "fk";
|
|
|
|
void func_80166060(PlayState* this) {
|
|
if (this->unk_18BF0.unk_02 != -1) {
|
|
func_80163D80(&this->unk_18BF0, this);
|
|
}
|
|
this->unk_18BF0.unk_00 = -1;
|
|
}
|
|
|
|
Gfx* func_801660B8(PlayState* this, Gfx* gfx) {
|
|
s32 phi_v1 = this->lightCtx.unkC * (5.0f / 64.0f);
|
|
|
|
return Gfx_SetFogWithSync(gfx, this->lightCtx.unk7, this->lightCtx.unk8, this->lightCtx.unk9, 0,
|
|
this->lightCtx.unkA, (phi_v1 <= 1000) ? 1000 : phi_v1);
|
|
}
|
|
|
|
void Play_Destroy(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
GraphicsContext* gfxCtx = this->state.gfxCtx;
|
|
|
|
if (D_801F6DFC != 0) {
|
|
MsgEvent_SendNullTask();
|
|
func_80178750();
|
|
gfxCtx->curFrameBuffer = SysCfb_GetFbPtr(gfxCtx->framebufferIdx % 2);
|
|
gfxCtx->zbuffer = SysCfb_GetZBuffer();
|
|
gfxCtx->viMode = D_801FBB88;
|
|
gfxCtx->viConfigFeatures = gViConfigFeatures;
|
|
gfxCtx->xScale = gViConfigXScale;
|
|
gfxCtx->yScale = gViConfigYScale;
|
|
gfxCtx->updateViMode = true;
|
|
D_801F6DFC = 0;
|
|
}
|
|
|
|
func_8016FC98(&D_801F6D50);
|
|
this->state.gfxCtx->callback = NULL;
|
|
this->state.gfxCtx->callbackParam = 0;
|
|
func_80165630();
|
|
|
|
if (SREG(94) != 0) {
|
|
PreRender_ApplyFiltersSlowlyDestroy(&this->pauseBgPreRender);
|
|
SREG(94) = 0;
|
|
}
|
|
|
|
SREG(89) = 0;
|
|
PreRender_Destroy(&this->pauseBgPreRender);
|
|
this->unk_18E58 = NULL;
|
|
this->unk_18E5C = NULL;
|
|
this->unk_18E60 = NULL;
|
|
this->unk_18E64 = NULL;
|
|
this->unk_18E68 = NULL;
|
|
Effect_DestroyAll(this);
|
|
EffectSS_Clear(this);
|
|
CollisionCheck_DestroyContext(this, &this->colChkCtx);
|
|
|
|
if (D_801F6D10 == 3) {
|
|
func_8016424C(&D_801F6C30);
|
|
D_801F6D10 = 0;
|
|
}
|
|
|
|
if ((this->transitionMode == TRANS_MODE_03) || (D_801D0D54 != 0)) {
|
|
this->unk_18BF0.unk_234(&this->unk_18BF0.unk_08);
|
|
func_80166060(this);
|
|
this->transitionMode = TRANS_MODE_OFF;
|
|
}
|
|
|
|
ShrinkWindow_Destroy();
|
|
TransitionFade_Destroy(&this->unk_18E48);
|
|
VisMono_Destroy(&D_801F6D18);
|
|
func_80140EA0(D_801F6D4C);
|
|
D_801F6D4C = NULL;
|
|
|
|
if (gSaveContext.save.weekEventReg[0x5C] & 0x80) {
|
|
Actor_CleanupContext(&this->actorCtx, this);
|
|
}
|
|
gSaveContext.save.weekEventReg[0x5C] &= (u8)~0x80;
|
|
|
|
func_80121F94(this);
|
|
KaleidoScopeCall_Destroy(this);
|
|
KaleidoManager_Destroy();
|
|
ZeldaArena_Cleanup();
|
|
}
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801663C4.s")
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166644.s")
|
|
|
|
f32 func_801668B4(PlayState* this, Vec3f* arg1, s32* arg2) {
|
|
Player* player = GET_PLAYER(this);
|
|
f32 sp38 = player->actor.world.pos.y;
|
|
WaterBox* sp34;
|
|
s32 sp30;
|
|
|
|
if (!WaterBox_GetSurfaceImpl(this, &this->colCtx, arg1->x, arg1->z, &sp38, &sp34, &sp30)) {
|
|
return BGCHECK_Y_MIN;
|
|
}
|
|
|
|
if (sp38 < arg1->y) {
|
|
return BGCHECK_Y_MIN;
|
|
}
|
|
|
|
*arg2 = WaterBox_GetLightSettingIndex(&this->colCtx, sp34);
|
|
return sp38;
|
|
}
|
|
|
|
void func_80166968(PlayState* this, Camera* camera) {
|
|
static s16 D_801D0D58 = -1;
|
|
static s16 sIsCameraUnderwater = false;
|
|
s32 pad;
|
|
s32 sp28;
|
|
Player* player = GET_PLAYER(this);
|
|
|
|
sIsCameraUnderwater = camera->stateFlags & CAM_STATE_UNDERWATER;
|
|
if (func_801668B4(this, &camera->eye, &sp28) != BGCHECK_Y_MIN) {
|
|
if (!sIsCameraUnderwater) {
|
|
Camera_SetFlags(camera, CAM_STATE_UNDERWATER);
|
|
D_801D0D58 = -1;
|
|
Distortion_SetType(0x10);
|
|
Distortion_SetCountdown(80);
|
|
}
|
|
|
|
func_801A3EC0(0x20);
|
|
func_800F6834(this, sp28);
|
|
|
|
if ((D_801D0D58 == -1) || (Quake_GetCountdown(D_801D0D58) == 0xA)) {
|
|
s16 quake = Quake_Add(camera, 5);
|
|
|
|
D_801D0D58 = quake;
|
|
if (quake != 0) {
|
|
Quake_SetSpeed(D_801D0D58, 0x226);
|
|
Quake_SetQuakeValues(D_801D0D58, 1, 1, 0xB4, 0);
|
|
Quake_SetCountdown(D_801D0D58, 1000);
|
|
}
|
|
}
|
|
if (player->stateFlags3 & PLAYER_STATE3_8000) {
|
|
Distortion_SetType(8);
|
|
Distortion_ClearType(4);
|
|
} else {
|
|
Distortion_SetType(4);
|
|
Distortion_ClearType(8);
|
|
}
|
|
} else {
|
|
if (sIsCameraUnderwater) {
|
|
Camera_ClearFlags(camera, CAM_STATE_UNDERWATER);
|
|
}
|
|
Distortion_ClearType(4);
|
|
Distortion_ClearType(0x10);
|
|
Distortion_ClearType(8);
|
|
if (D_801D0D58 != 0) {
|
|
Quake_RemoveFromIdx(D_801D0D58);
|
|
}
|
|
func_800F694C(this);
|
|
func_801A3EC0(0);
|
|
}
|
|
}
|
|
|
|
Input* D_801D0D60 = NULL;
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80166B30.s")
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Update.s")
|
|
|
|
void func_80167DE4(PlayState* play) {
|
|
if (D_801F6DFC == 0) {
|
|
if (play->pauseCtx.unk_1F0 != 0) {
|
|
D_801F6DFC = 1;
|
|
D_801F6D50.unk_00 = 0;
|
|
}
|
|
} else {
|
|
if (CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_L) ||
|
|
CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_B) ||
|
|
CHECK_BTN_ALL(CONTROLLER1(&play->state)->press.button, BTN_START) || (gIrqMgrResetStatus != 0)) {
|
|
D_801F6DFC = 0;
|
|
play->pauseCtx.unk_1F0 = 0;
|
|
D_801F6D50.unk_00 = 0;
|
|
play->msgCtx.msgLength = 0;
|
|
play->msgCtx.msgMode = 0;
|
|
play->msgCtx.currentTextId = 0;
|
|
play->msgCtx.stateTimer = 0;
|
|
play_sound(NA_SE_SY_CANCEL);
|
|
}
|
|
}
|
|
if (D_801F6DFC != 0) {
|
|
func_8016F5A8(play, &D_801F6D50, play->state.input);
|
|
func_8015680C(play);
|
|
} else {
|
|
Play_Update(play);
|
|
}
|
|
}
|
|
|
|
void func_80167F0C(PlayState* this) {
|
|
Gfx* sp34;
|
|
Gfx* sp30;
|
|
GraphicsContext* gfxCtx;
|
|
|
|
if ((this->pauseCtx.state != 0) || (this->pauseCtx.debugEditor != 0)) {
|
|
KaleidoScopeCall_Draw(this);
|
|
}
|
|
|
|
if (gSaveContext.gameMode == 0) {
|
|
func_8011F0E0(this);
|
|
}
|
|
|
|
if (((this->pauseCtx.state == 0) && (this->pauseCtx.debugEditor == 0)) || (this->msgCtx.currentTextId != 0xFF)) {
|
|
func_80156758(this);
|
|
}
|
|
|
|
if (this->gameOverCtx.state != 0) {
|
|
GameOver_FadeLights(this);
|
|
}
|
|
|
|
if (gSaveContext.screenScaleFlag != 0) {
|
|
gfxCtx = this->state.gfxCtx;
|
|
D_801F6D4C->scale = gSaveContext.screenScale / 1000.0f;
|
|
|
|
OPEN_DISPS(gfxCtx);
|
|
|
|
sp30 = POLY_OPA_DISP;
|
|
sp34 = Graph_GfxPlusOne(sp30);
|
|
gSPDisplayList(OVERLAY_DISP++, sp34);
|
|
|
|
func_80141778(D_801F6D4C, &sp34, this->unk_18E60, gfxCtx);
|
|
|
|
gSPEndDisplayList(sp34++);
|
|
Graph_BranchDlist(sp30, sp34);
|
|
POLY_OPA_DISP = sp34;
|
|
|
|
CLOSE_DISPS(gfxCtx);
|
|
}
|
|
}
|
|
|
|
#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Draw.s")
|
|
|
|
void func_80168DAC(PlayState* this) {
|
|
GraphicsContext* gfxCtx = this->state.gfxCtx;
|
|
|
|
{
|
|
GraphicsContext* gfxCtx2 = this->state.gfxCtx;
|
|
|
|
if (D_801F6DFC != 0) {
|
|
if (D_801FBBD4 != 1) {
|
|
MsgEvent_SendNullTask();
|
|
func_80178818();
|
|
gfxCtx2->curFrameBuffer = SysCfb_GetFbPtr(gfxCtx2->framebufferIdx % 2);
|
|
gfxCtx2->zbuffer = SysCfb_GetZBuffer();
|
|
gfxCtx2->viMode = D_801FBB88;
|
|
gfxCtx2->viConfigFeatures = gViConfigFeatures;
|
|
gfxCtx2->xScale = gViConfigXScale;
|
|
gfxCtx2->yScale = gViConfigYScale;
|
|
gfxCtx2->updateViMode = true;
|
|
}
|
|
} else {
|
|
if (D_801FBBD4 != 0) {
|
|
MsgEvent_SendNullTask();
|
|
func_80178750();
|
|
gfxCtx2->curFrameBuffer = SysCfb_GetFbPtr(gfxCtx2->framebufferIdx % 2);
|
|
gfxCtx2->zbuffer = SysCfb_GetZBuffer();
|
|
gfxCtx2->viMode = D_801FBB88;
|
|
gfxCtx2->viConfigFeatures = gViConfigFeatures;
|
|
gfxCtx2->xScale = gViConfigXScale;
|
|
gfxCtx2->yScale = gViConfigYScale;
|
|
gfxCtx2->updateViMode = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((D_801F6DFC != 0) && ((SREG(2) != 2) || (gZBufferPtr == NULL))) {
|
|
func_8016F1A8(&D_801F6D50, gfxCtx);
|
|
func_80156758(this);
|
|
} else {
|
|
Play_Draw(this);
|
|
}
|
|
}
|
|
|
|
void Play_Main(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
|
|
D_801D0D60 = CONTROLLER1(&this->state);
|
|
DebugDisplay_Init();
|
|
|
|
{
|
|
GraphicsContext* gfxCtx = this->state.gfxCtx;
|
|
|
|
if (1) {
|
|
this->state.gfxCtx = NULL;
|
|
}
|
|
func_80167DE4(this);
|
|
this->state.gfxCtx = gfxCtx;
|
|
}
|
|
|
|
{
|
|
Input sp28 = *CONTROLLER1(&this->state);
|
|
|
|
if (1) {
|
|
*CONTROLLER1(&this->state) = D_801F6C18;
|
|
}
|
|
func_80168DAC(this);
|
|
*CONTROLLER1(&this->state) = sp28;
|
|
}
|
|
|
|
ActorCutscene_Update();
|
|
ActorCutscene_ClearWaiting();
|
|
}
|
|
|
|
s32 Play_InCsMode(PlayState* this) {
|
|
return (this->csCtx.state != 0) || Player_InCsMode(this);
|
|
}
|
|
|
|
f32 func_80169100(PlayState* play, MtxF* mtx, CollisionPoly** poly, s32* bgId, Vec3f* feetPos) {
|
|
f32 floorHeight = BgCheck_EntityRaycastFloor3(&play->colCtx, poly, bgId, feetPos);
|
|
|
|
if (floorHeight > BGCHECK_Y_MIN) {
|
|
func_800C0094(*poly, feetPos->x, floorHeight, feetPos->z, mtx);
|
|
} else {
|
|
mtx->xy = 0.0f;
|
|
mtx->zx = 0.0f;
|
|
mtx->yx = 0.0f;
|
|
mtx->xx = 0.0f;
|
|
mtx->wz = 0.0f;
|
|
mtx->xz = 0.0f;
|
|
mtx->wy = 0.0f;
|
|
mtx->wx = 0.0f;
|
|
mtx->zz = 0.0f;
|
|
mtx->yz = 0.0f;
|
|
mtx->zy = 0.0f;
|
|
mtx->yy = 1.0f;
|
|
mtx->xw = feetPos->x;
|
|
mtx->yw = feetPos->y;
|
|
mtx->zw = feetPos->z;
|
|
mtx->ww = 1.0f;
|
|
}
|
|
return floorHeight;
|
|
}
|
|
|
|
void func_801691F0(PlayState* this, MtxF* mtx, Vec3f* feetPos) {
|
|
CollisionPoly* poly;
|
|
s32 bgId;
|
|
|
|
func_80169100(this, mtx, &poly, &bgId, feetPos);
|
|
}
|
|
|
|
void* Play_LoadScene(PlayState* this, RomFile* entry) {
|
|
size_t size = entry->vromEnd - entry->vromStart;
|
|
void* sp18 = THA_AllocEndAlign16(&this->state.heap, size);
|
|
|
|
DmaMgr_SendRequest0(sp18, entry->vromStart, size);
|
|
return sp18;
|
|
}
|
|
|
|
void func_8016927C(PlayState* this, s16 skyboxId) {
|
|
func_801434E4(&this->state, &this->skyboxCtx, skyboxId);
|
|
Kankyo_Init(this, &this->envCtx, 0);
|
|
}
|
|
|
|
void func_801692C4(PlayState* this, s32 spawn) {
|
|
this->curSpawn = spawn;
|
|
this->linkActorEntry = NULL;
|
|
this->actorCsCamList = NULL;
|
|
this->setupEntranceList = NULL;
|
|
this->setupExitList = NULL;
|
|
this->unk_18868 = NULL;
|
|
this->setupPathList = NULL;
|
|
this->sceneMaterialAnims = NULL;
|
|
this->roomCtx.unk74 = NULL;
|
|
this->numSetupActors = 0;
|
|
Object_InitBank(&this->state, &this->objectCtx);
|
|
LightContext_Init(this, &this->lightCtx);
|
|
Door_InitContext(&this->state, &this->doorCtx);
|
|
Room_Init(this, &this->roomCtx);
|
|
gSaveContext.worldMapArea = 0;
|
|
Scene_ProcessHeader(this, this->sceneSegment);
|
|
func_8016927C(this, this->skyboxId);
|
|
}
|
|
|
|
void Play_SceneInit(PlayState* this, s32 scene, s32 spawn) {
|
|
s32 pad;
|
|
SceneTableEntry* sp1C = &gSceneTable[scene];
|
|
|
|
sp1C->unk_D = 0;
|
|
this->loadedScene = sp1C;
|
|
this->sceneNum = scene;
|
|
this->sceneConfig = sp1C->drawConfig;
|
|
this->sceneSegment = Play_LoadScene(this, &sp1C->segment);
|
|
sp1C->unk_D = 0;
|
|
gSegments[0x02] = VIRTUAL_TO_PHYSICAL(this->sceneSegment);
|
|
func_801692C4(this, spawn);
|
|
Room_AllocateAndLoad(this, &this->roomCtx);
|
|
}
|
|
|
|
void Play_GetScreenPos(PlayState* this, Vec3f* worldPos, Vec3f* screenPos) {
|
|
f32 invW;
|
|
|
|
// screenPos temporarily stores the projectedPos
|
|
Actor_GetProjectedPos(this, worldPos, screenPos, &invW);
|
|
|
|
screenPos->x = (SCREEN_WIDTH / 2) + (screenPos->x * invW * (SCREEN_WIDTH / 2));
|
|
screenPos->y = (SCREEN_HEIGHT / 2) - (screenPos->y * invW * (SCREEN_HEIGHT / 2));
|
|
}
|
|
|
|
s16 Play_CreateSubCamera(PlayState* this) {
|
|
s16 subCamId;
|
|
|
|
for (subCamId = CAM_ID_SUB_FIRST; subCamId < NUM_CAMS; subCamId++) {
|
|
if (this->cameraPtrs[subCamId] == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// if no subCameras available
|
|
if (subCamId == NUM_CAMS) {
|
|
return CAM_ID_NONE;
|
|
}
|
|
|
|
this->cameraPtrs[subCamId] = &this->subCameras[subCamId - CAM_ID_SUB_FIRST];
|
|
Camera_Init(this->cameraPtrs[subCamId], &this->view, &this->colCtx, this);
|
|
this->cameraPtrs[subCamId]->camId = subCamId;
|
|
|
|
return subCamId;
|
|
}
|
|
|
|
s16 Play_GetActiveCamId(PlayState* this) {
|
|
return this->activeCamId;
|
|
}
|
|
|
|
s32 Play_ChangeCameraStatus(PlayState* this, s16 camId, s16 status) {
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
|
|
if (status == CAM_STATUS_ACTIVE) {
|
|
this->activeCamId = camIdx;
|
|
}
|
|
|
|
return Camera_ChangeStatus(this->cameraPtrs[camIdx], status);
|
|
}
|
|
|
|
void Play_ClearCamera(PlayState* this, s16 camId) {
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
|
|
if (this->cameraPtrs[camIdx] != NULL) {
|
|
Camera_ChangeStatus(this->cameraPtrs[camIdx], CAM_STATUS_INACTIVE);
|
|
this->cameraPtrs[camIdx] = NULL;
|
|
}
|
|
}
|
|
|
|
void Play_ClearAllSubCameras(PlayState* this) {
|
|
s16 subCamId;
|
|
|
|
for (subCamId = CAM_ID_SUB_FIRST; subCamId < NUM_CAMS; subCamId++) {
|
|
if (this->cameraPtrs[subCamId] != NULL) {
|
|
Play_ClearCamera(this, subCamId);
|
|
}
|
|
}
|
|
|
|
this->activeCamId = CAM_ID_MAIN;
|
|
}
|
|
|
|
Camera* Play_GetCamera(PlayState* this, s16 camId) {
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
|
|
return this->cameraPtrs[camIdx];
|
|
}
|
|
|
|
/**
|
|
* @return bit-packed success if each of the params were applied
|
|
*/
|
|
s32 Play_SetCameraAtEye(PlayState* this, s16 camId, Vec3f* at, Vec3f* eye) {
|
|
s32 successfullySet = 0;
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
Camera* camera = this->cameraPtrs[camIdx];
|
|
|
|
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_AT, at);
|
|
successfullySet <<= 1;
|
|
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_EYE, eye);
|
|
|
|
camera->dist = Math3D_Distance(at, eye);
|
|
|
|
if (camera->focalActor != NULL) {
|
|
camera->atActorOffset.x = at->x - camera->focalActor->world.pos.x;
|
|
camera->atActorOffset.y = at->y - camera->focalActor->world.pos.y;
|
|
camera->atActorOffset.z = at->z - camera->focalActor->world.pos.z;
|
|
} else {
|
|
camera->atActorOffset.x = camera->atActorOffset.y = camera->atActorOffset.z = 0.0f;
|
|
}
|
|
|
|
camera->atLerpStepScale = 0.01f;
|
|
|
|
return successfullySet;
|
|
}
|
|
|
|
/**
|
|
* @return bit-packed success if each of the params were applied
|
|
*/
|
|
s32 Play_SetCameraAtEyeUp(PlayState* this, s16 camId, Vec3f* at, Vec3f* eye, Vec3f* up) {
|
|
s32 successfullySet = 0;
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
Camera* camera = this->cameraPtrs[camIdx];
|
|
|
|
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_AT, at);
|
|
successfullySet <<= 1;
|
|
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_EYE, eye);
|
|
successfullySet <<= 1;
|
|
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_UP, up);
|
|
|
|
camera->dist = Math3D_Distance(at, eye);
|
|
|
|
if (camera->focalActor != NULL) {
|
|
camera->atActorOffset.x = at->x - camera->focalActor->world.pos.x;
|
|
camera->atActorOffset.y = at->y - camera->focalActor->world.pos.y;
|
|
camera->atActorOffset.z = at->z - camera->focalActor->world.pos.z;
|
|
} else {
|
|
camera->atActorOffset.x = camera->atActorOffset.y = camera->atActorOffset.z = 0.0f;
|
|
}
|
|
|
|
camera->atLerpStepScale = 0.01f;
|
|
|
|
return successfullySet;
|
|
}
|
|
|
|
/**
|
|
* @return true if the fov was successfully set
|
|
*/
|
|
s32 Play_SetCameraFov(PlayState* this, s16 camId, f32 fov) {
|
|
s32 successfullySet = Camera_SetViewParam(this->cameraPtrs[camId], CAM_VIEW_FOV, &fov) & 1;
|
|
|
|
if (1) {}
|
|
return successfullySet;
|
|
}
|
|
|
|
s32 Play_SetCameraRoll(PlayState* this, s16 camId, s16 roll) {
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
Camera* camera = this->cameraPtrs[camIdx];
|
|
|
|
camera->roll = roll;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void Play_CopyCamera(PlayState* this, s16 destCamId, s16 srcCamId) {
|
|
s16 srcCamId2 = (srcCamId == CAM_ID_NONE) ? this->activeCamId : srcCamId;
|
|
s16 destCamId1 = (destCamId == CAM_ID_NONE) ? this->activeCamId : destCamId;
|
|
|
|
Camera_Copy(this->cameraPtrs[destCamId1], this->cameraPtrs[srcCamId2]);
|
|
}
|
|
|
|
// Same as Play_ChangeCameraSetting but also calls Camera_InitPlayerSettings
|
|
s32 func_80169A50(PlayState* this, s16 camId, Player* player, s16 setting) {
|
|
Camera* camera;
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
|
|
camera = this->cameraPtrs[camIdx];
|
|
Camera_InitPlayerSettings(camera, player);
|
|
return Camera_ChangeSetting(camera, setting);
|
|
}
|
|
|
|
s32 Play_ChangeCameraSetting(PlayState* this, s16 camId, s16 setting) {
|
|
return Camera_ChangeSetting(Play_GetCamera(this, camId), setting);
|
|
}
|
|
|
|
// Related to bosses and fishing
|
|
void func_80169AFC(PlayState* this, s16 camId, s16 timer) {
|
|
s16 camIdx = (camId == CAM_ID_NONE) ? this->activeCamId : camId;
|
|
s16 i;
|
|
|
|
Play_ClearCamera(this, camIdx);
|
|
|
|
for (i = CAM_ID_SUB_FIRST; i < NUM_CAMS; i++) {
|
|
if (this->cameraPtrs[i] != NULL) {
|
|
Play_ClearCamera(this, i);
|
|
}
|
|
}
|
|
|
|
if (timer <= 0) {
|
|
Play_ChangeCameraStatus(this, CAM_ID_MAIN, CAM_STATUS_ACTIVE);
|
|
this->cameraPtrs[CAM_ID_MAIN]->childCamId = this->cameraPtrs[CAM_ID_MAIN]->doorTimer2 = 0;
|
|
}
|
|
}
|
|
|
|
s16 Play_GetCameraUID(PlayState* this, s16 camId) {
|
|
Camera* camera = this->cameraPtrs[camId];
|
|
|
|
if (camera != NULL) {
|
|
return camera->uid;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
// Unused in both MM and OoT, purpose is very unclear
|
|
s16 func_80169BF8(PlayState* this, s16 camId, s16 uid) {
|
|
Camera* camera = this->cameraPtrs[camId];
|
|
|
|
if (camera != NULL) {
|
|
return 0;
|
|
} else if (camera->uid != uid) {
|
|
return 0;
|
|
} else if (camera->status != CAM_STATUS_ACTIVE) {
|
|
return 2;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
u16 Play_GetActorCsCamSetting(PlayState* this, s32 csCamDataIndex) {
|
|
ActorCsCamInfo* actorCsCamList = &this->actorCsCamList[csCamDataIndex];
|
|
|
|
return actorCsCamList->setting;
|
|
}
|
|
|
|
Vec3s* Play_GetActorCsCamFuncData(PlayState* this, s32 csCamDataIndex) {
|
|
ActorCsCamInfo* actorCsCamList = &this->actorCsCamList[csCamDataIndex];
|
|
|
|
return Lib_SegmentedToVirtual(actorCsCamList->actorCsCamFuncData);
|
|
}
|
|
|
|
/**
|
|
* Converts the number of a scene to its "original" equivalent, the default version of the area which the player first
|
|
* enters.
|
|
*/
|
|
s16 Play_GetOriginalSceneNumber(s16 sceneNum) {
|
|
// Inverted Stone Tower Temple -> Stone Tower Temple
|
|
if (sceneNum == SCENE_INISIE_R) {
|
|
return SCENE_INISIE_N;
|
|
}
|
|
|
|
// Purified Southern Swamp -> Poisoned Sothern Swamp
|
|
if (sceneNum == SCENE_20SICHITAI2) {
|
|
return SCENE_20SICHITAI;
|
|
}
|
|
|
|
// Spring Mountain Village -> Winter Mountain Village
|
|
if (sceneNum == SCENE_10YUKIYAMANOMURA2) {
|
|
return SCENE_10YUKIYAMANOMURA;
|
|
}
|
|
|
|
// Spring Goron Village -> Winter Goron Village
|
|
if (sceneNum == SCENE_11GORONNOSATO2) {
|
|
return SCENE_11GORONNOSATO;
|
|
}
|
|
|
|
// Spring Path to Goron Village -> Winter Path to Goron Village
|
|
if (sceneNum == SCENE_17SETUGEN2) {
|
|
return SCENE_17SETUGEN;
|
|
}
|
|
|
|
// Inverted Stone Tower -> Stone Tower
|
|
if (sceneNum == SCENE_F41) {
|
|
return SCENE_F40;
|
|
}
|
|
|
|
return sceneNum;
|
|
}
|
|
|
|
/**
|
|
* Copies the flags set in ActorContext over to the current scene's CycleSceneFlags, usually using the original scene
|
|
* number. Exception for Inverted Stone Tower Temple, which uses its own.
|
|
*/
|
|
void Play_SaveCycleSceneFlags(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
CycleSceneFlags* cycleSceneFlags;
|
|
|
|
cycleSceneFlags = &gSaveContext.cycleSceneFlags[Play_GetOriginalSceneNumber(this->sceneNum)];
|
|
cycleSceneFlags->chest = this->actorCtx.flags.chest;
|
|
cycleSceneFlags->switch0 = this->actorCtx.flags.switches[0];
|
|
cycleSceneFlags->switch1 = this->actorCtx.flags.switches[1];
|
|
|
|
if (this->sceneNum == SCENE_INISIE_R) { // Inverted Stone Tower Temple
|
|
cycleSceneFlags = &gSaveContext.cycleSceneFlags[this->sceneNum];
|
|
}
|
|
|
|
cycleSceneFlags->collectible = this->actorCtx.flags.collectible[0];
|
|
cycleSceneFlags->clearedRoom = this->actorCtx.flags.clearedRoom;
|
|
}
|
|
|
|
void Play_SetRespawnData(GameState* thisx, s32 respawnMode, u16 entrance, s32 roomIndex, s32 playerParams, Vec3f* pos,
|
|
s16 yaw) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
|
|
gSaveContext.respawn[respawnMode].entrance = Entrance_Create(entrance >> 9, 0, entrance & 0xF);
|
|
gSaveContext.respawn[respawnMode].roomIndex = roomIndex;
|
|
gSaveContext.respawn[respawnMode].pos = *pos;
|
|
gSaveContext.respawn[respawnMode].yaw = yaw;
|
|
gSaveContext.respawn[respawnMode].playerParams = playerParams;
|
|
gSaveContext.respawn[respawnMode].tempSwitchFlags = this->actorCtx.flags.switches[2];
|
|
gSaveContext.respawn[respawnMode].unk_18 = this->actorCtx.flags.collectible[1];
|
|
gSaveContext.respawn[respawnMode].tempCollectFlags = this->actorCtx.flags.collectible[2];
|
|
}
|
|
|
|
void Play_SetupRespawnPoint(GameState* thisx, s32 respawnMode, s32 playerParams) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
Player* player = GET_PLAYER(this);
|
|
|
|
if (this->sceneNum != SCENE_KAKUSIANA) { // Grottos
|
|
Play_SetRespawnData(&this->state, respawnMode, (u16)((void)0, gSaveContext.save.entrance),
|
|
this->roomCtx.currRoom.num, playerParams, &player->actor.world.pos,
|
|
player->actor.shape.rot.y);
|
|
}
|
|
}
|
|
|
|
// Override respawn data in Sakon's Hideout
|
|
void func_80169ECC(PlayState* this) {
|
|
if (this->sceneNum == SCENE_SECOM) {
|
|
this->nextEntrance = ENTRANCE(IKANA_CANYON, 6);
|
|
gSaveContext.respawnFlag = -7;
|
|
}
|
|
}
|
|
|
|
// Gameplay_TriggerVoidOut ?
|
|
// Used by Player, Ikana_Rotaryroom, Bji01, Kakasi, LiftNuts, Test4, Warptag, WarpUzu, Roomtimer
|
|
void func_80169EFC(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwitchFlags = this->actorCtx.flags.switches[2];
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].unk_18 = this->actorCtx.flags.collectible[1];
|
|
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = this->actorCtx.flags.collectible[2];
|
|
this->nextEntrance = gSaveContext.respawn[RESPAWN_MODE_DOWN].entrance;
|
|
gSaveContext.respawnFlag = 1;
|
|
func_80169ECC(this);
|
|
this->transitionTrigger = TRANS_TRIGGER_START;
|
|
this->transitionType = TRANS_TYPE_02;
|
|
}
|
|
|
|
// Gameplay_LoadToLastEntrance ?
|
|
// Used by game_over and Test7
|
|
void func_80169F78(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
|
|
this->nextEntrance = gSaveContext.respawn[RESPAWN_MODE_TOP].entrance;
|
|
gSaveContext.respawnFlag = -1;
|
|
func_80169ECC(this);
|
|
this->transitionTrigger = TRANS_TRIGGER_START;
|
|
this->transitionType = TRANS_TYPE_02;
|
|
}
|
|
|
|
// Gameplay_TriggerRespawn ?
|
|
// Used for void by Wallmaster, Deku Shrine doors. Also used by Player, Kaleido, DoorWarp1
|
|
void func_80169FDC(GameState* thisx) {
|
|
func_80169F78(thisx);
|
|
}
|
|
|
|
// Used by Kankyo to determine how to change the lighting, e.g. for game over.
|
|
s32 func_80169FFC(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
|
|
return this->roomCtx.currRoom.mesh->type0.type != 1;
|
|
}
|
|
|
|
s32 FrameAdvance_IsEnabled(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
|
|
return this->frameAdvCtx.enabled != 0;
|
|
}
|
|
|
|
// Unused, unchanged from OoT, which uses it only in one Camera function.
|
|
/**
|
|
* @brief Tests if \p actor is a door and the sides are different rooms.
|
|
*
|
|
* @param[in] thisx GameState, promoted to play inside.
|
|
* @param[in] actor Actor to test.
|
|
* @param[out] yaw Facing angle of the actor, or reverse if in the back room.
|
|
* @return true if \p actor is a door and the sides are in different rooms, false otherwise
|
|
*/
|
|
s32 func_8016A02C(GameState* thisx, Actor* actor, s16* yaw) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
TransitionActorEntry* transitionActor;
|
|
s8 frontRoom;
|
|
|
|
if (actor->category != ACTORCAT_DOOR) {
|
|
return false;
|
|
}
|
|
|
|
transitionActor = &this->doorCtx.transitionActorList[(u16)actor->params >> 10];
|
|
frontRoom = transitionActor->sides[0].room;
|
|
if (frontRoom == transitionActor->sides[1].room) {
|
|
return false;
|
|
}
|
|
|
|
if (frontRoom == actor->room) {
|
|
*yaw = actor->shape.rot.y;
|
|
} else {
|
|
*yaw = actor->shape.rot.y + 0x8000;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Unused
|
|
/**
|
|
* @brief Tests if \p pos is underwater.
|
|
*
|
|
* @param[in] play PlayState
|
|
* @param[in] pos position to test
|
|
* @return true if inside a waterbox and not above a void.
|
|
*/
|
|
s32 Play_IsUnderwater(PlayState* this, Vec3f* pos) {
|
|
WaterBox* waterBox;
|
|
CollisionPoly* poly;
|
|
Vec3f waterSurfacePos;
|
|
s32 bgId;
|
|
|
|
waterSurfacePos = *pos;
|
|
|
|
if ((WaterBox_GetSurface1(this, &this->colCtx, waterSurfacePos.x, waterSurfacePos.z, &waterSurfacePos.y,
|
|
&waterBox) == true) &&
|
|
(pos->y < waterSurfacePos.y) &&
|
|
(BgCheck_EntityRaycastFloor3(&this->colCtx, &poly, &bgId, &waterSurfacePos) != BGCHECK_Y_MIN)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
s32 Play_IsDebugCamEnabled(void) {
|
|
return gDbgCamEnabled;
|
|
}
|
|
|
|
// A mapping from playerActorCsIds to sGlobalCamDataSettings indices.
|
|
s16 D_801D0D64[] = { -3, -2, -4, -5, -7, -11, -8, -9, -6, -16 };
|
|
|
|
// Used by Player
|
|
/**
|
|
* Extract the common actor cutscene ids used by Player from the scene and set the actor cutscene ids in
|
|
* this->playerActorCsIds. If a playerActorCsId is not present in the scene, then that particular id is set
|
|
* to -1. Otherwise, if there is an ActorCutscene where csCamSceneDataId matches the appropriate element of D_801D0D64,
|
|
* set the corresponding playerActorCsId (and possibly change its priority for the zeroth one)
|
|
*/
|
|
void Play_AssignPlayerActorCsIdsFromScene(GameState* thisx, s32 startActorCsId) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
s32 i;
|
|
s16* curPlayerActorCsId = this->playerActorCsIds;
|
|
s16* phi_s1 = D_801D0D64;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(this->playerActorCsIds); i++, curPlayerActorCsId++, phi_s1++) {
|
|
ActorCutscene* actorCutscene;
|
|
s32 curActorCsId;
|
|
|
|
*curPlayerActorCsId = -1;
|
|
|
|
for (curActorCsId = startActorCsId; curActorCsId != -1; curActorCsId = actorCutscene->additionalCutscene) {
|
|
actorCutscene = ActorCutscene_GetCutscene(curActorCsId);
|
|
|
|
if (actorCutscene->csCamSceneDataId == *phi_s1) {
|
|
if ((actorCutscene->csCamSceneDataId == -3) &&
|
|
(actorCutscene->priority == 700)) { // override ocarina cs priority
|
|
actorCutscene->priority = 550;
|
|
}
|
|
*curPlayerActorCsId = curActorCsId;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// These regs are used by Gameplay_Draw, and several actors, purpose as yet unclear.
|
|
void func_8016A268(GameState* thisx, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) {
|
|
MREG(64) = arg1;
|
|
MREG(65) = arg2;
|
|
MREG(66) = arg3;
|
|
MREG(67) = arg4;
|
|
MREG(68) = arg5;
|
|
}
|
|
|
|
void Play_Init(GameState* thisx) {
|
|
PlayState* this = (PlayState*)thisx;
|
|
GraphicsContext* gfxCtx = this->state.gfxCtx;
|
|
s32 pad;
|
|
s32 temp;
|
|
s32 sp94;
|
|
Player* player;
|
|
s32 spawn;
|
|
s32 i;
|
|
u8 sp87;
|
|
u32 temp_v0_12;
|
|
s32 scene;
|
|
s16 params;
|
|
|
|
if ((gSaveContext.respawnFlag == -4) || (gSaveContext.respawnFlag == -0x63)) {
|
|
if (gSaveContext.eventInf[2] & 0x80) {
|
|
gSaveContext.eventInf[2] &= (u8)~0x80;
|
|
this->state.running = false;
|
|
{
|
|
GameState* state = &this->state;
|
|
|
|
SET_NEXT_GAMESTATE(state, Daytelop_Init, DaytelopContext);
|
|
}
|
|
return;
|
|
}
|
|
|
|
gSaveContext.unk_3CA7 = 1;
|
|
if (gSaveContext.respawnFlag == ~0x62) {
|
|
gSaveContext.respawnFlag = 2;
|
|
}
|
|
} else {
|
|
gSaveContext.unk_3CA7 = 0;
|
|
}
|
|
|
|
if (gSaveContext.save.entrance == -1) {
|
|
gSaveContext.save.entrance = 0;
|
|
this->state.running = false;
|
|
{
|
|
GameState* state = &this->state;
|
|
|
|
SET_NEXT_GAMESTATE(state, Opening_Init, OpeningContext);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ((gSaveContext.nextCutsceneIndex == 0xFFEF) || (gSaveContext.nextCutsceneIndex == 0xFFF0)) {
|
|
scene = gSaveContext.save.entrance >> 9;
|
|
spawn = (gSaveContext.save.entrance >> 4) & 0x1F;
|
|
|
|
if (gSaveContext.save.weekEventReg[33] & 0x80) {
|
|
if (scene == ENTR_SCENE_MOUNTAIN_VILLAGE_WINTER) {
|
|
scene = ENTR_SCENE_MOUNTAIN_VILLAGE_SPRING;
|
|
} else if (scene == ENTR_SCENE_GORON_VILLAGE_WINTER) {
|
|
scene = ENTR_SCENE_GORON_VILLAGE_SPRING;
|
|
} else if (scene == ENTR_SCENE_PATH_TO_GORON_VILLAGE_WINTER) {
|
|
scene = ENTR_SCENE_PATH_TO_GORON_VILLAGE_SPRING;
|
|
} else if ((scene == ENTR_SCENE_SNOWHEAD) || (scene == ENTR_SCENE_PATH_TO_SNOWHEAD) ||
|
|
(scene == ENTR_SCENE_PATH_TO_MOUNTAIN_VILLAGE) || (scene == ENTR_SCENE_GORON_SHRINE) ||
|
|
(scene == ENTR_SCENE_GORON_RACETRACK)) {
|
|
gSaveContext.nextCutsceneIndex = 0xFFF0;
|
|
}
|
|
}
|
|
|
|
if (gSaveContext.save.weekEventReg[20] & 2) {
|
|
if (scene == ENTR_SCENE_SOUTHERN_SWAMP_POISONED) {
|
|
scene = ENTR_SCENE_SOUTHERN_SWAMP_CLEARED;
|
|
} else if (scene == ENTR_SCENE_WOODFALL) {
|
|
gSaveContext.nextCutsceneIndex = 0xFFF1;
|
|
}
|
|
}
|
|
|
|
if ((gSaveContext.save.weekEventReg[52] & 0x20) && (scene == ENTR_SCENE_IKANA_CANYON)) {
|
|
gSaveContext.nextCutsceneIndex = 0xFFF2;
|
|
}
|
|
|
|
if ((gSaveContext.save.weekEventReg[55] & 0x80) &&
|
|
((scene == ENTR_SCENE_GREAT_BAY_COAST) || (scene == ENTR_SCENE_ZORA_CAPE))) {
|
|
gSaveContext.nextCutsceneIndex = 0xFFF0;
|
|
}
|
|
|
|
if (INV_CONTENT(ITEM_OCARINA) != ITEM_OCARINA) {
|
|
if ((scene == ENTR_SCENE_TERMINA_FIELD) &&
|
|
(((void)0, gSaveContext.save.entrance) != ENTRANCE(TERMINA_FIELD, 10))) {
|
|
gSaveContext.nextCutsceneIndex = 0xFFF4;
|
|
}
|
|
}
|
|
gSaveContext.save.entrance = Entrance_Create(scene, spawn, ((void)0, gSaveContext.save.entrance) & 0xF);
|
|
}
|
|
|
|
GameState_Realloc(&this->state, 0);
|
|
KaleidoManager_Init(this);
|
|
ShrinkWindow_Init();
|
|
View_Init(&this->view, gfxCtx);
|
|
func_801A3EC0(0);
|
|
Quake_Init();
|
|
Distortion_Init(this);
|
|
|
|
for (i = 0; i < ARRAY_COUNT(this->cameraPtrs); i++) {
|
|
this->cameraPtrs[i] = NULL;
|
|
}
|
|
|
|
Camera_Init(&this->mainCamera, &this->view, &this->colCtx, this);
|
|
Camera_ChangeStatus(&this->mainCamera, CAM_STATUS_ACTIVE);
|
|
|
|
for (i = 0; i < ARRAY_COUNT(this->subCameras); i++) {
|
|
Camera_Init(&this->subCameras[i], &this->view, &this->colCtx, this);
|
|
Camera_ChangeStatus(&this->subCameras[i], CAM_STATUS_INACTIVE);
|
|
}
|
|
|
|
this->cameraPtrs[CAM_ID_MAIN] = &this->mainCamera;
|
|
this->cameraPtrs[CAM_ID_MAIN]->uid = CAM_ID_MAIN;
|
|
this->activeCamId = CAM_ID_MAIN;
|
|
|
|
func_800DFF18(&this->mainCamera, 0x7F);
|
|
Sram_Alloc(&this->state, &this->sramCtx);
|
|
func_801AAAA0(this);
|
|
Message_Init(this);
|
|
GameOver_Init(this);
|
|
SoundSource_InitAll(this);
|
|
EffFootmark_Init(this);
|
|
Effect_Init(this);
|
|
EffectSS_Init(this, 100);
|
|
CollisionCheck_InitContext(this, &this->colChkCtx);
|
|
AnimationContext_Reset(&this->animationCtx);
|
|
Cutscene_Init(this, &this->csCtx);
|
|
|
|
if (gSaveContext.nextCutsceneIndex != 0xFFEF) {
|
|
gSaveContext.save.cutscene = gSaveContext.nextCutsceneIndex;
|
|
gSaveContext.nextCutsceneIndex = 0xFFEF;
|
|
}
|
|
|
|
if (gSaveContext.save.cutscene == 0xFFFD) {
|
|
gSaveContext.save.cutscene = 0;
|
|
}
|
|
|
|
if (gSaveContext.nextDayTime != 0xFFFF) {
|
|
gSaveContext.save.time = gSaveContext.nextDayTime;
|
|
gSaveContext.skyboxTime = gSaveContext.nextDayTime;
|
|
}
|
|
|
|
if ((gSaveContext.save.time >= CLOCK_TIME(18, 0)) || (gSaveContext.save.time < CLOCK_TIME(6, 30))) {
|
|
gSaveContext.save.isNight = true;
|
|
} else {
|
|
gSaveContext.save.isNight = false;
|
|
}
|
|
|
|
func_800EDDB0(this);
|
|
|
|
if (((gSaveContext.gameMode != 0) && (gSaveContext.gameMode != 1)) || (gSaveContext.save.cutscene >= 0xFFF0)) {
|
|
gSaveContext.unk_3DC0 = 0;
|
|
func_80115D5C(&this->state);
|
|
gSaveContext.sceneSetupIndex = (gSaveContext.save.cutscene & 0xF) + 1;
|
|
gSaveContext.save.cutscene = 0;
|
|
} else {
|
|
gSaveContext.sceneSetupIndex = 0;
|
|
}
|
|
|
|
sp87 = gSaveContext.sceneSetupIndex;
|
|
|
|
//! FAKE: temp. Also introduces a warning.
|
|
Play_SceneInit(
|
|
this,
|
|
Entrance_GetSceneNumAbsolute(((void)0, gSaveContext.save.entrance) +
|
|
((void)0, (temp = gSaveContext.sceneSetupIndex))),
|
|
Entrance_GetSpawnNum(((void)0, gSaveContext.save.entrance) + ((void)0, (temp = gSaveContext.sceneSetupIndex))));
|
|
KaleidoScopeCall_Init(this);
|
|
func_80121FC4(this);
|
|
|
|
if (gSaveContext.nextDayTime != 0xFFFF) {
|
|
if (gSaveContext.nextDayTime == 0x8000) {
|
|
gSaveContext.save.day++;
|
|
gSaveContext.save.daysElapsed++;
|
|
gSaveContext.dogIsLost = true;
|
|
gSaveContext.nextDayTime = -2;
|
|
} else {
|
|
gSaveContext.nextDayTime = -3;
|
|
}
|
|
}
|
|
|
|
func_80165608();
|
|
|
|
SREG(94) = 0;
|
|
SREG(89) = 0;
|
|
|
|
PreRender_Init(&this->pauseBgPreRender);
|
|
PreRender_SetValuesSave(&this->pauseBgPreRender, D_801FBBCC, D_801FBBCE, NULL, NULL, NULL);
|
|
PreRender_SetValues(&this->pauseBgPreRender, D_801FBBCC, D_801FBBCE, NULL, NULL);
|
|
|
|
this->unk_18E64 = D_801FBB90;
|
|
this->unk_18E5C = D_80780000;
|
|
this->unk_18E68 = D_80784600;
|
|
this->unk_18E58 = D_80784600;
|
|
this->unk_18E60 = D_80784600;
|
|
D_801F6D10 = 0;
|
|
this->transitionMode = TRANS_MODE_OFF;
|
|
D_801D0D54 = 0;
|
|
|
|
FrameAdvance_Init(&this->frameAdvCtx);
|
|
Rand_Seed(osGetTime());
|
|
Matrix_Init(&this->state);
|
|
|
|
this->state.main = Play_Main;
|
|
this->state.destroy = Play_Destroy;
|
|
|
|
this->transitionTrigger = TRANS_TRIGGER_END;
|
|
this->unk_18876 = 0;
|
|
this->bgCoverAlpha = 0;
|
|
this->unk_18845 = 0;
|
|
this->unk_18844 = 0;
|
|
|
|
if (gSaveContext.gameMode != 1) {
|
|
if (gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) {
|
|
this->transitionType =
|
|
(Entrance_GetTransitionFlags(((void)0, gSaveContext.save.entrance) + sp87) >> 7) & 0x7F;
|
|
} else {
|
|
this->transitionType = gSaveContext.nextTransitionType;
|
|
gSaveContext.nextTransitionType = TRANS_NEXT_TYPE_DEFAULT;
|
|
}
|
|
} else {
|
|
this->transitionType = TRANS_TYPE_02;
|
|
}
|
|
|
|
TransitionFade_Init(&this->unk_18E48);
|
|
TransitionFade_SetType(&this->unk_18E48, 3);
|
|
TransitionFade_SetColor(&this->unk_18E48, RGBA8(160, 160, 160, 255));
|
|
TransitionFade_Start(&this->unk_18E48);
|
|
VisMono_Init(&D_801F6D18);
|
|
|
|
D_801F6D30.a = 0;
|
|
D_801F6D4C = &D_801F6D38;
|
|
func_80140E80(D_801F6D4C);
|
|
D_801F6D4C->lodProportion = 0.0f;
|
|
D_801F6D4C->mode = 1;
|
|
D_801F6D4C->primColor.r = 0;
|
|
D_801F6D4C->primColor.g = 0;
|
|
D_801F6D4C->primColor.b = 0;
|
|
D_801F6D4C->primColor.a = 0;
|
|
D_801F6D4C->envColor.r = 0;
|
|
D_801F6D4C->envColor.g = 0;
|
|
D_801F6D4C->envColor.b = 0;
|
|
D_801F6D4C->envColor.a = 0;
|
|
EnvFlags_UnsetAll(this);
|
|
THA_GetSize(&this->state.heap);
|
|
sp94 = THA_GetSize(&this->state.heap);
|
|
temp_v0_12 = (u32)THA_AllocEndAlign16(&this->state.heap, sp94);
|
|
ZeldaArena_Init(((temp_v0_12 + 8) & ~0xF), (sp94 - ((temp_v0_12 + 8) & ~0xF)) + temp_v0_12);
|
|
Actor_InitContext(this, &this->actorCtx, this->linkActorEntry);
|
|
|
|
while (Room_HandleLoadCallbacks(this, &this->roomCtx) == 0) {}
|
|
|
|
if ((CURRENT_DAY != 0) && ((this->roomCtx.currRoom.unk3 == 1) || (this->roomCtx.currRoom.unk3 == 5))) {
|
|
Actor_Spawn(&this->actorCtx, this, 0x15A, 0.0f, 0.0f, 0.0f, 0, 0, 0, 0);
|
|
}
|
|
|
|
player = GET_PLAYER(this);
|
|
|
|
Camera_InitPlayerSettings(&this->mainCamera, player);
|
|
gDbgCamEnabled = false;
|
|
|
|
if ((player->actor.params & 0xFF) != 0xFF) {
|
|
Camera_ChangeDataIdx(&this->mainCamera, player->actor.params & 0xFF);
|
|
}
|
|
|
|
func_800F15D8(&this->mainCamera);
|
|
func_801129E4(this);
|
|
func_800FB758(this);
|
|
gSaveContext.seqIndex = this->soundCtx.seqIndex;
|
|
gSaveContext.nightSeqIndex = this->soundCtx.nightSeqIndex;
|
|
AnimationContext_Update(this, &this->animationCtx);
|
|
func_800EDBE0(this);
|
|
gSaveContext.respawnFlag = 0;
|
|
D_801F6DFC = 0;
|
|
func_8016FC78(&D_801F6D50);
|
|
}
|
|
|
|
// play_hireso need to confirm still
|
|
u16 D_801D0D78[] = { 0, 0, 0, 0 };
|