eliminada tota la funcionalitat de gamepad_config_manager i la dependencia de json
This commit is contained in:
@@ -1,134 +0,0 @@
|
||||
#pragma once
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "core/input/input_types.hpp" // Solo incluimos los tipos compartidos
|
||||
#include "external/json.hpp"
|
||||
|
||||
// --- Estructuras ---
|
||||
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(std::string name, std::string path)
|
||||
: name(std::move(name)),
|
||||
path(std::move(path)),
|
||||
bindings{
|
||||
{InputAction::LEFT, SDL_GAMEPAD_BUTTON_DPAD_LEFT},
|
||||
{InputAction::RIGHT, SDL_GAMEPAD_BUTTON_DPAD_RIGHT},
|
||||
{InputAction::JUMP, SDL_GAMEPAD_BUTTON_WEST}} {}
|
||||
|
||||
// Reasigna un botón a una acción
|
||||
void rebindAction(InputAction action, SDL_GamepadButton new_button) {
|
||||
bindings[action] = new_button;
|
||||
}
|
||||
};
|
||||
|
||||
// --- Tipos ---
|
||||
using GamepadConfigs = std::vector<GamepadConfig>; // Vector de configuraciones de gamepad
|
||||
|
||||
// --- Clase GamepadConfigManager: gestor de configuraciones de gamepad ---
|
||||
class GamepadConfigManager {
|
||||
public:
|
||||
// --- Métodos estáticos ---
|
||||
static auto writeToJson(const GamepadConfigs& configs, const std::string& filename) -> bool { // Escribir configuraciones a JSON
|
||||
try {
|
||||
nlohmann::json j;
|
||||
j["gamepads"] = nlohmann::json::array();
|
||||
|
||||
for (const auto& config : configs) {
|
||||
nlohmann::json gamepad_json;
|
||||
gamepad_json["name"] = config.name;
|
||||
gamepad_json["path"] = config.path;
|
||||
gamepad_json["bindings"] = nlohmann::json::object();
|
||||
|
||||
// Convertir bindings a JSON
|
||||
for (const auto& [action, button] : config.bindings) {
|
||||
auto action_it = ACTION_TO_STRING.find(action);
|
||||
auto button_it = BUTTON_TO_STRING.find(button);
|
||||
|
||||
if (action_it != ACTION_TO_STRING.end() && button_it != BUTTON_TO_STRING.end()) {
|
||||
gamepad_json["bindings"][action_it->second] = button_it->second;
|
||||
}
|
||||
}
|
||||
|
||||
j["gamepads"].push_back(gamepad_json);
|
||||
}
|
||||
|
||||
// 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 auto readFromJson(GamepadConfigs& configs, const std::string& filename) -> bool {
|
||||
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& gamepad_json : j["gamepads"]) {
|
||||
if (!gamepad_json.contains("name") || !gamepad_json.contains("bindings")) {
|
||||
continue; // Saltar configuraciones malformadas
|
||||
}
|
||||
|
||||
// Leer el campo path si existe, si no dejarlo vacío
|
||||
std::string path = gamepad_json.contains("path") ? gamepad_json["path"].get<std::string>() : "";
|
||||
GamepadConfig config(gamepad_json["name"], path);
|
||||
|
||||
// Limpiar bindings por defecto para cargar los del archivo
|
||||
config.bindings.clear();
|
||||
|
||||
// Cargar bindings desde JSON
|
||||
for (const auto& [actionStr, buttonStr] : gamepad_json["bindings"].items()) {
|
||||
auto action_it = STRING_TO_ACTION.find(actionStr);
|
||||
auto button_it = STRING_TO_BUTTON.find(buttonStr);
|
||||
|
||||
if (action_it != STRING_TO_ACTION.end() && button_it != STRING_TO_BUTTON.end()) {
|
||||
config.bindings[action_it->second] = button_it->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 auto fileExists(const std::string& filename) -> bool {
|
||||
std::ifstream file(filename);
|
||||
return file.good();
|
||||
}
|
||||
};
|
||||
@@ -14,8 +14,8 @@
|
||||
Input* Input::instance = nullptr;
|
||||
|
||||
// Inicializa la instancia única del singleton
|
||||
void Input::init(const std::string& game_controller_db_path, const std::string& gamepad_configs_file) {
|
||||
Input::instance = new Input(game_controller_db_path, gamepad_configs_file);
|
||||
void Input::init(const std::string& game_controller_db_path) {
|
||||
Input::instance = new Input(game_controller_db_path);
|
||||
}
|
||||
|
||||
// Libera la instancia
|
||||
@@ -25,9 +25,8 @@ void Input::destroy() { delete Input::instance; }
|
||||
auto Input::get() -> Input* { return Input::instance; }
|
||||
|
||||
// Constructor
|
||||
Input::Input(std::string game_controller_db_path, std::string gamepad_configs_file)
|
||||
: gamepad_mappings_file_(std::move(game_controller_db_path)),
|
||||
gamepad_configs_file_(std::move(gamepad_configs_file)) {
|
||||
Input::Input(std::string game_controller_db_path)
|
||||
: gamepad_mappings_file_(std::move(game_controller_db_path)) {
|
||||
// Inicializar bindings del teclado
|
||||
keyboard_.bindings = {
|
||||
// Movimiento del jugador
|
||||
@@ -354,7 +353,6 @@ void Input::initSDLGamePad() {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GAMEPAD could not initialize! SDL Error: %s", SDL_GetError());
|
||||
} else {
|
||||
addGamepadMappingsFromFile();
|
||||
loadGamepadConfigs();
|
||||
discoverGamepads();
|
||||
std::cout << "Input System initialized successfully\n";
|
||||
}
|
||||
@@ -421,8 +419,6 @@ auto Input::addGamepad(int device_index) -> std::string {
|
||||
auto gamepad = std::make_shared<Gamepad>(pad);
|
||||
auto name = gamepad->name;
|
||||
std::cout << "Gamepad connected (" << name << ")" << '\n';
|
||||
applyGamepadConfig(gamepad);
|
||||
saveGamepadConfigFromGamepad(gamepad);
|
||||
gamepads_.push_back(std::move(gamepad));
|
||||
return name + " CONNECTED";
|
||||
}
|
||||
@@ -456,99 +452,6 @@ void Input::printConnectedGamepads() const {
|
||||
}
|
||||
}
|
||||
|
||||
void Input::loadGamepadConfigs() {
|
||||
if (GamepadConfigManager::fileExists(gamepad_configs_file_)) {
|
||||
GamepadConfigManager::readFromJson(gamepad_configs_, gamepad_configs_file_);
|
||||
}
|
||||
}
|
||||
|
||||
void Input::saveGamepadConfigs() {
|
||||
GamepadConfigManager::writeToJson(gamepad_configs_, gamepad_configs_file_);
|
||||
}
|
||||
|
||||
void Input::applyGamepadConfig(std::shared_ptr<Gamepad> gamepad) {
|
||||
if (!gamepad || gamepad->path.empty()) { // No podemos aplicar config sin una ruta
|
||||
return;
|
||||
}
|
||||
|
||||
// --- Buscar configuración por RUTA (path) ---
|
||||
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad](const GamepadConfig& config) {
|
||||
return config.path == gamepad->path;
|
||||
});
|
||||
|
||||
if (config_it != gamepad_configs_.end()) {
|
||||
// Se encontró una configuración específica para este puerto/dispositivo. La aplicamos.
|
||||
std::cout << "Applying custom config for gamepad at path: " << gamepad->path << '\n';
|
||||
for (const auto& [action, button] : config_it->bindings) {
|
||||
if (gamepad->bindings.find(action) != gamepad->bindings.end()) {
|
||||
gamepad->bindings[action].button = button;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Opcional: Podrías añadir un fallback para buscar por nombre si no se encuentra por ruta.
|
||||
}
|
||||
|
||||
void Input::saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad) {
|
||||
if (!gamepad || gamepad->path.empty()) { // No podemos guardar una config sin una ruta
|
||||
return;
|
||||
}
|
||||
|
||||
// --- CAMBIO CLAVE: Buscar si ya existe una configuración por RUTA (path) ---
|
||||
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad](const GamepadConfig& config) {
|
||||
return config.path == gamepad->path;
|
||||
});
|
||||
|
||||
// Crear nueva configuración desde el gamepad, incluyendo nombre y ruta
|
||||
GamepadConfig new_config(gamepad->name, gamepad->path); // <--- CAMBIO: Pasamos ambos
|
||||
new_config.bindings.clear();
|
||||
|
||||
// Copiar todos los bindings actuales del gamepad
|
||||
for (const auto& [action, buttonState] : gamepad->bindings) {
|
||||
new_config.bindings[action] = static_cast<SDL_GamepadButton>(buttonState.button);
|
||||
}
|
||||
|
||||
if (config_it != gamepad_configs_.end()) {
|
||||
// Sobreescribir configuración existente para esta ruta
|
||||
*config_it = new_config;
|
||||
} else {
|
||||
// Añadir nueva configuración
|
||||
gamepad_configs_.push_back(new_config);
|
||||
}
|
||||
|
||||
// Guardar cambios inmediatamente
|
||||
saveGamepadConfigs();
|
||||
}
|
||||
|
||||
// Método para establecer el archivo de configuración (opcional)
|
||||
void Input::setGamepadConfigsFile(const std::string& filename) {
|
||||
gamepad_configs_file_ = filename;
|
||||
loadGamepadConfigs(); // Recargar con el nuevo archivo
|
||||
}
|
||||
|
||||
// Método para obtener configuración de un gamepad específico (opcional)
|
||||
auto Input::getGamepadConfig(const std::string& gamepad_name) -> GamepadConfig* {
|
||||
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad_name](const GamepadConfig& config) {
|
||||
return config.name == gamepad_name;
|
||||
});
|
||||
|
||||
return (config_it != gamepad_configs_.end()) ? &(*config_it) : nullptr;
|
||||
}
|
||||
|
||||
// Método para eliminar configuración de gamepad (opcional)
|
||||
auto Input::removeGamepadConfig(const std::string& gamepad_name) -> bool {
|
||||
auto config_it = std::ranges::find_if(gamepad_configs_, [&gamepad_name](const GamepadConfig& config) {
|
||||
return config.name == gamepad_name;
|
||||
});
|
||||
|
||||
if (config_it != gamepad_configs_.end()) {
|
||||
gamepad_configs_.erase(config_it);
|
||||
saveGamepadConfigs();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto Input::findAvailableGamepadByName(const std::string& gamepad_name) -> std::shared_ptr<Input::Gamepad> {
|
||||
// Si no hay gamepads disponibles, devolver gamepad por defecto
|
||||
if (gamepads_.empty()) {
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <utility> // Para pair
|
||||
#include <vector> // Para vector
|
||||
|
||||
#include "core/input/gamepad_config_manager.hpp" // for GamepadConfig (ptr only), GamepadConfigs
|
||||
#include "core/input/input_types.hpp" // for InputAction
|
||||
|
||||
// --- Clase Input: gestiona la entrada de teclado y mandos (singleton) ---
|
||||
@@ -79,7 +78,7 @@ class Input {
|
||||
using Gamepads = std::vector<std::shared_ptr<Gamepad>>; // Vector de gamepads
|
||||
|
||||
// --- Singleton ---
|
||||
static void init(const std::string& game_controller_db_path, const std::string& gamepad_configs_file);
|
||||
static void init(const std::string& game_controller_db_path);
|
||||
static void destroy();
|
||||
static auto get() -> Input*;
|
||||
|
||||
@@ -109,7 +108,6 @@ class Input {
|
||||
static auto getControllerName(const std::shared_ptr<Gamepad>& gamepad) -> std::string;
|
||||
auto getControllerNames() const -> std::vector<std::string>;
|
||||
[[nodiscard]] static auto getControllerBinding(const std::shared_ptr<Gamepad>& gamepad, Action action) -> SDL_GamepadButton;
|
||||
void saveGamepadConfigFromGamepad(std::shared_ptr<Gamepad> gamepad);
|
||||
void printConnectedGamepads() const;
|
||||
|
||||
// --- Eventos ---
|
||||
@@ -122,7 +120,7 @@ class Input {
|
||||
static constexpr std::array<Action, 1> BUTTON_INPUTS = {Action::JUMP}; // Inputs que usan botones
|
||||
|
||||
// --- Métodos ---
|
||||
explicit Input(std::string game_controller_db_path, std::string gamepad_configs_file);
|
||||
explicit Input(std::string game_controller_db_path);
|
||||
~Input() = default;
|
||||
|
||||
void initSDLGamePad();
|
||||
@@ -133,19 +131,10 @@ class Input {
|
||||
void addGamepadMappingsFromFile();
|
||||
void discoverGamepads();
|
||||
|
||||
void loadGamepadConfigs();
|
||||
void saveGamepadConfigs();
|
||||
void applyGamepadConfig(std::shared_ptr<Gamepad> gamepad);
|
||||
void setGamepadConfigsFile(const std::string& filename);
|
||||
auto getGamepadConfig(const std::string& gamepad_name) -> GamepadConfig*;
|
||||
auto removeGamepadConfig(const std::string& gamepad_name) -> bool;
|
||||
|
||||
// --- Variables miembro ---
|
||||
static Input* instance; // Instancia única del singleton
|
||||
|
||||
Gamepads gamepads_{}; // Lista de gamepads conectados
|
||||
Keyboard keyboard_{}; // Estado del teclado
|
||||
std::string gamepad_mappings_file_{}; // Ruta al archivo de mappings
|
||||
std::string gamepad_configs_file_{}; // Ruta al archivo de configuraciones
|
||||
GamepadConfigs gamepad_configs_{}; // Configuraciones de gamepads guardadas
|
||||
};
|
||||
@@ -137,14 +137,15 @@ Director::Director(std::vector<std::string> const& args) {
|
||||
#ifdef RELEASE_BUILD
|
||||
// In release, construct the path manually (not from Asset which has empty executable_path)
|
||||
std::string gamecontroller_db = executable_path_ + PREFIX + "/gamecontrollerdb.txt";
|
||||
Input::init(gamecontroller_db, Resource::List::get()->get("controllers.json"));
|
||||
Input::init(gamecontroller_db);
|
||||
#else
|
||||
// In development, use Asset as normal
|
||||
Input::init(Resource::List::get()->get("gamecontrollerdb.txt"), Resource::List::get()->get("controllers.json")); // Carga configuración de controles
|
||||
Input::init(Resource::List::get()->get("gamecontrollerdb.txt")); // Carga configuración de controles
|
||||
#endif
|
||||
|
||||
// Aplica las teclas configuradas desde Options
|
||||
// Aplica las teclas y botones del gamepad configurados desde Options
|
||||
Input::get()->applyKeyboardBindingsFromOptions();
|
||||
Input::get()->applyGamepadBindingsFromOptions();
|
||||
|
||||
#ifdef _DEBUG
|
||||
Debug::init();
|
||||
|
||||
122
source/external/README.md
vendored
122
source/external/README.md
vendored
@@ -1,122 +0,0 @@
|
||||
# External Dependencies
|
||||
|
||||
This directory contains third-party libraries used by JailDoctor's Dilemma.
|
||||
|
||||
## Current Dependencies
|
||||
|
||||
| Library | Version | Type | Purpose |
|
||||
|---------|---------|------|---------|
|
||||
| **jail_audio** | Custom | Source (.cpp/.h) | Audio playback engine (OGG/WAV) |
|
||||
| **stb_image** | v2.x | Header-only | Image loading (PNG, GIF) |
|
||||
| **stb_vorbis** | v1.x | Header-only | OGG Vorbis audio decoding |
|
||||
| **json** | nlohmann/json | Header-only | JSON parsing (if needed) |
|
||||
| **fkYAML** | v3.x | Header-only | YAML parsing for room files |
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
external/
|
||||
├── jail_audio.cpp # Custom audio library implementation
|
||||
├── jail_audio.h # C interface for jail_audio
|
||||
├── stb_image.h # STB image loader (header-only)
|
||||
├── stb_vorbis.h # STB Vorbis decoder (header-only)
|
||||
├── json.hpp # nlohmann JSON library (header-only)
|
||||
└── fkyaml_node.hpp # fkYAML parser library (header-only)
|
||||
```
|
||||
|
||||
## Why Dependencies Are Here
|
||||
|
||||
All dependencies are kept in `source/external/` for several reasons:
|
||||
|
||||
1. **Build System Independence** - Can compile with CMake, Make, or other build systems
|
||||
2. **Offline Builds** - No internet required during compilation
|
||||
3. **Version Control** - Exact versions committed to repository
|
||||
4. **Portability** - Works on any platform without external package managers
|
||||
5. **Consistency** - All team members use identical library versions
|
||||
|
||||
## Using With Different Build Systems
|
||||
|
||||
### CMake (Recommended)
|
||||
```cmake
|
||||
# Include path for header-only libraries (fkYAML, json, stb)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_SOURCE_DIR}/source")
|
||||
|
||||
# All external dependencies are header-only except jail_audio
|
||||
# jail_audio.cpp is compiled as part of the main build
|
||||
```
|
||||
|
||||
### Makefile
|
||||
See `Makefile.example` in the project root for a complete example.
|
||||
|
||||
```makefile
|
||||
CXXFLAGS = -I./source
|
||||
# Compile jail_audio.cpp and link with your sources
|
||||
```
|
||||
|
||||
### Manual Compilation
|
||||
```bash
|
||||
# Compile jail_audio (only non-header-only library)
|
||||
g++ -c source/external/jail_audio.cpp -I./source
|
||||
|
||||
# Compile your project sources
|
||||
g++ -c source/game/*.cpp -I./source
|
||||
|
||||
# Link everything together
|
||||
g++ *.o -o game -lSDL3
|
||||
```
|
||||
|
||||
## Adding New Dependencies
|
||||
|
||||
### Header-Only Libraries
|
||||
1. Download the header file(s)
|
||||
2. Place in `source/external/`
|
||||
3. Include in code: `#include "external/library.h"`
|
||||
|
||||
### Source Libraries
|
||||
1. Place source files (.cpp) directly in `source/external/`
|
||||
2. Place header files (.h/.hpp) in `source/external/`
|
||||
3. Add to CMakeLists.txt if needed:
|
||||
```cmake
|
||||
# Most dependencies are header-only
|
||||
# For source libraries, add to SOURCES list
|
||||
```
|
||||
|
||||
## Updating Dependencies
|
||||
|
||||
### fkYAML
|
||||
To update fkYAML to a newer version:
|
||||
|
||||
```bash
|
||||
cd source/external
|
||||
# Download the single-header version from the releases page
|
||||
curl -L -O https://github.com/fktn-k/fkYAML/releases/download/v3.x.x/fkyaml_node.hpp
|
||||
```
|
||||
|
||||
Or download from: https://github.com/fktn-k/fkYAML/releases
|
||||
|
||||
### STB Libraries
|
||||
Download latest from: https://github.com/nothings/stb
|
||||
|
||||
```bash
|
||||
cd source/external
|
||||
curl -O https://raw.githubusercontent.com/nothings/stb/master/stb_image.h
|
||||
curl -O https://raw.githubusercontent.com/nothings/stb/master/stb_vorbis.h
|
||||
```
|
||||
|
||||
## License Information
|
||||
|
||||
Each library has its own license:
|
||||
|
||||
- **jail_audio** - Custom (see source files)
|
||||
- **stb libraries** - Public Domain / MIT
|
||||
- **nlohmann/json** - MIT License
|
||||
- **fkYAML** - MIT License
|
||||
|
||||
See individual library files for full license texts.
|
||||
|
||||
## Notes
|
||||
|
||||
- All dependencies are compatible with C++20
|
||||
- Most libraries are header-only and require no compilation
|
||||
- Only jail_audio (source library) is compiled as part of the main build
|
||||
- Keep dependencies minimal to reduce build times and binary size
|
||||
25526
source/external/json.hpp
vendored
25526
source/external/json.hpp
vendored
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user