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 <mutex>
|
||||
|
||||
#include "Runtime/Input/InputTypes.hpp"
|
||||
#include "Runtime/Input/CFinalInput.hpp"
|
||||
#include "Runtime/Input/CKeyboardMouseController.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
class CArchitectureQueue;
|
||||
|
||||
enum class EIOPort { Zero, One, Two, Three };
|
||||
|
||||
enum class EMotorState { Stop, Rumble, StopHard };
|
||||
|
||||
class CInputGenerator /*: public boo::DeviceFinder*/ {
|
||||
enum class EStatusChange { NoChange = 0, Connected = 1, Disconnected = 2 };
|
||||
|
||||
|
@ -152,7 +149,7 @@ public:
|
|||
// }
|
||||
void SetMotorState(EIOPort port, EMotorState state);
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
set(INPUT_SOURCES
|
||||
IController.hpp
|
||||
IController.hpp DolphinIController.cpp
|
||||
CControllerAxis.hpp
|
||||
CControllerButton.hpp
|
||||
CControllerGamepadData.hpp CControllerGamepadData.cpp
|
||||
CDolphinController.hpp CDolphinController.cpp
|
||||
CKeyboardMouseController.hpp
|
||||
ControlMapper.hpp ControlMapper.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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public:
|
|||
void StopRumble(s16 id) {
|
||||
if (id == -1)
|
||||
return;
|
||||
x0_rumbleGenerator.Stop(id, EIOPort::Zero);
|
||||
x0_rumbleGenerator.Stop(id, EIOPort::Player1);
|
||||
}
|
||||
void HardStopAll() { x0_rumbleGenerator.HardStopAll(); }
|
||||
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
|
||||
|
||||
#include "Runtime/Input/InputTypes.hpp"
|
||||
#include "Runtime/Input/CControllerGamepadData.hpp"
|
||||
|
||||
#include "Runtime/GCNTypes.hpp"
|
||||
|
||||
namespace metaforce {
|
||||
|
||||
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:
|
||||
enum class EMotorState { Stop = 0, Rumble = 1, StopHard = 2 };
|
||||
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
|
||||
|
|
|
@ -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) {
|
||||
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) {
|
||||
g_InputGenerator->SetMotorState(EIOPort::Zero, EMotorState::Stop);
|
||||
g_InputGenerator->SetMotorState(EIOPort::Player1, EMotorState::Stop);
|
||||
CSfxManager::SetChannel(CSfxManager::ESfxChannels::PauseScreen);
|
||||
BeginStateTransition(state, stateMgr);
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int oldSel) {
|
|||
|
||||
if (opt == EGameOption::Rumble && caller->GetUserSelection() > 0) {
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue