Skip to content

Commit

Permalink
Controller Configuration UI and JSON Config (HarbourMasters#760)
Browse files Browse the repository at this point in the history
* Initial controller hud ui

* Reverted fbdemo changes

* Moved config to json and implemented controller config

* fix build on linux, gitignore new config file

* fix build

* Fix compilation and file directory paths

* Call save on cvar save

* Fixed cvar loading and added deck slots to the config

* Changed control deck port 0 to use a physical device by default

* Added gyro and rumble & fixed loading errors

* Save config on toggle menubar

* fix linux build

* Fixed drift calculation

* Controller config now saves when pressing F1

* Removed ExitGame hook from ImGuiImpl

* Moved mappings to a map

* Added GetKeyName

* untranslate scancodes

* Fixed hud layout on keyboard device

* Fixed keyboard read on hud

* Fixed crash when reloading controllers

* Removed ConfigFile and changed file extension

* Changed Dummy to Disconnected and fixed filters

* Removed function leftover

* Changed ControllerHud to InputEditor

Co-authored-by: briaguya <briaguya@alice>
Co-authored-by: David Chavez <david@dcvz.io>
  • Loading branch information
3 people authored Jul 14, 2022
1 parent cb68767 commit 219804c
Show file tree
Hide file tree
Showing 49 changed files with 1,841 additions and 896 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -405,3 +405,4 @@ tags
oot.otr
*.sav
shipofharkinian.ini
shipofharkinian.json
2 changes: 2 additions & 0 deletions libultraship/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ CXX_FILES := \
$(shell find libultraship/Lib/Fast3D -name "*.cpp") \
$(shell find libultraship -maxdepth 1 -name "*.cpp") \
$(shell find libultraship/Lib/ImGui -maxdepth 1 -name "*.cpp") \
$(shell find libultraship/Lib/Mercury -maxdepth 1 -name "*.cpp") \
libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \
libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \
libultraship/Lib/StrHash64.cpp \
Expand Down Expand Up @@ -114,6 +115,7 @@ INC_DIRS := $(addprefix -I, \
libultraship/Lib/spdlog \
libultraship/Lib/spdlog/include \
libultraship/Lib/ImGui \
libultraship/Lib/Mercury \
libultraship \
../StormLib/src \
)
Expand Down
164 changes: 0 additions & 164 deletions libultraship/libultraship/ConfigFile.cpp

This file was deleted.

42 changes: 0 additions & 42 deletions libultraship/libultraship/ConfigFile.h

This file was deleted.

155 changes: 155 additions & 0 deletions libultraship/libultraship/ControlDeck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#include "ControlDeck.h"

#include "Window.h"
#include "Controller.h"
#include "DisconnectedController.h"
#include "KeyboardController.h"
#include "SDLController.h"
#include <Utils/StringHelper.h>

uint8_t* controllerBits;

void Ship::ControlDeck::Init(uint8_t* bits) {
ScanPhysicalDevices();
controllerBits = bits;
}

void Ship::ControlDeck::ScanPhysicalDevices() {

virtualDevices.clear();
physicalDevices.clear();

for (int i = 0; i < SDL_NumJoysticks(); i++) {
if (SDL_IsGameController(i)) {
auto sdl = std::make_shared<SDLController>(i);
sdl->Open();
physicalDevices.push_back(sdl);
}
}

physicalDevices.push_back(std::make_shared<KeyboardController>());
physicalDevices.push_back(std::make_shared<DisconnectedController>());

for (const auto& device : physicalDevices) {
for (int i = 0; i < MAXCONTROLLERS; i++) {
device->CreateDefaultBinding(i);
}
}

for (int i = 0; i < MAXCONTROLLERS; i++) {
virtualDevices.push_back(i == 0 ? 0 : static_cast<int>(physicalDevices.size()) - 1);
}

LoadControllerSettings();
}

void Ship::ControlDeck::SetPhysicalDevice(int slot, int deviceSlot) {
const std::shared_ptr<Controller> backend = physicalDevices[deviceSlot];
virtualDevices[slot] = deviceSlot;
*controllerBits |= (backend->Connected()) << slot;
}

void Ship::ControlDeck::WriteToPad(OSContPad* pad) const {
for (size_t i = 0; i < virtualDevices.size(); i++) {
physicalDevices[virtualDevices[i]]->Read(&pad[i], i);
}
}

#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), slot, __VA_ARGS__)

void Ship::ControlDeck::LoadControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();

for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
int slot = std::stoi(val.key().substr(5));

for (size_t dev = 0; dev < physicalDevices.size(); dev++) {
std::string guid = physicalDevices[dev]->GetGuid();
if(guid != val.value()) continue;

virtualDevices[slot] = dev;
}
}

for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}

for (const auto& device : physicalDevices) {

std::string guid = device->GetGuid();

for (int slot = 0; slot < MAXCONTROLLERS; slot++) {

if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", slot)))) continue;

auto& profile = device->profiles[slot];
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];

profile.Mappings.clear();
profile.Thresholds.clear();
profile.GyroThresholds.clear();
profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
profile.RumbleStrength = Config->getBool(NESTED("Rumble.Strength", ""));
profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));

for (auto const& val : rawProfile["Gyro"]["Thresholds"].items()) {
profile.GyroThresholds[std::stoi(val.key())] = val.value();
}

for (auto const& val : rawProfile["Thresholds"].items()) {
profile.Thresholds[static_cast<ControllerThresholds>(std::stoi(val.key()))] = val.value();
}

for (auto const& val : rawProfile["Mappings"].items()) {
device->SetButtonMapping(slot, std::stoi(val.key().substr(4)), val.value());
}
}
}
}

void Ship::ControlDeck::SaveControllerSettings() {
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();

for (size_t i = 0; i < virtualDevices.size(); i++) {
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
}

for (const auto& device : physicalDevices) {

int slot = 0;
std::string guid = device->GetGuid();

for (const auto& profile : device->profiles) {

if (!device->Connected()) continue;

auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
Config->setBool(NESTED("Rumble.Enabled", ""), profile.UseRumble);
Config->setFloat(NESTED("Rumble.Strength", ""), profile.RumbleStrength);
Config->setBool(NESTED("Gyro.Enabled", ""), profile.UseGyro);

for (auto const& val : rawProfile["Mappings"].items()) {
Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1);
}

for (auto const& [key, val] : profile.GyroThresholds) {
Config->setInt(NESTED("Gyro.Thresholds.%d", key), val);
}

for (auto const& [key, val] : profile.Thresholds) {
Config->setInt(NESTED("Thresholds.%d", key), val);
}

for (auto const& [key, val] : profile.Mappings) {
Config->setInt(NESTED("Mappings.BTN_%d", val), key);
}

slot++;
}
}

Config->save();
}
Loading

0 comments on commit 219804c

Please sign in to comment.