diff options
author | FeralChild64 <unknown> | 2022-10-09 20:48:47 +0300 |
---|---|---|
committer | kcgen <1557255+kcgen@users.noreply.github.com> | 2022-10-22 21:15:34 +0300 |
commit | cf4c2381f347715dd3130c39bc2c3b69e20797a4 (patch) | |
tree | 18ccc0f95b8c208232fec1f54e2bb91888911139 /src | |
parent | 5982bf5fbc3e38c6c0fb915da5b782a730b3ae0d (diff) |
Handle code review remarks
Diffstat (limited to 'src')
-rw-r--r-- | src/dos/program_mousectl.cpp | 71 | ||||
-rw-r--r-- | src/dos/program_mousectl.h | 9 | ||||
-rw-r--r-- | src/gui/sdlmain.cpp | 79 | ||||
-rw-r--r-- | src/hardware/mouse/mouse.cpp | 83 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_config.cpp | 74 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_config.h | 28 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_interfaces.cpp | 53 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_interfaces.h | 14 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_manymouse.cpp | 20 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_manymouse.h | 4 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_queue.h | 2 | ||||
-rw-r--r-- | src/hardware/mouse/mouseif_dos_driver.cpp | 8 |
12 files changed, 288 insertions, 157 deletions
diff --git a/src/dos/program_mousectl.cpp b/src/dos/program_mousectl.cpp index 073718edf..67fc0e993 100644 --- a/src/dos/program_mousectl.cpp +++ b/src/dos/program_mousectl.cpp @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: GPL-2.0-or-later * - * Copyright (C) 2021-2022 The DOSBox Staging Team + * Copyright (C) 2022 The DOSBox Staging Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ #include "ansi_code_markup.h" #include "checks.h" +#include "video.h" #include <set> @@ -45,7 +46,7 @@ bool MOUSECTL::ParseAndRun() std::vector<std::string> params; cmd->FillVector(params); - // Extract the list of interfaces from teh vector + // Extract the list of interfaces from the vector std::vector<MouseInterfaceId> list_ids; if (!ParseInterfaces(params, list_ids) || !CheckInterfaces(list_ids)) return false; @@ -100,16 +101,16 @@ bool MOUSECTL::ParseAndRun() return CmdMinRate(list_ids, params[1]); const auto value = std::atoi(params[1].c_str()); - if (value < 1 || value > 99) { + if (value < -99 || value > 99) { WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_SENSITIVITY")); return false; } if (param_equal(0, "-s")) - return CmdSensitivity(list_ids, static_cast<uint8_t>(value)); + return CmdSensitivity(list_ids, static_cast<int8_t>(value)); if (param_equal(0, "-sx")) - return CmdSensitivityX(list_ids, static_cast<uint8_t>(value)); + return CmdSensitivityX(list_ids, static_cast<int8_t>(value)); if (param_equal(0, "-sy")) - return CmdSensitivityY(list_ids, static_cast<uint8_t>(value)); + return CmdSensitivityY(list_ids, static_cast<int8_t>(value)); } WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX")); @@ -216,6 +217,7 @@ bool MOUSECTL::CmdShow(const bool show_all) // Display emulated interface list WriteOut("\n"); WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HEADER1")); + WriteOut("\n"); for (const auto &entry : info_interfaces) { if (!entry.IsEmulated()) continue; @@ -272,6 +274,7 @@ bool MOUSECTL::CmdShow(const bool show_all) if (hint) WriteOut("\n"); WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HEADER2")); + WriteOut("\n"); // Display physical mice mapped to some interface for (const auto &entry : info_interfaces) { @@ -299,6 +302,15 @@ bool MOUSECTL::CmdShow(const bool show_all) return true; } +void MOUSECTL::FinalizeMapping() +{ + WriteOut("\n"); + WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_HINT")); + WriteOut("\n\n"); + + GFX_MouseCaptureAfterMapping(); +} + bool MOUSECTL::CmdMap(const MouseInterfaceId interface_id, const std::string &pattern) { @@ -308,12 +320,18 @@ bool MOUSECTL::CmdMap(const MouseInterfaceId interface_id, return false; } + if (MouseConfigAPI::IsNoMouseMode()) { + WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE")); + return false; + } + MouseConfigAPI mouse_config_api; if (!mouse_config_api.Map(interface_id, regex)) { WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_MATCH")); return false; } + FinalizeMapping(); return true; } @@ -321,6 +339,11 @@ bool MOUSECTL::CmdMap(const std::vector<MouseInterfaceId> &list_ids) { assert(list_ids.size() >= 1); + if (MouseConfigAPI::IsNoMouseMode()) { + WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE")); + return false; + } + MouseConfigAPI mouse_config_api; const auto info_physical = mouse_config_api.GetInfoPhysical(); @@ -356,8 +379,8 @@ bool MOUSECTL::CmdMap(const std::vector<MouseInterfaceId> &list_ids) WriteOut("\n"); mouse_config_api.Map(interface_id, device_id); } - WriteOut("\n"); + FinalizeMapping(); return true; } @@ -384,7 +407,7 @@ bool MOUSECTL::CmdReset(const std::vector<MouseInterfaceId> &list_ids) } bool MOUSECTL::CmdSensitivity(const std::vector<MouseInterfaceId> &list_ids, - const uint8_t value) + const int8_t value) { MouseConfigAPI mouse_config_api; mouse_config_api.SetSensitivity(list_ids, value, value); @@ -392,7 +415,7 @@ bool MOUSECTL::CmdSensitivity(const std::vector<MouseInterfaceId> &list_ids, } bool MOUSECTL::CmdSensitivityX(const std::vector<MouseInterfaceId> &list_ids, - const uint8_t value) + const int8_t value) { MouseConfigAPI mouse_config_api; mouse_config_api.SetSensitivityX(list_ids, value); @@ -400,7 +423,7 @@ bool MOUSECTL::CmdSensitivityX(const std::vector<MouseInterfaceId> &list_ids, } bool MOUSECTL::CmdSensitivityY(const std::vector<MouseInterfaceId> &list_ids, - const uint8_t value) + const int8_t value) { MouseConfigAPI mouse_config_api; mouse_config_api.SetSensitivityY(list_ids, value); @@ -476,7 +499,7 @@ void MOUSECTL::AddMessages() "Where:\n" " [color=white]INTERFACE[reset] one of [color=white]DOS[reset], [color=white]PS/2[reset], [color=white]COM1[reset], [color=white]COM2[reset], [color=white]COM3[reset], [color=white]COM4[reset]\n" " -map -unmap maps/unmaps physical mouse, honors DOS wildcards in name\n" - " -s -sx -sy sets sensitivity / for x axis / for y axis, value is 1-99\n" + " -s -sx -sy sets sensitivity / for x axis / for y axis, from -99 to +99\n" " -r sets minimum mouse sampling rate\n" " -on -off enables or disables mouse on the given interface\n" " -reset restores all mouse settings from the configuration file\n" @@ -488,21 +511,22 @@ void MOUSECTL::AddMessages() "Examples:\n" " [color=green]mousectl[reset] [color=white]DOS[reset] [color=white]COM1[reset] -map ; asks user to select mice for a two player game"); - MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX", "Wrong command syntax"); - MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_PATTERN", "Wrong syntax, only ASCII characters allowed in pattern"); - MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_SENSITIVITY", "Wrong syntax, sensitivity needs to be in 1-99 range"); - MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_DUPLICATED", "Wrong syntax, duplicated mouse interfaces"); + MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX", "Wrong command syntax."); + MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_PATTERN", "Wrong syntax, only ASCII characters allowed in pattern."); + MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_SENSITIVITY", "Wrong syntax, sensitivity needs to be in -99 to +99 range."); + MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_DUPLICATED", "Wrong syntax, duplicated mouse interfaces."); MSG_Add("SHELL_CMD_MOUSECTL_SYNTAX_MIN_RATE", "Wrong syntax, sampling rate has to be one of:\n%s"); - MSG_Add("SHELL_CMD_MOUSECTL_NO_INTERFACES", "No mouse interfaces available"); - MSG_Add("SHELL_CMD_MOUSECTL_MISSING_INTERFACES", "Mouse interface not available"); - MSG_Add("SHELL_CMD_MOUSECTL_NO_PHYSICAL_MICE", "No physical mice detected"); - MSG_Add("SHELL_CMD_MOUSECTL_NO_MATCH", "No available mouse matching the pattern found"); + MSG_Add("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE", "Mapping not available in NoMouse mode."); + MSG_Add("SHELL_CMD_MOUSECTL_NO_INTERFACES", "No mouse interfaces available."); + MSG_Add("SHELL_CMD_MOUSECTL_MISSING_INTERFACES", "Mouse interface not available."); + MSG_Add("SHELL_CMD_MOUSECTL_NO_PHYSICAL_MICE", "No physical mice detected."); + MSG_Add("SHELL_CMD_MOUSECTL_NO_MATCH", "No available mouse matching the pattern found."); - MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HEADER1", "[color=white]Interface Sensitivity Rate (Hz) Status[reset]\n"); - MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT1", "[color=cyan]%-4s[reset] X:%02d Y:%02d %1s %3s %s"); + MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HEADER1", "[color=white]Interface Sensitivity Rate (Hz) Status[reset]"); + MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT1", "[color=cyan]%-4s[reset] X:%+.2d Y:%+.2d %1s %3s %s"); - MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HEADER2", "[color=white]Interface Mouse Name[reset]\n"); + MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HEADER2", "[color=white]Interface Mouse Name[reset]"); MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2", "[color=cyan]%-4s[reset] %s"); MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2_UNMAPPED", "not mapped %s"); @@ -519,4 +543,7 @@ void MOUSECTL::AddMessages() "any other button cancels the mapping and assigns system pointer to all the\n" "mouse interfaces."); MSG_Add("SHELL_CMD_MOUSECTL_MAP_CANCEL", "(mapping cancelled)"); + MSG_Add("SHELL_CMD_MOUSECTL_MAP_HINT", + "Mouse captured. Seamless mouse integration is always disabled while mapping is\n" + "in effect and mapped mice always receive raw input events."); } diff --git a/src/dos/program_mousectl.h b/src/dos/program_mousectl.h index f744de9cb..b0dbf273b 100644 --- a/src/dos/program_mousectl.h +++ b/src/dos/program_mousectl.h @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: GPL-2.0-or-later * - * Copyright (C) 2020-2022 The DOSBox Staging Team + * Copyright (C) 2022 The DOSBox Staging Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +44,7 @@ private: bool ParseInterfaces(std::vector<std::string> ¶ms, std::vector<MouseInterfaceId> &list_ids); bool CheckInterfaces(const std::vector<MouseInterfaceId> &list_ids); + void FinalizeMapping(); const char *GetInterfaceStr(const MouseInterfaceId interface_id) const; const char *GetMapStatusStr(const MouseMapStatus map_status) const; @@ -57,11 +58,11 @@ private: const bool enable); bool CmdReset(const std::vector<MouseInterfaceId> &list_ids); bool CmdSensitivity(const std::vector<MouseInterfaceId> &list_ids, - const uint8_t value); + const int8_t value); bool CmdSensitivityX(const std::vector<MouseInterfaceId> &list_ids, - const uint8_t value); + const int8_t value); bool CmdSensitivityY(const std::vector<MouseInterfaceId> &list_ids, - const uint8_t value); + const int8_t value); bool CmdSensitivity(const std::vector<MouseInterfaceId> &list_ids); bool CmdSensitivityX(const std::vector<MouseInterfaceId> &list_ids); bool CmdSensitivityY(const std::vector<MouseInterfaceId> &list_ids); diff --git a/src/gui/sdlmain.cpp b/src/gui/sdlmain.cpp index 25a7def26..6ef1c74c6 100644 --- a/src/gui/sdlmain.cpp +++ b/src/gui/sdlmain.cpp @@ -2173,6 +2173,14 @@ bool GFX_MouseIsAvailable() { return sdl.mouse.control_choice != NoMouse; } +void GFX_SetMouseRawInput(const bool raw_input) +{ + if (!SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, + raw_input ? "0" : "1", + SDL_HINT_OVERRIDE)) + LOG_WARNING("DISPLAY: Mouse raw input set failed"); +} + void GFX_ToggleMouseCapture() { /* @@ -2204,6 +2212,18 @@ static void toggle_mouse_capture_from_user(bool pressed) GFX_ToggleMouseCapture(); } +void GFX_MouseCaptureAfterMapping() +{ + if (sdl.desktop.fullscreen || + !sdl.mouse.has_focus || + mouse_is_captured) + return; + + mouse_capture_requested = true; + GFX_ToggleMouseCapture(); +} + + static void FocusInput() { // Ensure auto-cycles are enabled @@ -2258,7 +2278,7 @@ void GFX_UpdateMouseState() // it's auto-captured (but not manually requested) and // in seamless-mode } else if (!sdl.desktop.fullscreen && mouse_is_captured && - (mouse_seamless_driver || (!mouse_capture_requested && sdl.mouse.control_choice == Seamless))) { + (mouse_seamless_driver || (!mouse_capture_requested && mouse_seamless_user))) { GFX_ToggleMouseCapture(); SDL_ShowCursor(SDL_DISABLE); @@ -3552,10 +3572,11 @@ static void GUI_StartUp(Section *sec) } else if (control_choice == "nomouse") { sdl.mouse.control_choice = NoMouse; mouse_control_msg = "is disabled"; - MOUSE_SetNoMouse(); + MOUSE_SetConfigNoMouse(); } else { assert(sdl.mouse.control_choice == CaptureOnClick); } + LOG_MSG("SDL: Mouse %s", mouse_control_msg.c_str()); if (sdl.mouse.control_choice != NoMouse) { @@ -3574,19 +3595,8 @@ static void GUI_StartUp(Section *sec) MAPPER_AddHandler(toggle_mouse_capture_from_user, SDL_SCANCODE_F10, PRIMARY_MOD, "capmouse", "Cap Mouse"); - // Apply the user's mouse sensitivity settings - PropMultiVal *p3 = section->GetMultiVal("sensitivity"); - const auto sensitivity_x = static_cast<float>(p3->GetSection()->Get_int("xsens")) / 100.0f; - const auto sensitivity_y = static_cast<float>(p3->GetSection()->Get_int("ysens")) / 100.0f; - - // Apply raw mouse input setting - const auto raw_mouse_input = section->Get_bool("raw_mouse_input"); - SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, - raw_mouse_input ? "0" : "1", - SDL_HINT_OVERRIDE); - // Notify mouse emulation routines about the configuration - MOUSE_SetConfig(raw_mouse_input, sensitivity_x, sensitivity_y); + MOUSE_SetConfigSeamless(sdl.mouse.control_choice == Seamless); } /* Get some Event handlers */ @@ -3615,12 +3625,10 @@ static void GUI_StartUp(Section *sec) static void HandleMouseMotion(SDL_MouseMotionEvent *motion) { - if (mouse_seamless_driver || mouse_is_captured || - sdl.mouse.control_choice == Seamless) - MOUSE_EventMoved(static_cast<float>(motion->xrel), - static_cast<float>(motion->yrel), - std::clamp(motion->x, 0, static_cast<int>(UINT16_MAX)), - std::clamp(motion->y, 0, static_cast<int>(UINT16_MAX))); + MOUSE_EventMoved(static_cast<float>(motion->xrel), + static_cast<float>(motion->yrel), + std::clamp(motion->x, 0, static_cast<int>(UINT16_MAX)), + std::clamp(motion->y, 0, static_cast<int>(UINT16_MAX))); } static void HandleMouseWheel(SDL_MouseWheelEvent *wheel) @@ -3631,6 +3639,9 @@ static void HandleMouseWheel(SDL_MouseWheelEvent *wheel) static void HandleMouseButton(SDL_MouseButtonEvent * button) { + constexpr auto state_released = false; + constexpr auto state_pressed = true; + auto notify_button = [](const uint8_t button, const bool pressed) { switch (button) { case SDL_BUTTON_LEFT: MOUSE_EventButton(0, pressed); break; @@ -3640,16 +3651,16 @@ static void HandleMouseButton(SDL_MouseButtonEvent * button) case SDL_BUTTON_X2: MOUSE_EventButton(4, pressed); break; } }; - + if (button->state == SDL_RELEASED) { - notify_button(button->button, false); + notify_button(button->button, state_released); return; } - + assert(button->state == SDL_PRESSED); - + if (sdl.desktop.fullscreen || mouse_seamless_driver) { - notify_button(button->button, true); + notify_button(button->button, state_pressed); return; } @@ -4302,20 +4313,10 @@ void Config_Add_SDL() { mouse_control_help += mouse_control_defaults; Pmulti->Set_help(mouse_control_help); - Pmulti = sdl_sec->AddMultiVal("sensitivity", always, ","); - Pmulti->Set_help("Mouse sensitivity. The optional second parameter specifies vertical sensitivity\n" - "(e.g. 100,-50)."); - Pmulti->SetValue("100"); - Pint = Pmulti->GetSection()->Add_int("xsens", always,100); - Pint->SetMinMax(-1000,1000); - Pint = Pmulti->GetSection()->Add_int("ysens", always,100); - Pint->SetMinMax(-1000,1000); - - pbool = sdl_sec->Add_bool("raw_mouse_input", on_start, false); - pbool->Set_help( - "Enable this setting to bypass your operating system's mouse\n" - "acceleration and sensitivity settings. This works in\n" - "fullscreen or when the mouse is captured in window mode."); + Pmulti = sdl_sec->AddMultiVal("sensitivity", deprecated, ","); + Pmulti->Set_help("Moved [mouse] section; see documentation as values have different meaning now."); + pbool = sdl_sec->Add_bool("raw_mouse_input", deprecated, false); + pbool->Set_help("Moved to [mouse] section."); Pbool = sdl_sec->Add_bool("waitonerror", always, true); Pbool->Set_help("Keep the console open if an error has occurred."); diff --git a/src/hardware/mouse/mouse.cpp b/src/hardware/mouse/mouse.cpp index 765102d69..1f7b4ea68 100644 --- a/src/hardware/mouse/mouse.cpp +++ b/src/hardware/mouse/mouse.cpp @@ -38,6 +38,7 @@ CHECK_NARROWING(); bool mouse_seamless_driver = false; +bool mouse_seamless_user = false; static Bitu int74_ret_callback = 0; @@ -143,13 +144,29 @@ void MOUSE_NotifyResetDOS() void MOUSE_NotifyStateChanged() { - const auto old_seamless_driver = mouse_seamless_driver; + const auto old_seamless_driver = mouse_seamless_driver; + const auto old_seamless_user = mouse_seamless_user; - // Prepare suggestions to the GUI - mouse_seamless_driver = mouse_shared.active_vmm && !mouse_video.fullscreen; + const auto is_mapping_in_effect = manymouse.IsMappingInEffect(); - // If state has really changed, update the GUI - if (mouse_seamless_driver != old_seamless_driver) + static bool already_warned = false; + if (!already_warned && is_mapping_in_effect && + (mouse_shared.active_vmm || mouse_config.seamless)) { + LOG_WARNING("MOUSE: Mapping disables seamless pointer integration"); + already_warned = true; + } + + // Prepare suggestions to the GFX subsystem + mouse_seamless_driver = mouse_shared.active_vmm && + !mouse_video.fullscreen && + !is_mapping_in_effect; + mouse_seamless_user = mouse_config.seamless && + !mouse_video.fullscreen && + !is_mapping_in_effect; + + // If state has really changed, update GFX subsystem + if (mouse_seamless_driver != old_seamless_driver || + mouse_seamless_user != old_seamless_user) GFX_UpdateMouseState(); } @@ -183,6 +200,12 @@ void MOUSE_EventMoved(const float x_rel, const uint16_t x_abs, const uint16_t y_abs) { + // Drop unneeded events + if (!mouse_is_captured && + !mouse_seamless_user && + !mouse_seamless_driver) + return; + // From the GUI we are getting mouse movement data in two // distinct formats: // @@ -297,6 +320,12 @@ MouseConfigAPI::MouseConfigAPI() MouseConfigAPI::~MouseConfigAPI() { manymouse.StopConfigAPI(); + MOUSE_NotifyStateChanged(); +} + +bool MouseConfigAPI::IsNoMouseMode() +{ + return mouse_config.no_mouse; } const std::vector<MouseInterfaceInfoEntry> &MouseConfigAPI::GetInfoInterfaces() const @@ -354,6 +383,9 @@ bool MouseConfigAPI::PatternToRegex(const std::string &pattern, bool MouseConfigAPI::ProbeForMapping(uint8_t &device_id) { + if (mouse_config.no_mouse) + return false; + manymouse.RescanIfSafe(); return manymouse.ProbeForMapping(device_id); } @@ -361,6 +393,9 @@ bool MouseConfigAPI::ProbeForMapping(uint8_t &device_id) bool MouseConfigAPI::Map(const MouseInterfaceId interface_id, const uint8_t device_idx) { + if (mouse_config.no_mouse) + return false; + auto mouse_interface = MouseInterface::Get(interface_id); if (!mouse_interface) return false; @@ -371,6 +406,9 @@ bool MouseConfigAPI::Map(const MouseInterfaceId interface_id, bool MouseConfigAPI::Map(const MouseInterfaceId interface_id, const std::regex ®ex) { + if (mouse_config.no_mouse) + return false; + manymouse.RescanIfSafe(); const auto idx = manymouse.GetIdx(regex); if (idx >= mouse_info.physical.size()) @@ -414,11 +452,13 @@ bool MouseConfigAPI::Reset(const MouseConfigAPI::ListIDs &list_ids) } bool MouseConfigAPI::SetSensitivity(const MouseConfigAPI::ListIDs &list_ids, - const uint8_t sensitivity_x, - const uint8_t sensitivity_y) + const int8_t sensitivity_x, + const int8_t sensitivity_y) { - if (!sensitivity_x || sensitivity_x > mouse_predefined.sensitivity_user_max || - !sensitivity_y || sensitivity_y > mouse_predefined.sensitivity_user_max) + if (sensitivity_x > mouse_predefined.sensitivity_user_max || + sensitivity_x < -mouse_predefined.sensitivity_user_max || + sensitivity_y > mouse_predefined.sensitivity_user_max || + sensitivity_y < -mouse_predefined.sensitivity_user_max) return false; std::vector<MouseInterface *> list; @@ -431,9 +471,10 @@ bool MouseConfigAPI::SetSensitivity(const MouseConfigAPI::ListIDs &list_ids, } bool MouseConfigAPI::SetSensitivityX(const MouseConfigAPI::ListIDs &list_ids, - const uint8_t sensitivity_x) + const int8_t sensitivity_x) { - if (!sensitivity_x || sensitivity_x > mouse_predefined.sensitivity_user_max) + if (sensitivity_x > mouse_predefined.sensitivity_user_max || + sensitivity_x < -mouse_predefined.sensitivity_user_max) return false; std::vector<MouseInterface *> list; @@ -446,9 +487,10 @@ bool MouseConfigAPI::SetSensitivityX(const MouseConfigAPI::ListIDs &list_ids, } bool MouseConfigAPI::SetSensitivityY(const MouseConfigAPI::ListIDs &list_ids, - const uint8_t sensitivity_y) + const int8_t sensitivity_y) { - if (!sensitivity_y || sensitivity_y > mouse_predefined.sensitivity_user_max) + if (sensitivity_y > mouse_predefined.sensitivity_user_max || + sensitivity_y < -mouse_predefined.sensitivity_user_max) return false; std::vector<MouseInterface *> list; @@ -549,14 +591,11 @@ bool MouseConfigAPI::ResetMinRate(const MouseConfigAPI::ListIDs &list_ids) // Initialization // *************************************************************************** -void MOUSE_SetConfig(const bool raw_input, - const float sensitivity_x, - const float sensitivity_y) +void MOUSE_SetConfigSeamless(const bool seamless) { // Called during SDL initialization - mouse_config.raw_input = raw_input; - mouse_config.sensitivity_gui_x = sensitivity_x; - mouse_config.sensitivity_gui_y = sensitivity_y; + mouse_config.seamless = seamless; + MOUSE_NotifyStateChanged(); // Just in case it is also called later for (auto &interface : mouse_interfaces) @@ -567,12 +606,16 @@ void MOUSE_SetConfig(const bool raw_input, MOUSE_Startup(); } -void MOUSE_SetNoMouse() +void MOUSE_SetConfigNoMouse() { // NOTE: if it is decided to not allow enabling/disabling // this during runtime, add button click releases for all // the mouse buttons mouse_config.no_mouse = true; + + // Start mouse emulation if ready + mouse_shared.ready_config_sdl = true; + MOUSE_Startup(); } void MOUSE_Startup() diff --git a/src/hardware/mouse/mouse_config.cpp b/src/hardware/mouse/mouse_config.cpp index 893f91d78..87efb66b2 100644 --- a/src/hardware/mouse/mouse_config.cpp +++ b/src/hardware/mouse/mouse_config.cpp @@ -24,6 +24,7 @@ #include "control.h" #include "setup.h" #include "support.h" +#include "video.h" CHECK_NARROWING(); @@ -132,19 +133,32 @@ static void config_read(Section *section) if (!conf) return; - // Config - settings changeable during runtime + // Settings changeable during runtime - mouse_config.mouse_dos_immediate = conf->Get_bool("mouse_dos_immediate"); - if (mouse_shared.ready_config_mouse) + mouse_config.dos_immediate = conf->Get_bool("dos_mouse_immediate"); + mouse_config.raw_input = conf->Get_bool("mouse_raw_input"); + GFX_SetMouseRawInput(mouse_config.raw_input); + + // Settings below should be read only once + + if (mouse_shared.ready_config_mouse) { + MOUSE_NotifyStateChanged(); return; + } + + // Default mouse sensitivity - // Config - DOS driver + PropMultiVal *prop_multi = conf->GetMultiVal("mouse_sensitivity"); + mouse_config.sensitivity_x = static_cast<int8_t>(prop_multi->GetSection()->Get_int("xsens")); + mouse_config.sensitivity_y = static_cast<int8_t>(prop_multi->GetSection()->Get_int("ysens")); - mouse_config.mouse_dos_enable = conf->Get_bool("mouse_dos"); + // DOS driver configuration - // Config - PS/2 AUX port + mouse_config.dos_driver = conf->Get_bool("dos_mouse_driver"); - std::string prop_str = conf->Get_string("model_ps2"); + // PS/2 AUX port mouse configuration + + std::string prop_str = conf->Get_string("ps2_mouse_model"); if (prop_str == list_models_ps2[0]) mouse_config.model_ps2 = MouseModelPS2::Standard; if (prop_str == list_models_ps2[1]) @@ -154,7 +168,7 @@ static void config_read(Section *section) mouse_config.model_ps2 = MouseModelPS2::Explorer; #endif - // Config - serial (COM port) mice + // Serial (COM port) mice configuration auto set_model_com = [](const std::string &model_str, MouseModelCOM& model_var, @@ -176,7 +190,7 @@ static void config_read(Section *section) model_auto = false; }; - prop_str = conf->Get_string("model_com"); + prop_str = conf->Get_string("com_mouse_model"); set_model_com(prop_str, mouse_config.model_com, mouse_config.model_com_auto_msm); @@ -191,19 +205,39 @@ static void config_init(Section_prop &secprop) constexpr auto always = Property::Changeable::Always; constexpr auto only_at_start = Property::Changeable::OnlyAtStart; - Prop_bool *prop_bool = nullptr; - Prop_string *prop_str = nullptr; + Prop_bool *prop_bool = nullptr; + Prop_int *prop_int = nullptr; + Prop_string *prop_str = nullptr; + PropMultiVal *prop_multi = nullptr; + + // General configuration + + prop_multi = secprop.AddMultiVal("mouse_sensitivity", only_at_start, ","); + prop_multi->Set_help("Default mouse sensitivity. Works exponentially, add 10 to double the effect.\n" + "Negative values reverse mouse direction, 0 disables the movement completely.\n" + "The optional second parameter specifies vertical sensitivity (e.g. 30,40).\n" + "Setting can be adjusted in runtime (also per mouse interface) using internal\n" + "MOUSECTL.COM tool, available on drive Z:."); + prop_multi->SetValue("50"); + prop_int = prop_multi->GetSection()->Add_int("xsens", only_at_start, 50); + prop_int->SetMinMax(-99, 99); + prop_int = prop_multi->GetSection()->Add_int("ysens", only_at_start, 50); + prop_int->SetMinMax(-99, 99); + + prop_bool = secprop.Add_bool("mouse_raw_input", always, true); + prop_bool->Set_help("Enable to bypass your operating system's mouse acceleration and sensitivity\n" + "settings. Works in fullscreen or when the mouse is captured in window mode."); - // Mouse enable/disable settings + // DOS driver configuration - prop_bool = secprop.Add_bool("mouse_dos", only_at_start, true); + prop_bool = secprop.Add_bool("dos_mouse_driver", only_at_start, true); assert(prop_bool); prop_bool->Set_help("Enable built-in DOS mouse driver.\n" "Notes:\n" " Disable if you intend to use original MOUSE.COM driver in emulated DOS.\n" " When guest OS is booted, built-in driver gets disabled automatically."); - prop_bool = secprop.Add_bool("mouse_dos_immediate", always, false); + prop_bool = secprop.Add_bool("dos_mouse_immediate", always, false); assert(prop_bool); prop_bool->Set_help("Updates mouse movement counters immediately, without waiting for interrupt.\n" "May improve gameplay, especially in fast paced games (arcade, FPS, etc.) - as\n" @@ -215,21 +249,21 @@ static void config_init(Section_prop &secprop) "Please file a bug with the project if you find another game that fails when\n" "this is enabled, we will update this list."); - // Mouse models + // Physical mice configuration - prop_str = secprop.Add_string("model_ps2", only_at_start, "intellimouse"); + prop_str = secprop.Add_string("ps2_mouse_model", only_at_start, "intellimouse"); assert(prop_str); prop_str->Set_values(list_models_ps2); prop_str->Set_help("PS/2 AUX port mouse model:\n" // TODO - Add option "none" - " standard: 3 buttons (standard PS/2 mouse).\n" - " intellimouse: 3 buttons + wheel (Microsoft IntelliMouse).\n" + " standard: 3 buttons, standard PS/2 mouse.\n" + " intellimouse: 3 buttons + wheel, Microsoft IntelliMouse.\n" #ifdef ENABLE_EXPLORER_MOUSE - " explorer: 5 buttons + wheel (Microsoft IntelliMouse Explorer).\n" + " explorer: 5 buttons + wheel, Microsoft IntelliMouse Explorer.\n" #endif "Default: intellimouse"); - prop_str = secprop.Add_string("model_com", only_at_start, "wheel+msm"); + prop_str = secprop.Add_string("com_mouse_model", only_at_start, "wheel+msm"); assert(prop_str); prop_str->Set_values(list_models_com); prop_str->Set_help("COM (serial) port default mouse model:\n" diff --git a/src/hardware/mouse/mouse_config.h b/src/hardware/mouse/mouse_config.h index 2edd19058..0d41cfc39 100644 --- a/src/hardware/mouse/mouse_config.h +++ b/src/hardware/mouse/mouse_config.h @@ -33,22 +33,22 @@ struct MousePredefined { // values so that on full screen, with RAW mouse input, the mouse feel // is similar to Windows 3.11 for Workgroups with PS/2 mouse driver // and default settings - const float sensitivity_dos = 1.0f; - const float sensitivity_ps2 = 1.0f; - const float sensitivity_vmm = 3.0f; - const float sensitivity_com = 1.0f; + const float sensitivity_dos = 0.6f; + const float sensitivity_ps2 = 0.6f; + const float sensitivity_vmm = 1.8f; + const float sensitivity_com = 0.6f; // Constants to move 'intersection point' for the acceleration curve // Requires raw mouse input, otherwise there is no effect // Larger values = higher mouse acceleration const float acceleration_dos = 1.0f; const float acceleration_vmm = 1.0f; - const uint8_t sensitivity_user_default = 50; - const uint8_t sensitivity_user_max = 99; + const int8_t sensitivity_user_max = 99; }; extern MousePredefined mouse_predefined; + // *************************************************************************** // Configuration file content // *************************************************************************** @@ -78,16 +78,17 @@ struct MouseConfig { // From [sdl] section - float sensitivity_gui_x = 0.0f; - float sensitivity_gui_y = 0.0f; - bool no_mouse = false; // true = NoMouse selected in GUI - bool raw_input = false; // true = relative input is raw data, without - // host OS mouse acceleration applied + bool no_mouse = false; // true = NoMouse selected in GUI + bool seamless = false; // true = seamless mouse integration // From [mouse] section - bool mouse_dos_enable = false; - bool mouse_dos_immediate = false; + int8_t sensitivity_x = 50; // default sensitivity values + int8_t sensitivity_y = 50; + bool raw_input = false; // true = relative input is raw data + + bool dos_driver = false; // whether DOS virtual mouse driver should be enabled + bool dos_immediate = false; MouseModelPS2 model_ps2 = MouseModelPS2::Standard; @@ -102,4 +103,5 @@ struct MouseConfig { extern MouseConfig mouse_config; + #endif // DOSBOX_MOUSE_CONFIG_H diff --git a/src/hardware/mouse/mouse_interfaces.cpp b/src/hardware/mouse/mouse_interfaces.cpp index 0da6f3eb1..067b4c6cf 100644 --- a/src/hardware/mouse/mouse_interfaces.cpp +++ b/src/hardware/mouse/mouse_interfaces.cpp @@ -93,12 +93,12 @@ const std::string &MouseInterfaceInfoEntry::GetMappedDeviceName() const return MappedPhysical().GetName(); } -uint8_t MouseInterfaceInfoEntry::GetSensitivityX() const +int8_t MouseInterfaceInfoEntry::GetSensitivityX() const { return Interface().GetSensitivityX(); } -uint8_t MouseInterfaceInfoEntry::GetSensitivityY() const +int8_t MouseInterfaceInfoEntry::GetSensitivityY() const { return Interface().GetSensitivityY(); } @@ -306,7 +306,7 @@ MouseInterface *MouseInterface::GetPS2() MouseInterface *MouseInterface::GetSerial(const uint8_t port_id) { - if (port_id < num_mouse_interfaces_com) { + if (port_id < SERIAL_MAX_PORTS) { const auto idx = static_cast<uint8_t>(MouseInterfaceId::COM1) + port_id; return MouseInterface::Get(static_cast<MouseInterfaceId>(idx)); } @@ -381,12 +381,12 @@ uint8_t MouseInterface::GetMappedDeviceIdx() const return mapped_idx; } -uint8_t MouseInterface::GetSensitivityX() const +int8_t MouseInterface::GetSensitivityX() const { return sensitivity_user_x; } -uint8_t MouseInterface::GetSensitivityY() const +int8_t MouseInterface::GetSensitivityY() const { return sensitivity_user_y; } @@ -474,8 +474,8 @@ void MouseInterface::ConfigReset() ConfigResetMinRate(); } -void MouseInterface::ConfigSetSensitivity(const uint8_t value_x, - const uint8_t value_y) +void MouseInterface::ConfigSetSensitivity(const int8_t value_x, + const int8_t value_y) { if (!IsEmulated()) return; @@ -485,7 +485,7 @@ void MouseInterface::ConfigSetSensitivity(const uint8_t value_x, UpdateSensitivity(); } -void MouseInterface::ConfigSetSensitivityX(const uint8_t value) +void MouseInterface::ConfigSetSensitivityX(const int8_t value) { if (!IsEmulated()) return; @@ -494,7 +494,7 @@ void MouseInterface::ConfigSetSensitivityX(const uint8_t value) UpdateSensitivity(); } -void MouseInterface::ConfigSetSensitivityY(const uint8_t value) +void MouseInterface::ConfigSetSensitivityY(const int8_t value) { if (!IsEmulated()) return; @@ -505,18 +505,18 @@ void MouseInterface::ConfigSetSensitivityY(const uint8_t value) void MouseInterface::ConfigResetSensitivity() { - ConfigSetSensitivity(mouse_predefined.sensitivity_user_default, - mouse_predefined.sensitivity_user_default); + ConfigSetSensitivity(mouse_config.sensitivity_x, + mouse_config.sensitivity_y); } void MouseInterface::ConfigResetSensitivityX() { - ConfigSetSensitivityX(mouse_predefined.sensitivity_user_default); + ConfigSetSensitivityX(mouse_config.sensitivity_x); } void MouseInterface::ConfigResetSensitivityY() { - ConfigSetSensitivityY(mouse_predefined.sensitivity_user_default); + ConfigSetSensitivityY(mouse_config.sensitivity_y); } void MouseInterface::ConfigSetMinRate(const uint16_t value_hz) @@ -552,7 +552,7 @@ void MouseInterface::UpdateRawMapped() void MouseInterface::UpdateSensitivity() { - auto calculate = [this](const uint8_t user_val) + auto calculate = [this](const int8_t user_val) { // Mouse sensitivity formula is exponential - as it is probably // reasonable to expect user wanting to increase sensitivity @@ -560,15 +560,26 @@ void MouseInterface::UpdateSensitivity() // 5.0 and 5.4 times sensitivity increase is rather hard to // notice in a real life - // Increase user_val by 20 steps = double the sensitivity - constexpr float double_steps = 20.0f; + // Increase user_val by 10 steps = double the sensitivity + constexpr float double_steps = 10.0f; - return sensitivity_predefined * - std::pow(2.0f, static_cast<float>(user_val - 50) / double_steps); + float power = 0.0f; + float scaling = 0.0f; + + if (user_val > 0) { + power = static_cast<float>(user_val - 50); + scaling = sensitivity_predefined; + } else if (user_val < 0) { + power = static_cast<float>(-user_val - 50); + scaling = -sensitivity_predefined; + } else // user_cal == 0 + return 0.0f; + + return scaling * std::pow(2.0f, power / double_steps); }; - sensitivity_coeff_x = calculate(sensitivity_user_x) * mouse_config.sensitivity_gui_x; - sensitivity_coeff_y = calculate(sensitivity_user_y) * mouse_config.sensitivity_gui_y; + sensitivity_coeff_x = calculate(sensitivity_user_x); + sensitivity_coeff_y = calculate(sensitivity_user_y); } void MouseInterface::UpdateMinRate() @@ -661,7 +672,7 @@ InterfaceDos::InterfaceDos() : void InterfaceDos::Init() { - if (mouse_config.mouse_dos_enable) + if (mouse_config.dos_driver) MOUSEDOS_Init(); else emulated = false; diff --git a/src/hardware/mouse/mouse_interfaces.h b/src/hardware/mouse/mouse_interfaces.h index 6ddcb113e..dec05244e 100644 --- a/src/hardware/mouse/mouse_interfaces.h +++ b/src/hardware/mouse/mouse_interfaces.h @@ -154,8 +154,8 @@ public: MouseInterfaceId GetInterfaceId() const; MouseMapStatus GetMapStatus() const; uint8_t GetMappedDeviceIdx() const; - uint8_t GetSensitivityX() const; - uint8_t GetSensitivityY() const; + int8_t GetSensitivityX() const; + int8_t GetSensitivityY() const; uint16_t GetMinRate() const; uint16_t GetRate() const; @@ -164,9 +164,9 @@ public: void ConfigOnOff(const bool enable); void ConfigReset(); - void ConfigSetSensitivity(const uint8_t value_x, const uint8_t value_y); - void ConfigSetSensitivityX(const uint8_t value); - void ConfigSetSensitivityY(const uint8_t value); + void ConfigSetSensitivity(const int8_t value_x, const int8_t value_y); + void ConfigSetSensitivityX(const int8_t value); + void ConfigSetSensitivityY(const int8_t value); void ConfigResetSensitivity(); void ConfigResetSensitivityX(); void ConfigResetSensitivityY(); @@ -209,8 +209,8 @@ protected: float sensitivity_coeff_x = 1.0f; // cached combined sensitivity coefficients float sensitivity_coeff_y = 1.0f; // to reduce amount of multiplications - uint8_t sensitivity_user_x = 0; - uint8_t sensitivity_user_y = 0; + int8_t sensitivity_user_x = 0; + int8_t sensitivity_user_y = 0; uint16_t rate_hz = 0; uint16_t min_rate_hz = 0; diff --git a/src/hardware/mouse/mouse_manymouse.cpp b/src/hardware/mouse/mouse_manymouse.cpp index f8e798d85..cc71216e1 100644 --- a/src/hardware/mouse/mouse_manymouse.cpp +++ b/src/hardware/mouse/mouse_manymouse.cpp @@ -105,7 +105,7 @@ void ManyMouseGlue::InitIfNeeded() void ManyMouseGlue::ShutdownIfSafe() { - if (mapping_in_effect || config_api_counter) + if (is_mapping_in_effect || config_api_counter) return; ShutdownForced(); @@ -260,7 +260,7 @@ bool ManyMouseGlue::ProbeForMapping(uint8_t &device_id) break; } - if (mapping_in_effect && !mouse_config.no_mouse) + if (is_mapping_in_effect && !mouse_config.no_mouse) PIC_AddEvent(manymouse_tick, tick_interval); return success; } @@ -318,18 +318,23 @@ void ManyMouseGlue::UnMap(const MouseInterfaceId interface_id) void ManyMouseGlue::MapFinalize() { PIC_RemoveEvents(manymouse_tick); - mapping_in_effect = false; + is_mapping_in_effect = false; for (const auto &entry : mouse_info.physical) { if (entry.IsMapped()) continue; - mapping_in_effect = true; + is_mapping_in_effect = true; if (!mouse_config.no_mouse) PIC_AddEvent(manymouse_tick, tick_interval); break; } } +bool ManyMouseGlue::IsMappingInEffect() const +{ + return is_mapping_in_effect; +} + void ManyMouseGlue::HandleEvent(const ManyMouseEvent &event, const bool critical_only) { @@ -420,7 +425,7 @@ void ManyMouseGlue::Tick() rel_y[idx] = 0; } - if (mapping_in_effect) + if (is_mapping_in_effect) PIC_AddEvent(manymouse_tick, tick_interval); } @@ -463,4 +468,9 @@ void ManyMouseGlue::Map(const uint8_t, const MouseInterfaceId) { } +bool ManyMouseGlue::IsMappingInEffect() const +{ + return false; +} + #endif // C_MANYMOUSE diff --git a/src/hardware/mouse/mouse_manymouse.h b/src/hardware/mouse/mouse_manymouse.h index 94d3088b5..d8cb9b65f 100644 --- a/src/hardware/mouse/mouse_manymouse.h +++ b/src/hardware/mouse/mouse_manymouse.h @@ -65,6 +65,8 @@ public: void Map(const uint8_t physical_idx, const MouseInterfaceId interface_id); + bool IsMappingInEffect() const; + private: friend class MouseInterfaceInfoEntry; @@ -93,7 +95,7 @@ private: bool initialized = false; bool malfunction = false; // once set to false, will stay false forever - bool mapping_in_effect = false; + bool is_mapping_in_effect = false; bool rescan_blocked_config = false; // true = rescan blocked due to config API usage uint32_t config_api_counter = 0; diff --git a/src/hardware/mouse/mouse_queue.h b/src/hardware/mouse/mouse_queue.h index f2ffdefd4..7286b0826 100644 --- a/src/hardware/mouse/mouse_queue.h +++ b/src/hardware/mouse/mouse_queue.h @@ -49,7 +49,7 @@ private: void UpdateDelayCounters(); uint8_t ClampStartDelay(float value_ms) const; - struct { // intial value of delay counters, in milliseconds + struct { // initial value of delay counters, in milliseconds uint8_t dos_ms = 5; uint8_t ps2_ms = 5; } start_delay = {}; diff --git a/src/hardware/mouse/mouseif_dos_driver.cpp b/src/hardware/mouse/mouseif_dos_driver.cpp index 277d1d0c3..31ac9e361 100644 --- a/src/hardware/mouse/mouseif_dos_driver.cpp +++ b/src/hardware/mouse/mouseif_dos_driver.cpp @@ -992,7 +992,7 @@ static uint8_t move_cursor() uint8_t MOUSEDOS_UpdateMoved() { - if (mouse_config.mouse_dos_immediate) + if (mouse_config.dos_immediate) return static_cast<uint8_t>(MouseEventId::MouseHasMoved); else return move_cursor(); @@ -1062,7 +1062,7 @@ static uint8_t move_wheel() uint8_t MOUSEDOS_UpdateWheel() { - if (mouse_config.mouse_dos_immediate) + if (mouse_config.dos_immediate) return static_cast<uint8_t>(MouseEventId::WheelHasMoved); else return move_wheel(); @@ -1106,7 +1106,7 @@ bool MOUSEDOS_NotifyMoved(const float x_rel, if (!event_needed) return 0; - if (mouse_config.mouse_dos_immediate) + if (mouse_config.dos_immediate) return (move_cursor() != 0); else return true; @@ -1126,7 +1126,7 @@ bool MOUSEDOS_NotifyWheel(const int16_t w_rel) if (pending.w_rel == 0) return 0; - if (mouse_config.mouse_dos_immediate) + if (mouse_config.dos_immediate) return (move_wheel() != 0); else return true; |