diff --git a/source/cheevos.h b/source/cheevos.h index 1ba05e6..2a69c85 100644 --- a/source/cheevos.h +++ b/source/cheevos.h @@ -2,7 +2,7 @@ #include // Para string #include // Para vector class Screen; -struct options_t; +struct Options; // Struct para los logros struct Achievement diff --git a/source/const.h b/source/const.h index f95e0e4..d2586f9 100644 --- a/source/const.h +++ b/source/const.h @@ -5,9 +5,9 @@ #include "utils.h" // Textos -constexpr const char* WINDOW_CAPTION = "JailDoctor's Dilemma"; -constexpr const char* TEXT_COPYRIGHT = "@2022 JailDesigner"; -constexpr const char* VERSION = "0.7"; +constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma"; +constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner"; +constexpr const char *VERSION = "0.7"; // Tamaño de bloque constexpr int BLOCK = 8; @@ -45,5 +45,5 @@ constexpr int GAMECANVAS_FIRST_QUARTER_Y = GAMECANVAS_HEIGHT / 4; constexpr int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3; // Colores -const color_t borderColor = {0x27, 0x27, 0x36}; -const color_t black = {0xFF, 0xFF, 0xFF}; +const Color borderColor = {0x27, 0x27, 0x36}; +const Color black = {0xFF, 0xFF, 0xFF}; diff --git a/source/credits.cpp b/source/credits.cpp index bfda07a..182a129 100644 --- a/source/credits.cpp +++ b/source/credits.cpp @@ -31,12 +31,12 @@ Credits::Credits() sprite_ = new AnimatedSprite(renderer_, resource_->getAnimation("shine.ani")); // Inicializa variables - options.section.name = SECTION_CREDITS; - options.section.subsection = 0; + options.section.section = Section::CREDITS; + options.section.subsection = Subsection::NONE; sprite_->setRect({194, 174, 8, 8}); // Cambia el color del borde - screen_->setBorderColor(stringToColor(options.palette, "black")); + screen_->setBorderColor(stringToColor(options.video.palette, "black")); // Crea la textura para el texto que se escribe en pantalla text_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); @@ -93,11 +93,11 @@ void Credits::checkInput() void Credits::iniTexts() { std::string keys = ""; - if (options.keys == ctrl_cursor) + if (options.keys == ControlScheme::CURSOR) { keys = "CURSORS"; } - else if (options.keys == ctrl_opqa) + else if (options.keys == ControlScheme::OPQA) { keys = "O,P AND Q"; } @@ -108,62 +108,62 @@ void Credits::iniTexts() #ifndef GAME_CONSOLE texts_.clear(); - texts_.push_back({"", stringToColor(options.palette, "white")}); - texts_.push_back({"INSTRUCTIONS:", stringToColor(options.palette, "yellow")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); - texts_.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.palette, "white")}); - texts_.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.palette, "white")}); - texts_.push_back({"JAIL TO FINISH THEM", stringToColor(options.palette, "white")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); + texts_.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); + texts_.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.video.palette, "white")}); + texts_.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.video.palette, "white")}); + texts_.push_back({"JAIL TO FINISH THEM", stringToColor(options.video.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); - texts_.push_back({"KEYS:", stringToColor(options.palette, "yellow")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); - texts_.push_back({keys + " TO MOVE AND JUMP", stringToColor(options.palette, "white")}); - texts_.push_back({"M TO SWITCH THE MUSIC", stringToColor(options.palette, "white")}); - texts_.push_back({"H TO PAUSE THE GAME", stringToColor(options.palette, "white")}); - texts_.push_back({"F1-F2 TO CHANGE WINDOWS SIZE", stringToColor(options.palette, "white")}); - texts_.push_back({"F3 TO SWITCH TO FULLSCREEN", stringToColor(options.palette, "white")}); - texts_.push_back({"B TO TOOGLE THE BORDER SCREEN", stringToColor(options.palette, "white")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); + texts_.push_back({"KEYS:", stringToColor(options.video.palette, "yellow")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); + texts_.push_back({keys + " TO MOVE AND JUMP", stringToColor(options.video.palette, "white")}); + texts_.push_back({"M TO SWITCH THE MUSIC", stringToColor(options.video.palette, "white")}); + texts_.push_back({"H TO PAUSE THE GAME", stringToColor(options.video.palette, "white")}); + texts_.push_back({"F1-F2 TO CHANGE WINDOWS SIZE", stringToColor(options.video.palette, "white")}); + texts_.push_back({"F3 TO SWITCH TO FULLSCREEN", stringToColor(options.video.palette, "white")}); + texts_.push_back({"B TO TOOGLE THE BORDER SCREEN", stringToColor(options.video.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); - texts_.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.palette, "yellow")}); - texts_.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.palette, "yellow")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); + texts_.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.video.palette, "yellow")}); + texts_.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.video.palette, "yellow")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); - texts_.push_back({"I LOVE JAILGAMES! ", stringToColor(options.palette, "white")}); - texts_.push_back({"", stringToColor(options.palette, "white")}); + texts_.push_back({"I LOVE JAILGAMES! ", stringToColor(options.video.palette, "white")}); + texts_.push_back({"", stringToColor(options.video.palette, "white")}); #else texts.clear(); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"INSTRUCTIONS:", stringToColor(options.palette, "yellow")}); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.palette, "white")}); - texts.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.palette, "white")}); - texts.push_back({"JAIL TO FINISH THEM", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"HELP JAILDOC TO GET BACK ALL", stringToColor(options.video.palette, "white")}); + texts.push_back({"HIS PROJECTS AND GO TO THE", stringToColor(options.video.palette, "white")}); + texts.push_back({"JAIL TO FINISH THEM", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); - texts.push_back({"KEYS:", stringToColor(options.palette, "yellow")}); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"B TO JUMP", stringToColor(options.palette, "white")}); - texts.push_back({"R TO SWITCH THE MUSIC", stringToColor(options.palette, "white")}); - texts.push_back({"L TO SWAP THE COLOR PALETTE", stringToColor(options.palette, "white")}); - texts.push_back({"START TO PAUSE", stringToColor(options.palette, "white")}); - texts.push_back({"SELECT TO EXIT", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); + texts.push_back({"KEYS:", stringToColor(options.video.palette, "yellow")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"B TO JUMP", stringToColor(options.video.palette, "white")}); + texts.push_back({"R TO SWITCH THE MUSIC", stringToColor(options.video.palette, "white")}); + texts.push_back({"L TO SWAP THE COLOR PALETTE", stringToColor(options.video.palette, "white")}); + texts.push_back({"START TO PAUSE", stringToColor(options.video.palette, "white")}); + texts.push_back({"SELECT TO EXIT", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); - texts.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.palette, "yellow")}); - texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.palette, "yellow")}); - texts.push_back({"", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); + texts.push_back({"A GAME BY JAILDESIGNER", stringToColor(options.video.palette, "yellow")}); + texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options.video.palette, "yellow")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); - texts.push_back({"I LOVE JAILGAMES! ", stringToColor(options.palette, "white")}); - texts.push_back({"", stringToColor(options.palette, "white")}); + texts.push_back({"I LOVE JAILGAMES! ", stringToColor(options.video.palette, "white")}); + texts.push_back({"", stringToColor(options.video.palette, "white")}); #endif } @@ -175,7 +175,7 @@ void Credits::fillTexture() // Rellena la textura de texto SDL_SetRenderTarget(renderer_, text_texture_); - color_t c = stringToColor(options.palette, "black"); + Color c = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_RenderClear(renderer_); @@ -192,7 +192,7 @@ void Credits::fillTexture() // Escribe el corazón const int textLenght = text_->lenght(texts_[22].label, 1) - text_->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio const int posX = ((PLAY_AREA_WIDTH - textLenght) / 2) + textLenght; - text_->writeColored(posX, 176, "}", stringToColor(options.palette, "bright_red")); + text_->writeColored(posX, 176, "}", stringToColor(options.video.palette, "bright_red")); // Recoloca el sprite del brillo sprite_->setPosX(posX + 2); @@ -249,7 +249,7 @@ void Credits::updateCounter() // Comprueba si ha terminado la sección if (counter_ > 1200) { - options.section.name = SECTION_DEMO; + options.section.section = Section::DEMO; } } @@ -309,7 +309,7 @@ void Credits::render() // Bucle para el logo del juego void Credits::run() { - while (options.section.name == SECTION_CREDITS) + while (options.section.section == Section::CREDITS) { update(); checkEvents(); @@ -320,6 +320,6 @@ void Credits::run() // Cambia la paleta void Credits::switchPalette() { - options.palette = options.palette == p_zxspectrum ? p_zxarne : p_zxspectrum; + options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM; fillTexture(); } \ No newline at end of file diff --git a/source/credits.h b/source/credits.h index 1c021aa..5d5f6d5 100644 --- a/source/credits.h +++ b/source/credits.h @@ -19,7 +19,7 @@ private: struct captions_t { std::string label; // Texto a escribir - color_t color; // Color del texto + Color color; // Color del texto }; // Objetos y punteros diff --git a/source/debug.cpp b/source/debug.cpp index 89b992f..857edd4 100644 --- a/source/debug.cpp +++ b/source/debug.cpp @@ -13,19 +13,19 @@ Debug *Debug::debug_ = nullptr; // [SINGLETON] Crearemos el objeto con esta función estática void Debug::init() { - Debug::debug_ = new Debug(); + Debug::debug_ = new Debug(); } // [SINGLETON] Destruiremos el objeto con esta función estática void Debug::destroy() { - delete Debug::debug_; + delete Debug::debug_; } // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él Debug *Debug::get() { - return Debug::debug_; + return Debug::debug_; } // Constructor @@ -73,7 +73,7 @@ void Debug::render() y = 0; for (auto l : log_) { - text_->writeColored(x_ + 10, y, l, color_t(255, 255, 255)); + text_->writeColored(x_ + 10, y, l, Color(255, 255, 255)); y += text_->getCharacterSize() + 1; } } diff --git a/source/demo.cpp b/source/demo.cpp index f653c15..89373d9 100644 --- a/source/demo.cpp +++ b/source/demo.cpp @@ -53,12 +53,12 @@ Demo::Demo() board.lives = 9; board.items = 0; board.rooms = 1; - board.jailEnabled = false; + board.jail_is_open = false; board.music = true; setScoreBoardColor(); - options.section.name = SECTION_DEMO; - options.section.subsection = 0; + options.section.section = Section::DEMO; + options.section.subsection = Subsection::NONE; } Demo::~Demo() @@ -89,7 +89,7 @@ void Demo::checkInput() // Bucle para el juego void Demo::run() { - while (options.section.name == SECTION_DEMO) + while (options.section.section == Section::DEMO) { update(); checkEvents(); @@ -142,7 +142,7 @@ void Demo::renderRoomName() { // Texto en el centro de la pantalla SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; - color_t color = stringToColor(options.palette, "white"); + Color color = stringToColor(options.video.palette, "white"); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_RenderFillRect(renderer, &rect); @@ -165,13 +165,13 @@ void Demo::reLoadTextures() void Demo::switchPalette() { // Modifica la variable - if (options.palette == p_zxspectrum) + if (options.video.palette == Palette::ZXSPECTRUM) { - options.palette = p_zxarne; + options.video.palette = Palette::ZXARNE; } else { - options.palette = p_zxspectrum; + options.video.palette = Palette::ZXSPECTRUM; } room->reLoadPalette(); @@ -215,8 +215,8 @@ void Demo::checkRoomChange() roomIndex++; if (roomIndex == (int)rooms.size()) { - options.section.name = SECTION_LOGO; - options.section.subsection = SUBSECTION_LOGO_TO_TITLE; + options.section.section = Section::LOGO; + options.section.subsection = Subsection::LOGO_TO_TITLE; } else { @@ -229,13 +229,13 @@ void Demo::checkRoomChange() void Demo::setScoreBoardColor() { // Obtiene el color del borde - const color_t c = room->getBorderColor(); + const Color color = room->getBorderColor(); // Si el color es negro lo cambia a blanco - const color_t cBlack = stringToColor(options.palette, "black"); - board.color = colorAreEqual(c, cBlack) ? stringToColor(options.palette, "white") : c; + const Color black_color = stringToColor(options.video.palette, "black"); + board.color = colorAreEqual(color, black_color) ? stringToColor(options.video.palette, "white") : color; // Si el color es negro brillante lo cambia a blanco - const color_t cBrightBlack = stringToColor(options.palette, "bright_black"); - board.color = colorAreEqual(c, cBrightBlack) ? stringToColor(options.palette, "white") : c; + const Color bright_blac_color = stringToColor(options.video.palette, "bright_black"); + board.color = colorAreEqual(color, bright_blac_color) ? stringToColor(options.video.palette, "white") : color; } \ No newline at end of file diff --git a/source/demo.h b/source/demo.h index 5e54e5f..a0eb46f 100644 --- a/source/demo.h +++ b/source/demo.h @@ -14,8 +14,8 @@ class Resource; class Room; class Screen; class Text; -struct options_t; -struct section_t; +struct Options; +struct SectionState; class Demo { diff --git a/source/director.cpp b/source/director.cpp index 6819eea..828580a 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -20,7 +20,7 @@ #include // Para vector #include // Para std::make_unique #include "asset.h" // Para Asset, assetType -#include "const.h" // Para SECTION_LOGO, SECTION_TITLE +#include "const.h" // Para Section::LOGO, Section::TITLE #include "debug.h" // Para Debug #include "credits.h" // Para Credits #include "demo.h" // Para Demo @@ -126,22 +126,25 @@ std::string Director::checkProgramArguments(int argc, const char *argv[]) else if (strcmp(argv[i], "--infiniteLives") == 0) { - options.cheat.infiniteLives = true; + options.cheats.infinite_lives = Cheat::CheatState::ENABLED; } else if (strcmp(argv[i], "--invincible") == 0) { - options.cheat.invincible = true; + options.cheats.invincible = Cheat::CheatState::ENABLED; + ; } else if (strcmp(argv[i], "--jailEnabled") == 0) { - options.cheat.jailEnabled = true; + options.cheats.jail_is_open = Cheat::CheatState::ENABLED; + ; } else if (strcmp(argv[i], "--altSkin") == 0) { - options.cheat.altSkin = true; + options.cheats.alternate_skin = Cheat::CheatState::ENABLED; + ; } } @@ -209,14 +212,14 @@ void Director::createSystemFolder(const std::string &folder) } // Carga los recursos -void Director::loadResources(section_t section) +void Director::loadResources(SectionState section) { if (options.console) { std::cout << "** LOAD RESOURCES" << std::endl; } - if (options.section.name == SECTION_LOGO) + if (options.section.section == Section::LOGO) { std::vector textureList; textureList.push_back("jailgames.png"); @@ -225,7 +228,7 @@ void Director::loadResources(section_t section) Resource::get()->loadTextures(textureList); } - else if (options.section.name == SECTION_LOADING_SCREEN) + else if (options.section.section == Section::LOADING_SCREEN) { std::vector textureList; textureList.push_back("loading_screen_bn.png"); @@ -236,7 +239,7 @@ void Director::loadResources(section_t section) Resource::get()->loadTextures(textureList); } - else if (options.section.name == SECTION_TITLE) + else if (options.section.section == Section::TITLE) { std::vector textureList; textureList.push_back("loading_screen_color.png"); @@ -256,7 +259,7 @@ void Director::loadResources(section_t section) Resource::get()->loadOffsets(offsetsList); } - else if (options.section.name == SECTION_CREDITS) + else if (options.section.section == Section::CREDITS) { // Texturas std::vector textureList; @@ -278,7 +281,7 @@ void Director::loadResources(section_t section) Resource::get()->loadOffsets(offsetsList); } - else if (options.section.name == SECTION_ENDING) + else if (options.section.section == Section::ENDING) { // Texturas std::vector textureList; @@ -303,7 +306,7 @@ void Director::loadResources(section_t section) Resource::get()->loadOffsets(offsetsList); } - else if (options.section.name == SECTION_ENDING2) + else if (options.section.section == Section::ENDING2) { // Texturas std::vector textureList; @@ -441,7 +444,7 @@ void Director::loadResources(section_t section) Resource::get()->loadOffsets(offsetsList); } - else if (options.section.name == SECTION_GAME_OVER) + else if (options.section.section == Section::GAME_OVER) { // Texturas std::vector textureList; @@ -465,20 +468,13 @@ void Director::loadResources(section_t section) Resource::get()->loadOffsets(offsetsList); } - else if (options.section.name == SECTION_GAME || options.section.name == SECTION_DEMO) + else if (options.section.section == Section::GAME || options.section.section == Section::DEMO) { // Texturas std::vector textureList; // Jugador - if (options.cheat.altSkin) - { - textureList.push_back("player2.png"); - } - else - { - textureList.push_back("player.png"); - } + textureList.push_back(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"); // Tilesets textureList.push_back("standard.png"); @@ -556,14 +552,7 @@ void Director::loadResources(section_t section) std::vector animationList; // Jugador - if (options.cheat.altSkin) - { - animationList.push_back("player2.ani"); - } - else - { - animationList.push_back("player.ani"); - } + animationList.push_back(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani"); // Enemigos animationList.push_back("abad_bell.ani"); @@ -780,7 +769,7 @@ void Director::initInput() Input::get()->discoverGameController(); // Teclado - Movimiento - if (options.keys == ctrl_cursor) + if (options.keys == ControlScheme::CURSOR) { Input::get()->bindKey(input_jump, SDL_SCANCODE_UP); Input::get()->bindKey(input_left, SDL_SCANCODE_LEFT); @@ -788,7 +777,7 @@ void Director::initInput() Input::get()->bindKey(input_up, SDL_SCANCODE_UP); Input::get()->bindKey(input_down, SDL_SCANCODE_DOWN); } - else if (options.keys == ctrl_opqa) + else if (options.keys == ControlScheme::OPQA) { Input::get()->bindKey(input_jump, SDL_SCANCODE_Q); Input::get()->bindKey(input_left, SDL_SCANCODE_O); @@ -796,7 +785,7 @@ void Director::initInput() Input::get()->bindKey(input_up, SDL_SCANCODE_Q); Input::get()->bindKey(input_down, SDL_SCANCODE_A); } - else if (options.keys == ctrl_wasd) + else if (options.keys == ControlScheme::WASD) { Input::get()->bindKey(input_jump, SDL_SCANCODE_W); Input::get()->bindKey(input_left, SDL_SCANCODE_A); @@ -865,7 +854,7 @@ bool Director::initSDL() std::srand(static_cast(SDL_GetTicks())); // Establece el filtro de la textura a nearest - if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options.filter).c_str())) + if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(static_cast(options.video.filter)).c_str())) { if (options.console) { @@ -880,15 +869,10 @@ bool Director::initSDL() } // Crea la ventana - int incW = 0; - int incH = 0; - if (options.borderEnabled) - { - incW = options.borderWidth * 2; - incH = options.borderHeight * 2; - } + options.window.width = options.video.border.enabled ? options.game.width + options.video.border.width * 2 : options.game.width; + options.window.height = options.video.border.enabled ? options.game.height + options.video.border.height * 2 : options.game.height; - window_ = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (options.gameWidth + incW) * options.windowSize, (options.gameHeight + incH) * options.windowSize, SDL_WINDOW_HIDDEN); + window_ = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, options.window.width, options.window.height, SDL_WINDOW_HIDDEN); if (window_ == nullptr) { if (options.console) @@ -901,7 +885,7 @@ bool Director::initSDL() { // Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones Uint32 flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; - if (options.vSync) + if (options.video.vertical_sync) { flags = flags | SDL_RENDERER_PRESENTVSYNC; } @@ -921,7 +905,7 @@ bool Director::initSDL() SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); // Establece el tamaño del buffer de renderizado - SDL_RenderSetLogicalSize(renderer_, options.gameWidth, options.gameHeight); + SDL_RenderSetLogicalSize(renderer_, options.game.width, options.game.height); // Establece el modo de mezcla SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); @@ -1421,45 +1405,48 @@ void Director::runGame() int Director::run() { // Bucle principal - while (options.section.name != SECTION_QUIT) + while (options.section.section != Section::QUIT) { - switch (options.section.name) + switch (options.section.section) { - case SECTION_LOGO: + case Section::LOGO: runLogo(); break; - case SECTION_LOADING_SCREEN: + case Section::LOADING_SCREEN: runLoadingScreen(); break; - case SECTION_TITLE: + case Section::TITLE: runTitle(); break; - case SECTION_CREDITS: + case Section::CREDITS: runCredits(); break; - case SECTION_DEMO: + case Section::DEMO: runDemo(); break; - case SECTION_GAME: + case Section::GAME: runGame(); break; - case SECTION_GAME_OVER: + case Section::GAME_OVER: runGameOver(); break; - case SECTION_ENDING: + case Section::ENDING: runEnding(); break; - case SECTION_ENDING2: + case Section::ENDING2: runEnding2(); break; + + default: + break; } } diff --git a/source/director.h b/source/director.h index 55aa335..58c55bb 100644 --- a/source/director.h +++ b/source/director.h @@ -9,8 +9,8 @@ class Input; // lines 14-14 class Resource; // lines 17-17 class Screen; // lines 18-18 struct JA_Music_t; // lines 20-20 -struct options_t; // lines 21-21 -struct section_t; // lines 22-22 +struct Options; // lines 21-21 +struct SectionState; // lines 22-22 class Director { @@ -31,7 +31,7 @@ private: void createSystemFolder(const std::string &folder); // Carga los recursos - void loadResources(section_t section); + void loadResources(SectionState section); // Inicializa jail_audio void initJailAudio(); diff --git a/source/ending.cpp b/source/ending.cpp index 002c941..822a32a 100644 --- a/source/ending.cpp +++ b/source/ending.cpp @@ -36,8 +36,8 @@ Ending::Ending() counter = -1; preCounter = 0; coverCounter = 0; - options.section.name = SECTION_ENDING; - options.section.subsection = 0; + options.section.section = Section::ENDING; + options.section.subsection = Subsection::NONE; ticks = 0; ticksSpeed = 15; scene = 0; @@ -52,7 +52,7 @@ Ending::Ending() iniScenes(); // Cambia el color del borde - screen->setBorderColor(stringToColor(options.palette, "black")); + screen->setBorderColor(stringToColor(options.video.palette, "black")); // Crea la textura para cubrir el rexto coverTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8); @@ -131,7 +131,7 @@ void Ending::render() screen->start(); // Limpia la pantalla - screen->clean(stringToColor(options.palette, "black")); + screen->clean(stringToColor(options.video.palette, "black")); // Dibuja las imagenes de la escena spritePics[scene].sprite->render(); @@ -150,8 +150,6 @@ void Ending::render() // Dibuja la cortinilla de cambio de escena renderCoverTexture(); - // text->write(0, 0, std::to_string(counter)); - // Vuelca el contenido del renderizador en pantalla screen->render(); } @@ -222,7 +220,7 @@ void Ending::iniTexts() endingTexture_t st; const int width = text->lenght(t.caption, 1) + 2 + 2; const int height = text->getCharacterSize() + 2 + 2; - color_t c = stringToColor(options.palette, "black"); + Color c = stringToColor(options.video.palette, "black"); // Crea la texture st.texture = new Texture(renderer); @@ -246,7 +244,7 @@ void Ending::iniTexts() SDL_RenderClear(renderer); // Los primeros 8 pixels crea una malla - c = stringToColor(options.palette, "black"); + c = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); for (int i = 0; i < width; i += 2) { @@ -261,7 +259,7 @@ void Ending::iniTexts() // El resto se rellena de color sólido SDL_Rect rect = {0, 8, width, height}; - c = stringToColor(options.palette, "black"); + c = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_RenderFillRect(renderer, &rect); @@ -284,7 +282,7 @@ void Ending::iniPics() // Vector con las rutas y la posición std::vector pics; - if (options.palette == p_zxspectrum) + if (options.video.palette == Palette::ZXSPECTRUM) { pics.push_back({"ending1.png", 48}); pics.push_back({"ending2.png", 26}); @@ -334,7 +332,7 @@ void Ending::iniPics() SDL_RenderClear(renderer); // Los primeros 8 pixels crea una malla - color_t c = stringToColor(options.palette, "black"); + Color c = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); for (int i = 0; i < width; i += 2) { @@ -349,7 +347,7 @@ void Ending::iniPics() // El resto se rellena de color sólido SDL_Rect rect = {0, 8, width, height}; - c = stringToColor(options.palette, "black"); + c = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); SDL_RenderFillRect(renderer, &rect); @@ -454,7 +452,7 @@ void Ending::run() { JA_PlayMusic(music); - while (options.section.name == SECTION_ENDING) + while (options.section.section == Section::ENDING) { update(); checkEvents(); @@ -538,7 +536,7 @@ void Ending::checkChangeScene() if (scene == 5) { // Termina el bucle - options.section.name = SECTION_ENDING2; + options.section.section = Section::ENDING2; // Mantiene los valores anteriores scene = 4; @@ -556,8 +554,8 @@ void Ending::fillCoverTexture() SDL_RenderClear(renderer); // Los primeros 8 pixels crea una malla - const color_t c = stringToColor(options.palette, "brack"); - SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); + const Color color = stringToColor(options.video.palette, "black"); + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); for (int i = 0; i < 256; i += 2) { SDL_RenderDrawPoint(renderer, i + 0, GAMECANVAS_HEIGHT + 0); @@ -597,29 +595,4 @@ void Ending::updateMusicVolume() const int volume = 128 * step; JA_SetVolume(volume); } -} - -// Cambia la paleta -void Ending::switchPalette() -{ - if (options.palette == p_zxspectrum) - { - options.palette = p_zxarne; - - spritePics[0].sprite->setTexture(resource->getTexture("ending1_zxarne.png")); - spritePics[1].sprite->setTexture(resource->getTexture("ending2_zxarne.png")); - spritePics[2].sprite->setTexture(resource->getTexture("ending3_zxarne.png")); - spritePics[3].sprite->setTexture(resource->getTexture("ending4_zxarne.png")); - spritePics[4].sprite->setTexture(resource->getTexture("ending5_zxarne.png")); - } - else - { - options.palette = p_zxspectrum; - - spritePics[0].sprite->setTexture(resource->getTexture("ending1.png")); - spritePics[1].sprite->setTexture(resource->getTexture("ending2.png")); - spritePics[2].sprite->setTexture(resource->getTexture("ending3.png")); - spritePics[3].sprite->setTexture(resource->getTexture("ending4.png")); - spritePics[4].sprite->setTexture(resource->getTexture("ending5.png")); - } } \ No newline at end of file diff --git a/source/ending.h b/source/ending.h index 10d34dc..d80e283 100644 --- a/source/ending.h +++ b/source/ending.h @@ -13,8 +13,8 @@ class Sprite; class Text; class Texture; struct JA_Music_t; -struct options_t; -struct section_t; +struct Options; +struct SectionState; class Ending { @@ -109,9 +109,6 @@ private: // Actualiza el volumen de la musica void updateMusicVolume(); - // Cambia la paleta - void switchPalette(); - public: // Constructor Ending(); diff --git a/source/ending2.cpp b/source/ending2.cpp index cfa7813..9ec4e50 100644 --- a/source/ending2.cpp +++ b/source/ending2.cpp @@ -34,8 +34,8 @@ Ending2::Ending2() preCounter = 0; postCounter = 0; postCounterEnabled = false; - options.section.name = SECTION_ENDING2; - options.section.subsection = 0; + options.section.section = Section::ENDING2; + options.section.subsection = Subsection::NONE; ticks = 0; ticksSpeed = 15; distSpriteText = 8; @@ -45,14 +45,14 @@ Ending2::Ending2() secondCol = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Inicializa el vector de colores - const std::vector colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; - for (auto cl : colorList) + const std::vector color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; + for (auto color : color_list) { - colors.push_back(stringToColor(options.palette, cl)); + colors.push_back(stringToColor(options.video.palette, color)); } // Cambia el color del borde - screen->setBorderColor(stringToColor(options.palette, "black")); + screen->setBorderColor(stringToColor(options.video.palette, "black")); // Inicializa la lista de sprites iniSpriteList(); @@ -126,7 +126,7 @@ void Ending2::render() screen->start(); // Limpia la pantalla - screen->clean(stringToColor(options.palette, "black")); + screen->clean(stringToColor(options.video.palette, "black")); // Dibuja los sprites renderSprites(); @@ -207,7 +207,7 @@ void Ending2::run() { JA_PlayMusic(music); - while (options.section.name == SECTION_ENDING2) + while (options.section.section == Section::ENDING2) { update(); checkEvents(); @@ -238,8 +238,8 @@ void Ending2::updateCounters() if (postCounter > 600) { - options.section.name = SECTION_LOGO; - options.section.subsection = SUBSECTION_LOGO_TO_INTRO; + options.section.section = Section::LOGO; + options.section.subsection = Subsection::LOGO_TO_INTRO; } } @@ -377,7 +377,7 @@ void Ending2::updateTexts() // Dibuja los sprites void Ending2::renderSprites() { - const color_t color = stringToColor(options.palette, "red"); + const Color color = stringToColor(options.video.palette, "red"); for (auto sprite : sprites) { const bool a = sprite->getRect().y + sprite->getRect().h > 0; @@ -390,7 +390,7 @@ void Ending2::renderSprites() } // Pinta el ultimo elemento de otro color - const color_t c = stringToColor(options.palette, "white"); + const Color c = stringToColor(options.video.palette, "white"); sprites.back()->getTexture()->setColor(c.r, c.g, c.b); sprites.back()->render(); } @@ -398,7 +398,7 @@ void Ending2::renderSprites() // Dibuja los sprites con el texto void Ending2::renderSpriteTexts() { - const color_t color = stringToColor(options.palette, "white"); + const Color color = stringToColor(options.video.palette, "white"); for (auto sprite : spriteTexts) { const bool a = sprite->getRect().y + sprite->getRect().h > 0; @@ -600,10 +600,4 @@ void Ending2::updateMusicVolume() const int volume = 128 * step; JA_SetVolume(volume); } -} - -// Cambia la paleta -void Ending2::switchPalette() -{ - options.palette = (options.palette == p_zxspectrum) ? p_zxarne : p_zxspectrum; } \ No newline at end of file diff --git a/source/ending2.h b/source/ending2.h index 59f7529..b68dd79 100644 --- a/source/ending2.h +++ b/source/ending2.h @@ -13,9 +13,9 @@ class Resource; // lines 13-13 class Screen; // lines 14-14 class Text; // lines 15-15 struct JA_Music_t; // lines 16-16 -struct color_t; -struct options_t; -struct section_t; +struct Color; +struct Options; +struct SectionState; class Ending2 { @@ -40,7 +40,7 @@ private: Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa JA_Music_t *music; // Musica que suena durante el final std::vector spriteList; // Lista con todos los sprites a dibujar - std::vector colors; // Vector con los colores para el fade + std::vector colors; // Vector con los colores para el fade int maxSpriteWidth; // El valor de ancho del sprite mas ancho int maxSpriteHeight; // El valor de alto del sprite mas alto int distSpriteText; // Distancia entre el sprite y el texto que lo acompaña @@ -112,9 +112,6 @@ private: // Actualiza el volumen de la musica void updateMusicVolume(); - // Cambia la paleta - void switchPalette(); - public: // Constructor Ending2(); diff --git a/source/enemy.cpp b/source/enemy.cpp index 5b4db0f..84f1051 100644 --- a/source/enemy.cpp +++ b/source/enemy.cpp @@ -137,7 +137,7 @@ void Enemy::reLoadTexture() } // Asigna la paleta -void Enemy::setPalette(palette_e pal) +void Enemy::setPalette(Palette pal) { palette = pal; color = stringToColor(palette, colorString); diff --git a/source/enemy.h b/source/enemy.h index 714f5ad..62e63d4 100644 --- a/source/enemy.h +++ b/source/enemy.h @@ -27,7 +27,7 @@ struct enemy_t bool mirror; // Indica si el enemigo está volteado verticalmente int frame; // Frame inicial para la animación del enemigo std::string color; // Color del enemigo - palette_e palette; // Paleta de colores + Palette palette; // Paleta de colores }; class Enemy @@ -37,9 +37,9 @@ private: AnimatedSprite *sprite; // Sprite del enemigo // Variables - color_t color; // Color del enemigo + Color color; // Color del enemigo std::string colorString; // Color del enemigo en formato texto - palette_e palette; // Paleta de colores + Palette palette; // Paleta de colores int x1; // Limite izquierdo de la ruta en el eje X int x2; // Limite derecho de la ruta en el eje X int y1; // Limite superior de la ruta en el eje Y @@ -74,5 +74,5 @@ public: void reLoadTexture(); // Asigna la paleta - void setPalette(palette_e pal); + void setPalette(Palette pal); }; diff --git a/source/game.cpp b/source/game.cpp index c89caf0..75da5f9 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -55,8 +55,8 @@ Game::Game() item_tracker_ = new ItemTracker(); room_tracker_ = new RoomTracker(); room_ = new Room(resource_->getRoom(current_room_), item_tracker_, &board_.items, false); - const std::string playerPNG = options.cheat.altSkin ? "player2.png" : "player.png"; - const std::string playerANI = options.cheat.altSkin ? "player2.ani" : "player.ani"; + const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"; + const std::string playerANI = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani"; const player_t player = {spawn_point_, playerPNG, playerANI, room_}; player_ = new Player(player); text_ = new Text(resource_->getOffset("smb2.txt"), resource_->getTexture("smb2.png"), renderer_); @@ -93,7 +93,7 @@ Game::Game() board_.items = 0; board_.rooms = 1; board_.music = true; - board_.jailEnabled = options.cheat.jailEnabled; + board_.jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED; setScoreBoardColor(); room_tracker_->addRoom(current_room_); paused_ = false; @@ -102,11 +102,10 @@ Game::Game() total_items_ = getTotalItems(); initStats(); stats_->addVisit(room_->getName()); - const bool cheats = options.cheat.infiniteLives || options.cheat.invincible || options.cheat.jailEnabled; - cheevos_->enable(!cheats); // Deshabilita los logros si hay trucos activados + cheevos_->enable(!options.cheats.enabled()); // Deshabilita los logros si hay trucos activados - options.section.name = SECTION_GAME; - options.section.subsection = 0; + options.section.section = Section::GAME; + options.section.subsection = Subsection::NONE; } Game::~Game() @@ -141,7 +140,7 @@ void Game::checkEvents() { case SDL_SCANCODE_G: debug_->switchEnabled(); - options.cheat.invincible = debug_->getEnabled(); + options.cheats.invincible = static_cast(debug_->getEnabled()); board_.music = !debug_->getEnabled(); board_.music ? JA_ResumeMusic() : JA_PauseMusic(); break; @@ -215,7 +214,7 @@ void Game::run() JA_PauseMusic(); } - while (options.section.name == SECTION_GAME) + while (options.section.section == Section::GAME) { update(); checkEvents(); @@ -352,7 +351,7 @@ bool Game::changeRoom(std::string file) room_ = nullptr; // Crea un objeto habitación nuevo a partir del fichero - room_ = new Room(resource_->getRoom(file), item_tracker_, &board_.items, board_.jailEnabled); + room_ = new Room(resource_->getRoom(file), item_tracker_, &board_.items, board_.jail_is_open); // Pone el nombre de la habitación en la textura fillRoomNameTexture(); @@ -425,22 +424,22 @@ void Game::checkGameOver() { if (board_.lives < 0 && black_screen_counter_ > 17) { - options.section.name = SECTION_GAME_OVER; + options.section.section = Section::GAME_OVER; } } // Mata al jugador void Game::killPlayer() { - if (options.cheat.invincible) + if (options.cheats.invincible == Cheat::CheatState::ENABLED) { return; } // Resta una vida al jugador - if (!options.cheat.infiniteLives) + if (options.cheats.infinite_lives == Cheat::CheatState::DISABLED) { - board_.lives--; + --board_.lives; } // Actualiza las estadisticas @@ -460,15 +459,15 @@ void Game::killPlayer() setBlackScreen(); // Crea la nueva habitación y el nuevo jugador - room_ = new Room(resource_->getRoom(current_room_), item_tracker_, &board_.items, board_.jailEnabled); - const std::string playerPNG = options.cheat.altSkin ? "player2.png" : "player.png"; - const std::string playerANI = options.cheat.altSkin ? "player2.ani" : "player.ani"; + room_ = new Room(resource_->getRoom(current_room_), item_tracker_, &board_.items, board_.jail_is_open); + const std::string playerPNG = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"; + const std::string playerANI = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani"; const player_t player = {spawn_point_, playerPNG, playerANI, room_}; - this->player_ = new Player(player); + player_ = new Player(player); // Pone los objetos en pausa mientras esta la habitación en negro room_->pause(); - this->player_->pause(); + player_->pause(); } // Recarga todas las texturas @@ -484,26 +483,6 @@ void Game::reLoadTextures() text_->reLoadTexture(); } -// Cambia la paleta -void Game::switchPalette() -{ - if (options.console) - { - std::cout << "** PALETTE SWITCH REQUESTED" << std::endl; - } - - // Modifica la variable - options.palette = (options.palette == p_zxspectrum) ? p_zxarne : p_zxspectrum; - - // Recarga las paletas - room_->reLoadPalette(); - player_->reLoadPalette(); - scoreboard_->reLoadPalette(); - - // Pone el color del marcador en función del color del borde de la habitación - setScoreBoardColor(); -} - // Establece la pantalla en negro void Game::setBlackScreen() { @@ -534,7 +513,7 @@ void Game::renderBlackScreen() if (black_screen_) { screen_->clean(); - screen_->setBorderColor(stringToColor(options.palette, "black")); + screen_->setBorderColor(stringToColor(options.video.palette, "black")); } } @@ -542,25 +521,25 @@ void Game::renderBlackScreen() void Game::setScoreBoardColor() { // Obtiene el color del borde - const color_t colorBorder = room_->getBorderColor(); + const Color colorBorder = room_->getBorderColor(); - const bool isBlack = colorAreEqual(colorBorder, stringToColor(options.palette, "black")); - const bool isBrightBlack = colorAreEqual(colorBorder, stringToColor(options.palette, "bright_black")); + const bool isBlack = colorAreEqual(colorBorder, stringToColor(options.video.palette, "black")); + const bool isBrightBlack = colorAreEqual(colorBorder, stringToColor(options.video.palette, "bright_black")); // Si el color del borde es negro o negro brillante cambia el texto del marcador a blanco - board_.color = isBlack || isBrightBlack ? stringToColor(options.palette, "white") : colorBorder; + board_.color = isBlack || isBrightBlack ? stringToColor(options.video.palette, "white") : colorBorder; } // Comprueba si ha finalizado el juego bool Game::checkEndGame() { - const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca - const bool haveTheItems = board_.items >= int(total_items_ * 0.9f) || options.cheat.jailEnabled; // Con mas del 90% de los items recogidos - const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta) + const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca + const bool haveTheItems = board_.items >= int(total_items_ * 0.9f) || options.cheats.jail_is_open == Cheat::CheatState::ENABLED; // Con mas del 90% de los items recogidos + const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta) if (haveTheItems) { - board_.jailEnabled = true; + board_.jail_is_open = true; } if (haveTheItems && isOnTheRoom && isOnTheDoor) @@ -568,7 +547,7 @@ bool Game::checkEndGame() // Comprueba los logros de completar el juego checkEndGameCheevos(); - options.section.name = SECTION_ENDING; + options.section.section = Section::ENDING; return true; } @@ -671,7 +650,7 @@ void Game::fillRoomNameTexture() SDL_SetRenderTarget(renderer_, room_name_texture_); // Rellena la textura de color - const color_t color = stringToColor(options.palette, "white"); + const Color color = stringToColor(options.video.palette, "white"); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_RenderClear(renderer_); diff --git a/source/game.h b/source/game.h index f9df4ac..33fd81c 100644 --- a/source/game.h +++ b/source/game.h @@ -20,8 +20,8 @@ class Stats; class Text; struct JA_Music_t; struct JA_Sound_t; -struct options_t; -struct section_t; +struct Options; +struct SectionState; class Game { @@ -104,9 +104,6 @@ private: // Recarga todas las texturas void reLoadTextures(); - // Cambia la paleta - void switchPalette(); - // Establece la pantalla en negro void setBlackScreen(); diff --git a/source/game_over.cpp b/source/game_over.cpp index 8d02711..41f17f5 100644 --- a/source/game_over.cpp +++ b/source/game_over.cpp @@ -32,8 +32,8 @@ GameOver::GameOver() // Inicializa variables preCounter = 0; counter = 0; - options.section.name = SECTION_GAME_OVER; - options.section.subsection = 0; + options.section.section = Section::GAME_OVER; + options.section.subsection = Subsection::NONE; ticks = 0; ticksSpeed = 15; endSection = 400; @@ -48,7 +48,7 @@ GameOver::GameOver() const std::vector colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; for (auto cl : colorList) { - colors.push_back(stringToColor(options.palette, cl)); + colors.push_back(stringToColor(options.video.palette, cl)); } color = colors.back(); } @@ -116,7 +116,7 @@ void GameOver::render() // Escribe el texto con "Tu peor pesadilla" text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 110, "YOUR WORST NIGHTMARE IS", 1, color); - text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 120, options.stats.worstNightmare, 1, color); + text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, y + 120, options.stats.worst_nightmare, 1, color); // Vuelca el contenido del renderizador en pantalla screen->render(); @@ -141,7 +141,7 @@ void GameOver::checkInput() // Bucle principal void GameOver::run() { - while (options.section.name == SECTION_GAME_OVER) + while (options.section.section == Section::GAME_OVER) { update(); checkEvents(); @@ -200,13 +200,7 @@ void GameOver::updateCounters() // Comprueba si ha terminado la sección else if (counter == endSection) { - options.section.name = SECTION_LOGO; - options.section.subsection = SUBSECTION_LOGO_TO_TITLE; + options.section.section = Section::LOGO; + options.section.subsection = Subsection::LOGO_TO_TITLE; } -} - -// Cambia la paleta -void GameOver::switchPalette() -{ - options.palette = (options.palette == p_zxspectrum) ? p_zxarne : p_zxspectrum; } \ No newline at end of file diff --git a/source/game_over.h b/source/game_over.h index 5052cf9..1d76429 100644 --- a/source/game_over.h +++ b/source/game_over.h @@ -27,16 +27,16 @@ private: AnimatedSprite *tvSprite; // Sprite con el televisor // Variables - int preCounter; // Contador previo - int counter; // Contador - Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa - Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa - std::vector colors; // Vector con los colores para el fade - color_t color; // Color usado para el texto y los sprites - int endSection; // Contador: cuando acaba la sección - int iniFade; // Contador: cuando emiepza el fade - int fadeLenght; // Contador: duración del fade - JA_Music_t *music; // Musica que suena durante el juego + int preCounter; // Contador previo + int counter; // Contador + Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa + std::vector colors; // Vector con los colores para el fade + Color color; // Color usado para el texto y los sprites + int endSection; // Contador: cuando acaba la sección + int iniFade; // Contador: cuando emiepza el fade + int fadeLenght; // Contador: duración del fade + JA_Music_t *music; // Musica que suena durante el juego // Actualiza el objeto void update(); @@ -59,9 +59,6 @@ private: // Actualiza los contadores void updateCounters(); - // Cambia la paleta - void switchPalette(); - public: // Constructor GameOver(); diff --git a/source/global_events.cpp b/source/global_events.cpp index db8b5a4..f005925 100644 --- a/source/global_events.cpp +++ b/source/global_events.cpp @@ -1,5 +1,5 @@ #include "global_events.h" -#include "options.h" // Para Options, options, OptionsGame, OptionsAudio +#include "options.h" // Para Options, options, OptionsGame, OptionsAudio #include "mouse.h" namespace globalEvents @@ -10,14 +10,14 @@ namespace globalEvents // Evento de salida de la aplicación if (event.type == SDL_QUIT) { - options.section.name = SECTION_QUIT; + options.section.section = Section::QUIT; return; } if (event.type == SDL_RENDER_DEVICE_RESET || event.type == SDL_RENDER_TARGETS_RESET) - { - //reLoadTextures(); - } + { + // reLoadTextures(); + } Mouse::handleEvent(event); } diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index 6ebb932..be3f36b 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -9,23 +9,23 @@ namespace globalInputs // Cambia la paleta void switchPalette() { - options.palette = options.palette == p_zxspectrum ? p_zxarne : p_zxspectrum; + options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM; } // Cambia de seccion void skip_section() { - switch (options.section.name) + switch (options.section.section) { - case SECTION_LOGO: - case SECTION_LOADING_SCREEN: - case SECTION_CREDITS: - case SECTION_DEMO: - case SECTION_GAME_OVER: - case SECTION_ENDING: - case SECTION_ENDING2: - options.section.name = SECTION_TITLE; - options.section.subsection = 0; + case Section::LOGO: + case Section::LOADING_SCREEN: + case Section::CREDITS: + case Section::DEMO: + case Section::GAME_OVER: + case Section::ENDING: + case Section::ENDING2: + options.section.section = Section::TITLE; + options.section.subsection = Subsection::NONE; break; default: @@ -38,7 +38,7 @@ namespace globalInputs { if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) { - options.section.name = SECTION_QUIT; + options.section.section = Section::QUIT; } else if (Input::get()->checkInput(input_accept, REPEAT_FALSE)) @@ -58,12 +58,12 @@ namespace globalInputs else if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE)) { - Screen::get()->decWindowSize(); + Screen::get()->decWindowZoom(); } else if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE)) { - Screen::get()->incWindowSize(); + Screen::get()->incWindowZoom(); } else if (Input::get()->checkInput(input_toggle_shaders, REPEAT_FALSE)) diff --git a/source/item.cpp b/source/item.cpp index 2ff5791..248b785 100644 --- a/source/item.cpp +++ b/source/item.cpp @@ -17,7 +17,7 @@ Item::Item(item_t item) counter = item.counter * colorChangeSpeed; // Inicializa los colores - color_t c = item.color1; + Color c = item.color1; color.push_back(c); color.push_back(c); @@ -67,7 +67,7 @@ void Item::reLoadTexture() } // Asigna los colores del objeto -void Item::setColors(color_t col1, color_t col2) +void Item::setColors(Color col1, Color col2) { // Reinicializa el vector de colores color.clear(); diff --git a/source/item.h b/source/item.h index 04be7f4..de29bf6 100644 --- a/source/item.h +++ b/source/item.h @@ -17,8 +17,8 @@ struct item_t int y; // Posición del item en pantalla int tile; // Número de tile dentro de la textura int counter; // Contador inicial. Es el que lo hace cambiar de color - color_t color1; // Uno de los dos colores que se utiliza para el item - color_t color2; // Uno de los dos colores que se utiliza para el item + Color color1; // Uno de los dos colores que se utiliza para el item + Color color2; // Uno de los dos colores que se utiliza para el item // Constructor por defecto item_t() : renderer(nullptr), texture(nullptr), x(0), y(0), tile(0), counter(0), color1(), color2() {} @@ -31,10 +31,10 @@ private: Sprite *sprite; // Sprite del objeto // Variables - std::vector color; // Vector con los colores del objeto - int counter; // Contador interno - SDL_Rect collider; // Rectangulo de colisión - int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color + std::vector color; // Vector con los colores del objeto + int counter; // Contador interno + SDL_Rect collider; // Rectangulo de colisión + int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color public: // Constructor @@ -59,5 +59,5 @@ public: void reLoadTexture(); // Asigna los colores del objeto - void setColors(color_t col1, color_t col2); + void setColors(Color col1, Color col2); }; \ No newline at end of file diff --git a/source/loading_screen.cpp b/source/loading_screen.cpp index 2871b1e..cf33852 100644 --- a/source/loading_screen.cpp +++ b/source/loading_screen.cpp @@ -23,12 +23,12 @@ LoadingScreen::LoadingScreen() input_(Input::get()) { // Reserva memoria para los punteros - if (options.palette == p_zxspectrum) + if (options.video.palette == Palette::ZXSPECTRUM) { mono_loading_screen_texture_ = resource_->getTexture("loading_screen_bn.png"); color_loading_screen_texture_ = resource_->getTexture("loading_screen_color.png"); } - else if (options.palette == p_zxarne) + else if (options.video.palette == Palette::ZXARNE) { mono_loading_screen_texture_ = resource_->getTexture("loading_screen_bn_zxarne.png"); color_loading_screen_texture_ = resource_->getTexture("loading_screen_color_zxarne.png"); @@ -40,8 +40,8 @@ LoadingScreen::LoadingScreen() loading_sound3_ = JA_LoadMusic(asset_->get("loading_sound3.ogg").c_str()); // Inicializa variables - options.section.name = SECTION_LOADING_SCREEN; - options.section.subsection = 0; + options.section.section = Section::LOADING_SCREEN; + options.section.subsection = Subsection::NONE; // Establece el orden de las lineas para imitar el direccionamiento de memoria del spectrum for (int i = 0; i < 192; ++i) @@ -63,7 +63,7 @@ LoadingScreen::LoadingScreen() } // Cambia el color del borde - screen_->setBorderColor(stringToColor(options.palette, "black")); + screen_->setBorderColor(stringToColor(options.video.palette, "black")); } // Destructor @@ -133,8 +133,8 @@ void LoadingScreen::updateLoad() // Comprueba si ha terminado la intro if (load_counter_ >= 768) { - options.section.name = SECTION_TITLE; - options.section.subsection = SUBSECTION_TITLE_WITH_LOADING_SCREEN; + options.section.section = Section::TITLE; + options.section.subsection = Subsection::TITLE_WITH_LOADING_SCREEN; JA_StopMusic(); } } @@ -161,23 +161,16 @@ void LoadingScreen::renderLoad() void LoadingScreen::renderBorder() { // Pinta el borde de colro azul - color_t color = stringToColor(options.palette, "blue"); + Color color = stringToColor(options.video.palette, "blue"); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_RenderClear(renderer_); // Añade lineas amarillas - color = stringToColor(options.palette, "yellow"); + color = stringToColor(options.video.palette, "yellow"); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); - const int width = GAMECANVAS_WIDTH + (options.borderWidth * 2); - const int height = GAMECANVAS_HEIGHT + (options.borderHeight * 2); + const int width = GAMECANVAS_WIDTH + (options.video.border.width * 2); + const int height = GAMECANVAS_HEIGHT + (options.video.border.height * 2); bool drawEnabled = rand() % 2 == 0 ? true : false; - // Para (int i = 0; i < height; ++i) - //{ - // if (rand() % 2 == 0) - // { - // SDL_RenderDrawLine(renderer, 0, i, width, i); - // } - // } int row = 0; int rowSize = 1; while (row < height) @@ -218,7 +211,7 @@ void LoadingScreen::update() // Dibuja en pantalla void LoadingScreen::render() { - if (options.borderEnabled) + if (options.video.border.enabled) { // Prepara para empezar a dibujar en la textura del borde screen_->startDrawOnBorder(); @@ -249,7 +242,7 @@ void LoadingScreen::run() screen_->clean(); screen_->render(); - while (options.section.name == SECTION_LOADING_SCREEN) + while (options.section.section == Section::LOADING_SCREEN) { update(); checkEvents(); @@ -259,25 +252,6 @@ void LoadingScreen::run() JA_SetVolume(128); } -// Cambia la paleta -void LoadingScreen::switchPalette() -{ - if (options.palette == p_zxspectrum) - { - options.palette = p_zxarne; - mono_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_bn_zxarne.png")); - color_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_color_zxarne.png")); - } - else - { - options.palette = p_zxspectrum; - mono_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_bn.png")); - color_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_color.png")); - } - - recreateLoadingScreen(); -} - // Reconstruye la pantalla de carga void LoadingScreen::recreateLoadingScreen() { diff --git a/source/loading_screen.h b/source/loading_screen.h index ea70149..fb503c5 100644 --- a/source/loading_screen.h +++ b/source/loading_screen.h @@ -11,8 +11,8 @@ class Screen; class Sprite; class Texture; struct JA_Music_t; -struct options_t; -struct section_t; +struct Options; +struct SectionState; class LoadingScreen { @@ -65,9 +65,6 @@ private: // Dibuja el efecto de carga en el borde void renderBorder(); - // Cambia la paleta - void switchPalette(); - // Reconstruye la pantalla de carga void recreateLoadingScreen(); diff --git a/source/logo.cpp b/source/logo.cpp index 51bd65e..00be3c5 100644 --- a/source/logo.cpp +++ b/source/logo.cpp @@ -47,17 +47,17 @@ Logo::Logo() } // Inicializa variables - options.section.name = SECTION_LOGO; + options.section.section = Section::LOGO; // Inicializa el vector de colores const std::vector vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"}; for (auto v : vColors) { - color_.push_back(stringToColor(options.palette, v)); + color_.push_back(stringToColor(options.video.palette, v)); } // Cambia el color del borde - screen_->setBorderColor(stringToColor(options.palette, "black")); + screen_->setBorderColor(stringToColor(options.video.palette, "black")); } // Destructor @@ -265,7 +265,7 @@ void Logo::run() // Detiene la música JA_StopMusic(); - while (options.section.name == SECTION_LOGO) + while (options.section.section == Section::LOGO) { update(); checkEvents(); @@ -276,13 +276,13 @@ void Logo::run() // Termina la sección void Logo::endSection() { - if (options.section.subsection == SUBSECTION_LOGO_TO_TITLE) + if (options.section.subsection == Subsection::LOGO_TO_TITLE) { - options.section.name = SECTION_TITLE; + options.section.section = Section::TITLE; } - else if (options.section.subsection == SUBSECTION_LOGO_TO_INTRO) + else if (options.section.subsection == Subsection::LOGO_TO_INTRO) { - options.section.name = SECTION_LOADING_SCREEN; + options.section.section = Section::LOADING_SCREEN; } } \ No newline at end of file diff --git a/source/logo.h b/source/logo.h index 27b37ab..a389718 100644 --- a/source/logo.h +++ b/source/logo.h @@ -10,9 +10,9 @@ class Resource; // lines 10-10 class Screen; // lines 11-11 class Sprite; // lines 12-12 class Texture; // lines 13-13 -struct color_t; -struct options_t; -struct section_t; +struct Color; +struct Options; +struct SectionState; class Logo { @@ -29,13 +29,13 @@ private: Sprite *since_1998_sprite_; // Sprite para manejar la textura2 // Variables - std::vector color_; // Vector con los colores para el fade - int counter_ = 0; // Contador - Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa - Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa - int init_fade_ = 300; // Tiempo del contador cuando inicia el fade a negro - int end_logo_ = 400; // Tiempo del contador para terminar el logo - int post_logo_ = 20; // Tiempo que dura el logo con el fade al maximo + std::vector color_; // Vector con los colores para el fade + int counter_ = 0; // Contador + Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticks_speed_ = 15; // Velocidad a la que se repiten los bucles del programa + int init_fade_ = 300; // Tiempo del contador cuando inicia el fade a negro + int end_logo_ = 400; // Tiempo del contador para terminar el logo + int post_logo_ = 20; // Tiempo que dura el logo con el fade al maximo // Actualiza las variables void update(); diff --git a/source/notifier.cpp b/source/notifier.cpp index 38474eb..2f8060b 100644 --- a/source/notifier.cpp +++ b/source/notifier.cpp @@ -106,11 +106,11 @@ void Notifier::update() const float step = ((float)notifications_[i].counter / notifications_[i].travelDist); const int alpha = 255 * step; - if (options.notifications.posV == pos_top) + if (options.notifications.getVerticalPosition() == "UPPER") { notifications_[i].rect.y++; } - else + else if (options.notifications.getVerticalPosition() == "BOTTOM") { notifications_[i].rect.y--; } @@ -138,11 +138,11 @@ void Notifier::update() const float step = (notifications_[i].counter / (float)notifications_[i].travelDist); const int alpha = 255 * (1 - step); - if (options.notifications.posV == pos_top) + if (options.notifications.getVerticalPosition() == "UPPER") { notifications_[i].rect.y--; } - else + else if (options.notifications.getVerticalPosition() == "BOTTOM") { notifications_[i].rect.y++; } @@ -187,41 +187,41 @@ void Notifier::show(std::string text1, std::string text2, int icon) // Posición horizontal int despH = 0; - if (options.notifications.posH == pos_left) + if (options.notifications.getHorizontalPosition() == "LEFT") { despH = padding; } - else if (options.notifications.posH == pos_middle) + else if (options.notifications.getHorizontalPosition() == "CENTER") { - despH = ((options.screen.windowWidth * options.windowSize) / 2 - (width / 2)); + despH = (options.game.width - width) / 2; } - else + else if (options.notifications.getHorizontalPosition() == "RIGHT") { - despH = (options.screen.windowWidth * options.windowSize) - width - padding; + despH = options.game.width - width - padding; } // Posición vertical int despV = 0; - if (options.notifications.posV == pos_top) + if (options.notifications.getVerticalPosition() == "UPPER") { despV = padding; } else { - despV = (options.screen.windowHeight * options.windowSize) - height - padding; + despV = options.game.height - height - padding; } const int travelDist = height + padding; // Offset int offset = 0; - if (options.notifications.posV == pos_top) + if (options.notifications.getVerticalPosition() == "UPPER") { - offset = (int)notifications_.size() > 0 ? notifications_.back().y + travelDist : despV; + offset = static_cast(notifications_.size()) > 0 ? notifications_.back().y + travelDist : despV; } else { - offset = (int)notifications_.size() > 0 ? notifications_.back().y - travelDist : despV; + offset = static_cast(notifications_.size()) > 0 ? notifications_.back().y - travelDist : despV; } // Crea la notificacion @@ -234,7 +234,7 @@ void Notifier::show(std::string text1, std::string text2, int icon) n.state = ns_rising; n.text1 = text1; n.text2 = text2; - if (options.notifications.posV == pos_top) + if (options.notifications.getVerticalPosition() == "UPPER") { n.rect = {despH, offset - travelDist, width, height}; } @@ -277,7 +277,7 @@ void Notifier::show(std::string text1, std::string text2, int icon) } // Escribe el texto de la notificación - color_t color = {255, 255, 255}; + Color color = {255, 255, 255}; if (text2 != "") { // Dos lineas de texto text_->writeColored(padding + iconSpace, padding, text1, color); diff --git a/source/notifier.h b/source/notifier.h index d9c6760..65ef1cc 100644 --- a/source/notifier.h +++ b/source/notifier.h @@ -57,7 +57,7 @@ private: Text *text_; // Objeto para dibujar texto // Variables - color_t bg_color_; // Color de fondo de las notificaciones + Color bg_color_; // Color de fondo de las notificaciones int wait_time_; // Tiempo que se ve la notificación std::vector notifications_; // La lista de notificaciones activas JA_Sound_t *sound_; // Sonido a reproducir cuando suena la notificación diff --git a/source/options.cpp b/source/options.cpp index ef55f54..49457ff 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -5,72 +5,33 @@ #include // Para basic_ostream, operator<<, cout // Variables -options_t options; +Options options; -bool setOptions(std::string var, std::string value); +bool setOptions(const std::string &var, const std::string &value); +// Crea e inicializa las opciones del programa void initOptions() { - // Version del archivo de configuración - options.configVersion = "v1.06.1"; + options = Options(); - // Opciones de control - options.keys = ctrl_cursor; - - // Opciones de video - options.gameWidth = GAMECANVAS_WIDTH; - options.gameHeight = GAMECANVAS_HEIGHT; - options.videoMode = 0; - options.windowSize = 3; - options.filter = FILTER_NEAREST; - options.shaders = false; - options.vSync = true; - options.integerScale = true; - options.keepAspect = true; - options.borderEnabled = true; - options.borderWidth = 32; - options.borderHeight = 24; - options.palette = p_zxspectrum; - -#ifdef GAME_CONSOLE - options.windowSize = 2; -#endif - - // Estos valores no se guardan en el fichero de configuración - options.console = false; #ifdef DEBUG + options.section = SectionState(Section::TITLE, Subsection::NONE); options.console = true; -#endif - options.cheat.infiniteLives = false; - options.cheat.invincible = false; - options.cheat.jailEnabled = false; - options.cheat.altSkin = false; - options.stats.rooms = 0; - options.stats.items = 0; - - // Opciones de las notificaciones - options.notifications.posV = pos_top; - options.notifications.posH = pos_left; - options.notifications.sound = true; - options.notifications.color = {48, 48, 48}; - -#ifdef DEBUG - options.section.name = SECTION_TITLE; - options.section.subsection = SUBSECTION_LOGO_TO_INTRO; #else - options.section.name = SECTION_LOGO; - options.section.subsection = SUBSECTION_LOGO_TO_INTRO; + options.section = SectionState(Section::LOGO, Subsection::LOGO_TO_INTRO); + options.console = false; #endif } +// Carga las opciones desde un fichero bool loadOptionsFromFile(const std::string &file_path) { // Indicador de éxito en la carga bool success = true; // Versión actual del fichero - const std::string configVersion = options.configVersion; - options.configVersion = ""; + const std::string configVersion = options.version; + options.version = ""; // Variables para manejar el fichero std::string line; @@ -114,137 +75,70 @@ bool loadOptionsFromFile(const std::string &file_path) // El fichero no existe else - { // Crea el fichero con los valores por defecto + { + // Crea el fichero con los valores por defecto saveOptionsToFile(file_path); } // Si la versión de fichero no coincide, crea un fichero nuevo con los valores por defecto - if (configVersion != options.configVersion) + if (configVersion != options.version) { initOptions(); saveOptionsToFile(file_path); } // 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)) + if (options.video.mode != 0 && + options.video.mode != SDL_WINDOW_FULLSCREEN && + options.video.mode != SDL_WINDOW_FULLSCREEN_DESKTOP) { - options.videoMode = 0; - } - - if (options.windowSize < 1 || options.windowSize > 4) - { - options.windowSize = 3; + options.video.mode = 0; } return success; } +// Guarda las opciones en un fichero bool saveOptionsToFile(const std::string &file_path) { - bool success = true; - // Crea y abre el fichero de texto std::ofstream file(file_path); + bool success = file.is_open(); // Verifica si el archivo se abrió correctamente - if (file.good()) + if (!success) // Si no se pudo abrir el archivo, muestra un mensaje de error y devuelve false { if (options.console) { - std::cout << file_path << " open for writing" << std::endl; + std::cerr << "Error: Unable to open file " << file_path << " for writing." << std::endl; } + return false; } - else + + if (options.console) { - if (options.console) - { - std::cout << file_path << " can't be opened" << std::endl; - } + std::cout << file_path << " open for writing" << std::endl; } // Escribe en el fichero file << "## VERSION\n"; - file << "configVersion=" + options.configVersion + "\n"; + file << "version=" << options.version << "\n"; - file << "\n## CONTROL OPTIONS\n"; + file << "\n## CONTROL\n"; file << "## keys = CURSOR | OPQA | WASD\n"; - if (options.keys == ctrl_cursor) - { - file << "keys=CURSOR\n"; - } - else if (options.keys == ctrl_opqa) - { - file << "keys=OPQA\n"; - } - else if (options.keys == ctrl_wasd) - { - file << "keys=WASD\n"; - } + file << "keys=" << static_cast(options.keys) << "\n"; - file << "\n## 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_LINEAR\n"; - } - - file << "shaders=" + boolToString(options.shaders) + "\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"; - file << "palette=" + std::to_string(options.palette) + "\n"; - - file << "\n## NOTIFICATION OPTIONS\n"; - file << "## notifications.posV = pos_top | pos_bottom\n"; - if (options.notifications.posV == pos_top) - { - file << "notifications.posV=pos_top\n"; - } - else - { - file << "notifications.posV=pos_bottom\n"; - } - - file << "## notifications.posH = pos_left | pos_middle | pos_right\n"; - if (options.notifications.posH == pos_left) - { - file << "notifications.posH=pos_left\n"; - } - else if (options.notifications.posH == pos_middle) - { - file << "notifications.posH=pos_middle\n"; - } - else - { - file << "notifications.posH=pos_right\n"; - } - - file << "notifications.sound=" + boolToString(options.notifications.sound) + "\n"; + file << "\n## VIDEO\n"; + file << "video.mode=" << options.video.mode << "\n"; + file << "window.zoom=" << options.window.zoom << "\n"; + file << "video.filter=" << static_cast(options.video.filter) << "\n"; + file << "video.shaders=" << boolToString(options.video.shaders) << "\n"; + file << "video.vertical_sync=" << boolToString(options.video.vertical_sync) << "\n"; + file << "video.integer_scale=" << boolToString(options.video.integer_scale) << "\n"; + file << "video.keep_aspect=" << boolToString(options.video.keep_aspect) << "\n"; + file << "video.border.enabled=" << boolToString(options.video.border.enabled) << "\n"; + file << "video.border.width=" << options.video.border.width << "\n"; + file << "video.border.height=" << options.video.border.height << "\n"; + file << "video.palette=" << static_cast(options.video.palette) << "\n"; // Cierra el fichero file.close(); @@ -252,160 +146,27 @@ bool saveOptionsToFile(const std::string &file_path) return success; } -bool setOptions(std::string var, std::string value) -{ - // Indicador de éxito en la asignación - bool success = true; - - if (var == "configVersion") - { - options.configVersion = value; +// Establece las opciones +bool setOptions(const std::string &var, const std::string &value) { + static const std::unordered_map> optionHandlers = { + {"version", [](std::string v) { options.version = v; }}, + {"keys", [](std::string v) { options.keys = static_cast(safeStoi(v, static_cast(ControlScheme::CURSOR))); }}, + {"video.mode", [](std::string v) { options.video.mode = safeStoi(v, 0); }}, + {"window.zoom", [](std::string v) { options.window.zoom = safeStoi(v, 1); }}, + {"video.shaders", [](std::string v) { options.video.shaders = stringToBool(v); }}, + {"video.vertical_sync", [](std::string v) { options.video.vertical_sync = stringToBool(v); }}, + {"video.integer_scale", [](std::string v) { options.video.integer_scale = stringToBool(v); }}, + {"video.keep_aspect", [](std::string v) { options.video.keep_aspect = stringToBool(v); }}, + {"video.border.enabled", [](std::string v) { options.video.border.enabled = stringToBool(v); }}, + {"video.border.width", [](std::string v) { options.video.border.width = safeStoi(v, 32); }}, + {"video.border.height", [](std::string v) { options.video.border.height = safeStoi(v, 24); }}, + {"video.palette", [](std::string v) { options.video.palette = static_cast(safeStoi(v, static_cast(DEFAULT_PALETTE))); }} + }; + + auto it = optionHandlers.find(var); + if (it != optionHandlers.end()) { + it->second(value); + return true; } - - else if (var == "keys") - { - if (value == "OPQA") - { - options.keys = ctrl_opqa; - } - else if (value == "WASD") - { - options.keys = ctrl_wasd; - } - else - { - options.keys = ctrl_cursor; - } - } - - else 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_LINEAR") - { - options.filter = FILTER_LINEAR; - } - else - { - options.filter = FILTER_NEAREST; - } - } - - else if (var == "shaders") - { - options.shaders = stringToBool(value); - } - - 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); - } - - else if (var == "palette") - { - const int pal = std::stoi(value); - - if (pal == 0) - { - options.palette = p_zxspectrum; - } - - else if (pal == 1) - { - options.palette = p_zxarne; - } - } - - else if (var == "notifications.posH") - { - if (value == "pos_left") - { - options.notifications.posH = pos_left; - } - else if (value == "pos_middle") - { - options.notifications.posH = pos_middle; - } - else - { - options.notifications.posH = pos_right; - } - } - - else if (var == "notifications.posV") - { - if (value == "pos_top") - { - options.notifications.posV = pos_top; - } - else - { - options.notifications.posV = pos_bottom; - } - } - - else if (var == "notifications.sound") - { - options.notifications.sound = stringToBool(value); - } - - else if (var == "" || var.substr(0, 1) == "#") - { - } - - else - { - success = false; - } - - return success; + return false; } \ No newline at end of file diff --git a/source/options.h b/source/options.h index e3de6ba..5a0e3b6 100644 --- a/source/options.h +++ b/source/options.h @@ -4,110 +4,366 @@ #include // Para Uint8, Uint32 #include // Para string, basic_string #include "utils.h" +#include "screen.h" + +constexpr int DEFAULT_WINDOW_WIDTH = 320; // Ancho de la ventana por defecto +constexpr int DEFAULT_WINDOW_HEIGHT = 240; // Alto de la ventana por defecto +constexpr int DEFAULT_WINDOW_ZOOM = 2; // Zoom de la ventana por defecto +constexpr int DEFAULT_VIDEO_MODE = 0; // Modo de pantalla completa por defecto +constexpr int DEFAULT_BORDER_WIDTH = 32; // Ancho del borde por defecto +constexpr int DEFAULT_BORDER_HEIGHT = 24; // Alto del borde por defecto +constexpr Palette DEFAULT_PALETTE = Palette::ZXSPECTRUM; // Paleta por defecto // Secciones del programa -constexpr int SECTION_LOGO = 0; -constexpr int SECTION_LOADING_SCREEN = 1; -constexpr int SECTION_TITLE = 2; -constexpr int SECTION_CREDITS = 3; -constexpr int SECTION_GAME = 4; -constexpr int SECTION_DEMO = 5; -constexpr int SECTION_GAME_OVER = 6; -constexpr int SECTION_ENDING = 7; -constexpr int SECTION_ENDING2 = 8; -constexpr int SECTION_QUIT = 9; +enum class Section +{ + LOGO, + LOADING_SCREEN, + TITLE, + CREDITS, + GAME, + DEMO, + GAME_OVER, + ENDING, + ENDING2, + QUIT +}; // Subsecciones -constexpr int SUBSECTION_LOGO_TO_INTRO = 0; -constexpr int SUBSECTION_LOGO_TO_TITLE = 1; -constexpr int SUBSECTION_TITLE_WITH_LOADING_SCREEN = 2; -constexpr int SUBSECTION_TITLE_WITHOUT_LOADING_SCREEN = 3; +enum class Subsection +{ + NONE, + LOGO_TO_INTRO, + LOGO_TO_TITLE, + TITLE_WITH_LOADING_SCREEN, + TITLE_WITHOUT_LOADING_SCREEN +}; // Posiciones de las notificaciones -enum not_pos_e +enum class NotificationPosition { - pos_top, - pos_bottom, - pos_left, - pos_middle, - pos_right + UPPER_LEFT, + UPPER_CENTER, + UPPER_RIGHT, + MIDDLE_LEFT, + MIDDLE_RIGHT, + BOTTOM_LEFT, + BOTTOM_CENTER, + BOTTOM_RIGHT }; // Tipos de control de teclado -enum ctrl_schem_e +enum class ControlScheme { - ctrl_cursor, - ctrl_opqa, - ctrl_wasd + CURSOR, + OPQA, + WASD }; // Estructura para las opciones de las notificaciones -struct op_notification_t +struct OptionsNotification { - not_pos_e posH; // Ubicación de las notificaciones en pantalla - not_pos_e posV; // Ubicación de las notificaciones en pantalla - bool sound; // Indica si las notificaciones suenan - color_t color; // Color de las notificaciones + NotificationPosition pos; // Ubicación de las notificaciones en pantalla + bool sound; // Indica si las notificaciones suenan + Color color; // Color de las notificaciones + + // Constructor por defecto + OptionsNotification() + { + pos = NotificationPosition::UPPER_LEFT; + sound = true; + color = {48, 48, 48}; + } + + // Constructor + OptionsNotification(NotificationPosition p, bool s, Color c) + { + pos = p; + sound = s; + color = c; + } + + // Método que devuelve la posición horizontal + std::string getHorizontalPosition() const + { + switch (pos) + { + case NotificationPosition::UPPER_LEFT: + case NotificationPosition::MIDDLE_LEFT: + case NotificationPosition::BOTTOM_LEFT: + return "LEFT"; + case NotificationPosition::UPPER_CENTER: + case NotificationPosition::BOTTOM_CENTER: + return "CENTER"; + case NotificationPosition::UPPER_RIGHT: + case NotificationPosition::MIDDLE_RIGHT: + case NotificationPosition::BOTTOM_RIGHT: + return "RIGHT"; + } + return "UNKNOWN"; + } + + // Método que devuelve la posición vertical + std::string getVerticalPosition() const + { + switch (pos) + { + case NotificationPosition::UPPER_LEFT: + case NotificationPosition::UPPER_CENTER: + case NotificationPosition::UPPER_RIGHT: + return "UPPER"; + case NotificationPosition::MIDDLE_LEFT: + case NotificationPosition::MIDDLE_RIGHT: + return "MIDDLE"; + case NotificationPosition::BOTTOM_LEFT: + case NotificationPosition::BOTTOM_CENTER: + case NotificationPosition::BOTTOM_RIGHT: + return "BOTTOM"; + } + return "UNKNOWN"; + } }; // Estructura para saber la seccion y subseccion del programa -struct section_t +struct SectionState { - Uint8 name; - Uint8 subsection; + Section section; + Subsection subsection; + + // Constructor por defecto + SectionState() + { + section = Section::LOGO; + subsection = Subsection::LOGO_TO_INTRO; + } + + // Constructor + SectionState(Section s, Subsection ss) + { + section = s; + subsection = ss; + } }; // Estructura para albergar trucos -struct cheat_t +struct Cheat { - bool infiniteLives; // Indica si el jugador dispone de vidas infinitas - bool invincible; // Indica si el jugador puede morir - bool jailEnabled; // Indica si la Jail está abierta - bool altSkin; // Indicxa si se usa una skin diferente para el jugador + enum class CheatState : bool + { + DISABLED = false, + ENABLED = true + }; + + CheatState infinite_lives; // Indica si el jugador dispone de vidas infinitas + CheatState invincible; // Indica si el jugador puede morir + CheatState jail_is_open; // Indica si la Jail está abierta + CheatState alternate_skin; // Indica si se usa una skin diferente para el jugador + + // Constructor por defecto + Cheat() + : infinite_lives(CheatState::DISABLED), + invincible(CheatState::DISABLED), + jail_is_open(CheatState::DISABLED), + alternate_skin(CheatState::DISABLED) + { + } + + // Constructor + Cheat(CheatState il, CheatState i, CheatState je, CheatState as) + : infinite_lives(il), + invincible(i), + jail_is_open(je), + alternate_skin(as) + { + } + + // Método para comprobar si alguno de los tres primeros trucos está activo + bool enabled() const + { + return infinite_lives == CheatState::ENABLED || + invincible == CheatState::ENABLED || + jail_is_open == CheatState::ENABLED; + } }; // Estructura para almacenar estadísticas -struct op_stats_t +struct OptionsStats { - int rooms; // Cantidad de habitaciones visitadas - int items; // Cantidad de items obtenidos - std::string worstNightmare; // Habitación con más muertes acumuladas + int rooms; // Cantidad de habitaciones visitadas + int items; // Cantidad de items obtenidos + std::string worst_nightmare; // Habitación con más muertes acumuladas + + // Constructor por defecto + OptionsStats() + { + rooms = 0; + items = 0; + worst_nightmare = ""; + } + + // Constructor + OptionsStats(int r, int i, std::string wn) + { + rooms = r; + items = i; + worst_nightmare = wn; + } }; // Estructura con opciones de la pantalla -struct op_screen_t +struct OptionsWindows { - int windowWidth; // Ancho de la ventana - int windowHeight; // Alto de la ventana + int width; // Ancho de la ventana + int height; // Alto de la ventana + int zoom; // Zoom de la ventana + + // Constructor por defecto + OptionsWindows() + { + width = DEFAULT_WINDOW_WIDTH; + height = DEFAULT_WINDOW_HEIGHT; + zoom = DEFAULT_WINDOW_ZOOM; + } + + // Constructor + OptionsWindows(int w, int h, int z) + { + width = w; + height = h; + zoom = z; + } +}; + +// Estructura para gestionar el borde de la pantalla +struct Border +{ + bool enabled; // Indica si se ha de mostrar el borde + int width; // Ancho del borde + int height; // Alto del borde + + // Constructor por defecto + Border() + { + enabled = true; + width = DEFAULT_BORDER_WIDTH; + height = DEFAULT_BORDER_HEIGHT; + } + + // Constructor + Border(bool e, int w, int h) + { + enabled = e; + width = w; + height = h; + } +}; + +// Estructura para las opciones de video +struct OptionsVideo +{ + Uint32 mode; // Contiene el valor del modo de pantalla completa + ScreenFilter filter; // Filtro usado para el escalado de la imagen + bool vertical_sync; // Indica si se quiere usar vsync o no + bool shaders; // Indica si se van a usar shaders o no + bool integer_scale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa + bool keep_aspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa + Border border; // Borde de la pantalla + Palette palette; // Paleta de colores a usar en el juego + + // Constructor por defecto + OptionsVideo() + { + mode = DEFAULT_VIDEO_MODE; + filter = ScreenFilter::NEAREST; + vertical_sync = true; + shaders = false; + integer_scale = true; + keep_aspect = true; + border = Border(); + palette = DEFAULT_PALETTE; + } + + // Constructor + OptionsVideo(Uint32 m, ScreenFilter f, bool vs, bool s, bool is, bool ka, Border b, Palette p) + { + mode = m; + filter = f; + vertical_sync = vs; + shaders = s; + integer_scale = is; + keep_aspect = ka; + border = b; + palette = p; + } +}; + +// Estructura para las opciones de juego +struct OptionsGame +{ + int width; // Ancho de la resolucion nativa del juego + int height; // Alto de la resolucion nativa del juego + + // Constructor por defecto + OptionsGame() + { + width = 320; + height = 240; + } + + // Constructor + OptionsGame(int w, int h) + { + width = w; + height = h; + } }; // Estructura con todas las opciones de configuración del programa -struct options_t +struct Options { - std::string configVersion; // Versión del programa. Sirve para saber si las opciones son compatibles - Uint32 videoMode; // Contiene el valor del modo de pantalla completa - int windowSize; // Contiene el valor por el que se multiplica el tamaño de la ventana - Uint32 filter; // Filtro usado para el escalado de la imagen - bool vSync; // Indica si se quiere usar vsync o no - bool shaders; // Indica si se van a usar shaders o no - int gameWidth; // Ancho de la resolucion nativa del juego - int gameHeight; // Alto de la resolucion nativa del juego - bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa - bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa - bool borderEnabled; // Indica si ha de mostrar el borde en el modo de ventana - int borderWidth; // Cantidad de pixels que se añade en el borde de la ventana - int borderHeight; // Cantidad de pixels que se añade en el borde de la ventana - palette_e palette; // Paleta de colores a usar en el juego - bool console; // Indica si ha de mostrar información por la consola de texto - cheat_t cheat; // Contiene trucos y ventajas para el juego - op_stats_t stats; // Datos con las estadisticas de juego - op_notification_t notifications; // Opciones relativas a las notificaciones; - op_screen_t screen; // Opciones relativas a la clase screen - ctrl_schem_e keys; // Teclas usadas para jugar - section_t section; // Sección actual del programa + std::string version; // Versión del fichero de configuración. Sirve para saber si las opciones son compatibles + bool console; // Indica si ha de mostrar información por la consola de texto + Cheat cheats; // Contiene trucos y ventajas para el juego + OptionsGame game; // Opciones de juego + OptionsVideo video; // Opciones de video + OptionsStats stats; // Datos con las estadisticas de juego + OptionsNotification notifications; // Opciones relativas a las notificaciones; + OptionsWindows window; // Opciones relativas a la ventana + ControlScheme keys; // Teclas usadas para jugar + SectionState section; // Sección actual del programa + + // Constructor por defecto + Options() + { + version = "v1.07"; + console = false; + cheats = Cheat(); + game = OptionsGame(); + video = OptionsVideo(); + stats = OptionsStats(); + notifications = OptionsNotification(); + window = OptionsWindows(); + keys = ControlScheme::CURSOR; + section = SectionState(); + } + + // Constructor + Options(std::string cv, bool c, Cheat ch, OptionsGame g, OptionsVideo v, OptionsStats s, OptionsNotification n, OptionsWindows sw, ControlScheme k, SectionState sec) + { + version = cv; + console = c; + cheats = ch; + game = g; + video = v; + stats = s; + notifications = n; + window = sw; + keys = k; + section = sec; + } }; -extern options_t options; +extern Options options; // Crea e inicializa las opciones del programa void initOptions(); diff --git a/source/player.cpp b/source/player.cpp index b3d5f02..a678cf0 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -785,14 +785,20 @@ void Player::reLoadTexture() // Recarga la paleta void Player::reLoadPalette() { - color = stringToColor(options.palette, "white"); - if (options.cheat.infiniteLives) + color = stringToColor(options.video.palette, "white"); + if (options.cheats.infinite_lives == Cheat::CheatState::ENABLED) { - color = stringToColor(options.palette, "yellow"); + color = stringToColor(options.video.palette, "green"); } - if (options.cheat.invincible) { - color = stringToColor(options.palette, "cyan"); + color = stringToColor(options.video.palette, "yellow"); + } + if (options.cheats.invincible == Cheat::CheatState::ENABLED) + { + color = stringToColor(options.video.palette, "green"); + } + { + color = stringToColor(options.video.palette, "cyan"); } } diff --git a/source/player.h b/source/player.h index 1815d15..e5a2642 100644 --- a/source/player.h +++ b/source/player.h @@ -58,7 +58,7 @@ public: float vy; // Velocidad/desplazamiento del jugador en el eje Y int w; // Ancho del jugador int h; // ALto del jugador - color_t color; // Color del jugador + Color color; // Color del jugador SDL_Rect colliderBox; // Caja de colisión con los enemigos u objetos std::vector colliderPoints; // Puntos de colisión con el mapa std::vector underFeet; // Contiene los puntos que hay bajo cada pie del jugador @@ -82,7 +82,7 @@ public: #ifdef DEBUG SDL_Rect rx; // Rectangulo de desplazamiento para el modo debug SDL_Rect ry; // Rectangulo de desplazamiento para el modo debug - color_t debugColor; // Color del recuadro de debug del jugador + Color debugColor; // Color del recuadro de debug del jugador SDL_Point debugPoint; // Punto para debug #endif diff --git a/source/resource.h b/source/resource.h index 5e24e42..e7f7624 100644 --- a/source/resource.h +++ b/source/resource.h @@ -6,7 +6,7 @@ class Asset; class Texture; struct animatedSprite_t; -struct options_t; +struct Options; struct room_t; struct textFile_t; diff --git a/source/room.cpp b/source/room.cpp index c0088a3..0b954ab 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -95,7 +95,7 @@ room_t loadRoomFile(std::string file_path, bool verbose) enemy.flip = false; enemy.mirror = false; enemy.frame = -1; - enemy.palette = p_zxspectrum; + enemy.palette = Palette::ZXSPECTRUM; do { @@ -123,8 +123,8 @@ room_t loadRoomFile(std::string file_path, bool verbose) { item_t item; item.counter = 0; - item.color1 = stringToColor(p_zxspectrum, "yellow"); - item.color2 = stringToColor(p_zxspectrum, "magenta"); + item.color1 = stringToColor(Palette::ZXSPECTRUM, "yellow"); + item.color2 = stringToColor(Palette::ZXSPECTRUM, "magenta"); do { @@ -428,7 +428,7 @@ Room::Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEn textureA = room->textureA; textureB = room->textureB; tileMap = *room->tileMap; - texture = (options.palette == p_zxspectrum) ? textureA : textureB; + texture = (options.video.palette == Palette::ZXSPECTRUM) ? textureA : textureB; this->jailEnabled = jailEnabled; // Inicializa variables @@ -443,7 +443,7 @@ Room::Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEn for (auto &enemy : room->enemies) { enemy.renderer = renderer; - enemy.palette = options.palette; + enemy.palette = options.video.palette; enemies.push_back(new Enemy(enemy)); } @@ -455,8 +455,8 @@ Room::Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEn if (!itemTracker->hasBeenPicked(room->name, itemPos)) { item.renderer = renderer; - item.color1 = stringToColor(options.palette, itemColor1); - item.color2 = stringToColor(options.palette, itemColor2); + item.color1 = stringToColor(options.video.palette, itemColor1); + item.color2 = stringToColor(options.video.palette, itemColor2); items.push_back(new Item(item)); } } @@ -497,7 +497,7 @@ Room::Room(room_t *room, ItemTracker *itemTracker, int *itemsPicked, bool jailEn fillMapTexture(); // Establece el color del borde - screen->setBorderColor(stringToColor(options.palette, room->borderColor)); + screen->setBorderColor(stringToColor(options.video.palette, room->borderColor)); } // Destructor @@ -530,21 +530,21 @@ std::string Room::getName() } // Devuelve el color de la habitación -color_t Room::getBGColor() +Color Room::getBGColor() { - return stringToColor(options.palette, bgColor); + return stringToColor(options.video.palette, bgColor); } // Devuelve el color del borde -color_t Room::getBorderColor() +Color Room::getBorderColor() { - return stringToColor(options.palette, borderColor); + return stringToColor(options.video.palette, borderColor); } // Crea la textura con el mapeado de la habitación void Room::fillMapTexture() { - const color_t color = stringToColor(options.palette, bgColor); + const Color color = stringToColor(options.video.palette, bgColor); SDL_SetRenderTarget(renderer, mapTexture); SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); SDL_RenderClear(renderer); @@ -870,20 +870,20 @@ void Room::reLoadPalette() // Cambia el color de los items for (auto item : items) { - item->setColors(stringToColor(options.palette, itemColor1), stringToColor(options.palette, itemColor2)); + item->setColors(stringToColor(options.video.palette, itemColor1), stringToColor(options.video.palette, itemColor2)); } // Cambia el color de los enemigos for (auto enemy : enemies) { - enemy->setPalette(options.palette); + enemy->setPalette(options.video.palette); } // Establece el color del borde - screen->setBorderColor(stringToColor(options.palette, borderColor)); + screen->setBorderColor(stringToColor(options.video.palette, borderColor)); // Cambia la textura - texture = (options.palette == p_zxspectrum) ? textureA : textureB; + texture = (options.video.palette == Palette::ZXSPECTRUM) ? textureA : textureB; // Pone la nueva textura a los tiles animados for (auto tile : aTile) diff --git a/source/room.h b/source/room.h index cfedd37..4a45a39 100644 --- a/source/room.h +++ b/source/room.h @@ -168,10 +168,10 @@ public: std::string getName(); // Devuelve el color de la habitación - color_t getBGColor(); + Color getBGColor(); // Devuelve el color del borde - color_t getBorderColor(); + Color getBorderColor(); // Dibuja el mapa en pantalla void renderMap(); diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index 4e5524a..b69c093 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -20,7 +20,7 @@ Scoreboard::Scoreboard(board_t *board) { // Reserva memoria para los objetos itemTexture = resource->getTexture("items.png"); - const std::string playerANI = options.cheat.altSkin ? "player2.ani" : "player.ani"; + const std::string playerANI = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani"; sprite = new AnimatedSprite(renderer, resource->getAnimation(playerANI)); sprite->setCurrentAnimation("walk_menu"); text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); @@ -31,13 +31,13 @@ Scoreboard::Scoreboard(board_t *board) paused = false; timePaused = 0; totalTimePaused = 0; - itemsColor = stringToColor(options.palette, "white"); + itemsColor = stringToColor(options.video.palette, "white"); // Inicializa el vector de colores const std::vector vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"}; for (auto v : vColors) { - color.push_back(stringToColor(options.palette, v)); + color.push_back(stringToColor(options.video.palette, v)); } } @@ -76,7 +76,7 @@ void Scoreboard::render() // Muestra si suena la música if (board->music) { - const color_t c = board->color; + const Color c = board->color; SDL_Rect clip = {0, 8, 8, 8}; itemTexture->setColor(c.r, c.g, c.b); itemTexture->render(renderer, 20 * BLOCK, line2, &clip); @@ -88,11 +88,11 @@ void Scoreboard::render() this->text->writeColored(BLOCK, line1, "Items collected ", board->color); this->text->writeColored(17 * BLOCK, line1, itemsTxt, itemsColor); this->text->writeColored(20 * BLOCK, line1, " Time ", board->color); - this->text->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options.palette, "white")); + this->text->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options.video.palette, "white")); const std::string roomsTxt = std::to_string(board->rooms / 100) + std::to_string((board->rooms % 100) / 10) + std::to_string(board->rooms % 10); - this->text->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options.palette, "white")); - this->text->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options.palette, "white")); + this->text->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options.video.palette, "white")); + this->text->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options.video.palette, "white")); } // Actualiza las variables del objeto @@ -141,7 +141,7 @@ void Scoreboard::reLoadPalette() color.clear(); for (auto v : vColors) { - color.push_back(stringToColor(options.palette, v)); + color.push_back(stringToColor(options.video.palette, v)); } } @@ -162,18 +162,18 @@ void Scoreboard::resume() // Actualiza el color de la cantidad de items recogidos void Scoreboard::updateItemsColor() { - if (!board->jailEnabled) + if (!board->jail_is_open) { return; } if (counter % 20 < 10) { - itemsColor = stringToColor(options.palette, "white"); + itemsColor = stringToColor(options.video.palette, "white"); } else { - itemsColor = stringToColor(options.palette, "magenta"); + itemsColor = stringToColor(options.video.palette, "magenta"); } } diff --git a/source/scoreboard.h b/source/scoreboard.h index 7be98c4..102d9c2 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -13,13 +13,13 @@ class Texture; struct board_t { - int items; // Lleva la cuenta de los objetos recogidos - int lives; // Lleva la cuenta de ls vidas restantes del jugador - int rooms; // Lleva la cuenta de las habitaciones visitadas - bool music; // Indica si ha de sonar la musica durante el juego - color_t color; // Color para escribir el texto del marcador - Uint32 iniClock; // Tiempo inicial para calcular el tiempo transcurrido - bool jailEnabled; // Indica si se puede entrar a la Jail + int items; // Lleva la cuenta de los objetos recogidos + int lives; // Lleva la cuenta de ls vidas restantes del jugador + int rooms; // Lleva la cuenta de las habitaciones visitadas + bool music; // Indica si ha de sonar la musica durante el juego + Color color; // Color para escribir el texto del marcador + Uint32 iniClock; // Tiempo inicial para calcular el tiempo transcurrido + bool jail_is_open; // Indica si se puede entrar a la Jail }; class Scoreboard @@ -43,14 +43,14 @@ private: board_t *board; // Contiene las variables a mostrar en el marcador // Variables - std::vector color; // Vector con los colores del objeto - int counter; // Contador interno - int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color - bool paused; // Indica si el marcador esta en modo pausa - Uint32 timePaused; // Milisegundos que ha estado el marcador en pausa - Uint32 totalTimePaused; // Tiempo acumulado en pausa - clock_t clock; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida - color_t itemsColor; // Color de la cantidad de items recogidos + std::vector color; // Vector con los colores del objeto + int counter; // Contador interno + int colorChangeSpeed; // Cuanto mas alto, mas tarda en cambiar de color + bool paused; // Indica si el marcador esta en modo pausa + Uint32 timePaused; // Milisegundos que ha estado el marcador en pausa + Uint32 totalTimePaused; // Tiempo acumulado en pausa + clock_t clock; // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida + Color itemsColor; // Color de la cantidad de items recogidos // Obtiene el tiempo transcurrido de partida clock_t getTime(); diff --git a/source/screen.cpp b/source/screen.cpp index 02b9471..48fcc79 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -40,8 +40,8 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) : window_(window), renderer_(renderer) { - game_canvas_width_ = options.gameWidth; - game_canvas_height_ = options.gameHeight; + game_canvas_width_ = options.game.width; + game_canvas_height_ = options.game.height; notification_logical_width_ = game_canvas_width_; notification_logical_height_ = game_canvas_height_; @@ -62,7 +62,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) } // Crea la textura donde se dibuja el borde que rodea el area de juego - border_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_ + options.borderWidth * 2, game_canvas_height_ + options.borderHeight * 2); + border_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_ + options.video.border.width * 2, game_canvas_height_ + options.video.border.height * 2); if (border_canvas_ == nullptr) { if (options.console) @@ -73,7 +73,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) setBorderColor(border_color_); // Establece el modo de video - setVideoMode(options.videoMode); + setVideoMode(options.video.mode); // Muestra la ventana SDL_ShowWindow(window); @@ -87,7 +87,7 @@ Screen::~Screen() } // Limpia la pantalla -void Screen::clean(color_t color) +void Screen::clean(Color color) { SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_RenderClear(renderer_); @@ -112,7 +112,7 @@ void Screen::render() renderNotifications(); // Si está el borde activo, vuelca gameCanvas sobre borderCanvas - if (options.borderEnabled) + if (options.video.border.enabled) { gameCanvasToBorderCanvas(); } @@ -134,11 +134,11 @@ void Screen::setVideoMode(int videoMode) SDL_ShowCursor(SDL_ENABLE); // Modifica el tamaño de la ventana en función del borde - if (options.borderEnabled) + if (options.video.border.enabled) { - window_width_ = game_canvas_width_ + options.borderWidth * 2; - window_height_ = game_canvas_height_ + options.borderHeight * 2; - dest_ = {options.borderWidth, options.borderHeight, game_canvas_width_, game_canvas_height_}; + window_width_ = game_canvas_width_ + options.video.border.width * 2; + window_height_ = game_canvas_height_ + options.video.border.height * 2; + dest_ = {options.video.border.width, options.video.border.height, game_canvas_width_, game_canvas_height_}; } else @@ -149,7 +149,7 @@ void Screen::setVideoMode(int videoMode) } // Modifica el tamaño de la ventana - SDL_SetWindowSize(window_, window_width_ * options.windowSize, window_height_ * options.windowSize); + SDL_SetWindowSize(window_, window_width_ * options.window.zoom, window_height_ * options.window.zoom); SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } @@ -163,7 +163,7 @@ void Screen::setVideoMode(int videoMode) SDL_GetWindowSize(window_, &window_width_, &window_height_); // Aplica el escalado al rectangulo donde se pinta la textura del juego - if (options.integerScale) + if (options.video.integer_scale) { // Calcula el tamaño de la escala máxima int scale = 0; @@ -177,7 +177,7 @@ void Screen::setVideoMode(int videoMode) dest_.x = (window_width_ - dest_.w) / 2; dest_.y = (window_height_ - dest_.h) / 2; } - else if (options.keepAspect) + else if (options.video.keep_aspect) { float ratio = (float)game_canvas_width_ / (float)game_canvas_height_; if ((window_width_ - game_canvas_width_) >= (window_height_ - game_canvas_height_)) @@ -207,18 +207,18 @@ void Screen::setVideoMode(int videoMode) SDL_RenderSetLogicalSize(renderer_, window_width_, window_height_); // Actualiza las opciones - options.videoMode = videoMode; - options.screen.windowWidth = window_width_; - options.screen.windowHeight = window_height_; + options.video.mode = videoMode; + options.window.width = window_width_; + options.window.height = window_height_; // Reinicia los shaders - if (options.shaders) + if (options.video.shaders) { - const std::string glsl_file = options.screen.windowHeight == 192 ? "crtpi_192.glsl" : "crtpi_240.glsl"; + const std::string glsl_file = options.window.height == 192 ? "crtpi_192.glsl" : "crtpi_240.glsl"; std::ifstream f(Asset::get()->get(glsl_file).c_str()); std::string source((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - if (options.borderEnabled) + if (options.video.border.enabled) { shader::init(window_, border_canvas_, source.c_str()); } @@ -232,35 +232,35 @@ void Screen::setVideoMode(int videoMode) // Camibia entre pantalla completa y ventana void Screen::toggleVideoMode() { - options.videoMode = (options.videoMode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; - setVideoMode(options.videoMode); + options.video.mode = (options.video.mode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; + setVideoMode(options.video.mode); } // Cambia el tamaño de la ventana -void Screen::setWindowSize(int size) +void Screen::setWindowZoom(int size) { - options.windowSize = size; + options.window.zoom = size; setVideoMode(0); } // Reduce el tamaño de la ventana -void Screen::decWindowSize() +void Screen::decWindowZoom() { - --options.windowSize; - options.windowSize = std::max(options.windowSize, 1); + --options.window.zoom; + options.window.zoom = std::max(options.window.zoom, 1); setVideoMode(0); } // Aumenta el tamaño de la ventana -void Screen::incWindowSize() +void Screen::incWindowZoom() { - ++options.windowSize; - options.windowSize = std::min(options.windowSize, 4); + ++options.window.zoom; + options.window.zoom = std::min(options.window.zoom, 4); setVideoMode(0); } // Cambia el color del borde -void Screen::setBorderColor(color_t color) +void Screen::setBorderColor(Color color) { border_color_ = color; auto temp = SDL_GetRenderTarget(renderer_); @@ -279,33 +279,27 @@ void Screen::setBlendMode(SDL_BlendMode blendMode) // Establece el tamaño del borde void Screen::setBorderWidth(int s) { - options.borderWidth = s; + options.video.border.width = s; } // Establece el tamaño del borde void Screen::setBorderHeight(int s) { - options.borderHeight = s; + options.video.border.height = s; } // Establece si se ha de ver el borde en el modo ventana -void Screen::setBorderEnabled(bool value) -{ - options.borderEnabled = value; -} +void Screen::setBorderEnabled(bool value) { options.video.border.enabled = value; } // Cambia entre borde visible y no visible void Screen::toggleBorder() { - options.borderEnabled = !options.borderEnabled; + options.video.border.enabled = !options.video.border.enabled; setVideoMode(0); } // Activa el fade -void Screen::setFade() -{ - fade_ = true; -} +void Screen::setFade() { fade_ = true; } // Comprueba si ha terminado el fade bool Screen::fadeEnded() @@ -367,7 +361,7 @@ void Screen::renderFade() } const SDL_Rect rect = {0, 0, game_canvas_width_, game_canvas_height_}; - color_t color = {0, 0, 0}; + Color color = {0, 0, 0}; const float step = (float)fade_counter_ / (float)fade_lenght_; const int alpha = 0 + (255 - 0) * step; SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, alpha); @@ -387,7 +381,7 @@ void Screen::iniSpectrumFade() const std::vector vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"}; for (auto v : vColors) { - spectrum_color_.push_back(stringToColor(options.palette, v)); + spectrum_color_.push_back(stringToColor(options.video.palette, v)); } } @@ -418,7 +412,7 @@ void Screen::renderSpectrumFade() const float step = (float)spectrum_fade_counter_ / (float)spectrum_fade_lenght_; const int max = spectrum_color_.size() - 1; const int index = max + (0 - max) * step; - const color_t c = spectrum_color_[index]; + const Color c = spectrum_color_[index]; SDL_SetTextureColorMod(game_canvas_, c.r, c.g, c.b); } @@ -460,14 +454,14 @@ void Screen::renderPresent() SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF); SDL_RenderClear(renderer_); - if (options.shaders) + if (options.video.shaders) { // Aplica shaders y renderiza el contenido shader::render(); } else { - if (options.borderEnabled) + if (options.video.border.enabled) { SDL_RenderCopy(renderer_, border_canvas_, nullptr, nullptr); } @@ -482,8 +476,8 @@ void Screen::renderPresent() // Cambia el estado de los shaders void Screen::toggleShaders() { - options.shaders = !options.shaders; - setVideoMode(options.videoMode); + options.video.shaders = !options.video.shaders; + setVideoMode(options.video.mode); } // Actualiza la lógica de la clase diff --git a/source/screen.h b/source/screen.h index c3ecf2d..9b5f441 100644 --- a/source/screen.h +++ b/source/screen.h @@ -10,8 +10,12 @@ class Asset; class Notifier; -constexpr int FILTER_NEAREST = 0; -constexpr int FILTER_LINEAR = 1; +// Tipos de filtro +enum class ScreenFilter : Uint32 +{ + NEAREST = 0, + LINEAR = 1, +}; class Screen { @@ -31,18 +35,18 @@ private: int game_canvas_width_; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego int game_canvas_height_; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego SDL_Rect dest_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana - color_t border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla + Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla int notification_logical_width_; // Ancho lógico de las notificaciones en relación al tamaño de pantalla int notification_logical_height_; // Alto lógico de las notificaciones en relación al tamaño de pantalla // Variables - Efectos - bool fade_; // Indica si esta activo el efecto de fade - int fade_counter_; // Temporizador para el efecto de fade - int fade_lenght_; // Duración del fade - bool spectrum_fade_; // Indica si esta activo el efecto de fade spectrum - int spectrum_fade_counter_; // Temporizador para el efecto de fade spectrum - int spectrum_fade_lenght_; // Duración del fade spectrum - std::vector spectrum_color_; // Colores para el fade spectrum + bool fade_; // Indica si esta activo el efecto de fade + int fade_counter_; // Temporizador para el efecto de fade + int fade_lenght_; // Duración del fade + bool spectrum_fade_; // Indica si esta activo el efecto de fade spectrum + int spectrum_fade_counter_; // Temporizador para el efecto de fade spectrum + int spectrum_fade_lenght_; // Duración del fade spectrum + std::vector spectrum_color_; // Colores para el fade spectrum // Inicializa las variables para el fade void iniFade(); @@ -88,7 +92,7 @@ public: static Screen *get(); // Limpia la pantalla - void clean(color_t color = {0x00, 0x00, 0x00}); + void clean(Color color = {0x00, 0x00, 0x00}); // Prepara para empezar a dibujar en la textura de juego void start(); @@ -109,16 +113,16 @@ public: void toggleVideoMode(); // Cambia el tamaño de la ventana - void setWindowSize(int size); + void setWindowZoom(int size); // Reduce el tamaño de la ventana - void decWindowSize(); + void decWindowZoom(); // Aumenta el tamaño de la ventana - void incWindowSize(); + void incWindowZoom(); // Cambia el color del borde - void setBorderColor(color_t color); + void setBorderColor(Color color); // Cambia el tipo de mezcla void setBlendMode(SDL_BlendMode blendMode); diff --git a/source/stats.cpp b/source/stats.cpp index 8f45dac..cae4990 100644 --- a/source/stats.cpp +++ b/source/stats.cpp @@ -183,7 +183,7 @@ void Stats::checkWorstNightmare() if (item.died > deaths) { deaths = item.died; - options.stats.worstNightmare = item.name; + options.stats.worst_nightmare = item.name; } } } diff --git a/source/stats.h b/source/stats.h index b441aad..45e1261 100644 --- a/source/stats.h +++ b/source/stats.h @@ -2,7 +2,7 @@ #include // Para string, basic_string #include // Para vector -struct options_t; +struct Options; class Stats { diff --git a/source/text.cpp b/source/text.cpp index 5d62770..6623c23 100644 --- a/source/text.cpp +++ b/source/text.cpp @@ -147,7 +147,7 @@ void Text::write(int x, int y, std::string text, int kerning, int lenght) } // Escribe el texto con colores -void Text::writeColored(int x, int y, std::string text, color_t color, int kerning, int lenght) +void Text::writeColored(int x, int y, std::string text, Color color, int kerning, int lenght) { sprite->getTexture()->setColor(color.r, color.g, color.b); write(x, y, text, kerning, lenght); @@ -155,7 +155,7 @@ void Text::writeColored(int x, int y, std::string text, color_t color, int kerni } // Escribe el texto con sombra -void Text::writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance, int kerning, int lenght) +void Text::writeShadowed(int x, int y, std::string text, Color color, Uint8 shadowDistance, int kerning, int lenght) { sprite->getTexture()->setColor(color.r, color.g, color.b); write(x + shadowDistance, y + shadowDistance, text, kerning, lenght); @@ -171,7 +171,7 @@ void Text::writeCentered(int x, int y, std::string text, int kerning, int lenght } // Escribe texto con extras -void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, color_t textColor, Uint8 shadowDistance, color_t shadowColor, int lenght) +void Text::writeDX(Uint8 flags, int x, int y, std::string text, int kerning, Color textColor, Uint8 shadowDistance, Color shadowColor, int lenght) { const bool centered = ((flags & TXT_CENTER) == TXT_CENTER); const bool shadowed = ((flags & TXT_SHADOW) == TXT_SHADOW); diff --git a/source/text.h b/source/text.h index 011ad26..aca2550 100644 --- a/source/text.h +++ b/source/text.h @@ -54,16 +54,16 @@ public: void write(int x, int y, std::string text, int kerning = 1, int lenght = -1); // Escribe el texto con colores - void writeColored(int x, int y, std::string text, color_t color, int kerning = 1, int lenght = -1); + void writeColored(int x, int y, std::string text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con sombra - void writeShadowed(int x, int y, std::string text, color_t color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1); + void writeShadowed(int x, int y, std::string text, Color color, Uint8 shadowDistance = 1, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x void writeCentered(int x, int y, std::string text, int kerning = 1, int lenght = -1); // Escribe texto con extras - void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, color_t textColor = color_t(255, 255, 255), Uint8 shadowDistance = 1, color_t shadowColor = color_t(0, 0, 0), int lenght = -1); + void writeDX(Uint8 flags, int x, int y, std::string text, int kerning = 1, Color textColor = Color(255, 255, 255), Uint8 shadowDistance = 1, Color shadowColor = Color(0, 0, 0), int lenght = -1); // Obtiene la longitud en pixels de una cadena int lenght(std::string text, int kerning = 1); diff --git a/source/title.cpp b/source/title.cpp index 8a96fcb..9243866 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -27,11 +27,11 @@ Title::Title() input_(Input::get()) { // Reserva memoria para los punteros - if (options.palette == p_zxspectrum) + if (options.video.palette == Palette::ZXSPECTRUM) { texture_ = resource_->getTexture("title_logo.png"); } - else if (options.palette == p_zxarne) + else if (options.video.palette == Palette::ZXARNE) { texture_ = resource_->getTexture("title_logo.png"); } @@ -57,16 +57,16 @@ Title::Title() pSetSource(loading_screen_); // Inicializa variables - state_ = options.section.subsection == SUBSECTION_TITLE_WITH_LOADING_SCREEN ? show_loading_screen : show_menu; - options.section.name = SECTION_TITLE; - options.section.subsection = 0; + state_ = options.section.subsection == Subsection::TITLE_WITH_LOADING_SCREEN ? show_loading_screen : show_menu; + options.section.section = Section::TITLE; + options.section.subsection = Subsection::NONE; initMarquee(); // Crea y rellena la textura para mostrar los logros createCheevosTexture(); // Cambia el color del borde - screen_->setBorderColor(stringToColor(options.palette, "black")); + screen_->setBorderColor(stringToColor(options.video.palette, "black")); // Rellena la textura de fondo con todos los gráficos fillTexture(); @@ -107,7 +107,7 @@ void Title::checkEvents() while (SDL_PollEvent(&event)) { globalEvents::check(event); - + // Solo se comprueban estas teclas si no está activo el menu de logros if (event.type == SDL_KEYDOWN) { @@ -116,8 +116,8 @@ void Title::checkEvents() switch (event.key.keysym.scancode) { case SDL_SCANCODE_1: - options.section.name = SECTION_GAME; - options.section.subsection = 0; + options.section.section = Section::GAME; + options.section.subsection = Subsection::NONE; break; case SDL_SCANCODE_2: @@ -200,7 +200,7 @@ void Title::renderMarquee() { if (l.enabled) { - text_->writeColored(l.x, 184, l.letter, stringToColor(options.palette, "white")); + text_->writeColored(l.x, 184, l.letter, stringToColor(options.video.palette, "white")); } } } @@ -258,8 +258,8 @@ void Title::update() { if (!show_cheevos_) { - options.section.name = SECTION_CREDITS; - options.section.subsection = 0; + options.section.section = Section::CREDITS; + options.section.subsection = Subsection::NONE; } } break; @@ -275,7 +275,7 @@ void Title::render() { // Prepara para empezar a dibujar en la textura de juego screen_->start(); - screen_->clean(stringToColor(options.palette, "black")); + screen_->clean(stringToColor(options.video.palette, "black")); if (state_ == show_menu) { @@ -309,7 +309,7 @@ void Title::render() // Bucle para el logo del juego void Title::run() { - while (options.section.name == SECTION_TITLE) + while (options.section.section == Section::TITLE) { update(); checkEvents(); @@ -321,11 +321,11 @@ void Title::run() void Title::reLoadTextures() { // Carga la textura adecuada - if (options.palette == p_zxspectrum) + if (options.video.palette == Palette::ZXSPECTRUM) { texture_ = resource_->getTexture("loading_screen_color.png"); } - else if (options.palette == p_zxarne) + else if (options.video.palette == Palette::ZXARNE) { texture_ = resource_->getTexture("loading_screen_color_zxarne.png"); } @@ -336,19 +336,19 @@ void Title::reLoadTextures() // Cambia la paleta void Title::switchPalette() { - if (options.palette == p_zxspectrum) + if (options.video.palette == Palette::ZXSPECTRUM) { - options.palette = p_zxarne; + options.video.palette = Palette::ZXARNE; sprite_->setTexture(resource_->getTexture("loading_screen_color_zxarne.png")); } else { - options.palette = p_zxspectrum; + options.video.palette = Palette::ZXSPECTRUM; sprite_->setTexture(resource_->getTexture("loading_screen_color.png")); } // Cambia el color del borde - screen_->setBorderColor(stringToColor(options.palette, "bright_blue")); + screen_->setBorderColor(stringToColor(options.video.palette, "bright_blue")); } // Desplaza la lista de logros @@ -377,7 +377,7 @@ void Title::fillTexture() SDL_SetRenderTarget(renderer_, bg_texture_); // Rellena la textura de color - const color_t c = stringToColor(options.palette, "black"); + const Color c = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_RenderClear(renderer_); @@ -385,7 +385,7 @@ void Title::fillTexture() sprite_->render(); // Escribe el texto en la textura - const color_t textColor = stringToColor(options.palette, "green"); + const Color textColor = stringToColor(options.video.palette, "green"); const int textSize = text_->getCharacterSize(); text_->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, 11 * textSize, "1.PLAY", 1, textColor); text_->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, 13 * textSize, "2.ACHIEVEMENTS", 1, textColor); @@ -413,7 +413,7 @@ void Title::createCheevosTexture() cheevos_texture_->setBlendMode(SDL_BLENDMODE_BLEND); // Rellena la textura con color sólido - const color_t cheevosBGColor = stringToColor(options.palette, "black"); + const Color cheevosBGColor = stringToColor(options.video.palette, "black"); SDL_SetRenderDrawColor(renderer_, cheevosBGColor.r, cheevosBGColor.g, cheevosBGColor.b, 0xFF); SDL_RenderClear(renderer_); @@ -421,11 +421,11 @@ void Title::createCheevosTexture() const std::string cheevosOwner = "ACHIEVEMENTS"; const std::string cheevosListCaption = cheevosOwner + " (" + std::to_string(Cheevos::get()->unlocked()) + " / " + std::to_string(Cheevos::get()->count()) + ")"; int pos = 2; - info_text_->writeDX(TXT_CENTER | TXT_COLOR, cheevos_texture_->getWidth() / 2, pos, cheevosListCaption, 1, stringToColor(options.palette, "bright_green")); + info_text_->writeDX(TXT_CENTER | TXT_COLOR, cheevos_texture_->getWidth() / 2, pos, cheevosListCaption, 1, stringToColor(options.video.palette, "bright_green")); pos += info_text_->getCharacterSize(); - const color_t cheevoLockedColor = stringToColor(options.palette, "white"); - const color_t cheevoUnlockedColor = stringToColor(options.palette, "bright_green"); - color_t cheevoColor; + const Color cheevoLockedColor = stringToColor(options.video.palette, "white"); + const Color cheevoUnlockedColor = stringToColor(options.video.palette, "bright_green"); + Color cheevoColor; SDL_SetRenderDrawColor(renderer_, cheevoLockedColor.r, cheevoLockedColor.g, cheevoLockedColor.b, 0xFF); const int lineX1 = (cheevosTextureWidth / 7) * 3; const int lineX2 = lineX1 + ((cheevosTextureWidth / 7) * 1); diff --git a/source/title.h b/source/title.h index b44269e..3496095 100644 --- a/source/title.h +++ b/source/title.h @@ -16,8 +16,8 @@ class Screen; class Sprite; class Text; class Texture; -struct options_t; -struct section_t; +struct Options; +struct SectionState; class Title { @@ -37,17 +37,17 @@ private: }; // Objetos y punteros - Screen *screen_; // Objeto encargado de dibujar en pantalla - SDL_Renderer *renderer_; // El renderizador de la ventana - Resource *resource_; // Objeto con los recursos - Input *input_; // Objeto pata gestionar la entrada - Texture *texture_; // Textura con los graficos - Sprite *sprite_; // Sprite para manejar la textura - SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla - Text *text_; // Objeto para escribir texto en pantalla - Text *info_text_; // Objeto para escribir texto en pantalla - Texture *cheevos_texture_; // Textura con la lista de logros - Sprite *cheevos_sprite_; // Sprite para manejar la textura con la lista de logros + Screen *screen_; // Objeto encargado de dibujar en pantalla + SDL_Renderer *renderer_; // El renderizador de la ventana + Resource *resource_; // Objeto con los recursos + Input *input_; // Objeto pata gestionar la entrada + Texture *texture_; // Textura con los graficos + Sprite *sprite_; // Sprite para manejar la textura + SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla + Text *text_; // Objeto para escribir texto en pantalla + Text *info_text_; // Objeto para escribir texto en pantalla + Texture *cheevos_texture_; // Textura con la lista de logros + Sprite *cheevos_sprite_; // Sprite para manejar la textura con la lista de logros // Variables int counter_ = 0; // Contador diff --git a/source/utils.cpp b/source/utils.cpp index a817907..ded51be 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -1,7 +1,9 @@ #include "utils.h" -#include // Para path -#include // Para free, malloc, abs -#include // Para round, abs +#include // Para path +#include // Para free, malloc, abs +#include // Para round, abs +#include +#include // Calcula el cuadrado de la distancia entre dos puntos double distanceSquared(int x1, int y1, int x2, int y2) @@ -12,7 +14,7 @@ double distanceSquared(int x1, int y1, int x2, int y2) } // Detector de colisiones entre dos circulos -bool checkCollision(circle_t &a, circle_t &b) +bool checkCollision(Circle &a, Circle &b) { // Calcula el radio total al cuadrado int totalRadiusSquared = a.r + b.r; @@ -30,7 +32,7 @@ bool checkCollision(circle_t &a, circle_t &b) } // Detector de colisiones entre un circulo y un rectangulo -bool checkCollision(circle_t &a, SDL_Rect &b) +bool checkCollision(Circle &a, SDL_Rect &b) { // Closest point on collision box int cX, cY; @@ -350,9 +352,9 @@ bool checkCollision(SDL_Point &p, d_line_t &l) } // Devuelve un color_t a partir de un string -color_t stringToColor(palette_e pal, std::string str) +Color stringToColor(Palette pal, std::string str) { - if (pal == p_zxspectrum) + if (pal == Palette::ZXSPECTRUM) { if (str == "black") { @@ -435,8 +437,8 @@ color_t stringToColor(palette_e pal, std::string str) } } - else if (pal == p_zxarne) - { // zxarne + else if (pal == Palette::ZXARNE) + { if (str == "black") { return {0x00, 0x00, 0x00}; @@ -521,34 +523,35 @@ color_t stringToColor(palette_e pal, std::string str) return {0x00, 0x00, 0x00}; } -// Convierte una cadena en un valor booleano -bool stringToBool(std::string str) +// Convierte una cadena a un entero de forma segura +int safeStoi(const std::string &value, int defaultValue) { - if (str == "true") + try { - return true; + return std::stoi(value); } - else + catch (const std::exception &) { - return false; + return defaultValue; } } -// Convierte un valor booleano en una cadena +// Convierte una cadena a un booleano +bool stringToBool(const std::string &str) +{ + std::string lowerStr = str; + std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower); + return (lowerStr == "true" || lowerStr == "1" || lowerStr == "yes" || lowerStr == "on"); +} + +// Convierte un booleano a una cadena std::string boolToString(bool value) { - if (value) - { - return "true"; - } - else - { - return "false"; - } + return value ? "1" : "0"; } // Compara dos colores -bool colorAreEqual(color_t color1, color_t color2) +bool colorAreEqual(Color color1, Color color2) { const bool r = color1.r == color2.r; const bool g = color1.g == color2.g; diff --git a/source/utils.h b/source/utils.h index a1642f7..af49cc1 100644 --- a/source/utils.h +++ b/source/utils.h @@ -3,9 +3,17 @@ #include // Para SDL_Rect, SDL_Point #include // Para Uint8, Uint32 #include // Para string, basic_string +#include // Para vector + +// Tipos de paleta +enum class Palette : int +{ + ZXSPECTRUM, + ZXARNE +}; // Estructura para definir un circulo -struct circle_t +struct Circle { int x; int y; @@ -36,25 +44,18 @@ struct line_t int x1, y1, x2, y2; }; -// Tipos de paleta -enum palette_e -{ - p_zxspectrum, - p_zxarne -}; - // Estructura para definir un color -struct color_t +struct Color { Uint8 r; Uint8 g; Uint8 b; // Constructor por defecto - color_t() : r(0), g(0), b(0) {} + Color() : r(0), g(0), b(0) {} // Constructor - color_t(Uint8 red, Uint8 green, Uint8 blue) + Color(Uint8 red, Uint8 green, Uint8 blue) : r(red), g(green), b(blue) {} }; @@ -62,10 +63,10 @@ struct color_t double distanceSquared(int x1, int y1, int x2, int y2); // Detector de colisiones entre dos circulos -bool checkCollision(circle_t &a, circle_t &b); +bool checkCollision(Circle &a, Circle &b); // Detector de colisiones entre un circulo y un rectangulo -bool checkCollision(circle_t &a, SDL_Rect &b); +bool checkCollision(Circle &a, SDL_Rect &b); // Detector de colisiones entre un dos rectangulos bool checkCollision(SDL_Rect &a, SDL_Rect &b); @@ -95,16 +96,19 @@ bool checkCollision(SDL_Point &p, d_line_t &l); void normalizeLine(d_line_t &l); // Devuelve un color_t a partir de un string -color_t stringToColor(palette_e pal, std::string str); +Color stringToColor(Palette pal, std::string str); -// Convierte una cadena en un valor booleano -bool stringToBool(std::string str); +// Convierte una cadena a un entero de forma segura +int safeStoi(const std::string &value, int defaultValue = 0); -// Convierte un valor booleano en una cadena +// Convierte una cadena a un booleano +bool stringToBool(const std::string &str); + +// Convierte un booleano a una cadena std::string boolToString(bool value); // Compara dos colores -bool colorAreEqual(color_t color1, color_t color2); +bool colorAreEqual(Color color1, Color color2); // Convierte una cadena a minusculas std::string toLower(std::string str);