Split camera inversion into two settings, hooked up aiming camera inversion

This commit is contained in:
Mr-Wiseguy 2024-05-26 03:37:29 -04:00
parent 40aa4000cc
commit d8f9a2e5c8
9 changed files with 129 additions and 14 deletions

View file

@ -174,7 +174,7 @@
<!-- camera inversion -->
<div class="config-option" data-event-mouseover="set_cur_config_index(7)">
<label class="config-option__title">Inverted Camera Control</label>
<label class="config-option__title">Aiming Camera Mode</label>
<div class="config-option__list">
<input
type="radio"
@ -238,7 +238,7 @@
data-checked="analog_cam_mode"
value="On"
id="analog_cam_enabled"
style="nav-up: #camera_inversion_none"
style="nav-up: #camera_inversion_none; nav-down: analog_camera_inversion_none"
/>
<label class="config-option__tab-label" for="analog_cam_enabled">On</label>
@ -250,11 +250,65 @@
data-checked="analog_cam_mode"
value="Off"
id="analog_cam_disabled"
style="nav-up: #camera_inversion_x"
style="nav-up: #camera_inversion_x; nav-down: analog_camera_inversion_x"
/>
<label class="config-option__tab-label" for="analog_cam_disabled">Off</label>
</div>
</div>
<!-- analog camera inversion -->
<div class="config-option" data-event-mouseover="set_cur_config_index(9)">
<label class="config-option__title">Analog Camera Mode</label>
<div class="config-option__list">
<input
type="radio"
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(9)"
name="analog_camera_invert_mode"
data-checked="analog_camera_invert_mode"
value="InvertNone"
id="analog_camera_inversion_none"
style="nav-up: #analog_cam_enabled;"
/>
<label class="config-option__tab-label" for="analog_camera_inversion_none">None</label>
<input
type="radio"
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(9)"
name="analog_camera_invert_mode"
data-checked="analog_camera_invert_mode"
value="InvertX"
id="analog_camera_inversion_x"
style="nav-up: #analog_cam_disabled;"
/>
<label class="config-option__tab-label" for="analog_camera_inversion_x">Invert X</label>
<input
type="radio"
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(9)"
name="analog_camera_invert_mode"
data-checked="analog_camera_invert_mode"
value="InvertY"
id="analog_camera_inversion_y"
style="nav-up: #analog_cam_disabled;"
/>
<label class="config-option__tab-label" for="analog_camera_inversion_y">Invert Y</label>
<input
type="radio"
data-event-blur="set_cur_config_index(-1)"
data-event-focus="set_cur_config_index(9)"
name="analog_camera_invert_mode"
data-checked="analog_camera_invert_mode"
value="InvertBoth"
id="analog_camera_inversion_both"
style="nav-up: #analog_cam_disabled;"
/>
<label class="config-option__tab-label" for="analog_camera_inversion_both">Invert Both</label>
</div>
</div>
</div>
<!-- Descriptions -->
<div class="config__wrapper">
@ -294,10 +348,15 @@
<b>If autosaving is disabled, existing autosaves will be deleted when loaded.</b>
</p>
<p data-if="cur_config_index == 7">
Camera inversion description.
Inverts the camera controls for first-person aiming. <b>Invert Y</b> is the default and matches the original game.
</p>
<p data-if="cur_config_index == 8">
Analog cam description.
Enables an analog "free" camera similar to later entries in the series, which will be mapped to the right analog stick on your controller.
<br/>
When you move the right stick, the camera will enter "free" mode and stop centering behind Link. Press the <b>Target</b> button at any time to go back into "normal" camera. The camera will also return to "normal" mode after a cutscene plays or when you move between areas.
</p>
<p data-if="cur_config_index == 9">
Inverts the camera controls for the analog camera if it's enabled. <b>None</b> is the default.
</p>
</div>
</div>

View file

@ -183,6 +183,9 @@ namespace recomp {
CameraInvertMode get_camera_invert_mode();
void set_camera_invert_mode(CameraInvertMode mode);
CameraInvertMode get_analog_camera_invert_mode();
void set_analog_camera_invert_mode(CameraInvertMode mode);
bool game_input_disabled();
bool all_input_disabled();

View file

@ -67,7 +67,7 @@ void update_analog_cam(Camera* c) {
if (analog_cam_active) {
s32 inverted_x, inverted_y;
recomp_get_inverted_axes(&inverted_x, &inverted_y);
recomp_get_analog_inverted_axes(&inverted_x, &inverted_y);
if (inverted_x) {
input_x = -input_x;
@ -78,7 +78,7 @@ void update_analog_cam(Camera* c) {
}
analog_camera_yaw_vel = -input_x * analog_camera_x_sensitivity;
analog_camera_pitch_vel = -input_y * analog_camera_y_sensitivity;
analog_camera_pitch_vel = input_y * analog_camera_y_sensitivity;
analog_camera_pos.pitch += analog_camera_pitch_vel;
analog_camera_pos.yaw += analog_camera_yaw_vel;
@ -87,10 +87,11 @@ void update_analog_cam(Camera* c) {
analog_camera_pos.pitch = 0x36B0;
}
// -76.9 degrees
if (analog_camera_pos.pitch < -0x36B0) {
analog_camera_pos.pitch = -0x36B0;
if (analog_camera_pos.pitch < -0x16D0) {
analog_camera_pos.pitch = -0x16D0;
}
recomp_printf("analog cam pitch: %05X\n", analog_camera_pos.pitch);
}
}

View file

@ -13,12 +13,25 @@ s32 func_8082EF20(Player* this);
s32 func_80847190(PlayState* play, Player* this, s32 arg2) {
s32 pad;
s16 var_s0;
// @recomp Get the aiming camera inversion state.
s32 inverted_x, inverted_y;
recomp_get_inverted_axes(&inverted_x, &inverted_y);
if (!func_800B7128(this) && !func_8082EF20(this) && !arg2) {
var_s0 = play->state.input[0].rel.stick_y * 0xF0;
// @recomp Invert the Y axis accordingly (default is inverted, so negate if not inverted).
if (!inverted_y) {
var_s0 = -var_s0;
}
Math_SmoothStepToS(&this->actor.focus.rot.x, var_s0, 0xE, 0xFA0, 0x1E);
var_s0 = play->state.input[0].rel.stick_x * -0x10;
// @recomp Invert the X axis accordingly
if (inverted_x) {
var_s0 = -var_s0;
}
var_s0 = CLAMP(var_s0, -0xBB8, 0xBB8);
this->actor.focus.rot.y += var_s0;
}
@ -62,8 +75,14 @@ s32 func_80847190(PlayState* play, Player* this, s32 arg2) {
s16 temp3;
temp3 = ((play->state.input[0].rel.stick_y >= 0) ? 1 : -1) *
(s32)((1.0f - Math_CosS(play->state.input[0].rel.stick_y * 0xC8)) * 1500.0f);
// @recomp Invert the Y axis accordingly (default is inverted, so negate if not inverted).
s8 stick_y = play->state.input[0].rel.stick_y;
if (!inverted_y) {
stick_y = -stick_y;
}
temp3 = ((stick_y >= 0) ? 1 : -1) *
(s32)((1.0f - Math_CosS(stick_y * 0xC8)) * 1500.0f);
this->actor.focus.rot.x += temp3 + (s32)(target_aim_x - applied_aim_x);
applied_aim_x = target_aim_x;
@ -75,8 +94,14 @@ s32 func_80847190(PlayState* play, Player* this, s32 arg2) {
}
var_s0 = this->actor.focus.rot.y - this->actor.shape.rot.y;
temp3 = ((play->state.input[0].rel.stick_x >= 0) ? 1 : -1) *
(s32)((1.0f - Math_CosS(play->state.input[0].rel.stick_x * 0xC8)) * -1500.0f);
// @recomp Invert the X axis accordingly.
s8 stick_x = play->state.input[0].rel.stick_x;
if (inverted_x) {
stick_x = -stick_x;
}
temp3 = ((stick_x >= 0) ? 1 : -1) *
(s32)((1.0f - Math_CosS(stick_x * 0xC8)) * -1500.0f);
var_s0 += temp3 + (s32)(target_aim_y - applied_aim_y);
applied_aim_y = target_aim_y;

View file

@ -15,6 +15,7 @@ DECLARE_FUNC(void, recomp_get_mouse_deltas, float* x, float* y);
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_analog_inverted_axes, s32* x, s32* y);
DECLARE_FUNC(void, recomp_get_camera_inputs, float* x, float* y);
DECLARE_FUNC(void, recomp_set_right_analog_suppressed, s32 suppressed);

View file

@ -58,3 +58,4 @@ recomp_set_right_analog_suppressed = 0x8F0000A0;
recomp_get_inverted_axes = 0x8F0000A4;
recomp_high_precision_fb_enabled = 0x8F0000A8;
recomp_get_resolution_scale = 0x8F0000AC;
recomp_get_analog_inverted_axes = 0x8F0000B0;

View file

@ -167,6 +167,7 @@ void save_general_config(const std::filesystem::path& path) {
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["analog_camera_invert_mode"] = recomp::get_analog_camera_invert_mode();
config_json["debug_mode"] = recomp::get_debug_mode_enabled();
config_file << std::setw(4) << config_json;
}
@ -181,6 +182,7 @@ void set_general_settings_from_json(const nlohmann::json& config_json) {
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_analog_camera_invert_mode(from_or_default(config_json, "analog_camera_invert_mode", recomp::CameraInvertMode::InvertNone));
recomp::set_debug_mode_enabled(from_or_default(config_json, "debug_mode", false));
}

View file

@ -121,6 +121,16 @@ extern "C" void recomp_get_inverted_axes(uint8_t* rdram, recomp_context* ctx) {
*y_out = (mode == recomp::CameraInvertMode::InvertY || mode == recomp::CameraInvertMode::InvertBoth);
}
extern "C" void recomp_get_analog_inverted_axes(uint8_t* rdram, recomp_context* ctx) {
s32* x_out = _arg<0, s32*>(rdram, ctx);
s32* y_out = _arg<1, s32*>(rdram, ctx);
recomp::CameraInvertMode mode = recomp::get_analog_camera_invert_mode();
*x_out = (mode == recomp::CameraInvertMode::InvertX || mode == recomp::CameraInvertMode::InvertBoth);
*y_out = (mode == recomp::CameraInvertMode::InvertY || mode == recomp::CameraInvertMode::InvertBoth);
}
extern "C" void recomp_analog_cam_enabled(uint8_t* rdram, recomp_context* ctx) {
_return<s32>(ctx, recomp::get_analog_cam_mode() == recomp::AnalogCamMode::On);
}

View file

@ -280,6 +280,7 @@ struct ControlOptionsContext {
recomp::AutosaveMode autosave_mode;
recomp::CameraInvertMode camera_invert_mode;
recomp::AnalogCamMode analog_cam_mode;
recomp::CameraInvertMode analog_camera_invert_mode;
};
ControlOptionsContext control_options_context;
@ -389,6 +390,17 @@ void recomp::set_analog_cam_mode(recomp::AnalogCamMode mode) {
}
}
recomp::CameraInvertMode recomp::get_analog_camera_invert_mode() {
return control_options_context.analog_camera_invert_mode;
}
void recomp::set_analog_camera_invert_mode(recomp::CameraInvertMode mode) {
control_options_context.analog_camera_invert_mode = mode;
if (general_model_handle) {
general_model_handle.DirtyVariable("analog_camera_invert_mode");
}
}
struct SoundOptionsContext {
std::atomic<int> main_volume; // Option to control the volume of all sound
std::atomic<int> bgm_volume;
@ -890,6 +902,7 @@ public:
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);
bind_option(constructor, "analog_camera_invert_mode", &control_options_context.analog_camera_invert_mode);
general_model_handle = constructor.GetModelHandle();
}