mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-21 09:40:01 +00:00
Modules/cellGem: Implement pos, quat and handle_pos in Gemstate for mouse.
Modules/cellGem: Fix name for gem_image_state. Modules/cellGem: Implement projectiion(x/y) in gem_image_State for mouse. Modules/cellGem: Add cross, triangle, circle and start with use middle click for mouse. Modules/cellGem: Refactor global code. Modules/cellGem: fix some warning with initializing value.
This commit is contained in:
parent
ac2b0c9752
commit
af8ebc76e2
@ -7,6 +7,7 @@
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "pad_thread.h"
|
||||
#include "Emu/Io/MouseHandler.h"
|
||||
#include "Emu/RSX/GSRender.h"
|
||||
#include "Utilities/Timer.h"
|
||||
|
||||
LOG_CHANNEL(cellGem);
|
||||
@ -80,31 +81,27 @@ struct gem_config
|
||||
|
||||
struct gem_controller
|
||||
{
|
||||
u32 status; // connection status (CELL_GEM_STATUS_DISCONNECTED or CELL_GEM_STATUS_READY)
|
||||
u32 ext_status; // external port connection status
|
||||
u32 port; // assigned port
|
||||
bool enabled_magnetometer; // whether the magnetometer is enabled (probably used for additional rotational precision)
|
||||
bool calibrated_magnetometer; // whether the magnetometer is calibrated
|
||||
bool enabled_filtering; // whether filtering is enabled
|
||||
bool enabled_tracking; // whether tracking is enabled
|
||||
bool enabled_LED; // whether the LED is enabled
|
||||
u8 rumble; // rumble intensity
|
||||
gem_color sphere_rgb; // RGB color of the sphere LED
|
||||
u32 hue; // tracking hue of the motion controller
|
||||
|
||||
gem_controller() :
|
||||
status(CELL_GEM_STATUS_DISCONNECTED),
|
||||
enabled_filtering(false), rumble(0), sphere_rgb() {}
|
||||
u32 status = CELL_GEM_STATUS_DISCONNECTED; // Connection status (CELL_GEM_STATUS_DISCONNECTED or CELL_GEM_STATUS_READY)
|
||||
u32 ext_status = CELL_GEM_NO_EXTERNAL_PORT_DEVICE; // External port connection status
|
||||
u32 port = 0; // Assigned port
|
||||
bool enabled_magnetometer = false; // Whether the magnetometer is enabled (probably used for additional rotational precision)
|
||||
bool calibrated_magnetometer = false; // Whether the magnetometer is calibrated
|
||||
bool enabled_filtering = false; // Whether filtering is enabled
|
||||
bool enabled_tracking = false; // Whether tracking is enabled
|
||||
bool enabled_LED = false; // Whether the LED is enabled
|
||||
u8 rumble = 0; // Rumble intensity
|
||||
gem_color sphere_rgb = {}; // RGB color of the sphere LED
|
||||
u32 hue = 0; // Tracking hue of the motion controller
|
||||
};
|
||||
|
||||
CellGemAttribute attribute;
|
||||
CellGemVideoConvertAttribute vc_attribute;
|
||||
u64 status_flags;
|
||||
bool enable_pitch_correction;
|
||||
u32 inertial_counter;
|
||||
CellGemAttribute attribute = {};
|
||||
CellGemVideoConvertAttribute vc_attribute = {};
|
||||
u64 status_flags = CELL_GEM_NOT_CALIBRATED;
|
||||
bool enable_pitch_correction = false;
|
||||
u32 inertial_counter = 0;
|
||||
|
||||
std::array<gem_controller, CELL_GEM_MAX_NUM> controllers;
|
||||
u32 connected_controllers;
|
||||
u32 connected_controllers = 0;
|
||||
bool update_started{};
|
||||
u32 camera_frame{};
|
||||
u32 memory_ptr{};
|
||||
@ -123,33 +120,20 @@ struct gem_config
|
||||
{
|
||||
switch (g_cfg.io.move)
|
||||
{
|
||||
default:
|
||||
case move_handler::null:
|
||||
{
|
||||
connected_controllers = 0;
|
||||
|
||||
controllers[gem_num].status = CELL_GEM_STATUS_DISCONNECTED;
|
||||
controllers[gem_num].port = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case move_handler::fake:
|
||||
case move_handler::mouse:
|
||||
{
|
||||
// fake one connected controller
|
||||
connected_controllers = 1;
|
||||
|
||||
if (gem_num < connected_controllers)
|
||||
{
|
||||
controllers[gem_num].status = CELL_GEM_STATUS_READY;
|
||||
controllers[gem_num].port = 7u - gem_num;
|
||||
}
|
||||
else
|
||||
{
|
||||
controllers[gem_num].status = CELL_GEM_STATUS_DISCONNECTED;
|
||||
controllers[gem_num].port = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Assign status and port number
|
||||
if (gem_num < connected_controllers)
|
||||
{
|
||||
controllers[gem_num].status = CELL_GEM_STATUS_READY;
|
||||
controllers[gem_num].port = 7u - gem_num;
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -167,6 +151,7 @@ void fmt_class_string<move_handler>::format(std::string& out, u64 arg)
|
||||
{
|
||||
case move_handler::null: return "Null";
|
||||
case move_handler::fake: return "Fake";
|
||||
case move_handler::mouse: return "Mouse";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
@ -306,40 +291,113 @@ static bool ds3_input_to_ext(const u32 port_no, CellGemExtPortData& ext)
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Maps Move controller data (digital buttons, and analog Trigger data) to mouse input.
|
||||
* Move Button: Mouse1
|
||||
* Trigger: Mouse2
|
||||
* \param mouse_no Mouse index number to use
|
||||
* \param digital_buttons Bitmask filled with CELL_GEM_CTRL_* values
|
||||
* \param analog_t Analog value of Move's Trigger.
|
||||
* \return true on success, false if mouse mouse_no is invalid
|
||||
*/
|
||||
static bool map_to_mouse_input(const u32 mouse_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
|
||||
* \brief Maps Move controller data (digital buttons, and analog Trigger data) to mouse input.
|
||||
* Move Button: Mouse1
|
||||
* Trigger: Mouse2
|
||||
* \param mouse_no Mouse index number to use
|
||||
* \param digital_buttons Bitmask filled with CELL_GEM_CTRL_* values
|
||||
* \param analog_t Analog value of Move's Trigger.
|
||||
* \return true on success, false if mouse mouse_no is invalid
|
||||
*/
|
||||
static bool mouse_input_to_pad(const u32 mouse_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
|
||||
{
|
||||
const auto handler = g_fxo->get<MouseHandlerBase>();
|
||||
|
||||
if (handler->GetInfo().status[mouse_no] != CELL_MOUSE_STATUS_CONNECTED)
|
||||
std::scoped_lock lock(handler->mutex);
|
||||
|
||||
if (!handler || mouse_no >= handler->GetMice().size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MouseDataList& mouse_data_list = handler->GetDataList(mouse_no);
|
||||
memset(&digital_buttons, 0, sizeof(digital_buttons));
|
||||
|
||||
if (mouse_data_list.size())
|
||||
const auto& mouse_data = handler->GetMice().at(0);
|
||||
|
||||
if ((mouse_data.buttons & CELL_MOUSE_BUTTON_1) && (mouse_data.buttons & CELL_MOUSE_BUTTON_2))
|
||||
digital_buttons |= CELL_GEM_CTRL_CIRCLE;
|
||||
if (mouse_data.buttons & CELL_MOUSE_BUTTON_3)
|
||||
digital_buttons |= CELL_GEM_CTRL_CROSS;
|
||||
if (mouse_data.buttons & CELL_MOUSE_BUTTON_2)
|
||||
digital_buttons |= CELL_GEM_CTRL_MOVE;
|
||||
if ((mouse_data.buttons & CELL_MOUSE_BUTTON_1) && (mouse_data.buttons & CELL_MOUSE_BUTTON_3))
|
||||
digital_buttons |= CELL_GEM_CTRL_START;
|
||||
if (mouse_data.buttons & CELL_MOUSE_BUTTON_1)
|
||||
digital_buttons |= CELL_GEM_CTRL_T;
|
||||
if ((mouse_data.buttons & CELL_MOUSE_BUTTON_2) && (mouse_data.buttons & CELL_MOUSE_BUTTON_3))
|
||||
digital_buttons |= CELL_GEM_CTRL_TRIANGLE;
|
||||
|
||||
analog_t = mouse_data.buttons & (CELL_MOUSE_BUTTON_1 ? 0xFFFF : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mouse_pos_to_gem_image_state(const u32 mouse_no, vm::ptr<CellGemImageState>& gem_image_state)
|
||||
{
|
||||
const auto handler = g_fxo->get<MouseHandlerBase>();
|
||||
|
||||
std::scoped_lock lock(handler->mutex);
|
||||
|
||||
if (!gem_image_state || !handler || mouse_no >= handler->GetMice().size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& mouse = handler->GetMice().at(0);
|
||||
|
||||
const auto renderer = static_cast<GSRender*>(rsx::get_current_renderer());
|
||||
const auto width = renderer->get_frame()->client_width();
|
||||
const auto hight = renderer->get_frame()->client_height();
|
||||
const f32 scaling_width = width / 640.f;
|
||||
const f32 scaling_hight = hight / 480.f;
|
||||
|
||||
const f32 x = static_cast<f32>(mouse.x_pos) / scaling_width;
|
||||
const f32 y = static_cast<f32>(mouse.y_pos) / scaling_hight;
|
||||
|
||||
gem_image_state->u = 133.f + (x / 1.50f);
|
||||
gem_image_state->v = 160.f + (y / 1.67f);
|
||||
gem_image_state->projectionx = x - 320.f;
|
||||
gem_image_state->projectiony = 240.f - y;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mouse_pos_to_gem_state(const u32 mouse_no, vm::ptr<CellGemState>& gem_state)
|
||||
{
|
||||
const auto handler = g_fxo->get<MouseHandlerBase>();
|
||||
|
||||
std::scoped_lock lock(handler->mutex);
|
||||
|
||||
if (!gem_state || !handler || mouse_no >= handler->GetMice().size())
|
||||
{
|
||||
const MouseData& mouse_data = mouse_data_list.front();
|
||||
|
||||
if (mouse_data.buttons & CELL_MOUSE_BUTTON_1)
|
||||
digital_buttons |= CELL_GEM_CTRL_T;
|
||||
|
||||
if (mouse_data.buttons & CELL_MOUSE_BUTTON_2)
|
||||
digital_buttons |= CELL_GEM_CTRL_MOVE;
|
||||
|
||||
analog_t = mouse_data.buttons & CELL_MOUSE_BUTTON_1 ? 0xFFFF : 0;
|
||||
|
||||
mouse_data_list.pop_front();
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& mouse = handler->GetMice().at(0);
|
||||
|
||||
const auto renderer = static_cast<GSRender*>(rsx::get_current_renderer());
|
||||
const auto width = renderer->get_frame()->client_width();
|
||||
const auto hight = renderer->get_frame()->client_height();
|
||||
|
||||
const f32 scaling_width = width / 640.f;
|
||||
const f32 scaling_hight = hight / 480.f;
|
||||
const f32 x = static_cast<f32>(mouse.x_pos) / scaling_width;
|
||||
const f32 y = static_cast<f32>(mouse.y_pos) / scaling_hight;
|
||||
|
||||
gem_state->pos[0] = x;
|
||||
gem_state->pos[1] = -y;
|
||||
gem_state->pos[2] = 1500.f;
|
||||
gem_state->pos[3] = 0.f;
|
||||
|
||||
gem_state->quat[0] = 320.f - x;
|
||||
gem_state->quat[1] = (mouse.y_pos / scaling_width) - 180.f;
|
||||
gem_state->quat[2] = 1200.f;
|
||||
|
||||
gem_state->handle_pos[0] = x;
|
||||
gem_state->handle_pos[1] = y;
|
||||
gem_state->handle_pos[2] = 1500.f;
|
||||
gem_state->handle_pos[3] = 0.f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -365,9 +423,11 @@ error_code cellGemCalibrate(u32 gem_num)
|
||||
return CELL_GEM_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake)
|
||||
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
gem->controllers[gem_num].calibrated_magnetometer = true;
|
||||
gem->controllers[gem_num].enabled_tracking = true;
|
||||
gem->controllers[gem_num].hue = 1;
|
||||
gem->status_flags = CELL_GEM_FLAG_CALIBRATION_OCCURRED | CELL_GEM_FLAG_CALIBRATION_SUCCEEDED;
|
||||
}
|
||||
|
||||
@ -580,7 +640,7 @@ error_code cellGemGetCameraState(vm::ptr<CellGemCameraState> camera_state)
|
||||
return CELL_GEM_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
camera_state->exposure_time = 1.0f / 60.0f; // TODO: use correct framerate
|
||||
camera_state->exposure_time = 1.0f / 60.0f; // TODO: use correct framerate
|
||||
camera_state->gain = 1.0;
|
||||
|
||||
return CELL_OK;
|
||||
@ -629,9 +689,9 @@ error_code cellGemGetHuePixels(vm::cptr<void> camera_frame, u32 hue, vm::ptr<u8>
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellGemGetImageState(u32 gem_num, vm::ptr<CellGemImageState> image_state)
|
||||
error_code cellGemGetImageState(u32 gem_num, vm::ptr<CellGemImageState> gem_image_state)
|
||||
{
|
||||
cellGem.todo("cellGemGetImageState(gem_num=%d, image_state=&0x%x)", gem_num, image_state);
|
||||
cellGem.todo("cellGemGetImageState(gem_num=%d, image_state=&0x%x)", gem_num, gem_image_state);
|
||||
|
||||
const auto gem = g_fxo->get<gem_config>();
|
||||
|
||||
@ -640,40 +700,31 @@ error_code cellGemGetImageState(u32 gem_num, vm::ptr<CellGemImageState> image_st
|
||||
return CELL_GEM_ERROR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!check_gem_num(gem_num) || !image_state)
|
||||
if (!check_gem_num(gem_num) || !gem_image_state)
|
||||
{
|
||||
return CELL_GEM_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake &&
|
||||
g_cfg.io.mouse == mouse_handler::basic)
|
||||
auto shared_data = g_fxo->get<gem_camera_shared>();
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake)
|
||||
{
|
||||
auto shared_data = g_fxo->get<gem_camera_shared>();
|
||||
gem_image_state->u = 0;
|
||||
gem_image_state->v = 0;
|
||||
gem_image_state->projectionx = 1;
|
||||
gem_image_state->projectiony = 1;
|
||||
}
|
||||
else if (g_cfg.io.move == move_handler::mouse)
|
||||
mouse_pos_to_gem_image_state(gem_num, gem_image_state);
|
||||
|
||||
const auto handler = fxm::get<MouseHandlerBase>();
|
||||
auto& mouse = handler->GetMice().at(0);
|
||||
|
||||
f32 x_pos = mouse.x_pos;
|
||||
f32 y_pos = mouse.y_pos;
|
||||
|
||||
static constexpr auto aspect_ratio = 1.2;
|
||||
|
||||
static constexpr auto screen_offset_x = 400.0;
|
||||
static constexpr auto screen_offset_y = screen_offset_x * aspect_ratio;
|
||||
|
||||
static constexpr auto screen_scale = 3.0;
|
||||
|
||||
image_state->frame_timestamp = shared_data->frame_timestamp.load();
|
||||
image_state->timestamp = image_state->frame_timestamp + 10; // arbitrarily define 10 usecs of frame processing
|
||||
image_state->visible = true;
|
||||
image_state->u = screen_offset_x / screen_scale + x_pos / screen_scale;
|
||||
image_state->v = screen_offset_y / screen_scale + y_pos / screen_scale * aspect_ratio;
|
||||
image_state->r = 10;
|
||||
image_state->r_valid = true;
|
||||
image_state->distance = 2 * 1000; // 2 meters away from camera
|
||||
// TODO
|
||||
image_state->projectionx = 1;
|
||||
image_state->projectiony = 1;
|
||||
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
gem_image_state->frame_timestamp = shared_data->frame_timestamp.load();
|
||||
gem_image_state->timestamp = gem_image_state->frame_timestamp + 10;
|
||||
gem_image_state->r = 10;
|
||||
gem_image_state->distance = 2 * 1000; // 2 meters away from camera
|
||||
gem_image_state->visible = true;
|
||||
gem_image_state->r_valid = true;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@ -698,19 +749,16 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
|
||||
}
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake)
|
||||
{
|
||||
ds3_input_to_pad(gem_num, inertial_state->pad.digitalbuttons, inertial_state->pad.analog_T);
|
||||
else if (g_cfg.io.move == move_handler::mouse)
|
||||
mouse_input_to_pad(gem_num, inertial_state->pad.digitalbuttons, inertial_state->pad.analog_T);
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
ds3_input_to_ext(gem_num, inertial_state->ext);
|
||||
|
||||
if (g_cfg.io.mouse == mouse_handler::basic)
|
||||
{
|
||||
map_to_mouse_input(gem_num, inertial_state->pad.digitalbuttons, inertial_state->pad.analog_T);
|
||||
}
|
||||
|
||||
inertial_state->timestamp = gem->timer.GetElapsedTimeInMicroSec();
|
||||
|
||||
inertial_state->counter = gem->inertial_counter++;
|
||||
|
||||
inertial_state->accelerometer[0] = 10;
|
||||
}
|
||||
|
||||
@ -778,7 +826,7 @@ error_code cellGemGetRGB(u32 gem_num, vm::ptr<float> r, vm::ptr<float> g, vm::pt
|
||||
return CELL_GEM_ERROR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!check_gem_num(gem_num) || !r || !g || !b )
|
||||
if (!check_gem_num(gem_num) || !r || !g || !b)
|
||||
{
|
||||
return CELL_GEM_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
@ -833,19 +881,21 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
|
||||
}
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake)
|
||||
{
|
||||
ds3_input_to_pad(gem_num, gem_state->pad.digitalbuttons, gem_state->pad.analog_T);
|
||||
ds3_input_to_ext(gem_num, gem_state->ext);
|
||||
else if (g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
mouse_input_to_pad(gem_num, gem_state->pad.digitalbuttons, gem_state->pad.analog_T);
|
||||
mouse_pos_to_gem_state(gem_num, gem_state);
|
||||
}
|
||||
|
||||
if (g_cfg.io.mouse == mouse_handler::basic)
|
||||
{
|
||||
map_to_mouse_input(gem_num, gem_state->pad.digitalbuttons, gem_state->pad.analog_T);
|
||||
}
|
||||
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
ds3_input_to_ext(gem_num, gem_state->ext);
|
||||
|
||||
gem_state->tracking_flags = CELL_GEM_TRACKING_FLAG_POSITION_TRACKED | CELL_GEM_TRACKING_FLAG_VISIBLE;
|
||||
gem_state->timestamp = gem->timer.GetElapsedTimeInMicroSec();
|
||||
gem_state->quat[3] = 1.f;
|
||||
|
||||
gem_state->quat[3] = 1.0;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -959,13 +1009,12 @@ error_code cellGemInit(vm::cptr<CellGemAttribute> attribute)
|
||||
gem->status_flags = 0;
|
||||
gem->attribute = *attribute;
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake &&
|
||||
g_cfg.io.mouse == mouse_handler::basic)
|
||||
if (g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
// init mouse handler
|
||||
const auto handler = g_fxo->get<MouseHandlerBase>();
|
||||
|
||||
handler->Init(std::min(attribute->max_connect.value(), static_cast<u32>(CELL_GEM_MAX_NUM)));
|
||||
handler->Init(std::min<u32>(attribute->max_connect, CELL_GEM_MAX_NUM));
|
||||
}
|
||||
|
||||
for (int gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++)
|
||||
@ -997,7 +1046,7 @@ error_code cellGemInvalidateCalibration(s32 gem_num)
|
||||
return CELL_GEM_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (g_cfg.io.move == move_handler::fake)
|
||||
if (g_cfg.io.move == move_handler::fake || g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
gem->controllers[gem_num].calibrated_magnetometer = false;
|
||||
// TODO: gem->status_flags
|
||||
|
@ -126,6 +126,7 @@ enum class move_handler
|
||||
{
|
||||
null,
|
||||
fake,
|
||||
mouse,
|
||||
};
|
||||
|
||||
enum class microphone_handler
|
||||
|
@ -153,7 +153,7 @@
|
||||
"mouseHandlerBox": "Some games support native mouse input.\nBasic will work in these cases.",
|
||||
"cameraBox": "Camera support is not implemented, leave this on null.",
|
||||
"cameraTypeBox": "Camera support is not implemented, leave this on unknown.",
|
||||
"moveBox": "PlayStation Move support.\nFake: Experimental! This maps Move controls to DS4 controller mappings."
|
||||
"moveBox": "PlayStation Move support.\nFake: Experimental! This maps Move controls to DS3 controller mappings.\nMouse: Emulate PSMove with Mouse handler."
|
||||
},
|
||||
"network": {
|
||||
"netStatusBox": "Leave as disconnected unless you're debugging.\nRPCS3 has no online support."
|
||||
|
@ -100,7 +100,15 @@ EmuCallbacks main_application::CreateCallbacks()
|
||||
{
|
||||
case mouse_handler::null:
|
||||
{
|
||||
g_fxo->init<MouseHandlerBase, NullMouseHandler>();
|
||||
if (g_cfg.io.move == move_handler::mouse)
|
||||
{
|
||||
basic_mouse_handler* ret = g_fxo->init<MouseHandlerBase, basic_mouse_handler>();
|
||||
ret->moveToThread(get_thread());
|
||||
ret->SetTargetWindow(m_game_window);
|
||||
}
|
||||
else
|
||||
g_fxo->init<MouseHandlerBase, NullMouseHandler>();
|
||||
|
||||
break;
|
||||
}
|
||||
case mouse_handler::basic:
|
||||
|
@ -419,7 +419,7 @@ void gs_frame::take_screenshot(const std::vector<u8> sshot_data, const u32 sshot
|
||||
|
||||
void gs_frame::mouseDoubleClickEvent(QMouseEvent* ev)
|
||||
{
|
||||
if (m_disable_mouse) return;
|
||||
if (m_disable_mouse || g_cfg.io.move == move_handler::mouse) return;
|
||||
|
||||
if (ev->button() == Qt::LeftButton)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user