Fix bug with bowstring tranform tagging, transform tagging for effects, made d-pad buttons skip mask transformation cutscene
This commit is contained in:
parent
8c2a999697
commit
5b38b8eec9
|
@ -2,6 +2,7 @@
|
||||||
#include "transform_ids.h"
|
#include "transform_ids.h"
|
||||||
#include "overlays/actors/ovl_En_Test7/z_en_test7.h"
|
#include "overlays/actors/ovl_En_Test7/z_en_test7.h"
|
||||||
#include "overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h"
|
#include "overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h"
|
||||||
|
#include "z64effect.h"
|
||||||
|
|
||||||
// Decomp renames, TODO update decomp and remove these
|
// Decomp renames, TODO update decomp and remove these
|
||||||
#define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0
|
#define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0
|
||||||
|
@ -325,3 +326,142 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {
|
||||||
|
|
||||||
CLOSE_DISPS(play->state.gfxCtx);
|
CLOSE_DISPS(play->state.gfxCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SPARK_COUNT 3
|
||||||
|
#define BLURE_COUNT 25
|
||||||
|
#define SHIELD_PARTICLE_COUNT 3
|
||||||
|
#define TIRE_MARK_COUNT 15
|
||||||
|
|
||||||
|
#define TOTAL_EFFECT_COUNT SPARK_COUNT + BLURE_COUNT + SHIELD_PARTICLE_COUNT + TIRE_MARK_COUNT
|
||||||
|
|
||||||
|
typedef struct EffectStatus {
|
||||||
|
/* 0x0 */ u8 active;
|
||||||
|
/* 0x1 */ u8 unk1;
|
||||||
|
/* 0x2 */ u8 unk2;
|
||||||
|
} EffectStatus; // size = 0x3
|
||||||
|
|
||||||
|
typedef struct EffectContext {
|
||||||
|
/* 0x0000 */ struct PlayState* play;
|
||||||
|
struct {
|
||||||
|
EffectStatus status;
|
||||||
|
EffectSpark effect;
|
||||||
|
} /* 0x0004 */ sparks[SPARK_COUNT];
|
||||||
|
struct {
|
||||||
|
EffectStatus status;
|
||||||
|
EffectBlure effect;
|
||||||
|
} /* 0x0E5C */ blures[BLURE_COUNT];
|
||||||
|
struct {
|
||||||
|
EffectStatus status;
|
||||||
|
EffectShieldParticle effect;
|
||||||
|
} /* 0x388C */ shieldParticles[SHIELD_PARTICLE_COUNT];
|
||||||
|
struct {
|
||||||
|
EffectStatus status;
|
||||||
|
EffectTireMark effect;
|
||||||
|
} /* 0x3DF0 */ tireMarks[TIRE_MARK_COUNT];
|
||||||
|
} EffectContext; // size = 0x98E0
|
||||||
|
|
||||||
|
typedef struct EffectInfo {
|
||||||
|
/* 0x00 */ u32 size;
|
||||||
|
/* 0x04 */ void (*init)(void* effect, void* initParams);
|
||||||
|
/* 0x08 */ void (*destroy)(void* effect);
|
||||||
|
/* 0x0C */ s32 (*update)(void* effect);
|
||||||
|
/* 0x10 */ void (*draw)(void* effect, struct GraphicsContext* gfxCtx);
|
||||||
|
} EffectInfo; // size = 0x14
|
||||||
|
|
||||||
|
extern EffectContext sEffectContext;
|
||||||
|
extern EffectInfo sEffectInfoTable[];
|
||||||
|
|
||||||
|
static inline void tag_interpolate_effect(GraphicsContext* gfxCtx, u32 id) {
|
||||||
|
OPEN_DISPS(gfxCtx);
|
||||||
|
|
||||||
|
gEXMatrixGroupDecomposed(POLY_OPA_DISP++, id, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE,
|
||||||
|
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
|
||||||
|
gEXMatrixGroupDecomposed(POLY_XLU_DISP++, id + EFFECT_TRANSFORM_ID_COUNT, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE,
|
||||||
|
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
|
||||||
|
CLOSE_DISPS();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void tag_skip_effect(GraphicsContext* gfxCtx, u32 id) {
|
||||||
|
OPEN_DISPS(gfxCtx);
|
||||||
|
|
||||||
|
gEXMatrixGroupSimple(POLY_OPA_DISP++, id, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP,
|
||||||
|
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
|
||||||
|
gEXMatrixGroupSimple(POLY_XLU_DISP++, id + EFFECT_TRANSFORM_ID_COUNT, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP, G_EX_COMPONENT_SKIP,
|
||||||
|
G_EX_COMPONENT_SKIP, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
|
||||||
|
CLOSE_DISPS();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void pop_effect_tag(GraphicsContext* gfxCtx) {
|
||||||
|
OPEN_DISPS(gfxCtx);
|
||||||
|
|
||||||
|
gEXPopMatrixGroup(POLY_OPA_DISP++);
|
||||||
|
gEXPopMatrixGroup(POLY_XLU_DISP++);
|
||||||
|
|
||||||
|
CLOSE_DISPS();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @recomp Patched to tag effects.
|
||||||
|
void Effect_DrawAll(GraphicsContext* gfxCtx) {
|
||||||
|
s32 i;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < SPARK_COUNT; i++) {
|
||||||
|
if (!sEffectContext.sparks[i].status.active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// @recomp Tag transform.
|
||||||
|
tag_interpolate_effect(gfxCtx, EFFECT_SPARK_TRANSFORM_ID_START + i);
|
||||||
|
|
||||||
|
sEffectInfoTable[EFFECT_SPARK].draw(&sEffectContext.sparks[i].effect, gfxCtx);
|
||||||
|
|
||||||
|
// @recomp Pop tag.
|
||||||
|
pop_effect_tag(gfxCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < BLURE_COUNT; i++) {
|
||||||
|
if (!sEffectContext.blures[i].status.active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// @recomp Tag transform to skip interpolation as this effect doesn't work well with it.
|
||||||
|
tag_skip_effect(gfxCtx, EFFECT_BLURE_TRANSFORM_ID_START + i);
|
||||||
|
|
||||||
|
sEffectInfoTable[EFFECT_BLURE1].draw(&sEffectContext.blures[i].effect, gfxCtx);
|
||||||
|
|
||||||
|
// @recomp Pop tag.
|
||||||
|
pop_effect_tag(gfxCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) {
|
||||||
|
if (!sEffectContext.shieldParticles[i].status.active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// @recomp Tag transform.
|
||||||
|
tag_interpolate_effect(gfxCtx, EFFECT_SHIELD_PARTICLE_TRANSFORM_ID_START + i);
|
||||||
|
|
||||||
|
sEffectInfoTable[EFFECT_SHIELD_PARTICLE].draw(&sEffectContext.shieldParticles[i].effect, gfxCtx);
|
||||||
|
|
||||||
|
// @recomp Pop tag.
|
||||||
|
pop_effect_tag(gfxCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < TIRE_MARK_COUNT; i++) {
|
||||||
|
if (!sEffectContext.tireMarks[i].status.active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// @recomp Tag transform to skip interpolation as this effect doesn't work well with it.
|
||||||
|
tag_skip_effect(gfxCtx, EFFECT_TIRE_MARK_TRANSFORM_ID_START + i);
|
||||||
|
|
||||||
|
sEffectInfoTable[EFFECT_TIRE_MARK].draw(&sEffectContext.tireMarks[i].effect, gfxCtx);
|
||||||
|
|
||||||
|
// @recomp Pop tag.
|
||||||
|
pop_effect_tag(gfxCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
112
patches/input.c
112
patches/input.c
|
@ -282,6 +282,118 @@ ItemId Player_GetItemOnButton(PlayState* play, Player* player, EquipSlot slot) {
|
||||||
return C_BTN_ITEM(EQUIP_SLOT_C_RIGHT);
|
return C_BTN_ITEM(EQUIP_SLOT_C_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct struct_8085D910 {
|
||||||
|
/* 0x0 */ u8 unk_0;
|
||||||
|
/* 0x1 */ u8 unk_1;
|
||||||
|
/* 0x2 */ u8 unk_2;
|
||||||
|
/* 0x3 */ u8 unk_3;
|
||||||
|
} struct_8085D910; // size = 0x4
|
||||||
|
|
||||||
|
u16 D_8085D908[] = {
|
||||||
|
WEEKEVENTREG_30_80, // PLAYER_FORM_FIERCE_DEITY
|
||||||
|
WEEKEVENTREG_30_20, // PLAYER_FORM_GORON
|
||||||
|
WEEKEVENTREG_30_40, // PLAYER_FORM_ZORA
|
||||||
|
WEEKEVENTREG_30_10, // PLAYER_FORM_DEKU
|
||||||
|
};
|
||||||
|
struct_8085D910 D_8085D910[] = {
|
||||||
|
{ 0x10, 0xA, 0x3B, 0x3F },
|
||||||
|
{ 9, 0x32, 0xA, 0xD },
|
||||||
|
};
|
||||||
|
|
||||||
|
bool func_808323C0(Player *this, s16 csId);
|
||||||
|
void func_80855218(PlayState *play, Player *this, struct_8085D910 **arg2);
|
||||||
|
void func_808550D0(PlayState *play, Player *this, f32 arg2, f32 arg3, s32 arg4);
|
||||||
|
|
||||||
|
void Player_Action_86(Player *this, PlayState *play) {
|
||||||
|
struct_8085D910 *sp4C = D_8085D910;
|
||||||
|
s32 sp48 = false;
|
||||||
|
|
||||||
|
func_808323C0(this, play->playerCsIds[PLAYER_CS_ID_MASK_TRANSFORMATION]);
|
||||||
|
sPlayerControlInput = play->state.input;
|
||||||
|
|
||||||
|
Camera_ChangeMode(GET_ACTIVE_CAM(play),
|
||||||
|
(this->transformation == PLAYER_FORM_HUMAN) ? CAM_MODE_NORMAL : CAM_MODE_JUMP);
|
||||||
|
this->stateFlags2 |= PLAYER_STATE2_40;
|
||||||
|
this->actor.shape.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000;
|
||||||
|
|
||||||
|
func_80855218(play, this, &sp4C);
|
||||||
|
|
||||||
|
if (this->av1.actionVar1 == 0x14) {
|
||||||
|
Play_EnableMotionBlurPriority(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_PLAY_FILL_SCREEN_ON != 0) {
|
||||||
|
R_PLAY_FILL_SCREEN_ALPHA += R_PLAY_FILL_SCREEN_ON;
|
||||||
|
if (R_PLAY_FILL_SCREEN_ALPHA > 255) {
|
||||||
|
R_PLAY_FILL_SCREEN_ALPHA = 255;
|
||||||
|
this->actor.update = func_8012301C;
|
||||||
|
this->actor.draw = NULL;
|
||||||
|
this->av1.actionVar1 = 0;
|
||||||
|
Play_DisableMotionBlurPriority();
|
||||||
|
SET_WEEKEVENTREG(D_8085D908[GET_PLAYER_FORM]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((this->av1.actionVar1++ > ((this->transformation == PLAYER_FORM_HUMAN) ? 0x53 : 0x37)) ||
|
||||||
|
((this->av1.actionVar1 >= 5) &&
|
||||||
|
(sp48 =
|
||||||
|
((this->transformation != PLAYER_FORM_HUMAN) || CHECK_WEEKEVENTREG(D_8085D908[GET_PLAYER_FORM])) &&
|
||||||
|
// @recomp Patched to also check for d-pad buttons for skipping the transformation cutscene.
|
||||||
|
CHECK_BTN_ANY(sPlayerControlInput->press.button,
|
||||||
|
BTN_CRIGHT | BTN_CLEFT | BTN_CDOWN | BTN_CUP | BTN_B | BTN_A | BTN_DRIGHT | BTN_DLEFT | BTN_DDOWN | BTN_DUP)))) {
|
||||||
|
R_PLAY_FILL_SCREEN_ON = 45;
|
||||||
|
R_PLAY_FILL_SCREEN_R = 220;
|
||||||
|
R_PLAY_FILL_SCREEN_G = 220;
|
||||||
|
R_PLAY_FILL_SCREEN_B = 220;
|
||||||
|
R_PLAY_FILL_SCREEN_ALPHA = 0;
|
||||||
|
|
||||||
|
if (sp48) {
|
||||||
|
if (CutsceneManager_GetCurrentCsId() == this->csId) {
|
||||||
|
func_800E0348(Play_GetCamera(play, CutsceneManager_GetCurrentSubCamId(this->csId)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->transformation == PLAYER_FORM_HUMAN) {
|
||||||
|
AudioSfx_StopById(NA_SE_PL_TRANSFORM_VOICE);
|
||||||
|
AudioSfx_StopById(NA_SE_IT_TRANSFORM_MASK_BROKEN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AudioSfx_StopById(NA_SE_PL_FACE_CHANGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Player_PlaySfx(this, NA_SE_SY_TRANSFORM_MASK_FLASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->av1.actionVar1 >= sp4C->unk_0) {
|
||||||
|
if (this->av1.actionVar1 < sp4C->unk_2) {
|
||||||
|
Math_StepToF(&this->unk_B10[4], 1.0f, sp4C->unk_1 / 100.0f);
|
||||||
|
}
|
||||||
|
else if (this->av1.actionVar1 < sp4C->unk_3) {
|
||||||
|
if (this->av1.actionVar1 == sp4C->unk_2) {
|
||||||
|
Lib_PlaySfx_2(NA_SE_EV_LIGHTNING_HARD);
|
||||||
|
}
|
||||||
|
|
||||||
|
Math_StepToF(&this->unk_B10[4], 2.0f, 0.5f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Math_StepToF(&this->unk_B10[4], 3.0f, 0.2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->av1.actionVar1 >= 0x10) {
|
||||||
|
if (this->av1.actionVar1 < 0x40) {
|
||||||
|
Math_StepToF(&this->unk_B10[5], 1.0f, 0.2f);
|
||||||
|
}
|
||||||
|
else if (this->av1.actionVar1 < 0x37) {
|
||||||
|
Math_StepToF(&this->unk_B10[5], 2.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Math_StepToF(&this->unk_B10[5], 3.0f, 0.55f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func_808550D0(play, this, this->unk_B10[4], this->unk_B10[5], (this->transformation == PLAYER_FORM_HUMAN) ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
extern s16 sPictoState;
|
extern s16 sPictoState;
|
||||||
extern s16 sPictoPhotoBeingTaken;
|
extern s16 sPictoPhotoBeingTaken;
|
||||||
extern void* gWorkBuffer;
|
extern void* gWorkBuffer;
|
||||||
|
|
|
@ -157,27 +157,29 @@ void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList,
|
||||||
// @recomp Force the closest LOD
|
// @recomp Force the closest LOD
|
||||||
lod = 0;
|
lod = 0;
|
||||||
|
|
||||||
// @recomp Patch object_link_child_DL_017818 (the DL for the bowstring) with a transform tag.
|
// @recomp If the player is a human, patch object_link_child_DL_017818 (the DL for the bowstring) with a transform tag.
|
||||||
gSegments[0x0C] = OS_K0_TO_PHYSICAL(cullDList);
|
if (this->transformation == PLAYER_FORM_HUMAN) {
|
||||||
Gfx* dl_virtual_address = (Gfx*)Lib_SegmentedToVirtual(object_link_child_DL_017818);
|
gSegments[0x0C] = OS_K0_TO_PHYSICAL(cullDList);
|
||||||
|
Gfx* dl_virtual_address = (Gfx*)Lib_SegmentedToVirtual(object_link_child_DL_017818);
|
||||||
|
|
||||||
// Check if the commands have already been overwritten.
|
// Check if the commands have already been overwritten.
|
||||||
if ((dl_virtual_address[0].words.w0 >> 24) != G_DL) {
|
if ((dl_virtual_address[0].words.w0 >> 24) != G_DL) {
|
||||||
// Copy the first command before overwriting.
|
// Copy the first command before overwriting.
|
||||||
bowstring_start_hook_dl[0] = dl_virtual_address[0];
|
bowstring_start_hook_dl[0] = dl_virtual_address[0];
|
||||||
// Overwrite the first command with a branch.
|
// Overwrite the first command with a branch.
|
||||||
gSPBranchList(dl_virtual_address, OS_K0_TO_PHYSICAL(bowstring_start_hook_dl));
|
gSPBranchList(dl_virtual_address, OS_K0_TO_PHYSICAL(bowstring_start_hook_dl));
|
||||||
Gfx* enddl_command = dl_virtual_address;
|
Gfx* enddl_command = dl_virtual_address;
|
||||||
while ((enddl_command->words.w0 >> 24) != G_ENDDL) {
|
while ((enddl_command->words.w0 >> 24) != G_ENDDL) {
|
||||||
enddl_command++;
|
enddl_command++;
|
||||||
|
}
|
||||||
|
// Overwrite the last command with a branch.
|
||||||
|
gSPBranchList(enddl_command, bowstring_end_hook_dl);
|
||||||
|
// Write the transform tag command. Use simple interpolation to avoid issues from decomposition failure due to a scale of zero.
|
||||||
|
gEXMatrixGroupSimple(&bowstring_start_hook_dl[1], BOWSTRING_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW,
|
||||||
|
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
||||||
|
// Write the pop group command.
|
||||||
|
gEXPopMatrixGroup(&bowstring_end_hook_dl[0]);
|
||||||
}
|
}
|
||||||
// Overwrite the last command with a branch.
|
|
||||||
gSPBranchList(enddl_command, bowstring_end_hook_dl);
|
|
||||||
// Write the transform tag command. Use simple interpolation to avoid issues from decomposition failure due to a scale of zero.
|
|
||||||
gEXMatrixGroupSimple(&bowstring_start_hook_dl[1], BOWSTRING_TRANSFORM_ID, G_EX_PUSH, G_MTX_MODELVIEW,
|
|
||||||
G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_COMPONENT_INTERPOLATE, G_EX_ORDER_LINEAR);
|
|
||||||
// Write the pop group command.
|
|
||||||
gEXPopMatrixGroup(&bowstring_end_hook_dl[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @recomp Manually relocate Player_PostLimbDrawGameplay.
|
// @recomp Manually relocate Player_PostLimbDrawGameplay.
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
|
|
||||||
#define STAR_TRANSFORM_ID_START 0x1000U
|
#define STAR_TRANSFORM_ID_START 0x1000U
|
||||||
|
|
||||||
|
#define EFFECT_TRANSFORM_ID_COUNT 0x800U
|
||||||
|
#define EFFECT_SPARK_TRANSFORM_ID_START 0x2000U
|
||||||
|
#define EFFECT_BLURE_TRANSFORM_ID_START (EFFECT_SPARK_TRANSFORM_ID_START + 2 * EFFECT_TRANSFORM_ID_COUNT)
|
||||||
|
#define EFFECT_SHIELD_PARTICLE_TRANSFORM_ID_START (EFFECT_BLURE_TRANSFORM_ID_START + 2 * EFFECT_TRANSFORM_ID_COUNT)
|
||||||
|
#define EFFECT_TIRE_MARK_TRANSFORM_ID_START (EFFECT_SHIELD_PARTICLE_TRANSFORM_ID_START + 2 * EFFECT_TRANSFORM_ID_COUNT)
|
||||||
|
|
||||||
#define ACTOR_TRANSFORM_LIMB_COUNT 128
|
#define ACTOR_TRANSFORM_LIMB_COUNT 128
|
||||||
#define ACTOR_TRANSFORM_ID_COUNT (ACTOR_TRANSFORM_LIMB_COUNT * 2) // One ID for each limb and another for each post-draw
|
#define ACTOR_TRANSFORM_ID_COUNT (ACTOR_TRANSFORM_LIMB_COUNT * 2) // One ID for each limb and another for each post-draw
|
||||||
#define ACTOR_TRANSFORM_ID_START 0x1000000U
|
#define ACTOR_TRANSFORM_ID_START 0x1000000U
|
||||||
|
|
Loading…
Reference in New Issue