803 lines
23 KiB
C++
803 lines
23 KiB
C++
#include "director.h"
|
||
#include <SDL2/SDL.h> // for SDL_Init, SDL_Quit, SDL_INIT_EV...
|
||
#include <SDL2/SDL_audio.h> // for AUDIO_S16
|
||
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
|
||
#include <SDL2/SDL_error.h> // for SDL_GetError
|
||
#include <SDL2/SDL_gamecontroller.h> // for SDL_CONTROLLER_BUTTON_B, SDL_CO...
|
||
#include <SDL2/SDL_hints.h> // for SDL_SetHint, SDL_HINT_RENDER_SC...
|
||
#include <SDL2/SDL_scancode.h> // for SDL_SCANCODE_ESCAPE, SDL_SCANCO...
|
||
#include <SDL2/SDL_stdinc.h> // for Uint32
|
||
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
|
||
#include <errno.h> // for errno, EEXIST, EACCES, ENAMETOO...
|
||
#include <stdio.h> // for printf, perror
|
||
#include <string.h> // for strcmp
|
||
#include <sys/stat.h> // for mkdir, stat, S_IRWXU
|
||
#include <unistd.h> // for getuid
|
||
#include <cstdlib> // for exit, EXIT_FAILURE, srand
|
||
#include <fstream> // for basic_ostream, operator<<, basi...
|
||
#include <iostream> // for cout
|
||
#include <string> // for basic_string, operator+, char_t...
|
||
#include <vector> // for vector
|
||
#include <memory>
|
||
#include "asset.h" // for Asset, assetType
|
||
#include "const.h" // for SECTION_PROG_LOGO, GAMECANVAS_H...
|
||
#include "game.h" // for Game
|
||
#include "input.h" // for Input, inputs_e, INPUT_USE_GAME...
|
||
#include "intro.h" // for Intro
|
||
#include "jail_audio.h" // for JA_Init
|
||
#include "lang.h" // for Lang, MAX_LANGUAGES, ba_BA, en_UK
|
||
#include "logo.h" // for Logo
|
||
#include "screen.h" // for FILTER_NEAREST, Screen, FILTER_...
|
||
#include "title.h" // for Title
|
||
#include "utils.h" // for options_t, input_t, boolToString
|
||
|
||
#ifndef _WIN32
|
||
#include <pwd.h>
|
||
#endif
|
||
|
||
// Constructor
|
||
Director::Director(int argc, const char *argv[])
|
||
{
|
||
std::cout << "Game start" << std::endl;
|
||
// Inicializa variables
|
||
section = new section_t();
|
||
section->name = SECTION_PROG_LOGO;
|
||
|
||
// Inicializa las opciones del programa
|
||
initOptions();
|
||
|
||
// Comprueba los parametros del programa
|
||
checkProgramArguments(argc, argv);
|
||
|
||
// Crea la carpeta del sistema donde guardar datos
|
||
createSystemFolder("jailgames");
|
||
#ifndef DEBUG
|
||
createSystemFolder("jailgames/coffee_crisis");
|
||
#else
|
||
createSystemFolder("jailgames/coffee_crisis_debug");
|
||
#endif
|
||
|
||
// Crea el objeto que controla los ficheros de recursos
|
||
asset = new Asset(executablePath);
|
||
asset->setVerbose(options->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();
|
||
|
||
// Inicializa JailAudio
|
||
initJailAudio();
|
||
|
||
// Crea los objetos
|
||
lang = new Lang(asset);
|
||
lang->setLang(options->language);
|
||
|
||
input = new Input(asset->get("gamecontrollerdb.txt"));
|
||
initInput();
|
||
|
||
screen = new Screen(window, renderer, asset, options);
|
||
}
|
||
|
||
Director::~Director()
|
||
{
|
||
saveConfigFile();
|
||
|
||
delete asset;
|
||
delete input;
|
||
delete screen;
|
||
delete lang;
|
||
delete options;
|
||
delete section;
|
||
|
||
SDL_DestroyRenderer(renderer);
|
||
SDL_DestroyWindow(window);
|
||
|
||
SDL_Quit();
|
||
|
||
std::cout << "\nBye!" << std::endl;
|
||
}
|
||
|
||
// Inicializa el objeto input
|
||
void Director::initInput()
|
||
{
|
||
// Establece si ha de mostrar mensajes
|
||
input->setVerbose(options->console);
|
||
|
||
// Busca si hay un mando conectado
|
||
input->discoverGameController();
|
||
|
||
// Teclado - Movimiento del jugador
|
||
input->bindKey(input_up, SDL_SCANCODE_UP);
|
||
input->bindKey(input_down, SDL_SCANCODE_DOWN);
|
||
input->bindKey(input_left, SDL_SCANCODE_LEFT);
|
||
input->bindKey(input_right, SDL_SCANCODE_RIGHT);
|
||
input->bindKey(input_fire_left, SDL_SCANCODE_Q);
|
||
input->bindKey(input_fire_center, SDL_SCANCODE_W);
|
||
input->bindKey(input_fire_right, SDL_SCANCODE_E);
|
||
|
||
// Teclado - Otros
|
||
input->bindKey(input_accept, SDL_SCANCODE_RETURN);
|
||
input->bindKey(input_cancel, SDL_SCANCODE_ESCAPE);
|
||
input->bindKey(input_pause, SDL_SCANCODE_ESCAPE);
|
||
input->bindKey(input_exit, SDL_SCANCODE_ESCAPE);
|
||
input->bindKey(input_window_dec_size, SDL_SCANCODE_F1);
|
||
input->bindKey(input_window_inc_size, SDL_SCANCODE_F2);
|
||
input->bindKey(input_window_fullscreen, SDL_SCANCODE_F3);
|
||
|
||
// Mando - Movimiento del jugador
|
||
input->bindGameControllerButton(input_up, SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||
input->bindGameControllerButton(input_down, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||
input->bindGameControllerButton(input_left, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||
input->bindGameControllerButton(input_right, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||
input->bindGameControllerButton(input_fire_left, SDL_CONTROLLER_BUTTON_X);
|
||
input->bindGameControllerButton(input_fire_center, SDL_CONTROLLER_BUTTON_Y);
|
||
input->bindGameControllerButton(input_fire_right, SDL_CONTROLLER_BUTTON_B);
|
||
|
||
// Mando - Otros
|
||
input->bindGameControllerButton(input_accept, SDL_CONTROLLER_BUTTON_B);
|
||
input->bindGameControllerButton(input_cancel, SDL_CONTROLLER_BUTTON_A);
|
||
#ifdef GAME_CONSOLE
|
||
input->bindGameControllerButton(input_pause, SDL_CONTROLLER_BUTTON_BACK);
|
||
input->bindGameControllerButton(input_exit, SDL_CONTROLLER_BUTTON_START);
|
||
#else
|
||
input->bindGameControllerButton(input_pause, SDL_CONTROLLER_BUTTON_START);
|
||
input->bindGameControllerButton(input_exit, SDL_CONTROLLER_BUTTON_BACK);
|
||
#endif
|
||
}
|
||
|
||
// Inicializa JailAudio
|
||
void Director::initJailAudio()
|
||
{
|
||
JA_Init(48000, AUDIO_S16, 2);
|
||
}
|
||
|
||
// Arranca SDL y crea la ventana
|
||
bool Director::initSDL()
|
||
{
|
||
// Indicador de éxito
|
||
bool success = true;
|
||
|
||
// Inicializa SDL
|
||
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
|
||
// if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_AUDIO) < 0)
|
||
{
|
||
if (options->console)
|
||
{
|
||
std::cout << "SDL could not initialize!\nSDL Error: " << SDL_GetError() << std::endl;
|
||
}
|
||
success = false;
|
||
}
|
||
else
|
||
{
|
||
// Inicia el generador de numeros aleatorios
|
||
std::srand(static_cast<unsigned int>(SDL_GetTicks()));
|
||
|
||
// Establece el filtro de la textura
|
||
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str()))
|
||
{
|
||
if (options->console)
|
||
{
|
||
std::cout << "Warning: Nearest texture filtering not enabled!\n";
|
||
}
|
||
}
|
||
|
||
// 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, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (options->gameWidth + incW) * options->windowSize, (options->gameHeight + incH) * options->windowSize, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
|
||
if (window == nullptr)
|
||
{
|
||
if (options->console)
|
||
{
|
||
std::cout << "Window could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||
}
|
||
success = false;
|
||
}
|
||
else
|
||
{
|
||
// Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones
|
||
// Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones
|
||
// Uint32 flags = SDL_RENDERER_SOFTWARE;
|
||
// Uint32 flags = SDL_RENDERER_ACCELERATED;
|
||
Uint32 flags = 0;
|
||
if (options->vSync)
|
||
{
|
||
flags = flags | SDL_RENDERER_PRESENTVSYNC;
|
||
}
|
||
renderer = SDL_CreateRenderer(window, -1, flags);
|
||
|
||
if (renderer == nullptr)
|
||
{
|
||
if (options->console)
|
||
{
|
||
std::cout << "Renderer could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
||
}
|
||
success = false;
|
||
}
|
||
else
|
||
{
|
||
// Inicializa el color de renderizado
|
||
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
|
||
|
||
// Establece el tamaño del buffer de renderizado
|
||
SDL_RenderSetLogicalSize(renderer, options->gameWidth, options->gameHeight);
|
||
|
||
// Establece el modo de mezcla
|
||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (options->console)
|
||
{
|
||
std::cout << std::endl;
|
||
}
|
||
return success;
|
||
}
|
||
|
||
// Crea el indice de ficheros
|
||
bool Director::setFileList()
|
||
{
|
||
#ifdef MACOS_BUNDLE
|
||
const std::string prefix = "/../Resources";
|
||
#else
|
||
const std::string prefix = "";
|
||
#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/config/demo.bin", t_data);
|
||
asset->add(prefix + "/data/config/gamecontrollerdb.txt", t_data);
|
||
|
||
// Musicas
|
||
asset->add(prefix + "/data/music/intro.ogg", t_music);
|
||
asset->add(prefix + "/data/music/playing.ogg", t_music);
|
||
asset->add(prefix + "/data/music/title.ogg", t_music);
|
||
|
||
// Sonidos
|
||
asset->add(prefix + "/data/sound/balloon.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/bubble1.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/bubble2.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/bubble3.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/bubble4.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/bullet.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/coffeeout.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/hiscore.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/itemdrop.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/itempickup.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/menu_move.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/menu_select.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/player_collision.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/stage_change.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/title.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/clock.wav", t_sound);
|
||
asset->add(prefix + "/data/sound/powerball.wav", t_sound);
|
||
|
||
// Texturas
|
||
asset->add(prefix + "/data/gfx/balloon1.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/balloon1.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/balloon2.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/balloon2.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/balloon3.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/balloon3.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/balloon4.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/balloon4.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/bullet.png", t_bitmap);
|
||
|
||
asset->add(prefix + "/data/gfx/game_buildings.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/game_clouds.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/game_grass.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/game_power_meter.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/game_sky_colors.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/game_text.png", t_bitmap);
|
||
|
||
asset->add(prefix + "/data/gfx/intro.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/logo.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/menu_game_over.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/menu_game_over_end.png", t_bitmap);
|
||
|
||
asset->add(prefix + "/data/gfx/item_points1_disk.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/item_points1_disk.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/item_points2_gavina.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/item_points2_gavina.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/item_points3_pacmar.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/item_points3_pacmar.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/item_clock.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/item_clock.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/item_coffee.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/item_coffee.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/item_coffee_machine.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/item_coffee_machine.ani", t_data);
|
||
|
||
asset->add(prefix + "/data/gfx/title_bg_tile.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/title_coffee.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/title_crisis.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/title_dust.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/title_dust.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/title_gradient.png", t_bitmap);
|
||
|
||
asset->add(prefix + "/data/gfx/player_head.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/player_body.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/player_legs.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/player_death.ani", t_data);
|
||
asset->add(prefix + "/data/gfx/player_fire.ani", t_data);
|
||
|
||
asset->add(prefix + "/data/gfx/player_bal1_head.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_bal1_body.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_bal1_legs.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_bal1_death.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_bal1_fire.png", t_bitmap);
|
||
|
||
asset->add(prefix + "/data/gfx/player_arounder_head.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_arounder_body.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_arounder_legs.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_arounder_death.png", t_bitmap);
|
||
asset->add(prefix + "/data/gfx/player_arounder_fire.png", t_bitmap);
|
||
|
||
// Fuentes
|
||
asset->add(prefix + "/data/font/8bithud.png", t_font);
|
||
asset->add(prefix + "/data/font/8bithud.txt", t_font);
|
||
asset->add(prefix + "/data/font/nokia.png", t_font);
|
||
asset->add(prefix + "/data/font/nokia_big2.png", t_font);
|
||
asset->add(prefix + "/data/font/nokia.txt", t_font);
|
||
asset->add(prefix + "/data/font/nokia2.png", t_font);
|
||
asset->add(prefix + "/data/font/nokia2.txt", t_font);
|
||
asset->add(prefix + "/data/font/nokia_big2.txt", t_font);
|
||
asset->add(prefix + "/data/font/smb2_big.png", t_font);
|
||
asset->add(prefix + "/data/font/smb2_big.txt", t_font);
|
||
asset->add(prefix + "/data/font/smb2.png", t_font);
|
||
asset->add(prefix + "/data/font/smb2.txt", t_font);
|
||
|
||
// Textos
|
||
asset->add(prefix + "/data/lang/es_ES.txt", t_lang);
|
||
asset->add(prefix + "/data/lang/en_UK.txt", t_lang);
|
||
asset->add(prefix + "/data/lang/ba_BA.txt", t_lang);
|
||
|
||
// Menus
|
||
asset->add(prefix + "/data/menu/title.men", t_data);
|
||
asset->add(prefix + "/data/menu/title_gc.men", t_data);
|
||
asset->add(prefix + "/data/menu/options.men", t_data);
|
||
asset->add(prefix + "/data/menu/options_gc.men", t_data);
|
||
asset->add(prefix + "/data/menu/pause.men", t_data);
|
||
asset->add(prefix + "/data/menu/gameover.men", t_data);
|
||
asset->add(prefix + "/data/menu/player_select.men", t_data);
|
||
|
||
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;
|
||
}
|
||
|
||
// Comprueba los parametros del programa
|
||
void Director::checkProgramArguments(int argc, const char *argv[])
|
||
{
|
||
// Establece la ruta del programa
|
||
executablePath = argv[0];
|
||
|
||
// Comprueba el resto de parametros
|
||
for (int i = 1; i < argc; ++i)
|
||
{
|
||
if (strcmp(argv[i], "--console") == 0)
|
||
{
|
||
options->console = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Crea la carpeta del sistema donde guardar datos
|
||
void Director::createSystemFolder(const std::string &folder)
|
||
{
|
||
#ifdef _WIN32
|
||
systemFolder = std::string(getenv("APPDATA")) + "/" + folder;
|
||
#elif __APPLE__
|
||
struct passwd *pw = getpwuid(getuid());
|
||
const char *homedir = pw->pw_dir;
|
||
systemFolder = std::string(homedir) + "/Library/Application Support" + "/" + folder;
|
||
#elif __linux__
|
||
struct passwd *pw = getpwuid(getuid());
|
||
const char *homedir = pw->pw_dir;
|
||
systemFolder = std::string(homedir) + "/.config/" + folder;
|
||
|
||
{
|
||
// Intenta crear ".config", per si no existeix
|
||
std::string config_base_folder = std::string(homedir) + "/.config";
|
||
int ret = mkdir(config_base_folder.c_str(), S_IRWXU);
|
||
if (ret == -1 && errno != EEXIST)
|
||
{
|
||
printf("ERROR CREATING CONFIG BASE FOLDER.");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
}
|
||
#endif
|
||
|
||
struct stat st = {0};
|
||
if (stat(systemFolder.c_str(), &st) == -1)
|
||
{
|
||
errno = 0;
|
||
#ifdef _WIN32
|
||
int ret = mkdir(systemFolder.c_str());
|
||
#else
|
||
int ret = mkdir(systemFolder.c_str(), S_IRWXU);
|
||
#endif
|
||
|
||
if (ret == -1)
|
||
{
|
||
switch (errno)
|
||
{
|
||
case EACCES:
|
||
printf("the parent directory does not allow write");
|
||
exit(EXIT_FAILURE);
|
||
|
||
case EEXIST:
|
||
printf("pathname already exists");
|
||
exit(EXIT_FAILURE);
|
||
|
||
case ENAMETOOLONG:
|
||
printf("pathname is too long");
|
||
exit(EXIT_FAILURE);
|
||
|
||
default:
|
||
perror("mkdir");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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
|
||
const bool a = options->videoMode == 0;
|
||
const bool b = options->videoMode == SDL_WINDOW_FULLSCREEN;
|
||
const bool c = options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||
if (!(a || b || c))
|
||
{
|
||
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";
|
||
}
|
||
|
||
else if (options->videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
|
||
{
|
||
file << "videoMode=SDL_WINDOW_FULLSCREEN_DESKTOP\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";
|
||
|
||
// 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;
|
||
}
|
||
|
||
void Director::runLogo()
|
||
{
|
||
auto logo = std::make_unique<Logo>(renderer, screen, asset, input, section);
|
||
logo->run();
|
||
}
|
||
|
||
void Director::runIntro()
|
||
{
|
||
auto intro = std::make_unique<Intro>(renderer, screen, asset, input, lang, section);
|
||
intro->run();
|
||
}
|
||
|
||
void Director::runTitle()
|
||
{
|
||
auto title = std::make_unique<Title>(renderer, screen, input, asset, options, lang, section);
|
||
title->run();
|
||
}
|
||
|
||
void Director::runGame()
|
||
{
|
||
const int numPlayers = section->subsection == SUBSECTION_GAME_PLAY_1P ? 1 : 2;
|
||
auto game = std::make_unique<Game>(numPlayers, 0, renderer, screen, asset, lang, input, false, options, section);
|
||
game->run();
|
||
}
|
||
|
||
int Director::run()
|
||
{
|
||
// Bucle principal
|
||
while (section->name != SECTION_PROG_QUIT)
|
||
{
|
||
switch (section->name)
|
||
{
|
||
case SECTION_PROG_LOGO:
|
||
runLogo();
|
||
break;
|
||
|
||
case SECTION_PROG_INTRO:
|
||
runIntro();
|
||
break;
|
||
|
||
case SECTION_PROG_TITLE:
|
||
runTitle();
|
||
break;
|
||
|
||
case SECTION_PROG_GAME:
|
||
runGame();
|
||
break;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
// 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_DESKTOP")
|
||
{
|
||
options->videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||
}
|
||
else if (value == "SDL_WINDOW_FULLSCREEN")
|
||
{
|
||
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 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;
|
||
} |