migrant input: define_buttons no agarra inputs del mando que no toca falta: Options ha de comprovar que el gamepad que te en la configuracio estiga o no estiga conectat
132 lines
5.0 KiB
C++
132 lines
5.0 KiB
C++
#pragma once
|
|
#include <external/json.hpp>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "input_types.h" // Solo incluimos los tipos compartidos
|
|
|
|
struct GamepadConfig {
|
|
std::string name; // Nombre del dispositivo
|
|
std::string path; // Ruta física del dispositivo
|
|
std::unordered_map<InputAction, SDL_GamepadButton> bindings; // Asociación acción-botón
|
|
|
|
GamepadConfig(const std::string& name, const std::string& path)
|
|
: name(name),
|
|
path(path),
|
|
bindings{
|
|
{InputAction::FIRE_LEFT, SDL_GAMEPAD_BUTTON_WEST},
|
|
{InputAction::FIRE_CENTER, SDL_GAMEPAD_BUTTON_NORTH},
|
|
{InputAction::FIRE_RIGHT, SDL_GAMEPAD_BUTTON_EAST},
|
|
{InputAction::START, SDL_GAMEPAD_BUTTON_START},
|
|
{InputAction::SERVICE, SDL_GAMEPAD_BUTTON_BACK}} {}
|
|
|
|
// Reasigna un botón a una acción
|
|
void rebindAction(InputAction action, SDL_GamepadButton new_button) {
|
|
bindings[action] = new_button;
|
|
}
|
|
};
|
|
|
|
using GamepadConfigs = std::vector<GamepadConfig>;
|
|
|
|
class GamepadConfigManager {
|
|
public:
|
|
// Escribir vector de GamepadConfig a archivo JSON
|
|
static bool writeToJson(const GamepadConfigs& configs, const std::string& filename) {
|
|
try {
|
|
nlohmann::json j;
|
|
j["gamepads"] = nlohmann::json::array();
|
|
|
|
for (const auto& config : configs) {
|
|
nlohmann::json gamepadJson;
|
|
gamepadJson["name"] = config.name;
|
|
gamepadJson["path"] = config.path;
|
|
gamepadJson["bindings"] = nlohmann::json::object();
|
|
|
|
// Convertir bindings a JSON
|
|
for (const auto& [action, button] : config.bindings) {
|
|
auto actionIt = actionToString.find(action);
|
|
auto buttonIt = buttonToString.find(button);
|
|
|
|
if (actionIt != actionToString.end() && buttonIt != buttonToString.end()) {
|
|
gamepadJson["bindings"][actionIt->second] = buttonIt->second;
|
|
}
|
|
}
|
|
|
|
j["gamepads"].push_back(gamepadJson);
|
|
}
|
|
|
|
// Escribir al archivo
|
|
std::ofstream file(filename);
|
|
if (!file.is_open()) {
|
|
return false;
|
|
}
|
|
|
|
file << j.dump(4); // Formato con indentación de 4 espacios
|
|
file.close();
|
|
return true;
|
|
|
|
} catch (const std::exception& e) {
|
|
// Log del error si tienes sistema de logging
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Leer vector de GamepadConfig desde archivo JSON
|
|
static bool readFromJson(GamepadConfigs& configs, const std::string& filename) {
|
|
try {
|
|
std::ifstream file(filename);
|
|
if (!file.is_open()) {
|
|
return false;
|
|
}
|
|
|
|
nlohmann::json j;
|
|
file >> j;
|
|
file.close();
|
|
|
|
configs.clear();
|
|
|
|
if (!j.contains("gamepads") || !j["gamepads"].is_array()) {
|
|
return false;
|
|
}
|
|
|
|
for (const auto& gamepadJson : j["gamepads"]) {
|
|
if (!gamepadJson.contains("name") || !gamepadJson.contains("bindings")) {
|
|
continue; // Saltar configuraciones malformadas
|
|
}
|
|
|
|
// Leer el campo path si existe, si no dejarlo vacío
|
|
std::string path = gamepadJson.contains("path") ? gamepadJson["path"].get<std::string>() : "";
|
|
GamepadConfig config(gamepadJson["name"], path);
|
|
|
|
// Limpiar bindings por defecto para cargar los del archivo
|
|
config.bindings.clear();
|
|
|
|
// Cargar bindings desde JSON
|
|
for (const auto& [actionStr, buttonStr] : gamepadJson["bindings"].items()) {
|
|
auto actionIt = stringToAction.find(actionStr);
|
|
auto buttonIt = stringToButton.find(buttonStr);
|
|
|
|
if (actionIt != stringToAction.end() && buttonIt != stringToButton.end()) {
|
|
config.bindings[actionIt->second] = buttonIt->second;
|
|
}
|
|
}
|
|
|
|
configs.push_back(config);
|
|
}
|
|
|
|
return true;
|
|
|
|
} catch (const std::exception& e) {
|
|
// Log del error si tienes sistema de logging
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Método auxiliar para verificar si un archivo existe
|
|
static bool fileExists(const std::string& filename) {
|
|
std::ifstream file(filename);
|
|
return file.good();
|
|
}
|
|
}; |