1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-08-07 14:50:15 +00:00

ovl_Obj_Lightswitch OK and documented (#373)

* ovl_Obj_Lightswitch OK

* ovl_Obj_Lightswitch documented

* Removed unneeded prototypes

* Minor cleanup

* Cleanup, names

* Use color array for more sane SetEnvColor

* enum styling

Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com>

* more enum styling

* globalCtx2 meme

* XxxInit -> SetupXxx

Co-authored-by: Roman971 <32455037+Roman971@users.noreply.github.com>
This commit is contained in:
Dragorn421 2020-09-27 16:35:52 +02:00 committed by GitHub
parent 2a9225763b
commit a7beb8814b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 466 additions and 1486 deletions

View file

@ -5,17 +5,43 @@
*/
#include "z_obj_lightswitch.h"
#include <vt.h>
#define FLAGS 0x00000010
#define THIS ((ObjLightswitch*)thisx)
typedef enum {
/* 0x00 */ FACE_EYES_CLOSED,
/* 0x01 */ FACE_EYES_OPEN,
/* 0x02 */ FACE_EYES_OPEN_SMILING
} FaceTextureIndex;
void ObjLightswitch_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjLightswitch_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjLightswitch_Draw(Actor* thisx, GlobalContext* globalCtx);
/*
void ObjLightswitch_SetupOff(ObjLightswitch* this);
void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_SetupTurnOn(ObjLightswitch* this);
void ObjLightswitch_TurnOn(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_SetupOn(ObjLightswitch* this);
void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_SetupTurnOff(ObjLightswitch* this);
void ObjLightswitch_TurnOff(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_SetupDisappearDelay(ObjLightswitch* this);
void ObjLightswitch_DisappearDelay(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_SetupDisappear(ObjLightswitch* this);
void ObjLightswitch_Disappear(ObjLightswitch* this, GlobalContext* globalCtx);
extern Gfx D_06000260[]; // face, uses rgba16 32x32 texture at 0x08000000, branches to dlist 0x09000000, uses env color
extern Gfx D_06000398[]; // flame ring, branches to dlist 0x09000000, uses env color
extern Gfx D_06000408[]; // a square, geometry only
extern UNK_TYPE D_06000420[]; // rgba16 32x32 eyes open
extern UNK_TYPE D_06000C20[]; // rgba16 32x32 eyes closed
extern UNK_TYPE D_06001420[]; // rgba16 32x32 eyes open, smiling
const ActorInit Obj_Lightswitch_InitVars = {
ACTOR_OBJ_LIGHTSWITCH,
ACTORTYPE_SWITCH,
@ -27,47 +53,433 @@ const ActorInit Obj_Lightswitch_InitVars = {
(ActorFunc)ObjLightswitch_Update,
(ActorFunc)ObjLightswitch_Draw,
};
*/
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B96BA0.s")
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B96C3C.s")
static ColliderJntSphItemInit sColliderJntSphItemInit[] = {
{
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 0, { { 0, 0, 0 }, 19 }, 100 },
},
};
static ColliderJntSphInit sColliderJntSphInit = {
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x20, COLSHAPE_JNTSPH },
1,
sColliderJntSphItemInit,
};
static CollisionCheckInfoInit sCollisionCheckInfoInit = { 0, 0xC, 0x3C, 0xFF };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B96D00.s")
static UNK_PTR faceTextures[] = { D_06000C20, D_06000420, D_06001420 };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B96D80.s")
static Vec3f D_80B97F68 = { -1707.0f, 843.0f, -180.0f };
static Vec3f D_80B97F74 = { 0.0f, 0.0f, 0.0f };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/ObjLightswitch_Init.s")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/ObjLightswitch_Destroy.s")
void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) {
s32 pad;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B971A8.s")
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sColliderJntSphInit, this->colliderItems);
func_800D1694(this->actor.posRot.pos.x, this->actor.posRot.pos.y + (this->actor.shape.unk_08 * this->actor.scale.y),
this->actor.posRot.pos.z, &this->actor.shape.rot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
func_800628A4(0, &this->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B971D8.s")
void ObjLightswitch_SetSwitchFlag(ObjLightswitch* this, GlobalContext* globalCtx) {
Actor* thisx = &this->actor; // required
s32 type;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B972B8.s")
if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) {
type = this->actor.params >> 4 & 3;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B972D8.s")
Flags_SetSwitch(globalCtx, this->actor.params >> 8 & 0x3F);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B973C8.s")
if (type == OBJLIGHTSWITCH_TYPE_1) {
func_800806BC(globalCtx, thisx, 0x4807);
} else if (type == OBJLIGHTSWITCH_TYPE_BURN) {
func_800806BC(globalCtx, thisx, 0x4806);
} else {
func_800806BC(globalCtx, thisx, 0x4802);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97400.s")
void ObjLightswitch_ClearSwitchFlag(ObjLightswitch* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) {
Flags_UnsetSwitch(globalCtx, this->actor.params >> 8 & 0x3F);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97518.s")
if ((this->actor.params >> 4 & 3) == OBJLIGHTSWITCH_TYPE_1) {
func_800806BC(globalCtx, &this->actor, 0x4807);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97540.s")
void ObjLightswitch_SpawnDisappearEffects(ObjLightswitch* this, GlobalContext* globalCtx) {
Vec3f pos;
f32 s = Math_Sins(this->actor.shape.rot.y);
f32 c = Math_Coss(this->actor.shape.rot.y);
f32 x;
f32 y;
f32 z;
s32 pad;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97630.s")
if (this->alpha >= (100 << 6)) {
x = (CLAMP_MAX((1.0f - 1.0f / (255 << 6) * this->alpha) * 400.0f, 60.0f) - 30.0f + 30.0f) * Math_Rand_ZeroOne();
y = x - 30.0f;
if (x > 30.0f) {
x = 30.0f;
} else {
x = 900.0f - (y * y);
if (x < 100.0f) {
x = 100.0f;
}
x = sqrtf(x);
}
x = 2.0f * (x * (Math_Rand_ZeroOne() - 0.5f));
z = (30.0f - fabsf(x)) * 0.5f + 10.0f * Math_Rand_ZeroOne();
pos.x = this->actor.posRot.pos.x + ((z * s) + (x * c));
pos.y = this->actor.posRot.pos.y + y + 10.0f;
pos.z = this->actor.posRot.pos.z + ((z * c) - (x * s));
func_8002A6B8(globalCtx, &pos, &D_80B97F74, &D_80B97F74, 0x64, 0, 0xFF, 0xFF, 0xA0, 0xA0, 0xFF, 0, 0, 1, 9, 1);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97648.s")
void ObjLightswitch_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
s32 switchFlagSet = Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F);
s32 removeSelf = false;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97690.s")
Actor_ProcessInitChain(&this->actor, sInitChain);
Actor_SetHeight(&this->actor, 0.0f);
if (switchFlagSet) {
if ((this->actor.params >> 4 & 3) == OBJLIGHTSWITCH_TYPE_BURN) {
removeSelf = true;
} else {
ObjLightswitch_SetupOn(this);
}
} else {
ObjLightswitch_SetupOff(this);
}
if ((this->actor.params & 1) == 1) {
if (switchFlagSet) {
Math_Vec3f_Copy(&this->actor.posRot.pos, &D_80B97F68);
Math_Vec3f_Copy(&this->actor.initPosRot.pos, &D_80B97F68);
}
this->actor.shape.rot.x = -0x4000;
this->actor.shape.rot.z = 0;
this->actor.posRot.rot.x = this->actor.initPosRot.rot.x = this->actor.shape.rot.x;
this->actor.posRot.rot.z = this->actor.initPosRot.rot.z = this->actor.shape.rot.z;
this->actor.flags |= 0x20;
if (!Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_OBJ_OSHIHIKI,
this->actor.initPosRot.pos.x, this->actor.initPosRot.pos.y,
this->actor.initPosRot.pos.z, 0, this->actor.initPosRot.rot.y, 0, 0xFF00)) {
osSyncPrintf(VT_COL(RED, WHITE));
osSyncPrintf("押引ブロック発生失敗(%s %d)(arg_data 0x%04x)\n", "../z_obj_lightswitch.c", 452,
this->actor.params);
osSyncPrintf(VT_RST);
removeSelf = true;
}
}
ObjLightswitch_InitCollider(this, globalCtx);
func_80061ED4(&this->actor.colChkInfo, NULL, &sCollisionCheckInfoInit);
if (removeSelf) {
Actor_Kill(&this->actor);
}
osSyncPrintf("(光スイッチ)(arg_data 0x%04x)\n", this->actor.params);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B976A8.s")
void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx) {
Collider_DestroyJntSph(globalCtx, &THIS->collider);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/ObjLightswitch_Update.s")
void ObjLightswitch_SetupOff(ObjLightswitch* this) {
this->actionFunc = ObjLightswitch_Off;
this->faceTextureIndex = FACE_EYES_CLOSED;
this->color[0] = 155 << 6;
this->color[1] = 125 << 6;
this->color[2] = 255 << 6;
this->alpha = 255 << 6;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B977D0.s")
void ObjLightswitch_Off(ObjLightswitch* this, GlobalContext* globalCtx) {
switch (this->actor.params >> 4 & 3) {
case OBJLIGHTSWITCH_TYPE_STAY_ON:
case OBJLIGHTSWITCH_TYPE_2:
if (this->collider.base.acFlags & 2) {
ObjLightswitch_SetupTurnOn(this);
ObjLightswitch_SetSwitchFlag(this, globalCtx);
}
break;
case OBJLIGHTSWITCH_TYPE_1:
if ((this->collider.base.acFlags & 2) && !(this->prevFrameACflags & 2)) {
ObjLightswitch_SetupTurnOn(this);
ObjLightswitch_SetSwitchFlag(this, globalCtx);
}
break;
case OBJLIGHTSWITCH_TYPE_BURN:
if (this->collider.base.acFlags & 2) {
ObjLightswitch_SetupDisappearDelay(this);
ObjLightswitch_SetSwitchFlag(this, globalCtx);
}
break;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/func_80B97B50.s")
void ObjLightswitch_SetupTurnOn(ObjLightswitch* this) {
this->actionFunc = ObjLightswitch_TurnOn;
this->toggleDelay = 100;
this->timer = 0;
this->faceTextureIndex = FACE_EYES_CLOSED;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Lightswitch/ObjLightswitch_Draw.s")
void ObjLightswitch_TurnOn(ObjLightswitch* this, GlobalContext* globalCtx) {
if (func_8005B198() == this->actor.type || this->toggleDelay <= 0) {
if (this->timer == 0) {
Audio_PlayActorSound2(&this->actor, NA_SE_EV_TRIFORCE_FLASH);
}
this->timer++;
Math_ApproxS(&this->flameRingRotSpeed, -0xAA, 0xA);
this->flameRingRot += this->flameRingRotSpeed;
this->color[0] = this->timer * (((255 - 155) << 6) / 20) + (155 << 6);
this->color[1] = this->timer * (((255 - 125) << 6) / 20) + (125 << 6);
if (this->timer >= 20) {
ObjLightswitch_SetupOn(this);
} else if (this->timer == 15) {
this->faceTextureIndex = FACE_EYES_OPEN;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FOOT_SWITCH);
}
}
}
void ObjLightswitch_SetupOn(ObjLightswitch* this) {
this->actionFunc = ObjLightswitch_On;
this->faceTextureIndex = FACE_EYES_OPEN_SMILING;
this->color[0] = 255 << 6;
this->color[1] = 255 << 6;
this->color[2] = 255 << 6;
this->alpha = 255 << 6;
this->flameRingRotSpeed = -0xAA;
this->timer = 0;
}
void ObjLightswitch_On(ObjLightswitch* this, GlobalContext* globalCtx) {
switch (this->actor.params >> 4 & 3) {
case OBJLIGHTSWITCH_TYPE_STAY_ON:
if (!Flags_GetSwitch(globalCtx, this->actor.params >> 8 & 0x3F)) {
ObjLightswitch_SetupTurnOff(this);
}
break;
case OBJLIGHTSWITCH_TYPE_1:
if (this->collider.base.acFlags & 2 && !(this->prevFrameACflags & 2)) {
ObjLightswitch_SetupTurnOff(this);
ObjLightswitch_ClearSwitchFlag(this, globalCtx);
}
break;
case OBJLIGHTSWITCH_TYPE_2:
if (!(this->collider.base.acFlags & 2)) {
if (this->timer >= 7) {
ObjLightswitch_SetupTurnOff(this);
ObjLightswitch_ClearSwitchFlag(this, globalCtx);
} else {
this->timer++;
}
} else {
this->timer = 0;
}
break;
}
this->flameRingRot += this->flameRingRotSpeed;
}
void ObjLightswitch_SetupTurnOff(ObjLightswitch* this) {
this->actionFunc = ObjLightswitch_TurnOff;
this->toggleDelay = 100;
this->timer = 20;
this->faceTextureIndex = FACE_EYES_OPEN;
}
void ObjLightswitch_TurnOff(ObjLightswitch* this, GlobalContext* globalCtx) {
if ((this->actor.params >> 4 & 3) != OBJLIGHTSWITCH_TYPE_1 || func_8005B198() == this->actor.type ||
this->toggleDelay <= 0) {
this->timer--;
Math_ApproxS(&this->flameRingRotSpeed, 0, 0xA);
this->flameRingRot += this->flameRingRotSpeed;
this->color[0] = this->timer * (((255 - 155) << 6) / 20) + (155 << 6);
this->color[1] = this->timer * (((255 - 125) << 6) / 20) + (125 << 6);
if (this->timer <= 0) {
ObjLightswitch_SetupOff(this);
} else if (this->timer == 15) {
this->faceTextureIndex = FACE_EYES_CLOSED;
Audio_PlayActorSound2(&this->actor, NA_SE_EV_FOOT_SWITCH);
}
}
}
void ObjLightswitch_SetupDisappearDelay(ObjLightswitch* this) {
this->actionFunc = ObjLightswitch_DisappearDelay;
this->toggleDelay = 100;
}
void ObjLightswitch_DisappearDelay(ObjLightswitch* this, GlobalContext* globalCtx) {
if (func_8005B198() == this->actor.type || this->toggleDelay <= 0) {
ObjLightswitch_SetupDisappear(this);
}
}
void ObjLightswitch_SetupDisappear(ObjLightswitch* this) {
this->actionFunc = ObjLightswitch_Disappear;
this->alpha = 255 << 6;
}
void ObjLightswitch_Disappear(ObjLightswitch* this, GlobalContext* globalCtx) {
this->alpha -= 200;
ObjLightswitch_SpawnDisappearEffects(this, globalCtx);
if (this->alpha < 0) {
Actor_Kill(&this->actor);
}
}
void ObjLightswitch_Update(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
GlobalContext* globalCtx2 = globalCtx;
if (this->toggleDelay > 0) {
this->toggleDelay--;
}
this->actionFunc(this, globalCtx2);
if (this->actor.update != NULL) {
if ((this->actor.params & 1) == 1) {
this->actor.posRot.pos.x = this->actor.child->posRot.pos.x;
this->actor.posRot.pos.y = this->actor.child->posRot.pos.y + 60.0f;
this->actor.posRot.pos.z = this->actor.child->posRot.pos.z;
Actor_SetHeight(&this->actor, 0.0f);
}
this->prevFrameACflags = this->collider.base.acFlags;
this->collider.base.acFlags &= ~2;
CollisionCheck_SetOC(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
CollisionCheck_SetAC(globalCtx2, &globalCtx2->colChkCtx, &this->collider.base);
}
}
void ObjLightswitch_DrawOpa(ObjLightswitch* this, GlobalContext* globalCtx) {
Actor* child;
Vec3f pos;
Vec3s rot;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 809);
func_80093D18(globalCtx->state.gfxCtx);
gDPSetEnvColor(oGfxCtx->polyOpa.p++, (u8)(this->color[0] >> 6), (u8)(this->color[1] >> 6),
(u8)(this->color[2] >> 6), (u8)(this->alpha >> 6));
gSPSegment(oGfxCtx->polyOpa.p++, 0x09, &D_80116280[2]);
if ((this->actor.params & 1) == 1) {
child = this->actor.child;
this->actor.posRot.pos.x = child->posRot.pos.x;
this->actor.posRot.pos.y = child->posRot.pos.y + 60.0f;
this->actor.posRot.pos.z = child->posRot.pos.z;
Math_Vec3f_Copy(&pos, &this->actor.posRot.pos);
func_800D1694(pos.x, pos.y, pos.z, &this->actor.shape.rot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
} else {
pos.x = this->actor.posRot.pos.x;
pos.y = this->actor.posRot.pos.y + this->actor.shape.unk_08 * this->actor.scale.y;
pos.z = this->actor.posRot.pos.z;
}
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 841),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(oGfxCtx->polyOpa.p++, 0x08, SEGMENTED_TO_VIRTUAL(faceTextures[this->faceTextureIndex]));
gSPDisplayList(oGfxCtx->polyOpa.p++, D_06000260);
rot.x = this->actor.shape.rot.x;
rot.y = this->actor.shape.rot.y;
rot.z = this->actor.shape.rot.z + this->flameRingRot;
func_800D1694(pos.x, pos.y, pos.z, &rot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 859),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyOpa.p++, D_06000398);
rot.z = this->actor.shape.rot.z - this->flameRingRot;
func_800D1694(pos.x, pos.y, pos.z, &rot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 873),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyOpa.p++, D_06000408);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 878);
}
void ObjLightswitch_DrawXlu(ObjLightswitch* this, GlobalContext* globalCtx) {
s32 pad;
Vec3f sp68;
Vec3s sp60;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 890);
func_80093D84(globalCtx->state.gfxCtx);
gDPSetEnvColor(oGfxCtx->polyXlu.p++, (u8)(this->color[0] >> 6), (u8)(this->color[1] >> 6),
(u8)(this->color[2] >> 6), (u8)(this->alpha >> 6));
gSPSegment(oGfxCtx->polyXlu.p++, 0x09, D_80116280);
sp68.x = this->actor.posRot.pos.x;
sp68.y = this->actor.posRot.pos.y + (this->actor.shape.unk_08 * this->actor.scale.y);
sp68.z = this->actor.posRot.pos.z;
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 912),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(oGfxCtx->polyXlu.p++, 0x08, SEGMENTED_TO_VIRTUAL(faceTextures[this->faceTextureIndex]));
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06000260);
sp60.x = this->actor.shape.rot.x;
sp60.y = this->actor.shape.rot.y;
sp60.z = this->actor.shape.rot.z + this->flameRingRot;
func_800D1694(sp68.x, sp68.y, sp68.z, &sp60);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 930),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06000398);
sp60.z = this->actor.shape.rot.z - this->flameRingRot;
func_800D1694(sp68.x, sp68.y, sp68.z, &sp60);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY);
gSPMatrix(oGfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 944),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(oGfxCtx->polyXlu.p++, D_06000408);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_obj_lightswitch.c", 949);
}
void ObjLightswitch_Draw(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
s32 alpha = this->alpha >> 6 & 0xFF;
if ((this->actor.params & 1) == 1) {
func_800628A4(0, &this->collider);
}
if ((this->actor.params >> 4 & 3) == OBJLIGHTSWITCH_TYPE_BURN && (alpha > 0 || alpha < 255)) {
ObjLightswitch_DrawXlu(this, globalCtx);
} else {
ObjLightswitch_DrawOpa(this, globalCtx);
}
}

View file

@ -6,9 +6,28 @@
struct ObjLightswitch;
typedef void (*ObjLightswitchActionFunc)(struct ObjLightswitch*, GlobalContext*);
typedef enum {
/* 0 */ OBJLIGHTSWITCH_TYPE_STAY_ON, // doesn't turn off unless the switch flag is cleared some other way
/* 1 */ OBJLIGHTSWITCH_TYPE_1, // turns on and off
/* 2 */ OBJLIGHTSWITCH_TYPE_2, // turns on and off
/* 3 */ OBJLIGHTSWITCH_TYPE_BURN // disappears when turned on
} ObjLightswitch_Type;
typedef struct ObjLightswitch {
/* 0x0000 */ Actor actor;
/* 0x014C */ char unk_14C[0x78];
/* 0x014C */ ObjLightswitchActionFunc actionFunc;
/* 0x0150 */ ColliderJntSph collider;
/* 0x0170 */ ColliderJntSphItem colliderItems[1];
/* 0x01B0 */ s16 timer; // collision-related threshold and controls animation/logic when turning on/off
/* 0x01B2 */ s16 toggleDelay; // timer ticking down used for delaying tuning on/off or disappearing, can be bypassed
/* 0x01B4 */ s16 faceTextureIndex; // texture used by the center part of the sun
/* 0x01B6 */ s16 color[3]; // rgb, (0-255 color component) << 6
/* 0x01BC */ s16 alpha; // (0-255 alpha) << 6
/* 0x01BE */ s16 flameRingRot;
/* 0x01C0 */ s16 flameRingRotSpeed;
/* 0x01C2 */ u8 prevFrameACflags;
} ObjLightswitch; // size = 0x01C4
extern const ActorInit Obj_Lightswitch_InitVars;