mirror of
https://github.com/zeldaret/mm.git
synced 2026-07-29 07:32:25 -04:00
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:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user