Obj_Lightswitch (Sunswitch and Stonetower Temple flip switch) (#107)

* ObjLightswitch: fast

* ObjLightswitch: data migrated, except collider init is broke

* ObjLightswitch: nvm, collider documented

* ObjLightswitch: OK with 3 non-equiv, docs starting

* ObjLightswitch: more docs

* ObjLightswitch: some requested changes

* ObjLightswitch: requested changes

Co-authored-by: isghj8 <isghj8@gmail.com>
This commit is contained in:
Isghj 2021-05-09 19:18:57 -07:00 committed by GitHub
parent 874a75f456
commit d98e9dfb01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 531 additions and 48 deletions

View File

@ -668,7 +668,8 @@ void EffectSsKakera_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity,
// void EffectSsEnFire_SpawnVec3f(UNK_TYPE4 uParm1, Actor* pzParm2, Vec3f* pzParm3, UNK_TYPE2 uParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7);
// void EffectSsEnFire_SpawnVec3s(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7);
// void EffectSsExtra_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6);
// void EffectSsDeadDb_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE1* param_5, UNK_TYPE1* param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE4 param_9);
void EffectSsDeadDb_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim, Color_RGBA8* env,
s16 scale, s16 scaleStep, s32 unk);
// void func_800B3030(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE4 param_7);
// void EffectSsDeadDd_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE1* param_5, UNK_TYPE1* param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE4 param_10);
// void EffectSsDeadDs_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE4 param_8);
@ -826,7 +827,7 @@ void func_800B8C50(Actor* actor, GlobalContext* globalCtx);
// void func_800B8E1C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5);
// void func_800B8E58(void);
// void func_800B8FC0(void);
void func_800B9010(Actor* actor, UNK_TYPE2 uParm2);
void func_800B9010(Actor* actor, s16 sfxId);
// void func_800B9038(void);
// void func_800B9084(void);
void func_800B9098(Actor* actor);

View File

@ -2506,7 +2506,7 @@ SECTIONS
ovl_Obj_Lightswitch : AT(RomLocation)
{
build/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.o(.text)
build/asm/overlays/ovl_Obj_Lightswitch_data.o(.data)
build/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.o(.data)
build/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.o(.rodata)
build/asm/overlays/ovl_Obj_Lightswitch_rodata.o(.rodata)
}

View File

@ -130,6 +130,11 @@ D_06007750 = 0x06007750;
D_0600A390 = 0x0600A390;
D_0600A490 = 0x0600A490;
/* obj_lightswitch */
D_06000C20 = 0x6000C20;
D_06000420 = 0x6000420;
D_06001420 = 0x6001420;
/* z_obj_kepn_koya */
D_0600805C = 0x0600805C;
D_06003478 = 0x06003478;
@ -200,4 +205,4 @@ D_06000710 = 0x06000710;
D_06000958 = 0x06000958;
/* z_en_jc_mato */
D_06000390 = 0x06000390;
D_06000390 = 0x06000390;

View File

@ -8,8 +8,18 @@ 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_PlayCinema(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightSwitch_SetupEnabled(ObjLightswitch* this);
void ObjLightSwitch_Enabled(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_SetupIdle(ObjLightswitch* this);
void ObjLightSwitch_SetupFade(ObjLightswitch* this);
void ObjLightSwitch_Fade(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightSwitch_SetupAsleep(ObjLightswitch* this);
void ObjLightSwitch_Asleep(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightSwitch_SetupDisabled(ObjLightswitch* this);
void ObjLightSwitch_Disabled(ObjLightswitch* this, GlobalContext* globalCtx);
void ObjLightswitch_Idle(ObjLightswitch* this, GlobalContext* globalCtx);
/*
const ActorInit Obj_Lightswitch_InitVars = {
ACTOR_OBJ_LIGHTSWITCH,
ACTORCAT_SWITCH,
@ -21,46 +31,471 @@ const ActorInit Obj_Lightswitch_InitVars = {
(ActorFunc)ObjLightswitch_Update,
(ActorFunc)ObjLightswitch_Draw
};
*/
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_8095FBF0.asm")
static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00202000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, },
{ 0, { { 0, 0, 0 }, 19 }, 100 },
},
};
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_8095FC94.asm")
static ColliderJntSphInit sJntSphInit = {
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, },
1, sJntSphElementsInit,
};
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_8095FCEC.asm")
// different face addresses for (sleep -> waking -> awake) of light switch face
Gfx* lightswitchFaceGfx[] = {D_06000C20, D_06000420, D_06001420,};
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightswitch_Init.asm")
Color_RGBA8 lightswitchEffectPrimColor = { 0xFF, 0xFF, 0xA0, 0xA0, };
Color_RGBA8 lightswitchEffectEnvColor = { 0xFF, 0x0, 0x0, 0x0, };
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightswitch_Destroy.asm")
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP),
};
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_8095FFF8.asm")
void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) {
s32 pad;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960014.asm")
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, &this->elements);
this->actor.colChkInfo.mass = 0xFF;
SysMatrix_SetStateRotationAndTranslation(this->actor.world.pos.x,
this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y),
this->actor.world.pos.z, &this->actor.shape);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1);
Collider_UpdateSpheres(0, &this->collider);
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960088.asm")
void ObjLightswitch_UpdateSwitchFlags(ObjLightswitch* this, GlobalContext* globalCtx, s32 set) {
if (this){}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_809600BC.asm")
if (set) {
Actor_SetSwitchFlag(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this));
} else {
Actor_UnsetSwitchFlag(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this));
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_8096012C.asm")
#if NON_EQUIVELENT
// issues: a lot of ordering issues leading up to the big effect spawn function call
// there are a lot of temps, some might have been removed that were required by accident
// however, constantly on the edge of stack oversize, so something has to go
void ObjLightswitch_SpawnEffects(ObjLightswitch* this, GlobalContext* globalCtx) {
Vec3f effectPos;
f32 sinResult;
f32 cosResult;
f32 tempResult;
f32 tempResult2; // must exist because of condition assignemt?
f32 tempResult_shorter; // tempResult - 30
f32 randomOutput;
f32 tempResult5;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960148.asm")
sinResult = Math_SinS(this->actor.shape.rot.y);
cosResult = Math_CosS(this->actor.shape.rot.y);
if (this->colorAlpha >= 0x1900) {
// late rodata: 6.127451e-05f = 1 / 16320 ?
tempResult = (1.0f - ( this->colorAlpha * 6.127451e-05f)) * 400.0f;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960224.asm")
if (tempResult > 60.0f) {
tempResult2 = 60.0f;
} else {
tempResult2 = tempResult;
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960260.asm")
tempResult = Rand_ZeroOne() * ((tempResult2 - 30.0f) + 30.0f);
tempResult_shorter = tempResult - 30.0f;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_8096034C.asm")
if (tempResult > 30.0f) {
tempResult = 30.0f;
} else {
tempResult = 900.0f - SQ(tempResult_shorter);
if (tempResult < 100.0f) {
tempResult = 100.0f;
}
tempResult = sqrtf(tempResult);
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960370.asm")
tempResult5 = 2.0f * ((Rand_ZeroOne() - 0.5f) * tempResult);
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960424.asm")
// permuter seems to think something could be added to fix ordering here, but doesn't fix enough
//goto dummy_label_809848; dummy_label_809848: ; // minor regalloc fix
//if (cosResult){} // minor regalloc fix, but breaks some code
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960440.asm")
// saving fabsf result as a temp might help, but need to reduce temps
//fabsResult = fabsf(tempResult5);
//randomOutput = (Rand_ZeroOne() * 10.0f) + ((30.0f - fabsResult) * 0.5f);
//randomOutput = fabsf(tempResult5);
//randomOutput = (Rand_ZeroOne() * 10.0f) + ((30.0f - randomOutput) * 0.5f);
randomOutput = (Rand_ZeroOne() * 10.0f) + ((30.0f - fabsf(tempResult5)) * 0.5f);
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightswitch_Update.asm")
effectPos.x = this->actor.world.pos.x + ((randomOutput * sinResult) + (tempResult5 * cosResult));
effectPos.y = this->actor.world.pos.y + tempResult_shorter + 10.0f;
effectPos.z = this->actor.world.pos.z + ((randomOutput * cosResult) - (tempResult5 * sinResult));
// weirdly, using a temp here make a big difference, but.. is that right? just one temp? prob ordering issue above
//tempResult = this->actor.world.pos.z + ((randomOutput * cosResult) - (tempResult5 * sinResult));
//effectPos.z = tempResult;
EffectSsDeadDb_Spawn(globalCtx, &effectPos, &D_801D15B0, &D_801D15B0,
&lightswitchEffectPrimColor, &lightswitchEffectEnvColor,
100, 0, 9);
}
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightswitch_SpawnEffects.asm")
#endif
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_809605F4.asm")
void ObjLightswitch_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
s32 pad;
u32 switchFlagResult;
s32 isTriggered;
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/func_80960880.asm")
switchFlagResult = Actor_GetSwitchFlag(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this));
isTriggered = 0;
Actor_ProcessInitChain(&this->actor, &sInitChain);
Actor_SetHeight(&this->actor, 0.0f);
if (switchFlagResult != 0) {
if (GET_LIGHTSWITCH_TYPE(this) == LIGHTSWITCH_TYPE_FAKE) {
isTriggered = 1;
} else {
ObjLightSwitch_SetupEnabled(this);
}
} else {
ObjLightswitch_SetupIdle(this);
}
ObjLightswitch_InitCollider(this, globalCtx);
if (GET_LIGHTSWITCH_INVISIBLE(this)) {
// the stone tower exterior switch is part of the scene mesh, the actor is invisble on top
this->actor.draw = NULL;
}
if (isTriggered) {
Actor_MarkForDeath(&this->actor);
}
}
void ObjLightswitch_Destroy(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
Collider_DestroyJntSph(globalCtx, &this->collider);
}
void ObjLightswitch_SetAction(ObjLightswitch* this, ObjLightswitchSetupFunc setupFunc, u32 setState) {
this->setupFunc = setupFunc;
this->switchFlagSetType = setState;
this->actionFunc = ObjLightswitch_PlayCinema;
}
void ObjLightswitch_PlayCinema(ObjLightswitch* this, GlobalContext* globalCtx) {
if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) {
ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor);
ObjLightswitch_UpdateSwitchFlags(this, globalCtx, this->switchFlagSetType);
this->cutsceneTimer = 50;
this->setupFunc(this);
} else {
ActorCutscene_SetIntentToPlay(this->actor.cutscene);
}
}
void ObjLightswitch_SetupIdle(ObjLightswitch* this) {
this->faceState = LIGHTSWITCH_FACE_ASLEEP;
this->colorR = 0x26C0;
this->colorG = 0x1F40;
this->colorB = 0x3FC0;
this->colorAlpha = 0x3FC0;
this->actionFunc = ObjLightswitch_Idle;
}
void ObjLightswitch_Idle(ObjLightswitch* this, GlobalContext* globalCtx) {
s32 actorType = GET_LIGHTSWITCH_TYPE(this);
if (this->hitState >= 10) {
if (actorType == LIGHTSWITCH_TYPE_FAKE) {
ObjLightswitch_SetAction(this, ObjLightSwitch_SetupFade, 1);
} else {
if (actorType == LIGHTSWITCH_TYPE_FLIP) {
this->hitState = 0;
}
ObjLightswitch_SetAction(this, ObjLightSwitch_SetupAsleep, 1);
}
}
}
void ObjLightSwitch_SetupAsleep(ObjLightswitch* this) {
this->faceState = LIGHTSWITCH_FACE_ASLEEP;
this->colorShiftTimer = 0;
this->actionFunc = ObjLightSwitch_Asleep;
}
void ObjLightSwitch_Asleep(ObjLightswitch* this, GlobalContext* globalCtx) {
if (this->colorShiftTimer == 0) {
Audio_PlayActorSound2(&this->actor, 0x286F); // sfx NA_SE_EV_SUN_MARK_FLASH
}
this->colorShiftTimer++;
Math_StepToS(&this->edgeRotSpeed, -0xAA, 0xA);
this->edgeRot += this->edgeRotSpeed;
this->colorR = (this->colorShiftTimer * 0x140) + 0x26C0;
this->colorG = (this->colorShiftTimer * 0x1A0) + 0x1F40;
if (this->colorShiftTimer >= 20) {
ObjLightSwitch_SetupEnabled(this);
} else if (this->colorShiftTimer == 15) {
this->faceState = LIGHTSWITCH_FACE_WAKING;
Audio_PlayActorSound2(this, 0x2815); // sfx NA_SE_EV_FOOT_SWITCH
}
}
void ObjLightSwitch_SetupEnabled(ObjLightswitch* this) {
this->faceState = LIGHTSWITCH_FACE_FULLAWAKE;
this->colorR = 0x3FC0;
this->colorG = 0x3FC0;
this->colorB = 0x3FC0;
this->colorAlpha = 0x3FC0;
this->edgeRotSpeed = -0xAA;
this->colorShiftTimer = 0;
this->actionFunc = ObjLightSwitch_Enabled;
}
void ObjLightSwitch_Enabled(ObjLightswitch* this, GlobalContext* globalCtx) {
s32 actorType = GET_LIGHTSWITCH_TYPE(this);
if (actorType == LIGHTSWITCH_TYPE_REGULAR) {
// switch can be disabled outside of this actor by flag
if (Actor_GetSwitchFlag(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this)) == 0) {
ObjLightSwitch_SetupDisabled(this);
}
} else if (actorType == LIGHTSWITCH_TYPE_FLIP) {
if (this->hitState >= 10) {
this->hitState = 0;
ObjLightswitch_SetAction(this, ObjLightSwitch_SetupDisabled, 0);
}
} else if (this->hitState == 0) {
if (this->colorShiftTimer >= 13) {
ObjLightswitch_UpdateSwitchFlags(this, globalCtx, 0);
ObjLightSwitch_SetupDisabled(this);
} else {
this->colorShiftTimer += 1;
}
} else {
this->colorShiftTimer = 0;
}
this->edgeRot += this->edgeRotSpeed;
}
void ObjLightSwitch_SetupDisabled(ObjLightswitch* this) {
this->colorShiftTimer = 20;
this->faceState = LIGHTSWITCH_FACE_WAKING;
this->actionFunc = ObjLightSwitch_Disabled;
}
void ObjLightSwitch_Disabled(ObjLightswitch* this, GlobalContext* globalCtx) {
this->colorShiftTimer--;
Math_StepToS(&this->edgeRotSpeed, 0, 0xA);
this->edgeRot += this->edgeRotSpeed;
this->colorR = (this->colorShiftTimer * 0x140) + 0x26C0;
this->colorG = (this->colorShiftTimer * 0x1A0) + 0x1F40;
if (this->colorShiftTimer <= 0) {
ObjLightswitch_SetupIdle(this);
} else if (this->colorShiftTimer == 15) {
this->faceState = LIGHTSWITCH_FACE_ASLEEP;
Audio_PlayActorSound2(&this->actor, 0x2815); // NA_SE_EV_FOOT_SWITCH
}
}
void ObjLightSwitch_SetupFade(ObjLightswitch* this) {
this->colorAlpha = 0x3FC0;
this->actionFunc = ObjLightSwitch_Fade;
}
void ObjLightSwitch_Fade(ObjLightswitch* this, GlobalContext* globalCtx) {
this->colorAlpha -= 0xC8;
ObjLightswitch_SpawnEffects(this, globalCtx); // spawn burning fire effect
if (this->colorAlpha < 0) {
Actor_MarkForDeath(&this->actor);
} else {
func_800B9010(&this->actor, 0x321F); // sfx NA_SE_EN_COMMON_EXTINCT_LEV "burn into ashes"
}
}
void ObjLightswitch_Update(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
s32 pad;
if ((this->collider.base.acFlags & AC_HIT) != 0) {
// dmgFlags enum doesn't exist yet, 0x2000 is light arrows
if ((this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x2000) != 0) {
this->hitState = 10;
} else if (GET_LIGHTSWITCH_TYPE(this) == LIGHTSWITCH_TYPE_FLIP) {
if (this->hitState == 0) {
if ((this->previousACFlags & AC_HIT) == 0) {
this->hitState = 1;
}
} else if (this->hitState < 10) {
this->hitState++;
}
} else {
if (this->hitState < 10) {
this->hitState++;
}
}
} else {
this->hitState = 0;
}
// why wouldn't this be in the action func?
if ((this->cutsceneTimer > 0) && ( (s32) this->actionFunc != (s32) ObjLightswitch_PlayCinema )) {
this->cutsceneTimer--;
if (this->cutsceneTimer == 0) {
ActorCutscene_Stop(this->actor.cutscene);
}
}
this->actionFunc(this, globalCtx);
if (this->actor.update != 0) {
this->previousACFlags = this->collider.base.acFlags;
CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider);
CollisionCheck_SetAC(globalCtx, &globalCtx->colCheckCtx, &this->collider);
}
}
#if NON_EQUIVELENT
// gDPSetEnvColor parameter load order is different than the order in which the value is built
// also massive regalloc probably caused by the above
void ObjLightSwitch_DrawOpa(ObjLightswitch* this, GlobalContext* globalCtx) {
Vec3f tempPos;
Vec3s tempRot;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_8012C28C(globalCtx->state.gfxCtx);
//temp_v0->words.w1 = ((((s32) this->colorB >> 6) & 0xFF) << 8)
//| (((s32) this->colorR >> 6) << 0x18)
//| ((((s32) this->colorG >> 6) & 0xFF) << 0x10)
//| (((s32) this->colorAlpha >> 6) & 0xFF);
// load order issues with loading this in the right order for the function
gDPSetEnvColor(POLY_OPA_DISP++,
this->colorR >> 6,
this->colorG >> 6,
this->colorB >> 6,
this->colorAlpha >> 6);
gSPSegment(POLY_OPA_DISP++, 0x09, D_801AEFA0);
tempPos.x = this->actor.world.pos.x;
tempPos.y = this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y);
tempPos.z = this->actor.world.pos.z;
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80960BC4[this->faceState]));
gSPDisplayList(POLY_OPA_DISP++, 0x6000260);
tempRot.x = this->actor.shape.rot.x;
tempRot.y = this->actor.shape.rot.y;
tempRot.z = this->actor.shape.rot.z + this->edgeRot;
SysMatrix_SetStateRotationAndTranslation(tempPos.z, tempPos.y, tempPos.x, &tempRot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, 0x6000398);
tempRot.z = this->actor.shape.rot.z - this->edgeRot;
SysMatrix_SetStateRotationAndTranslation(tempPos.z, tempPos.y, tempPos.x, &tempRot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, 0x6000408);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightSwitch_DrawOpa.asm")
#endif
#if NON_EQUIVELENT
// same issue as above
void ObjLightSwitch_DrawXlu(ObjLightswitch* this, GlobalContext* globalCtx) {
Vec3f tempPos;
Vec3s tempRot;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_8012C2DC(globalCtx->state.gfxCtx);
//temp_v0->words.w1 = ((((s32) this->colorB >> 6) & 0xFF) << 8)
//| (((s32) this->colorR >> 6) << 0x18)
//| ((((s32) this->colorG >> 6) & 0xFF) << 0x10)
//| (((s32) this->colorAlpha >> 6) & 0xFF);
gDPSetEnvColor(POLY_XLU_DISP++,
this->colorR >> 6,
this->colorG >> 6,
this->colorB >> 6,
this->colorAlpha >> 6);
gSPSegment(POLY_XLU_DISP++, 0x09, D_801AEF88);
tempPos.x = this->actor.world.pos.x;
tempPos.y = this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y);
tempPos.z = this->actor.world.pos.z;
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80960BC4[this->faceState]));
gSPDisplayList(POLY_XLU_DISP++, 0x6000260);
tempRot.x = this->actor.shape.rot.x;
tempRot.y = this->actor.shape.rot.y;
tempRot.z = this->actor.shape.rot.z + this->edgeRot;
SysMatrix_SetStateRotationAndTranslation(tempPos.x, tempPos.y, tempPos.z, &tempRot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, 0x6000398);
tempRot.z = this->actor.shape.rot.z - this->edgeRot;
SysMatrix_SetStateRotationAndTranslation(tempPos.x, tempPos.y, tempPos.z, &tempRot);
Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, 0x6000408);
CLOSE_DISPS(globalCtx->state.gfxCtx);
}
#else
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightSwitch_DrawXlu.asm")
#endif
void ObjLightswitch_Draw(Actor* thisx, GlobalContext* globalCtx) {
ObjLightswitch* this = THIS;
s32 alpha = (this->colorAlpha >> 6) & 0xFF;
if ((GET_LIGHTSWITCH_TYPE(this) == LIGHTSWITCH_TYPE_FAKE) && (alpha > 0) && (alpha < 0xFF)) {
ObjLightSwitch_DrawXlu(this, globalCtx);
} else {
ObjLightSwitch_DrawOpa(this, globalCtx);
}
}
#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_Obj_Lightswitch_0x8095FBF0/ObjLightswitch_Draw.asm")

View File

@ -3,13 +3,55 @@
#include <global.h>
typedef void (*ObjLightswitchActionFunc)(struct ObjLightswitch*, GlobalContext*);
typedef void (*ObjLightswitchSetupFunc)(struct ObjLightswitch*);
struct ObjLightswitch;
typedef struct ObjLightswitch {
/* 0x000 */ Actor actor;
/* 0x144 */ char unk_144[0x7C];
/* 0x144 */ ColliderJntSph collider;
/* 0x164 */ ColliderJntSphElement elements;
/* 0x1A4 */ ObjLightswitchActionFunc actionFunc;
/* 0x1A8 */ s16 colorR; // not RGBA8 as 4x s16 (not 4x s8)
/* 0x1AA */ s16 colorG;
/* 0x1AC */ s16 colorB;
/* 0x1AE */ s16 colorAlpha;
/* 0x1B0 */ s16 edgeRot;
/* 0x1B2 */ s16 edgeRotSpeed;
/* 0x1B4 */ s8 colorShiftTimer;
/* 0x1B5 */ s8 hitState;
/* 0x1B6 */ s8 faceState;
/* 0x1B7 */ u8 previousACFlags;
/* 0x1B8 */ ObjLightswitchSetupFunc setupFunc;
/* 0x1BC */ s8 switchFlagSetType; // 1 or 0 , for set or unset flags
/* 0x1BD */ s8 cutsceneTimer;
} ObjLightswitch; // size = 0x1C0
extern const ActorInit Obj_Lightswitch_InitVars;
extern Gfx D_06000C20[];
extern Gfx D_06000420[];
extern Gfx D_06001420[];
// opa func
extern s32 D_801AEFA0;
// xlu func
extern s32 D_801AEF88;
#define LIGHTSWITCH_FACE_ASLEEP 0
#define LIGHTSWITCH_FACE_WAKING 1
#define LIGHTSWITCH_FACE_FULLAWAKE 2
#define LIGHTSWITCH_TYPE_REGULAR 0
#define LIGHTSWITCH_TYPE_FLIP 1
#define LIGHTSWITCH_TYPE_UNK2 2
#define LIGHTSWITCH_TYPE_FAKE 3
#define GET_LIGHTSWITCH_TYPE(this) (((this)->actor.params >> 4) & 0x3)
#define GET_LIGHTSWITCH_INVISIBLE(this) (((this)->actor.params >> 3) & 1)
#define GET_LIGHTSWITCH_SWITCHFLAG(this) (((this)->actor.params >> 8) & 0x7F)
#endif // Z_OBJ_LIGHTSWITCH_H

View File

@ -7807,26 +7807,26 @@
0x8095FB38:("ObjHana_Destroy",),
0x8095FB48:("ObjHana_Update",),
0x8095FB58:("ObjHana_Draw",),
0x8095FBF0:("func_8095FBF0",),
0x8095FC94:("func_8095FC94",),
0x8095FCEC:("func_8095FCEC",),
0x8095FBF0:("ObjLightswitch_InitCollider",),
0x8095FC94:("ObjLightswitch_UpdateSwitchFlags",),
0x8095FCEC:("ObjLightswitch_SpawnEffects",),
0x8095FEEC:("ObjLightswitch_Init",),
0x8095FFCC:("ObjLightswitch_Destroy",),
0x8095FFF8:("func_8095FFF8",),
0x80960014:("func_80960014",),
0x80960088:("func_80960088",),
0x809600BC:("func_809600BC",),
0x8096012C:("func_8096012C",),
0x80960148:("func_80960148",),
0x80960224:("func_80960224",),
0x80960260:("func_80960260",),
0x8096034C:("func_8096034C",),
0x80960370:("func_80960370",),
0x80960424:("func_80960424",),
0x80960440:("func_80960440",),
0x8095FFF8:("ObjLightswitch_SetAction",),
0x80960014:("ObjLightswitch_PlayCinema",),
0x80960088:("ObjLightswitch_SetupIdle",),
0x809600BC:("ObjLightswitch_Idle",),
0x8096012C:("ObjLightSwitch_SetupAsleep",),
0x80960148:("ObjLightSwitch_Asleep",),
0x80960224:("ObjLightSwitch_SetupEnabled",),
0x80960260:("ObjLightSwitch_Enabled",),
0x8096034C:("ObjLightSwitch_SetupDisabled",),
0x80960370:("ObjLightSwitch_Disabled",),
0x80960424:("ObjLightSwitch_SetupFade",),
0x80960440:("ObjLightSwitch_Fade",),
0x80960494:("ObjLightswitch_Update",),
0x809605F4:("func_809605F4",),
0x80960880:("func_80960880",),
0x809605F4:("ObjLightSwitch_DrawOpa",),
0x80960880:("ObjLightSwitch_DrawXlu",),
0x80960B0C:("ObjLightswitch_Draw",),
0x80960CF0:("func_80960CF0",),
0x80960E0C:("func_80960E0C",),

View File

@ -9481,9 +9481,9 @@
0x80960B70:("Obj_Lightswitch_InitVars","UNK_TYPE1","",0x1),
0x80960B90:("D_80960B90","UNK_TYPE1","",0x1),
0x80960BB4:("D_80960BB4","UNK_TYPE1","",0x1),
0x80960BC4:("D_80960BC4","UNK_TYPE1","",0x1),
0x80960BD0:("D_80960BD0","UNK_TYPE1","",0x1),
0x80960BD4:("D_80960BD4","UNK_TYPE1","",0x1),
0x80960BC4:("lightswitchFaceGfx","UNK_TYPE1","",0x1),
0x80960BD0:("lightswitchEffectPrimColor","UNK_TYPE1","",0x1),
0x80960BD4:("lightswitchEffectEnvColor","UNK_TYPE1","",0x1),
0x80960BD8:("D_80960BD8","UNK_TYPE1","",0x1),
0x80960BF0:("D_80960BF0","f32","",0x4),
0x80960C00:("objLightswitchOverlayInfo","OverlayRelocationSection","",0x14),