478 lines
12 KiB
C++
478 lines
12 KiB
C++
#include "options.h"
|
|
#include "screen.h"
|
|
#include "lang.h"
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
// Variables
|
|
options_t options;
|
|
|
|
// Declaraciones
|
|
bool setOptions(std::string var, std::string value);
|
|
|
|
// Inicializa las opciones del programa
|
|
void initOptions()
|
|
{
|
|
// Opciones varias
|
|
#ifdef VERBOSE
|
|
options.console = true;
|
|
#else
|
|
options.console = false;
|
|
#endif
|
|
|
|
// Opciones de video
|
|
#ifdef ANBERNIC
|
|
options.video.mode = 0;
|
|
options.video.window.size = 3;
|
|
#else
|
|
options.video.mode = 0;
|
|
options.video.window.size = 2;
|
|
#endif
|
|
options.video.filter = SCREEN_FILTER_NEAREST;
|
|
options.video.vSync = true;
|
|
options.video.integerScale = true;
|
|
options.video.keepAspect = true;
|
|
options.video.shaders = true;
|
|
|
|
// Opciones de las notificaciones
|
|
options.notification.posV = pos_top;
|
|
options.notification.posH = pos_left;
|
|
options.notification.sound = false;
|
|
options.notification.color = {48, 48, 48};
|
|
|
|
// Opciones de audio
|
|
options.audio.music.enabled = true;
|
|
options.audio.music.volume = 128;
|
|
options.audio.sound.enabled = true;
|
|
options.audio.sound.volume = 64;
|
|
|
|
// Opciones de juego
|
|
options.game.difficulty = DIFFICULTY_NORMAL;
|
|
options.game.language = lang::ba_BA;
|
|
options.game.autofire = true;
|
|
|
|
// Opciones de control
|
|
options.controller.clear();
|
|
op_controller_t c;
|
|
|
|
const int numPlayers = 2;
|
|
for (int index = 0; index < numPlayers; ++index)
|
|
{
|
|
c.index = index;
|
|
c.playerId = index + 1;
|
|
c.deviceType = INPUT_USE_GAMECONTROLLER;
|
|
c.name = "NO NAME";
|
|
|
|
// Inputs que se guardan en las opciones y, por tanto, a disco
|
|
c.inputs.clear();
|
|
c.inputs.push_back(input_fire_left);
|
|
c.inputs.push_back(input_fire_center);
|
|
c.inputs.push_back(input_fire_right);
|
|
c.inputs.push_back(input_start);
|
|
c.inputs.push_back(input_service);
|
|
|
|
// Botones asociados a los inputs anteriores
|
|
c.buttons.clear();
|
|
c.buttons.push_back(SDL_CONTROLLER_BUTTON_X);
|
|
c.buttons.push_back(SDL_CONTROLLER_BUTTON_Y);
|
|
c.buttons.push_back(SDL_CONTROLLER_BUTTON_B);
|
|
c.buttons.push_back(SDL_CONTROLLER_BUTTON_START);
|
|
c.buttons.push_back(SDL_CONTROLLER_BUTTON_BACK);
|
|
|
|
options.controller.push_back(c);
|
|
}
|
|
options.controller[0].deviceType = INPUT_USE_ANY; // El primer jugador puede usar tanto el teclado como el primer mando
|
|
}
|
|
|
|
// Carga el fichero de configuración
|
|
bool loadOptionsFile(std::string filePath)
|
|
{
|
|
// Inicializa las opciones del programa
|
|
initOptions();
|
|
|
|
// Indicador de éxito en la carga
|
|
bool success = true;
|
|
|
|
// Variables para manejar el fichero
|
|
std::string line;
|
|
std::ifstream file(filePath);
|
|
|
|
// Si el fichero se puede abrir
|
|
if (file.good())
|
|
{
|
|
// Procesa el fichero linea a linea
|
|
if (options.console)
|
|
{
|
|
std::cout << "Reading file: " << filePath << std::endl;
|
|
}
|
|
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())))
|
|
{
|
|
if (options.console)
|
|
{
|
|
std::cout << "Warning: file " << filePath << std::endl;
|
|
std::cout << "Unknown parameter " << line.substr(0, pos).c_str() << std::endl;
|
|
}
|
|
success = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Cierra el fichero
|
|
file.close();
|
|
}
|
|
|
|
// El fichero no existe
|
|
else
|
|
{ // Crea el fichero con los valores por defecto
|
|
saveOptionsFile(filePath);
|
|
}
|
|
|
|
// Normaliza los valores
|
|
const bool a = options.video.mode == 0;
|
|
const bool b = options.video.mode == SDL_WINDOW_FULLSCREEN;
|
|
const bool c = options.video.mode == SDL_WINDOW_FULLSCREEN_DESKTOP;
|
|
if (!(a || b || c))
|
|
{
|
|
options.video.mode = SCREEN_VIDEO_MODE_WINDOW;
|
|
}
|
|
|
|
if (options.video.window.size < 1 || options.video.window.size > 4)
|
|
{
|
|
options.video.window.size = 3;
|
|
}
|
|
|
|
if (options.game.language < 0 || options.game.language > 2)
|
|
{
|
|
options.game.language = lang::en_UK;
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
// Guarda el fichero de configuración
|
|
bool saveOptionsFile(std::string filePath)
|
|
{
|
|
const std::string filename = filePath;
|
|
std::ofstream file(filePath);
|
|
|
|
if (!file.good())
|
|
{
|
|
if (options.console)
|
|
{
|
|
std::cout << filename << " can't be opened" << std::endl;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (options.console)
|
|
{
|
|
std::cout << "Writing file: " << filename << std::endl;
|
|
}
|
|
|
|
// Opciones de video
|
|
file << "## VIDEO\n";
|
|
file << "## video.mode [0: window, 1: full screen]\n";
|
|
file << "## video.filter [0: nearest, 1: lineal]\n";
|
|
file << "\n";
|
|
|
|
if (options.video.mode == SCREEN_VIDEO_MODE_WINDOW)
|
|
{
|
|
file << "video.mode=0\n";
|
|
}
|
|
|
|
else if (options.video.mode == SCREEN_VIDEO_MODE_FULLSCREEN)
|
|
{
|
|
file << "video.mode=1\n";
|
|
}
|
|
|
|
file << "video.window.size=" + std::to_string(options.video.window.size) + "\n";
|
|
|
|
options.video.filter == SCREEN_FILTER_NEAREST ? file << "video.filter=0\n" : file << "video.filter=1\n";
|
|
|
|
file << "video.shaders=" + boolToString(options.video.shaders) + "\n";
|
|
file << "video.vSync=" + boolToString(options.video.vSync) + "\n";
|
|
file << "video.integerScale=" + boolToString(options.video.integerScale) + "\n";
|
|
file << "video.keepAspect=" + boolToString(options.video.keepAspect) + "\n";
|
|
|
|
// Opciones de notificaciones
|
|
file << "\n\n## NOTIFICATION\n";
|
|
file << "## notification.posV [pos_top | pos_bottom]\n";
|
|
file << "## notification.posH [pos_left | pos_middle | pos_right]\n";
|
|
file << "\n";
|
|
|
|
if (options.notification.posV == pos_top)
|
|
{
|
|
file << "notification.posV=pos_top\n";
|
|
}
|
|
|
|
else
|
|
{
|
|
file << "notification.posV=pos_bottom\n";
|
|
}
|
|
|
|
if (options.notification.posH == pos_left)
|
|
{
|
|
file << "notification.posH=pos_left\n";
|
|
}
|
|
|
|
else if (options.notification.posH == pos_middle)
|
|
{
|
|
file << "notification.posH=pos_middle\n";
|
|
}
|
|
|
|
else
|
|
{
|
|
file << "notification.posH=pos_right\n";
|
|
}
|
|
|
|
file << "notification.sound=" + boolToString(options.notification.sound) + "\n";
|
|
|
|
// Opciones de audio
|
|
file << "\n\n## AUDIO\n";
|
|
file << "## volume [0 .. 128]\n";
|
|
file << "\n";
|
|
|
|
file << "audio.music.enabled=" + boolToString(options.audio.music.enabled) + "\n";
|
|
file << "audio.music.volume=" + std::to_string(options.audio.music.volume) + "\n";
|
|
file << "audio.sound.enabled=" + boolToString(options.audio.sound.enabled) + "\n";
|
|
file << "audio.sound.volume=" + std::to_string(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 [0: easy, 1: normal, 2: hard]\n";
|
|
file << "\n";
|
|
|
|
file << "game.language=" + std::to_string(options.game.language) + "\n";
|
|
file << "game.difficulty=" + std::to_string(options.game.difficulty) + "\n";
|
|
file << "game.autofire=" + boolToString(options.game.autofire) + "\n";
|
|
|
|
// Opciones de mandos
|
|
file << "\n\n## CONTROLLERS\n";
|
|
file << "\n";
|
|
|
|
const int numPlayers = 2;
|
|
for (int index = 0; index < numPlayers; ++index)
|
|
{
|
|
const std::string joyIndex = std::to_string(index + 1);
|
|
file << "controller" + joyIndex + ".name=" + options.controller[index].name + "\n";
|
|
file << "controller" + joyIndex + ".player=" + std::to_string(options.controller[index].playerId) + "\n";
|
|
file << "controller" + joyIndex + ".button.fire_left=" + std::to_string((int)options.controller[index].buttons[0]) + "\n";
|
|
file << "controller" + joyIndex + ".button.fire_center=" + std::to_string((int)options.controller[index].buttons[1]) + "\n";
|
|
file << "controller" + joyIndex + ".button.fire_right=" + std::to_string((int)options.controller[index].buttons[2]) + "\n";
|
|
file << "controller" + joyIndex + ".button.start=" + std::to_string((int)options.controller[index].buttons[3]) + "\n";
|
|
file << "controller" + joyIndex + ".button.service=" + std::to_string((int)options.controller[index].buttons[4]) + "\n";
|
|
|
|
if (index < numPlayers - 1)
|
|
{
|
|
file << "\n";
|
|
}
|
|
}
|
|
|
|
// Cierra el fichero
|
|
file.close();
|
|
|
|
return true;
|
|
}
|
|
|
|
// Asigna variables a partir de dos cadenas
|
|
bool setOptions(std::string var, std::string value)
|
|
{
|
|
// Indicador de éxito en la asignación
|
|
bool success = true;
|
|
|
|
// Opciones de video
|
|
if (var == "video.mode")
|
|
{
|
|
options.video.mode = value == std::to_string(SCREEN_VIDEO_MODE_WINDOW) ? SCREEN_VIDEO_MODE_WINDOW : SCREEN_VIDEO_MODE_FULLSCREEN;
|
|
}
|
|
|
|
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 = value == std::to_string(SCREEN_FILTER_NEAREST) ? SCREEN_FILTER_NEAREST : SCREEN_FILTER_LINEAL;
|
|
}
|
|
|
|
else if (var == "video.shaders")
|
|
{
|
|
options.video.shaders = stringToBool(value);
|
|
}
|
|
|
|
else if (var == "video.vSync")
|
|
{
|
|
options.video.vSync = stringToBool(value);
|
|
}
|
|
|
|
else if (var == "video.integerScale")
|
|
{
|
|
options.video.integerScale = stringToBool(value);
|
|
}
|
|
|
|
else if (var == "video.keepAspect")
|
|
{
|
|
options.video.keepAspect = stringToBool(value);
|
|
}
|
|
|
|
// Opciones de notificaciones
|
|
else if (var == "notification.posH")
|
|
{
|
|
if (value == "pos_left")
|
|
{
|
|
options.notification.posH = pos_left;
|
|
}
|
|
else if (value == "pos_middle")
|
|
{
|
|
options.notification.posH = pos_middle;
|
|
}
|
|
else
|
|
{
|
|
options.notification.posH = pos_right;
|
|
}
|
|
}
|
|
|
|
else if (var == "notification.posV")
|
|
{
|
|
options.notification.posV = value == "pos_top" ? pos_top : pos_bottom;
|
|
}
|
|
|
|
else if (var == "notification.sound")
|
|
{
|
|
options.notification.sound = stringToBool(value);
|
|
}
|
|
|
|
// Opciones de audio
|
|
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 = std::stoi(value);
|
|
}
|
|
|
|
else if (var == "game.difficulty")
|
|
{
|
|
options.game.difficulty = std::stoi(value);
|
|
}
|
|
|
|
else if (var == "game.autofire")
|
|
{
|
|
options.game.autofire = stringToBool(value);
|
|
}
|
|
|
|
// Opciones de mandos
|
|
else if (var == "controller1.name")
|
|
{
|
|
options.controller[0].name = value;
|
|
}
|
|
|
|
else if (var == "controller1.player")
|
|
{
|
|
options.controller[0].playerId = std::max(1, std::min(2, std::stoi(value)));
|
|
}
|
|
|
|
else if (var == "controller1.button.fire_left")
|
|
{
|
|
options.controller[0].buttons[0] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller1.button.fire_center")
|
|
{
|
|
options.controller[0].buttons[1] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller1.button.fire_right")
|
|
{
|
|
options.controller[0].buttons[2] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller1.button.start")
|
|
{
|
|
options.controller[0].buttons[3] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller1.button.service")
|
|
{
|
|
options.controller[0].buttons[4] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller2.name")
|
|
{
|
|
options.controller[1].name = value;
|
|
}
|
|
|
|
else if (var == "controller2.player")
|
|
{
|
|
options.controller[1].playerId = std::max(1, std::min(2, std::stoi(value)));
|
|
}
|
|
|
|
else if (var == "controller2.button.fire_left")
|
|
{
|
|
options.controller[1].buttons[0] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller2.button.fire_center")
|
|
{
|
|
options.controller[1].buttons[1] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller2.button.fire_right")
|
|
{
|
|
options.controller[1].buttons[2] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller2.button.start")
|
|
{
|
|
options.controller[1].buttons[3] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
else if (var == "controller2.button.service")
|
|
{
|
|
options.controller[1].buttons[4] = (SDL_GameControllerButton)std::stoi(value);
|
|
}
|
|
|
|
// Lineas vacias o que empiezan por comentario
|
|
else if (var == "" || var.substr(0, 1) == "#")
|
|
{
|
|
}
|
|
|
|
else
|
|
{
|
|
success = false;
|
|
}
|
|
|
|
return success;
|
|
} |