Automatically suppress inputs on the right stick while analog cam is active

This commit is contained in:
Mr-Wiseguy 2024-05-25 04:00:11 -04:00
parent cda95efc7d
commit e30e85ea52
6 changed files with 34 additions and 7 deletions

View file

@ -135,6 +135,7 @@ namespace recomp {
void set_mouse_sensitivity(int strength);
void set_joystick_deadzone(int strength);
void apply_joystick_deadzone(float x_in, float y_in, float* x_out, float* y_out);
void set_right_analog_suppressed(bool suppressed);
enum class TargetingMode {
Switch,

View file

@ -16,5 +16,6 @@ DECLARE_FUNC(s32, recomp_get_targeting_mode);
DECLARE_FUNC(void, recomp_get_inverted_axes, s32* x, s32* y);
DECLARE_FUNC(s32, recomp_analog_cam_enabled);
DECLARE_FUNC(void, recomp_get_camera_inputs, float* x, float* y);
DECLARE_FUNC(void, recomp_set_right_analog_suppressed, s32 suppressed);
#endif

View file

@ -8,6 +8,7 @@
#include "z64viscvg.h"
#include "z64vismono.h"
#include "z64viszbuf.h"
#include "input.h"
void recomp_set_current_frame_poll_id();
void PadMgr_HandleRetrace(void);
@ -62,11 +63,16 @@ void PadMgr_HandleRetrace(void) {
}
}
extern u8 sOcarinaInstrumentId;
void poll_inputs(void) {
OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue();
// Begin reading controller data
osContStartReadData(serialEventQueue);
// 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);
// Wait for controller data
osRecvMesg(serialEventQueue, NULL, OS_MESG_BLOCK);
osContGetReadData(sPadMgrInstance->pads);

View file

@ -54,5 +54,6 @@ recomp_load_overlays = 0x8F000090;
osInvalICache_recomp = 0x8F000094;
recomp_analog_cam_enabled = 0x8F000098;
recomp_get_camera_inputs = 0x8F00009C;
recomp_set_right_analog_suppressed = 0x8F0000A0;
recomp_high_precision_fb_enabled = 0x8F0000A8;
recomp_get_resolution_scale = 0x8F0000AC;

View file

@ -483,7 +483,9 @@ bool controller_button_state(int32_t input_id) {
return false;
}
float controller_axis_state(int32_t input_id) {
static std::atomic_bool right_analog_suppressed = false;
float controller_axis_state(int32_t input_id, bool allow_suppression) {
if (abs(input_id) - 1 < SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_MAX) {
SDL_GameControllerAxis axis = (SDL_GameControllerAxis)(abs(input_id) - 1);
bool negative_range = input_id < 0;
@ -496,6 +498,12 @@ float controller_axis_state(int32_t input_id) {
if (negative_range) {
cur_val = -cur_val;
}
// Check if this input is a right analog axis and suppress it accordingly.
if (allow_suppression && right_analog_suppressed.load() &&
(axis == SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX || axis == SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY)) {
cur_val = 0;
}
ret += std::clamp(cur_val, 0.0f, 1.0f);
}
}
@ -518,7 +526,7 @@ float recomp::get_input_analog(const recomp::InputField& field) {
case InputType::ControllerDigital:
return controller_button_state(field.input_id) ? 1.0f : 0.0f;
case InputType::ControllerAnalog:
return controller_axis_state(field.input_id);
return controller_axis_state(field.input_id, true);
case InputType::Mouse:
// TODO mouse support
return 0.0f;
@ -549,7 +557,7 @@ bool recomp::get_input_digital(const recomp::InputField& field) {
return controller_button_state(field.input_id);
case InputType::ControllerAnalog:
// TODO adjustable threshold
return controller_axis_state(field.input_id) >= axis_threshold;
return controller_axis_state(field.input_id, true) >= axis_threshold;
case InputType::Mouse:
// TODO mouse support
return false;
@ -617,14 +625,18 @@ void recomp::apply_joystick_deadzone(float x_in, float y_in, float* x_out, float
void recomp::get_right_analog(float* x, float* y) {
float x_val =
controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX + 1)) -
controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX + 1));
controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX + 1), false) -
controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX + 1), false);
float y_val =
controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1)) -
controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1));
controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1), false) -
controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1), false);
recomp::apply_joystick_deadzone(x_val, y_val, x, y);
}
void recomp::set_right_analog_suppressed(bool suppressed) {
right_analog_suppressed.store(suppressed);
}
bool recomp::game_input_disabled() {
// Disable input if any menu is open.
return recomp::get_current_menu() != recomp::Menu::None;

View file

@ -130,3 +130,9 @@ extern "C" void recomp_get_camera_inputs(uint8_t* rdram, recomp_context* ctx) {
recomp::get_right_analog(x_out, y_out);
}
extern "C" void recomp_set_right_analog_suppressed(uint8_t* rdram, recomp_context* ctx) {
s32 suppressed = _arg<0, s32>(rdram, ctx);
recomp::set_right_analog_suppressed(suppressed);
}