mirror of https://github.com/AxioDL/metaforce.git
Initial CDolphinController RE
This commit is contained in:
parent
ec430567c3
commit
a96fe24260
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
enum class EJoyAxis {
|
||||||
|
LeftX,
|
||||||
|
LeftY,
|
||||||
|
RightX,
|
||||||
|
RightY,
|
||||||
|
MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
class CControllerAxis {
|
||||||
|
float x0_absolute = 0.f;
|
||||||
|
float x4_relative = 0.f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetRelativeValue(float val) { x0_absolute = val; }
|
||||||
|
float GetRelativeValue() const { return x0_absolute; }
|
||||||
|
void SetAbsoluteValue(float val) { x4_relative = val; }
|
||||||
|
float GetAbsoluteValue() const { return x4_relative; }
|
||||||
|
};
|
||||||
|
} // namespace metaforce
|
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Runtime/GCNTypes.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
enum class EButton {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Start,
|
||||||
|
Z,
|
||||||
|
Up,
|
||||||
|
Right,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EAnalogButton {
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
};
|
||||||
|
|
||||||
|
class CControllerButton {
|
||||||
|
bool x0_;
|
||||||
|
bool x1_pressed;
|
||||||
|
bool x2_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetIsPressed(bool pressed) { x1_pressed = pressed; }
|
||||||
|
[[nodiscard]] bool GetIsPressed() const { return x1_pressed; }
|
||||||
|
void SetPressEvent(bool press);
|
||||||
|
[[nodiscard]] bool GetPressEvent() const;
|
||||||
|
void SetReleaseEvent(bool release);
|
||||||
|
};
|
||||||
|
} // namespace metaforce
|
|
@ -0,0 +1,4 @@
|
||||||
|
#include "Runtime/Input/CControllerGamepadData.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Runtime/Input/CControllerAxis.hpp"
|
||||||
|
#include "Runtime/Input/CControllerButton.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
class CControllerGamepadData {
|
||||||
|
bool x0_present;
|
||||||
|
std::array<CControllerAxis, 4> x4_axes;
|
||||||
|
std::array<CControllerAxis, 2> x24_triggers;
|
||||||
|
std::array<CControllerButton, 12> x34_buttons;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void SetDeviceIsPresent(bool present) { x0_present = present; }
|
||||||
|
[[nodiscard]] bool DeviceIsPresent() const { return x0_present; }
|
||||||
|
|
||||||
|
[[nodiscard]] const CControllerAxis& GetAxis(EJoyAxis axis) const { return x4_axes[u32(axis)]; }
|
||||||
|
[[nodiscard]] CControllerAxis& GetAxis(EJoyAxis axis) { return x4_axes[u32(axis)]; }
|
||||||
|
|
||||||
|
[[nodiscard]] const CControllerButton& GetButton(EButton button) const { return x34_buttons[u32(button)]; }
|
||||||
|
[[nodiscard]] CControllerButton& GetButton(EButton button) { return x34_buttons[u32(button)]; }
|
||||||
|
|
||||||
|
[[nodiscard]] const CControllerAxis& GetAnalogButton(EAnalogButton button) const { return x24_triggers[u32(button)]; }
|
||||||
|
[[nodiscard]] CControllerAxis& GetAnalogButton(EAnalogButton button) { return x24_triggers[u32(button)]; }
|
||||||
|
};
|
||||||
|
} // namespace metaforce
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include "Runtime/Input/CDolphinController.hpp"
|
||||||
|
|
||||||
|
namespace PAD {
|
||||||
|
// clang-format off
|
||||||
|
enum BUTTON : u16 {
|
||||||
|
LEFT = 0x0001,
|
||||||
|
RIGHT = 0x0002,
|
||||||
|
DOWN = 0x0004,
|
||||||
|
UP = 0x0008,
|
||||||
|
TRIGGER_Z = 0x0010,
|
||||||
|
TRIGGER_R = 0x0020,
|
||||||
|
TRIGGER_L = 0x0040,
|
||||||
|
BUTTON_A = 0x0100,
|
||||||
|
BUTTON_B = 0x0200,
|
||||||
|
BUTTON_X = 0x0400,
|
||||||
|
BUTTON_Y = 0x0800,
|
||||||
|
BUTTON_START = 0x1000,
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
} // namespace PAD
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
CDolphinController::CDolphinController() {
|
||||||
|
static bool sIsInitialized = false;
|
||||||
|
if (!sIsInitialized) {
|
||||||
|
// PADSetSpec(5);
|
||||||
|
// PADInit();
|
||||||
|
sIsInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CDolphinController::SetMotorState(EIOPort port, EMotorState state) { x194_motorStates[u32(port)] = state; }
|
||||||
|
|
||||||
|
float CDolphinController::GetAnalogStickMaxValue(EJoyAxis axis) {
|
||||||
|
if (axis >= EJoyAxis::LeftX && axis <= EJoyAxis::LeftY) {
|
||||||
|
return 72.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis >= EJoyAxis::RightX && axis <= EJoyAxis::RightY) {
|
||||||
|
return 59.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDolphinController::ProcessAxis(u32 controller, EJoyAxis axis) {
|
||||||
|
const auto maxAxisValue = GetAnalogStickMaxValue(axis);
|
||||||
|
auto& data = x34_gamepadStates[controller].GetAxis(axis);
|
||||||
|
|
||||||
|
float axisValue = 0.f;
|
||||||
|
if (axis == EJoyAxis::LeftX) {
|
||||||
|
axisValue = x4_status[controller].x2_stickX;
|
||||||
|
} else if (axis == EJoyAxis::LeftY) {
|
||||||
|
axisValue = x4_status[controller].x3_stickY;
|
||||||
|
} else if (axis == EJoyAxis::RightX) {
|
||||||
|
axisValue = x4_status[controller].x4_substickX;
|
||||||
|
} else if (axis == EJoyAxis::RightY) {
|
||||||
|
axisValue = x4_status[controller].x5_substickY;
|
||||||
|
}
|
||||||
|
axisValue *= 1.f / maxAxisValue;
|
||||||
|
float absolute = kAbsoluteMinimum;
|
||||||
|
if (axisValue < kAbsoluteMinimum) {
|
||||||
|
absolute = kAbsoluteMinimum;
|
||||||
|
} else if (axisValue > kAbsoluteMaximum) {
|
||||||
|
absolute = kAbsoluteMaximum;
|
||||||
|
}
|
||||||
|
|
||||||
|
axisValue = absolute - data.GetAbsoluteValue();
|
||||||
|
float relativeValue = kRelativeMinimum;
|
||||||
|
if (axisValue < kRelativeMinimum) {
|
||||||
|
relativeValue = kRelativeMinimum;
|
||||||
|
} else if (axisValue > kRelativeMaximum) {
|
||||||
|
relativeValue = kRelativeMaximum;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.SetAbsoluteValue(absolute);
|
||||||
|
data.SetRelativeValue(relativeValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::array<u16, size_t(EButton::MAX)> mButtonMapping{
|
||||||
|
PAD::BUTTON_A, PAD::BUTTON_B, PAD::BUTTON_X, PAD::BUTTON_Y, PAD::BUTTON_START, PAD::TRIGGER_Z,
|
||||||
|
PAD::UP, PAD::RIGHT, PAD::DOWN, PAD::LEFT, PAD::TRIGGER_L, PAD::TRIGGER_R,
|
||||||
|
};
|
||||||
|
|
||||||
|
void CDolphinController::ProcessButtons(u32 controller) {
|
||||||
|
for (u32 i = 0; i < u32(EButton::MAX); ++i) {
|
||||||
|
ProcessDigitalButton(controller, x34_gamepadStates[controller].GetButton(EButton(i)), mButtonMapping[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessAnalogButton(x4_status[controller].x6_triggerL,
|
||||||
|
x34_gamepadStates[controller].GetAnalogButton(EAnalogButton::Left));
|
||||||
|
ProcessAnalogButton(x4_status[controller].x7_triggerR,
|
||||||
|
x34_gamepadStates[controller].GetAnalogButton(EAnalogButton::Right));
|
||||||
|
}
|
||||||
|
void CDolphinController::ProcessDigitalButton(u32 controller, CControllerButton& button, u16 mapping) {}
|
||||||
|
void CDolphinController::ProcessAnalogButton(float value, CControllerAxis& axis) {}
|
||||||
|
|
||||||
|
void CDolphinController::Initialize() {}
|
||||||
|
} // namespace metaforce
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Runtime/Input/IController.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
struct PADStatus {
|
||||||
|
u16 x0_buttons;
|
||||||
|
s8 x2_stickX;
|
||||||
|
s8 x3_stickY;
|
||||||
|
s8 x4_substickX;
|
||||||
|
s8 x5_substickY;
|
||||||
|
u8 x6_triggerL;
|
||||||
|
u8 x7_triggerR;
|
||||||
|
u8 x8_analogA;
|
||||||
|
u8 x9_analogB;
|
||||||
|
s8 xa_err;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CDolphinController : public IController {
|
||||||
|
|
||||||
|
std::array<PADStatus, 4> x4_status;
|
||||||
|
std::array<CControllerGamepadData, 4> x34_gamepadStates{};
|
||||||
|
std::array<EMotorState, 4> x194_motorStates;
|
||||||
|
std::array<u32, 4> x1a4_controllerTypes{};
|
||||||
|
std::array<u32, 4> x1b4_{};
|
||||||
|
u32 x1c4_ = 0xf0000000;
|
||||||
|
u32 x1c8_ = 0;
|
||||||
|
u32 x1cc_ = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CDolphinController();
|
||||||
|
void Poll() override{};
|
||||||
|
[[nodiscard]] u32 GetDeviceCount() const override { return 4; };
|
||||||
|
[[nodiscard]] CControllerGamepadData& GetGamepadData(u32 controller) override {
|
||||||
|
return x34_gamepadStates[controller];
|
||||||
|
};
|
||||||
|
[[nodiscard]] u32 GetControllerType(u32 controller) const override { return x1a4_controllerTypes[controller]; }
|
||||||
|
void SetMotorState(EIOPort port, EMotorState state) override;
|
||||||
|
|
||||||
|
float GetAnalogStickMaxValue(EJoyAxis axis);
|
||||||
|
void ProcessAxis(u32 controller, EJoyAxis axis);
|
||||||
|
void ProcessButtons(u32 controller);
|
||||||
|
void ProcessDigitalButton(u32 controller, CControllerButton& button, u16 mapping);
|
||||||
|
void ProcessAnalogButton(float value, CControllerAxis& axis);
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
};
|
||||||
|
} // namespace metaforce
|
|
@ -4,16 +4,13 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "Runtime/Input/InputTypes.hpp"
|
||||||
#include "Runtime/Input/CFinalInput.hpp"
|
#include "Runtime/Input/CFinalInput.hpp"
|
||||||
#include "Runtime/Input/CKeyboardMouseController.hpp"
|
#include "Runtime/Input/CKeyboardMouseController.hpp"
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
class CArchitectureQueue;
|
class CArchitectureQueue;
|
||||||
|
|
||||||
enum class EIOPort { Zero, One, Two, Three };
|
|
||||||
|
|
||||||
enum class EMotorState { Stop, Rumble, StopHard };
|
|
||||||
|
|
||||||
class CInputGenerator /*: public boo::DeviceFinder*/ {
|
class CInputGenerator /*: public boo::DeviceFinder*/ {
|
||||||
enum class EStatusChange { NoChange = 0, Connected = 1, Disconnected = 2 };
|
enum class EStatusChange { NoChange = 0, Connected = 1, Disconnected = 2 };
|
||||||
|
|
||||||
|
@ -152,7 +149,7 @@ public:
|
||||||
// }
|
// }
|
||||||
void SetMotorState(EIOPort port, EMotorState state);
|
void SetMotorState(EIOPort port, EMotorState state);
|
||||||
void ControlAllMotors(const std::array<EMotorState, 4>& states) {
|
void ControlAllMotors(const std::array<EMotorState, 4>& states) {
|
||||||
for (u32 i = 0; i <= size_t(EIOPort::Three); ++i ) {
|
for (u32 i = 0; i <= size_t(EIOPort::Player4); ++i ) {
|
||||||
SetMotorState(EIOPort(i), states[i]);
|
SetMotorState(EIOPort(i), states[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
set(INPUT_SOURCES
|
set(INPUT_SOURCES
|
||||||
IController.hpp
|
IController.hpp DolphinIController.cpp
|
||||||
|
CControllerAxis.hpp
|
||||||
|
CControllerButton.hpp
|
||||||
|
CControllerGamepadData.hpp CControllerGamepadData.cpp
|
||||||
|
CDolphinController.hpp CDolphinController.cpp
|
||||||
CKeyboardMouseController.hpp
|
CKeyboardMouseController.hpp
|
||||||
ControlMapper.hpp ControlMapper.cpp
|
ControlMapper.hpp ControlMapper.cpp
|
||||||
CInputGenerator.hpp CInputGenerator.cpp
|
CInputGenerator.hpp CInputGenerator.cpp
|
||||||
|
|
|
@ -20,7 +20,7 @@ s16 CRumbleManager::Rumble(CStateManager& mgr, const zeus::CVector3f& pos, ERumb
|
||||||
|
|
||||||
s16 CRumbleManager::Rumble(CStateManager& mgr, ERumbleFxId fx, float gain, ERumblePriority priority) {
|
s16 CRumbleManager::Rumble(CStateManager& mgr, ERumbleFxId fx, float gain, ERumblePriority priority) {
|
||||||
if (g_GameState->GameOptions().GetIsRumbleEnabled())
|
if (g_GameState->GameOptions().GetIsRumbleEnabled())
|
||||||
return x0_rumbleGenerator.Rumble(RumbleFxTable[size_t(fx)], gain, priority, EIOPort::Zero);
|
return x0_rumbleGenerator.Rumble(RumbleFxTable[size_t(fx)], gain, priority, EIOPort::Player1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
void StopRumble(s16 id) {
|
void StopRumble(s16 id) {
|
||||||
if (id == -1)
|
if (id == -1)
|
||||||
return;
|
return;
|
||||||
x0_rumbleGenerator.Stop(id, EIOPort::Zero);
|
x0_rumbleGenerator.Stop(id, EIOPort::Player1);
|
||||||
}
|
}
|
||||||
void HardStopAll() { x0_rumbleGenerator.HardStopAll(); }
|
void HardStopAll() { x0_rumbleGenerator.HardStopAll(); }
|
||||||
s16 Rumble(CStateManager& mgr, const zeus::CVector3f& pos, ERumbleFxId fx, float dist, ERumblePriority priority);
|
s16 Rumble(CStateManager& mgr, const zeus::CVector3f& pos, ERumbleFxId fx, float dist, ERumblePriority priority);
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "Runtime/Input/IController.hpp"
|
||||||
|
#include "Runtime/Input/CDolphinController.hpp"
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
IController* IController::Create() {
|
||||||
|
CDolphinController* cont = new CDolphinController();
|
||||||
|
cont->Initialize();
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,26 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Runtime/Input/InputTypes.hpp"
|
||||||
|
#include "Runtime/Input/CControllerGamepadData.hpp"
|
||||||
|
|
||||||
|
#include "Runtime/GCNTypes.hpp"
|
||||||
|
|
||||||
namespace metaforce {
|
namespace metaforce {
|
||||||
|
|
||||||
class IController {
|
class IController {
|
||||||
|
protected:
|
||||||
|
static constexpr float kAbsoluteMinimum = -1.f;
|
||||||
|
static constexpr float kAbsoluteMaximum = 1.f;
|
||||||
|
static constexpr float kRelativeMinimum = -1.f;
|
||||||
|
static constexpr float kRelativeMaximum = 1.f;
|
||||||
public:
|
public:
|
||||||
enum class EMotorState { Stop = 0, Rumble = 1, StopHard = 2 };
|
|
||||||
virtual void Poll() = 0;
|
virtual void Poll() = 0;
|
||||||
virtual void SetMotorState(EMotorState state) = 0;
|
virtual u32 GetDeviceCount() const = 0;
|
||||||
|
virtual CControllerGamepadData& GetGamepadData(u32 controller) = 0;
|
||||||
|
virtual u32 GetControllerType(u32 controller) const = 0;
|
||||||
|
virtual void SetMotorState(EIOPort port, EMotorState state) = 0;
|
||||||
|
|
||||||
|
static IController* Create();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace metaforce
|
} // namespace metaforce
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace metaforce {
|
||||||
|
enum class EIOPort {
|
||||||
|
Player1,
|
||||||
|
Player2,
|
||||||
|
Player3,
|
||||||
|
Player4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EMotorState {
|
||||||
|
Stop = 0,
|
||||||
|
Rumble = 1,
|
||||||
|
StopHard = 2,
|
||||||
|
};
|
||||||
|
} // namespace metaforce
|
|
@ -1395,7 +1395,7 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoMenuSelectionChange(CGuiTableGroup* c
|
||||||
|
|
||||||
if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0) {
|
if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0) {
|
||||||
x40_rumbleGen.HardStopAll();
|
x40_rumbleGen.HardStopAll();
|
||||||
x40_rumbleGen.Rumble(RumbleFxTable[size_t(ERumbleFxId::PlayerBump)], 1.f, ERumblePriority::One, EIOPort::Zero);
|
x40_rumbleGen.Rumble(RumbleFxTable[size_t(ERumbleFxId::PlayerBump)], 1.f, ERumblePriority::One, EIOPort::Player1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -629,7 +629,7 @@ void CInGameGuiManager::ShowPauseGameHudMessage(CStateManager& stateMgr, CAssetI
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInGameGuiManager::PauseGame(CStateManager& stateMgr, EInGameGuiState state) {
|
void CInGameGuiManager::PauseGame(CStateManager& stateMgr, EInGameGuiState state) {
|
||||||
g_InputGenerator->SetMotorState(EIOPort::Zero, EMotorState::Stop);
|
g_InputGenerator->SetMotorState(EIOPort::Player1, EMotorState::Stop);
|
||||||
CSfxManager::SetChannel(CSfxManager::ESfxChannels::PauseScreen);
|
CSfxManager::SetChannel(CSfxManager::ESfxChannels::PauseScreen);
|
||||||
BeginStateTransition(state, stateMgr);
|
BeginStateTransition(state, stateMgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int oldSel) {
|
||||||
|
|
||||||
if (opt == EGameOption::Rumble && caller->GetUserSelection() > 0) {
|
if (opt == EGameOption::Rumble && caller->GetUserSelection() > 0) {
|
||||||
x1a8_rumble.HardStopAll();
|
x1a8_rumble.HardStopAll();
|
||||||
x1a8_rumble.Rumble(RumbleFxTable[size_t(ERumbleFxId::PlayerBump)], 1.f, ERumblePriority::One, EIOPort::Zero);
|
x1a8_rumble.Rumble(RumbleFxTable[size_t(ERumbleFxId::PlayerBump)], 1.f, ERumblePriority::One, EIOPort::Player1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPauseScreenBase::UpdateSideTable(caller);
|
CPauseScreenBase::UpdateSideTable(caller);
|
||||||
|
|
Loading…
Reference in New Issue