diff --git a/patches/input.c b/patches/input.c index 2962204..7812dc4 100644 --- a/patches/input.c +++ b/patches/input.c @@ -6,21 +6,35 @@ #include "z64voice.h" #include "audiothread_cmd.h" +RECOMP_DECLARE_EVENT(recomp_before_first_person_aiming_update_event(PlayState* play, Player* this, bool in_free_look, RecompAimingOverideMode* recomp_aiming_override_mode)); +RECOMP_DECLARE_EVENT(recomp_after_first_person_aiming_update_event(PlayState* play, Player* this, bool in_free_look)); + s32 func_80847190(PlayState* play, Player* this, s32 arg2); s16 func_80832754(Player* this, s32 arg1); s32 func_8082EF20(Player* this); +// This flag is reset every frame by 'poll_inputs()'. +RecompAimingOverideMode recomp_aiming_override_mode = RECOMP_AIMING_OVERRIDE_OFF; + // @recomp Patched to add gyro and mouse aiming. RECOMP_PATCH s32 func_80847190(PlayState* play, Player* this, s32 arg2) { s32 pad; s16 var_s0; + + // Checks if we're in free look (C-Up look around mode). + bool in_free_look = (!func_800B7128(this) && !func_8082EF20(this) && !arg2); + + // Checking if any mods have disabled aiming with the left stick. + recomp_before_first_person_aiming_update_event(play, this, in_free_look, &recomp_aiming_override_mode); + // @recomp Get the aiming camera inversion state. s32 inverted_x, inverted_y; recomp_get_inverted_axes(&inverted_x, &inverted_y); - // @recomp Get the analog camera input values if analog cam is enabled. + + // @recomp Get the analog camera input values if analog cam is enabled, or right-stick aiming is being forced. s32 analog_x = 0; s32 analog_y = 0; - if (recomp_analog_cam_enabled()) { + if (recomp_analog_cam_enabled() || recomp_aiming_override_mode == RECOMP_AIMING_OVERRIDE_FORCE_RIGHT_STICK) { float analog_x_float = 0.0f; float analog_y_float = 0.0f; recomp_get_camera_inputs(&analog_x_float, &analog_y_float); @@ -35,9 +49,13 @@ RECOMP_PATCH s32 func_80847190(PlayState* play, Player* this, s32 arg2) { // play->state.input[0].rel.stick_x, play->state.input[0].rel.stick_y, // analog_x, analog_y); - if (!func_800B7128(this) && !func_8082EF20(this) && !arg2) { + if (in_free_look) { // @recomp Add in the analog camera Y input. Clamp to prevent moving the camera twice as fast if both sticks are held. - var_s0 = CLAMP(play->state.input[0].rel.stick_y + analog_y, -61, 61) * 0xF0; + s32 cam_input_y = analog_y; + if (recomp_aiming_override_mode == RECOMP_AIMING_OVERRIDE_OFF) { + cam_input_y += play->state.input[0].rel.stick_y; + } + var_s0 = CLAMP(cam_input_y, -61, 61) * 0xF0; // @recomp Invert the Y axis accordingly (default is inverted, so negate if not inverted). if (!inverted_y) { @@ -46,7 +64,11 @@ RECOMP_PATCH s32 func_80847190(PlayState* play, Player* this, s32 arg2) { Math_SmoothStepToS(&this->actor.focus.rot.x, var_s0, 0xE, 0xFA0, 0x1E); // @recomp Add in the analog camera X input. Clamp to prevent moving the camera twice as fast if both sticks are held. - var_s0 = CLAMP(play->state.input[0].rel.stick_x + analog_x, -61, 61) * -0x10; + s32 cam_input_x = analog_x; + if (recomp_aiming_override_mode == RECOMP_AIMING_OVERRIDE_OFF) { + cam_input_x += play->state.input[0].rel.stick_x; + } + var_s0 = CLAMP(cam_input_x, -61, 61) * -0x10; // @recomp Invert the X axis accordingly if (inverted_x) { @@ -97,7 +119,13 @@ RECOMP_PATCH s32 func_80847190(PlayState* play, Player* this, s32 arg2) { // @recomp Invert the Y axis accordingly (default is inverted, so negate if not inverted). // Also add in the analog camera Y input. Clamp to prevent moving the camera twice as fast if both sticks are held. - s32 stick_y = CLAMP(play->state.input[0].rel.stick_y + analog_y, -61, 61); + s32 cam_input_y = analog_y; + if (recomp_aiming_override_mode == RECOMP_AIMING_OVERRIDE_OFF) { + cam_input_y += play->state.input[0].rel.stick_y; + } + s32 stick_y; + stick_y = CLAMP(cam_input_y, -61, 61); + if (!inverted_y) { stick_y = -stick_y; } @@ -118,7 +146,13 @@ RECOMP_PATCH s32 func_80847190(PlayState* play, Player* this, s32 arg2) { // @recomp Invert the X axis accordingly. Also add in the analog camera Y input. // Clamp to prevent moving the camera twice as fast if both sticks are held. - s32 stick_x = CLAMP(play->state.input[0].rel.stick_x + analog_x, -61, 61); + s32 cam_input_x = analog_x; + if (recomp_aiming_override_mode == RECOMP_AIMING_OVERRIDE_OFF) { + cam_input_x += play->state.input[0].rel.stick_x; + } + s32 stick_x; + stick_x = CLAMP(cam_input_x, -61, 61); + if (inverted_x) { stick_x = -stick_x; } @@ -130,6 +164,8 @@ RECOMP_PATCH s32 func_80847190(PlayState* play, Player* this, s32 arg2) { this->actor.focus.rot.y = CLAMP(var_s0, -0x4AAA, 0x4AAA) + this->actor.shape.rot.y; } + recomp_after_first_person_aiming_update_event(play, this, in_free_look); + this->unk_AA6 |= 2; return func_80832754(this, (play->unk_1887C != 0) || func_800B7128(this) || func_8082EF20(this)); diff --git a/patches/input.h b/patches/input.h index 0f00e36..efb4443 100644 --- a/patches/input.h +++ b/patches/input.h @@ -8,7 +8,14 @@ typedef enum { RECOMP_CAMERA_DUALANALOG, } RecompCameraMode; +typedef enum { + RECOMP_AIMING_OVERRIDE_OFF = 0, + RECOMP_AIMING_OVERRIDE_DISABLE_LEFT_STICK = 1, + RECOMP_AIMING_OVERRIDE_FORCE_RIGHT_STICK = 2 +} RecompAimingOverideMode; + extern RecompCameraMode recomp_camera_mode; +extern RecompAimingOverideMode recomp_aiming_override_mode; DECLARE_FUNC(void, recomp_get_gyro_deltas, float* x, float* y); DECLARE_FUNC(void, recomp_get_mouse_deltas, float* x, float* y); diff --git a/patches/input_latency.c b/patches/input_latency.c index 8007c6a..b5974f9 100644 --- a/patches/input_latency.c +++ b/patches/input_latency.c @@ -70,8 +70,11 @@ void poll_inputs(void) { // Begin reading controller data osContStartReadData(serialEventQueue); + bool needs_right_stick = recomp_analog_cam_enabled() || recomp_aiming_override_mode == RECOMP_AIMING_OVERRIDE_FORCE_RIGHT_STICK; // Suppress the right analog stick if analog camera is active unless the ocarina is in use. - recomp_set_right_analog_suppressed(recomp_analog_cam_enabled() && sOcarinaInstrumentId == OCARINA_INSTRUMENT_OFF); + recomp_set_right_analog_suppressed(needs_right_stick && sOcarinaInstrumentId == OCARINA_INSTRUMENT_OFF); + // Resets this flag for the next frame; + recomp_aiming_override_mode = RECOMP_AIMING_OVERRIDE_OFF; // Wait for controller data osRecvMesg(serialEventQueue, NULL, OS_MESG_BLOCK);