fix cellMouse lag + fullscreen mouse

This commit is contained in:
Megamouse 2018-08-04 14:37:32 +02:00
parent aaea9d6946
commit 1a5b950d8b
3 changed files with 83 additions and 26 deletions

View file

@ -4,6 +4,9 @@
#include "Emu/Cell/PPUModule.h" #include "Emu/Cell/PPUModule.h"
#include "Emu/Io/MouseHandler.h" #include "Emu/Io/MouseHandler.h"
#include "Utilities/sema.h"
#include "cellMouse.h" #include "cellMouse.h"
extern logs::channel sys_io; extern logs::channel sys_io;
@ -159,6 +162,8 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
return CELL_MOUSE_ERROR_INVALID_PARAMETER; return CELL_MOUSE_ERROR_INVALID_PARAMETER;
} }
semaphore_lock lock(handler->mutex);
const MouseInfo& current_info = handler->GetInfo(); const MouseInfo& current_info = handler->GetInfo();
if (port_no >= handler->GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED) if (port_no >= handler->GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
@ -168,7 +173,15 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
// TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_MOUSE_MODE) has any impact // TODO: check if (current_info.mode[port_no] != CELL_MOUSE_INFO_TABLET_MOUSE_MODE) has any impact
MouseData& current_data = handler->GetDataList(port_no).front(); MouseDataList& data_list = handler->GetDataList(port_no);
if (data_list.size() == 0)
{
*data = {};
return CELL_OK;
}
const MouseData current_data = data_list.front();
data->update = current_data.update; data->update = current_data.update;
data->buttons = current_data.buttons; data->buttons = current_data.buttons;
data->x_axis = current_data.x_axis; data->x_axis = current_data.x_axis;
@ -176,10 +189,7 @@ s32 cellMouseGetData(u32 port_no, vm::ptr<CellMouseData> data)
data->wheel = current_data.wheel; data->wheel = current_data.wheel;
data->tilt = current_data.tilt; data->tilt = current_data.tilt;
current_data.update = CELL_MOUSE_DATA_NON; data_list.pop_front();
current_data.x_axis = 0;
current_data.y_axis = 0;
current_data.wheel = 0;
return CELL_OK; return CELL_OK;
} }
@ -200,6 +210,8 @@ s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
return CELL_MOUSE_ERROR_INVALID_PARAMETER; return CELL_MOUSE_ERROR_INVALID_PARAMETER;
} }
semaphore_lock lock(handler->mutex);
const MouseInfo& current_info = handler->GetInfo(); const MouseInfo& current_info = handler->GetInfo();
if (port_no >= handler->GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED) if (port_no >= handler->GetMice().size() || current_info.status[port_no] != CELL_MOUSE_STATUS_CONNECTED)
@ -221,13 +233,10 @@ s32 cellMouseGetDataList(u32 port_no, vm::ptr<CellMouseDataList> data)
data->list[i].y_axis = it->y_axis; data->list[i].y_axis = it->y_axis;
data->list[i].wheel = it->wheel; data->list[i].wheel = it->wheel;
data->list[i].tilt = it->tilt; data->list[i].tilt = it->tilt;
it->update = CELL_MOUSE_DATA_NON;
it->x_axis = 0;
it->y_axis = 0;
it->wheel = 0;
} }
list.clear();
return CELL_OK; return CELL_OK;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <list> #include <list>
#include "Utilities/sema.h"
// TODO: HLE info (constants, structs, etc.) should not be available here // TODO: HLE info (constants, structs, etc.) should not be available here
@ -108,6 +109,7 @@ struct Mouse
{ {
s16 x_pos; s16 x_pos;
s16 y_pos; s16 y_pos;
u8 buttons; // actual mouse button positions
MouseTabletDataList m_tablet_datalist; MouseTabletDataList m_tablet_datalist;
MouseDataList m_datalist; MouseDataList m_datalist;
@ -127,14 +129,32 @@ class MouseHandlerBase
protected: protected:
MouseInfo m_info; MouseInfo m_info;
std::vector<Mouse> m_mice; std::vector<Mouse> m_mice;
std::chrono::steady_clock::time_point last_update;
bool is_time_for_update(double elapsed_time = 10.0) // 4-10 ms, let's use 10 for now
{
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
double elapsed = std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count() / 1000.0;
if (elapsed > elapsed_time)
{
last_update = now;
return true;
}
return false;
}
public: public:
semaphore<> mutex;
virtual void Init(const u32 max_connect) = 0; virtual void Init(const u32 max_connect) = 0;
virtual ~MouseHandlerBase() = default; virtual ~MouseHandlerBase() = default;
void Button(u8 button, bool pressed) void Button(u8 button, bool pressed)
{ {
for(u32 p=0; p < (u32)m_mice.size(); ++p) semaphore_lock lock(mutex);
for (u32 p = 0; p < (u32)m_mice.size(); ++p)
{ {
if (m_info.status[p] != CELL_MOUSE_STATUS_CONNECTED) if (m_info.status[p] != CELL_MOUSE_STATUS_CONNECTED)
{ {
@ -148,13 +168,14 @@ public:
datalist.pop_front(); datalist.pop_front();
} }
if (pressed)
m_mice[p].buttons |= button;
else
m_mice[p].buttons &= ~button;
MouseData new_data; MouseData new_data;
new_data.update = CELL_MOUSE_DATA_UPDATE; new_data.update = CELL_MOUSE_DATA_UPDATE;
new_data.buttons = m_mice[p].buttons;
if (pressed)
new_data.buttons |= button;
else
new_data.buttons &= ~button;
datalist.push_back(new_data); datalist.push_back(new_data);
} }
@ -162,7 +183,9 @@ public:
void Scroll(const s8 rotation) void Scroll(const s8 rotation)
{ {
for(u32 p=0; p < (u32)m_mice.size(); ++p) semaphore_lock lock(mutex);
for (u32 p = 0; p < (u32)m_mice.size(); ++p)
{ {
if (m_info.status[p] != CELL_MOUSE_STATUS_CONNECTED) if (m_info.status[p] != CELL_MOUSE_STATUS_CONNECTED)
{ {
@ -179,14 +202,17 @@ public:
MouseData new_data; MouseData new_data;
new_data.update = CELL_MOUSE_DATA_UPDATE; new_data.update = CELL_MOUSE_DATA_UPDATE;
new_data.wheel = rotation / 120; //120=event.GetWheelDelta() new_data.wheel = rotation / 120; //120=event.GetWheelDelta()
new_data.buttons = m_mice[p].buttons;
datalist.push_back(new_data); datalist.push_back(new_data);
} }
} }
void Move(const s16 x_pos_new, const s16 y_pos_new) void Move(const s32 x_pos_new, const s32 y_pos_new, bool is_qt_fullscreen = false)
{ {
for(u32 p=0; p < (u32)m_mice.size(); ++p) semaphore_lock lock(mutex);
for (u32 p = 0; p < (u32)m_mice.size(); ++p)
{ {
if (m_info.status[p] != CELL_MOUSE_STATUS_CONNECTED) if (m_info.status[p] != CELL_MOUSE_STATUS_CONNECTED)
{ {
@ -202,11 +228,21 @@ public:
MouseData new_data; MouseData new_data;
new_data.update = CELL_MOUSE_DATA_UPDATE; new_data.update = CELL_MOUSE_DATA_UPDATE;
new_data.x_axis += x_pos_new - m_mice[p].x_pos; new_data.buttons = m_mice[p].buttons;
new_data.y_axis += y_pos_new - m_mice[p].y_pos;
m_mice[p].x_pos = x_pos_new; if (is_qt_fullscreen)
m_mice[p].y_pos = y_pos_new; {
new_data.x_axis = static_cast<s8>(std::clamp(x_pos_new, -127, 128));
new_data.y_axis = static_cast<s8>(std::clamp(y_pos_new, -127, 128));
}
else
{
new_data.x_axis = static_cast<s8>(std::clamp(x_pos_new - m_mice[p].x_pos, -127, 128));
new_data.y_axis = static_cast<s8>(std::clamp(y_pos_new - m_mice[p].y_pos, -127, 128));
m_mice[p].x_pos = x_pos_new;
m_mice[p].y_pos = y_pos_new;
}
/*CellMouseRawData& rawdata = GetRawData(p); /*CellMouseRawData& rawdata = GetRawData(p);
rawdata.data[rawdata.len % CELL_MOUSE_MAX_CODES] = 0; // (TODO) rawdata.data[rawdata.len % CELL_MOUSE_MAX_CODES] = 0; // (TODO)

View file

@ -1,6 +1,7 @@
#include "basic_mouse_handler.h" #include "basic_mouse_handler.h"
#include <QApplication> #include <QApplication>
#include <QCursor>
void basic_mouse_handler::Init(const u32 max_connect) void basic_mouse_handler::Init(const u32 max_connect)
{ {
@ -83,11 +84,22 @@ void basic_mouse_handler::MouseButtonUp(QMouseEvent* event)
void basic_mouse_handler::MouseScroll(QWheelEvent* event) void basic_mouse_handler::MouseScroll(QWheelEvent* event)
{ {
// Woo lads, Qt handles multidimensional scrolls. Just gonna grab the x for now. Not sure if this works. TODO: Test MouseHandlerBase::Scroll(event->angleDelta().y());
MouseHandlerBase::Scroll(event->angleDelta().x());
} }
void basic_mouse_handler::MouseMove(QMouseEvent* event) void basic_mouse_handler::MouseMove(QMouseEvent* event)
{ {
MouseHandlerBase::Move(event->x(), event->y()); if (is_time_for_update())
{
if (m_target && m_target->visibility() == QWindow::Visibility::FullScreen)
{
QPoint p_delta = m_target->geometry().topLeft() + QPoint(m_target->width() / 2, m_target->height() / 2);
QCursor::setPos(p_delta);
MouseHandlerBase::Move(event->x() - p_delta.x(), event->y() - p_delta.y(), true);
}
else
{
MouseHandlerBase::Move(event->x(), event->y());
}
}
} }