Controller Updates (#193)

* Moves MenuBar from Window to ImGuiImpl

* Fixes a few clang-tidy issues.

* Renames ControlDeck functions to be more clear in what they do.

* Names are now consistent in Controller classes

* Updates gitignore for intellij projects.

* Controller.writeToSource has been removed.

We now use SetRumble and SetLed functions

* Runs clang-format

* Addresses clang-tidy on existing Controller code.
This commit is contained in:
Kenix3
2023-05-04 21:44:52 -04:00
committed by GitHub
parent 991c96ccbc
commit f9e554dc21
21 changed files with 528 additions and 477 deletions
+4 -1
View File
@@ -342,4 +342,7 @@ libultraship.a
libultraship.lib
ZAPDUtils.lib
.DS_Store
.vscode
.vscode/
.vs/
.idea/
cmake-build-**
@@ -129,11 +129,6 @@ typedef struct {
/* 0x20 */ int8_t right_stick_y;
} OSContPad; // size = 0x24
typedef struct {
/* 0x00 */ uint8_t rumble;
/* 0x01 */ uint8_t ledColor;
} ControllerCallback; // size = 0x02
typedef struct {
/* 0x00 */ void* address;
/* 0x04 */ uint8_t databuffer[32];
+61 -58
View File
@@ -18,113 +18,118 @@
namespace Ship {
void ControlDeck::Init(uint8_t* bits) {
ScanPhysicalDevices();
ScanDevices();
mControllerBits = bits;
}
void ControlDeck::ScanPhysicalDevices() {
void ControlDeck::ScanDevices() {
mPortList.clear();
mDevices.clear();
mVirtualDevices.clear();
mPhysicalDevices.clear();
auto controlDeck = Window::GetInstance()->GetControlDeck();
// Always load controllers that need their device indices zero based first because we add some other devices
// afterward.
int32_t i;
#ifndef __WIIU__
for (int32_t i = 0; i < SDL_NumJoysticks(); i++) {
for (i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
auto sdl = std::make_shared<SDLController>(i);
auto sdl = std::make_shared<SDLController>(controlDeck, i);
sdl->Open();
mPhysicalDevices.push_back(sdl);
mDevices.push_back(sdl);
}
}
mPhysicalDevices.push_back(std::make_shared<DummyController>("Auto", "Auto", true));
mPhysicalDevices.push_back(std::make_shared<KeyboardController>());
mDevices.push_back(std::make_shared<DummyController>(controlDeck, i++, "Auto", "Auto", true));
mDevices.push_back(std::make_shared<KeyboardController>(controlDeck, i++));
#else
mPhysicalDevices.push_back(std::make_shared<DummyController>("Auto", "Auto", true));
auto gamepad = std::make_shared<Ship::WiiUGamepad>();
gamepad->Open();
mPhysicalDevices.push_back(gamepad);
for (int32_t i = 0; i < 4; i++) {
auto controller = std::make_shared<Ship::WiiUController>((WPADChan)i);
for (i = 0; i < 4; i++) {
auto controller = std::make_shared<Ship::WiiUController>(controlDeck, i, (WPADChan)i);
controller->Open();
mPhysicalDevices.push_back(controller);
mDevices.push_back(controller);
}
auto gamepad = std::make_shared<Ship::WiiUGamepad>(controlDeck, i++);
gamepad->Open();
mDevices.push_back(gamepad);
mDevices.push_back(std::make_shared<DummyController>(controlDeck, i++, "Auto", "Auto", true));
#endif
mPhysicalDevices.push_back(std::make_shared<DummyController>("Disconnected", "None", false));
mDevices.push_back(std::make_shared<DummyController>(controlDeck, i++, "Disconnected", "None", false));
for (const auto& device : mPhysicalDevices) {
for (const auto& device : mDevices) {
for (int32_t i = 0; i < MAXCONTROLLERS; i++) {
device->CreateDefaultBinding(i);
}
}
for (int32_t i = 0; i < MAXCONTROLLERS; i++) {
mVirtualDevices.push_back(i == 0 ? 0 : static_cast<int>(mPhysicalDevices.size()) - 1);
mPortList.push_back(i == 0 ? 0 : static_cast<int>(mDevices.size()) - 1);
}
LoadControllerSettings();
LoadSettings();
}
void ControlDeck::SetPhysicalDevice(int32_t slot, int32_t deviceSlot) {
const std::shared_ptr<Controller> backend = mPhysicalDevices[deviceSlot];
mVirtualDevices[slot] = deviceSlot;
*mControllerBits |= (backend->Connected()) << slot;
void ControlDeck::SetDeviceToPort(int32_t portIndex, int32_t deviceIndex) {
const std::shared_ptr<Controller> backend = mDevices[deviceIndex];
mPortList[portIndex] = deviceIndex;
*mControllerBits |= (backend->Connected()) << portIndex;
}
void ControlDeck::WriteToPad(OSContPad* pad) const {
for (size_t i = 0; i < mVirtualDevices.size(); i++) {
const std::shared_ptr<Controller> backend = mPhysicalDevices[mVirtualDevices[i]];
for (size_t i = 0; i < mPortList.size(); i++) {
const std::shared_ptr<Controller> backend = mDevices[mPortList[i]];
// If the controller backend is "Auto" we need to get the real device
// we search for the real device to read input from it
if (backend->GetGuid() == "Auto") {
for (const auto& device : mPhysicalDevices) {
for (const auto& device : mDevices) {
if (ShouldBlockGameInput(device->GetGuid())) {
device->Read(nullptr, i);
device->ReadToPad(nullptr, i);
continue;
}
device->Read(&pad[i], i);
device->ReadToPad(&pad[i], i);
}
continue;
}
if (ShouldBlockGameInput(backend->GetGuid())) {
backend->Read(nullptr, i);
backend->ReadToPad(nullptr, i);
continue;
}
backend->Read(&pad[i], i);
backend->ReadToPad(&pad[i], i);
}
}
#define NESTED(key, ...) \
StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), virtualSlot, __VA_ARGS__)
void ControlDeck::LoadControllerSettings() {
void ControlDeck::LoadSettings() {
std::shared_ptr<Mercury> config = Window::GetInstance()->GetConfig();
for (auto const& val : config->rjson["Controllers"]["Deck"].items()) {
int32_t slot = std::stoi(val.key().substr(5));
for (size_t dev = 0; dev < mPhysicalDevices.size(); dev++) {
std::string guid = mPhysicalDevices[dev]->GetGuid();
for (size_t dev = 0; dev < mDevices.size(); dev++) {
std::string guid = mDevices[dev]->GetGuid();
if (guid != val.value().get<std::string>()) {
continue;
}
mVirtualDevices[slot] = dev;
mPortList[slot] = dev;
}
}
for (size_t i = 0; i < mVirtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = mPhysicalDevices[mVirtualDevices[i]];
for (size_t i = 0; i < mPortList.size(); i++) {
std::shared_ptr<Controller> backend = mDevices[mPortList[i]];
config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}
for (const auto& device : mPhysicalDevices) {
for (const auto& device : mDevices) {
std::string guid = device->GetGuid();
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
@@ -134,7 +139,7 @@ void ControlDeck::LoadControllerSettings() {
continue;
}
auto profile = device->getProfile(virtualSlot);
auto profile = device->GetProfile(virtualSlot);
auto rawProfile = config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", virtualSlot)];
profile->Mappings.clear();
@@ -194,21 +199,19 @@ void ControlDeck::LoadControllerSettings() {
}
}
void ControlDeck::SaveControllerSettings() {
void ControlDeck::SaveSettings() {
std::shared_ptr<Mercury> config = Window::GetInstance()->GetConfig();
for (size_t i = 0; i < mVirtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = mPhysicalDevices[mVirtualDevices[i]];
for (size_t i = 0; i < mPortList.size(); i++) {
std::shared_ptr<Controller> backend = mDevices[mPortList[i]];
config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}
for (const auto& device : mPhysicalDevices) {
int32_t virtualSlot = 0;
for (const auto& device : mDevices) {
std::string guid = device->GetGuid();
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
auto profile = device->getProfile(virtualSlot);
auto profile = device->GetProfile(virtualSlot);
if (!device->Connected()) {
continue;
@@ -248,24 +251,24 @@ void ControlDeck::SaveControllerSettings() {
config->save();
}
std::shared_ptr<Controller> ControlDeck::GetPhysicalDevice(int32_t deviceSlot) {
return mPhysicalDevices[deviceSlot];
std::shared_ptr<Controller> ControlDeck::GetDeviceFromDeviceIndex(int32_t deviceIndex) {
return mDevices[deviceIndex];
}
size_t ControlDeck::GetNumPhysicalDevices() {
return mPhysicalDevices.size();
size_t ControlDeck::GetNumDevices() {
return mDevices.size();
}
int32_t ControlDeck::GetVirtualDevice(int32_t slot) {
return mVirtualDevices[slot];
int32_t ControlDeck::GetDeviceIndexFromPortIndex(int32_t portIndex) {
return mPortList[portIndex];
}
size_t ControlDeck::GetNumVirtualDevices() {
return mVirtualDevices.size();
size_t ControlDeck::GetNumConnectedPorts() {
return mPortList.size();
}
std::shared_ptr<Controller> ControlDeck::GetPhysicalDeviceFromVirtualSlot(int32_t slot) {
return GetPhysicalDevice(GetVirtualDevice(slot));
std::shared_ptr<Controller> ControlDeck::GetDeviceFromPortIndex(int32_t portIndex) {
return GetDeviceFromDeviceIndex(GetDeviceIndexFromPortIndex(portIndex));
}
uint8_t* ControlDeck::GetControllerBits() {
+11 -11
View File
@@ -9,24 +9,24 @@ namespace Ship {
class ControlDeck {
public:
void Init(uint8_t* controllerBits);
void ScanPhysicalDevices();
void ScanDevices();
void WriteToPad(OSContPad* pad) const;
void LoadControllerSettings();
void SaveControllerSettings();
void SetPhysicalDevice(int32_t slot, int32_t deviceSlot);
std::shared_ptr<Controller> GetPhysicalDevice(int32_t deviceSlot);
std::shared_ptr<Controller> GetPhysicalDeviceFromVirtualSlot(int32_t slot);
size_t GetNumPhysicalDevices();
int32_t GetVirtualDevice(int32_t slot);
size_t GetNumVirtualDevices();
void LoadSettings();
void SaveSettings();
void SetDeviceToPort(int32_t portIndex, int32_t deviceIndex);
std::shared_ptr<Controller> GetDeviceFromDeviceIndex(int32_t deviceIndex);
std::shared_ptr<Controller> GetDeviceFromPortIndex(int32_t portIndex);
int32_t GetDeviceIndexFromPortIndex(int32_t portIndex);
size_t GetNumDevices();
size_t GetNumConnectedPorts();
uint8_t* GetControllerBits();
void BlockGameInput();
void UnblockGameInput();
bool ShouldBlockGameInput(std::string inputDeviceGuid) const;
private:
std::vector<int32_t> mVirtualDevices = {};
std::vector<std::shared_ptr<Controller>> mPhysicalDevices = {};
std::vector<int32_t> mPortList = {};
std::vector<std::shared_ptr<Controller>> mDevices = {};
uint8_t* mControllerBits = nullptr;
bool mShouldBlockGameInput = false;
};
+58 -51
View File
@@ -14,40 +14,39 @@
namespace Ship {
Controller::Controller() : mIsRumbling(false) {
mAttachment = nullptr;
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
mProfiles[virtualSlot] = std::make_shared<DeviceProfile>();
mButtonData[virtualSlot] = std::make_shared<Buttons>();
Controller::Controller(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex)
: mIsRumbling(false), mAttachment(nullptr), mDeviceIndex(deviceIndex), mControlDeck(controlDeck) {
for (int32_t portIndex = 0; portIndex < MAXCONTROLLERS; portIndex++) {
mProfiles[portIndex] = std::make_shared<DeviceProfile>();
mButtonData[portIndex] = std::make_shared<Buttons>();
}
}
int8_t Controller::ReadStick(int32_t virtualSlot, Stick stick, Axis axis) {
int8_t Controller::ReadStick(int32_t portIndex, Stick stick, Axis axis) {
switch (stick) {
case Stick::LEFT: {
switch (axis) {
case Axis::X: {
if (getLeftStickX(virtualSlot) == 0) {
if (getPressedButtons(virtualSlot) & BTN_STICKLEFT) {
if (GetLeftStickX(portIndex) == 0) {
if (GetPressedButtons(portIndex) & BTN_STICKLEFT) {
return -MAX_AXIS_RANGE;
} else if (getPressedButtons(virtualSlot) & BTN_STICKRIGHT) {
} else if (GetPressedButtons(portIndex) & BTN_STICKRIGHT) {
return MAX_AXIS_RANGE;
}
} else {
return getLeftStickX(virtualSlot);
return GetLeftStickX(portIndex);
}
break;
}
case Axis::Y: {
if (getLeftStickY(virtualSlot) == 0) {
if (getPressedButtons(virtualSlot) & BTN_STICKDOWN) {
if (GetLeftStickY(portIndex) == 0) {
if (GetPressedButtons(portIndex) & BTN_STICKDOWN) {
return -MAX_AXIS_RANGE;
} else if (getPressedButtons(virtualSlot) & BTN_STICKUP) {
} else if (GetPressedButtons(portIndex) & BTN_STICKUP) {
return MAX_AXIS_RANGE;
}
} else {
return getLeftStickY(virtualSlot);
return GetLeftStickY(portIndex);
}
break;
}
@@ -57,26 +56,26 @@ int8_t Controller::ReadStick(int32_t virtualSlot, Stick stick, Axis axis) {
case Stick::RIGHT: {
switch (axis) {
case Axis::X: {
if (getRightStickX(virtualSlot) == 0) {
if (getPressedButtons(virtualSlot) & BTN_VSTICKLEFT) {
if (GetRightStickX(portIndex) == 0) {
if (GetPressedButtons(portIndex) & BTN_VSTICKLEFT) {
return -MAX_AXIS_RANGE;
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKRIGHT) {
} else if (GetPressedButtons(portIndex) & BTN_VSTICKRIGHT) {
return MAX_AXIS_RANGE;
}
} else {
return getRightStickX(virtualSlot);
return GetRightStickX(portIndex);
}
break;
}
case Axis::Y: {
if (getRightStickY(virtualSlot) == 0) {
if (getPressedButtons(virtualSlot) & BTN_VSTICKDOWN) {
if (GetRightStickY(portIndex) == 0) {
if (GetPressedButtons(portIndex) & BTN_VSTICKDOWN) {
return -MAX_AXIS_RANGE;
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKUP) {
} else if (GetPressedButtons(portIndex) & BTN_VSTICKUP) {
return MAX_AXIS_RANGE;
}
} else {
return getRightStickY(virtualSlot);
return GetRightStickY(portIndex);
}
break;
}
@@ -138,8 +137,8 @@ void Controller::ProcessStick(int8_t& x, int8_t& y, float deadzoneX, float deadz
y = copysign(uy, y);
}
void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
ReadFromSource(virtualSlot);
void Controller::ReadToPad(OSContPad* pad, int32_t portIndex) {
ReadDevice(portIndex);
OSContPad padToBuffer = { 0 };
@@ -148,15 +147,15 @@ void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
#endif
// Button Inputs
padToBuffer.button |= getPressedButtons(virtualSlot) & 0xFFFF;
padToBuffer.button |= GetPressedButtons(portIndex) & 0xFFFF;
// Stick Inputs
int8_t leftStickX = ReadStick(virtualSlot, LEFT, X);
int8_t leftStickY = ReadStick(virtualSlot, LEFT, Y);
int8_t rightStickX = ReadStick(virtualSlot, RIGHT, X);
int8_t rightStickY = ReadStick(virtualSlot, RIGHT, Y);
int8_t leftStickX = ReadStick(portIndex, LEFT, X);
int8_t leftStickY = ReadStick(portIndex, LEFT, Y);
int8_t rightStickX = ReadStick(portIndex, RIGHT, X);
int8_t rightStickY = ReadStick(portIndex, RIGHT, Y);
auto profile = getProfile(virtualSlot);
auto profile = GetProfile(portIndex);
ProcessStick(leftStickX, leftStickY, profile->AxisDeadzones[0], profile->AxisDeadzones[1],
profile->NotchProximityThreshold);
ProcessStick(rightStickX, rightStickY, profile->AxisDeadzones[2], profile->AxisDeadzones[3],
@@ -172,8 +171,8 @@ void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
padToBuffer.right_stick_y = rightStickY;
// Gyro
padToBuffer.gyro_x = getGyroX(virtualSlot);
padToBuffer.gyro_y = getGyroY(virtualSlot);
padToBuffer.gyro_x = GetGyroX(portIndex);
padToBuffer.gyro_y = GetGyroY(portIndex);
mPadBuffer.push_front(padToBuffer);
if (pad != nullptr) {
@@ -205,42 +204,42 @@ void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
}
}
void Controller::SetButtonMapping(int32_t virtualSlot, int32_t n64Button, int32_t scancode) {
std::map<int32_t, int32_t>& mappings = getProfile(virtualSlot)->Mappings;
void Controller::SetButtonMapping(int32_t portIndex, int32_t n64Button, int32_t scancode) {
std::map<int32_t, int32_t>& mappings = GetProfile(portIndex)->Mappings;
std::erase_if(mappings, [n64Button](const std::pair<int32_t, int32_t>& bin) { return bin.second == n64Button; });
mappings[scancode] = n64Button;
}
int8_t& Controller::getLeftStickX(int32_t virtualSlot) {
return mButtonData[virtualSlot]->LeftStickX;
int8_t& Controller::GetLeftStickX(int32_t portIndex) {
return mButtonData[portIndex]->LeftStickX;
}
int8_t& Controller::getLeftStickY(int32_t virtualSlot) {
return mButtonData[virtualSlot]->LeftStickY;
int8_t& Controller::GetLeftStickY(int32_t portIndex) {
return mButtonData[portIndex]->LeftStickY;
}
int8_t& Controller::getRightStickX(int32_t virtualSlot) {
return mButtonData[virtualSlot]->RightStickX;
int8_t& Controller::GetRightStickX(int32_t portIndex) {
return mButtonData[portIndex]->RightStickX;
}
int8_t& Controller::getRightStickY(int32_t virtualSlot) {
return mButtonData[virtualSlot]->RightStickY;
int8_t& Controller::GetRightStickY(int32_t portIndex) {
return mButtonData[portIndex]->RightStickY;
}
int32_t& Controller::getPressedButtons(int32_t virtualSlot) {
return mButtonData[virtualSlot]->PressedButtons;
int32_t& Controller::GetPressedButtons(int32_t portIndex) {
return mButtonData[portIndex]->PressedButtons;
}
float& Controller::getGyroX(int32_t virtualSlot) {
return mButtonData[virtualSlot]->GyroX;
float& Controller::GetGyroX(int32_t portIndex) {
return mButtonData[portIndex]->GyroX;
}
float& Controller::getGyroY(int32_t virtualSlot) {
return mButtonData[virtualSlot]->GyroY;
float& Controller::GetGyroY(int32_t portIndex) {
return mButtonData[portIndex]->GyroY;
}
std::shared_ptr<DeviceProfile> Controller::getProfile(int32_t virtualSlot) {
return mProfiles[virtualSlot];
std::shared_ptr<DeviceProfile> Controller::GetProfile(int32_t portIndex) {
return mProfiles[portIndex];
}
std::shared_ptr<ControllerAttachment> Controller::GetAttachment() {
@@ -255,10 +254,18 @@ std::string Controller::GetGuid() {
return mGuid;
}
std::string Controller::GetControllerName() {
return mControllerName;
}
double Controller::GetClosestNotch(double angle, double approximationThreshold) {
constexpr auto octagonAngle = M_TAU / 8;
const auto closestNotch = std::round(angle / octagonAngle) * octagonAngle;
const auto distanceToNotch = std::abs(fmod(closestNotch - angle + M_PI, M_TAU) - M_PI);
return distanceToNotch < approximationThreshold / 2 ? closestNotch : angle;
}
std::shared_ptr<ControlDeck> Controller::GetControlDeck() {
return mControlDeck;
}
} // namespace Ship
+26 -17
View File
@@ -33,41 +33,49 @@ struct DeviceProfile {
std::map<int32_t, int32_t> Mappings;
};
class ControlDeck;
class Controller {
public:
virtual ~Controller() = default;
Controller();
virtual void ReadFromSource(int32_t virtualSlot) = 0;
virtual void WriteToSource(int32_t virtualSlot, ControllerCallback* controller) = 0;
Controller(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex);
virtual void ReadDevice(int32_t portIndex) = 0;
virtual bool Connected() const = 0;
virtual bool CanRumble() const = 0;
virtual bool CanSetLed() const = 0;
virtual bool CanGyro() const = 0;
virtual void CreateDefaultBinding(int32_t virtualSlot) = 0;
virtual void CreateDefaultBinding(int32_t portIndex) = 0;
virtual void ClearRawPress() = 0;
virtual int32_t ReadRawPress() = 0;
virtual const std::string GetButtonName(int32_t virtualSlot, int32_t n64Button) = 0;
virtual const std::string GetControllerName() = 0;
void Read(OSContPad* pad, int32_t virtualSlot);
void SetButtonMapping(int32_t virtualSlot, int32_t n64Button, int32_t scancode);
virtual const std::string GetButtonName(int32_t portIndex, int32_t n64Button) = 0;
virtual int32_t SetRumble(int32_t portIndex, bool rumble) = 0;
virtual int32_t SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) = 0;
std::string GetControllerName();
void ReadToPad(OSContPad* pad, int32_t portIndex);
void SetButtonMapping(int32_t portIndex, int32_t n64Button, int32_t scancode);
std::shared_ptr<ControllerAttachment> GetAttachment();
std::shared_ptr<DeviceProfile> getProfile(int32_t virtualSlot);
int8_t& getLeftStickX(int32_t virtualSlot);
int8_t& getLeftStickY(int32_t virtualSlot);
int8_t& getRightStickX(int32_t virtualSlot);
int8_t& getRightStickY(int32_t virtualSlot);
int32_t& getPressedButtons(int32_t virtualSlot);
float& getGyroX(int32_t virtualSlot);
float& getGyroY(int32_t virtualSlot);
std::shared_ptr<DeviceProfile> GetProfile(int32_t portIndex);
int8_t& GetLeftStickX(int32_t portIndex);
int8_t& GetLeftStickY(int32_t portIndex);
int8_t& GetRightStickX(int32_t portIndex);
int8_t& GetRightStickY(int32_t portIndex);
int32_t& GetPressedButtons(int32_t portIndex);
float& GetGyroX(int32_t portIndex);
float& GetGyroY(int32_t portIndex);
bool IsRumbling();
std::string GetGuid();
std::shared_ptr<ControlDeck> GetControlDeck();
protected:
std::shared_ptr<ControllerAttachment> mAttachment;
std::string mGuid;
bool mIsRumbling;
int32_t mDeviceIndex;
std::string mControllerName = "Unknown";
void LoadBinding();
int8_t ReadStick(int32_t virtualSlot, Stick stick, Axis axis);
int8_t ReadStick(int32_t portIndex, Stick stick, Axis axis);
void ProcessStick(int8_t& x, int8_t& y, float deadzoneX, float deadzoneY, int32_t notchProxmityThreshold);
private:
@@ -84,6 +92,7 @@ class Controller {
std::unordered_map<int32_t, std::shared_ptr<DeviceProfile>> mProfiles;
std::unordered_map<int32_t, std::shared_ptr<Buttons>> mButtonData = {};
std::deque<OSContPad> mPadBuffer;
std::shared_ptr<ControlDeck> mControlDeck;
double GetClosestNotch(double angle, double approximationThreshold);
};
+19 -23
View File
@@ -1,30 +1,38 @@
#include "DummyController.h"
namespace Ship {
DummyController::DummyController(const std::string& guid, const std::string& keyName, bool connected) {
DummyController::DummyController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex, const std::string& guid,
const std::string& keyName, bool connected)
: Controller(controlDeck, deviceIndex) {
mGuid = guid;
mControllerName = guid;
mIsConnected = connected;
mButtonName = keyName;
}
void DummyController::ReadFromSource(int32_t virtualSlot) {
void DummyController::ReadDevice(int32_t portIndex) {
}
const std::string DummyController::GetControllerName() {
return mGuid;
}
const std::string DummyController::GetButtonName(int32_t virtualSlot, int32_t n64Button) {
const std::string DummyController::GetButtonName(int32_t portIndex, int32_t n64Button) {
return mButtonName;
}
void DummyController::WriteToSource(int32_t virtualSlot, ControllerCallback* controller) {
}
bool DummyController::Connected() const {
return mIsConnected;
}
int32_t DummyController::SetRumble(int32_t portIndex, bool rumble) {
return -1000;
}
int32_t DummyController::SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) {
return -1000;
}
bool DummyController::CanSetLed() const {
return false;
}
bool DummyController::CanRumble() const {
return false;
}
@@ -33,19 +41,7 @@ bool DummyController::CanGyro() const {
return false;
}
void DummyController::CreateDefaultBinding(int32_t slot) {
}
std::string DummyController::GetControllerType() {
return "Unk";
}
std::string DummyController::GetConfSection() {
return "Unk";
}
std::string DummyController::GetBindingConfSection() {
return "Unk";
void DummyController::CreateDefaultBinding(int32_t portIndex) {
}
void DummyController::ClearRawPress() {
+8 -11
View File
@@ -7,26 +7,23 @@
namespace Ship {
class DummyController final : public Controller {
public:
DummyController(const std::string& guid, const std::string& keyName, bool connected);
DummyController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex, const std::string& guid,
const std::string& keyName, bool connected);
std::map<std::vector<std::string>, int32_t> ReadButtonPress();
void ReadFromSource(int32_t virtualSlot) override;
const std::string GetControllerName() override;
const std::string GetButtonName(int32_t virtualSlot, int32_t n64Button) override;
void WriteToSource(int32_t slot, ControllerCallback* controller) override;
void ReadDevice(int32_t portIndex) override;
const std::string GetButtonName(int32_t portIndex, int32_t n64Button) override;
bool Connected() const override;
bool CanRumble() const override;
bool CanSetLed() const override;
bool CanGyro() const override;
void ClearRawPress() override;
int32_t ReadRawPress() override;
bool HasPadConf() const;
std::optional<std::string> GetPadConfSection();
void CreateDefaultBinding(int32_t virtualSlot) override;
int32_t SetRumble(int32_t portIndex, bool rumble) override;
int32_t SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) override;
void CreateDefaultBinding(int32_t portIndex) override;
protected:
std::string mButtonName;
bool mIsConnected = false;
std::string GetControllerType();
std::string GetConfSection();
std::string GetBindingConfSection();
};
} // namespace Ship
+35 -27
View File
@@ -11,18 +11,20 @@
namespace Ship {
KeyboardController::KeyboardController() : Controller(), mLastScancode(-1) {
KeyboardController::KeyboardController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex)
: Controller(controlDeck, deviceIndex), mLastScancode(-1) {
mGuid = "Keyboard";
mControllerName = "Keyboard";
}
bool KeyboardController::PressButton(int32_t scancode) {
mLastKey = scancode;
bool readSuccess = false;
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
for (int32_t portIndex = 0; portIndex < MAXCONTROLLERS; portIndex++) {
if (getProfile(virtualSlot)->Mappings.contains(scancode)) {
getPressedButtons(virtualSlot) |= getProfile(virtualSlot)->Mappings[scancode];
if (GetProfile(portIndex)->Mappings.contains(scancode)) {
GetPressedButtons(portIndex) |= GetProfile(portIndex)->Mappings[scancode];
readSuccess = true;
}
}
@@ -33,9 +35,9 @@ bool KeyboardController::PressButton(int32_t scancode) {
bool KeyboardController::ReleaseButton(int32_t scancode) {
bool readSuccess = false;
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
if (getProfile(virtualSlot)->Mappings.contains(scancode)) {
getPressedButtons(virtualSlot) &= ~getProfile(virtualSlot)->Mappings[scancode];
for (int32_t portIndex = 0; portIndex < MAXCONTROLLERS; portIndex++) {
if (GetProfile(portIndex)->Mappings.contains(scancode)) {
GetPressedButtons(portIndex) &= ~GetProfile(portIndex)->Mappings[scancode];
readSuccess = true;
}
}
@@ -44,40 +46,37 @@ bool KeyboardController::ReleaseButton(int32_t scancode) {
}
void KeyboardController::ReleaseAllButtons() {
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
getPressedButtons(virtualSlot) = 0;
for (int32_t portIndex = 0; portIndex < MAXCONTROLLERS; portIndex++) {
GetPressedButtons(portIndex) = 0;
}
}
void KeyboardController::ReadFromSource(int32_t virtualSlot) {
getLeftStickX(virtualSlot) = 0;
getLeftStickY(virtualSlot) = 0;
getRightStickX(virtualSlot) = 0;
getRightStickY(virtualSlot) = 0;
void KeyboardController::ReadDevice(int32_t portIndex) {
GetLeftStickX(portIndex) = 0;
GetLeftStickY(portIndex) = 0;
GetRightStickX(portIndex) = 0;
GetRightStickY(portIndex) = 0;
}
int32_t KeyboardController::ReadRawPress() {
return mLastKey;
}
void KeyboardController::WriteToSource(int32_t virtualSlot, ControllerCallback* controller) {
}
const std::string KeyboardController::GetButtonName(int32_t virtualSlot, int32_t n64Button) {
std::map<int32_t, int32_t>& Mappings = getProfile(virtualSlot)->Mappings;
const std::string KeyboardController::GetButtonName(int32_t portIndex, int32_t n64Button) {
std::map<int32_t, int32_t>& mappings = GetProfile(portIndex)->Mappings;
const auto find =
std::find_if(Mappings.begin(), Mappings.end(),
std::find_if(mappings.begin(), mappings.end(),
[n64Button](const std::pair<int32_t, int32_t>& pair) { return pair.second == n64Button; });
if (find == Mappings.end()) {
if (find == mappings.end()) {
return "Unknown";
}
const char* name = Window::GetInstance()->GetKeyName(find->first);
return strlen(name) == 0 ? "Unknown" : name;
}
void KeyboardController::CreateDefaultBinding(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void KeyboardController::CreateDefaultBinding(int32_t portIndex) {
auto profile = GetProfile(portIndex);
profile->Mappings[0x14D] = BTN_CRIGHT;
profile->Mappings[0x14B] = BTN_CLEFT;
profile->Mappings[0x150] = BTN_CDOWN;
@@ -100,10 +99,6 @@ void KeyboardController::CreateDefaultBinding(int32_t virtualSlot) {
profile->Mappings[0x036] = BTN_MODIFIER2;
}
const std::string KeyboardController::GetControllerName() {
return "Keyboard";
}
bool KeyboardController::Connected() const {
return true;
}
@@ -127,4 +122,17 @@ void KeyboardController::SetLastScancode(int32_t key) {
int32_t KeyboardController::GetLastScancode() {
return mLastScancode;
}
bool KeyboardController::CanSetLed() const {
return false;
}
int32_t KeyboardController::SetRumble(int32_t portIndex, bool rumble) {
return -1001;
}
int32_t KeyboardController::SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) {
// Not supported today, but theoretically we could tie into some of the keyboard APIs to set RGB lights.
return -1001;
}
} // namespace Ship
+7 -6
View File
@@ -5,23 +5,24 @@
namespace Ship {
class KeyboardController : public Controller {
public:
KeyboardController();
KeyboardController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex);
void ReadFromSource(int32_t virtualSlot) override;
void WriteToSource(int32_t virtualSlot, ControllerCallback* controller) override;
const std::string GetControllerName() override;
const std::string GetButtonName(int32_t virtualSlot, int32_t n64Button) override;
void ReadDevice(int32_t portIndex) override;
const std::string GetButtonName(int32_t portIndex, int32_t n64Button) override;
bool PressButton(int32_t scancode);
bool ReleaseButton(int32_t scancode);
bool Connected() const override;
bool CanRumble() const override;
bool CanSetLed() const override;
bool CanGyro() const override;
void ClearRawPress() override;
int32_t SetRumble(int32_t portIndex, bool rumble) override;
int32_t SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) override;
void CreateDefaultBinding(int32_t portIndex) override;
int32_t ReadRawPress() override;
void ReleaseAllButtons();
void SetLastScancode(int32_t key);
int32_t GetLastScancode();
void CreateDefaultBinding(int32_t virtualSlot) override;
protected:
int32_t mLastScancode;
+62 -66
View File
@@ -3,7 +3,6 @@
#include "SDLController.h"
#include <spdlog/spdlog.h>
#include "core/Window.h"
#include <Utils/StringHelper.h>
#ifdef _MSC_VER
@@ -14,11 +13,12 @@
namespace Ship {
SDLController::SDLController(int32_t physicalSlot) : Controller(), mController(nullptr), mPhysicalSlot(physicalSlot) {
SDLController::SDLController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex)
: Controller(controlDeck, deviceIndex), mController(nullptr) {
}
bool SDLController::Open() {
const auto newCont = SDL_GameControllerOpen(mPhysicalSlot);
const auto newCont = SDL_GameControllerOpen(mDeviceIndex);
// We failed to load the controller. Go to next.
if (newCont == nullptr) {
@@ -32,16 +32,16 @@ bool SDLController::Open() {
mSupportsGyro = true;
}
char GuidBuf[33];
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(mPhysicalSlot), GuidBuf, sizeof(GuidBuf));
char guidBuf[33];
SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(mDeviceIndex), guidBuf, sizeof(guidBuf));
mController = newCont;
#ifdef __SWITCH__
mGuid = StringHelper::Sprintf("%s:%d", GuidBuf, mPhysicalSlot);
mControllerName = StringHelper::Sprintf("%s #%d", SDL_GameControllerNameForIndex(mPhysicalSlot), mPhysicalSlot + 1);
mGuid = StringHelper::Sprintf("%s:%d", guidBuf, mDeviceIndex);
mControllerName = StringHelper::Sprintf("%s #%d", SDL_GameControllerNameForIndex(mDeviceIndex), mDeviceIndex + 1);
#else
mGuid = std::string(GuidBuf);
mControllerName = std::string(SDL_GameControllerNameForIndex(mPhysicalSlot));
mGuid = std::string(guidBuf);
mControllerName = std::string(SDL_GameControllerNameForIndex(mDeviceIndex));
#endif
return true;
}
@@ -58,8 +58,7 @@ bool SDLController::Close() {
return true;
}
void SDLController::NormalizeStickAxis(SDL_GameControllerAxis axisX, SDL_GameControllerAxis axisY,
int32_t virtualSlot) {
void SDLController::NormalizeStickAxis(SDL_GameControllerAxis axisX, SDL_GameControllerAxis axisY, int32_t portIndex) {
const auto axisValueX = SDL_GameControllerGetAxis(mController, axisX);
const auto axisValueY = SDL_GameControllerGetAxis(mController, axisY);
@@ -68,11 +67,11 @@ void SDLController::NormalizeStickAxis(SDL_GameControllerAxis axisX, SDL_GameCon
auto ay = axisValueY * MAX_AXIS_RANGE / MAX_SDL_RANGE;
if (axisX == SDL_CONTROLLER_AXIS_LEFTX) {
getLeftStickX(virtualSlot) = +ax;
getLeftStickY(virtualSlot) = -ay;
GetLeftStickX(portIndex) = +ax;
GetLeftStickY(portIndex) = -ay;
} else if (axisX == SDL_CONTROLLER_AXIS_RIGHTX) {
getRightStickX(virtualSlot) = +ax;
getRightStickY(virtualSlot) = -ay;
GetRightStickX(portIndex) = +ax;
GetRightStickY(portIndex) = -ay;
}
}
@@ -101,8 +100,8 @@ int32_t SDLController::ReadRawPress() {
return -1;
}
void SDLController::ReadFromSource(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void SDLController::ReadDevice(int32_t portIndex) {
auto profile = GetProfile(portIndex);
SDL_GameControllerUpdate();
@@ -126,7 +125,7 @@ void SDLController::ReadFromSource(int32_t virtualSlot) {
float gyroDriftX = profile->GyroData[DRIFT_X] / 100.0f;
float gyroDriftY = profile->GyroData[DRIFT_Y] / 100.0f;
const float gyro_sensitivity = profile->GyroData[GYRO_SENSITIVITY];
const float gyroSensitivity = profile->GyroData[GYRO_SENSITIVITY];
if (gyroDriftX == 0) {
gyroDriftX = gyroData[0];
@@ -139,24 +138,24 @@ void SDLController::ReadFromSource(int32_t virtualSlot) {
profile->GyroData[DRIFT_X] = gyroDriftX * 100.0f;
profile->GyroData[DRIFT_Y] = gyroDriftY * 100.0f;
getGyroX(virtualSlot) = gyroData[0] - gyroDriftX;
getGyroY(virtualSlot) = gyroData[1] - gyroDriftY;
GetGyroX(portIndex) = gyroData[0] - gyroDriftX;
GetGyroY(portIndex) = gyroData[1] - gyroDriftY;
getGyroX(virtualSlot) *= gyro_sensitivity;
getGyroY(virtualSlot) *= gyro_sensitivity;
GetGyroX(portIndex) *= gyroSensitivity;
GetGyroY(portIndex) *= gyroSensitivity;
} else {
getGyroX(virtualSlot) = 0;
getGyroY(virtualSlot) = 0;
GetGyroX(portIndex) = 0;
GetGyroY(portIndex) = 0;
}
getPressedButtons(virtualSlot) = 0;
GetPressedButtons(portIndex) = 0;
for (int32_t i = SDL_CONTROLLER_BUTTON_A; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
if (profile->Mappings.contains(i)) {
if (SDL_GameControllerGetButton(mController, static_cast<SDL_GameControllerButton>(i))) {
getPressedButtons(virtualSlot) |= profile->Mappings[i];
GetPressedButtons(portIndex) |= profile->Mappings[i];
} else {
getPressedButtons(virtualSlot) &= ~profile->Mappings[i];
GetPressedButtons(portIndex) &= ~profile->Mappings[i];
}
}
}
@@ -196,14 +195,14 @@ void SDLController::ReadFromSource(int32_t virtualSlot) {
// The axis is being treated as a "button"
if (axisValue > axisMinimumPress) {
getPressedButtons(virtualSlot) |= posButton;
getPressedButtons(virtualSlot) &= ~negButton;
GetPressedButtons(portIndex) |= posButton;
GetPressedButtons(portIndex) &= ~negButton;
} else if (axisValue < -axisMinimumPress) {
getPressedButtons(virtualSlot) &= ~posButton;
getPressedButtons(virtualSlot) |= negButton;
GetPressedButtons(portIndex) &= ~posButton;
GetPressedButtons(portIndex) |= negButton;
} else {
getPressedButtons(virtualSlot) &= ~posButton;
getPressedButtons(virtualSlot) &= ~negButton;
GetPressedButtons(portIndex) &= ~posButton;
GetPressedButtons(portIndex) &= ~negButton;
}
} else {
// The axis is being treated as a "stick"
@@ -277,45 +276,42 @@ void SDLController::ReadFromSource(int32_t virtualSlot) {
}
if (leftStickAxisX != SDL_CONTROLLER_AXIS_INVALID && leftStickAxisY != SDL_CONTROLLER_AXIS_INVALID) {
NormalizeStickAxis(leftStickAxisX, leftStickAxisY, virtualSlot);
NormalizeStickAxis(leftStickAxisX, leftStickAxisY, portIndex);
}
if (rightStickAxisX != SDL_CONTROLLER_AXIS_INVALID && rightStickAxisY != SDL_CONTROLLER_AXIS_INVALID) {
NormalizeStickAxis(rightStickAxisX, rightStickAxisY, virtualSlot);
NormalizeStickAxis(rightStickAxisX, rightStickAxisY, portIndex);
}
}
void SDLController::WriteToSource(int32_t virtualSlot, ControllerCallback* controller) {
if (CanRumble() && getProfile(virtualSlot)->UseRumble) {
if (controller->rumble > 0) {
float rumble_strength = getProfile(virtualSlot)->RumbleStrength;
SDL_GameControllerRumble(mController, 0xFFFF * rumble_strength, 0xFFFF * rumble_strength, 0);
} else {
SDL_GameControllerRumble(mController, 0, 0, 0);
}
int32_t SDLController::SetRumble(int32_t portIndex, bool rumble) {
if (!CanRumble()) {
return -1000;
}
if (SDL_GameControllerHasLED(mController)) {
switch (controller->ledColor) {
case 0:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(mController), 255, 0, 0);
break;
case 1:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(mController), 0x1E, 0x69, 0x1B);
break;
case 2:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(mController), 0x64, 0x14, 0x00);
break;
case 3:
SDL_JoystickSetLED(SDL_GameControllerGetJoystick(mController), 0x00, 0x3C, 0x64);
break;
}
if (!GetProfile(portIndex)->UseRumble) {
return -1001;
}
if (rumble) {
float rumbleStrength = GetProfile(portIndex)->RumbleStrength;
return SDL_GameControllerRumble(mController, 0xFFFF * rumbleStrength, 0xFFFF * rumbleStrength, 0);
} else {
return SDL_GameControllerRumble(mController, 0, 0, 0);
}
}
const std::string SDLController::GetButtonName(int32_t virtualSlot, int32_t n64Button) {
int32_t SDLController::SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) {
if (!CanSetLed()) {
return -1000;
}
return SDL_JoystickSetLED(SDL_GameControllerGetJoystick(mController), r, g, b);
}
const std::string SDLController::GetButtonName(int32_t portIndex, int32_t n64Button) {
char buffer[50];
std::map<int32_t, int32_t>& mappings = getProfile(virtualSlot)->Mappings;
std::map<int32_t, int32_t>& mappings = GetProfile(portIndex)->Mappings;
const auto find =
std::find_if(mappings.begin(), mappings.end(),
@@ -338,12 +334,8 @@ const std::string SDLController::GetButtonName(int32_t virtualSlot, int32_t n64B
return buffer;
}
const std::string SDLController::GetControllerName() {
return mControllerName;
}
void SDLController::CreateDefaultBinding(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void SDLController::CreateDefaultBinding(int32_t portIndex) {
auto profile = GetProfile(portIndex);
profile->Mappings.clear();
profile->AxisDeadzones.clear();
profile->AxisMinimumPress.clear();
@@ -400,6 +392,10 @@ bool SDLController::CanRumble() const {
return false;
}
bool SDLController::CanSetLed() const {
return SDL_GameControllerHasLED(mController);
}
void SDLController::ClearRawPress() {
}
} // namespace Ship
+8 -9
View File
@@ -5,14 +5,15 @@
namespace Ship {
class SDLController : public Controller {
public:
SDLController(int32_t physicalSlot);
void ReadFromSource(int32_t virtualSlot) override;
const std::string GetControllerName() override;
const std::string GetButtonName(int32_t virtualSlot, int32_t n64Button) override;
void WriteToSource(int32_t virtualSlot, ControllerCallback* controller) override;
SDLController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex);
void ReadDevice(int32_t portIndex) override;
const std::string GetButtonName(int32_t portIndex, int32_t n64Button) override;
int32_t SetRumble(int32_t portIndex, bool rumble) override;
int32_t SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) override;
bool Connected() const override;
bool CanGyro() const override;
bool CanRumble() const override;
bool CanSetLed() const override;
bool Open();
void ClearRawPress() override;
int32_t ReadRawPress() override;
@@ -21,14 +22,12 @@ class SDLController : public Controller {
inline static const char* AxisNames[] = { "Left Stick X", "Left Stick Y", "Right Stick X", "Right Stick Y",
"Left Trigger", "Right Trigger", "Start Button" };
void CreateDefaultBinding(int32_t virtualSlot) override;
void CreateDefaultBinding(int32_t portIndex) override;
private:
std::string mControllerName = "Unknown";
SDL_GameController* mController;
int32_t mPhysicalSlot;
bool mSupportsGyro;
void NormalizeStickAxis(SDL_GameControllerAxis axisX, SDL_GameControllerAxis axisY, int32_t virtualSlot);
void NormalizeStickAxis(SDL_GameControllerAxis axisX, SDL_GameControllerAxis axisY, int32_t portIndex);
bool Close();
};
} // namespace Ship
+5 -13
View File
@@ -140,7 +140,7 @@ void Window::Initialize(const std::vector<std::string>& otrFiles, const std::uno
mWindowManagerApi->set_fullscreen_changed_callback(OnFullscreenChanged);
mWindowManagerApi->set_keyboard_callbacks(KeyDown, KeyUp, AllKeysUp);
Ship::RegisterHook<ExitGame>([this]() { mControlDeck->SaveControllerSettings(); });
Ship::RegisterHook<ExitGame>([this]() { mControlDeck->SaveSettings(); });
}
void Window::Close() {
@@ -229,7 +229,7 @@ bool Window::KeyUp(int32_t scancode) {
bool isProcessed = false;
auto controlDeck = GetInstance()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(
controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
controlDeck->GetDeviceFromDeviceIndex(controlDeck->GetNumDevices() - 2).get());
if (pad != nullptr) {
if (pad->ReleaseButton(scancode)) {
isProcessed = true;
@@ -243,7 +243,7 @@ bool Window::KeyDown(int32_t scancode) {
bool isProcessed = false;
auto controlDeck = GetInstance()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(
controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
controlDeck->GetDeviceFromDeviceIndex(controlDeck->GetNumDevices() - 2).get());
if (pad != nullptr) {
if (pad->PressButton(scancode)) {
isProcessed = true;
@@ -258,7 +258,7 @@ bool Window::KeyDown(int32_t scancode) {
void Window::AllKeysUp(void) {
auto controlDeck = Window::GetInstance()->GetControlDeck();
const auto pad = dynamic_cast<KeyboardController*>(
controlDeck->GetPhysicalDevice(controlDeck->GetNumPhysicalDevices() - 2).get());
controlDeck->GetDeviceFromDeviceIndex(controlDeck->GetNumDevices() - 2).get());
if (pad != nullptr) {
pad->ReleaseAllButtons();
}
@@ -270,7 +270,7 @@ void Window::OnFullscreenChanged(bool isNowFullscreen) {
Window::GetInstance()->mIsFullscreen = isNowFullscreen;
pConf->setBool("Window.Fullscreen.Enabled", isNowFullscreen);
if (isNowFullscreen) {
bool menuBarOpen = Window::GetInstance()->GetMenuBar();
bool menuBarOpen = GetMenuBar();
Window::GetInstance()->SetCursorVisibility(menuBarOpen);
} else if (!isNowFullscreen) {
Window::GetInstance()->SetCursorVisibility(true);
@@ -529,14 +529,6 @@ bool Window::IsFullscreen() {
return mIsFullscreen;
}
uint32_t Window::GetMenuBar() {
return mMenuBar;
}
void Window::SetMenuBar(uint32_t menuBar) {
this->mMenuBar = menuBar;
}
std::string Window::GetName() {
return mName;
}
-3
View File
@@ -51,8 +51,6 @@ class Window {
bool CanDisableVerticalSync();
float GetCurrentAspectRatio();
bool IsFullscreen();
uint32_t GetMenuBar();
void SetMenuBar(uint32_t menuBar);
std::string GetName();
std::string GetShortName();
std::shared_ptr<ControlDeck> GetControlDeck();
@@ -107,7 +105,6 @@ class Window {
uint32_t mRefreshRate;
uint32_t mWidth;
uint32_t mHeight;
bool mMenuBar;
int32_t mLastScancode;
std::string mName;
std::string mShortName;
+12 -3
View File
@@ -94,6 +94,7 @@ static ImVector<ImRect> s_GroupPanelLabelStack;
std::function<void(void)> clientDrawMenu;
std::function<void(void)> clientSetupHooks;
bool mMenuBar;
bool needsSave = false;
int lastRenderingBackendID = 0;
int lastAudioBackendID = 0;
@@ -503,7 +504,7 @@ void InitGui(WindowImpl windowImpl) {
Ship::RegisterHook<Ship::GfxInit>([] {
bool menuBarOpen = CVarGetInteger("gOpenMenuBar", 0);
Window::GetInstance()->SetMenuBar(menuBarOpen);
SetMenuBar(menuBarOpen);
if (Window::GetInstance()->IsFullscreen()) {
setCursorVisibility(menuBarOpen);
}
@@ -590,11 +591,11 @@ void DrawMainMenuAndCalculateGameSize(void) {
bool menuBar = !CVarGetInteger("gOpenMenuBar", 0);
CVarSetInteger("gOpenMenuBar", menuBar);
needsSave = true;
Window::GetInstance()->SetMenuBar(menuBar);
SetMenuBar(menuBar);
if (Window::GetInstance()->IsFullscreen()) {
setCursorVisibility(menuBar);
}
Window::GetInstance()->GetControlDeck()->SaveControllerSettings();
Window::GetInstance()->GetControlDeck()->SaveSettings();
if (CVarGetInteger("gControlNav", 0) && CVarGetInteger("gOpenMenuBar", 0)) {
io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
} else {
@@ -1180,4 +1181,12 @@ void EndGroupPanel(float minHeight) {
ImGui::EndGroup();
}
uint32_t GetMenuBar() {
return mMenuBar;
}
void SetMenuBar(uint32_t menuBar) {
mMenuBar = menuBar;
}
} // namespace Ship
+4
View File
@@ -88,6 +88,10 @@ void RenderImGui(void);
void CancelFrame(void);
void DrawSettings();
// OTRTODO: Rename these two
uint32_t GetMenuBar();
void SetMenuBar(uint32_t menuBar);
Backend WindowBackend();
std::vector<std::pair<const char*, const char*>> GetAvailableRenderingBackends();
std::pair<const char*, const char*> GetCurrentRenderingBackend();
+13 -13
View File
@@ -17,7 +17,7 @@ void InputEditor::Init() {
std::shared_ptr<Controller> GetControllerPerSlot(int slot) {
auto controlDeck = Ship::Window::GetInstance()->GetControlDeck();
return controlDeck->GetPhysicalDeviceFromVirtualSlot(slot);
return controlDeck->GetDeviceFromPortIndex(slot);
}
void InputEditor::DrawButton(const char* label, int32_t n64Btn, int32_t currentPort, int32_t* btnReading) {
@@ -67,16 +67,16 @@ void InputEditor::DrawButton(const char* label, int32_t n64Btn, int32_t currentP
void InputEditor::DrawControllerSelect(int32_t currentPort) {
auto controlDeck = Ship::Window::GetInstance()->GetControlDeck();
std::string controllerName = controlDeck->GetPhysicalDeviceFromVirtualSlot(currentPort)->GetControllerName();
std::string controllerName = controlDeck->GetDeviceFromPortIndex(currentPort)->GetControllerName();
if (ImGui::BeginCombo("##ControllerEntries", controllerName.c_str())) {
for (uint8_t i = 0; i < controlDeck->GetNumPhysicalDevices(); i++) {
std::string deviceName = controlDeck->GetPhysicalDevice(i)->GetControllerName();
for (uint8_t i = 0; i < controlDeck->GetNumDevices(); i++) {
std::string deviceName = controlDeck->GetDeviceFromDeviceIndex(i)->GetControllerName();
if (deviceName != "Keyboard" && deviceName != "Auto") {
deviceName += "##" + std::to_string(i);
}
if (ImGui::Selectable(deviceName.c_str(), i == controlDeck->GetVirtualDevice(currentPort))) {
controlDeck->SetPhysicalDevice(currentPort, i);
if (ImGui::Selectable(deviceName.c_str(), i == controlDeck->GetDeviceIndexFromPortIndex(currentPort))) {
controlDeck->SetDeviceToPort(currentPort, i);
}
}
ImGui::EndCombo();
@@ -85,7 +85,7 @@ void InputEditor::DrawControllerSelect(int32_t currentPort) {
ImGui::SameLine();
if (ImGui::Button("Refresh")) {
controlDeck->ScanPhysicalDevices();
controlDeck->ScanDevices();
}
}
@@ -111,11 +111,11 @@ void InputEditor::DrawVirtualStick(const char* label, ImVec2 stick) {
}
void InputEditor::DrawControllerSchema() {
auto backend = Ship::Window::GetInstance()->GetControlDeck()->GetPhysicalDeviceFromVirtualSlot(mCurrentPort);
auto profile = backend->getProfile(mCurrentPort);
auto backend = Ship::Window::GetInstance()->GetControlDeck()->GetDeviceFromPortIndex(mCurrentPort);
auto profile = backend->GetProfile(mCurrentPort);
bool isKeyboard = backend->GetGuid() == "Keyboard" || backend->GetGuid() == "Auto" || !backend->Connected();
backend->Read(nullptr, mCurrentPort);
backend->ReadToPad(nullptr, mCurrentPort);
DrawControllerSelect(mCurrentPort);
@@ -154,7 +154,7 @@ void InputEditor::DrawControllerSchema() {
if (!isKeyboard) {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 8);
DrawVirtualStick("##MainVirtualStick",
ImVec2(backend->getLeftStickX(mCurrentPort), backend->getLeftStickY(mCurrentPort)));
ImVec2(backend->GetLeftStickX(mCurrentPort), backend->GetLeftStickY(mCurrentPort)));
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
@@ -200,7 +200,7 @@ void InputEditor::DrawControllerSchema() {
// 2 is the SDL value for right stick X axis
// 3 is the SDL value for right stick Y axis.
DrawVirtualStick("##RightVirtualStick",
ImVec2(backend->getRightStickX(mCurrentPort), backend->getRightStickY(mCurrentPort)));
ImVec2(backend->GetRightStickX(mCurrentPort), backend->GetRightStickY(mCurrentPort)));
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
@@ -256,7 +256,7 @@ void InputEditor::DrawControllerSchema() {
}
ImGui::SetCursorPosX(cursorX);
DrawVirtualStick("##GyroPreview",
ImVec2(-10.0f * backend->getGyroY(mCurrentPort), 10.0f * backend->getGyroX(mCurrentPort)));
ImVec2(-10.0f * backend->GetGyroY(mCurrentPort), 10.0f * backend->GetGyroX(mCurrentPort)));
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 5);
+82 -57
View File
@@ -6,70 +6,72 @@
#include "WiiUImpl.h"
namespace Ship {
WiiUController::WiiUController(WPADChan chan) : Controller(), chan(chan) {
connected = false;
extensionType = (WPADExtensionType)-1;
controllerName = std::string("Wii U Controller ") + std::to_string((int)chan) + " (Disconnected)";
WiiUController::WiiUController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex, WPADChan chan)
: Controller(controlDeck, deviceIndex), mChan(chan) {
mConnected = false;
mExtensionType = (WPADExtensionType)-1;
mControllerName = std::string("Wii U Controller ") + std::to_string((int)mChan) + " (Disconnected)";
}
bool WiiUController::Open() {
KPADError error;
KPADStatus* status = Ship::WiiU::GetKPADStatus(chan, &error);
KPADStatus* status = Ship::WiiU::GetKPADStatus(mChan, &error);
if (!status || error != KPAD_ERROR_OK) {
Close();
return false;
}
connected = true;
extensionType = (WPADExtensionType)status->extensionType;
mConnected = true;
mControllerName = std::string("Wii U Controller ") + std::to_string((int)mChan);
mExtensionType = (WPADExtensionType)status->extensionType;
// Create a GUID and name based on extension and channel
mGuid = std::string("WiiU") + GetControllerExtensionName() + std::to_string((int)chan);
controllerName =
std::string("Wii U ") + GetControllerExtensionName() + std::string(" ") + std::to_string((int)chan);
mGuid = std::string("WiiU") + GetControllerExtensionName() + std::to_string((int)mChan);
mControllerName =
std::string("Wii U ") + GetControllerExtensionName() + std::string(" ") + std::to_string((int)mChan);
return true;
}
void WiiUController::Close() {
connected = false;
extensionType = (WPADExtensionType)-1;
mConnected = false;
mControllerName = std::string("Wii U Controller ") + std::to_string((int)mChan) + " (Disconnected)";
mExtensionType = (WPADExtensionType)-1;
for (int i = 0; i < MAXCONTROLLERS; i++) {
getPressedButtons(i) = 0;
getLeftStickX(i) = 0;
getLeftStickY(i) = 0;
getRightStickX(i) = 0;
getRightStickY(i) = 0;
getGyroX(i) = 0;
getGyroY(i) = 0;
GetPressedButtons(i) = 0;
GetLeftStickX(i) = 0;
GetLeftStickY(i) = 0;
GetRightStickX(i) = 0;
GetRightStickY(i) = 0;
GetGyroX(i) = 0;
GetGyroY(i) = 0;
}
}
void WiiUController::ReadFromSource(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void WiiUController::ReadDevice(int32_t portIndex) {
auto profile = GetProfile(portIndex);
KPADError error;
KPADStatus* status = Ship::WiiU::GetKPADStatus(chan, &error);
KPADStatus* status = Ship::WiiU::GetKPADStatus(mChan, &error);
if (!status) {
Close();
return;
}
// Make sure the controller type doesn't change after opening
if (status->extensionType != extensionType) {
if (status->extensionType != mExtensionType) {
Close();
return;
}
getPressedButtons(virtualSlot) = 0;
getLeftStickX(virtualSlot) = 0;
getLeftStickY(virtualSlot) = 0;
getRightStickX(virtualSlot) = 0;
getRightStickY(virtualSlot) = 0;
getGyroX(virtualSlot) = 0;
getGyroY(virtualSlot) = 0;
GetPressedButtons(portIndex) = 0;
GetLeftStickX(portIndex) = 0;
GetLeftStickY(portIndex) = 0;
GetRightStickX(portIndex) = 0;
GetRightStickY(portIndex) = 0;
GetGyroX(portIndex) = 0;
GetGyroY(portIndex) = 0;
if (error != KPAD_ERROR_OK) {
return;
@@ -80,7 +82,7 @@ void WiiUController::ReadFromSource(int32_t virtualSlot) {
int16_t camX = 0;
int16_t camY = 0;
switch (extensionType) {
switch (mExtensionType) {
case WPAD_EXT_PRO_CONTROLLER:
for (uint32_t i = WPAD_PRO_BUTTON_UP; i <= WPAD_PRO_STICK_R_EMULATION_UP; i <<= 1) {
if (profile->Mappings.contains(i)) {
@@ -107,7 +109,7 @@ void WiiUController::ReadFromSource(int32_t virtualSlot) {
}
if (status->pro.hold & i) {
getPressedButtons(virtualSlot) |= profile->Mappings[i];
GetPressedButtons(portIndex) |= profile->Mappings[i];
}
}
}
@@ -139,7 +141,7 @@ void WiiUController::ReadFromSource(int32_t virtualSlot) {
}
if (status->classic.hold & i) {
getPressedButtons(virtualSlot) |= profile->Mappings[i];
GetPressedButtons(portIndex) |= profile->Mappings[i];
}
}
}
@@ -151,7 +153,7 @@ void WiiUController::ReadFromSource(int32_t virtualSlot) {
for (uint32_t i = WPAD_BUTTON_LEFT; i <= WPAD_BUTTON_HOME; i <<= 1) {
if (profile->Mappings.contains(i)) {
if (status->hold & i) {
getPressedButtons(virtualSlot) |= profile->Mappings[i];
GetPressedButtons(portIndex) |= profile->Mappings[i];
}
}
}
@@ -161,28 +163,39 @@ void WiiUController::ReadFromSource(int32_t virtualSlot) {
}
if (stickX || stickY) {
getLeftStickX(virtualSlot) = stickX;
getLeftStickY(virtualSlot) = stickY;
GetLeftStickX(portIndex) = stickX;
GetLeftStickY(portIndex) = stickY;
}
if (camX || camY) {
getRightStickX(virtualSlot) = camX;
getRightStickY(virtualSlot) = camY;
GetRightStickX(portIndex) = camX;
GetRightStickY(portIndex) = camY;
}
}
void WiiUController::WriteToSource(int32_t virtualSlot, ControllerCallback* controller) {
if (getProfile(virtualSlot)->UseRumble) {
WPADControlMotor(chan, controller->rumble);
int32_t WiiUController::SetRumble(int32_t portIndex, bool rumble) {
if (!CanRumble()) {
return -1000;
}
if (GetProfile(portIndex)->UseRumble) {
return -1001;
}
WPADControlMotor(mChan, rumble);
return 0;
}
int32_t WiiUController::SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) {
return -1000;
}
void WiiUController::ClearRawPress() {
// Clear already triggered buttons
KPADError error;
KPADStatus* status = Ship::WiiU::GetKPADStatus(chan, &error);
KPADStatus* status = Ship::WiiU::GetKPADStatus(mChan, &error);
if (status) {
switch (extensionType) {
switch (mExtensionType) {
case WPAD_EXT_PRO_CONTROLLER:
status->pro.trigger = 0;
break;
@@ -202,12 +215,12 @@ void WiiUController::ClearRawPress() {
int32_t WiiUController::ReadRawPress() {
KPADError error;
KPADStatus* status = Ship::WiiU::GetKPADStatus(chan, &error);
KPADStatus* status = Ship::WiiU::GetKPADStatus(mChan, &error);
if (!status || error != KPAD_ERROR_OK) {
return -1;
}
switch (extensionType) {
switch (mExtensionType) {
case WPAD_EXT_PRO_CONTROLLER:
for (uint32_t i = WPAD_PRO_BUTTON_UP; i <= WPAD_PRO_STICK_R_EMULATION_UP; i <<= 1) {
if (status->pro.trigger & i) {
@@ -290,8 +303,8 @@ int32_t WiiUController::ReadRawPress() {
return -1;
}
const std::string WiiUController::GetButtonName(int32_t virtualSlot, int n64Button) {
std::map<int32_t, int32_t>& Mappings = getProfile(virtualSlot)->Mappings;
const std::string WiiUController::GetButtonName(int32_t portIndex, int n64Button) {
std::map<int32_t, int32_t>& Mappings = GetProfile(portIndex)->Mappings;
const auto find =
std::find_if(Mappings.begin(), Mappings.end(),
[n64Button](const std::pair<int32_t, int32_t>& pair) { return pair.second == n64Button; });
@@ -301,7 +314,7 @@ const std::string WiiUController::GetButtonName(int32_t virtualSlot, int n64Butt
uint32_t btn = find->first;
switch (extensionType) {
switch (mExtensionType) {
case WPAD_EXT_PRO_CONTROLLER:
switch (btn) {
case WPAD_PRO_BUTTON_A:
@@ -439,19 +452,15 @@ const std::string WiiUController::GetButtonName(int32_t virtualSlot, int n64Butt
return "Unknown";
}
const std::string WiiUController::GetControllerName() {
return controllerName;
}
void WiiUController::CreateDefaultBinding(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void WiiUController::CreateDefaultBinding(int32_t portIndex) {
auto profile = GetProfile(portIndex);
profile->Mappings.clear();
profile->UseRumble = true;
profile->RumbleStrength = 1.0f;
profile->UseGyro = false;
switch (extensionType) {
switch (mExtensionType) {
case WPAD_EXT_PRO_CONTROLLER:
profile->Mappings[WPAD_PRO_STICK_R_EMULATION_RIGHT] = BTN_CRIGHT;
profile->Mappings[WPAD_PRO_STICK_R_EMULATION_LEFT] = BTN_CLEFT;
@@ -517,7 +526,7 @@ void WiiUController::CreateDefaultBinding(int32_t virtualSlot) {
}
std::string WiiUController::GetControllerExtensionName() {
switch (extensionType) {
switch (mExtensionType) {
case WPAD_EXT_PRO_CONTROLLER:
return "ProController";
case WPAD_EXT_CLASSIC:
@@ -532,5 +541,21 @@ std::string WiiUController::GetControllerExtensionName() {
return "Controller";
}
bool WiiUController::Connected() const override {
return mConnected;
};
bool WiiUController::CanGyro() const override {
return false;
}
bool WiiUController::CanRumble() const override {
return true;
};
bool WiiUController::CanSetLed() const {
return false;
}
} // namespace Ship
#endif
+13 -22
View File
@@ -10,37 +10,28 @@
namespace Ship {
class WiiUController : public Controller {
public:
WiiUController(WPADChan chan);
WiiUController(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex, WPADChan chan);
bool Open();
void Close();
void ReadFromSource(int32_t virtualSlot) override;
void WriteToSource(int32_t virtualSlot, ControllerCallback* controller) override;
bool Connected() const override {
return connected;
};
bool CanGyro() const override {
return false;
}
bool CanRumble() const override {
return true;
};
void ReadDevice(int32_t portIndex) override;
bool Connected() const;
bool CanGyro() const;
bool CanRumble() const;
bool CanSetLed() const override;
void ClearRawPress() override;
int32_t ReadRawPress() override;
const std::string GetButtonName(int32_t virtualSlot, int n64Button) override;
const std::string GetControllerName() override;
int32_t SetRumble(int32_t portIndex, bool rumble) override;
int32_t SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) override;
const std::string GetButtonName(int32_t portIndex, int n64Button) override;
protected:
void CreateDefaultBinding(int32_t virtualSlot) override;
void CreateDefaultBinding(int32_t portIndex) override;
private:
std::string GetControllerExtensionName();
std::string controllerName;
bool connected;
WPADChan chan;
WPADExtensionType extensionType;
bool mConnected;
WPADChan mChan;
WPADExtensionType mExtensionType;
};
} // namespace Ship
+87 -61
View File
@@ -5,10 +5,11 @@
#include "WiiUImpl.h"
namespace Ship {
WiiUGamepad::WiiUGamepad() : Controller(), connected(true), rumblePatternStrength(1.0f) {
memset(rumblePattern, 0xff, sizeof(rumblePattern));
WiiUGamepad::WiiUGamepad(std::shared_ptr<ControlDeck> controlDeck, int32_t deviceIndex)
: Controller(controlDeck, deviceIndex), mConnected(true), mRumblePatternStrength(1.0f) {
memset(mRumblePattern, 0xff, sizeof(mRumblePattern));
mGuid = "WiiUGamepad";
mControllerName = "Wii U GamePad";
}
bool WiiUGamepad::Open() {
@@ -19,25 +20,29 @@ bool WiiUGamepad::Open() {
return false;
}
mConnected = true;
mControllerName = "Wii U GamePad";
return true;
}
void WiiUGamepad::Close() {
connected = false;
mConnected = false;
mControllerName = "Wii U Gamepad (Disconnected)";
for (int i = 0; i < MAXCONTROLLERS; i++) {
getPressedButtons(i) = 0;
getLeftStickX(i) = 0;
getLeftStickY(i) = 0;
getRightStickX(i) = 0;
getRightStickY(i) = 0;
getGyroX(i) = 0;
getGyroY(i) = 0;
GetPressedButtons(i) = 0;
GetLeftStickX(i) = 0;
GetLeftStickY(i) = 0;
GetRightStickX(i) = 0;
GetRightStickY(i) = 0;
GetGyroX(i) = 0;
GetGyroY(i) = 0;
}
}
void WiiUGamepad::ReadFromSource(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void WiiUGamepad::ReadDevice(int32_t portIndex) {
auto profile = GetProfile(portIndex);
VPADReadError error;
VPADStatus* status = Ship::WiiU::GetVPADStatus(&error);
@@ -46,13 +51,13 @@ void WiiUGamepad::ReadFromSource(int32_t virtualSlot) {
return;
}
getPressedButtons(virtualSlot) = 0;
getLeftStickX(virtualSlot) = 0;
getLeftStickY(virtualSlot) = 0;
getRightStickX(virtualSlot) = 0;
getRightStickY(virtualSlot) = 0;
getGyroX(virtualSlot) = 0;
getGyroY(virtualSlot) = 0;
GetPressedButtons(portIndex) = 0;
GetLeftStickX(portIndex) = 0;
GetLeftStickY(portIndex) = 0;
GetRightStickX(portIndex) = 0;
GetRightStickY(portIndex) = 0;
GetGyroX(portIndex) = 0;
GetGyroY(portIndex) = 0;
if (error != VPAD_READ_SUCCESS) {
return;
@@ -86,19 +91,19 @@ void WiiUGamepad::ReadFromSource(int32_t virtualSlot) {
}
if (status->hold & i) {
getPressedButtons(virtualSlot) |= profile->Mappings[i];
GetPressedButtons(portIndex) |= profile->Mappings[i];
}
}
}
if (stickX || stickY) {
getLeftStickX(virtualSlot) = stickX;
getLeftStickY(virtualSlot) = stickY;
GetLeftStickX(portIndex) = stickX;
GetLeftStickY(portIndex) = stickY;
}
if (camX || camY) {
getRightStickX(virtualSlot) = camX;
getRightStickY(virtualSlot) = camY;
GetRightStickX(portIndex) = camX;
GetRightStickY(portIndex) = camY;
}
if (profile->UseGyro) {
@@ -120,42 +125,51 @@ void WiiUGamepad::ReadFromSource(int32_t virtualSlot) {
profile->GyroData[DRIFT_X] = gyro_drift_x * 100.0f;
profile->GyroData[DRIFT_Y] = gyro_drift_y * 100.0f;
getGyroX(virtualSlot) = gyroX - gyro_drift_x;
getGyroY(virtualSlot) = gyroY - gyro_drift_y;
GetGyroX(portIndex) = gyroX - gyro_drift_x;
GetGyroY(portIndex) = gyroY - gyro_drift_y;
getGyroX(virtualSlot) *= gyro_sensitivity;
getGyroY(virtualSlot) *= gyro_sensitivity;
GetGyroX(portIndex) *= gyro_sensitivity;
GetGyroY(portIndex) *= gyro_sensitivity;
}
}
void WiiUGamepad::WriteToSource(int32_t virtualSlot, ControllerCallback* controller) {
auto profile = getProfile(virtualSlot);
int32_t WiiUGamepad::SetRumble(int32_t portIndex, bool rumble) {
if (!CanRumble()) {
return -1000;
}
if (profile->UseRumble) {
int patternSize = sizeof(rumblePattern) * 8;
if (!profile->UseRumble) {
return -1001;
}
// update rumble pattern if strength changed
if (rumblePatternStrength != profile->RumbleStrength) {
rumblePatternStrength = profile->RumbleStrength;
if (rumblePatternStrength > 1.0f) {
rumblePatternStrength = 1.0f;
} else if (rumblePatternStrength < 0.0f) {
rumblePatternStrength = 0.0f;
}
auto profile = GetProfile(portIndex);
int32_t patternSize = sizeof(mRumblePattern) * 8;
memset(rumblePattern, 0, sizeof(rumblePattern));
// distribute wanted amount of bits equally in pattern
float scale = (rumblePatternStrength * (1.0f - 0.3f)) + 0.3f;
int bitcnt = patternSize * scale;
for (int i = 0; i < bitcnt; i++) {
int bitpos = ((i * patternSize) / bitcnt) % patternSize;
rumblePattern[bitpos / 8] |= 1 << (bitpos % 8);
}
// update rumble pattern if strength changed
if (mRumblePatternStrength != profile->RumbleStrength) {
mRumblePatternStrength = profile->RumbleStrength;
if (mRumblePatternStrength > 1.0f) {
mRumblePatternStrength = 1.0f;
} else if (mRumblePatternStrength < 0.0f) {
mRumblePatternStrength = 0.0f;
}
VPADControlMotor(VPAD_CHAN_0, rumblePattern, controller->rumble ? patternSize : 0);
memset(mRumblePattern, 0, sizeof(mRumblePattern));
// distribute wanted amount of bits equally in pattern
float scale = (mRumblePatternStrength * (1.0f - 0.3f)) + 0.3f;
int32_t bitcnt = patternSize * scale;
for (int32_t i = 0; i < bitcnt; i++) {
int32_t bitpos = ((i * patternSize) / bitcnt) % patternSize;
mRumblePattern[bitpos / 8] |= 1 << (bitpos % 8);
}
}
return VPADControlMotor(VPAD_CHAN_0, mRumblePattern, rumble ? patternSize : 0);
}
int32_t WiiUGamepad::SetLed(int32_t portIndex, int8_t r, int8_t g, int8_t b) {
return -1000;
}
void WiiUGamepad::ClearRawPress() {
@@ -209,13 +223,13 @@ int32_t WiiUGamepad::ReadRawPress() {
return -1;
}
const std::string WiiUGamepad::GetButtonName(int32_t virtualSlot, int n64Button) {
std::map<int32_t, int32_t>& Mappings = getProfile(virtualSlot)->Mappings;
const std::string WiiUGamepad::GetButtonName(int32_t portIndex, int n64Button) {
std::map<int32_t, int32_t>& mappings = GetProfile(portIndex)->Mappings;
const auto find =
std::find_if(Mappings.begin(), Mappings.end(),
std::find_if(mappings.begin(), mappings.end(),
[n64Button](const std::pair<int32_t, int32_t>& pair) { return pair.second == n64Button; });
if (find == Mappings.end())
if (find == mappings.end())
return "Unknown";
uint32_t btn = find->first;
@@ -273,12 +287,8 @@ const std::string WiiUGamepad::GetButtonName(int32_t virtualSlot, int n64Button)
return "Unknown";
}
const std::string WiiUGamepad::GetControllerName() {
return Connected() ? "Wii U GamePad" : "Wii U GamePad (Disconnected)";
}
void WiiUGamepad::CreateDefaultBinding(int32_t virtualSlot) {
auto profile = getProfile(virtualSlot);
void WiiUGamepad::CreateDefaultBinding(int32_t portIndex) {
auto profile = GetProfile(portIndex);
profile->Mappings.clear();
profile->Version = DEVICE_PROFILE_CURRENT_VERSION;
@@ -314,5 +324,21 @@ void WiiUGamepad::CreateDefaultBinding(int32_t virtualSlot) {
profile->GyroData[DRIFT_X] = 0.0f;
profile->GyroData[DRIFT_Y] = 0.0f;
}
bool WiiUGamePad::Connected() const override {
return mConnected;
};
bool WiiUGamePad::CanGyro() const override {
return true;
}
bool WiiUGamePad::CanRumble() const override {
return true;
};
bool DummyController::CanSetLed() const {
return false;
}
} // namespace Ship
#endif

Some files were not shown because too many files have changed in this diff Show More