mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
emulate dualsense touchpad + refactor (ps1 emulation)
This commit is contained in:
@@ -29,6 +29,7 @@ struct ControlInfo {
|
|||||||
uint32_t button = 0;
|
uint32_t button = 0;
|
||||||
Controller::Axis axis = Controller::Axis::AxisMax;
|
Controller::Axis axis = Controller::Axis::AxisMax;
|
||||||
bool positive = false;
|
bool positive = false;
|
||||||
|
float touch_x = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr std::array CONTROL_INFO = {
|
static constexpr std::array CONTROL_INFO = {
|
||||||
@@ -47,7 +48,10 @@ static constexpr std::array CONTROL_INFO = {
|
|||||||
ControlInfo {"Circle", Controller::PAD_BUTTON_CIRCLE},
|
ControlInfo {"Circle", Controller::PAD_BUTTON_CIRCLE},
|
||||||
ControlInfo {"Cross", Controller::PAD_BUTTON_CROSS},
|
ControlInfo {"Cross", Controller::PAD_BUTTON_CROSS},
|
||||||
ControlInfo {"Square", Controller::PAD_BUTTON_SQUARE},
|
ControlInfo {"Square", Controller::PAD_BUTTON_SQUARE},
|
||||||
ControlInfo {"TouchPad", Controller::PAD_BUTTON_TOUCH_PAD},
|
ControlInfo {"TouchPad", Controller::PAD_BUTTON_TOUCH_PAD, Controller::Axis::AxisMax, false,
|
||||||
|
0.25f},
|
||||||
|
ControlInfo {"TouchPadRight", Controller::PAD_BUTTON_TOUCH_PAD, Controller::Axis::AxisMax,
|
||||||
|
false, 0.75f},
|
||||||
ControlInfo {"LeftStickLeft", 0, Controller::Axis::LeftX, false},
|
ControlInfo {"LeftStickLeft", 0, Controller::Axis::LeftX, false},
|
||||||
ControlInfo {"LeftStickRight", 0, Controller::Axis::LeftX, true},
|
ControlInfo {"LeftStickRight", 0, Controller::Axis::LeftX, true},
|
||||||
ControlInfo {"LeftStickUp", 0, Controller::Axis::LeftY, false},
|
ControlInfo {"LeftStickUp", 0, Controller::Axis::LeftY, false},
|
||||||
@@ -83,11 +87,6 @@ std::size_t ControlFromName(std::string_view name) {
|
|||||||
return static_cast<std::size_t>(std::distance(CONTROL_INFO.begin(), info));
|
return static_cast<std::size_t>(std::distance(CONTROL_INFO.begin(), info));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ControlInfo& Info(std::size_t control) {
|
|
||||||
EXIT_IF(control >= CONTROL_INFO.size());
|
|
||||||
return CONTROL_INFO[control];
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Keycode NormalizeKey(SDL_Keycode key) {
|
SDL_Keycode NormalizeKey(SDL_Keycode key) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case SDLK_RSHIFT: return SDLK_LSHIFT;
|
case SDLK_RSHIFT: return SDLK_LSHIFT;
|
||||||
@@ -205,6 +204,10 @@ void SetButton(uint32_t button, bool down) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetTouchPad(float x, bool down) {
|
||||||
|
Controller::ControllerTouchPad(Controller::HOST_INPUT_CONTROLLER_ID, 0, down, x, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t DefaultKeyboardButton(int key_code) {
|
uint32_t DefaultKeyboardButton(int key_code) {
|
||||||
switch (NormalizeKey(static_cast<SDL_Keycode>(key_code))) {
|
switch (NormalizeKey(static_cast<SDL_Keycode>(key_code))) {
|
||||||
case SDLK_UP: return Controller::PAD_BUTTON_UP;
|
case SDLK_UP: return Controller::PAD_BUTTON_UP;
|
||||||
@@ -221,8 +224,6 @@ uint32_t DefaultKeyboardButton(int key_code) {
|
|||||||
case SDLK_LCTRL: return Controller::PAD_BUTTON_R3;
|
case SDLK_LCTRL: return Controller::PAD_BUTTON_R3;
|
||||||
case SDLK_RETURN:
|
case SDLK_RETURN:
|
||||||
case SDLK_RETURN2: return Controller::PAD_BUTTON_OPTIONS;
|
case SDLK_RETURN2: return Controller::PAD_BUTTON_OPTIONS;
|
||||||
case SDLK_BACKSPACE:
|
|
||||||
case SDLK_TAB: return Controller::PAD_BUTTON_TOUCH_PAD;
|
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -235,7 +236,12 @@ struct StickKeys {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void SetStickAxis(Controller::Axis axis, bool negative, bool positive) {
|
void SetStickAxis(Controller::Axis axis, bool negative, bool positive) {
|
||||||
const int value = negative == positive ? 128 : negative ? 0 : 255;
|
int value = 128;
|
||||||
|
if (negative && !positive) {
|
||||||
|
value = 0;
|
||||||
|
} else if (positive && !negative) {
|
||||||
|
value = 255;
|
||||||
|
}
|
||||||
Controller::ControllerAxis(Controller::HOST_INPUT_CONTROLLER_ID, axis, value);
|
Controller::ControllerAxis(Controller::HOST_INPUT_CONTROLLER_ID, axis, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +250,11 @@ void SetControl(std::size_t control, bool down) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& info = Info(control);
|
const auto& info = CONTROL_INFO[control];
|
||||||
|
if (info.button == Controller::PAD_BUTTON_TOUCH_PAD) {
|
||||||
|
SetTouchPad(info.touch_x, down);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (info.button != 0) {
|
if (info.button != 0) {
|
||||||
SetButton(info.button, down);
|
SetButton(info.button, down);
|
||||||
return;
|
return;
|
||||||
@@ -271,6 +281,8 @@ void DefaultKeyboardInput(int key_code, bool down) {
|
|||||||
static StickKeys right;
|
static StickKeys right;
|
||||||
|
|
||||||
switch (NormalizeKey(static_cast<SDL_Keycode>(key_code))) {
|
switch (NormalizeKey(static_cast<SDL_Keycode>(key_code))) {
|
||||||
|
case SDLK_BACKSPACE: SetTouchPad(0.25f, down); return;
|
||||||
|
case SDLK_TAB: SetTouchPad(0.75f, down); return;
|
||||||
case SDLK_a:
|
case SDLK_a:
|
||||||
left.left = down;
|
left.left = down;
|
||||||
SetStickAxis(Controller::Axis::LeftX, left.left, left.right);
|
SetStickAxis(Controller::Axis::LeftX, left.left, left.right);
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ static uint32_t ControllerButtonToPadButton(int button) {
|
|||||||
case SDL_CONTROLLER_BUTTON_B: return Controller::PAD_BUTTON_CIRCLE;
|
case SDL_CONTROLLER_BUTTON_B: return Controller::PAD_BUTTON_CIRCLE;
|
||||||
case SDL_CONTROLLER_BUTTON_X: return Controller::PAD_BUTTON_SQUARE;
|
case SDL_CONTROLLER_BUTTON_X: return Controller::PAD_BUTTON_SQUARE;
|
||||||
case SDL_CONTROLLER_BUTTON_Y: return Controller::PAD_BUTTON_TRIANGLE;
|
case SDL_CONTROLLER_BUTTON_Y: return Controller::PAD_BUTTON_TRIANGLE;
|
||||||
case SDL_CONTROLLER_BUTTON_BACK: return Controller::PAD_BUTTON_TOUCH_PAD;
|
|
||||||
case SDL_CONTROLLER_BUTTON_START: return Controller::PAD_BUTTON_OPTIONS;
|
case SDL_CONTROLLER_BUTTON_START: return Controller::PAD_BUTTON_OPTIONS;
|
||||||
case SDL_CONTROLLER_BUTTON_LEFTSTICK: return Controller::PAD_BUTTON_L3;
|
case SDL_CONTROLLER_BUTTON_LEFTSTICK: return Controller::PAD_BUTTON_L3;
|
||||||
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return Controller::PAD_BUTTON_R3;
|
case SDL_CONTROLLER_BUTTON_RIGHTSTICK: return Controller::PAD_BUTTON_R3;
|
||||||
@@ -86,6 +85,7 @@ static uint32_t ControllerButtonToPadButton(int button) {
|
|||||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return Controller::PAD_BUTTON_DOWN;
|
case SDL_CONTROLLER_BUTTON_DPAD_DOWN: return Controller::PAD_BUTTON_DOWN;
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return Controller::PAD_BUTTON_LEFT;
|
case SDL_CONTROLLER_BUTTON_DPAD_LEFT: return Controller::PAD_BUTTON_LEFT;
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return Controller::PAD_BUTTON_RIGHT;
|
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: return Controller::PAD_BUTTON_RIGHT;
|
||||||
|
case SDL_CONTROLLER_BUTTON_TOUCHPAD: return Controller::PAD_BUTTON_TOUCH_PAD;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -705,6 +705,16 @@ void WindowContext::ProcessEvent(double time_s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||||
|
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||||
|
case SDL_CONTROLLERTOUCHPADUP:
|
||||||
|
if (event->ctouchpad.touchpad == 0) {
|
||||||
|
Controller::ControllerTouchPad(event->ctouchpad.which, event->ctouchpad.finger,
|
||||||
|
event->ctouchpad.type != SDL_CONTROLLERTOUCHPADUP,
|
||||||
|
event->ctouchpad.x, event->ctouchpad.y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SDL_CONTROLLERDEVICEADDED:
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
case SDL_CONTROLLERDEVICEREMOVED:
|
case SDL_CONTROLLERDEVICEREMOVED:
|
||||||
case SDL_CONTROLLERDEVICEREMAPPED: {
|
case SDL_CONTROLLERDEVICEREMAPPED: {
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ constexpr PadControl PAD_CONTROLS[] = {
|
|||||||
{"L3", "L3", "Left Shift"},
|
{"L3", "L3", "Left Shift"},
|
||||||
{"R3", "R3", "Left Ctrl"},
|
{"R3", "R3", "Left Ctrl"},
|
||||||
{"Options", "Options", "Return"},
|
{"Options", "Options", "Return"},
|
||||||
{"TouchPad", "Touch pad", "Backspace"},
|
{"TouchPad", "Touch pad left (SELECT)", "Backspace"},
|
||||||
|
{"TouchPadRight", "Touch pad right (START)", "Tab"},
|
||||||
};
|
};
|
||||||
|
|
||||||
QString KeypadName(int key) {
|
QString KeypadName(int key) {
|
||||||
|
|||||||
+89
-85
@@ -45,15 +45,22 @@ struct PadVibrationParam {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ControllerState {
|
struct ControllerState {
|
||||||
|
struct Touch {
|
||||||
|
uint8_t id = 0;
|
||||||
|
bool down = false;
|
||||||
|
uint16_t x = 0;
|
||||||
|
uint16_t y = 0;
|
||||||
|
};
|
||||||
|
|
||||||
uint64_t time = 0;
|
uint64_t time = 0;
|
||||||
uint32_t buttons = 0;
|
uint32_t buttons = 0;
|
||||||
int axes[static_cast<int>(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0};
|
int axes[static_cast<int>(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0};
|
||||||
|
Touch touch[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameController {
|
class GameController {
|
||||||
public:
|
public:
|
||||||
GameController() = default;
|
GameController() = default;
|
||||||
virtual ~GameController() = default;
|
|
||||||
|
|
||||||
KYTY_CLASS_NO_COPY(GameController);
|
KYTY_CLASS_NO_COPY(GameController);
|
||||||
|
|
||||||
@@ -62,6 +69,7 @@ public:
|
|||||||
void Button(int id, uint32_t button, bool down);
|
void Button(int id, uint32_t button, bool down);
|
||||||
void Axis(int id, Axis axis, int value);
|
void Axis(int id, Axis axis, int value);
|
||||||
void RightStick(int id, int x, int y);
|
void RightStick(int id, int x, int y);
|
||||||
|
void TouchPad(int id, int finger, bool down, float x, float y);
|
||||||
void ResetInputState();
|
void ResetInputState();
|
||||||
void GetConnectionInfo(bool* flag, int* count);
|
void GetConnectionInfo(bool* flag, int* count);
|
||||||
void SetVibration(uint8_t large_motor, uint8_t small_motor);
|
void SetVibration(uint8_t large_motor, uint8_t small_motor);
|
||||||
@@ -71,32 +79,24 @@ public:
|
|||||||
private:
|
private:
|
||||||
static constexpr uint32_t STATES_MAX = 64;
|
static constexpr uint32_t STATES_MAX = 64;
|
||||||
|
|
||||||
struct StatePrivate {
|
|
||||||
bool obtained = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
void CheckActive();
|
void CheckActive();
|
||||||
[[nodiscard]] ControllerState GetLastState() const;
|
void AddState();
|
||||||
void AddState(const ControllerState& state);
|
|
||||||
|
|
||||||
Common::Mutex m_mutex;
|
Common::Mutex m_mutex;
|
||||||
std::vector<int> m_connected_ids;
|
std::vector<int> m_connected_ids;
|
||||||
int m_active_id = -1;
|
int m_active_id = -1;
|
||||||
bool m_connected = false;
|
bool m_connected = false;
|
||||||
int m_connected_count = 0;
|
int m_connected_count = 0;
|
||||||
|
ControllerState m_state;
|
||||||
ControllerState m_states[STATES_MAX];
|
ControllerState m_states[STATES_MAX];
|
||||||
StatePrivate m_private[STATES_MAX];
|
bool m_obtained[STATES_MAX] {};
|
||||||
ControllerState m_last_state;
|
|
||||||
uint32_t m_states_num = 0;
|
uint32_t m_states_num = 0;
|
||||||
uint32_t m_first_state = 0;
|
uint32_t m_first_state = 0;
|
||||||
|
uint8_t m_next_touch_id = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GameController* g_controller = nullptr;
|
static GameController* g_controller = nullptr;
|
||||||
|
|
||||||
static uint8_t pad_connected_count_to_u8(int connected_count) {
|
|
||||||
return static_cast<uint8_t>(connected_count > 255 ? 255 : connected_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pad_fill_data(PadData* data, const ControllerState& state, bool connected,
|
static void pad_fill_data(PadData* data, const ControllerState& state, bool connected,
|
||||||
int connected_count) {
|
int connected_count) {
|
||||||
EXIT_IF(data == nullptr);
|
EXIT_IF(data == nullptr);
|
||||||
@@ -111,11 +111,17 @@ static void pad_fill_data(PadData* data, const ControllerState& state, bool conn
|
|||||||
data->analog_buttons_l2 = state.axes[static_cast<int>(Axis::TriggerLeft)];
|
data->analog_buttons_l2 = state.axes[static_cast<int>(Axis::TriggerLeft)];
|
||||||
data->analog_buttons_r2 = state.axes[static_cast<int>(Axis::TriggerRight)];
|
data->analog_buttons_r2 = state.axes[static_cast<int>(Axis::TriggerRight)];
|
||||||
data->orientation_w = 1.0f;
|
data->orientation_w = 1.0f;
|
||||||
data->touch_data_touch0_id = 1;
|
for (const auto& touch: state.touch) {
|
||||||
data->touch_data_touch1_id = 2;
|
if (touch.down) {
|
||||||
|
auto& output = data->touch_data.touch[data->touch_data.touch_num++];
|
||||||
|
output.x = touch.x;
|
||||||
|
output.y = touch.y;
|
||||||
|
output.id = touch.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
data->connected = connected;
|
data->connected = connected;
|
||||||
data->timestamp = state.time;
|
data->timestamp = state.time;
|
||||||
data->connected_count = pad_connected_count_to_u8(connected_count);
|
data->connected_count = static_cast<uint8_t>(std::min(connected_count, 255));
|
||||||
data->device_unique_data_len = 0;
|
data->device_unique_data_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +161,6 @@ void GameController::Disconnect(int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GameController::CheckActive() {
|
void GameController::CheckActive() {
|
||||||
bool reset = false;
|
|
||||||
int new_active_id = -1;
|
int new_active_id = -1;
|
||||||
bool new_connected = false;
|
bool new_connected = false;
|
||||||
|
|
||||||
@@ -170,46 +175,29 @@ void GameController::CheckActive() {
|
|||||||
new_connected = true;
|
new_connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool was_connected = m_connected;
|
if (m_connected == new_connected && m_active_id == new_active_id) {
|
||||||
|
return;
|
||||||
if (m_connected != new_connected || m_active_id != new_active_id) {
|
}
|
||||||
m_active_id = new_active_id;
|
if (!m_connected && new_connected) {
|
||||||
m_connected = new_connected;
|
|
||||||
if (!was_connected && new_connected) {
|
|
||||||
m_connected_count++;
|
m_connected_count++;
|
||||||
}
|
}
|
||||||
reset = true;
|
m_active_id = new_active_id;
|
||||||
}
|
m_connected = new_connected;
|
||||||
|
m_state = {};
|
||||||
if (reset) {
|
|
||||||
m_states_num = 0;
|
m_states_num = 0;
|
||||||
m_last_state = ControllerState();
|
m_first_state = 0;
|
||||||
}
|
m_next_touch_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerState GameController::GetLastState() const {
|
void GameController::AddState() {
|
||||||
if (m_states_num == 0) {
|
|
||||||
return m_last_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto last = (m_first_state + m_states_num - 1) % STATES_MAX;
|
|
||||||
|
|
||||||
return m_states[last];
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameController::AddState(const ControllerState& state) {
|
|
||||||
if (m_states_num >= STATES_MAX) {
|
if (m_states_num >= STATES_MAX) {
|
||||||
m_states_num = STATES_MAX - 1;
|
m_states_num = STATES_MAX - 1;
|
||||||
m_first_state = (m_first_state + 1) % STATES_MAX;
|
m_first_state = (m_first_state + 1) % STATES_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto index = (m_first_state + m_states_num) % STATES_MAX;
|
const auto index = (m_first_state + m_states_num) % STATES_MAX;
|
||||||
|
m_states[index] = m_state;
|
||||||
m_states[index] = state;
|
m_obtained[index] = false;
|
||||||
m_last_state = state;
|
|
||||||
|
|
||||||
m_private[index].obtained = false;
|
|
||||||
|
|
||||||
m_states_num++;
|
m_states_num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,17 +206,11 @@ void GameController::Button(int id, uint32_t button, bool down) {
|
|||||||
|
|
||||||
// The keyboard shares the player-1 pad with the active gamepad.
|
// The keyboard shares the player-1 pad with the active gamepad.
|
||||||
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
||||||
auto state = GetLastState();
|
m_state.time = LibKernel::KernelGetProcessTime();
|
||||||
|
|
||||||
state.time = LibKernel::KernelGetProcessTime();
|
m_state.buttons = down ? m_state.buttons | button : m_state.buttons & ~button;
|
||||||
|
|
||||||
if (down) {
|
AddState();
|
||||||
state.buttons |= button;
|
|
||||||
} else {
|
|
||||||
state.buttons &= ~button;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddState(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,33 +218,25 @@ void GameController::Axis(int id, Controller::Axis axis, int value) {
|
|||||||
Common::LockGuard lock(m_mutex);
|
Common::LockGuard lock(m_mutex);
|
||||||
|
|
||||||
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
||||||
auto state = GetLastState();
|
m_state.time = LibKernel::KernelGetProcessTime();
|
||||||
|
|
||||||
state.time = LibKernel::KernelGetProcessTime();
|
|
||||||
|
|
||||||
int axis_id = static_cast<int>(axis);
|
int axis_id = static_cast<int>(axis);
|
||||||
|
|
||||||
EXIT_IF(axis_id < 0 || axis_id >= static_cast<int>(Controller::Axis::AxisMax));
|
EXIT_IF(axis_id < 0 || axis_id >= static_cast<int>(Controller::Axis::AxisMax));
|
||||||
|
|
||||||
state.axes[axis_id] = value;
|
m_state.axes[axis_id] = value;
|
||||||
|
|
||||||
|
uint32_t trigger = 0;
|
||||||
if (axis == Controller::Axis::TriggerLeft) {
|
if (axis == Controller::Axis::TriggerLeft) {
|
||||||
if (value > 0) {
|
trigger = PAD_BUTTON_L2;
|
||||||
state.buttons |= PAD_BUTTON_L2;
|
} else if (axis == Controller::Axis::TriggerRight) {
|
||||||
} else {
|
trigger = PAD_BUTTON_R2;
|
||||||
state.buttons &= ~PAD_BUTTON_L2;
|
|
||||||
}
|
}
|
||||||
|
if (trigger != 0) {
|
||||||
|
m_state.buttons = value > 0 ? m_state.buttons | trigger : m_state.buttons & ~trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (axis == Controller::Axis::TriggerRight) {
|
AddState();
|
||||||
if (value > 0) {
|
|
||||||
state.buttons |= PAD_BUTTON_R2;
|
|
||||||
} else {
|
|
||||||
state.buttons &= ~PAD_BUTTON_R2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddState(state);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,21 +244,45 @@ void GameController::RightStick(int id, int x, int y) {
|
|||||||
Common::LockGuard lock(m_mutex);
|
Common::LockGuard lock(m_mutex);
|
||||||
|
|
||||||
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
||||||
auto state = GetLastState();
|
m_state.time = LibKernel::KernelGetProcessTime();
|
||||||
state.time = LibKernel::KernelGetProcessTime();
|
m_state.axes[static_cast<int>(Axis::RightX)] = x;
|
||||||
state.axes[static_cast<int>(Axis::RightX)] = x;
|
m_state.axes[static_cast<int>(Axis::RightY)] = y;
|
||||||
state.axes[static_cast<int>(Axis::RightY)] = y;
|
AddState();
|
||||||
AddState(state);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameController::TouchPad(int id, int finger, bool down, float x, float y) {
|
||||||
|
if (finger < 0 || finger >= 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::LockGuard lock(m_mutex);
|
||||||
|
if (m_active_id == id || id == HOST_INPUT_CONTROLLER_ID) {
|
||||||
|
auto& touch = m_state.touch[finger];
|
||||||
|
m_state.time = LibKernel::KernelGetProcessTime();
|
||||||
|
if (down && !touch.down) {
|
||||||
|
touch.id = m_next_touch_id;
|
||||||
|
m_next_touch_id = m_next_touch_id == 127 ? 1 : m_next_touch_id + 1;
|
||||||
|
}
|
||||||
|
touch.down = down;
|
||||||
|
touch.x = static_cast<uint16_t>(std::clamp(x, 0.0f, 1.0f) * 1920.0f);
|
||||||
|
touch.y = static_cast<uint16_t>(std::clamp(y, 0.0f, 1.0f) * 943.0f);
|
||||||
|
if (id == HOST_INPUT_CONTROLLER_ID) {
|
||||||
|
m_state.buttons = down ? m_state.buttons | PAD_BUTTON_TOUCH_PAD
|
||||||
|
: m_state.buttons & ~PAD_BUTTON_TOUCH_PAD;
|
||||||
|
}
|
||||||
|
AddState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameController::ResetInputState() {
|
void GameController::ResetInputState() {
|
||||||
Common::LockGuard lock(m_mutex);
|
Common::LockGuard lock(m_mutex);
|
||||||
ControllerState state {};
|
m_state = {};
|
||||||
state.time = LibKernel::KernelGetProcessTime();
|
m_state.time = LibKernel::KernelGetProcessTime();
|
||||||
m_states_num = 0;
|
m_states_num = 0;
|
||||||
m_first_state = 0;
|
m_first_state = 0;
|
||||||
AddState(state);
|
m_next_touch_id = 1;
|
||||||
|
AddState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameController::SetVibration(uint8_t large_motor, uint8_t small_motor) {
|
void GameController::SetVibration(uint8_t large_motor, uint8_t small_motor) {
|
||||||
@@ -325,7 +323,7 @@ void GameController::ReadState(ControllerState* state, bool* flag, int* count) {
|
|||||||
|
|
||||||
*flag = m_connected;
|
*flag = m_connected;
|
||||||
*count = m_connected_count;
|
*count = m_connected_count;
|
||||||
*state = GetLastState();
|
*state = m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GameController::ReadStates(ControllerState* states, int states_num, bool* flag, int* count) {
|
int GameController::ReadStates(ControllerState* states, int states_num, bool* flag, int* count) {
|
||||||
@@ -348,8 +346,8 @@ int GameController::ReadStates(ControllerState* states, int states_num, bool* fl
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto index = (m_first_state + i) % STATES_MAX;
|
auto index = (m_first_state + i) % STATES_MAX;
|
||||||
if (!m_private[index].obtained) {
|
if (!m_obtained[index]) {
|
||||||
m_private[index].obtained = true;
|
m_obtained[index] = true;
|
||||||
|
|
||||||
states[ret_num++] = m_states[index];
|
states[ret_num++] = m_states[index];
|
||||||
}
|
}
|
||||||
@@ -390,6 +388,12 @@ void ControllerRightStick(int id, int x, int y) {
|
|||||||
g_controller->RightStick(id, x, y);
|
g_controller->RightStick(id, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ControllerTouchPad(int id, int finger, bool down, float x, float y) {
|
||||||
|
EXIT_IF(g_controller == nullptr);
|
||||||
|
|
||||||
|
g_controller->TouchPad(id, finger, down, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void ControllerResetInputState() {
|
void ControllerResetInputState() {
|
||||||
EXIT_IF(g_controller == nullptr);
|
EXIT_IF(g_controller == nullptr);
|
||||||
g_controller->ResetInputState();
|
g_controller->ResetInputState();
|
||||||
@@ -508,7 +512,7 @@ int KYTY_SYSV_ABI PadGetControllerInformation(int handle, PadControllerInformati
|
|||||||
info->stick_dead_zone_left = controller_get_axis(-32768, 32767, 8000) - 128;
|
info->stick_dead_zone_left = controller_get_axis(-32768, 32767, 8000) - 128;
|
||||||
info->stick_dead_zone_right = controller_get_axis(-32768, 32767, 8000) - 128;
|
info->stick_dead_zone_right = controller_get_axis(-32768, 32767, 8000) - 128;
|
||||||
info->connection_type = 0;
|
info->connection_type = 0;
|
||||||
info->connected_count = pad_connected_count_to_u8(connected_count);
|
info->connected_count = static_cast<uint8_t>(std::min(connected_count, 255));
|
||||||
info->connected = connected;
|
info->connected = connected;
|
||||||
info->device_class = 0;
|
info->device_class = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,13 @@ struct PadLightBarParam;
|
|||||||
|
|
||||||
inline int controller_get_axis(int min, int max, int value) {
|
inline int controller_get_axis(int min, int max, int value) {
|
||||||
int v = (255 * (value - min)) / (max - min);
|
int v = (255 * (value - min)) / (max - min);
|
||||||
return (v < 0 ? 0 : (v > 255 ? 255 : v));
|
if (v < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (v > 255) {
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerConnect(int id);
|
void ControllerConnect(int id);
|
||||||
@@ -59,6 +65,7 @@ void ControllerDisconnect(int id);
|
|||||||
void ControllerButton(int id, uint32_t button, bool down);
|
void ControllerButton(int id, uint32_t button, bool down);
|
||||||
void ControllerAxis(int id, Axis axis, int value);
|
void ControllerAxis(int id, Axis axis, int value);
|
||||||
void ControllerRightStick(int id, int x, int y);
|
void ControllerRightStick(int id, int x, int y);
|
||||||
|
void ControllerTouchPad(int id, int finger, bool down, float x, float y);
|
||||||
void ControllerResetInputState();
|
void ControllerResetInputState();
|
||||||
|
|
||||||
int KYTY_SYSV_ABI PadInit();
|
int KYTY_SYSV_ABI PadInit();
|
||||||
|
|||||||
+15
-11
@@ -5,6 +5,20 @@
|
|||||||
|
|
||||||
namespace Libs::Controller {
|
namespace Libs::Controller {
|
||||||
|
|
||||||
|
struct PadTouch {
|
||||||
|
uint16_t x;
|
||||||
|
uint16_t y;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t reserve[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PadTouchData {
|
||||||
|
uint8_t touch_num;
|
||||||
|
uint8_t reserve[3];
|
||||||
|
uint32_t reserve1;
|
||||||
|
PadTouch touch[2];
|
||||||
|
};
|
||||||
|
|
||||||
struct PadData {
|
struct PadData {
|
||||||
uint32_t buttons;
|
uint32_t buttons;
|
||||||
uint8_t left_stick_x;
|
uint8_t left_stick_x;
|
||||||
@@ -24,17 +38,7 @@ struct PadData {
|
|||||||
float angular_velocity_x;
|
float angular_velocity_x;
|
||||||
float angular_velocity_y;
|
float angular_velocity_y;
|
||||||
float angular_velocity_z;
|
float angular_velocity_z;
|
||||||
uint8_t touch_data_touch_num;
|
PadTouchData touch_data;
|
||||||
uint8_t touch_data_reserve[3];
|
|
||||||
uint32_t touch_data_reserve1;
|
|
||||||
uint16_t touch_data_touch0_x;
|
|
||||||
uint16_t touch_data_touch0_y;
|
|
||||||
uint8_t touch_data_touch0_id;
|
|
||||||
uint8_t touch_data_touch0_reserve[3];
|
|
||||||
uint16_t touch_data_touch1_x;
|
|
||||||
uint16_t touch_data_touch1_y;
|
|
||||||
uint8_t touch_data_touch1_id;
|
|
||||||
uint8_t touch_data_touch1_reserve[3];
|
|
||||||
bool connected;
|
bool connected;
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
uint32_t extension_unit_data_extension_unit_id;
|
uint32_t extension_unit_data_extension_unit_id;
|
||||||
|
|||||||
Reference in New Issue
Block a user