fix: la tabla de punts no guardava a disc el estat de 1CC de cada entrada
395 lines
12 KiB
C++
395 lines
12 KiB
C++
#include "options.h"
|
|
#include <SDL2/SDL_gamecontroller.h> // Para SDL_GameControllerButton
|
|
#include <algorithm> // Para clamp
|
|
#include <fstream> // Para basic_ostream, operator<<, basi...
|
|
#include <iostream> // Para cout
|
|
#include <utility> // Para swap
|
|
#include <vector> // Para vector
|
|
#include "input.h" // Para InputDeviceToUse
|
|
#include "lang.h" // Para Code
|
|
#include "screen.h" // Para ScreenVideoMode, ScreenFilter
|
|
#include "utils.h" // Para boolToString, stringToBool, get...
|
|
|
|
// Variables
|
|
Options options;
|
|
|
|
// Declaraciones
|
|
bool setOptions(const std::string &var, const std::string &value);
|
|
|
|
// Inicializa las opciones del programa
|
|
void initOptions()
|
|
{
|
|
// Opciones de video
|
|
#ifdef ANBERNIC
|
|
options.video.mode = ScreenVideoMode::WINDOW;
|
|
options.video.window.size = 3;
|
|
#else
|
|
options.video.mode = ScreenVideoMode::WINDOW;
|
|
options.video.window.size = 2;
|
|
#endif
|
|
options.video.filter = ScreenFilter::NEAREST;
|
|
options.video.v_sync = true;
|
|
options.video.integer_scale = true;
|
|
options.video.shaders = true;
|
|
|
|
// Opciones de audio
|
|
options.audio.enabled = true;
|
|
options.audio.volume = 100;
|
|
options.audio.music.enabled = true;
|
|
options.audio.music.volume = 100;
|
|
options.audio.sound.enabled = true;
|
|
options.audio.sound.volume = 50;
|
|
|
|
// Opciones de juego
|
|
options.game.difficulty = GameDifficulty::NORMAL;
|
|
options.game.language = lang::Code::ba_BA;
|
|
options.game.autofire = true;
|
|
options.game.clear_last_hi_score_entries();
|
|
|
|
// Opciones de control
|
|
options.controllers.clear();
|
|
options.controllers.resize(2);
|
|
options.controllers.at(0).player_id = 1;
|
|
options.controllers.at(1).player_id = 2;
|
|
setKeyboardToPlayer(1);
|
|
}
|
|
|
|
// Carga el fichero de configuración
|
|
bool loadOptionsFile(std::string file_path)
|
|
{
|
|
// Inicializa las opciones del programa
|
|
initOptions();
|
|
|
|
// Indicador de éxito en la carga
|
|
bool success = true;
|
|
|
|
// Variables para manejar el fichero
|
|
std::ifstream file(file_path);
|
|
|
|
// Si el fichero se puede abrir
|
|
if (file.good())
|
|
{
|
|
// Procesa el fichero linea a linea
|
|
std::cout << "Reading file: " << getFileName(file_path) << std::endl;
|
|
std::string line;
|
|
while (std::getline(file, line))
|
|
{
|
|
// Comprueba que la linea no sea un comentario
|
|
if (line.substr(0, 1) != "#")
|
|
{
|
|
// Encuentra la posición del caracter '='
|
|
int pos = line.find("=");
|
|
// Procesa las dos subcadenas
|
|
if (!setOptions(line.substr(0, pos), line.substr(pos + 1, line.length())))
|
|
{
|
|
std::cout << "Warning: file " << getFileName(file_path) << std::endl;
|
|
std::cout << "Unknown parameter " << line.substr(0, pos).c_str() << std::endl;
|
|
success = false;
|
|
}
|
|
}
|
|
}
|
|
file.close();
|
|
}
|
|
|
|
// El fichero no existe
|
|
else
|
|
{ // Crea el fichero con los valores por defecto
|
|
saveOptionsFile(file_path);
|
|
}
|
|
|
|
// Normaliza los valores
|
|
const bool a = options.video.mode == ScreenVideoMode::WINDOW;
|
|
const bool b = options.video.mode == ScreenVideoMode::FULLSCREEN;
|
|
if (!(a || b))
|
|
{
|
|
options.video.mode = ScreenVideoMode::WINDOW;
|
|
}
|
|
|
|
options.video.window.size = std::clamp(options.video.window.size, 1, 4);
|
|
|
|
if (options.game.language != lang::Code::en_UK &&
|
|
options.game.language != lang::Code::ba_BA &&
|
|
options.game.language != lang::Code::es_ES)
|
|
{
|
|
options.game.language = lang::Code::en_UK;
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
// Guarda el fichero de configuración
|
|
bool saveOptionsFile(std::string file_path)
|
|
{
|
|
std::ofstream file(file_path);
|
|
|
|
if (!file.good())
|
|
{
|
|
std::cout << getFileName(file_path) << " can't be opened" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
std::cout << "Writing file: " << getFileName(file_path) << std::endl;
|
|
|
|
// Opciones de video
|
|
file << "## VIDEO\n";
|
|
file << "## video.mode [" << static_cast<int>(ScreenVideoMode::WINDOW) << ": window, " << static_cast<int>(ScreenVideoMode::FULLSCREEN) << ": fullscreen]\n";
|
|
file << "## video.filter [" << static_cast<int>(ScreenFilter::NEAREST) << ": nearest, " << static_cast<int>(ScreenFilter::LINEAL) << ": lineal]\n";
|
|
file << "\n";
|
|
|
|
file << "video.mode=" << static_cast<int>(options.video.mode) << "\n";
|
|
file << "video.window.size=" << options.video.window.size << "\n";
|
|
file << "video.filter=" << static_cast<int>(options.video.filter) << "\n";
|
|
file << "video.v_sync=" << boolToString(options.video.v_sync) << "\n";
|
|
file << "video.integer_scale=" << boolToString(options.video.integer_scale) << "\n";
|
|
file << "video.shaders=" << boolToString(options.video.shaders) << "\n";
|
|
|
|
// Opciones de audio
|
|
file << "\n\n## AUDIO\n";
|
|
file << "## volume [0 .. 100]\n";
|
|
file << "\n";
|
|
|
|
file << "audio.enabled=" << boolToString(options.audio.enabled) << "\n";
|
|
file << "audio.volume=" << options.audio.volume << "\n";
|
|
file << "audio.music.enabled=" << boolToString(options.audio.music.enabled) << "\n";
|
|
file << "audio.music.volume=" << options.audio.music.volume << "\n";
|
|
file << "audio.sound.enabled=" << boolToString(options.audio.sound.enabled) << "\n";
|
|
file << "audio.sound.volume=" << options.audio.sound.volume << "\n";
|
|
|
|
// Opciones del juego
|
|
file << "\n\n## GAME\n";
|
|
file << "## game.language [0: spanish, 1: valencian, 2: english]\n";
|
|
file << "## game.difficulty [" << static_cast<int>(GameDifficulty::EASY) << ": easy, " << static_cast<int>(GameDifficulty::NORMAL) << ": normal, " << static_cast<int>(GameDifficulty::HARD) << ": hard]\n";
|
|
file << "\n";
|
|
|
|
file << "game.language=" << static_cast<int>(options.game.language) << "\n";
|
|
file << "game.difficulty=" << static_cast<int>(options.game.difficulty) << "\n";
|
|
file << "game.autofire=" << boolToString(options.game.autofire) << "\n";
|
|
|
|
// Opciones de mandos
|
|
file << "\n\n## CONTROLLERS\n";
|
|
|
|
int controller_index = 0;
|
|
for (const auto &controller : options.controllers)
|
|
{
|
|
file << "\n";
|
|
file << "controller." << controller_index << ".name=" << controller.name << "\n";
|
|
file << "controller." << controller_index << ".player=" << controller.player_id << "\n";
|
|
file << "controller." << controller_index << ".type=" << static_cast<int>(controller.type) << "\n";
|
|
file << "controller." << controller_index << ".button.fire_left=" << controller.buttons.at(0) << "\n";
|
|
file << "controller." << controller_index << ".button.fire_center=" << controller.buttons.at(1) << "\n";
|
|
file << "controller." << controller_index << ".button.fire_right=" << controller.buttons.at(2) << "\n";
|
|
file << "controller." << controller_index << ".button.start=" << controller.buttons.at(3) << "\n";
|
|
file << "controller." << controller_index << ".button.service=" << controller.buttons.at(4) << "\n";
|
|
|
|
// Incrementa el índice
|
|
++controller_index;
|
|
}
|
|
|
|
// Cierra el fichero
|
|
file.close();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Asigna variables a partir de dos cadenas
|
|
bool setOptions(const std::string &var, const std::string &value)
|
|
{
|
|
// Indicador de éxito en la asignación
|
|
auto success = true;
|
|
|
|
// Opciones de video
|
|
if (var == "video.mode")
|
|
{
|
|
options.video.mode = static_cast<ScreenVideoMode>(std::stoi(value));
|
|
}
|
|
else if (var == "video.window.size")
|
|
{
|
|
options.video.window.size = std::stoi(value);
|
|
if ((options.video.window.size < 1) || (options.video.window.size > 4))
|
|
{
|
|
options.video.window.size = 3;
|
|
}
|
|
}
|
|
else if (var == "video.filter")
|
|
{
|
|
options.video.filter = static_cast<ScreenFilter>(std::stoi(value));
|
|
}
|
|
else if (var == "video.shaders")
|
|
{
|
|
options.video.shaders = stringToBool(value);
|
|
}
|
|
else if (var == "video.integer_scale")
|
|
{
|
|
options.video.integer_scale = stringToBool(value);
|
|
}
|
|
else if (var == "video.v_sync")
|
|
{
|
|
options.video.v_sync = stringToBool(value);
|
|
}
|
|
|
|
// Opciones de audio
|
|
else if (var == "audio.enabled")
|
|
{
|
|
options.audio.enabled = stringToBool(value);
|
|
}
|
|
else if (var == "audio.volume")
|
|
{
|
|
options.audio.volume = std::stoi(value);
|
|
}
|
|
else if (var == "audio.music.enabled")
|
|
{
|
|
options.audio.music.enabled = stringToBool(value);
|
|
}
|
|
else if (var == "audio.music.volume")
|
|
{
|
|
options.audio.music.volume = std::stoi(value);
|
|
}
|
|
else if (var == "audio.sound.enabled")
|
|
{
|
|
options.audio.sound.enabled = stringToBool(value);
|
|
}
|
|
else if (var == "audio.sound.volume")
|
|
{
|
|
options.audio.sound.volume = std::stoi(value);
|
|
}
|
|
|
|
// Opciones de juego
|
|
else if (var == "game.language")
|
|
{
|
|
options.game.language = static_cast<lang::Code>(std::stoi(value));
|
|
}
|
|
else if (var == "game.difficulty")
|
|
{
|
|
options.game.difficulty = static_cast<GameDifficulty>(std::stoi(value));
|
|
}
|
|
else if (var == "game.autofire")
|
|
{
|
|
options.game.autofire = stringToBool(value);
|
|
}
|
|
|
|
// Opciones de mandos
|
|
else if (var == "controller.0.name")
|
|
{
|
|
options.controllers.at(0).name = value;
|
|
}
|
|
else if (var == "controller.0.player")
|
|
{
|
|
options.controllers.at(0).player_id = std::clamp(std::stoi(value), 1, 2);
|
|
}
|
|
else if (var == "controller.0.type")
|
|
{
|
|
options.controllers.at(0).type = static_cast<InputDeviceToUse>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.0.button.fire_left")
|
|
{
|
|
options.controllers.at(0).buttons.at(0) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.0.button.fire_center")
|
|
{
|
|
options.controllers.at(0).buttons.at(1) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.0.button.fire_right")
|
|
{
|
|
options.controllers.at(0).buttons.at(2) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.0.button.start")
|
|
{
|
|
options.controllers.at(0).buttons.at(3) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.0.button.service")
|
|
{
|
|
options.controllers.at(0).buttons.at(4) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.1.name")
|
|
{
|
|
options.controllers.at(1).name = value;
|
|
}
|
|
else if (var == "controller.1.player")
|
|
{
|
|
options.controllers.at(1).player_id = std::clamp(std::stoi(value), 1, 2);
|
|
}
|
|
else if (var == "controller.1.type")
|
|
{
|
|
options.controllers.at(1).type = static_cast<InputDeviceToUse>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.1.button.fire_left")
|
|
{
|
|
options.controllers.at(1).buttons.at(0) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.1.button.fire_center")
|
|
{
|
|
options.controllers.at(1).buttons.at(1) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.1.button.fire_right")
|
|
{
|
|
options.controllers.at(1).buttons.at(2) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.1.button.start")
|
|
{
|
|
options.controllers.at(1).buttons.at(3) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
else if (var == "controller.1.button.service")
|
|
{
|
|
options.controllers.at(1).buttons.at(4) = static_cast<SDL_GameControllerButton>(std::stoi(value));
|
|
}
|
|
|
|
// Lineas vacias o que empiezan por comentario
|
|
else if (var.empty() || var.starts_with("#"))
|
|
{
|
|
}
|
|
else
|
|
{
|
|
success = false;
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
// Convierte valores de 0 a 100 en valores de 0 a 128
|
|
int to_JA_volume(int vol)
|
|
{
|
|
vol = vol * 1.28f;
|
|
return std::clamp(vol, 0, 128);
|
|
}
|
|
|
|
// Asigna el teclado al jugador
|
|
void setKeyboardToPlayer(int player_id)
|
|
{
|
|
for (auto &controller : options.controllers)
|
|
{
|
|
if (controller.player_id == player_id)
|
|
{
|
|
controller.type = InputDeviceToUse::ANY;
|
|
}
|
|
else
|
|
{
|
|
controller.type = InputDeviceToUse::CONTROLLER;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Intercambia el teclado de jugador
|
|
void swapOptionsKeyboard()
|
|
{
|
|
std::swap(options.controllers.at(0).type, options.controllers.at(1).type);
|
|
}
|
|
|
|
// Intercambia los jugadores asignados a los dos primeros mandos
|
|
void swapOptionsControllers()
|
|
{
|
|
std::swap(options.controllers.at(0).player_id, options.controllers.at(1).player_id);
|
|
std::swap(options.controllers.at(0).type, options.controllers.at(1).type);
|
|
}
|
|
|
|
// Averigua quien está usando el teclado
|
|
int getPlayerWhoUsesKeyboard()
|
|
{
|
|
for (const auto &controller : options.controllers)
|
|
{
|
|
if (controller.type == InputDeviceToUse::ANY)
|
|
{
|
|
return controller.player_id;
|
|
}
|
|
}
|
|
return 0;
|
|
} |