From 0d27774c74d87d01a44ab1aa0ca10c6fac73df93 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 29 Aug 2022 20:57:28 +0200 Subject: [PATCH] Eliminado el fichero const.h --- source/const.h | 97 --------------- source/director.cpp | 287 +++++++++++++------------------------------- source/director.h | 28 ++--- source/game.cpp | 4 +- source/game.h | 2 +- source/room.h | 28 ++--- source/screen.cpp | 118 ++++++++++++++---- source/screen.h | 29 +++-- source/utils.cpp | 51 ++++++-- source/utils.h | 53 ++++---- 10 files changed, 289 insertions(+), 408 deletions(-) delete mode 100644 source/const.h diff --git a/source/const.h b/source/const.h deleted file mode 100644 index f496a94..0000000 --- a/source/const.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once -#include -#include -#include "utils.h" - -#ifndef CONST_H -#define CONST_H - -// Textos -#define WINDOW_CAPTION "JailDoctor's Dilemma" -#define TEXT_COPYRIGHT "@2022 JailDesigner" -#define VERSION "0.1" - -// Tamaño de bloque -#define BLOCK 8 -#define HALF_BLOCK 4 - -// Tamaño de la pantalla real -#define SCREEN_WIDTH 256 -#define SCREEN_HEIGHT 192 - -// Tamaño de la pantalla virtual -#define GAMECANVAS_WIDTH 256 -#define GAMECANVAS_HEIGHT 192 - -// Tamaño de la pantalla que se muestra -const int VIEW_WIDTH = SCREEN_WIDTH * 3; -const int VIEW_HEIGHT = SCREEN_HEIGHT * 3; - -// Zona de juego -const int PLAY_AREA_TOP = (0 * BLOCK); -const int PLAY_AREA_BOTTOM = (16 * BLOCK); -const int PLAY_AREA_LEFT = (0 * BLOCK); -const int PLAY_AREA_RIGHT = (32 * BLOCK); -const int PLAY_AREA_WIDTH = PLAY_AREA_RIGHT - PLAY_AREA_LEFT; -const int PLAY_AREA_HEIGHT = PLAY_AREA_BOTTOM - PLAY_AREA_TOP; -const int PLAY_AREA_CENTER_X = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2); -const int PLAY_AREA_CENTER_FIRST_QUARTER_X = (PLAY_AREA_WIDTH / 4); -const int PLAY_AREA_CENTER_THIRD_QUARTER_X = (PLAY_AREA_WIDTH / 4) * 3; -const int PLAY_AREA_CENTER_Y = PLAY_AREA_TOP + (PLAY_AREA_HEIGHT / 2); -const int PLAY_AREA_FIRST_QUARTER_Y = PLAY_AREA_HEIGHT / 4; -const int PLAY_AREA_THIRD_QUARTER_Y = (PLAY_AREA_HEIGHT / 4) * 3; - -#define BORDER_TOP 0 -#define BORDER_RIGHT 1 -#define BORDER_BOTTOM 2 -#define BORDER_LEFT 3 - -// Anclajes de pantalla -const int GAMECANVAS_CENTER_X = GAMECANVAS_WIDTH / 2; -const int GAMECANVAS_FIRST_QUARTER_X = GAMECANVAS_WIDTH / 4; -const int GAMECANVAS_THIRD_QUARTER_X = (GAMECANVAS_WIDTH / 4) * 3; -const int GAMECANVAS_CENTER_Y = GAMECANVAS_HEIGHT / 2; -const int GAMECANVAS_FIRST_QUARTER_Y = GAMECANVAS_HEIGHT / 4; -const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3; - -// Secciones del programa -#define SECTION_PROG_LOGO 0 -#define SECTION_PROG_INTRO 1 -#define SECTION_PROG_TITLE 2 -#define SECTION_PROG_GAME 3 -#define SECTION_PROG_QUIT 4 - -// Subsecciones -#define SECTION_GAME_PLAY 0 -#define SECTION_GAME_PAUSE 1 -#define SECTION_GAME_GAMEOVER 2 -#define SECTION_TITLE_1 3 -#define SECTION_TITLE_2 4 -#define SECTION_TITLE_3 5 -#define SECTION_TITLE_INSTRUCTIONS 6 - -// Estados de cada elemento que pertenece a un evento -#define EVENT_WAITING 1 -#define EVENT_RUNNING 2 -#define EVENT_COMPLETED 3 - -// Estados de entrada -#define INPUT_NULL 0 -#define INPUT_FIRE_LEFT 7 -#define INPUT_FIRE_UP 8 -#define INPUT_FIRE_RIGHT 9 -#define INPUT_PAUSE 10 - -// Zona muerta del mando analógico -#define JOYSTICK_DEAD_ZONE 8000 - -// Colores -const color_t bgColor = {0x27, 0x27, 0x36}; -const color_t noColor = {0xFF, 0xFF, 0xFF}; -const color_t shdwTxtColor = {0x43, 0x43, 0x4F}; - -// Tipo de filtro -#define FILTER_NEAREST 0 -#define FILTER_LINEAL 1 - -#endif \ No newline at end of file diff --git a/source/director.cpp b/source/director.cpp index 1a99f93..a6911ae 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -11,31 +11,29 @@ Director::Director(std::string path) setExecutablePath(path); // Crea el objeto que controla los ficheros de recursos - mAsset = new Asset(mExecutablePath); + asset = new Asset(executablePath); // Establece la lista de ficheros setFileList(); // Si falta algún fichero no inicia el programa Uint8 section = SECTION_PROG_GAME; - if (!mAsset->check()) + if (!asset->check()) section = SECTION_PROG_QUIT; // Crea el puntero a la estructura y carga el fichero de configuración - mOptions = new options_t; - if (!loadConfigFile()) - { - mOptions->fullScreenMode = 0; - mOptions->windowSize = 3; - mOptions->difficulty = DIFFICULTY_NORMAL; - mOptions->input[0].deviceType = INPUT_USE_KEYBOARD; - mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; - mOptions->filter = FILTER_NEAREST; - mOptions->vSync = true; - } + options = new options_t; + options->fullScreenMode = 0; + options->windowSize = 2; + options->filter = FILTER_NEAREST; + options->vSync = true; + options->screenWidth = GAME_WIDTH * options->windowSize; + options->screenHeight = GAME_HEIGHT * options->windowSize; + options->integerScale = true; + options->keepAspect = true; // Crea los objetos - mInput = new Input(mAsset->get("gamecontrollerdb.txt")); + input = new Input(asset->get("gamecontrollerdb.txt")); // Inicializa SDL initSDL(); @@ -44,8 +42,8 @@ Director::Director(std::string path) initJailAudio(); // Aplica las opciones - SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); - SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize); + SDL_SetWindowFullscreen(window, options->fullScreenMode); + SDL_SetWindowSize(window, SCREEN_WIDTH * options->windowSize, SCREEN_HEIGHT * options->windowSize); // Inicializa el resto de variables init(section); @@ -53,22 +51,13 @@ Director::Director(std::string path) Director::~Director() { - saveConfigFile(); - - delete mInput; - mInput = nullptr; - - delete mOptions; - mOptions = nullptr; - - delete mAsset; - mAsset = nullptr; - - SDL_DestroyRenderer(mRenderer); - SDL_DestroyWindow(mWindow); - mRenderer = nullptr; - mWindow = nullptr; + delete options; + delete asset; + delete input; + delete screen; + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); SDL_Quit(); } @@ -76,30 +65,30 @@ Director::~Director() void Director::init(Uint8 name) { // Sección - mSection.name = name; - mSection.subsection = 0; + section.name = name; + section.subsection = 0; // Controles - mInput->bindKey(INPUT_UP, SDL_SCANCODE_UP); - mInput->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN); - mInput->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT); - mInput->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT); - mInput->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN); - mInput->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE); - mInput->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_SPACE); - mInput->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_D); - mInput->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); - mInput->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); + input->bindKey(INPUT_UP, SDL_SCANCODE_UP); + input->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN); + input->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT); + input->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT); + input->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN); + input->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE); + input->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_SPACE); + input->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_D); + input->bindKey(INPUT_BUTTON_PAUSE, SDL_SCANCODE_ESCAPE); + input->bindKey(INPUT_BUTTON_ESCAPE, SDL_SCANCODE_ESCAPE); - mInput->bindGameControllerButton(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP); - mInput->bindGameControllerButton(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN); - mInput->bindGameControllerButton(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT); - mInput->bindGameControllerButton(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); - mInput->bindGameControllerButton(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B); - mInput->bindGameControllerButton(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A); - mInput->bindGameControllerButton(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_B); - mInput->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); - mInput->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); + input->bindGameControllerButton(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP); + input->bindGameControllerButton(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN); + input->bindGameControllerButton(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT); + input->bindGameControllerButton(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + input->bindGameControllerButton(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_B); + input->bindGameControllerButton(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_A); + input->bindGameControllerButton(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_B); + input->bindGameControllerButton(INPUT_BUTTON_PAUSE, SDL_CONTROLLER_BUTTON_GUIDE); + input->bindGameControllerButton(INPUT_BUTTON_ESCAPE, SDL_CONTROLLER_BUTTON_GUIDE); } // Inicializa JailAudio @@ -127,14 +116,14 @@ 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(mOptions->filter).c_str())) + if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(options->filter).c_str())) { printf("Warning: Nearest texture filtering not enabled!\n"); } // Crea la ventana - mWindow = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); - if (mWindow == NULL) + window = SDL_CreateWindow(WINDOW_CAPTION, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, VIEW_WIDTH, VIEW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + if (window == NULL) { printf("Window could not be created!\nSDL Error: %s\n", SDL_GetError()); success = false; @@ -142,12 +131,12 @@ bool Director::initSDL() else { // Crea un renderizador para la ventana. El vsync se activa en funcion de las opciones - if (mOptions->vSync) - mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + if (options->vSync) + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); else - mRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_ACCELERATED); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - if (mRenderer == NULL) + if (renderer == NULL) { printf("Renderer could not be created!\nSDL Error: %s\n", SDL_GetError()); success = false; @@ -155,13 +144,13 @@ bool Director::initSDL() else { // Inicializa el color de renderizado - SDL_SetRenderDrawColor(mRenderer, 0x00, 0x00, 0x00, 0xFF); + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); // Establece el tamaño del buffer de renderizado - SDL_RenderSetLogicalSize(mRenderer, SCREEN_WIDTH, SCREEN_HEIGHT); + SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); // Establece el modo de mezcla - SDL_SetRenderDrawBlendMode(mRenderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); } } } @@ -173,165 +162,55 @@ bool Director::initSDL() // Crea el indice de ficheros void Director::setFileList() { - mAsset->add("/media/font/smb2.png", font); - mAsset->add("/media/font/smb2.txt", font); - mAsset->add("/media/font/debug.png", font); - mAsset->add("/media/font/debug.txt", font); - mAsset->add("/data/gamecontrollerdb.txt", data); - mAsset->add("/data/config.bin", data, false); - mAsset->add("/data/room/01.room", room); - mAsset->add("/data/room/02.room", room); - mAsset->add("/data/room/03.room", room); - mAsset->add("/data/room/04.room", room); - mAsset->add("/data/room/05.room", room); - mAsset->add("/data/room/01.tmx", room); - mAsset->add("/data/room/02.tmx", room); - mAsset->add("/data/room/03.tmx", room); - mAsset->add("/data/room/04.tmx", room); - mAsset->add("/data/room/05.tmx", room); - mAsset->add("/media/tilesets/standard.png", bitmap); - mAsset->add("/media/enemies/paco.png", bitmap); - mAsset->add("/media/enemies/paco.ani", data); - mAsset->add("/media/enemies/chip.png", bitmap); - mAsset->add("/media/enemies/chip.ani", data); - mAsset->add("/media/enemies/wave.png", bitmap); - mAsset->add("/media/enemies/wave.ani", data); - mAsset->add("/media/player/player01.png", bitmap); - mAsset->add("/media/player/player01.ani", data); - mAsset->add("/media/items/items.png", bitmap); -} - -// Carga el fichero de configuración -bool Director::loadConfigFile() -{ - // Pone unos valores por defecto - mOptions->fullScreenMode = 0; - mOptions->windowSize = 3; - mOptions->difficulty = DIFFICULTY_NORMAL; - mOptions->input[0].deviceType = INPUT_USE_KEYBOARD; - mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; - mOptions->filter = FILTER_NEAREST; - mOptions->vSync = true; - - // Indicador de éxito en la carga - bool success = true; - - const std::string p = mAsset->get("config.bin"); - std::string filename = p.substr(p.find_last_of("\\/") + 1); - SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b"); - - // El fichero no existe - if (file == NULL) - { - printf("Warning: Unable to open %s file\n", filename.c_str()); - - // Crea el fichero para escritura - file = SDL_RWFromFile(p.c_str(), "w+b"); - if (file != NULL) - { - printf("New file (%s) created!\n", filename.c_str()); - - // Escribe los datos - SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); - SDL_RWwrite(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1); - SDL_RWwrite(file, &mOptions->language, sizeof(mOptions->language), 1); - SDL_RWwrite(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1); - SDL_RWwrite(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1); - SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); - SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); - SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); - - // Cierra el fichero - SDL_RWclose(file); - } - else - { - printf("Error: Unable to create file %s\n", filename.c_str()); - success = false; - } - } - // El fichero existe - else - { - // Carga los datos - printf("Reading file %s\n", filename.c_str()); - SDL_RWread(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); - SDL_RWread(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1); - SDL_RWread(file, &mOptions->language, sizeof(mOptions->language), 1); - SDL_RWread(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1); - SDL_RWread(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1); - SDL_RWread(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); - SDL_RWread(file, &mOptions->filter, sizeof(mOptions->filter), 1); - SDL_RWread(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); - - // Normaliza los valores - if (!((mOptions->fullScreenMode == 0) || - (mOptions->fullScreenMode == SDL_WINDOW_FULLSCREEN) || - (mOptions->fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP))) - mOptions->fullScreenMode = 0; - if ((mOptions->windowSize < 1) || (mOptions->windowSize > 4)) - mOptions->windowSize = 3; - - // Cierra el fichero - SDL_RWclose(file); - } - - return success; -} - -// Guarda el fichero de configuración -bool Director::saveConfigFile() -{ - bool success = true; - const std::string p = mAsset->get("config.bin"); - std::string filename = p.substr(p.find_last_of("\\/") + 1); - SDL_RWops *file = SDL_RWFromFile(p.c_str(), "w+b"); - if (file != NULL) - { - // Guarda los datos - SDL_RWwrite(file, &mOptions->fullScreenMode, sizeof(mOptions->fullScreenMode), 1); - SDL_RWwrite(file, &mOptions->windowSize, sizeof(mOptions->windowSize), 1); - SDL_RWwrite(file, &mOptions->language, sizeof(mOptions->language), 1); - SDL_RWwrite(file, &mOptions->difficulty, sizeof(mOptions->difficulty), 1); - SDL_RWwrite(file, &mOptions->input[0].deviceType, sizeof(mOptions->input[0].deviceType), 1); - SDL_RWwrite(file, &mOptions->input[1].deviceType, sizeof(mOptions->input[1].deviceType), 1); - SDL_RWwrite(file, &mOptions->filter, sizeof(mOptions->filter), 1); - SDL_RWwrite(file, &mOptions->vSync, sizeof(mOptions->vSync), 1); - - printf("Writing file %s\n", filename.c_str()); - - // Cierra el fichero - SDL_RWclose(file); - } - else - { - printf("Error: Unable to save %s file! %s\n", filename.c_str(), SDL_GetError()); - } - return success; + asset->add("/media/font/smb2.png", font); + asset->add("/media/font/smb2.txt", font); + asset->add("/media/font/debug.png", font); + asset->add("/media/font/debug.txt", font); + asset->add("/data/gamecontrollerdb.txt", data); + asset->add("/data/room/01.room", room); + asset->add("/data/room/02.room", room); + asset->add("/data/room/03.room", room); + asset->add("/data/room/04.room", room); + asset->add("/data/room/05.room", room); + asset->add("/data/room/01.tmx", room); + asset->add("/data/room/02.tmx", room); + asset->add("/data/room/03.tmx", room); + asset->add("/data/room/04.tmx", room); + asset->add("/data/room/05.tmx", room); + asset->add("/media/tilesets/standard.png", bitmap); + asset->add("/media/enemies/paco.png", bitmap); + asset->add("/media/enemies/paco.ani", data); + asset->add("/media/enemies/chip.png", bitmap); + asset->add("/media/enemies/chip.ani", data); + asset->add("/media/enemies/wave.png", bitmap); + asset->add("/media/enemies/wave.ani", data); + asset->add("/media/player/player01.png", bitmap); + asset->add("/media/player/player01.ani", data); + asset->add("/media/items/items.png", bitmap); } // Establece el valor de la variable void Director::setExecutablePath(std::string path) { - mExecutablePath = path.substr(0, path.find_last_of("\\/")); + executablePath = path.substr(0, path.find_last_of("\\/")); } // Obtiene el valor de la variable Uint8 Director::getSubsection() { - return mSection.subsection; + return section.subsection; } // Obtiene el valor de la variable Uint8 Director::getSection() { - return mSection.name; + return section.name; } // Establece el valor de la variable void Director::setSection(section_t section) { - mSection = section; + section = section; } void Director::runLogo() @@ -348,9 +227,9 @@ void Director::runTitle() void Director::runGame() { - mGame = new Game(mWindow, mRenderer, mAsset, mInput); - setSection(mGame->run()); - delete mGame; + game = new Game(renderer, screen, asset, input); + setSection(game->run()); + delete game; } void Director::run() diff --git a/source/director.h b/source/director.h index 7528e91..1117afb 100644 --- a/source/director.h +++ b/source/director.h @@ -14,23 +14,25 @@ #ifndef DIRECTOR_H #define DIRECTOR_H -#define MAX_FILE_LIST 100 +#define WINDOW_CAPTION "JailDoctor's Dilemma" +#define GAME_WIDTH 320 +#define GAME_HEIGHT 240 // Director class Director { private: - SDL_Window *mWindow; // La ventana donde dibujamos - SDL_Renderer *mRenderer; // El renderizador de la ventana + SDL_Window *window; // La ventana donde dibujamos + SDL_Renderer *renderer; // El renderizador de la ventana + Screen *screen; // Objeto encargado de dibujar en pantalla + Input *input; // Objeto Input para gestionar las entradas + Game *game; // Objeto para la sección del juego + Asset *asset; // Objeto que gestiona todos los ficheros de recursos - Input *mInput; // Objeto Input para gestionar las entradas - Game *mGame; // Objeto para la sección del juego - Asset *mAsset; // Objeto que gestiona todos los ficheros de recursos + struct options_t *options; // Variable con todas las opciones del programa - struct options_t *mOptions; // Variable con todas las opciones del programa - - std::string mExecutablePath; // Path del ejecutable - section_t mSection; // Sección y subsección actual del programa; + std::string executablePath; // Path del ejecutable + section_t section; // Sección y subsección actual del programa; // Inicia las variables necesarias para arrancar el programa void init(Uint8 name); @@ -47,12 +49,6 @@ private: // Comprueba que todos los ficheros existen bool checkFileList(); - // Carga el fichero de configuración - bool loadConfigFile(); - - // Guarda el fichero de configuración - bool saveConfigFile(); - // Establece el valor de la variable void setExecutablePath(std::string path); diff --git a/source/game.cpp b/source/game.cpp index d95d073..2556c4f 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -1,7 +1,7 @@ #include "game.h" // Constructor -Game::Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Input *input) +Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input) { // Inicia variables currentRoom = "01.room"; @@ -11,10 +11,10 @@ Game::Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Input *inpu // Copia los punteros this->renderer = renderer; this->asset = asset; + this->screen = screen; this->input = input; // Crea los objetos - screen = new Screen(window, renderer); itemTracker = new ItemTracker(); room = new Room(asset->get(currentRoom), renderer, asset, itemTracker); player = new Player(spawnPoint, asset->get("player01.png"), asset->get("player01.ani"), renderer, asset, input, room); diff --git a/source/game.h b/source/game.h index e84a09f..f70d174 100644 --- a/source/game.h +++ b/source/game.h @@ -69,7 +69,7 @@ private: public: // Constructor - Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Input *input); + Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input); // Destructor ~Game(); diff --git a/source/room.h b/source/room.h index a410f0d..c432273 100644 --- a/source/room.h +++ b/source/room.h @@ -35,21 +35,21 @@ LISTADO DE ITEMS (tipo, posicion) class Room { private: - std::string name; // Nombre de la habitación - color_t bgColor; // Color de fondo de la habitación - std::string roomUp; // Identificador de la habitación que se encuentra arriba - std::string roomDown; // Identificador de la habitación que se encuentra abajp - std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda - std::string roomRight; // Identificador de la habitación que se encuentra a la derecha - std::string tileset; // Imagen con los graficos para la habitación - std::vector tilemap; // Indice de los tiles a dibujar en la habitación + std::string name; // Nombre de la habitación + color_t bgColor; // Color de fondo de la habitación + std::string roomUp; // Identificador de la habitación que se encuentra arriba + std::string roomDown; // Identificador de la habitación que se encuentra abajp + std::string roomLeft; // Identificador de la habitación que se encuentra a la izquierda + std::string roomRight; // Identificador de la habitación que se encuentra a la derecha + std::string tileset; // Imagen con los graficos para la habitación + std::vector tilemap; // Indice de los tiles a dibujar en la habitación std::vector enemies; // Listado con los enemigos de la habitación - std::vector items; // Listado con los items que hay en la habitación - LTexture *texture; // Textura con los graficos de la habitación - Asset *asset; // Objeto con la ruta a todos los ficheros de recursos - ItemTracker *itemTracker; // Lleva el control de los objetos recogidos - SDL_Renderer *renderer; // El renderizador de la ventana - SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación + std::vector items; // Listado con los items que hay en la habitación + LTexture *texture; // Textura con los graficos de la habitación + Asset *asset; // Objeto con la ruta a todos los ficheros de recursos + ItemTracker *itemTracker; // Lleva el control de los objetos recogidos + SDL_Renderer *renderer; // El renderizador de la ventana + SDL_Texture *mapTexture; // Textura para dibujar el mapa de la habitación // Carga las variables desde un fichero bool load(std::string file_path); diff --git a/source/screen.cpp b/source/screen.cpp index 821f5ff..4f71934 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -1,63 +1,133 @@ #include "screen.h" #include "const.h" +#include +#include // Constructor -Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) +Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options) { // Inicializa variables - mWindow = window; - mRenderer = renderer; + this->window = window; + this->renderer = renderer; + this->options = options; - mScreenWidth = SCREEN_WIDTH; - mScreenHeight = SCREEN_HEIGHT; - mGameCanvasWidth = GAMECANVAS_WIDTH; - mGameCanvasHeight = GAMECANVAS_HEIGHT; - mGameCanvasPosX = (SCREEN_WIDTH - GAMECANVAS_WIDTH) / 2; - mGameCanvasPosY = (SCREEN_HEIGHT - GAMECANVAS_HEIGHT) / 2; + gameCanvasWidth = SCREEN_WIDTH; + gameCanvasHeight = SCREEN_HEIGHT; - mBorderColor = {0x27, 0x27, 0x36}; + // Establece el modo de video + setVideoMode(options->fullScreenMode); + + // Define el color del borde para el modo de pantalla completa + borderColor = {0x27, 0x27, 0x36}; + borderColor = {0x00, 0x00, 0x00}; // Crea la textura donde se dibujan los graficos del juego - mGameCanvas = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); - if (mGameCanvas == NULL) + gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight); + if (gameCanvas == NULL) printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError()); } // Destructor Screen::~Screen() { - mRenderer = nullptr; + renderer = nullptr; } // Limpia la pantalla void Screen::clean(color_t color) { - SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF); - SDL_RenderClear(mRenderer); + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); + SDL_RenderClear(renderer); } // Prepara para empezar a dibujar en la textura de juego void Screen::start() { - SDL_SetRenderTarget(mRenderer, mGameCanvas); + SDL_SetRenderTarget(renderer, gameCanvas); } // Vuelca el contenido del renderizador en pantalla void Screen::blit() { // Vuelve a dejar el renderizador en modo normal - SDL_SetRenderTarget(mRenderer, NULL); + SDL_SetRenderTarget(renderer, NULL); // Borra el contenido previo - SDL_SetRenderDrawColor(mRenderer, mBorderColor.r, mBorderColor.g, mBorderColor.b, 0xFF); - SDL_RenderClear(mRenderer); - - // Rectangulo de destino donde se dibujarà la textura con el juego - SDL_Rect dest = {mGameCanvasPosX, mGameCanvasPosY, mGameCanvasWidth, mGameCanvasHeight}; + SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, 0xFF); + SDL_RenderClear(renderer); // Copia la textura de juego en el renderizador en la posición adecuada - SDL_RenderCopy(mRenderer, mGameCanvas, NULL, &dest); + SDL_RenderCopy(renderer, gameCanvas, NULL, &dest); // Muestra por pantalla el renderizador - SDL_RenderPresent(mRenderer); + SDL_RenderPresent(renderer); +} + +// Establece el modo de video +void Screen::setVideoMode(int fullScreenMode) +{ + // Aplica el modo de video + SDL_SetWindowFullscreen(window, fullScreenMode); + + // Si está activo el modo ventana quita el borde + if (fullScreenMode == 0) + { + screenWidth = gameCanvasWidth; + screenHeight = gameCanvasHeight; + dest = {0, 0, gameCanvasWidth, gameCanvasHeight}; + + // Modifica el tamaño del renderizador y de la ventana + SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); + SDL_SetWindowSize(window, screenWidth * options->windowSize, screenHeight * options->windowSize); + } + + // Si está activo el modo de pantalla completa añade el borde + if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) + { + // Obten el alto y el ancho de la ventana + SDL_GetWindowSize(window, &screenWidth, &screenHeight); + + // Aplica el escalado al rectangulo donde se pinta la textura del juego + if (options->integerScale) + { + // Calcula el tamaño de la escala máxima + int scale = 0; + while (((gameCanvasWidth * (scale + 1)) <= screenWidth) && ((gameCanvasHeight * (scale + 1)) <= screenHeight)) + { + scale++; + } + + dest.w = gameCanvasWidth * scale; + dest.h = gameCanvasHeight * scale; + dest.x = (screenWidth - dest.w) / 2; + dest.y = (screenHeight - dest.h) / 2; + } + else if (options->keepAspect) + { + float ratio = (float)gameCanvasWidth / (float)gameCanvasHeight; + if ((screenWidth - gameCanvasWidth) >= (screenHeight - gameCanvasHeight)) + { + dest.h = screenHeight; + dest.w = (int)((screenHeight * ratio) + 0.5f); + dest.x = (screenWidth - dest.w) / 2; + dest.y = (screenHeight - dest.h) / 2; + } + else + { + dest.w = screenWidth; + dest.h = (int)((screenWidth / ratio) + 0.5f); + dest.x = (screenWidth - dest.w) / 2; + dest.y = (screenHeight - dest.h) / 2; + } + } + else + { + dest.w = screenWidth; + dest.h = screenHeight; + dest.x = dest.y = 0; + } + + // Modifica el tamaño del renderizador + SDL_RenderSetLogicalSize(renderer, screenWidth, screenHeight); + } } \ No newline at end of file diff --git a/source/screen.h b/source/screen.h index 102b497..04f416f 100644 --- a/source/screen.h +++ b/source/screen.h @@ -1,4 +1,5 @@ #pragma once + #include #include "utils.h" @@ -9,34 +10,36 @@ class Screen { private: - SDL_Window *mWindow; // Ventana de la aplicación - SDL_Renderer *mRenderer; // El renderizador de la ventana - SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa + SDL_Window *window; // Ventana de la aplicación + SDL_Renderer *renderer; // El renderizador de la ventana + SDL_Texture *gameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa + options_t *options; // Variable con todas las opciones del programa - int mScreenWidth; // Ancho de la pantalla - int mScreenHeight; // Alto de la pantalla - int mGameCanvasWidth; // Ancho de la textura donde se dibuja el juego - int mGameCanvasHeight; // Alto de la textura donde se dibuja el juego - int mGameCanvasPosX; // Posicion en el eje X donde se dibujará la textura del juego dentro de la pantalla - int mGameCanvasPosY; // Posicion en el eje Y donde se dibujará la textura del juego dentro de la pantalla - - color_t mBorderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla + int screenWidth; // Ancho de la pantalla + int screenHeight; // Alto de la pantalla + int gameCanvasWidth; // Ancho de la textura donde se dibuja el juego + int gameCanvasHeight; // Alto de la textura donde se dibuja el juego + SDL_Rect dest; // Coordenadas donde se va a dibujar la textura del juego + color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla public: // Constructor - Screen(SDL_Window *windows, SDL_Renderer *renderer); + Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options); // Destructor ~Screen(); // Limpia la pantalla - void clean(color_t color); + void clean(color_t color = {0x00, 0x00, 0x00}); // Prepara para empezar a dibujar en la textura de juego void start(); // Vuelca el contenido del renderizador en pantalla void blit(); + + // Establece el modo de video + void setVideoMode(int fullScreenMode); }; #endif diff --git a/source/utils.cpp b/source/utils.cpp index a90cf2d..36b15cb 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -3,8 +3,8 @@ // Calcula el cuadrado de la distancia entre dos puntos double distanceSquared(int x1, int y1, int x2, int y2) { - int deltaX = x2 - x1; - int deltaY = y2 - y1; + const int deltaX = x2 - x1; + const int deltaY = y2 - y1; return deltaX * deltaX + deltaY * deltaY; } @@ -71,20 +71,20 @@ bool checkCollision(circle_t &a, SDL_Rect &b) return false; } -// Detector de colisiones entre un dos rectangulos +// Detector de colisiones entre dos rectangulos bool checkCollision(SDL_Rect &a, SDL_Rect &b) { // Calculate the sides of rect A - int leftA = a.x; - int rightA = a.x + a.w; - int topA = a.y; - int bottomA = a.y + a.h; + const int leftA = a.x; + const int rightA = a.x + a.w; + const int topA = a.y; + const int bottomA = a.y + a.h; // Calculate the sides of rect B - int leftB = b.x; - int rightB = b.x + b.w; - int topB = b.y; - int bottomB = b.y + b.h; + const int leftB = b.x; + const int rightB = b.x + b.w; + const int topB = b.y; + const int bottomB = b.y + b.h; // If any of the sides from A are outside of B if (bottomA <= topB) @@ -111,6 +111,35 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b) return true; } +// Detector de colisiones entre un punto y u rectangulo +bool checkCollision(SDL_Point &p, SDL_Rect &r) +{ + // Comprueba si el punto está fuera del rectangulo en el eje X + if (p.x < r.x) + { + return false; + } + + if (p.x > r.x + r.w) + { + return false; + } + + // Comprueba si el punto está fuera del rectangulo en el eje Y + if (p.y < r.y) + { + return false; + } + + if (p.y > r.y + r.h) + { + return false; + } + + // Si ha llegado hasta aquí, es que está dentro + return true; +} + // Carga un archivo de imagen en una textura bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer) { diff --git a/source/utils.h b/source/utils.h index 1e859c0..2acf21f 100644 --- a/source/utils.h +++ b/source/utils.h @@ -1,4 +1,5 @@ #pragma once + #include #include "ltexture.h" #include @@ -6,9 +7,24 @@ #ifndef UTILS_H #define UTILS_H -#define DIFFICULTY_EASY 0 -#define DIFFICULTY_NORMAL 1 -#define DIFFICULTY_HARD 2 +#define FILTER_NEAREST 0 +#define FILTER_LINEAL 1 + +// Secciones del programa +#define SECTION_PROG_LOGO 0 +#define SECTION_PROG_INTRO 1 +#define SECTION_PROG_TITLE 2 +#define SECTION_PROG_GAME 3 +#define SECTION_PROG_QUIT 4 + +// Subsecciones +#define SUBSECTION_GAME_PLAY 0 +#define SUBSECTION_GAME_PAUSE 1 +#define SUBSECTION_GAME_GAMEOVER 2 +#define SUBSECTION_TITLE_1 3 +#define SUBSECTION_TITLE_2 4 +#define SUBSECTION_TITLE_3 5 +#define SUBSECTION_TITLE_INSTRUCTIONS 6 // Estructura para definir un circulo struct circle_t @@ -33,35 +49,17 @@ struct section_t Uint8 subsection; }; -// Estructura para mapear el teclado usado en la demo -struct demoKeys_t -{ - Uint8 left; - Uint8 right; - Uint8 noInput; - Uint8 fire; - Uint8 fireLeft; - Uint8 fireRight; -}; - -// Estructura para albergar métodos de control -struct input_t -{ - int id; // Identificador en el vector de mandos - std::string name; // Nombre del dispositivo - Uint8 deviceType; // Tipo de dispositivo (teclado o mando) -}; - // Estructura con todas las opciones de configuración del programa struct options_t { - Uint8 difficulty; // Dificultad del juego - input_t input[2]; // Modo de control (teclado o mando) - Uint8 language; // Idioma usado en el juego Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa - Uint8 windowSize; // Contiene el valor del tamaño de la ventana + 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 + int screenWidth; // Ancho de la pantalla/ventana + int screenHeight; // Alto de la pantalla/ventana + 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 }; // Calcula el cuadrado de la distancia entre dos puntos @@ -76,6 +74,9 @@ bool checkCollision(circle_t &a, SDL_Rect &b); // Detector de colisiones entre un dos rectangulos bool checkCollision(SDL_Rect &a, SDL_Rect &b); +// Detector de colisiones entre un punto y u rectangulo +bool checkCollision(SDL_Point &p, SDL_Rect &r); + // Carga un archivo de imagen en una textura bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer);