modernitzat el sistema d'opcions
This commit is contained in:
@@ -21,17 +21,18 @@
|
||||
#include "core/input/input.h" // for Input, inputs_e, INPUT_USE_GAME...
|
||||
#include "core/input/mouse.hpp" // for Mouse::handleEvent, Mouse::upda...
|
||||
#include "core/locale/lang.h" // for Lang, MAX_LANGUAGES, ba_BA, en_UK
|
||||
#include "core/rendering/screen.h" // for FILTER_NEAREST, Screen, FILTER_...
|
||||
#include "core/rendering/screen.h" // for Screen
|
||||
#include "core/rendering/texture.h" // for Texture
|
||||
#include "core/resources/asset.h" // for Asset, assetType
|
||||
#include "core/resources/resource.h"
|
||||
#include "core/resources/resource_helper.h"
|
||||
#include "game/defaults.hpp" // for SECTION_PROG_LOGO, GAMECANVAS_H...
|
||||
#include "game/game.h" // for Game
|
||||
#include "game/options.hpp" // for Options::init, loadFromFile...
|
||||
#include "game/scenes/intro.h" // for Intro
|
||||
#include "game/scenes/logo.h" // for Logo
|
||||
#include "game/scenes/title.h" // for Title
|
||||
#include "utils/utils.h" // for options_t, input_t, boolToString
|
||||
#include "utils/utils.h" // for input_t, boolToString
|
||||
|
||||
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__)
|
||||
#include <pwd.h>
|
||||
@@ -44,10 +45,10 @@ Director::Director(int argc, const char *argv[]) {
|
||||
section = new section_t();
|
||||
section->name = SECTION_PROG_LOGO;
|
||||
|
||||
// Inicializa las opciones del programa
|
||||
initOptions();
|
||||
// Inicializa las opciones del programa (defaults + dispositivos d'entrada)
|
||||
Options::init();
|
||||
|
||||
// Comprueba los parametros del programa
|
||||
// Comprueba los parametros del programa (pot activar console)
|
||||
checkProgramArguments(argc, argv);
|
||||
|
||||
// Crea la carpeta del sistema donde guardar datos
|
||||
@@ -58,6 +59,11 @@ Director::Director(int argc, const char *argv[]) {
|
||||
createSystemFolder("jailgames/coffee_crisis_debug");
|
||||
#endif
|
||||
|
||||
// Estableix el fitxer de configuració i carrega les opcions (o crea el
|
||||
// YAML amb defaults si no existeix).
|
||||
Options::setConfigFile(systemFolder + "/config.yaml");
|
||||
Options::loadFromFile();
|
||||
|
||||
// Inicializa el sistema de recursos (pack + fallback).
|
||||
// En wasm siempre se usa filesystem (MEMFS) porque el propio --preload-file
|
||||
// de emscripten ya empaqueta data/ — no hay resources.pack.
|
||||
@@ -77,16 +83,13 @@ Director::Director(int argc, const char *argv[]) {
|
||||
|
||||
// Crea el objeto que controla los ficheros de recursos
|
||||
asset = new Asset(executablePath);
|
||||
asset->setVerbose(options->console);
|
||||
asset->setVerbose(Options::settings.console);
|
||||
|
||||
// Si falta algún fichero no inicia el programa
|
||||
if (!setFileList()) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Carga el fichero de configuración
|
||||
loadConfigFile();
|
||||
|
||||
// Inicializa SDL
|
||||
initSDL();
|
||||
|
||||
@@ -94,11 +97,11 @@ Director::Director(int argc, const char *argv[]) {
|
||||
initJailAudio();
|
||||
|
||||
// Establece el modo de escalado de texturas
|
||||
Texture::setGlobalScaleMode(options->filter == FILTER_NEAREST ? SDL_SCALEMODE_NEAREST : SDL_SCALEMODE_LINEAR);
|
||||
Texture::setGlobalScaleMode(Options::video.scale_mode);
|
||||
|
||||
// Crea los objetos
|
||||
lang = new Lang(asset);
|
||||
lang->setLang(options->language);
|
||||
lang->setLang(Options::settings.language);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
input = new Input("/gamecontrollerdb.txt");
|
||||
@@ -122,10 +125,10 @@ Director::Director(int argc, const char *argv[]) {
|
||||
//
|
||||
// Por eso el constructor de Screen NO carga notificationText desde
|
||||
// Resource; se enlaza después vía `screen->initNotifications()`.
|
||||
screen = new Screen(window, renderer, asset, options);
|
||||
screen = new Screen(window, renderer, asset);
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
if (options->videoGpuAcceleration) {
|
||||
if (Options::video.gpu.acceleration) {
|
||||
screen->initShaders();
|
||||
}
|
||||
#endif
|
||||
@@ -142,7 +145,7 @@ Director::Director(int argc, const char *argv[]) {
|
||||
}
|
||||
|
||||
Director::~Director() {
|
||||
saveConfigFile();
|
||||
Options::saveToFile();
|
||||
|
||||
// Libera las secciones primero: sus destructores tocan audio/render SDL
|
||||
// (p.ej. Intro::~Intro llama a JA_DeleteMusic) y deben ejecutarse antes
|
||||
@@ -162,7 +165,6 @@ Director::~Director() {
|
||||
delete asset;
|
||||
delete input;
|
||||
delete lang;
|
||||
delete options;
|
||||
delete section;
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
@@ -178,7 +180,7 @@ Director::~Director() {
|
||||
// Inicializa el objeto input
|
||||
void Director::initInput() {
|
||||
// Establece si ha de mostrar mensajes
|
||||
input->setVerbose(options->console);
|
||||
input->setVerbose(Options::settings.console);
|
||||
|
||||
// Busca si hay un mando conectado
|
||||
input->discoverGameController();
|
||||
@@ -237,7 +239,7 @@ bool Director::initSDL() {
|
||||
|
||||
// Inicializa SDL
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD)) {
|
||||
if (options->console) {
|
||||
if (Options::settings.console) {
|
||||
std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
success = false;
|
||||
@@ -246,15 +248,13 @@ bool Director::initSDL() {
|
||||
std::srand(static_cast<unsigned int>(SDL_GetTicks()));
|
||||
|
||||
// Crea la ventana
|
||||
int incW = 0;
|
||||
int incH = 0;
|
||||
if (options->borderEnabled) {
|
||||
incW = options->borderWidth * 2;
|
||||
incH = options->borderHeight * 2;
|
||||
}
|
||||
window = SDL_CreateWindow(WINDOW_CAPTION, (options->gameWidth + incW) * options->windowSize, (options->gameHeight + incH) * options->windowSize, 0);
|
||||
window = SDL_CreateWindow(
|
||||
Options::window.caption.c_str(),
|
||||
GAMECANVAS_WIDTH * Options::window.zoom,
|
||||
GAMECANVAS_HEIGHT * Options::window.zoom,
|
||||
0);
|
||||
if (window == nullptr) {
|
||||
if (options->console) {
|
||||
if (Options::settings.console) {
|
||||
std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
success = false;
|
||||
@@ -265,7 +265,7 @@ bool Director::initSDL() {
|
||||
renderer = SDL_CreateRenderer(window, NULL);
|
||||
|
||||
if (renderer == nullptr) {
|
||||
if (options->console) {
|
||||
if (Options::settings.console) {
|
||||
std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
success = false;
|
||||
@@ -275,7 +275,7 @@ bool Director::initSDL() {
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Activa vsync si es necesario
|
||||
if (options->vSync) {
|
||||
if (Options::video.vsync) {
|
||||
SDL_SetRenderVSync(renderer, 1);
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ bool Director::initSDL() {
|
||||
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
|
||||
|
||||
// Establece el tamaño del buffer de renderizado
|
||||
SDL_SetRenderLogicalPresentation(renderer, options->gameWidth, options->gameHeight, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
SDL_SetRenderLogicalPresentation(renderer, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||
|
||||
// Establece el modo de mezcla
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
@@ -291,7 +291,7 @@ bool Director::initSDL() {
|
||||
}
|
||||
}
|
||||
|
||||
if (options->console) {
|
||||
if (Options::settings.console) {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
return success;
|
||||
@@ -306,7 +306,6 @@ bool Director::setFileList() {
|
||||
#endif
|
||||
|
||||
// Ficheros de configuración
|
||||
asset->add(systemFolder + "/config.txt", t_data, false, true);
|
||||
asset->add(systemFolder + "/score.bin", t_data, false, true);
|
||||
asset->add(prefix + "/data/demo/demo.bin", t_data);
|
||||
|
||||
@@ -426,52 +425,6 @@ bool Director::setFileList() {
|
||||
return asset->check();
|
||||
}
|
||||
|
||||
// Inicializa las opciones del programa
|
||||
void Director::initOptions() {
|
||||
// Crea el puntero a la estructura de opciones
|
||||
options = new options_t;
|
||||
|
||||
// Pone unos valores por defecto para las opciones de control
|
||||
options->input.clear();
|
||||
|
||||
input_t inp;
|
||||
inp.id = 0;
|
||||
inp.name = "KEYBOARD";
|
||||
inp.deviceType = INPUT_USE_KEYBOARD;
|
||||
options->input.push_back(inp);
|
||||
|
||||
inp.id = 0;
|
||||
inp.name = "GAME CONTROLLER";
|
||||
inp.deviceType = INPUT_USE_GAMECONTROLLER;
|
||||
options->input.push_back(inp);
|
||||
|
||||
// Opciones de video
|
||||
options->gameWidth = GAMECANVAS_WIDTH;
|
||||
options->gameHeight = GAMECANVAS_HEIGHT;
|
||||
options->videoMode = 0;
|
||||
options->windowSize = 3;
|
||||
options->filter = FILTER_NEAREST;
|
||||
options->vSync = true;
|
||||
options->integerScale = true;
|
||||
options->keepAspect = true;
|
||||
options->borderWidth = 0;
|
||||
options->borderHeight = 0;
|
||||
options->borderEnabled = false;
|
||||
|
||||
// Opciones varios
|
||||
options->playerSelected = 0;
|
||||
options->difficulty = DIFFICULTY_NORMAL;
|
||||
options->language = ba_BA;
|
||||
options->console = false;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// En Emscripten la ventana la gestiona el navegador
|
||||
options->windowSize = 4;
|
||||
options->videoMode = 0;
|
||||
options->integerScale = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Comprueba los parametros del programa
|
||||
void Director::checkProgramArguments(int argc, const char *argv[]) {
|
||||
// Establece la ruta del programa
|
||||
@@ -480,7 +433,7 @@ void Director::checkProgramArguments(int argc, const char *argv[]) {
|
||||
// Comprueba el resto de parametros
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "--console") == 0) {
|
||||
options->console = true;
|
||||
Options::settings.console = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,127 +501,6 @@ void Director::createSystemFolder(const std::string &folder) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Carga el fichero de configuración
|
||||
bool Director::loadConfigFile() {
|
||||
// Indicador de éxito en la carga
|
||||
bool success = true;
|
||||
|
||||
// Variables para manejar el fichero
|
||||
const std::string filePath = "config.txt";
|
||||
std::string line;
|
||||
std::ifstream file(asset->get(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(options, 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
|
||||
if (options->console) {
|
||||
std::cout << "Closing file " << filePath << std::endl;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
// El fichero no existe
|
||||
else { // Crea el fichero con los valores por defecto
|
||||
saveConfigFile();
|
||||
}
|
||||
|
||||
// Normaliza los valores
|
||||
if (options->videoMode != 0 && options->videoMode != SDL_WINDOW_FULLSCREEN) {
|
||||
options->videoMode = 0;
|
||||
}
|
||||
|
||||
if (options->windowSize < 1 || options->windowSize > 4) {
|
||||
options->windowSize = 3;
|
||||
}
|
||||
|
||||
if (options->language < 0 || options->language > MAX_LANGUAGES) {
|
||||
options->language = en_UK;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Guarda el fichero de configuración
|
||||
bool Director::saveConfigFile() {
|
||||
bool success = true;
|
||||
|
||||
// Crea y abre el fichero de texto
|
||||
std::ofstream file(asset->get("config.txt"));
|
||||
|
||||
if (file.good()) {
|
||||
if (options->console) {
|
||||
std::cout << asset->get("config.txt") << " open for writing" << std::endl;
|
||||
}
|
||||
} else {
|
||||
if (options->console) {
|
||||
std::cout << asset->get("config.txt") << " can't be opened" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Opciones g´raficas
|
||||
file << "## VISUAL OPTIONS\n";
|
||||
if (options->videoMode == 0) {
|
||||
file << "videoMode=0\n";
|
||||
}
|
||||
|
||||
else if (options->videoMode == SDL_WINDOW_FULLSCREEN) {
|
||||
file << "videoMode=SDL_WINDOW_FULLSCREEN\n";
|
||||
}
|
||||
|
||||
file << "windowSize=" + std::to_string(options->windowSize) + "\n";
|
||||
|
||||
if (options->filter == FILTER_NEAREST) {
|
||||
file << "filter=FILTER_NEAREST\n";
|
||||
} else {
|
||||
file << "filter=FILTER_LINEAL\n";
|
||||
}
|
||||
|
||||
file << "vSync=" + boolToString(options->vSync) + "\n";
|
||||
file << "integerScale=" + boolToString(options->integerScale) + "\n";
|
||||
file << "keepAspect=" + boolToString(options->keepAspect) + "\n";
|
||||
file << "borderEnabled=" + boolToString(options->borderEnabled) + "\n";
|
||||
file << "borderWidth=" + std::to_string(options->borderWidth) + "\n";
|
||||
file << "borderHeight=" + std::to_string(options->borderHeight) + "\n";
|
||||
|
||||
// Opciones de GPU / shaders (post-procesado)
|
||||
file << "videoGpuAcceleration=" + boolToString(options->videoGpuAcceleration) + "\n";
|
||||
file << "videoGpuPreferredDriver=" + options->videoGpuPreferredDriver + "\n";
|
||||
file << "videoShaderEnabled=" + boolToString(options->videoShaderEnabled) + "\n";
|
||||
file << "videoShaderType=" + std::to_string(options->videoShaderType) + "\n";
|
||||
|
||||
// Otras opciones del programa
|
||||
file << "\n## OTHER OPTIONS\n";
|
||||
file << "language=" + std::to_string(options->language) + "\n";
|
||||
file << "difficulty=" + std::to_string(options->difficulty) + "\n";
|
||||
file << "input0=" + std::to_string(options->input[0].deviceType) + "\n";
|
||||
file << "input1=" + std::to_string(options->input[1].deviceType) + "\n";
|
||||
|
||||
// Cierra el fichero
|
||||
file.close();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Gestiona las transiciones entre secciones
|
||||
void Director::handleSectionTransition() {
|
||||
// Determina qué sección debería estar activa
|
||||
@@ -707,11 +539,11 @@ void Director::handleSectionTransition() {
|
||||
intro = std::make_unique<Intro>(renderer, screen, asset, input, lang, section);
|
||||
break;
|
||||
case ActiveSection::Title:
|
||||
title = std::make_unique<Title>(renderer, screen, input, asset, options, lang, section);
|
||||
title = std::make_unique<Title>(renderer, screen, input, asset, lang, section);
|
||||
break;
|
||||
case ActiveSection::Game: {
|
||||
const int numPlayers = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2;
|
||||
game = std::make_unique<Game>(numPlayers, 0, renderer, screen, asset, lang, input, false, options, section);
|
||||
game = std::make_unique<Game>(numPlayers, 0, renderer, screen, asset, lang, input, false, section);
|
||||
break;
|
||||
}
|
||||
case ActiveSection::None:
|
||||
@@ -733,7 +565,7 @@ SDL_AppResult Director::iterate() {
|
||||
#endif
|
||||
|
||||
// Actualiza la visibilidad del cursor del ratón
|
||||
Mouse::updateCursorVisibility(options->videoMode != 0);
|
||||
Mouse::updateCursorVisibility(Options::video.fullscreen);
|
||||
|
||||
// Gestiona las transiciones entre secciones
|
||||
handleSectionTransition();
|
||||
@@ -789,7 +621,7 @@ SDL_AppResult Director::handleEvent(SDL_Event *event) {
|
||||
}
|
||||
|
||||
// Gestiona la visibilidad del cursor según el movimiento del ratón
|
||||
Mouse::handleEvent(*event, options->videoMode != 0);
|
||||
Mouse::handleEvent(*event, Options::video.fullscreen);
|
||||
|
||||
// Reenvía el evento a la sección activa
|
||||
switch (activeSection) {
|
||||
@@ -812,103 +644,3 @@ SDL_AppResult Director::handleEvent(SDL_Event *event) {
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
// Asigna variables a partir de dos cadenas
|
||||
bool Director::setOptions(options_t *options, std::string var, std::string value) {
|
||||
// Indicador de éxito en la asignación
|
||||
bool success = true;
|
||||
|
||||
// Opciones de video
|
||||
if (var == "videoMode") {
|
||||
if (value == "SDL_WINDOW_FULLSCREEN" || value == "SDL_WINDOW_FULLSCREEN_DESKTOP") {
|
||||
options->videoMode = SDL_WINDOW_FULLSCREEN;
|
||||
} else {
|
||||
options->videoMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
else if (var == "windowSize") {
|
||||
options->windowSize = std::stoi(value);
|
||||
if ((options->windowSize < 1) || (options->windowSize > 4)) {
|
||||
options->windowSize = 3;
|
||||
}
|
||||
}
|
||||
|
||||
else if (var == "filter") {
|
||||
if (value == "FILTER_LINEAL") {
|
||||
options->filter = FILTER_LINEAL;
|
||||
} else {
|
||||
options->filter = FILTER_NEAREST;
|
||||
}
|
||||
}
|
||||
|
||||
else if (var == "vSync") {
|
||||
options->vSync = stringToBool(value);
|
||||
}
|
||||
|
||||
else if (var == "integerScale") {
|
||||
options->integerScale = stringToBool(value);
|
||||
}
|
||||
|
||||
else if (var == "keepAspect") {
|
||||
options->keepAspect = stringToBool(value);
|
||||
}
|
||||
|
||||
else if (var == "borderEnabled") {
|
||||
options->borderEnabled = stringToBool(value);
|
||||
}
|
||||
|
||||
else if (var == "borderWidth") {
|
||||
options->borderWidth = std::stoi(value);
|
||||
}
|
||||
|
||||
else if (var == "borderHeight") {
|
||||
options->borderHeight = std::stoi(value);
|
||||
}
|
||||
|
||||
// Opciones de GPU / shaders
|
||||
else if (var == "videoGpuAcceleration") {
|
||||
options->videoGpuAcceleration = stringToBool(value);
|
||||
}
|
||||
|
||||
else if (var == "videoGpuPreferredDriver") {
|
||||
options->videoGpuPreferredDriver = value;
|
||||
}
|
||||
|
||||
else if (var == "videoShaderEnabled") {
|
||||
options->videoShaderEnabled = stringToBool(value);
|
||||
}
|
||||
|
||||
else if (var == "videoShaderType") {
|
||||
options->videoShaderType = std::stoi(value);
|
||||
if (options->videoShaderType < 0 || options->videoShaderType > 1) {
|
||||
options->videoShaderType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Opciones varias
|
||||
else if (var == "language") {
|
||||
options->language = std::stoi(value);
|
||||
}
|
||||
|
||||
else if (var == "difficulty") {
|
||||
options->difficulty = std::stoi(value);
|
||||
}
|
||||
|
||||
else if (var == "input0") {
|
||||
options->input[0].deviceType = std::stoi(value);
|
||||
}
|
||||
|
||||
else if (var == "input1") {
|
||||
options->input[1].deviceType = std::stoi(value);
|
||||
}
|
||||
|
||||
// Lineas vacias o que empiezan por comentario
|
||||
else if (var == "" || var.substr(0, 1) == "#") {
|
||||
}
|
||||
|
||||
else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
Reference in New Issue
Block a user