mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp.git
synced 2026-04-28 05:01:39 +00:00
Added analog cam and camera inversion options to menu, initial implementation of analog cam
This commit is contained in:
parent
a4f61016bb
commit
cda95efc7d
14 changed files with 294 additions and 124 deletions
|
|
@ -154,7 +154,7 @@
|
|||
data-checked="autosave_mode"
|
||||
value="On"
|
||||
id="autosave_enabled"
|
||||
style="nav-up: #bg_input_enabled; nav-down: #analog_cam_enabled"
|
||||
style="nav-up: #bg_input_enabled; nav-down: #camera_inversion_none"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="autosave_enabled">On</label>
|
||||
|
||||
|
|
@ -166,11 +166,95 @@
|
|||
data-checked="autosave_mode"
|
||||
value="Off"
|
||||
id="autosave_disabled"
|
||||
style="nav-up: #bg_input_disabled; nav-down: #analog_cam_disabled"
|
||||
style="nav-up: #bg_input_disabled; nav-down: #camera_inversion_x"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="autosave_disabled">Off</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- camera inversion -->
|
||||
<div class="config-option" data-event-mouseover="set_cur_config_index(7)">
|
||||
<label class="config-option__title">Inverted Camera Control</label>
|
||||
<div class="config-option__list">
|
||||
<input
|
||||
type="radio"
|
||||
data-event-blur="set_cur_config_index(-1)"
|
||||
data-event-focus="set_cur_config_index(7)"
|
||||
name="camera_invert_mode"
|
||||
data-checked="camera_invert_mode"
|
||||
value="InvertNone"
|
||||
id="camera_inversion_none"
|
||||
style="nav-up: #autosave_enabled; nav-down: #analog_cam_enabled"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="camera_inversion_none">None</label>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
data-event-blur="set_cur_config_index(-1)"
|
||||
data-event-focus="set_cur_config_index(7)"
|
||||
name="camera_invert_mode"
|
||||
data-checked="camera_invert_mode"
|
||||
value="InvertX"
|
||||
id="camera_inversion_x"
|
||||
style="nav-up: #autosave_disabled; nav-down: #analog_cam_disabled"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="camera_inversion_x">Invert X</label>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
data-event-blur="set_cur_config_index(-1)"
|
||||
data-event-focus="set_cur_config_index(7)"
|
||||
name="camera_invert_mode"
|
||||
data-checked="camera_invert_mode"
|
||||
value="InvertY"
|
||||
id="camera_inversion_y"
|
||||
style="nav-up: #autosave_disabled; nav-down: #analog_cam_disabled"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="camera_inversion_y">Invert Y</label>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
data-event-blur="set_cur_config_index(-1)"
|
||||
data-event-focus="set_cur_config_index(7)"
|
||||
name="camera_invert_mode"
|
||||
data-checked="camera_invert_mode"
|
||||
value="InvertBoth"
|
||||
id="camera_inversion_both"
|
||||
style="nav-up: #autosave_disabled; nav-down: #analog_cam_disabled"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="camera_inversion_both">Invert Both</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- analog camera -->
|
||||
<div class="config-option" data-event-mouseover="set_cur_config_index(8)">
|
||||
<label class="config-option__title">Analog Camera</label>
|
||||
<div class="config-option__list">
|
||||
<input
|
||||
type="radio"
|
||||
data-event-blur="set_cur_config_index(-1)"
|
||||
data-event-focus="set_cur_config_index(8)"
|
||||
name="analog_cam_mode"
|
||||
data-checked="analog_cam_mode"
|
||||
value="On"
|
||||
id="analog_cam_enabled"
|
||||
style="nav-up: #camera_inversion_none"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="analog_cam_enabled">On</label>
|
||||
|
||||
<input
|
||||
type="radio"
|
||||
data-event-blur="set_cur_config_index(-1)"
|
||||
data-event-focus="set_cur_config_index(8)"
|
||||
name="analog_cam_mode"
|
||||
data-checked="analog_cam_mode"
|
||||
value="Off"
|
||||
id="analog_cam_disabled"
|
||||
style="nav-up: #camera_inversion_x"
|
||||
/>
|
||||
<label class="config-option__tab-label" for="analog_cam_disabled">Off</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Descriptions -->
|
||||
<div class="config__wrapper">
|
||||
|
|
@ -209,6 +293,12 @@
|
|||
<br/>
|
||||
<b>If autosaving is disabled, existing autosaves will be deleted when loaded.</b>
|
||||
</p>
|
||||
<p data-if="cur_config_index == 7">
|
||||
Camera inversion description.
|
||||
</p>
|
||||
<p data-if="cur_config_index == 8">
|
||||
Analog cam description.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -28,13 +28,27 @@ namespace recomp {
|
|||
OptionCount
|
||||
};
|
||||
|
||||
enum class AnalogCamMode {
|
||||
On,
|
||||
Off,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::AutosaveMode, {
|
||||
{recomp::AutosaveMode::On, "On"},
|
||||
{recomp::AutosaveMode::Off, "Off"}
|
||||
});
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::AnalogCamMode, {
|
||||
{recomp::AnalogCamMode::On, "On"},
|
||||
{recomp::AnalogCamMode::Off, "Off"}
|
||||
});
|
||||
|
||||
AutosaveMode get_autosave_mode();
|
||||
void set_autosave_mode(AutosaveMode mode);
|
||||
|
||||
AnalogCamMode get_analog_cam_mode();
|
||||
void set_analog_cam_mode(AnalogCamMode mode);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ namespace recomp {
|
|||
bool get_input_digital(const std::span<const recomp::InputField> fields);
|
||||
void get_gyro_deltas(float* x, float* y);
|
||||
void get_mouse_deltas(float* x, float* y);
|
||||
void get_right_analog(float* x, float* y);
|
||||
|
||||
enum class InputDevice {
|
||||
Controller,
|
||||
|
|
@ -133,6 +134,7 @@ namespace recomp {
|
|||
void set_gyro_sensitivity(int strength);
|
||||
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);
|
||||
|
||||
enum class TargetingMode {
|
||||
Switch,
|
||||
|
|
@ -162,6 +164,24 @@ namespace recomp {
|
|||
BackgroundInputMode get_background_input_mode();
|
||||
void set_background_input_mode(BackgroundInputMode mode);
|
||||
|
||||
enum class CameraInvertMode {
|
||||
InvertNone,
|
||||
InvertX,
|
||||
InvertY,
|
||||
InvertBoth,
|
||||
OptionCount
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(recomp::CameraInvertMode, {
|
||||
{recomp::CameraInvertMode::InvertNone, "InvertNone"},
|
||||
{recomp::CameraInvertMode::InvertX, "InvertX"},
|
||||
{recomp::CameraInvertMode::InvertY, "InvertY"},
|
||||
{recomp::CameraInvertMode::InvertBoth, "InvertBoth"}
|
||||
});
|
||||
|
||||
CameraInvertMode get_camera_invert_mode();
|
||||
void set_camera_invert_mode(CameraInvertMode mode);
|
||||
|
||||
bool game_input_disabled();
|
||||
bool all_input_disabled();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,65 +1,44 @@
|
|||
#include "patches.h"
|
||||
#include "input.h"
|
||||
#include "z64quake.h"
|
||||
#if 0
|
||||
RecompCameraMode recomp_camera_mode = RECOMP_CAMERA_NORMAL;
|
||||
#include "play_patches.h"
|
||||
|
||||
VecGeo recomp_camera_pos = { .r = 66.0f, .pitch = 0, .yaw = 0 };
|
||||
static bool was_in_analog_cam = false;
|
||||
static bool is_in_analog_cam = false;
|
||||
|
||||
float recomp_camera_yaw_vel = 0.0f;
|
||||
float recomp_camera_pitch_vel = 0.0f;
|
||||
VecGeo analog_camera_pos = { .r = 66.0f, .pitch = 0, .yaw = 0 };
|
||||
|
||||
float analog_camera_yaw_vel = 0.0f;
|
||||
float analog_camera_pitch_vel = 0.0f;
|
||||
|
||||
float recomp_deadzone = 0.2f;
|
||||
float recomp_camera_x_sensitivity = 1500.0f;
|
||||
float recomp_camera_y_sensitivity = 500.0f;
|
||||
// float recomp_camera_acceleration = 500.0f;
|
||||
float analog_deadzone = 0.2f;
|
||||
float analog_camera_x_sensitivity = 1500.0f;
|
||||
float analog_camera_y_sensitivity = 500.0f;
|
||||
// float analog_camera_acceleration = 500.0f;
|
||||
|
||||
void update_recomp_camera_params(Camera* camera) {
|
||||
recomp_camera_pos.yaw = Math_Atan2S(-camera->at.x + camera->eye.x, -camera->at.z + camera->eye.z);
|
||||
void update_analog_camera_params(Camera* camera) {
|
||||
analog_camera_pos.yaw = Math_Atan2S(-camera->at.x + camera->eye.x, -camera->at.z + camera->eye.z);
|
||||
// recomp_printf("Camera at: %.2f %.2f %.2f\n"
|
||||
// " eye: %.2f %.2f %.2f\n"
|
||||
// " yaw: %d",
|
||||
// camera->at.x, camera->at.y, camera->at.z,
|
||||
// camera->eye.x, camera->eye.y, camera->eye.z,
|
||||
// recomp_camera_pos.yaw);
|
||||
// analog_camera_pos.yaw);
|
||||
|
||||
float input_x, input_y;
|
||||
recomp_get_camera_inputs(&input_x, &input_y);
|
||||
if (was_in_analog_cam) {
|
||||
float input_x, input_y;
|
||||
recomp_get_camera_inputs(&input_x, &input_y);
|
||||
|
||||
// Math_StepToF(&recomp_camera_yaw_vel, input_x * recomp_camera_x_sensitivity, recomp_camera_acceleration);
|
||||
// Math_StepToF(&recomp_camera_pitch_vel, input_y * recomp_camera_y_sensitivity, recomp_camera_acceleration);
|
||||
if (fabsf(input_x) > recomp_deadzone) {
|
||||
recomp_camera_yaw_vel = input_x * recomp_camera_x_sensitivity;
|
||||
}
|
||||
else {
|
||||
recomp_camera_yaw_vel = 0;
|
||||
}
|
||||
|
||||
if (fabsf(input_y) > recomp_deadzone) {
|
||||
recomp_camera_pitch_vel = input_y * recomp_camera_y_sensitivity;
|
||||
}
|
||||
else {
|
||||
recomp_camera_pitch_vel = 0;
|
||||
}
|
||||
analog_camera_yaw_vel = input_x * analog_camera_x_sensitivity;
|
||||
analog_camera_pitch_vel = input_y * analog_camera_y_sensitivity;
|
||||
|
||||
recomp_camera_pos.pitch += recomp_camera_pitch_vel;
|
||||
recomp_camera_pos.yaw += recomp_camera_yaw_vel;
|
||||
analog_camera_pos.pitch += analog_camera_pitch_vel;
|
||||
analog_camera_pos.yaw += analog_camera_yaw_vel;
|
||||
}
|
||||
}
|
||||
|
||||
extern s32 sUpdateCameraDirection;
|
||||
static s32 sIsFalse = false;
|
||||
extern s32 sCameraInitSceneTimer;
|
||||
|
||||
extern s16 sCameraNextUID;
|
||||
extern s32 sCameraInterfaceFlags;
|
||||
extern s32 sCameraHudVisibility;
|
||||
extern s32 sCameraLetterboxSize;
|
||||
extern s32 sCameraNegOne1;
|
||||
|
||||
#define CAM_DATA_IS_BG (1 << 12) // if not set, then cam data is for actor cutscenes
|
||||
|
||||
typedef s32 (*CameraUpdateFunc)(Camera*);
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ s16 val;
|
||||
|
|
@ -78,20 +57,34 @@ typedef struct {
|
|||
/* 0x8 */ CameraMode* cameraModes;
|
||||
} CameraSetting;
|
||||
|
||||
extern CameraUpdateFunc sCameraUpdateHandlers[];
|
||||
extern CameraSetting sCameraSettings[];
|
||||
f32 Camera_GetFocalActorHeight(Camera* camera);
|
||||
f32 Camera_Vec3fMagnitude(Vec3f* vec);
|
||||
|
||||
#if 0
|
||||
static s32 sIsFalse = false;
|
||||
extern s32 sCameraInitSceneTimer;
|
||||
|
||||
extern s16 sCameraNextUID;
|
||||
extern s32 sCameraHudVisibility;
|
||||
extern s32 sCameraLetterboxSize;
|
||||
extern s32 sCameraNegOne1;
|
||||
|
||||
#define CAM_DATA_IS_BG (1 << 12) // if not set, then cam data is for actor cutscenes
|
||||
|
||||
typedef s32 (*CameraUpdateFunc)(Camera*);
|
||||
|
||||
extern CameraUpdateFunc sCameraUpdateHandlers[];
|
||||
|
||||
Vec3f Camera_CalcUpVec(s16 pitch, s16 yaw, s16 roll);
|
||||
f32 Camera_fabsf(f32 f);
|
||||
s32 Camera_GetBgCamIndex(Camera* camera, s32* bgId, CollisionPoly* poly);
|
||||
f32 Camera_GetFocalActorHeight(Camera* camera);
|
||||
f32 Camera_GetRunSpeedLimit(Camera* camera);
|
||||
s32 Camera_IsDekuHovering(Camera* camera);
|
||||
s32 Camera_IsMountedOnHorse(Camera* camera);
|
||||
s32 Camera_IsUnderwaterAsZora(Camera* camera);
|
||||
s32 Camera_IsUsingZoraFins(Camera* camera);
|
||||
void Camera_UpdateInterface(s32 interfaceFlags);
|
||||
f32 Camera_Vec3fMagnitude(Vec3f* vec);
|
||||
s32 func_800CB7CC(Camera* camera);
|
||||
s32 func_800CB854(Camera* camera);
|
||||
|
||||
|
|
@ -275,7 +268,7 @@ Vec3s Camera_Update(Camera* camera) {
|
|||
sCameraUpdateHandlers[sCameraSettings[camera->setting].cameraModes[camera->mode].funcId](camera);
|
||||
|
||||
// @recomp
|
||||
update_recomp_camera_params(camera);
|
||||
update_analog_camera_params(camera);
|
||||
|
||||
// Update the interface
|
||||
if (sCameraInitSceneTimer != 0) {
|
||||
|
|
@ -357,6 +350,8 @@ Vec3s Camera_Update(Camera* camera) {
|
|||
return camera->inputDir;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern SwingAnimation D_801EDC30[4];
|
||||
s32 Camera_CalcAtDefault(Camera* camera, VecGeo* eyeAtDir, f32 yOffset, s16 calcSlope);
|
||||
s32 Camera_CalcAtForNormal1(Camera* camera, VecGeo* arg1, f32 yOffset, f32 forwardDist);
|
||||
|
|
@ -691,10 +686,11 @@ s32 Camera_Normal1(Camera* camera) {
|
|||
}
|
||||
|
||||
// @recomp
|
||||
if (recomp_camera_mode == RECOMP_CAMERA_DUALANALOG) {
|
||||
spB4.pitch = recomp_camera_pos.pitch;
|
||||
// spB4.r = recomp_camera_pos.r;
|
||||
spB4.yaw = recomp_camera_pos.yaw;
|
||||
if (recomp_analog_cam_enabled()) {
|
||||
is_in_analog_cam = true;
|
||||
spB4.pitch = analog_camera_pos.pitch;
|
||||
// spB4.r = analog_camera_pos.r;
|
||||
spB4.yaw = analog_camera_pos.yaw;
|
||||
}
|
||||
|
||||
// 76.9 degrees
|
||||
|
|
@ -708,7 +704,7 @@ s32 Camera_Normal1(Camera* camera) {
|
|||
}
|
||||
|
||||
// @recomp
|
||||
recomp_camera_pos.pitch = spB4.pitch;
|
||||
analog_camera_pos.pitch = spB4.pitch;
|
||||
|
||||
*eyeNext = OLib_AddVecGeoToVec3f(at, &spB4);
|
||||
|
||||
|
|
@ -755,11 +751,10 @@ s32 Camera_Normal1(Camera* camera) {
|
|||
|
||||
phi_f2 = (gSaveContext.save.saveInfo.playerData.health <= 0x10) ? 0.8f : 1.0f;
|
||||
|
||||
// @recomp
|
||||
// // Don't zoom in on low health when dual analog is used
|
||||
// if (recomp_camera_mode == RECOMP_CAMERA_DUALANALOG) {
|
||||
// phi_f2;
|
||||
// }
|
||||
// @recomp Don't zoom in on low health when dual analog is used
|
||||
if (recomp_analog_cam_enabled()) {
|
||||
phi_f2 = 1.0f;
|
||||
}
|
||||
|
||||
camera->fov = Camera_ScaledStepToCeilF(roData->unk_18 * phi_f2, camera->fov, camera->fovUpdateRate, 0.1f);
|
||||
|
||||
|
|
@ -783,4 +778,14 @@ s32 Camera_Normal1(Camera* camera) {
|
|||
|
||||
return true;
|
||||
}
|
||||
#endif // #if 0
|
||||
|
||||
void analog_cam_pre_play_update(PlayState* play) {
|
||||
Camera *active_cam = play->cameraPtrs[play->activeCamId];
|
||||
update_analog_camera_params(active_cam);
|
||||
}
|
||||
|
||||
void analog_cam_post_play_update(PlayState* play) {
|
||||
// recomp_printf("was_in_analog_cam: %d is_in_analog_cam: %d\n", was_in_analog_cam, is_in_analog_cam);
|
||||
was_in_analog_cam = is_in_analog_cam;
|
||||
is_in_analog_cam = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,18 +95,6 @@ u32 sPlayerItemButtons[] = {
|
|||
BTN_CRIGHT,
|
||||
};
|
||||
|
||||
// u32 sPlayerItemButtonsDualAnalog[] = {
|
||||
// BTN_B,
|
||||
// BTN_DLEFT,
|
||||
// BTN_DDOWN,
|
||||
// BTN_DRIGHT
|
||||
// };
|
||||
|
||||
// u32 prev_item_buttons = 0;
|
||||
// u32 cur_item_buttons = 0;
|
||||
// u32 pressed_item_buttons = 0;
|
||||
// u32 released_item_buttons = 0;
|
||||
|
||||
// D-Pad items
|
||||
|
||||
#define EXTRA_ITEM_SLOT_COUNT 4
|
||||
|
|
@ -129,31 +117,6 @@ typedef enum {
|
|||
EQUIP_SLOT_EX_DDOWN,
|
||||
} EquipSlotEx;
|
||||
|
||||
// static inline void dup_to_cup(u16* button) {
|
||||
// if (*button & BTN_DUP) {
|
||||
// *button |= BTN_CUP;
|
||||
// }
|
||||
// }
|
||||
|
||||
void GameState_GetInput(GameState* gameState) {
|
||||
PadMgr_GetInput(gameState->input, true);
|
||||
|
||||
// if (recomp_camera_mode == RECOMP_CAMERA_DUALANALOG) {
|
||||
// gameState->input[0].cur.button &= ~BTN_CUP;
|
||||
// gameState->input[0].press.button &= ~BTN_CUP;
|
||||
// gameState->input[0].rel.button &= ~BTN_CUP;
|
||||
// dup_to_cup(&gameState->input[0].cur.button);
|
||||
// dup_to_cup(&gameState->input[0].press.button);
|
||||
// dup_to_cup(&gameState->input[0].rel.button);
|
||||
// }
|
||||
|
||||
// prev_item_buttons = cur_item_buttons;
|
||||
// recomp_get_item_inputs(&cur_item_buttons);
|
||||
// u32 button_diff = prev_item_buttons ^ cur_item_buttons;
|
||||
// pressed_item_buttons = cur_item_buttons & button_diff;
|
||||
// released_item_buttons = prev_item_buttons & button_diff;
|
||||
}
|
||||
|
||||
struct ExButtonMapping {
|
||||
u32 button;
|
||||
EquipSlotEx slot;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ extern RecompCameraMode recomp_camera_mode;
|
|||
|
||||
DECLARE_FUNC(void, recomp_get_gyro_deltas, float* x, float* y);
|
||||
DECLARE_FUNC(void, recomp_get_mouse_deltas, float* x, float* y);
|
||||
DECLARE_FUNC(int, recomp_get_targeting_mode);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ void Play_Main(GameState* thisx) {
|
|||
// @recomp
|
||||
debug_play_update(this);
|
||||
controls_play_update(this);
|
||||
analog_cam_pre_play_update(this);
|
||||
matrix_play_update(this);
|
||||
|
||||
// @recomp avoid unused variable warning
|
||||
|
|
@ -33,6 +34,7 @@ void Play_Main(GameState* thisx) {
|
|||
camera_pre_play_update(this);
|
||||
Play_Update(this);
|
||||
camera_post_play_update(this);
|
||||
analog_cam_post_play_update(this);
|
||||
autosave_post_play_update(this);
|
||||
this->state.gfxCtx = gfxCtx;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
void debug_play_update(PlayState* play);
|
||||
void camera_pre_play_update(PlayState* play);
|
||||
void camera_post_play_update(PlayState* play);
|
||||
void analog_cam_pre_play_update(PlayState* play);
|
||||
void analog_cam_post_play_update(PlayState* play);
|
||||
void matrix_play_update(PlayState* play);
|
||||
void autosave_post_play_update(PlayState* play);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,5 +52,7 @@ osGetTime_recomp = 0x8F000088;
|
|||
recomp_autosave_enabled = 0x8F00008C;
|
||||
recomp_load_overlays = 0x8F000090;
|
||||
osInvalICache_recomp = 0x8F000094;
|
||||
recomp_analog_cam_enabled = 0x8F000098;
|
||||
recomp_get_camera_inputs = 0x8F00009C;
|
||||
recomp_high_precision_fb_enabled = 0x8F0000A8;
|
||||
recomp_get_resolution_scale = 0x8F0000AC;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,8 @@ void save_general_config(const std::filesystem::path& path) {
|
|||
config_json["mouse_sensitivity"] = recomp::get_mouse_sensitivity();
|
||||
config_json["joystick_deadzone"] = recomp::get_joystick_deadzone();
|
||||
config_json["autosave_mode"] = recomp::get_autosave_mode();
|
||||
config_json["camera_invert_mode"] = recomp::get_camera_invert_mode();
|
||||
config_json["analog_cam_mode"] = recomp::get_analog_cam_mode();
|
||||
config_json["debug_mode"] = recomp::get_debug_mode_enabled();
|
||||
config_file << std::setw(4) << config_json;
|
||||
}
|
||||
|
|
@ -177,6 +179,8 @@ void set_general_settings_from_json(const nlohmann::json& config_json) {
|
|||
recomp::set_mouse_sensitivity(from_or_default(config_json, "mouse_sensitivity", is_steam_deck ? 50 : 0));
|
||||
recomp::set_joystick_deadzone(from_or_default(config_json, "joystick_deadzone", 5));
|
||||
recomp::set_autosave_mode(from_or_default(config_json, "autosave_mode", recomp::AutosaveMode::On));
|
||||
recomp::set_camera_invert_mode(from_or_default(config_json, "camera_invert_mode", recomp::CameraInvertMode::InvertY));
|
||||
recomp::set_analog_cam_mode(from_or_default(config_json, "analog_cam_mode", recomp::AnalogCamMode::Off));
|
||||
recomp::set_debug_mode_enabled(from_or_default(config_json, "debug_mode", false));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,33 +95,7 @@ void recomp::get_n64_input(uint16_t* buttons_out, float* x_out, float* y_out) {
|
|||
float joystick_y = recomp::get_input_analog(controller_input_mappings[(size_t)GameInput::Y_AXIS_POS])
|
||||
- recomp::get_input_analog(controller_input_mappings[(size_t)GameInput::Y_AXIS_NEG]);
|
||||
|
||||
if(fabsf(joystick_x) < joystick_deadzone) {
|
||||
joystick_x = 0.0f;
|
||||
}
|
||||
else {
|
||||
if(joystick_x > 0.0f) {
|
||||
joystick_x -= joystick_deadzone;
|
||||
}
|
||||
else {
|
||||
joystick_x += joystick_deadzone;
|
||||
}
|
||||
|
||||
joystick_x /= (1.0f - joystick_deadzone);
|
||||
}
|
||||
|
||||
if(fabsf(joystick_y) < joystick_deadzone) {
|
||||
joystick_y = 0.0f;
|
||||
}
|
||||
else {
|
||||
if(joystick_y > 0.0f) {
|
||||
joystick_y -= joystick_deadzone;
|
||||
}
|
||||
else {
|
||||
joystick_y += joystick_deadzone;
|
||||
}
|
||||
|
||||
joystick_y /= (1.0f - joystick_deadzone);
|
||||
}
|
||||
recomp::apply_joystick_deadzone(joystick_x, joystick_y, &joystick_x, &joystick_y);
|
||||
|
||||
cur_x = recomp::get_input_analog(keyboard_input_mappings[(size_t)GameInput::X_AXIS_POS])
|
||||
- recomp::get_input_analog(keyboard_input_mappings[(size_t)GameInput::X_AXIS_NEG]) + joystick_x;
|
||||
|
|
|
|||
|
|
@ -580,6 +580,51 @@ void recomp::get_mouse_deltas(float* x, float* y) {
|
|||
*y = cur_mouse_delta[1] * sensitivity;
|
||||
}
|
||||
|
||||
void recomp::apply_joystick_deadzone(float x_in, float y_in, float* x_out, float* y_out) {
|
||||
float joystick_deadzone = (float)recomp::get_joystick_deadzone() / 100.0f;
|
||||
|
||||
if(fabsf(x_in) < joystick_deadzone) {
|
||||
x_in = 0.0f;
|
||||
}
|
||||
else {
|
||||
if(x_in > 0.0f) {
|
||||
x_in -= joystick_deadzone;
|
||||
}
|
||||
else {
|
||||
x_in += joystick_deadzone;
|
||||
}
|
||||
|
||||
x_in /= (1.0f - joystick_deadzone);
|
||||
}
|
||||
|
||||
if(fabsf(y_in) < joystick_deadzone) {
|
||||
y_in = 0.0f;
|
||||
}
|
||||
else {
|
||||
if(y_in > 0.0f) {
|
||||
y_in -= joystick_deadzone;
|
||||
}
|
||||
else {
|
||||
y_in += joystick_deadzone;
|
||||
}
|
||||
|
||||
y_in /= (1.0f - joystick_deadzone);
|
||||
}
|
||||
|
||||
*x_out = x_in;
|
||||
*y_out = y_in;
|
||||
}
|
||||
|
||||
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));
|
||||
float y_val =
|
||||
controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1)) -
|
||||
controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1));
|
||||
recomp::apply_joystick_deadzone(x_val, y_val, x, y);
|
||||
}
|
||||
|
||||
bool recomp::game_input_disabled() {
|
||||
// Disable input if any menu is open.
|
||||
return recomp::get_current_menu() != recomp::Menu::None;
|
||||
|
|
|
|||
|
|
@ -110,3 +110,23 @@ extern "C" void recomp_high_precision_fb_enabled(uint8_t * rdram, recomp_context
|
|||
extern "C" void recomp_get_resolution_scale(uint8_t* rdram, recomp_context* ctx) {
|
||||
_return(ctx, ultramodern::get_resolution_scale());
|
||||
}
|
||||
|
||||
extern "C" void recomp_get_inverted_axes(uint8_t* rdram, recomp_context* ctx) {
|
||||
s32* x_out = _arg<0, s32*>(rdram, ctx);
|
||||
s32* y_out = _arg<1, s32*>(rdram, ctx);
|
||||
|
||||
// TODO implement this
|
||||
*x_out = 0;
|
||||
*y_out = 1;
|
||||
}
|
||||
|
||||
extern "C" void recomp_analog_cam_enabled(uint8_t* rdram, recomp_context* ctx) {
|
||||
_return<s32>(ctx, recomp::get_analog_cam_mode() == recomp::AnalogCamMode::On);
|
||||
}
|
||||
|
||||
extern "C" void recomp_get_camera_inputs(uint8_t* rdram, recomp_context* ctx) {
|
||||
float* x_out = _arg<0, float*>(rdram, ctx);
|
||||
float* y_out = _arg<1, float*>(rdram, ctx);
|
||||
|
||||
recomp::get_right_analog(x_out, y_out);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,6 +278,8 @@ struct ControlOptionsContext {
|
|||
recomp::TargetingMode targeting_mode;
|
||||
recomp::BackgroundInputMode background_input_mode;
|
||||
recomp::AutosaveMode autosave_mode;
|
||||
recomp::CameraInvertMode camera_invert_mode;
|
||||
recomp::AnalogCamMode analog_cam_mode;
|
||||
};
|
||||
|
||||
ControlOptionsContext control_options_context;
|
||||
|
|
@ -365,6 +367,28 @@ void recomp::set_autosave_mode(recomp::AutosaveMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
recomp::CameraInvertMode recomp::get_camera_invert_mode() {
|
||||
return control_options_context.camera_invert_mode;
|
||||
}
|
||||
|
||||
void recomp::set_camera_invert_mode(recomp::CameraInvertMode mode) {
|
||||
control_options_context.camera_invert_mode = mode;
|
||||
if (general_model_handle) {
|
||||
general_model_handle.DirtyVariable("camera_invert_mode");
|
||||
}
|
||||
}
|
||||
|
||||
recomp::AnalogCamMode recomp::get_analog_cam_mode() {
|
||||
return control_options_context.analog_cam_mode;
|
||||
}
|
||||
|
||||
void recomp::set_analog_cam_mode(recomp::AnalogCamMode mode) {
|
||||
control_options_context.analog_cam_mode = mode;
|
||||
if (general_model_handle) {
|
||||
general_model_handle.DirtyVariable("analog_cam_mode");
|
||||
}
|
||||
}
|
||||
|
||||
struct SoundOptionsContext {
|
||||
std::atomic<int> main_volume; // Option to control the volume of all sound
|
||||
std::atomic<int> bgm_volume;
|
||||
|
|
@ -864,6 +888,8 @@ public:
|
|||
bind_option(constructor, "targeting_mode", &control_options_context.targeting_mode);
|
||||
bind_option(constructor, "background_input_mode", &control_options_context.background_input_mode);
|
||||
bind_option(constructor, "autosave_mode", &control_options_context.autosave_mode);
|
||||
bind_option(constructor, "camera_invert_mode", &control_options_context.camera_invert_mode);
|
||||
bind_option(constructor, "analog_cam_mode", &control_options_context.analog_cam_mode);
|
||||
|
||||
general_model_handle = constructor.GetModelHandle();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue