diff --git a/common/include/common/config/GameConfig.h b/common/include/common/config/GameConfig.h index a0e295f4..cd5f230d 100644 --- a/common/include/common/config/GameConfig.h +++ b/common/include/common/config/GameConfig.h @@ -68,6 +68,8 @@ struct GameConfig // Audio CfgVar level_sound_volume = 1.0f; + CfgVar scope_sensitivity_modifier = 1.0f; + CfgVar scanner_sensitivity_modifier = 1.0f; CfgVar eax_sound = true; // Multiplayer diff --git a/common/src/config/GameConfig.cpp b/common/src/config/GameConfig.cpp index abaceaeb..a52be52c 100644 --- a/common/src/config/GameConfig.cpp +++ b/common/src/config/GameConfig.cpp @@ -166,6 +166,8 @@ bool GameConfig::visit_vars(T&& visitor, bool is_save) result &= visitor(dash_faction_key, "Fast Start", fast_start); result &= visitor(dash_faction_key, "Scoreboard Animations", scoreboard_anim); result &= visitor(dash_faction_key, "Level Sound Volume", level_sound_volume); + result &= visitor(dash_faction_key, "Scope Sensitivity Modifier", scope_sensitivity_modifier); + result &= visitor(dash_faction_key, "Scanner Sensitivity Modifier", scanner_sensitivity_modifier); result &= visitor(dash_faction_key, "Allow Overwriting Game Files", allow_overwrite_game_files); result &= visitor(dash_faction_key, "Version", dash_faction_version); result &= visitor(dash_faction_key, "Swap Assault Rifle Controls", swap_assault_rifle_controls); diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1c2cb258..f18d22cd 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -43,6 +43,7 @@ Version 1.9.0 (not released yet) - Do not load unnecessary VPPs in dedicated server mode - Add level filename to "Level Initializing" console message - Properly handle WM_PAINT in dedicated server, may improve performance (DF bug) +- Add `scope_sensitivity_modifier` and `scanner_sensitivity_modifier` commands Version 1.8.0 (released 2022-09-17) ----------------------------------- diff --git a/game_patch/input/mouse.cpp b/game_patch/input/mouse.cpp index 7e337f73..8874ecb9 100644 --- a/game_patch/input/mouse.cpp +++ b/game_patch/input/mouse.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -111,6 +112,70 @@ ConsoleCommand2 ms_cmd{ "ms ", }; +float scope_sensitivity_factor = 1.0f; +float scanner_sensitivity_factor = 1.0f; + +constexpr float clamp_sensitivity_modifier(float modifier) +{ + constexpr const float min = 0.01f; // prevent division by zero in scope sens + constexpr const float max = 4.0f; + return std::clamp(modifier, min, max); +} + +void patch_scope_and_scanner_sensitivity() +{ + AsmWriter{0x004309B1}.fmul(AsmRegMem{&scope_sensitivity_factor}); + AsmWriter{0x004309DE}.fmul(AsmRegMem{&scanner_sensitivity_factor}); +} + +void update_scope_sensitivity() +{ + float modifier = clamp_sensitivity_modifier(g_game_config.scope_sensitivity_modifier); + scope_sensitivity_factor = rf::scope_sensitivity_constant * (1.0f / modifier); +} + +void update_scanner_sensitivity() +{ + float modifier = clamp_sensitivity_modifier(g_game_config.scanner_sensitivity_modifier); + scanner_sensitivity_factor = rf::scanner_sensitivity_constant * modifier; +} + +ConsoleCommand2 scope_sens_cmd{ + "scope_sensitivity_modifier", + [](std::optional value_opt) { + if (value_opt) { + g_game_config.scope_sensitivity_modifier = value_opt.value(); + g_game_config.save(); + update_scope_sensitivity(); + } + else { + rf::console::print("Scope sensitivity modifier: {:.2f}", + static_cast(clamp_sensitivity_modifier(g_game_config.scope_sensitivity_modifier))); + } + + }, + "Sets mouse sensitivity modifier used while scoped in.", + "scope_sensitivity_modifier (valid range: 0.01 - 4.00)", +}; + +ConsoleCommand2 scanner_sens_cmd{ + "scanner_sensitivity_modifier", + [](std::optional value_opt) { + if (value_opt) { + g_game_config.scanner_sensitivity_modifier = value_opt.value(); + g_game_config.save(); + update_scanner_sensitivity(); + } + else { + rf::console::print( + "Scanner sensitivity modifier: {:.2f}", + static_cast(clamp_sensitivity_modifier(g_game_config.scanner_sensitivity_modifier))); + } + }, + "Sets mouse sensitivity modifier used while in a rail scanner.", + "scanner_sensitivity_modifier (valid range: 0.01 - 4.00)", +}; + rf::Vector3 fw_vector_from_non_linear_yaw_pitch(float yaw, float pitch) { // Based on RF code @@ -242,6 +307,11 @@ ConsoleCommand2 linear_pitch_cmd{ void mouse_apply_patch() { + // Scale zoomed sensitivity + patch_scope_and_scanner_sensitivity(); + update_scope_sensitivity(); + update_scanner_sensitivity(); + // Disable mouse when window is not active mouse_eval_deltas_hook.install(); @@ -262,5 +332,7 @@ void mouse_apply_patch() // Commands input_mode_cmd.register_cmd(); ms_cmd.register_cmd(); + scope_sens_cmd.register_cmd(); + scanner_sens_cmd.register_cmd(); linear_pitch_cmd.register_cmd(); } diff --git a/game_patch/rf/input.h b/game_patch/rf/input.h index 171e8817..2c34b6fb 100644 --- a/game_patch/rf/input.h +++ b/game_patch/rf/input.h @@ -122,6 +122,8 @@ namespace rf static auto& mouse_set_visible = addr_as_ref(0x0051E680); static auto& key_process_event = addr_as_ref(0x0051E6C0); + static auto& scope_sensitivity_constant = addr_as_ref(0x005895C0); + static auto& scanner_sensitivity_constant = addr_as_ref(0x005893D4); static auto& mouse_initialized = addr_as_ref(0x01885461); static auto& direct_input_disabled = addr_as_ref(0x005A4F88); static auto& di_mouse = addr_as_ref(0x0188545C);