mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-19 18:04:56 +00:00
119 lines
3.2 KiB
C++
119 lines
3.2 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "core/libraries/kernel/time_management.h"
|
|
#include "core/libraries/pad/pad.h"
|
|
#include "input/controller.h"
|
|
namespace Input {
|
|
|
|
GameController::GameController() {
|
|
m_states_num = 0;
|
|
m_last_state = State();
|
|
}
|
|
|
|
void GameController::ReadState(State* state, bool* isConnected, int* connectedCount) {
|
|
std::scoped_lock lock{m_mutex};
|
|
|
|
*isConnected = m_connected;
|
|
*connectedCount = m_connected_count;
|
|
*state = GetLastState();
|
|
}
|
|
|
|
int GameController::ReadStates(State* states, int states_num, bool* isConnected,
|
|
int* connectedCount) {
|
|
std::scoped_lock lock{m_mutex};
|
|
|
|
*isConnected = m_connected;
|
|
*connectedCount = m_connected_count;
|
|
|
|
int ret_num = 0;
|
|
|
|
if (m_connected) {
|
|
if (m_states_num == 0) {
|
|
ret_num = 1;
|
|
states[0] = m_last_state;
|
|
} else {
|
|
for (uint32_t i = 0; i < m_states_num; i++) {
|
|
if (ret_num >= states_num) {
|
|
break;
|
|
}
|
|
auto index = (m_first_state + i) % MAX_STATES;
|
|
if (!m_private[index].obtained) {
|
|
m_private[index].obtained = true;
|
|
|
|
states[ret_num++] = m_states[index];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret_num;
|
|
}
|
|
|
|
State GameController::GetLastState() const {
|
|
if (m_states_num == 0) {
|
|
return m_last_state;
|
|
}
|
|
|
|
auto last = (m_first_state + m_states_num - 1) % MAX_STATES;
|
|
|
|
return m_states[last];
|
|
}
|
|
|
|
void GameController::AddState(const State& state) {
|
|
if (m_states_num >= MAX_STATES) {
|
|
m_states_num = MAX_STATES - 1;
|
|
m_first_state = (m_first_state + 1) % MAX_STATES;
|
|
}
|
|
|
|
auto index = (m_first_state + m_states_num) % MAX_STATES;
|
|
|
|
m_states[index] = state;
|
|
m_last_state = state;
|
|
m_private[index].obtained = false;
|
|
m_states_num++;
|
|
}
|
|
|
|
void GameController::CheckButton(int id, u32 button, bool isPressed) {
|
|
std::scoped_lock lock{m_mutex};
|
|
auto state = GetLastState();
|
|
state.time = Libraries::Kernel::sceKernelGetProcessTime();
|
|
if (isPressed) {
|
|
state.buttonsState |= button;
|
|
} else {
|
|
state.buttonsState &= ~button;
|
|
}
|
|
|
|
AddState(state);
|
|
}
|
|
|
|
void GameController::Axis(int id, Input::Axis axis, int value) {
|
|
std::scoped_lock lock{m_mutex};
|
|
auto state = GetLastState();
|
|
|
|
state.time = Libraries::Kernel::sceKernelGetProcessTime();
|
|
|
|
int axis_id = static_cast<int>(axis);
|
|
|
|
state.axes[axis_id] = value;
|
|
|
|
if (axis == Input::Axis::TriggerLeft) {
|
|
if (value > 0) {
|
|
state.buttonsState |= Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2;
|
|
} else {
|
|
state.buttonsState &= ~Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2;
|
|
}
|
|
}
|
|
|
|
if (axis == Input::Axis::TriggerRight) {
|
|
if (value > 0) {
|
|
state.buttonsState |= Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2;
|
|
} else {
|
|
state.buttonsState &= ~Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2;
|
|
}
|
|
}
|
|
|
|
AddState(state);
|
|
}
|
|
|
|
} // namespace Input
|