diff --git a/include/functions.h b/include/functions.h index 7a20d0bd19..243c6b97fd 100644 --- a/include/functions.h +++ b/include/functions.h @@ -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); diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index 472e324bfc..61d9681665 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -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) } diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index cda0993a76..eba42dfad4 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -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; \ No newline at end of file +D_06000390 = 0x06000390; diff --git a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 4a3b24381d..c2d02b02ab 100644 --- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -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") diff --git a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h index 5e13ada89b..a46710fd50 100644 --- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h +++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h @@ -3,13 +3,55 @@ #include +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 diff --git a/tables/functions.txt b/tables/functions.txt index 9995d09f96..1d9a1db45a 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -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",), diff --git a/tables/variables.txt b/tables/variables.txt index e3f2d352e5..d3cabc176c 100644 --- a/tables/variables.txt +++ b/tables/variables.txt @@ -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),