mirror of
https://github.com/Mr-Wiseguy/Zelda64Recomp.git
synced 2024-12-23 03:21:56 +01:00
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 "overlays/actors/ovl_En_Test7/z_en_test7.h"
|
||||
#include "overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h"
|
||||
#include "z64effect.h"
|
||||
|
||||
// Decomp renames, TODO update decomp and remove these
|
||||
#define gSoaringWarpCsWindCapsuleTexAnim gameplay_keep_Matanimheader_0815D0
|
||||
@ -325,3 +326,142 @@ void func_808DD3C8(Actor* thisx, PlayState* play2) {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 sPictoPhotoBeingTaken;
|
||||
extern void* gWorkBuffer;
|
||||
|
@ -157,27 +157,29 @@ void Player_DrawGameplay(PlayState* play, Player* this, s32 lod, Gfx* cullDList,
|
||||
// @recomp Force the closest LOD
|
||||
lod = 0;
|
||||
|
||||
// @recomp Patch object_link_child_DL_017818 (the DL for the bowstring) with a transform tag.
|
||||
gSegments[0x0C] = OS_K0_TO_PHYSICAL(cullDList);
|
||||
Gfx* dl_virtual_address = (Gfx*)Lib_SegmentedToVirtual(object_link_child_DL_017818);
|
||||
// @recomp If the player is a human, patch object_link_child_DL_017818 (the DL for the bowstring) with a transform tag.
|
||||
if (this->transformation == PLAYER_FORM_HUMAN) {
|
||||
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.
|
||||
if ((dl_virtual_address[0].words.w0 >> 24) != G_DL) {
|
||||
// Copy the first command before overwriting.
|
||||
bowstring_start_hook_dl[0] = dl_virtual_address[0];
|
||||
// Overwrite the first command with a branch.
|
||||
gSPBranchList(dl_virtual_address, OS_K0_TO_PHYSICAL(bowstring_start_hook_dl));
|
||||
Gfx* enddl_command = dl_virtual_address;
|
||||
while ((enddl_command->words.w0 >> 24) != G_ENDDL) {
|
||||
enddl_command++;
|
||||
// Check if the commands have already been overwritten.
|
||||
if ((dl_virtual_address[0].words.w0 >> 24) != G_DL) {
|
||||
// Copy the first command before overwriting.
|
||||
bowstring_start_hook_dl[0] = dl_virtual_address[0];
|
||||
// Overwrite the first command with a branch.
|
||||
gSPBranchList(dl_virtual_address, OS_K0_TO_PHYSICAL(bowstring_start_hook_dl));
|
||||
Gfx* enddl_command = dl_virtual_address;
|
||||
while ((enddl_command->words.w0 >> 24) != G_ENDDL) {
|
||||
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.
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
#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_ID_COUNT (ACTOR_TRANSFORM_LIMB_COUNT * 2) // One ID for each limb and another for each post-draw
|
||||
#define ACTOR_TRANSFORM_ID_START 0x1000000U
|
||||
|
Loading…
Reference in New Issue
Block a user