Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dosbox-staging/dosbox-staging.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFeralChild64 <unknown>2022-10-16 20:44:33 +0300
committerkcgen <1557255+kcgen@users.noreply.github.com>2022-10-22 21:15:34 +0300
commit04401fc0270091cde34672ba097c2cb40af14fbc (patch)
treeae66bc74df49da1366b29806b3e0dc32f4345cc9
parent175b256ddb43dac52dc7da3cf8c42eb392438c41 (diff)
Handle code review remarks
-rw-r--r--include/mouse.h26
-rw-r--r--src/dos/program_mousectl.cpp904
-rw-r--r--src/dos/program_mousectl.h72
-rw-r--r--src/hardware/mouse/mouse.cpp54
-rw-r--r--src/hardware/mouse/mouse_common.cpp4
-rw-r--r--src/hardware/mouse/mouse_config.cpp199
-rw-r--r--src/hardware/mouse/mouse_config.h30
-rw-r--r--src/hardware/mouse/mouse_interfaces.cpp148
-rw-r--r--src/hardware/mouse/mouse_interfaces.h31
-rw-r--r--src/hardware/mouse/mouse_manymouse.cpp88
-rw-r--r--src/hardware/mouse/mouse_manymouse.h8
-rw-r--r--src/hardware/mouse/mouse_queue.cpp20
-rw-r--r--src/hardware/mouse/mouse_queue.h4
-rw-r--r--src/hardware/mouse/mouseif_dos_driver.cpp48
-rw-r--r--src/hardware/mouse/mouseif_ps2_bios.cpp125
-rw-r--r--src/hardware/serialport/serialmouse.cpp12
-rw-r--r--src/ints/bios.cpp8
17 files changed, 913 insertions, 868 deletions
diff --git a/include/mouse.h b/include/mouse.h
index 12b3b5e51..98ef12871 100644
--- a/include/mouse.h
+++ b/include/mouse.h
@@ -98,7 +98,8 @@ bool MOUSE_IsUsingSeamlessSetting(); // if user selected seamless mode is in eff
// BIOS mouse interface for PS/2 mouse
// ***************************************************************************
-bool MOUSEBIOS_SetState(const bool use);
+bool MOUSEBIOS_Enable();
+bool MOUSEBIOS_Disable();
void MOUSEBIOS_SetCallback(const uint16_t pseg, const uint16_t pofs);
void MOUSEBIOS_Reset();
bool MOUSEBIOS_SetPacketSize(const uint8_t packet_size);
@@ -134,16 +135,16 @@ public:
MouseInterfaceId GetInterfaceId() const;
MouseMapStatus GetMapStatus() const;
const std::string &GetMappedDeviceName() const;
- int8_t GetSensitivityX() const; // -99 to +99
- int8_t GetSensitivityY() const; // -99 to +99
- uint16_t GetMinRate() const; // 10-500, 0 for none
- uint16_t GetRate() const; // current rate, 10-500, 0 for N/A
+ int16_t GetSensitivityX() const; // -999 to +999
+ int16_t GetSensitivityY() const; // -999 to +999
+ uint16_t GetMinRate() const; // 10-500, 0 for none
+ uint16_t GetRate() const; // current rate, 10-500, 0 for N/A
private:
friend class MouseInterface;
MouseInterfaceInfoEntry(const MouseInterfaceId interface_id);
- const uint8_t idx;
+ const uint8_t interface_idx;
const MouseInterface &Interface() const;
const MousePhysical &MappedPhysical() const;
};
@@ -192,11 +193,12 @@ public:
bool OnOff(const ListIDs &list_ids, const bool enable);
bool Reset(const ListIDs &list_ids);
- // Valid sensitivity values are from -99 to +99
- bool SetSensitivity(const ListIDs &list_ids, const int8_t sensitivity_x,
- const int8_t sensitivity_y);
- bool SetSensitivityX(const ListIDs &list_ids, const int8_t sensitivity_x);
- bool SetSensitivityY(const ListIDs &list_ids, const int8_t sensitivity_y);
+ // Valid sensitivity values are from -999 to +999
+ bool SetSensitivity(const ListIDs &list_ids,
+ const int16_t sensitivity_x,
+ const int16_t sensitivity_y);
+ bool SetSensitivityX(const ListIDs &list_ids, const int16_t sensitivity_x);
+ bool SetSensitivityY(const ListIDs &list_ids, const int16_t sensitivity_y);
bool ResetSensitivity(const ListIDs &list_ids);
bool ResetSensitivityX(const ListIDs &list_ids);
@@ -204,6 +206,8 @@ public:
static const std::vector<uint16_t> &GetValidMinRateList();
static const std::string &GetValidMinRateStr();
+ static std::string GetInterfaceNameStr(const MouseInterfaceId interface_id);
+
bool SetMinRate(const MouseControlAPI::ListIDs &list_ids,
const uint16_t value_hz);
bool ResetMinRate(const MouseControlAPI::ListIDs &list_ids);
diff --git a/src/dos/program_mousectl.cpp b/src/dos/program_mousectl.cpp
index 656b27c4c..64709fe55 100644
--- a/src/dos/program_mousectl.cpp
+++ b/src/dos/program_mousectl.cpp
@@ -29,510 +29,566 @@
CHECK_NARROWING();
-
void MOUSECTL::Run()
{
- if (HelpRequested()) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_HELP_LONG"));
- return;
- }
+ if (HelpRequested()) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_HELP_LONG"));
+ return;
+ }
- ParseAndRun();
- // TODO: once exit codes are supported, set it according to result
+ ParseAndRun();
+ // TODO: once exit codes are supported, set it according to result
}
bool MOUSECTL::ParseAndRun()
{
- // Put all the parameters into vector
- std::vector<std::string> params;
- cmd->FillVector(params);
-
- // Extract the list of interfaces from the vector
- list_ids.clear();
- if (!ParseInterfaces(params) || !CheckInterfaces())
- return false;
-
- auto param_equal = [&params](const size_t idx, const char *string)
- {
- if (idx >= params.size())
- return false;
- return iequals(params[idx], string);
- };
-
- // CmdShow
- if (list_ids.size() == 0 && params.size() == 0)
- return CmdShow(false);
- if (list_ids.size() == 0 && params.size() == 1)
- if (param_equal(0, "-all"))
- return CmdShow(true);
-
- // CmdMap - by supplied host mouse name
- if (list_ids.size() == 1 && params.size() == 2)
- if (param_equal(0, "-map"))
- return CmdMap(list_ids[0], params[1]);
-
- // CmdMap - interactive
- if (list_ids.size() >= 1 && params.size() == 1)
- if (param_equal(0, "-map"))
- return CmdMap();
-
- // CmdUnmap / CmdOnOff / CmdReset / CmdSensitivity / CmdMinRate
- if (params.size() == 1) {
- if (param_equal(0, "-unmap"))
- return CmdUnMap();
- if (param_equal(0, "-on"))
- return CmdOnOff(true);
- if (param_equal(0, "-off"))
- return CmdOnOff(false);
- if (param_equal(0, "-reset"))
- return CmdReset();
- if (param_equal(0, "-s"))
- return CmdSensitivity();
- if (param_equal(0, "-sx"))
- return CmdSensitivityX();
- if (param_equal(0, "-sy"))
- return CmdSensitivityY();
- if (param_equal(0, "-r"))
- return CmdMinRate();
- }
-
- // CmdSensitivity / CmdMinRate with a non-default value
- if (params.size() == 2) {
- if (param_equal(0, "-r"))
- return CmdMinRate(params[1]);
-
- const auto value = std::atoi(params[1].c_str());
- if (value < -99 || value > 99) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_SENSITIVITY"));
- return false;
- }
- if (param_equal(0, "-s"))
- return CmdSensitivity(static_cast<int8_t>(value));
- if (param_equal(0, "-sx"))
- return CmdSensitivityX(static_cast<int8_t>(value));
- if (param_equal(0, "-sy"))
- return CmdSensitivityY(static_cast<int8_t>(value));
- }
-
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX"));
- return false;
+ // Put all the parameters into vector
+ std::vector<std::string> params;
+ cmd->FillVector(params);
+
+ // Extract the list of interfaces from the vector
+ list_ids.clear();
+ if (!ParseInterfaces(params) || !CheckInterfaces())
+ return false;
+
+ auto param_equal = [&params](const size_t idx, const char *string) {
+ if (idx >= params.size())
+ return false;
+ return iequals(params[idx], string);
+ };
+
+ // CmdShow
+ if (list_ids.size() == 0 && params.empty())
+ return CmdShow(false);
+ if (list_ids.size() == 0 && params.size() == 1)
+ if (param_equal(0, "-all"))
+ return CmdShow(true);
+
+ // CmdMap - by supplied host mouse name
+ if (list_ids.size() == 1 && params.size() == 2)
+ if (param_equal(0, "-map"))
+ return CmdMap(list_ids[0], params[1]);
+
+ // CmdMap - interactive
+ if (!list_ids.empty() && params.size() == 1)
+ if (param_equal(0, "-map"))
+ return CmdMap();
+
+ // CmdUnmap / CmdOnOff / CmdReset / CmdSensitivity / CmdMinRate
+ if (params.size() == 1) {
+ if (param_equal(0, "-unmap"))
+ return CmdUnMap();
+ if (param_equal(0, "-on"))
+ return CmdOnOff(true);
+ if (param_equal(0, "-off"))
+ return CmdOnOff(false);
+ if (param_equal(0, "-reset"))
+ return CmdReset();
+ if (param_equal(0, "-s"))
+ return CmdSensitivity();
+ if (param_equal(0, "-sx"))
+ return CmdSensitivityX();
+ if (param_equal(0, "-sy"))
+ return CmdSensitivityY();
+ if (param_equal(0, "-r"))
+ return CmdMinRate();
+ }
+
+ // CmdSensitivity / CmdMinRate with a non-default value
+ if (params.size() == 2) {
+ if (param_equal(0, "-r"))
+ return CmdMinRate(params[1]);
+
+ if (param_equal(0, "-s"))
+ return CmdSensitivity(params[1], params[1]);
+ if (param_equal(0, "-sx"))
+ return CmdSensitivityX(params[1]);
+ if (param_equal(0, "-sy"))
+ return CmdSensitivityY(params[1]);
+ }
+ if (params.size() == 3) {
+ if (param_equal(0, "-s"))
+ return CmdSensitivity(params[1], params[2]);
+ }
+
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX"));
+ return false;
}
-bool MOUSECTL::ParseInterfaces(std::vector<std::string> &params)
+bool MOUSECTL::ParseSensitivity(const std::string &param, int16_t &value)
{
- auto add_if_is_interface = [&](const std::string &param) {
- for (const auto id : {
- MouseInterfaceId::DOS,
- MouseInterfaceId::PS2,
- MouseInterfaceId::COM1,
- MouseInterfaceId::COM2,
- MouseInterfaceId::COM3,
- MouseInterfaceId::COM4,
- }) {
- if (iequals(param, GetInterfaceStr(id))) {
- list_ids.push_back(id);
- return true;
- }
- }
- if (iequals(param, "PS2")) { // syntax sugar, easier to type than 'PS/2'
- list_ids.push_back(MouseInterfaceId::PS2);
- return true;
- }
- return false;
- };
- while (!params.empty() && add_if_is_interface(params.front()))
- params.erase(params.begin()); // pop
-
- // Check that all interfaces are unique
- std::set<MouseInterfaceId> tmp(list_ids.begin(), list_ids.end());
- if (list_ids.size() != tmp.size()) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_DUPLICATED"));
- return false;
- }
-
- return true;
+ value = 0;
+
+ int tmp = 0;
+ if (!ParseIntParam(param, tmp)) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_SENSITIVITY"));
+ return false;
+ }
+
+ // Maximum allowed user sensitivity value
+ constexpr int16_t sensitivity_user_max = 999;
+ if (tmp < -sensitivity_user_max || tmp > sensitivity_user_max) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_SENSITIVITY"));
+ return false;
+ }
+
+ value = static_cast<int16_t>(tmp);
+ return true;
}
-bool MOUSECTL::CheckInterfaces()
+bool MOUSECTL::ParseIntParam(const std::string &param, int &value)
{
- if (MouseControlAPI::CheckInterfaces(list_ids))
- return true;
-
- if (list_ids.empty())
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_INTERFACES"));
- else
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MISSING_INTERFACES"));
+ try {
+ value = std::stoi(param);
+ } catch (...) {
+ value = 0;
+ return false;
+ }
+
+ return true;
+}
- return false;
+bool MOUSECTL::ParseInterfaces(std::vector<std::string> &params)
+{
+ auto add_if_is_interface = [&](const std::string &param) {
+ for (const auto id : {
+ MouseInterfaceId::DOS,
+ MouseInterfaceId::PS2,
+ MouseInterfaceId::COM1,
+ MouseInterfaceId::COM2,
+ MouseInterfaceId::COM3,
+ MouseInterfaceId::COM4,
+ }) {
+ if (iequals(param, MouseControlAPI::GetInterfaceNameStr(id))) {
+ list_ids.push_back(id);
+ return true;
+ }
+ }
+ if (iequals(param, "PS2")) { // syntax sugar, easier to type
+ // than 'PS/2'
+ list_ids.push_back(MouseInterfaceId::PS2);
+ return true;
+ }
+ return false;
+ };
+ while (!params.empty() && add_if_is_interface(params.front()))
+ params.erase(params.begin()); // pop
+
+ // Check that all interfaces are unique
+ const std::set<MouseInterfaceId> tmp(list_ids.begin(), list_ids.end());
+ if (list_ids.size() != tmp.size()) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_DUPLICATED"));
+ return false;
+ }
+
+ return true;
}
-const char *MOUSECTL::GetInterfaceStr(const MouseInterfaceId interface_id) const
+bool MOUSECTL::CheckInterfaces()
{
- switch (interface_id) {
- case MouseInterfaceId::DOS: return "DOS";
- case MouseInterfaceId::PS2: return "PS/2";
- case MouseInterfaceId::COM1: return "COM1";
- case MouseInterfaceId::COM2: return "COM2";
- case MouseInterfaceId::COM3: return "COM3";
- case MouseInterfaceId::COM4: return "COM4";
- case MouseInterfaceId::None: return "";
- default:
- assert(false); // missing implementation
- return nullptr;
- }
+ if (MouseControlAPI::CheckInterfaces(list_ids))
+ return true;
+
+ if (list_ids.empty())
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_INTERFACES"));
+ else
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MISSING_INTERFACES"));
+
+ return false;
}
-const char *MOUSECTL::GetMapStatusStr(const MouseMapStatus map_status) const
+const char *MOUSECTL::GetMapStatusStr(const MouseMapStatus map_status)
{
- switch (map_status) {
- case MouseMapStatus::HostPointer:
- return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_HOST");
- case MouseMapStatus::Mapped:
- return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_MAPPED");
- case MouseMapStatus::Disconnected:
- return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISCONNECTED");
- case MouseMapStatus::Disabled:
- return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISABLED");
- default:
- assert(false); // missing implementation
- return nullptr;
- }
+ switch (map_status) {
+ case MouseMapStatus::HostPointer:
+ return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_HOST");
+ case MouseMapStatus::Mapped:
+ return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_MAPPED");
+ case MouseMapStatus::Disconnected:
+ return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISCONNECTED");
+ case MouseMapStatus::Disabled:
+ return MSG_Get("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISABLED");
+ default:
+ assert(false); // missing implementation
+ return nullptr;
+ }
}
bool MOUSECTL::CmdShow(const bool show_all)
{
- MouseControlAPI mouse_config_api;
- const auto info_interfaces = mouse_config_api.GetInfoInterfaces();
-
- bool show_mapped = false;
- bool hint_rate_com = false;
- bool hint_rate_min = false;
-
- // 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;
- const auto interface_id = entry.GetInterfaceId();
- const auto rate_hz = entry.GetRate();
- const bool rate_enforced = entry.GetMinRate();
-
- if (rate_enforced)
- hint_rate_min = true;
-
- if (interface_id == MouseInterfaceId::COM1 ||
- interface_id == MouseInterfaceId::COM2 ||
- interface_id == MouseInterfaceId::COM3 ||
- interface_id == MouseInterfaceId::COM4)
- hint_rate_com = true;
-
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_LAYOUT1"),
- GetInterfaceStr(interface_id),
- entry.GetSensitivityX(),
- entry.GetSensitivityY(),
- rate_enforced ? "*" : "",
- rate_hz ? std::to_string(rate_hz).c_str() : "-",
- convert_ansi_markup(GetMapStatusStr(entry.GetMapStatus())).c_str());
- WriteOut("\n");
-
- if (entry.GetMapStatus() == MouseMapStatus::Mapped)
- show_mapped = true;
- }
- WriteOut("\n");
-
- const bool hint = hint_rate_com || hint_rate_min;
- if (hint)
- {
- if (hint_rate_com) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_COM"));
- WriteOut("\n");
- }
- if (hint_rate_min) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_MIN"));
- WriteOut("\n");
- }
- WriteOut("\n");
- }
-
- if (!show_all && !show_mapped)
- return true;
-
- const auto info_physical = mouse_config_api.GetInfoPhysical();
- if (info_physical.empty()) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_PHYSICAL_MICE"));
- WriteOut("\n\n");
- return true;
- }
-
- 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) {
- if (!entry.IsMapped() || entry.IsMappedDeviceDisconnected())
- continue;
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2"),
- GetInterfaceStr(entry.GetInterfaceId()),
- entry.GetMappedDeviceName().c_str());
- WriteOut("\n");
- }
-
- if (!show_all)
- return true;
-
- // Display physical mice not mapped to any interface
- for (const auto &entry : info_physical) {
- if (entry.IsMapped() || entry.IsDeviceDisconnected())
- continue;
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2_UNMAPPED"),
- entry.GetDeviceName().c_str());
- WriteOut("\n");
- }
- WriteOut("\n");
-
- return true;
+ MouseControlAPI mouse_config_api;
+ const auto info_interfaces = mouse_config_api.GetInfoInterfaces();
+
+ bool show_mapped = false;
+ bool hint_rate_com = false;
+ bool hint_rate_min = false;
+
+ // 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;
+ const auto interface_id = entry.GetInterfaceId();
+ const auto rate_hz = entry.GetRate();
+ const bool rate_enforced = entry.GetMinRate();
+
+ if (rate_enforced)
+ hint_rate_min = true;
+
+ if (interface_id == MouseInterfaceId::COM1 ||
+ interface_id == MouseInterfaceId::COM2 ||
+ interface_id == MouseInterfaceId::COM3 ||
+ interface_id == MouseInterfaceId::COM4)
+ hint_rate_com = true;
+
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_LAYOUT1"),
+ MouseControlAPI::GetInterfaceNameStr(interface_id).c_str(),
+ entry.GetSensitivityX(),
+ entry.GetSensitivityY(),
+ rate_enforced ? "*" : "",
+ rate_hz ? std::to_string(rate_hz).c_str() : "-",
+ convert_ansi_markup(GetMapStatusStr(entry.GetMapStatus()))
+ .c_str());
+ WriteOut("\n");
+
+ if (entry.GetMapStatus() == MouseMapStatus::Mapped)
+ show_mapped = true;
+ }
+ WriteOut("\n");
+
+ const bool hint = hint_rate_com || hint_rate_min;
+ if (hint) {
+ if (hint_rate_com) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_COM"));
+ WriteOut("\n");
+ }
+ if (hint_rate_min) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_MIN"));
+ WriteOut("\n");
+ }
+ WriteOut("\n");
+ }
+
+ if (!show_all && !show_mapped)
+ return true;
+
+ const auto info_physical = mouse_config_api.GetInfoPhysical();
+ if (info_physical.empty()) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_PHYSICAL_MICE"));
+ WriteOut("\n\n");
+ return true;
+ }
+
+ if (hint)
+ WriteOut("\n");
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_HEADER2"));
+ WriteOut("\n");
+
+ // Display physical mice mapped to some interface
+ bool needs_newline = false;
+ for (const auto &entry : info_interfaces) {
+ if (!entry.IsMapped() || entry.IsMappedDeviceDisconnected())
+ continue;
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2"),
+ MouseControlAPI::GetInterfaceNameStr(entry.GetInterfaceId())
+ .c_str(),
+ entry.GetMappedDeviceName().c_str());
+ WriteOut("\n");
+ needs_newline = true;
+ }
+
+ if (!show_all) {
+ if (needs_newline)
+ WriteOut("\n");
+ return true;
+ }
+
+ // Display physical mice not mapped to any interface
+ for (const auto &entry : info_physical) {
+ if (entry.IsMapped() || entry.IsDeviceDisconnected())
+ continue;
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2_UNMAPPED"),
+ entry.GetDeviceName().c_str());
+ WriteOut("\n");
+ }
+ WriteOut("\n");
+
+ return true;
}
void MOUSECTL::FinalizeMapping()
{
- WriteOut("\n");
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_HINT"));
- WriteOut("\n\n");
+ WriteOut("\n");
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_HINT"));
+ WriteOut("\n\n");
- GFX_MouseCaptureAfterMapping();
+ GFX_MouseCaptureAfterMapping();
}
bool MOUSECTL::CmdMap(const MouseInterfaceId interface_id, const std::string &pattern)
{
- std::regex regex;
- if (!MouseControlAPI::PatternToRegex(pattern, regex)) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_PATTERN"));
- return false;
- }
-
- if (MouseControlAPI::IsNoMouseMode()) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE"));
- return false;
- }
-
- MouseControlAPI mouse_config_api;
- if (!mouse_config_api.Map(interface_id, regex)) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_MATCH"));
- return false;
- }
-
- FinalizeMapping();
- return true;
+ std::regex regex;
+ if (!MouseControlAPI::PatternToRegex(pattern, regex)) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_PATTERN"));
+ return false;
+ }
+
+ if (MouseControlAPI::IsNoMouseMode()) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE"));
+ return false;
+ }
+
+ MouseControlAPI mouse_config_api;
+ if (!mouse_config_api.Map(interface_id, regex)) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_MATCH"));
+ return false;
+ }
+
+ FinalizeMapping();
+ return true;
}
bool MOUSECTL::CmdMap()
{
- assert(list_ids.size() >= 1);
-
- if (MouseControlAPI::IsNoMouseMode()) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE"));
- return false;
- }
-
- MouseControlAPI mouse_config_api;
- const auto info_physical = mouse_config_api.GetInfoPhysical();
-
- if (info_physical.empty()) {
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_PHYSICAL_MICE"));
- WriteOut("\n\n");
- return false;
- }
-
- // Clear the current mapping before starting interactive mapper
- std::vector<MouseInterfaceId> empty;
- mouse_config_api.UnMap(empty);
-
- WriteOut("\n");
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_ADVICE"));
- WriteOut("\n\n");
-
- for (const auto &interface_id : list_ids) {
- WriteOut(convert_ansi_markup("[color=cyan]%-4s[reset] ?").c_str(),
- GetInterfaceStr(interface_id));
-
- uint8_t device_id = 0;
- if (!mouse_config_api.ProbeForMapping(device_id)) {
- mouse_config_api.UnMap(empty);
- WriteOut("\b");
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_CANCEL"));
- WriteOut("\n\n");
- return false;
- }
-
- WriteOut("\b");
- WriteOut(info_physical[device_id].GetDeviceName().c_str());
- WriteOut("\n");
- mouse_config_api.Map(interface_id, device_id);
- }
-
- FinalizeMapping();
- return true;
+ assert(!list_ids.empty());
+
+ if (MouseControlAPI::IsNoMouseMode()) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAPPING_NO_MOUSE"));
+ return false;
+ }
+
+ MouseControlAPI mouse_config_api;
+ const auto info_physical = mouse_config_api.GetInfoPhysical();
+
+ if (info_physical.empty()) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_NO_PHYSICAL_MICE"));
+ WriteOut("\n\n");
+ return false;
+ }
+
+ // Clear the current mapping before starting interactive mapper
+ std::vector<MouseInterfaceId> empty;
+ mouse_config_api.UnMap(empty);
+
+ WriteOut("\n");
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_ADVICE"));
+ WriteOut("\n\n");
+
+ for (const auto &interface_id : list_ids) {
+ WriteOut(convert_ansi_markup("[color=cyan]%-4s[reset] ?").c_str(),
+ MouseControlAPI::GetInterfaceNameStr(interface_id).c_str());
+
+ uint8_t device_id = 0;
+ if (!mouse_config_api.ProbeForMapping(device_id)) {
+ mouse_config_api.UnMap(empty);
+ WriteOut("\b");
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_MAP_CANCEL"));
+ WriteOut("\n\n");
+ return false;
+ }
+
+ WriteOut("\b");
+ WriteOut(info_physical[device_id].GetDeviceName().c_str());
+ WriteOut("\n");
+ mouse_config_api.Map(interface_id, device_id);
+ }
+
+ FinalizeMapping();
+ return true;
}
bool MOUSECTL::CmdUnMap()
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.UnMap(list_ids);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.UnMap(list_ids);
+ return true;
}
bool MOUSECTL::CmdOnOff(const bool enable)
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.OnOff(list_ids, enable);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.OnOff(list_ids, enable);
+ return true;
}
bool MOUSECTL::CmdReset()
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.Reset(list_ids);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.Reset(list_ids);
+ return true;
}
-bool MOUSECTL::CmdSensitivity(const int8_t value)
+bool MOUSECTL::CmdSensitivity(const std::string &param_x, const std::string &param_y)
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.SetSensitivity(list_ids, value, value);
- return true;
+ int16_t value_x = 0;
+ int16_t value_y = 0;
+ if (!ParseSensitivity(param_x, value_x) || !ParseSensitivity(param_y, value_y))
+ return false;
+
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.SetSensitivity(list_ids, value_x, value_y);
+ return true;
}
-bool MOUSECTL::CmdSensitivityX(const int8_t value)
+bool MOUSECTL::CmdSensitivityX(const std::string &param)
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.SetSensitivityX(list_ids, value);
- return true;
+ int16_t value = 0;
+ if (!ParseSensitivity(param, value))
+ return false;
+
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.SetSensitivityX(list_ids, value);
+ return true;
}
-bool MOUSECTL::CmdSensitivityY(const int8_t value)
+bool MOUSECTL::CmdSensitivityY(const std::string &param)
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.SetSensitivityY(list_ids, value);
- return true;
+ int16_t value = 0;
+ if (!ParseSensitivity(param, value))
+ return false;
+
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.SetSensitivityY(list_ids, value);
+ return true;
}
bool MOUSECTL::CmdSensitivity()
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.ResetSensitivity(list_ids);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.ResetSensitivity(list_ids);
+ return true;
}
bool MOUSECTL::CmdSensitivityX()
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.ResetSensitivityX(list_ids);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.ResetSensitivityX(list_ids);
+ return true;
}
bool MOUSECTL::CmdSensitivityY()
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.ResetSensitivityY(list_ids);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.ResetSensitivityY(list_ids);
+ return true;
}
bool MOUSECTL::CmdMinRate(const std::string &param)
{
- const auto &valid_list = MouseControlAPI::GetValidMinRateList();
- const auto &valid_str = MouseControlAPI::GetValidMinRateStr();
-
- const auto tmp = std::atoi(param.c_str());
- if (tmp < 0 || tmp > UINT16_MAX) {
- // Parameter way out of range
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_MIN_RATE"), valid_str.c_str());
- return false;
- }
-
- uint16_t value_hz = static_cast<uint16_t>(tmp);
- if (std::find(valid_list.begin(), valid_list.end(), value_hz) == valid_list.end()) {
- // Parameter not in the list of allowed values
- WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_MIN_RATE"), valid_str.c_str());
- return false;
- }
-
- MouseControlAPI mouse_config_api;
- mouse_config_api.SetMinRate(list_ids, value_hz);
- return true;
+ const auto &valid_list = MouseControlAPI::GetValidMinRateList();
+ const auto &valid_str = MouseControlAPI::GetValidMinRateStr();
+
+ int tmp = 0;
+ if (!ParseIntParam(param, tmp)) {
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_MIN_RATE"),
+ valid_str.c_str());
+ return false;
+ }
+
+ if (tmp < 0 || tmp > UINT16_MAX) {
+ // Parameter way out of range
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_MIN_RATE"),
+ valid_str.c_str());
+ return false;
+ }
+
+ const auto value_hz = static_cast<uint16_t>(tmp);
+ if (!contains(valid_list, value_hz)) {
+ // Parameter not in the list of allowed values
+ WriteOut(MSG_Get("SHELL_CMD_MOUSECTL_SYNTAX_MIN_RATE"),
+ valid_str.c_str());
+ return false;
+ }
+
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.SetMinRate(list_ids, value_hz);
+ return true;
}
bool MOUSECTL::CmdMinRate()
{
- MouseControlAPI mouse_config_api;
- mouse_config_api.ResetMinRate(list_ids);
- return true;
+ MouseControlAPI mouse_config_api;
+ mouse_config_api.ResetMinRate(list_ids);
+ return true;
}
void MOUSECTL::AddMessages()
{
- MSG_Add("SHELL_CMD_MOUSECTL_HELP_LONG",
- "Manages physical and logical mice.\n"
- "\n"
- "Usage:\n"
- " [color=green]mousectl[reset] [-all]\n"
- " [color=green]mousectl[reset] [color=white]INTERFACE[reset] -map name\n"
- " [color=green]mousectl[reset] [color=white]INTERFACE[reset] [[color=white]INTERFACE[reset] ...] -map\n"
- " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -unmap | -on | -off | -reset\n"
- " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -s | -sx | -sy [sensitivity]\n"
- " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -r [min_rate]\n"
- "\n"
- "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, 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"
- "\n"
- "Notes:\n"
- " - if host mouse name is omitted, it is mapped in interactive mode\n"
- " - if sensitivity or rate is omitted, it is reset to default value\n"
- "\n"
- "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 -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_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]");
- 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]");
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2", "[color=cyan]%-4s[reset] %s");
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT2_UNMAPPED", "not mapped %s");
-
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_HOST", "uses system pointer");
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_MAPPED", "mapped physical mouse");
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISCONNECTED", "[color=red]mapped mouse disconnected[reset]");
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISABLED", "disabled");
-
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_COM", "Sampling rates for mice on [color=cyan]COM[reset] interfaces are estimations only.");
- MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_MIN", "Sampling rates with minimum value set are marked with '*'.");
-
- MSG_Add("SHELL_CMD_MOUSECTL_MAP_ADVICE",
- "Click [color=white]left[reset] mouse button to map the physical mouse to the interface. Clicking\n"
- "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.");
+ MSG_Add("SHELL_CMD_MOUSECTL_HELP_LONG",
+ "Manages physical and logical mice.\n"
+ "\n"
+ "Usage:\n"
+ " [color=green]mousectl[reset] [-all]\n"
+ " [color=green]mousectl[reset] [color=white]INTERFACE[reset] -map [color=cyan]NAME[reset]\n"
+ " [color=green]mousectl[reset] [color=white]INTERFACE[reset] [[color=white]INTERFACE[reset] ...] -map\n"
+ " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -unmap | -on | -off | -reset\n"
+ " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -s | -sx | -sy [sensitivity]\n"
+ " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -s sensitivity_x sensitivity_y\n"
+ " [color=green]mousectl[reset] [[color=white]INTERFACE[reset] ...] -r [min_rate]\n"
+ "\n"
+ "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 [color=cyan]NAME[reset]\n"
+ " -s -sx -sy sets sensitivity / for x axis / for y axis, from -999 to +999\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"
+ "\n"
+ "Notes:\n"
+ " - if sensitivity or rate is omitted, it is reset to default value\n"
+ "\n"
+ "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 -999 to +999 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_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]");
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_LAYOUT1",
+ "[color=cyan]%-4s[reset] X:%+.3d Y:%+.3d %1s %3s %s");
+
+ 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");
+
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_HOST", "uses system pointer");
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_MAPPED", "mapped physical mouse");
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISCONNECTED",
+ "[color=red]mapped mouse disconnected[reset]");
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_STATUS_DISABLED", "disabled");
+
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_COM",
+ "Sampling rates for mice on [color=cyan]COM[reset] interfaces are estimations only.");
+ MSG_Add("SHELL_CMD_MOUSECTL_TABLE_HINT_RATE_MIN",
+ "Sampling rates with minimum value set are marked with '*'.");
+
+ MSG_Add("SHELL_CMD_MOUSECTL_MAP_ADVICE",
+ "Click [color=white]left[reset] mouse button to map the physical mouse to the interface. Clicking\n"
+ "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 5aa8d543d..03fcab311 100644
--- a/src/dos/program_mousectl.h
+++ b/src/dos/program_mousectl.h
@@ -25,51 +25,49 @@
#include "mouse.h"
-
class MOUSECTL final : public Program {
public:
- MOUSECTL()
- {
- AddMessages();
- help_detail = {HELP_Filter::All,
- HELP_Category::Dosbox,
- HELP_CmdType::Program,
- "MOUSECTL"};
- }
- void Run();
+ MOUSECTL()
+ {
+ AddMessages();
+ help_detail = {HELP_Filter::All,
+ HELP_Category::Dosbox,
+ HELP_CmdType::Program,
+ "MOUSECTL"};
+ }
+ void Run();
private:
+ bool ParseAndRun();
+ bool ParseInterfaces(std::vector<std::string> &params);
+ bool ParseSensitivity(const std::string &param, int16_t &value);
+ static bool ParseIntParam(const std::string &param, int &value);
+ bool CheckInterfaces();
+ void FinalizeMapping();
- bool ParseAndRun();
- bool ParseInterfaces(std::vector<std::string> &params);
- bool CheckInterfaces();
- void FinalizeMapping();
-
- const char *GetInterfaceStr(const MouseInterfaceId interface_id) const;
- const char *GetMapStatusStr(const MouseMapStatus map_status) const;
+ static const char *GetMapStatusStr(const MouseMapStatus map_status);
- // Methods below exectute specific commands requested by the user,
- // they return 'true' if DOS error code should indicate success,
- // and 'false' if we should report a failure
- bool CmdShow(const bool show_all);
- bool CmdMap(const MouseInterfaceId interface_id,
- const std::string &pattern);
- bool CmdMap();
- bool CmdUnMap();
- bool CmdOnOff(const bool enable);
- bool CmdReset();
- bool CmdSensitivity(const int8_t value);
- bool CmdSensitivityX(const int8_t value);
- bool CmdSensitivityY(const int8_t value);
- bool CmdSensitivity();
- bool CmdSensitivityX();
- bool CmdSensitivityY();
- bool CmdMinRate(const std::string &param);
- bool CmdMinRate();
+ // Methods below exectute specific commands requested by the user,
+ // they return 'true' if DOS error code should indicate success,
+ // and 'false' if we should report a failure
+ bool CmdShow(const bool show_all);
+ bool CmdMap(const MouseInterfaceId interface_id, const std::string &pattern);
+ bool CmdMap();
+ bool CmdUnMap();
+ bool CmdOnOff(const bool enable);
+ bool CmdReset();
+ bool CmdSensitivity(const std::string &param_x, const std::string &param_y);
+ bool CmdSensitivityX(const std::string &param);
+ bool CmdSensitivityY(const std::string &param);
+ bool CmdSensitivity();
+ bool CmdSensitivityX();
+ bool CmdSensitivityY();
+ bool CmdMinRate(const std::string &param);
+ bool CmdMinRate();
- void AddMessages();
+ void AddMessages();
- std::vector<MouseInterfaceId> list_ids = {};
+ std::vector<MouseInterfaceId> list_ids = {};
};
#endif
diff --git a/src/hardware/mouse/mouse.cpp b/src/hardware/mouse/mouse.cpp
index 6db7b6e52..6f99a6e1e 100644
--- a/src/hardware/mouse/mouse.cpp
+++ b/src/hardware/mouse/mouse.cpp
@@ -24,6 +24,7 @@
#include "mouse_queue.h"
#include <algorithm>
+#include <cctype>
#include <sstream>
#include <string>
#include <vector>
@@ -41,7 +42,7 @@ bool seamless_setting = false;
static Bitu int74_ret_callback = 0;
-static MouseQueue &queue = MouseQueue::GetInstance();
+static MouseQueue &mouse_queue = MouseQueue::GetInstance();
static ManyMouseGlue &manymouse = ManyMouseGlue::GetInstance();
// ***************************************************************************
@@ -59,7 +60,7 @@ static Bitu int74_exit()
static Bitu int74_handler()
{
MouseEvent ev;
- queue.FetchEvent(ev);
+ mouse_queue.FetchEvent(ev);
// Handle DOS events
if (ev.request_dos) {
@@ -112,7 +113,7 @@ static Bitu int74_handler()
Bitu int74_ret_handler()
{
- queue.StartTimerIfNeeded();
+ mouse_queue.StartTimerIfNeeded();
return CBRET_NONE;
}
@@ -155,7 +156,7 @@ void MOUSE_NewScreenParams(const uint16_t clip_x, const uint16_t clip_y,
void MOUSE_NotifyResetDOS()
{
- queue.ClearEventsDOS();
+ mouse_queue.ClearEventsDOS();
}
void MOUSE_NotifyStateChanged()
@@ -198,7 +199,7 @@ void MOUSE_NotifyFakePS2()
if (interface && interface->IsUsingEvents()) {
MouseEvent ev;
ev.request_ps2 = true;
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
}
@@ -237,7 +238,7 @@ void MOUSE_EventMoved(const float x_rel, const float y_rel,
for (auto &interface : mouse_interfaces)
if (interface->IsUsingHostPointer())
interface->NotifyMoved(ev, x_rel, y_rel, x_abs, y_abs);
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
void MOUSE_EventMoved(const float x_rel, const float y_rel,
@@ -247,7 +248,7 @@ void MOUSE_EventMoved(const float x_rel, const float y_rel,
if (interface && interface->IsUsingEvents()) {
MouseEvent ev;
interface->NotifyMoved(ev, x_rel, y_rel, 0, 0);
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
}
@@ -257,7 +258,7 @@ void MOUSE_EventButton(const uint8_t idx, const bool pressed)
for (auto &interface : mouse_interfaces)
if (interface->IsUsingHostPointer())
interface->NotifyButton(ev, idx, pressed);
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
void MOUSE_EventButton(const uint8_t idx, const bool pressed,
@@ -267,7 +268,7 @@ void MOUSE_EventButton(const uint8_t idx, const bool pressed,
if (interface && interface->IsUsingEvents()) {
MouseEvent ev;
interface->NotifyButton(ev, idx, pressed);
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
}
@@ -277,7 +278,7 @@ void MOUSE_EventWheel(const int16_t w_rel)
for (auto &interface : mouse_interfaces)
if (interface->IsUsingHostPointer())
interface->NotifyWheel(ev, w_rel);
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
void MOUSE_EventWheel(const int16_t w_rel, const MouseInterfaceId interface_id)
@@ -286,7 +287,7 @@ void MOUSE_EventWheel(const int16_t w_rel, const MouseInterfaceId interface_id)
if (interface && interface->IsUsingEvents()) {
MouseEvent ev;
interface->NotifyWheel(ev, w_rel);
- queue.AddEvent(ev);
+ mouse_queue.AddEvent(ev);
}
}
@@ -373,9 +374,7 @@ bool MouseControlAPI::PatternToRegex(const std::string &pattern, std::regex &reg
pattern_regex << ".";
else if (character == '*')
pattern_regex << ".*";
- else if ((character >= '0' && character <= '9') ||
- (character >= 'a' && character <= 'z') ||
- (character >= 'A' && character <= 'Z'))
+ else if (std::isalnum(character))
pattern_regex << character;
else
pattern_regex << "\\x" << static_cast<int>(character);
@@ -448,8 +447,8 @@ bool MouseControlAPI::Reset(const MouseControlAPI::ListIDs &list_ids)
}
bool MouseControlAPI::SetSensitivity(const MouseControlAPI::ListIDs &list_ids,
- const int8_t sensitivity_x,
- const int8_t sensitivity_y)
+ const int16_t sensitivity_x,
+ const int16_t sensitivity_y)
{
if (sensitivity_x > mouse_predefined.sensitivity_user_max ||
sensitivity_x < -mouse_predefined.sensitivity_user_max ||
@@ -465,7 +464,7 @@ bool MouseControlAPI::SetSensitivity(const MouseControlAPI::ListIDs &list_ids,
}
bool MouseControlAPI::SetSensitivityX(const MouseControlAPI::ListIDs &list_ids,
- const int8_t sensitivity_x)
+ const int16_t sensitivity_x)
{
if (sensitivity_x > mouse_predefined.sensitivity_user_max ||
sensitivity_x < -mouse_predefined.sensitivity_user_max)
@@ -479,7 +478,7 @@ bool MouseControlAPI::SetSensitivityX(const MouseControlAPI::ListIDs &list_ids,
}
bool MouseControlAPI::SetSensitivityY(const MouseControlAPI::ListIDs &list_ids,
- const int8_t sensitivity_y)
+ const int16_t sensitivity_y)
{
if (sensitivity_y > mouse_predefined.sensitivity_user_max ||
sensitivity_y < -mouse_predefined.sensitivity_user_max)
@@ -544,12 +543,27 @@ const std::string &MouseControlAPI::GetValidMinRateStr()
return out_str;
}
+std::string MouseControlAPI::GetInterfaceNameStr(const MouseInterfaceId interface_id)
+{
+ switch (interface_id) {
+ case MouseInterfaceId::DOS: return "DOS";
+ case MouseInterfaceId::PS2: return "PS/2";
+ case MouseInterfaceId::COM1: return "COM1";
+ case MouseInterfaceId::COM2: return "COM2";
+ case MouseInterfaceId::COM3: return "COM3";
+ case MouseInterfaceId::COM4: return "COM4";
+ case MouseInterfaceId::None: return "";
+ default:
+ assert(false); // missing implementation
+ return nullptr;
+ }
+}
+
bool MouseControlAPI::SetMinRate(const MouseControlAPI::ListIDs &list_ids,
const uint16_t value_hz)
{
const auto &valid_list = GetValidMinRateList();
- if (std::find(valid_list.begin(), valid_list.end(), value_hz) ==
- valid_list.end())
+ if (!contains(valid_list, value_hz))
return false; // invalid value
auto list = get_relevant_interfaces(list_ids);
diff --git a/src/hardware/mouse/mouse_common.cpp b/src/hardware/mouse/mouse_common.cpp
index cad02c5e7..eb526ce9b 100644
--- a/src/hardware/mouse/mouse_common.cpp
+++ b/src/hardware/mouse/mouse_common.cpp
@@ -83,8 +83,8 @@ float MOUSE_GetBallisticsCoeff(const float speed)
uint8_t MOUSE_GetDelayFromRateHz(const uint16_t rate_hz)
{
assert(rate_hz);
- const auto tmp = std::lround(1000.0f / MOUSE_ClampRateHz(rate_hz));
- return static_cast<uint8_t>(tmp);
+ const auto period_in_ms = std::lround(1000.0f / MOUSE_ClampRateHz(rate_hz));
+ return static_cast<uint8_t>(period_in_ms);
}
float MOUSE_ClampRelativeMovement(const float rel)
diff --git a/src/hardware/mouse/mouse_config.cpp b/src/hardware/mouse/mouse_config.cpp
index ce6dbe1a1..f81735790 100644
--- a/src/hardware/mouse/mouse_config.cpp
+++ b/src/hardware/mouse/mouse_config.cpp
@@ -24,6 +24,7 @@
#include "control.h"
#include "math_utils.h"
#include "setup.h"
+#include "string_utils.h"
#include "support.h"
#include "video.h"
@@ -41,22 +42,42 @@ CHECK_NARROWING();
MouseConfig mouse_config;
MousePredefined mouse_predefined;
-static const std::vector<std::string> list_models_ps2 = {
- "standard",
- "intellimouse",
+static struct {
+ const std::string param_standard = "standard";
+ const std::string param_intellimouse = "intellimouse";
#ifdef ENABLE_EXPLORER_MOUSE
- "explorer",
+ const std::string param_explorer = "explorer";
#endif
+} models_ps2;
+
+static struct {
+ const std::string param_2button = "2button";
+ const std::string param_3button = "3button";
+ const std::string param_wheel = "wheel";
+ const std::string param_msm = "msm";
+ const std::string param_2button_msm = "2button+msm";
+ const std::string param_3button_msm = "3button+msm";
+ const std::string param_wheel_msm = "wheel+msm";
+} models_com;
+
+static const char *list_models_ps2[] = {
+ models_ps2.param_standard.c_str(),
+ models_ps2.param_intellimouse.c_str(),
+#ifdef ENABLE_EXPLORER_MOUSE
+ models_ps2.param_explorer.c_str(),
+#endif
+ nullptr
};
-static const std::vector<std::string> list_models_com = {
- "2button",
- "3button",
- "wheel",
- "msm",
- "2button+msm",
- "3button+msm",
- "wheel+msm",
+static const char *list_models_com[] = {
+ models_com.param_2button.c_str(),
+ models_com.param_3button.c_str(),
+ models_com.param_wheel.c_str(),
+ models_com.param_msm.c_str(),
+ models_com.param_2button_msm.c_str(),
+ models_com.param_3button_msm.c_str(),
+ models_com.param_wheel_msm.c_str(),
+ nullptr
};
static const std::vector<uint16_t> list_rates = {
@@ -66,7 +87,7 @@ static const std::vector<uint16_t> list_rates = {
// 20", // PS/2 mouse
// 30", // bus/InPort mouse
40, // PS/2 mouse, approx. limit for 1200 baud serial mouse
- // 50, // bus/InPort mouse
+ // 50, // bus/InPort mouse
60, // PS/2 mouse, used by Microsoft Mouse Driver 8.20
80, // PS/2 mouse, approx. limit for 2400 baud serial mouse
100, // PS/2 mouse, bus/InPort mouse, used by CuteMouse 2.1b4
@@ -84,34 +105,34 @@ static const std::vector<uint16_t> list_rates = {
// issues.
};
-bool MouseConfig::ParseSerialModel(const std::string &model_str,
- MouseModelCOM &model, bool &auto_msm)
+bool MouseConfig::ParseCOMModel(const std::string &model_str,
+ MouseModelCOM &model, bool &auto_msm)
{
- if (model_str == list_models_com[0]) {
+ if (model_str == models_com.param_2button) {
model = MouseModelCOM::Microsoft;
auto_msm = false;
return true;
- } else if (model_str == list_models_com[1]) {
+ } else if (model_str == models_com.param_3button) {
model = MouseModelCOM::Logitech;
auto_msm = false;
return true;
- } else if (model_str == list_models_com[2]) {
+ } else if (model_str == models_com.param_wheel) {
model = MouseModelCOM::Wheel;
auto_msm = false;
return true;
- } else if (model_str == list_models_com[3]) {
+ } else if (model_str == models_com.param_msm) {
model = MouseModelCOM::MouseSystems;
auto_msm = false;
return true;
- } else if (model_str == list_models_com[4]) {
+ } else if (model_str == models_com.param_2button_msm) {
model = MouseModelCOM::Microsoft;
auto_msm = true;
return true;
- } else if (model_str == list_models_com[5]) {
+ } else if (model_str == models_com.param_3button_msm) {
model = MouseModelCOM::Logitech;
auto_msm = true;
return true;
- } else if (model_str == list_models_com[6]) {
+ } else if (model_str == models_com.param_wheel_msm) {
model = MouseModelCOM::Wheel;
auto_msm = true;
return true;
@@ -120,6 +141,21 @@ bool MouseConfig::ParseSerialModel(const std::string &model_str,
return false;
}
+bool MouseConfig::ParsePS2Model(const std::string &model_str, MouseModelPS2 &model)
+{
+ if (model_str == models_ps2.param_standard)
+ model = MouseModelPS2::Standard;
+ else if (model_str == models_ps2.param_intellimouse)
+ model = MouseModelPS2::IntelliMouse;
+#ifdef ENABLE_EXPLORER_MOUSE
+ else if (model_str == models_ps2.param_explorer)
+ model = MouseModelPS2::Explorer;
+#endif
+ else
+ return false;
+ return true;
+}
+
const std::vector<uint16_t> &MouseConfig::GetValidMinRateList()
{
return list_rates;
@@ -148,64 +184,11 @@ static void config_read(Section *section)
// Default mouse sensitivity
- auto sensitivity_from_str = [](const std::string &str) {
- const int32_t base_value = 50;
- int32_t ret_val = base_value; // default
- bool invalid_input = false;
-
- if (str.find('.') != std::string::npos) {
- // Parameter supplied in a form of floating point
- float tmp_float = 1.0f;
- try {
- tmp_float = std::stof(str);
- } catch (...) {
- invalid_input = true;
- tmp_float = 1.0f;
- }
- // We need 'tmp_float' to be positive for further calculations
- if (tmp_float < 0.0f) {
- tmp_float = -tmp_float;
- ret_val = -1;
- } else if (tmp_float > 0.0f)
- ret_val = 1;
- else
- ret_val = 0;
- // Now calculate user steps as a logarithm
- if (ret_val != 0) {
- tmp_float = std::log(tmp_float) / std::log(2.0f);
- tmp_float *= mouse_predefined.sensitivity_double_steps;
- tmp_float += static_cast<float>(base_value);
- const auto tmp_rounded = std::lround(
- std::max(tmp_float, 1.0f));
- ret_val = clamp_to_int8(ret_val * tmp_rounded);
- }
- } else if (!str.empty()) {
- // Parameter supplied in a form of integer
- try {
- ret_val = std::stoi(str);
- } catch (...) {
- invalid_input = true;
- ret_val = base_value;
- }
- }
-
- if (invalid_input)
- LOG_ERR("MOUSE: Invalid sensitivity value");
-
- const auto min = clamp_to_int8(-mouse_predefined.sensitivity_user_max);
- const auto max = clamp_to_int8(mouse_predefined.sensitivity_user_max);
- return std::clamp(clamp_to_int8(ret_val), min, max);
- };
-
PropMultiVal *prop_multi = conf->GetMultiVal("mouse_sensitivity");
- const std::string xsens = prop_multi->GetSection()->Get_string("xsens");
- const std::string ysens = prop_multi->GetSection()->Get_string("ysens");
-
- mouse_config.sensitivity_x = sensitivity_from_str(xsens);
- if (ysens.empty())
- mouse_config.sensitivity_y = mouse_config.sensitivity_x;
- else
- mouse_config.sensitivity_y = sensitivity_from_str(ysens);
+ mouse_config.sensitivity_x = static_cast<int16_t>(
+ prop_multi->GetSection()->Get_int("xsens"));
+ mouse_config.sensitivity_y = static_cast<int16_t>(
+ prop_multi->GetSection()->Get_int("ysens"));
// DOS driver configuration
@@ -214,42 +197,14 @@ static void config_read(Section *section)
// 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])
- mouse_config.model_ps2 = MouseModelPS2::IntelliMouse;
-#ifdef ENABLE_EXPLORER_MOUSE
- if (prop_str == list_models_ps2[2])
- mouse_config.model_ps2 = MouseModelPS2::Explorer;
-#endif
+ MouseConfig::ParsePS2Model(prop_str, mouse_config.model_ps2);
- // Serial (COM port) mice configuration
-
- auto set_model_com = [](const std::string &model_str,
- MouseModelCOM &model_var,
- bool &model_auto) {
- if (model_str == list_models_com[0] ||
- model_str == list_models_com[4])
- model_var = MouseModelCOM::Microsoft;
- if (model_str == list_models_com[1] ||
- model_str == list_models_com[5])
- model_var = MouseModelCOM::Logitech;
- if (model_str == list_models_com[2] ||
- model_str == list_models_com[6])
- model_var = MouseModelCOM::Wheel;
- if (model_str == list_models_com[3])
- model_var = MouseModelCOM::MouseSystems;
-
- if (model_str == list_models_com[4] ||
- model_str == list_models_com[5] ||
- model_str == list_models_com[6])
- model_auto = true;
- else
- model_auto = false;
- };
+ // COM port mouse configuration
prop_str = conf->Get_string("com_mouse_model");
- set_model_com(prop_str, mouse_config.model_com, mouse_config.model_com_auto_msm);
+ MouseConfig::ParseCOMModel(prop_str,
+ mouse_config.model_com,
+ mouse_config.model_com_auto_msm);
// Start mouse emulation if ready
mouse_shared.ready_config_mouse = true;
@@ -261,7 +216,8 @@ 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_bool *prop_bool = nullptr;
+ Prop_int *prop_int = nullptr;
Prop_string *prop_str = nullptr;
PropMultiVal *prop_multi = nullptr;
@@ -269,16 +225,19 @@ static void config_init(Section_prop &secprop)
prop_multi = secprop.AddMultiVal("mouse_sensitivity", only_at_start, ",");
prop_multi->Set_help(
- "Default mouse sensitivity.\n"
- "Integer values work exponentially, add 10 to double the effect.\n"
- "Alternatively, put 1.0 for base sensitivity, 1.5 do double sensitivity, etc.\n"
+ "Default mouse sensitivity. 100 is a base value, 150 is 150% sensitivity, etc.\n"
"Negative values reverse mouse direction, 0 disables the movement completely.\n"
- "The optional second parameter specifies vertical sensitivity (e.g. 1.5,3.0).\n"
+ "The optional second parameter specifies vertical sensitivity (e.g. 100,200).\n"
"Setting can be adjusted in runtime (also per mouse interface) using internal\n"
"MOUSECTL.COM tool, available on drive Z:.");
- prop_multi->SetValue("1.0");
- prop_multi->GetSection()->Add_string("xsens", only_at_start, "1.0");
- prop_multi->GetSection()->Add_string("ysens", only_at_start, "1.0");
+ prop_multi->SetValue("100");
+
+ prop_int = prop_multi->GetSection()->Add_int("xsens", only_at_start, 100);
+ prop_int->SetMinMax(-mouse_predefined.sensitivity_user_max,
+ mouse_predefined.sensitivity_user_max);
+ prop_int = prop_multi->GetSection()->Add_int("ysens", only_at_start, 100);
+ prop_int->SetMinMax(-mouse_predefined.sensitivity_user_max,
+ mouse_predefined.sensitivity_user_max);
prop_bool = secprop.Add_bool("mouse_raw_input", always, true);
prop_bool->Set_help(
diff --git a/src/hardware/mouse/mouse_config.h b/src/hardware/mouse/mouse_config.h
index 35ca040b0..b8e757342 100644
--- a/src/hardware/mouse/mouse_config.h
+++ b/src/hardware/mouse/mouse_config.h
@@ -32,21 +32,25 @@ 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 = 0.6f;
- const float sensitivity_ps2 = 0.6f;
- const float sensitivity_vmm = 1.8f;
- const float sensitivity_com = 0.6f;
+ const float sensitivity_dos = 1.0f;
+ const float sensitivity_ps2 = 1.0f;
+ const float sensitivity_vmm = 3.0f;
+ const float sensitivity_com = 1.0f;
// 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;
- // Maximum allowe user sensitivity value
- const int8_t sensitivity_user_max = 99;
+ // Maximum allowed user sensitivity value
+ const int16_t sensitivity_user_max = 999;
// How many user steps causes sensitivity to double
// (sensitivity works exponentially)
const float sensitivity_double_steps = 10.0f;
+
+ // IRQ used by PS/2 mouse - do not change unless you really know
+ // what you are doing!
+ const uint8_t IRQ_PS2 = 12;
};
extern MousePredefined mouse_predefined;
@@ -84,12 +88,11 @@ struct MouseConfig {
// From [mouse] section
- int8_t sensitivity_x = 50; // default sensitivity values
- int8_t sensitivity_y = 50;
- bool raw_input = false; // true = relative input is raw data
+ int16_t sensitivity_x = 50; // default sensitivity values
+ int16_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_driver = false; // whether DOS virtual mouse driver should be enabled
bool dos_immediate = false;
MouseModelPS2 model_ps2 = MouseModelPS2::Standard;
@@ -100,8 +103,9 @@ struct MouseConfig {
// Helper functions for external modules
static const std::vector<uint16_t> &GetValidMinRateList();
- static bool ParseSerialModel(const std::string &model_str,
- MouseModelCOM &model, bool &auto_msm);
+ static bool ParseCOMModel(const std::string &model_str,
+ MouseModelCOM &model, bool &auto_msm);
+ static bool ParsePS2Model(const std::string &model_str, MouseModelPS2 &model);
};
extern MouseConfig mouse_config;
diff --git a/src/hardware/mouse/mouse_interfaces.cpp b/src/hardware/mouse/mouse_interfaces.cpp
index 379e2554b..f2a3620a4 100644
--- a/src/hardware/mouse/mouse_interfaces.cpp
+++ b/src/hardware/mouse/mouse_interfaces.cpp
@@ -27,6 +27,8 @@
CHECK_NARROWING();
+static MouseQueue &mouse_queue = MouseQueue::GetInstance();
+
std::vector<MouseInterface *> mouse_interfaces = {};
// ***************************************************************************
@@ -34,18 +36,18 @@ std::vector<MouseInterface *> mouse_interfaces = {};
// ***************************************************************************
MouseInterfaceInfoEntry::MouseInterfaceInfoEntry(const MouseInterfaceId interface_id)
- : idx(static_cast<uint8_t>(interface_id))
+ : interface_idx(static_cast<uint8_t>(interface_id))
{}
const MouseInterface &MouseInterfaceInfoEntry::Interface() const
{
- return *mouse_interfaces[idx];
+ return *mouse_interfaces[interface_idx];
}
const MousePhysical &MouseInterfaceInfoEntry::MappedPhysical() const
{
- const auto idx = Interface().GetMappedDeviceIdx();
- return ManyMouseGlue::GetInstance().physical_devices[idx];
+ const auto mapped_idx = Interface().GetMappedDeviceIdx();
+ return ManyMouseGlue::GetInstance().physical_devices[mapped_idx];
}
bool MouseInterfaceInfoEntry::IsEmulated() const
@@ -90,12 +92,12 @@ const std::string &MouseInterfaceInfoEntry::GetMappedDeviceName() const
return MappedPhysical().GetName();
}
-int8_t MouseInterfaceInfoEntry::GetSensitivityX() const
+int16_t MouseInterfaceInfoEntry::GetSensitivityX() const
{
return Interface().GetSensitivityX();
}
-int8_t MouseInterfaceInfoEntry::GetSensitivityY() const
+int16_t MouseInterfaceInfoEntry::GetSensitivityY() const
{
return Interface().GetSensitivityY();
}
@@ -142,6 +144,9 @@ const std::string &MousePhysicalInfoEntry::GetDeviceName() const
class InterfaceDos final : public MouseInterface {
public:
+ InterfaceDos();
+ ~InterfaceDos() = default;
+
void NotifyMoved(MouseEvent &ev, const float x_rel, const float y_rel,
const uint16_t x_abs, const uint16_t y_abs) override;
void NotifyButton(MouseEvent &ev, const uint8_t idx,
@@ -153,8 +158,6 @@ public:
private:
friend class MouseInterface;
- InterfaceDos();
- ~InterfaceDos() = default;
InterfaceDos(const InterfaceDos &) = delete;
InterfaceDos &operator=(const InterfaceDos &) = delete;
@@ -167,6 +170,9 @@ private:
class InterfacePS2 final : public MouseInterface {
public:
+ InterfacePS2();
+ ~InterfacePS2() = default;
+
void NotifyMoved(MouseEvent &ev, const float x_rel, const float y_rel,
const uint16_t x_abs, const uint16_t y_abs) override;
void NotifyButton(MouseEvent &ev, const uint8_t idx,
@@ -176,8 +182,6 @@ public:
private:
friend class MouseInterface;
- InterfacePS2();
- ~InterfacePS2() = default;
InterfacePS2(const InterfacePS2 &other) = delete;
InterfacePS2 &operator=(const InterfacePS2 &other) = delete;
@@ -193,6 +197,9 @@ private:
class InterfaceCOM final : public MouseInterface {
public:
+ InterfaceCOM(const uint8_t port_id);
+ ~InterfaceCOM() = default;
+
void NotifyMoved(MouseEvent &ev, const float x_rel, const float y_rel,
const uint16_t x_abs, const uint16_t y_abs) override;
void NotifyButton(MouseEvent &ev, const uint8_t idx,
@@ -207,9 +214,7 @@ public:
private:
friend class MouseInterface;
- InterfaceCOM(const uint8_t port_id);
InterfaceCOM() = delete;
- ~InterfaceCOM() = default;
InterfaceCOM(const InterfaceCOM &) = delete;
InterfaceCOM &operator=(const InterfaceCOM &) = delete;
@@ -220,29 +225,40 @@ private:
// Base mouse interface
// ***************************************************************************
+static InterfaceDos interface_dos;
+static InterfacePS2 interface_ps2;
+static InterfaceCOM interface_com1(0);
+static InterfaceCOM interface_com2(1);
+static InterfaceCOM interface_com3(2);
+static InterfaceCOM interface_com4(3);
+
void MouseInterface::InitAllInstances()
{
if (!mouse_interfaces.empty())
return; // already initialized
- const auto i_first = static_cast<uint8_t>(MouseInterfaceId::First);
- const auto i_last = static_cast<uint8_t>(MouseInterfaceId::Last);
- const auto i_com1 = static_cast<uint8_t>(MouseInterfaceId::COM1);
+ const auto first = static_cast<uint8_t>(MouseInterfaceId::First);
+ const auto last = static_cast<uint8_t>(MouseInterfaceId::Last);
- for (uint8_t i = i_first; i <= i_last; i++)
+ for (uint8_t i = first; i <= last; i++)
switch (static_cast<MouseInterfaceId>(i)) {
case MouseInterfaceId::DOS:
- mouse_interfaces.emplace_back(new InterfaceDos());
+ mouse_interfaces.push_back(&interface_dos);
break;
case MouseInterfaceId::PS2:
- mouse_interfaces.emplace_back(new InterfacePS2());
+ mouse_interfaces.push_back(&interface_ps2);
break;
case MouseInterfaceId::COM1:
+ mouse_interfaces.push_back(&interface_com1);
+ break;
case MouseInterfaceId::COM2:
+ mouse_interfaces.push_back(&interface_com2);
+ break;
case MouseInterfaceId::COM3:
+ mouse_interfaces.push_back(&interface_com3);
+ break;
case MouseInterfaceId::COM4:
- mouse_interfaces.emplace_back(new InterfaceCOM(
- static_cast<uint8_t>(i - i_com1)));
+ mouse_interfaces.push_back(&interface_com4);
break;
default: assert(false); break;
}
@@ -290,11 +306,15 @@ MouseInterface::MouseInterface(const MouseInterfaceId interface_id,
: interface_id(interface_id),
sensitivity_predefined(sensitivity_predefined)
{
- ConfigResetSensitivity();
mouse_info.interfaces.emplace_back(MouseInterfaceInfoEntry(interface_id));
}
-void MouseInterface::Init() {}
+void MouseInterface::Init()
+{
+ // At this point configuration should already be loaded,
+ // so the default sensitivity is known
+ ConfigResetSensitivity();
+}
uint8_t MouseInterface::GetInterfaceIdx() const
{
@@ -347,12 +367,12 @@ uint8_t MouseInterface::GetMappedDeviceIdx() const
return mapped_idx;
}
-int8_t MouseInterface::GetSensitivityX() const
+int16_t MouseInterface::GetSensitivityX() const
{
return sensitivity_user_x;
}
-int8_t MouseInterface::GetSensitivityY() const
+int16_t MouseInterface::GetSensitivityY() const
{
return sensitivity_user_y;
}
@@ -362,9 +382,9 @@ uint16_t MouseInterface::GetRate() const
return rate_hz;
}
-void MouseInterface::NotifyInterfaceRate(const uint16_t value_hz)
+void MouseInterface::NotifyInterfaceRate(const uint16_t new_rate_hz)
{
- interface_rate_hz = value_hz;
+ interface_rate_hz = new_rate_hz;
UpdateRate();
}
@@ -437,30 +457,21 @@ void MouseInterface::ConfigReset()
ConfigResetMinRate();
}
-void MouseInterface::ConfigSetSensitivity(const int8_t value_x, const int8_t value_y)
+void MouseInterface::ConfigSetSensitivity(const int16_t value_x, const int16_t value_y)
{
- if (!IsEmulated())
- return;
-
sensitivity_user_x = value_x;
sensitivity_user_y = value_y;
UpdateSensitivity();
}
-void MouseInterface::ConfigSetSensitivityX(const int8_t value)
+void MouseInterface::ConfigSetSensitivityX(const int16_t value)
{
- if (!IsEmulated())
- return;
-
sensitivity_user_x = value;
UpdateSensitivity();
}
-void MouseInterface::ConfigSetSensitivityY(const int8_t value)
+void MouseInterface::ConfigSetSensitivityY(const int16_t value)
{
- if (!IsEmulated())
- return;
-
sensitivity_user_y = value;
UpdateSensitivity();
}
@@ -511,27 +522,12 @@ void MouseInterface::UpdateRawMapped() {}
void MouseInterface::UpdateSensitivity()
{
- 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
- // 1.5 times, but not 1.9 times - while the difference between
- // 5.0 and 5.4 times sensitivity increase is rather hard to
- // notice in a real life
-
- 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
+ auto calculate = [this](const int16_t setting) {
+ if (setting == 0)
return 0.0f;
-
- power /= mouse_predefined.sensitivity_double_steps;
- return scaling * std::pow(2.0f, power);
+ const float user_value = static_cast<float>(setting);
+ const float scaling = sensitivity_predefined / 100.0f;
+ return user_value * scaling;
};
sensitivity_coeff_x = calculate(sensitivity_user_x);
@@ -621,26 +617,26 @@ MouseButtons12S MouseInterface::GetButtonsSquished() const
InterfaceDos::InterfaceDos()
: MouseInterface(MouseInterfaceId::DOS, mouse_predefined.sensitivity_dos)
-{
- UpdateSensitivity();
-}
+{}
void InterfaceDos::Init()
{
- if (mouse_config.dos_driver)
+ MouseInterface::Init();
+ if (mouse_config.dos_driver) {
+ emulated = true;
MOUSEDOS_Init();
- else
- emulated = false;
+ }
MOUSEDOS_NotifyMinRate(min_rate_hz);
}
void InterfaceDos::NotifyMoved(MouseEvent &ev, const float x_rel, const float y_rel,
const uint16_t x_abs, const uint16_t y_abs)
{
- ev.dos_moved = MOUSEDOS_NotifyMoved(x_rel * sensitivity_coeff_x,
- y_rel * sensitivity_coeff_y,
- x_abs,
- y_abs);
+ ev.dos_moved = MOUSEDOS_NotifyMoved(x_rel * sensitivity_coeff_x,
+ y_rel * sensitivity_coeff_y,
+ x_abs,
+ y_abs);
+
ev.request_dos = ev.dos_moved;
}
@@ -686,17 +682,17 @@ void InterfaceDos::UpdateMinRate()
void InterfaceDos::UpdateRate()
{
MouseInterface::UpdateRate();
- MouseQueue::GetInstance().SetRateDOS(rate_hz);
+ mouse_queue.SetRateDOS(rate_hz);
}
InterfacePS2::InterfacePS2()
: MouseInterface(MouseInterfaceId::PS2, mouse_predefined.sensitivity_ps2)
-{
- UpdateSensitivity();
-}
+{}
void InterfacePS2::Init()
{
+ MouseInterface::Init();
+ emulated = true;
MOUSEPS2_Init();
MOUSEVMM_Init();
}
@@ -754,18 +750,14 @@ void InterfacePS2::UpdateSensitivity()
void InterfacePS2::UpdateRate()
{
MouseInterface::UpdateRate();
- MouseQueue::GetInstance().SetRatePS2(rate_hz);
+ mouse_queue.SetRatePS2(rate_hz);
}
InterfaceCOM::InterfaceCOM(const uint8_t port_id)
: MouseInterface(static_cast<MouseInterfaceId>(
static_cast<uint8_t>(MouseInterfaceId::COM1) + port_id),
mouse_predefined.sensitivity_com)
-{
- UpdateSensitivity();
- // Wait for CSerialMouse to register itself
- emulated = false;
-}
+{}
void InterfaceCOM::NotifyMoved(MouseEvent &, const float x_rel,
const float y_rel, const uint16_t, const uint16_t)
diff --git a/src/hardware/mouse/mouse_interfaces.h b/src/hardware/mouse/mouse_interfaces.h
index a0c754960..8974add8a 100644
--- a/src/hardware/mouse/mouse_interfaces.h
+++ b/src/hardware/mouse/mouse_interfaces.h
@@ -117,6 +117,10 @@ bool MOUSEVMM_NotifyWheel(const int16_t w_rel);
class MouseInterface {
public:
+ MouseInterface() = delete;
+ MouseInterface(const MouseInterface &) = delete;
+ MouseInterface &operator=(const MouseInterface &) = delete;
+
static void InitAllInstances();
static MouseInterface *Get(const MouseInterfaceId interface_id);
static MouseInterface *GetDOS();
@@ -129,7 +133,7 @@ public:
const bool pressed) = 0;
virtual void NotifyWheel(MouseEvent &ev, const int16_t w_rel) = 0;
- void NotifyInterfaceRate(const uint16_t rate_hz);
+ void NotifyInterfaceRate(const uint16_t new_rate_hz);
virtual void NotifyBooting();
void NotifyDisconnect();
@@ -142,8 +146,8 @@ public:
MouseInterfaceId GetInterfaceId() const;
MouseMapStatus GetMapStatus() const;
uint8_t GetMappedDeviceIdx() const;
- int8_t GetSensitivityX() const;
- int8_t GetSensitivityY() const;
+ int16_t GetSensitivityX() const;
+ int16_t GetSensitivityY() const;
uint16_t GetMinRate() const;
uint16_t GetRate() const;
@@ -152,9 +156,9 @@ public:
void ConfigOnOff(const bool enable);
void ConfigReset();
- 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 ConfigSetSensitivity(const int16_t value_x, const int16_t value_y);
+ void ConfigSetSensitivityX(const int16_t value);
+ void ConfigSetSensitivityY(const int16_t value);
void ConfigResetSensitivity();
void ConfigResetSensitivityX();
void ConfigResetSensitivityY();
@@ -191,30 +195,25 @@ protected:
MouseButtonsAll GetButtonsJoined() const;
MouseButtons12S GetButtonsSquished() const;
- bool emulated = true;
+ bool emulated = false;
- float sensitivity_coeff_x = 1.0f; // cached combined sensitivity
- // coefficients
+ float sensitivity_coeff_x = 1.0f; // cached combined sensitivity coefficients
float sensitivity_coeff_y = 1.0f; // to reduce amount of multiplications
- int8_t sensitivity_user_x = 0;
- int8_t sensitivity_user_y = 0;
+ int16_t sensitivity_user_x = 0;
+ int16_t sensitivity_user_y = 0;
uint16_t rate_hz = 0;
uint16_t min_rate_hz = 0;
uint16_t interface_rate_hz = 0;
private:
- MouseInterface() = delete;
- MouseInterface(const MouseInterface &) = delete;
- MouseInterface &operator=(const MouseInterface &) = delete;
-
const MouseInterfaceId interface_id = MouseInterfaceId::None;
MouseMapStatus map_status = MouseMapStatus::HostPointer;
uint8_t mapped_idx = idx_host_pointer; // index of mapped physical mouse
- MouseButtons12 buttons_12 = 0; // host side buttons 1 (left), 2 (right)
+ MouseButtons12 buttons_12 = 0; // host side buttons 1 (left), 2 (right)
MouseButtons345 buttons_345 = 0; // host side buttons 3 (middle), 4, and 5
MouseButtons12 old_buttons_12 = 0; // pre-update values
diff --git a/src/hardware/mouse/mouse_manymouse.cpp b/src/hardware/mouse/mouse_manymouse.cpp
index 1cacc84db..2a1b8a0fa 100644
--- a/src/hardware/mouse/mouse_manymouse.cpp
+++ b/src/hardware/mouse/mouse_manymouse.cpp
@@ -26,6 +26,8 @@
#include "pic.h"
#include "string_utils.h"
+#include <algorithm>
+
CHECK_NARROWING();
void manymouse_tick(uint32_t)
@@ -59,37 +61,49 @@ const std::string &MousePhysical::GetName() const
ManyMouseGlue &ManyMouseGlue::GetInstance()
{
- static ManyMouseGlue *instance = nullptr;
- if (!instance)
- instance = new ManyMouseGlue();
- return *instance;
+ static ManyMouseGlue manymouse_glue;
+ return manymouse_glue;
}
#if C_MANYMOUSE
+ManyMouseGlue::~ManyMouseGlue()
+{
+ PIC_RemoveEvents(manymouse_tick);
+ ManyMouse_Quit();
+}
+
void ManyMouseGlue::InitIfNeeded()
{
if (initialized || malfunction)
return;
- num_mice = ManyMouse_Init();
- if (num_mice < 0) {
+ // Initialize ManyMouse library, fetch number of mice
+
+ const auto result = ManyMouse_Init();
+
+ if (result < 0) {
+ malfunction = true;
+ num_mice = 0;
+
LOG_ERR("MOUSE: ManyMouse initialization failed");
ManyMouse_Quit();
- malfunction = true;
return;
- }
- initialized = true;
+ } else if (result > max_mice) {
+ num_mice = max_mice;
- if (num_mice >= max_mice) {
- num_mice = max_mice - 1;
- static bool logged = false;
- if (!logged) {
- logged = true;
+ static bool already_warned = false;
+ if (!already_warned) {
+ already_warned = true;
LOG_ERR("MOUSE: Up to %d simultaneously connected mice supported",
max_mice);
}
- }
+ } else
+ num_mice = static_cast<uint8_t>(result);
+
+ initialized = true;
+
+ // Get and log ManyMouse driver name
const auto new_driver_name = std::string(ManyMouse_DriverName());
if (new_driver_name != driver_name) {
@@ -97,6 +111,8 @@ void ManyMouseGlue::InitIfNeeded()
LOG_INFO("MOUSE: ManyMouse driver '%s'", driver_name.c_str());
}
+ // Scan for the physical mice
+
Rescan();
}
@@ -160,21 +176,22 @@ void ManyMouseGlue::Rescan()
std::string name;
UTF8_RenderForDos(name_utf8, name);
- const char character_nbsp = 0x7f; // non-breaking space
+ // Replace non-breaking space with a regular space
+ const char character_nbsp = 0x7f;
const char character_space = 0x20;
+ std::replace(name.begin(), name.end(), character_nbsp, character_space);
+ // Remove non-ASCII and control characters
for (auto pos = name.size(); pos > 0; pos--) {
- // Replace non-breaking space with a regular space
- if (name[pos - 1] == character_nbsp)
- name[pos - 1] = character_space;
- // Remove non-ASCII and control characters
if (name[pos - 1] < character_space ||
name[pos - 1] >= character_nbsp)
name.erase(pos - 1, 1);
}
- // Try to rework into something useful names in the forms
- // 'FooBar Corp FooBar Corp Incredible Mouse'
+ // Try to rework into something useful name if we receive
+ // something with double manufacturer name, for example change:
+ // 'FooBar Corp FooBar Corp Incredible Mouse' into
+ // 'FooBar Corp Incredible Mouse'
size_t pos = name.size() / 2 + 1;
while (--pos > 2) {
if (name[pos - 1] != ' ')
@@ -187,13 +204,15 @@ void ManyMouseGlue::Rescan()
}
// ManyMouse should limit device names to 64 characters,
- // but make sure name is indeed limited in length, and
- // strip trailing spaces
- name.resize(std::min(static_cast<size_t>(64), name.size()));
- while (!name.empty() && name.back() == ' ')
- name.pop_back();
+ // but make sure name is indeed limited in length
+ constexpr size_t max_size = 64;
+ if (name.size() > max_size)
+ name.resize(max_size);
+
+ // Strip trailing spaces, newlines, etc.
+ trim(name);
- physical_devices.emplace_back(MousePhysical(name));
+ physical_devices.emplace_back(name);
mouse_info.physical.emplace_back(MousePhysicalInfoEntry(
static_cast<uint8_t>(physical_devices.size() - 1)));
}
@@ -211,8 +230,10 @@ void ManyMouseGlue::RescanIfSafe()
bool ManyMouseGlue::ProbeForMapping(uint8_t &device_id)
{
// Wait a little to speedup screen update
+ constexpr uint32_t ticks_threshold = 50; // time to wait idle in PIC ticks
const auto pic_ticks_start = PIC_Ticks;
- while (PIC_Ticks >= pic_ticks_start && PIC_Ticks - pic_ticks_start < 50)
+ while (PIC_Ticks >= pic_ticks_start &&
+ PIC_Ticks - pic_ticks_start < ticks_threshold)
CALLBACK_Idle();
// Make sure the module is initialized,
@@ -228,7 +249,7 @@ bool ManyMouseGlue::ProbeForMapping(uint8_t &device_id)
HandleEvent(event, true); // handle critical events
bool success = false;
- while (true) {
+ while (!shutdown_requested) {
// Poll mouse events, handle critical ones
if (!ManyMouse_PollEvent(&event)) {
CALLBACK_Idle();
@@ -267,6 +288,8 @@ bool ManyMouseGlue::ProbeForMapping(uint8_t &device_id)
uint8_t ManyMouseGlue::GetIdx(const std::regex &regex)
{
+ assert(max_mice < UINT8_MAX);
+
// Try to match the mouse name which is not mapped yet
for (size_t i = 0; i < physical_devices.size(); i++) {
@@ -282,7 +305,7 @@ uint8_t ManyMouseGlue::GetIdx(const std::regex &regex)
return static_cast<uint8_t>(i);
}
- return max_mice; // return value which will be considered out of range
+ return max_mice + 1; // return value which will be considered out of range
}
void ManyMouseGlue::Map(const uint8_t physical_idx, const MouseInterfaceId interface_id)
@@ -420,6 +443,7 @@ void ManyMouseGlue::Tick()
HandleEvent(event);
// Report accumulated mouse movements
+ assert(rel_x.size() < UINT8_MAX);
for (uint8_t idx = 0; idx < rel_x.size(); idx++) {
if (rel_x[idx] == 0 && rel_y[idx] == 0)
continue;
@@ -440,6 +464,8 @@ void ManyMouseGlue::Tick()
// ManyMouse is not available
+ManyMouseGlue::~ManyMouseGlue() {}
+
void ManyMouseGlue::RescanIfSafe()
{
static bool already_warned = false;
diff --git a/src/hardware/mouse/mouse_manymouse.h b/src/hardware/mouse/mouse_manymouse.h
index 034aee515..66d6edb94 100644
--- a/src/hardware/mouse/mouse_manymouse.h
+++ b/src/hardware/mouse/mouse_manymouse.h
@@ -67,8 +67,8 @@ private:
friend class MouseInterfaceInfoEntry;
friend class MousePhysicalInfoEntry;
- ManyMouseGlue() = default;
- ~ManyMouseGlue() = delete;
+ ManyMouseGlue() = default;
+ ~ManyMouseGlue();
ManyMouseGlue(const ManyMouseGlue &) = delete;
ManyMouseGlue &operator=(const ManyMouseGlue &) = delete;
@@ -95,7 +95,7 @@ private:
// config API usage
uint32_t config_api_counter = 0;
- int num_mice = 0;
+ uint8_t num_mice = 0;
std::string driver_name = "";
@@ -103,7 +103,7 @@ private:
std::vector<int> rel_y = {};
static constexpr uint8_t max_buttons = 3;
- static constexpr uint8_t max_mice = UINT8_MAX;
+ static constexpr uint8_t max_mice = UINT8_MAX - 1;
static constexpr double tick_interval = 5.0;
#endif // C_MANYMOUSE
diff --git a/src/hardware/mouse/mouse_queue.cpp b/src/hardware/mouse/mouse_queue.cpp
index a9d173a37..282048561 100644
--- a/src/hardware/mouse/mouse_queue.cpp
+++ b/src/hardware/mouse/mouse_queue.cpp
@@ -66,10 +66,13 @@ void mouse_queue_tick(uint32_t)
MouseQueue &MouseQueue::GetInstance()
{
- static MouseQueue *instance = nullptr;
- if (!instance)
- instance = new MouseQueue();
- return *instance;
+ static MouseQueue mouse_queue;
+ return mouse_queue;
+}
+
+MouseQueue::~MouseQueue()
+{
+ PIC_RemoveEvents(mouse_queue_tick);
}
void MouseQueue::SetRateDOS(const uint16_t rate_hz)
@@ -142,7 +145,7 @@ void MouseQueue::AddEvent(MouseEvent &ev)
} else if (!timer_in_progress) {
DEBUG_QUEUE("ActivateIRQ, in %s", __FUNCTION__);
// If no timer in progress, handle the event now
- PIC_ActivateIRQ(12);
+ PIC_ActivateIRQ(mouse_predefined.IRQ_PS2);
}
}
@@ -259,9 +262,8 @@ void MouseQueue::UpdateDelayCounters()
if (!pic_ticks_start)
elapsed = 1;
- auto calc_new_delay = [](const uint8_t delay, const uint8_t elapsed) {
- return static_cast<uint8_t>((delay > elapsed) ? (delay - elapsed)
- : 0);
+ auto calc_new_delay = [](const uint8_t base_delay, const uint8_t elapsed) {
+ return static_cast<uint8_t>((base_delay > elapsed) ? (base_delay - elapsed) : 0);
};
delay.dos_ms = calc_new_delay(delay.dos_ms, elapsed);
@@ -281,7 +283,7 @@ void MouseQueue::Tick()
// interrupt; otherwise start the timer again
if (HasReadyEventDos() || HasReadyEventPS2()) {
DEBUG_QUEUE("ActivateIRQ, in %s", __FUNCTION__);
- PIC_ActivateIRQ(12);
+ PIC_ActivateIRQ(mouse_predefined.IRQ_PS2);
} else
StartTimerIfNeeded();
}
diff --git a/src/hardware/mouse/mouse_queue.h b/src/hardware/mouse/mouse_queue.h
index e5cfe3c2c..becc80641 100644
--- a/src/hardware/mouse/mouse_queue.h
+++ b/src/hardware/mouse/mouse_queue.h
@@ -34,8 +34,8 @@ public:
void StartTimerIfNeeded();
private:
- MouseQueue() = default;
- ~MouseQueue() = delete;
+ MouseQueue() = default;
+ ~MouseQueue();
MouseQueue(const MouseQueue &) = delete;
MouseQueue &operator=(const MouseQueue &) = delete;
diff --git a/src/hardware/mouse/mouseif_dos_driver.cpp b/src/hardware/mouse/mouseif_dos_driver.cpp
index 08e5111d6..81587c2e5 100644
--- a/src/hardware/mouse/mouseif_dos_driver.cpp
+++ b/src/hardware/mouse/mouseif_dos_driver.cpp
@@ -214,29 +214,17 @@ static RealPt user_callback;
static uint8_t signed_to_reg8(const int8_t x)
{
- if (x >= 0)
- return static_cast<uint8_t>(x);
- else
- // -1 for 0xff, -2 for 0xfe, etc.
- return static_cast<uint8_t>(0x100 + x);
+ return static_cast<uint8_t>(x);
}
static uint16_t signed_to_reg16(const int16_t x)
{
- if (x >= 0)
- return static_cast<uint16_t>(x);
- else
- // -1 for 0xffff, -2 for 0xfffe, etc.
- return static_cast<uint16_t>(0x10000 + x);
+ return static_cast<uint16_t>(x);
}
static int16_t reg_to_signed16(const uint16_t x)
{
- if (bit::is(x, b15))
- // 0xffff for -1, 0xfffe for -2, etc.
- return static_cast<int16_t>(x - 0x10000);
- else
- return static_cast<int16_t>(x);
+ return static_cast<int16_t>(x);
}
static uint16_t get_pos_x()
@@ -311,7 +299,7 @@ static void draw_cursor_text()
state.background.pos_x = state.background.pos_x / 2;
// use current page (CV program)
- uint8_t page = real_readb(BIOSMEM_SEG, BIOSMEM_CURRENT_PAGE);
+ const uint8_t page = real_readb(BIOSMEM_SEG, BIOSMEM_CURRENT_PAGE);
if (state.cursor_type == MouseCursor::Software) {
uint16_t result = 0;
@@ -342,7 +330,7 @@ static void draw_cursor_text()
state.background.pos_x) *
2);
address /= 2;
- uint16_t cr = real_readw(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS);
+ const uint16_t cr = real_readw(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS);
IO_Write(cr, 0xe);
IO_Write(static_cast<io_port_t>(cr + 1),
static_cast<uint8_t>((address >> 8) & 0xff));
@@ -710,7 +698,7 @@ static void reset_hardware()
state.wheel_api = false;
counter_w = 0;
- PIC_SetIRQMask(12, false); // lower IRQ line
+ PIC_SetIRQMask(mouse_predefined.IRQ_PS2, false); // lower IRQ line
// Reset mouse refresh rate
rate_is_set = false;
@@ -745,7 +733,7 @@ void MOUSEDOS_AfterNewVideoMode(const bool setmode)
{
state.inhibit_draw = false;
// Get the correct resolution from the current video mode
- uint8_t mode = mem_readb(BIOS_VIDEO_MODE);
+ const uint8_t mode = mem_readb(BIOS_VIDEO_MODE);
if (setmode && mode == state.mode)
LOG(LOG_MOUSE, LOG_NORMAL)
("New video mode is the same as the old");
@@ -921,8 +909,8 @@ static void move_cursor_seamless(const float x_rel, const float y_rel,
};
// Apply mouse movement to mimic host OS
- float x = calculate(x_abs, mouse_video.res_x, mouse_video.clip_x);
- float y = calculate(y_abs, mouse_video.res_y, mouse_video.clip_y);
+ const float x = calculate(x_abs, mouse_video.res_x, mouse_video.clip_x);
+ const float y = calculate(y_abs, mouse_video.res_y, mouse_video.clip_y);
// TODO: this is probably overcomplicated, especially
// the usage of relative movement - to be investigated
@@ -1568,10 +1556,10 @@ static Bitu int33_handler()
static Bitu mouse_bd_handler()
{
// the stack contains offsets to register values
- uint16_t raxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x0a));
- uint16_t rbxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x08));
- uint16_t rcxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x06));
- uint16_t rdxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x04));
+ const uint16_t raxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x0a));
+ const uint16_t rbxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x08));
+ const uint16_t rcxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x06));
+ const uint16_t rdxpt = real_readw(SegValue(ss), static_cast<uint16_t>(reg_sp + 0x04));
// read out the actual values, registers ARE overwritten
const uint16_t rax = real_readw(SegValue(ds), raxpt);
@@ -1684,11 +1672,11 @@ void MOUSEDOS_NotifyRawInput(const bool enabled)
void MOUSEDOS_Init()
{
// Callback for mouse interrupt 0x33
- auto call_int33 = CALLBACK_Allocate();
+ const auto call_int33 = CALLBACK_Allocate();
// RealPt int33_location = RealMake(CB_SEG + 1,(call_int33 * CB_SIZE) -
// 0x10);
- RealPt int33_location = RealMake(static_cast<uint16_t>(DOS_GetMemory(0x1) - 1),
- 0x10);
+ const RealPt int33_location =
+ RealMake(static_cast<uint16_t>(DOS_GetMemory(0x1) - 1), 0x10);
CALLBACK_Setup(call_int33,
&int33_handler,
CB_MOUSE,
@@ -1697,7 +1685,7 @@ void MOUSEDOS_Init()
// Wasteland needs low(seg(int33))!=0 and low(ofs(int33))!=0
real_writed(0, 0x33 << 2, int33_location);
- auto call_mouse_bd = CALLBACK_Allocate();
+ const auto call_mouse_bd = CALLBACK_Allocate();
CALLBACK_Setup(call_mouse_bd,
&mouse_bd_handler,
CB_RETF8,
@@ -1713,7 +1701,7 @@ void MOUSEDOS_Init()
// iret
// Callback for mouse user routine return
- auto call_user = CALLBACK_Allocate();
+ const auto call_user = CALLBACK_Allocate();
CALLBACK_Setup(call_user, &user_callback_handler, CB_RETF_CLI, "mouse user ret");
user_callback = CALLBACK_RealPointer(call_user);
diff --git a/src/hardware/mouse/mouseif_ps2_bios.cpp b/src/hardware/mouse/mouseif_ps2_bios.cpp
index 3ea8c9869..5ea009bb6 100644
--- a/src/hardware/mouse/mouseif_ps2_bios.cpp
+++ b/src/hardware/mouse/mouseif_ps2_bios.cpp
@@ -47,6 +47,14 @@ CHECK_NARROWING();
// - https://isdaman.com/alsos/hardware/mouse/ps2interface.htm
// - https://wiki.osdev.org/Mouse_Input
+static const std::vector<uint8_t> list_rates_hz = {
+ 10, 20, 40, 60, 80, 100, 200 // PS/2 mouse sampling rates
+};
+
+static const std::vector<uint8_t> list_resolutions = {
+ 1, 2, 4, 8 // PS/2 mouse resolution values
+};
+
static MouseButtonsAll buttons; // currently visible button state
static MouseButtonsAll buttons_all; // state of all 5 buttons as on the host side
static MouseButtons12S buttons_12S; // buttons with 3/4/5 quished together
@@ -85,7 +93,7 @@ void MOUSEPS2_UpdateButtonSquish()
buttons.data = squish ? buttons_12S.data : buttons_all.data;
}
-static void terminate_unlick_sequence()
+static void terminate_unlock_sequence()
{
unlock_idx_im = 0;
unlock_idx_xp = 0;
@@ -93,7 +101,7 @@ static void terminate_unlick_sequence()
static void set_protocol(const MouseModelPS2 new_protocol)
{
- terminate_unlick_sequence();
+ terminate_unlock_sequence();
static bool first_time = true;
if (first_time || protocol != new_protocol) {
@@ -153,13 +161,13 @@ static int16_t get_scaled_movement(const int16_t d)
case -5: return -9;
case -4: return -6;
case -3: return -3;
- case -2: return -1;
+ case -2: [[fallthrough]];
case -1: return -1;
- case 1: return 1;
- case 2: return 1;
- case 3: return 3;
- case 4: return 6;
- case 5: return 9;
+ case 1: [[fallthrough]];
+ case 2: return 1;
+ case 3: return 3;
+ case 4: return 6;
+ case 5: return 9;
default: return static_cast<int16_t>(2 * d);
}
}
@@ -208,21 +216,21 @@ void MOUSEPS2_UpdatePacket()
static_cast<int16_t>(-UINT8_MAX),
static_cast<int16_t>(UINT8_MAX));
} else {
- if ((dx > 0xff) || (dx < -0xff))
+ if ((dx > UINT8_MAX) || (dx < -UINT8_MAX))
mdat.overflow_x = 1;
- if ((dy > 0xff) || (dy < -0xff))
+ if ((dy > UINT8_MAX) || (dy < -UINT8_MAX))
mdat.overflow_y = 1;
}
- dx %= 0x100;
+ dx = static_cast<int16_t>(dx % (UINT8_MAX + 1));
if (dx < 0) {
- dx = static_cast<int16_t>(dx + 0x100);
+ dx = static_cast<int16_t>(dx + UINT8_MAX + 1);
mdat.sign_x = 1;
}
- dy %= 0x100;
+ dy = static_cast<int16_t>(dy % (UINT8_MAX + 1));
if (dy < 0) {
- dy = static_cast<int16_t>(dy + 0x100);
+ dy = static_cast<int16_t>(dy + UINT8_MAX + 1);
mdat.sign_y = 1;
}
@@ -244,7 +252,7 @@ void MOUSEPS2_UpdatePacket()
static void cmd_set_resolution(const uint8_t new_counts_mm)
{
- terminate_unlick_sequence();
+ terminate_unlock_sequence();
if (new_counts_mm != 1 && new_counts_mm != 2 && new_counts_mm != 4 &&
new_counts_mm != 8)
@@ -260,11 +268,9 @@ static void cmd_set_sample_rate(const uint8_t new_rate_hz)
{
reset_counters();
- if (new_rate_hz != 10 && new_rate_hz != 20 && new_rate_hz != 40 &&
- new_rate_hz != 60 && new_rate_hz != 80 && new_rate_hz != 100 &&
- new_rate_hz != 200) {
+ if (!std::binary_search(list_rates_hz.begin(), list_rates_hz.end(), new_rate_hz)) {
// Invalid parameter, set default
- terminate_unlick_sequence();
+ terminate_unlock_sequence();
rate_hz = 100;
} else
rate_hz = new_rate_hz;
@@ -273,9 +279,9 @@ static void cmd_set_sample_rate(const uint8_t new_rate_hz)
MouseInterface::GetPS2()->NotifyInterfaceRate(rate_hz);
// Handle extended mouse protocol unlock sequences
- auto unlock = [](const std::vector<uint8_t> &sequence,
- uint8_t &idx,
- const MouseModelPS2 potential_protocol) {
+ auto process_unlock = [](const std::vector<uint8_t> &sequence,
+ uint8_t &idx,
+ const MouseModelPS2 potential_protocol) {
if (sequence[idx] != rate_hz)
idx = 0;
else if (sequence.size() == ++idx) {
@@ -283,14 +289,18 @@ static void cmd_set_sample_rate(const uint8_t new_rate_hz)
}
};
- static const std::vector<uint8_t> seq_im = {200, 100, 80};
- static const std::vector<uint8_t> seq_xp = {200, 200, 80};
+ static const std::vector<uint8_t> unlock_sequence_im = {200, 100, 80};
+ static const std::vector<uint8_t> unlock_sequence_xp = {200, 200, 80};
if (mouse_config.model_ps2 == MouseModelPS2::IntelliMouse)
- unlock(seq_im, unlock_idx_im, MouseModelPS2::IntelliMouse);
+ process_unlock(unlock_sequence_im,
+ unlock_idx_im,
+ MouseModelPS2::IntelliMouse);
else if (mouse_config.model_ps2 == MouseModelPS2::Explorer) {
- unlock(seq_im, unlock_idx_im, MouseModelPS2::IntelliMouse);
- unlock(seq_xp, unlock_idx_xp, MouseModelPS2::Explorer);
+ process_unlock(unlock_sequence_im,
+ unlock_idx_im,
+ MouseModelPS2::IntelliMouse);
+ process_unlock(unlock_sequence_xp, unlock_idx_xp, MouseModelPS2::Explorer);
}
}
@@ -311,7 +321,7 @@ static void cmd_reset()
static void cmd_set_scaling_21(const bool enable)
{
- terminate_unlick_sequence();
+ terminate_unlock_sequence();
scaling_21 = enable;
}
@@ -321,7 +331,12 @@ bool MOUSEPS2_NotifyMoved(const float x_rel, const float y_rel)
delta_x = MOUSE_ClampRelativeMovement(delta_x + x_rel);
delta_y = MOUSE_ClampRelativeMovement(delta_y + y_rel);
- return (std::fabs(delta_x) >= 0.5f) || (std::fabs(delta_y) >= 0.5f);
+ // Threshold the accumulated movement needs to cross
+ // to be considered significant enough for new event
+ constexpr float threshold = 0.5f;
+
+ return (std::fabs(delta_x) >= threshold) ||
+ (std::fabs(delta_y) >= threshold);
}
bool MOUSEPS2_NotifyButton(const MouseButtons12S new_buttons_12S,
@@ -370,8 +385,8 @@ static RealPt ps2_callback = 0;
void MOUSEBIOS_Reset()
{
cmd_reset();
- PIC_SetIRQMask(12, false); // lower IRQ line
- MOUSEVMM_Deactivate(); // VBADOS seems to expect this
+ PIC_SetIRQMask(mouse_predefined.IRQ_PS2, false); // lower IRQ line
+ MOUSEVMM_Deactivate(); // VBADOS seems to expect this
}
void MOUSEBIOS_SetCallback(const uint16_t pseg, const uint16_t pofs)
@@ -399,30 +414,19 @@ bool MOUSEBIOS_SetPacketSize(const uint8_t packet_size)
bool MOUSEBIOS_SetSampleRate(const uint8_t rate_id)
{
- switch (rate_id) {
- case 0: cmd_set_sample_rate(10); break;
- case 1: cmd_set_sample_rate(20); break;
- case 2: cmd_set_sample_rate(40); break;
- case 3: cmd_set_sample_rate(60); break;
- case 4: cmd_set_sample_rate(80); break;
- case 5: cmd_set_sample_rate(100); break;
- case 6: cmd_set_sample_rate(200); break;
- default: return false;
- }
+ if (rate_id >= list_rates_hz.size())
+ return false;
+ cmd_set_sample_rate(list_rates_hz[rate_id]);
return true;
}
bool MOUSEBIOS_SetResolution(const uint8_t res_id)
{
- switch (res_id) {
- case 0: cmd_set_resolution(1); break;
- case 1: cmd_set_resolution(2); break;
- case 2: cmd_set_resolution(4); break;
- case 3: cmd_set_resolution(8); break;
- default: return false;
- }
+ if (res_id >= list_resolutions.size())
+ return false;
+ cmd_set_sample_rate(list_resolutions[res_id]);
return true;
}
@@ -431,17 +435,18 @@ void MOUSEBIOS_SetScaling21(const bool enable)
cmd_set_scaling_21(enable);
}
-bool MOUSEBIOS_SetState(const bool use)
+bool MOUSEBIOS_Enable()
{
- if (use && !callback_init) {
- mouse_shared.active_bios = false;
- MOUSE_NotifyStateChanged();
- return false;
- } else {
- mouse_shared.active_bios = use;
- MOUSE_NotifyStateChanged();
- return true;
- }
+ mouse_shared.active_bios = callback_init;
+ MOUSE_NotifyStateChanged();
+ return callback_init;
+}
+
+bool MOUSEBIOS_Disable()
+{
+ mouse_shared.active_bios = false;
+ MOUSE_NotifyStateChanged();
+ return true;
}
uint8_t MOUSEBIOS_GetResolution()
@@ -504,7 +509,7 @@ Bitu MOUSEBIOS_DoCallback()
CPU_Push16(packet[2]);
CPU_Push16(packet[3]);
}
- CPU_Push16((uint16_t)0);
+ CPU_Push16(0u);
CPU_Push16(RealSeg(ps2_callback));
CPU_Push16(RealOff(ps2_callback));
@@ -517,7 +522,7 @@ Bitu MOUSEBIOS_DoCallback()
void MOUSEPS2_Init()
{
// Callback for ps2 user callback handling
- auto call_ps2 = CALLBACK_Allocate();
+ const auto call_ps2 = CALLBACK_Allocate();
CALLBACK_Setup(call_ps2, &callback_ret, CB_RETF, "ps2 bios callback");
ps2_callback = CALLBACK_RealPointer(call_ps2);
diff --git a/src/hardware/serialport/serialmouse.cpp b/src/hardware/serialport/serialmouse.cpp
index 745f740a1..1dc9dee73 100644
--- a/src/hardware/serialport/serialmouse.cpp
+++ b/src/hardware/serialport/serialmouse.cpp
@@ -62,7 +62,7 @@ CSerialMouse::CSerialMouse(const uint8_t id, CommandLine *cmd)
std::string model_string;
if (cmd->FindStringBegin("model:", model_string, false) &&
- !MouseConfig::ParseSerialModel(model_string, param_model, param_auto_msm)) {
+ !MouseConfig::ParseCOMModel(model_string, param_model, param_auto_msm)) {
LOG_ERR("MOUSE (COM%d): Invalid model '%s'",
port_num,
model_string.c_str());
@@ -139,9 +139,7 @@ void CSerialMouse::BoostRate(const uint16_t rate_hz)
}
// Estimate current sampling rate, as precisely as possible
- auto estimate = [](const uint16_t bauds,
- const uint8_t byte_len,
- const MouseModelCOM model) {
+ auto estimate = [this](const uint16_t bauds) {
// In addition to byte_len, the mouse has to send
// 3 more bits per each byte: start, parity, stop
@@ -149,19 +147,19 @@ void CSerialMouse::BoostRate(const uint16_t rate_hz)
model == MouseModelCOM::Logitech || model == MouseModelCOM::Wheel)
// Microsoft-style protocol
// single movement needs exactly 3 bytes to be reported
- return bauds / (static_cast<float>(byte_len + 3) * 3.0f);
+ return bauds / (static_cast<float>(port_byte_len + 3) * 3.0f);
else if (model == MouseModelCOM::MouseSystems)
// Mouse Systems protocol
// single movement needs per average 2.5 bytes to be
// reported
- return bauds / (static_cast<float>(byte_len + 3) * 2.5f);
+ return bauds / (static_cast<float>(port_byte_len + 3) * 2.5f);
assert(false); // unimplemented
return static_cast<float>(rate_1200_baud);
};
// Calculate coefficient to match requested rate
- rate_coeff = estimate(1200, port_byte_len, model) / rate_hz;
+ rate_coeff = estimate(1200) / rate_hz;
}
void CSerialMouse::SetModel(const MouseModelCOM new_model)
diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp
index b766c35af..b3740cfa2 100644
--- a/src/ints/bios.cpp
+++ b/src/ints/bios.cpp
@@ -951,12 +951,12 @@ static Bitu INT15_Handler(void) {
case 0xc2: /* BIOS PS2 Pointing Device Support */
switch (reg_al) {
case 0x00: // enable/disable
- if (reg_bh == 0) { // disable
- MOUSEBIOS_SetState(false);
+ if (reg_bh == 0) { // disable
+ MOUSEBIOS_Disable();
reg_ah = 0;
CALLBACK_SCF(false);
} else if (reg_bh == 0x01) { // enable
- if (!MOUSEBIOS_SetState(true)) {
+ if (!MOUSEBIOS_Enable()) {
reg_ah = 5;
CALLBACK_SCF(true);
break;
@@ -978,7 +978,7 @@ static Bitu INT15_Handler(void) {
reg_ah = 2;
break;
}
- MOUSEBIOS_SetState(false);
+ MOUSEBIOS_Disable();
CALLBACK_SCF(false);
reg_ah=0;
break;