mirror of
https://github.com/zeldaret/oot.git
synced 2025-08-07 06:40:15 +00:00
Elf_Msg, Elf_Msg2 OK (#317)
* matched func_809AD700, ElfMsg2_Init * func_809AD968 done * func_809AD978 and func_809AD9F4 done * func_809ADA28 done * ElfMsg2_Update Done, ElfMsg2_Draw Started * whole file decomped * Matching and all symbols defined * Formatting changes, not currently building * run format.sh * fixed typos in comments * Changes to reflect comments * C file matching, polish needed * making parenthesis usage consistent * Documenting draw function, Vtx and Gfx arrays * Added japanese translation comments * line spacing fix * renaming stuff * Early return in Draw * naming updates * Cleaning up names, comments and formatting after the merge * comment cleanup * more cleanup * More cleanup * Adding commas at end of arrays so they look nicer :) * more cleanup * removing unnecessary parentheses * comment and code changes * Name changes * Renamings * Removing documentation at top
This commit is contained in:
parent
13891f1366
commit
7a9c51375b
31 changed files with 396 additions and 1136 deletions
|
@ -1,4 +1,12 @@
|
|||
/*
|
||||
* File: z_elf_msg.c
|
||||
* Overlay: ovl_Elf_Msg
|
||||
* Description: Readable Navi call spot
|
||||
*/
|
||||
|
||||
#include "z_elf_msg.h"
|
||||
#include <vt.h>
|
||||
#include "overlays/actors/ovl_En_Elf/z_en_elf.h"
|
||||
|
||||
#define FLAGS 0x00000010
|
||||
|
||||
|
@ -9,7 +17,9 @@ void ElfMsg_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void ElfMsg_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void ElfMsg_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
void ElfMsg_CallNaviCuboid(ElfMsg* this, GlobalContext* globalCtx);
|
||||
void ElfMsg_CallNaviCylinder(ElfMsg* this, GlobalContext* globalCtx);
|
||||
|
||||
const ActorInit Elf_Msg_InitVars = {
|
||||
ACTOR_ELF_MSG,
|
||||
ACTORTYPE_ITEMACTION,
|
||||
|
@ -21,23 +31,217 @@ const ActorInit Elf_Msg_InitVars = {
|
|||
(ActorFunc)ElfMsg_Update,
|
||||
(ActorFunc)ElfMsg_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/func_809ACB20.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/func_809ACB28.s")
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/ElfMsg_Init.s")
|
||||
// Draw properties
|
||||
Gfx D_809AD278[] = {
|
||||
gsDPPipeSync(),
|
||||
gsDPSetTextureLUT(G_TT_NONE),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
|
||||
gsDPSetCombineLERP(PRIMITIVE, 0, SHADE, 0, 0, 0, 0, PRIMITIVE, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED),
|
||||
gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_XLU_SURF2),
|
||||
gsSPClearGeometryMode(G_CULL_BACK | G_FOG | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR),
|
||||
gsSPSetGeometryMode(G_LIGHTING),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/ElfMsg_Destroy.s")
|
||||
static Vtx sCylinderVertices[] = {
|
||||
VTX(100, 0, 0, 0, 0, 0x59, 0xA7, 0x00, 0xFF), VTX(70, 0, 70, 0, 0, 0x49, 0xB7, 0x49, 0xFF),
|
||||
VTX(0, 0, 100, 0, 0, 0x00, 0xA7, 0x59, 0xFF), VTX(-70, 0, 70, 0, 0, 0xB7, 0xB7, 0x49, 0xFF),
|
||||
VTX(-100, 0, 0, 0, 0, 0xA7, 0xA7, 0x00, 0xFF), VTX(-70, 0, -70, 0, 0, 0xB7, 0xB7, 0xB7, 0xFF),
|
||||
VTX(0, 0, -100, 0, 0, 0x00, 0xA7, 0xA7, 0xFF), VTX(70, 0, -70, 0, 0, 0x49, 0xB7, 0xB7, 0xFF),
|
||||
VTX(100, 100, 0, 0, 0, 0x59, 0x59, 0x00, 0xFF), VTX(70, 100, 70, 0, 0, 0x49, 0x49, 0x49, 0xFF),
|
||||
VTX(0, 100, 100, 0, 0, 0x00, 0x59, 0x59, 0xFF), VTX(-70, 100, 70, 0, 0, 0xB7, 0x49, 0x49, 0xFF),
|
||||
VTX(-100, 100, 0, 0, 0, 0xA7, 0x59, 0x00, 0xFF), VTX(-70, 100, -70, 0, 0, 0xB7, 0x49, 0xB7, 0xFF),
|
||||
VTX(0, 100, -100, 0, 0, 0x00, 0x59, 0xA7, 0xFF), VTX(70, 100, -70, 0, 0, 0x49, 0x49, 0xB7, 0xFF),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/func_809ACDCC.s")
|
||||
// Polygons for cylinder
|
||||
Gfx D_809AD3B8[] = {
|
||||
gsSPVertex(sCylinderVertices, 16, 0), gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0),
|
||||
gsSP2Triangles(0, 3, 4, 0, 0, 4, 5, 0), gsSP2Triangles(0, 5, 6, 0, 0, 6, 7, 0),
|
||||
gsSP2Triangles(8, 9, 10, 0, 8, 10, 11, 0), gsSP2Triangles(8, 11, 12, 0, 8, 12, 13, 0),
|
||||
gsSP2Triangles(8, 13, 14, 0, 8, 14, 15, 0), gsSP2Triangles(0, 1, 8, 0, 1, 8, 9, 0),
|
||||
gsSP2Triangles(1, 2, 9, 0, 2, 9, 10, 0), gsSP2Triangles(2, 3, 10, 0, 3, 10, 11, 0),
|
||||
gsSP2Triangles(3, 4, 11, 0, 4, 11, 12, 0), gsSP2Triangles(4, 5, 12, 0, 5, 12, 13, 0),
|
||||
gsSP2Triangles(5, 6, 13, 0, 6, 13, 14, 0), gsSP2Triangles(6, 7, 14, 0, 7, 14, 15, 0),
|
||||
gsSP2Triangles(7, 0, 15, 0, 0, 15, 8, 0), gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/func_809ACDF8.s")
|
||||
static Vtx sCuboidVertices[] = {
|
||||
VTX(100, 0, 100, 0, 0, 0x49, 0xB7, 0x49, 0xFF), VTX(100, 0, -100, 0, 0, 0x49, 0xB7, 0xB7, 0xFF),
|
||||
VTX(-100, 0, -100, 0, 0, 0xB7, 0xB7, 0xB7, 0xFF), VTX(-100, 0, 100, 0, 0, 0xB7, 0xB7, 0x49, 0xFF),
|
||||
VTX(100, 100, 100, 0, 0, 0x49, 0x49, 0x49, 0xFF), VTX(100, 100, -100, 0, 0, 0x49, 0x49, 0xB7, 0xFF),
|
||||
VTX(-100, 100, -100, 0, 0, 0xB7, 0x49, 0xB7, 0xFF), VTX(-100, 100, 100, 0, 0, 0xB7, 0x49, 0x49, 0xFF),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/func_809ACEC8.s")
|
||||
// Polygons for cuboid
|
||||
Gfx D_809AD4B8[] = {
|
||||
gsSPVertex(sCuboidVertices, 8, 0), gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0),
|
||||
gsSP2Triangles(4, 5, 6, 0, 4, 6, 7, 0), gsSP2Triangles(0, 1, 4, 0, 1, 4, 5, 0),
|
||||
gsSP2Triangles(1, 2, 5, 0, 2, 5, 6, 0), gsSP2Triangles(2, 3, 6, 0, 3, 6, 7, 0),
|
||||
gsSP2Triangles(3, 0, 7, 0, 0, 7, 4, 0), gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/func_809ACF18.s")
|
||||
void ElfMsg_SetupAction(ElfMsg* this, ElfMsgActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/ElfMsg_Update.s")
|
||||
/**
|
||||
* Checks a scene flag - if flag is set, the actor is killed and function returns 1. Otherwise returns 0.
|
||||
* Can also set a switch flag from params while killing.
|
||||
*/
|
||||
s32 ElfMsg_KillCheck(ElfMsg* this, GlobalContext* globalCtx) {
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg/ElfMsg_Draw.s")
|
||||
if ((this->actor.posRot.rot.y > 0) && (this->actor.posRot.rot.y < 0x41) &&
|
||||
(Flags_GetSwitch(globalCtx, this->actor.posRot.rot.y - 1))) {
|
||||
// "Mutual destruction"
|
||||
LOG_STRING("共倒れ", "../z_elf_msg.c", 161);
|
||||
if (((this->actor.params >> 8) & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(globalCtx, ((this->actor.params >> 8) & 0x3F));
|
||||
}
|
||||
Actor_Kill(&this->actor);
|
||||
return 1;
|
||||
} else if ((this->actor.posRot.rot.y == -1) && (Flags_GetClear(globalCtx, this->actor.room))) {
|
||||
// "Mutual destruction"
|
||||
LOG_STRING("共倒れ", "../z_elf_msg.c", 172);
|
||||
if (((this->actor.params >> 8) & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(globalCtx, ((this->actor.params >> 8) & 0x3F));
|
||||
}
|
||||
Actor_Kill(&this->actor);
|
||||
return 1;
|
||||
} else if (((this->actor.params >> 8) & 0x3F) == 0x3F) {
|
||||
return 0;
|
||||
} else if (Flags_GetSwitch(globalCtx, ((this->actor.params >> 8) & 0x3F))) {
|
||||
Actor_Kill(&this->actor);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ElfMsg_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ElfMsg* this = THIS;
|
||||
|
||||
// "Conditions for Elf Tag disappearing"
|
||||
osSyncPrintf(VT_FGCOL(CYAN) "\nエルフ タグ 消える条件 %d" VT_RST "\n", (thisx->params >> 8) & 0x3F);
|
||||
osSyncPrintf(VT_FGCOL(CYAN) "\nthisx->shape.angle.sy = %d\n" VT_RST, thisx->shape.rot.y);
|
||||
if (thisx->shape.rot.y >= 0x41) {
|
||||
// "Conditions for Elf Tag appearing"
|
||||
osSyncPrintf(VT_FGCOL(CYAN) "\nエルフ タグ 出現条件 %d" VT_RST "\n", thisx->shape.rot.y - 0x41);
|
||||
}
|
||||
|
||||
if (!ElfMsg_KillCheck(this, globalCtx)) {
|
||||
Actor_ProcessInitChain(thisx, sInitChain);
|
||||
if (thisx->posRot.rot.x == 0) {
|
||||
thisx->scale.z = 0.4f;
|
||||
thisx->scale.x = 0.4f;
|
||||
} else {
|
||||
thisx->scale.x = thisx->scale.z = thisx->posRot.rot.x * 0.04f;
|
||||
}
|
||||
|
||||
if (thisx->posRot.rot.z == 0) {
|
||||
thisx->scale.y = 0.4f;
|
||||
} else {
|
||||
thisx->scale.y = thisx->posRot.rot.z * 0.04f;
|
||||
}
|
||||
|
||||
if (thisx->params & 0x4000) {
|
||||
ElfMsg_SetupAction(this, ElfMsg_CallNaviCuboid);
|
||||
} else {
|
||||
ElfMsg_SetupAction(this, ElfMsg_CallNaviCylinder);
|
||||
}
|
||||
|
||||
thisx->shape.rot.x = thisx->shape.rot.y = thisx->shape.rot.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
s32 ElfMsg_GetMessageId(ElfMsg* this) {
|
||||
// Negative message ID forces link to talk to Navi
|
||||
if (this->actor.params & 0x8000) {
|
||||
return (this->actor.params & 0xFF) + 0x100;
|
||||
} else {
|
||||
return -((this->actor.params & 0xFF) + 0x100);
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg_CallNaviCuboid(ElfMsg* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
EnElf* navi = (EnElf*)player->navi;
|
||||
|
||||
if ((fabsf(player->actor.posRot.pos.x - this->actor.posRot.pos.x) < (100.0f * this->actor.scale.x)) &&
|
||||
(this->actor.posRot.pos.y <= player->actor.posRot.pos.y) &&
|
||||
((player->actor.posRot.pos.y - this->actor.posRot.pos.y) < (100.0f * this->actor.scale.y)) &&
|
||||
(fabsf(player->actor.posRot.pos.z - this->actor.posRot.pos.z) < (100.0f * this->actor.scale.z))) {
|
||||
player->naviMessageId = ElfMsg_GetMessageId(this);
|
||||
navi->unk_298 = &this->actor;
|
||||
}
|
||||
}
|
||||
|
||||
s32 ElfMsg_WithinXZDistance(Vec3f* pos1, Vec3f* pos2, f32 distance) {
|
||||
return (SQ(pos2->x - pos1->x) + SQ(pos2->z - pos1->z)) < SQ(distance);
|
||||
}
|
||||
|
||||
void ElfMsg_CallNaviCylinder(ElfMsg* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
EnElf* navi = (EnElf*)player->navi;
|
||||
|
||||
if (ElfMsg_WithinXZDistance(&player->actor.posRot.pos, &this->actor.posRot.pos, this->actor.scale.x * 100.0f) &&
|
||||
(this->actor.posRot.pos.y <= player->actor.posRot.pos.y) &&
|
||||
((player->actor.posRot.pos.y - this->actor.posRot.pos.y) < (100.0f * this->actor.scale.y))) {
|
||||
player->naviMessageId = ElfMsg_GetMessageId(this);
|
||||
navi->unk_298 = &this->actor;
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ElfMsg* this = THIS;
|
||||
|
||||
if (!ElfMsg_KillCheck(this, globalCtx)) {
|
||||
if (func_8002F194(&this->actor, globalCtx)) {
|
||||
if (((this->actor.params >> 8) & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(globalCtx, (this->actor.params >> 8) & 0x3F);
|
||||
}
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
if ((this->actor.posRot.rot.y <= 0x41) || (this->actor.posRot.rot.y > 0x80) ||
|
||||
Flags_GetSwitch(globalCtx, this->actor.posRot.rot.y - 0x41)) {
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
GraphicsContext* gfxCtx = globalCtx->state.gfxCtx;
|
||||
Gfx* dispRefs[4];
|
||||
|
||||
Graph_OpenDisps(dispRefs, globalCtx->state.gfxCtx, "../z_elf_msg.c", 436);
|
||||
if (R_NAVI_MSG_REGION_ALPHA == 0) {
|
||||
return;
|
||||
}
|
||||
func_80093D18(globalCtx->state.gfxCtx);
|
||||
if (thisx->params & 0x8000) {
|
||||
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0, 255, 100, 100, R_NAVI_MSG_REGION_ALPHA);
|
||||
} else {
|
||||
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0, 255, 255, 255, R_NAVI_MSG_REGION_ALPHA);
|
||||
}
|
||||
|
||||
gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_elf_msg.c", 448),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gfxCtx->polyXlu.p++, D_809AD278);
|
||||
|
||||
if (thisx->params & 0x4000) {
|
||||
gSPDisplayList(gfxCtx->polyXlu.p++, D_809AD4B8);
|
||||
} else {
|
||||
gSPDisplayList(gfxCtx->polyXlu.p++, D_809AD3B8);
|
||||
}
|
||||
|
||||
Graph_CloseDisps(dispRefs, globalCtx->state.gfxCtx, "../z_elf_msg.c", 457);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
|
||||
struct ElfMsg;
|
||||
|
||||
typedef void (*ElfMsgActionFunc)(struct ElfMsg*, GlobalContext*);
|
||||
|
||||
typedef struct ElfMsg {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x4];
|
||||
/* 0x014C */ ElfMsgActionFunc actionFunc;
|
||||
} ElfMsg; // size = 0x0150
|
||||
|
||||
extern const ActorInit Elf_Msg_InitVars;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
/*
|
||||
* File: z_elf_msg2.c
|
||||
* Overlay: ovl_Elf_Msg2
|
||||
* Description: Targetable Navi check spot
|
||||
*/
|
||||
|
||||
#include "z_elf_msg2.h"
|
||||
#include <vt.h>
|
||||
|
||||
#define FLAGS 0x00000010
|
||||
|
||||
|
@ -9,7 +16,10 @@ void ElfMsg2_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void ElfMsg2_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void ElfMsg2_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
s32 ElfMsg2_GetMessageId(ElfMsg2* this);
|
||||
void ElfMsg2_WaitUntilActivated(ElfMsg2* this, GlobalContext* globalCtx);
|
||||
void ElfMsg2_WaitForTextRead(ElfMsg2* this, GlobalContext* globalCtx);
|
||||
|
||||
const ActorInit Elf_Msg2_InitVars = {
|
||||
ACTOR_ELF_MSG2,
|
||||
ACTORTYPE_BG,
|
||||
|
@ -21,23 +31,168 @@ const ActorInit Elf_Msg2_InitVars = {
|
|||
(ActorFunc)ElfMsg2_Update,
|
||||
(ActorFunc)ElfMsg2_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/func_809AD700.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/func_809AD708.s")
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 200, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/ElfMsg2_Init.s")
|
||||
// Draw properties
|
||||
Gfx D_809ADC38[] = {
|
||||
gsDPPipeSync(),
|
||||
gsDPSetTextureLUT(G_TT_NONE),
|
||||
gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF),
|
||||
gsDPSetCombineLERP(PRIMITIVE, 0, SHADE, 0, 0, 0, 0, PRIMITIVE, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED),
|
||||
gsDPSetRenderMode(G_RM_PASS, G_RM_AA_ZB_XLU_SURF2),
|
||||
gsSPClearGeometryMode(G_CULL_BACK | G_FOG | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR),
|
||||
gsSPSetGeometryMode(G_LIGHTING),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/ElfMsg2_Destroy.s")
|
||||
static Vtx sCuboidVertices[] = {
|
||||
VTX(100, 0, 100, 0, 0, 0x49, 0xB7, 0x49, 0xFF), VTX(100, 0, -100, 0, 0, 0x49, 0xB7, 0xB7, 0xFF),
|
||||
VTX(-100, 0, -100, 0, 0, 0xB7, 0xB7, 0xB7, 0xFF), VTX(-100, 0, 100, 0, 0, 0xB7, 0xB7, 0x49, 0xFF),
|
||||
VTX(100, 100, 100, 0, 0, 0x49, 0x49, 0x49, 0xFF), VTX(100, 100, -100, 0, 0, 0x49, 0x49, 0xB7, 0xFF),
|
||||
VTX(-100, 100, -100, 0, 0, 0xB7, 0x49, 0xB7, 0xFF), VTX(-100, 100, 100, 0, 0, 0xB7, 0x49, 0x49, 0xFF),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/func_809AD968.s")
|
||||
// Cuboid polygons
|
||||
Gfx D_809ADCF8[] = {
|
||||
gsSPVertex(sCuboidVertices, 8, 0), gsSP2Triangles(0, 1, 2, 0, 0, 2, 3, 0),
|
||||
gsSP2Triangles(4, 5, 6, 0, 4, 6, 7, 0), gsSP2Triangles(0, 1, 4, 0, 1, 4, 5, 0),
|
||||
gsSP2Triangles(1, 2, 5, 0, 2, 5, 6, 0), gsSP2Triangles(2, 3, 6, 0, 3, 6, 7, 0),
|
||||
gsSP2Triangles(3, 0, 7, 0, 0, 7, 4, 0), gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/func_809AD978.s")
|
||||
void ElfMsg2_SetupAction(ElfMsg2* this, ElfMsg2ActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/func_809AD9F4.s")
|
||||
/**
|
||||
* Checks a scene flag - if flag is set, the actor is killed and function returns 1. Otherwise returns 0.
|
||||
* Can also set a switch flag from params while killing.
|
||||
*/
|
||||
s32 ElfMsg2_KillCheck(ElfMsg2* this, GlobalContext* globalCtx) {
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/func_809ADA28.s")
|
||||
if ((this->actor.posRot.rot.y > 0) && (this->actor.posRot.rot.y < 0x41) &&
|
||||
(Flags_GetSwitch(globalCtx, this->actor.posRot.rot.y - 1))) {
|
||||
// "Mutual destruction"
|
||||
LOG_STRING("共倒れ", "../z_elf_msg2.c", 171);
|
||||
if (((this->actor.params >> 8) & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(globalCtx, ((this->actor.params >> 8) & 0x3F));
|
||||
}
|
||||
Actor_Kill(&this->actor);
|
||||
return 1;
|
||||
} else if ((this->actor.posRot.rot.y == -1) && (Flags_GetClear(globalCtx, this->actor.room))) {
|
||||
// "Mutual destruction 2"
|
||||
LOG_STRING("共倒れ2", "../z_elf_msg2.c", 182);
|
||||
if (((this->actor.params >> 8) & 0x3F) != 0x3F) {
|
||||
Flags_SetSwitch(globalCtx, ((this->actor.params >> 8) & 0x3F));
|
||||
}
|
||||
Actor_Kill(&this->actor);
|
||||
return 1;
|
||||
} else if (((this->actor.params >> 8) & 0x3F) == 0x3F) {
|
||||
return 0;
|
||||
} else if (Flags_GetSwitch(globalCtx, ((this->actor.params >> 8) & 0x3F))) {
|
||||
// "Mutual destruction"
|
||||
LOG_STRING("共倒れ", "../z_elf_msg2.c", 192);
|
||||
Actor_Kill(&this->actor);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/ElfMsg2_Update.s")
|
||||
void ElfMsg2_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ElfMsg2* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Elf_Msg2/ElfMsg2_Draw.s")
|
||||
osSyncPrintf(VT_FGCOL(CYAN) " Elf_Msg2_Actor_ct %04x\n\n" VT_RST, this->actor.params);
|
||||
if (!ElfMsg2_KillCheck(this, globalCtx)) {
|
||||
if ((this->actor.posRot.rot.x > 0) && (this->actor.posRot.rot.x < 8)) {
|
||||
this->actor.unk_1F = this->actor.posRot.rot.x - 1;
|
||||
}
|
||||
Actor_ProcessInitChain(thisx, sInitChain);
|
||||
if (this->actor.posRot.rot.y >= 0x41) {
|
||||
ElfMsg2_SetupAction(this, ElfMsg2_WaitUntilActivated);
|
||||
} else {
|
||||
ElfMsg2_SetupAction(this, ElfMsg2_WaitForTextRead);
|
||||
this->actor.flags |= 0x00040001; // Make actor targetable and Navi-checkable
|
||||
this->actor.textId = ElfMsg2_GetMessageId(this);
|
||||
}
|
||||
this->actor.shape.rot.x = this->actor.shape.rot.y = this->actor.shape.rot.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
s32 ElfMsg2_GetMessageId(ElfMsg2* this) {
|
||||
return (this->actor.params & 0xFF) + 0x100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs while Navi text is up. Kills the actor upon closing the text box unless rot.z == 1, can also set a switch flag
|
||||
* from params.
|
||||
*/
|
||||
void ElfMsg2_WaitForTextClose(ElfMsg2* this, GlobalContext* globalCtx) {
|
||||
s32 switchFlag;
|
||||
|
||||
if (func_8002F334(&this->actor, globalCtx)) {
|
||||
if (this->actor.posRot.rot.z != 1) {
|
||||
Actor_Kill(&this->actor);
|
||||
switchFlag = (this->actor.params >> 8) & 0x3F;
|
||||
if (switchFlag != 0x3F) {
|
||||
Flags_SetSwitch(globalCtx, switchFlag);
|
||||
}
|
||||
} else {
|
||||
ElfMsg2_SetupAction(this, ElfMsg2_WaitForTextRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs while Navi text is not up.
|
||||
*/
|
||||
void ElfMsg2_WaitForTextRead(ElfMsg2* this, GlobalContext* globalCtx) {
|
||||
if (func_8002F194(&this->actor, globalCtx)) {
|
||||
ElfMsg2_SetupAction(this, ElfMsg2_WaitForTextClose);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Idles until a switch flag is set, at which point the actor becomes interactable
|
||||
*/
|
||||
void ElfMsg2_WaitUntilActivated(ElfMsg2* this, GlobalContext* globalCtx) {
|
||||
// If (y >= 0x41) && (y <= 0x80), Idles until switch flag (actor.posRot.rot.y - 0x41) is set
|
||||
// If (y > 0x80), Idles forever (Bug?)
|
||||
if ((this->actor.posRot.rot.y >= 0x41) && (this->actor.posRot.rot.y <= 0x80) &&
|
||||
(Flags_GetSwitch(globalCtx, (this->actor.posRot.rot.y - 0x41)))) {
|
||||
ElfMsg2_SetupAction(this, ElfMsg2_WaitForTextRead);
|
||||
this->actor.flags |= 0x00040001; // Make actor targetable and Navi-checkable
|
||||
this->actor.textId = ElfMsg2_GetMessageId(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg2_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ElfMsg2* this = THIS;
|
||||
if (!ElfMsg2_KillCheck(this, globalCtx)) {
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void ElfMsg2_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
GraphicsContext* gfxCtx;
|
||||
Gfx* dispRefs[4];
|
||||
|
||||
gfxCtx = globalCtx->state.gfxCtx;
|
||||
Graph_OpenDisps(dispRefs, globalCtx->state.gfxCtx, "../z_elf_msg2.c", 355);
|
||||
if (R_NAVI_MSG_REGION_ALPHA == 0) {
|
||||
return;
|
||||
}
|
||||
func_80093D18(globalCtx->state.gfxCtx);
|
||||
gDPSetPrimColor(gfxCtx->polyXlu.p++, 0, 0, 100, 100, 255, R_NAVI_MSG_REGION_ALPHA);
|
||||
gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_elf_msg2.c", 362),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gfxCtx->polyXlu.p++, D_809ADC38);
|
||||
gSPDisplayList(gfxCtx->polyXlu.p++, D_809ADCF8);
|
||||
Graph_CloseDisps(dispRefs, globalCtx->state.gfxCtx, "../z_elf_msg2.c", 367);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
|
||||
struct ElfMsg2;
|
||||
|
||||
typedef void (*ElfMsg2ActionFunc)(struct ElfMsg2*, GlobalContext*);
|
||||
|
||||
typedef struct ElfMsg2 {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x4];
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ ElfMsg2ActionFunc actionFunc;
|
||||
} ElfMsg2; // size = 0x0150
|
||||
|
||||
extern const ActorInit Elf_Msg2_InitVars;
|
||||
|
|
|
@ -8,7 +8,9 @@ struct EnElf;
|
|||
|
||||
typedef struct EnElf {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x184];
|
||||
/* 0x014C */ char unk_14C[0x14C];
|
||||
/* 0x0298 */ Actor* unk_298;
|
||||
/* 0x029C */ char unk_29C[0x34];
|
||||
} EnElf; // size = 0x02D0
|
||||
|
||||
extern const ActorInit En_Elf_InitVars;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue