diff --git a/data/map/01 - copia.tmx b/data/map/01 - copia.tmx
new file mode 100644
index 0000000..c8bd17e
--- /dev/null
+++ b/data/map/01 - copia.tmx
@@ -0,0 +1,38 @@
+
+
diff --git a/data/map/01.map b/data/map/01.map
new file mode 100644
index 0000000..fb09aba
--- /dev/null
+++ b/data/map/01.map
@@ -0,0 +1,11 @@
+tileset_img=tiles_surface.png
+bg_img=bg_surface.png
+
+room_up=0
+room_down=0
+room_left=0
+room_right=0
+
+[tilemap]
+01.tmx
+[tilemap-end]
\ No newline at end of file
diff --git a/data/map/01.tmx b/data/map/01.tmx
new file mode 100644
index 0000000..698e5b5
--- /dev/null
+++ b/data/map/01.tmx
@@ -0,0 +1,21 @@
+
+
diff --git a/data/volcano.map b/data/volcano.map
deleted file mode 100644
index fc53dab..0000000
Binary files a/data/volcano.map and /dev/null differ
diff --git a/source/const.h b/source/const.h
index b318fe5..aea615f 100644
--- a/source/const.h
+++ b/source/const.h
@@ -3,12 +3,9 @@
#ifndef CONST_H
#define CONST_H
-// Textos
-#define WINDOW_CAPTION "Volcano (©2016,2022 JailDesigner v0.6)"
-
// Tamaño de bloque
-#define BLOCK 8
-#define HALF_BLOCK 4
+#define BLOCK 16
+#define HALF_BLOCK 8
// Tamaño de la pantalla real
#define SCREEN_WIDTH 320
diff --git a/source/game.cpp b/source/game.cpp
index 0d3af22..8df6571 100644
--- a/source/game.cpp
+++ b/source/game.cpp
@@ -3,19 +3,21 @@
// Constructor
Game::Game(SDL_Renderer *renderer, Asset *asset, Screen *screen, Input *input)
{
-
+
this->renderer = renderer;
this->asset = asset;
this->screen = screen;
this->input = input;
eventHandler = new SDL_Event();
+ map = new Map(asset->get("01.map"), renderer, asset);
}
// Destructor
Game::~Game()
{
delete eventHandler;
+ delete map;
}
// Bucle para el juego
@@ -78,6 +80,9 @@ void Game::render()
screen->start();
screen->clean();
+ // Dibuja el mapa
+ map->render();
+
// Actualiza la pantalla
screen->blit();
}
\ No newline at end of file
diff --git a/source/game.h b/source/game.h
index fd7577e..9953857 100644
--- a/source/game.h
+++ b/source/game.h
@@ -4,6 +4,7 @@
#include "asset.h"
#include "screen.h"
#include "input.h"
+#include "map.h"
#ifndef GAME_H
#define GAME_H
@@ -19,6 +20,7 @@ private:
section_t section; // Seccion actual dentro del programa
int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
+ Map *map; // Objeto encargado de gestionar el mapeado del juego
// Actualiza el juego, las variables, comprueba la entrada, etc.
void update();
diff --git a/source/map.cpp b/source/map.cpp
index 0b0148b..7d9596a 100644
--- a/source/map.cpp
+++ b/source/map.cpp
@@ -1,12 +1,212 @@
#include "map.h"
// Constructor
-Map::Map()
+Map::Map(std::string file, SDL_Renderer *renderer, Asset *asset)
{
+ // Copia los punteros a objetos
+ this->asset = asset;
+ this->renderer = renderer;
+ // Crea los objetos
+ texture_tile = new LTexture();
+ texture_bg = new LTexture();
+ load(file);
+ loadTextureFromFile(texture_tile, asset->get(tileset_img), renderer);
+ loadTextureFromFile(texture_bg, asset->get(bg_img), renderer);
+
+ // Crea la textura para el mapa de tiles de la habitación
+ map_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
+ if (map_texture == NULL)
+ printf("Error: map_texture could not be created!\nSDL Error: %s\n", SDL_GetError());
+
+ // Pinta el mapa de la habitación en la textura
+ fillMapTexture();
}
// Destructor
Map::~Map()
{
+ // Reclama la memoria utilizada por los objetos
+ texture_tile->unload();
+ delete texture_tile;
+
+ texture_bg->unload();
+ delete texture_bg;
+
+ SDL_DestroyTexture(map_texture);
}
+
+// Carga las variables desde un fichero
+bool Map::load(std::string file_path)
+{
+ // Indicador de éxito en la carga
+ bool success = true;
+
+ std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
+ std::string line;
+ std::ifstream file(file_path);
+
+ // El fichero se puede abrir
+ if (file.good())
+ {
+ // Procesa el fichero linea a linea
+ printf("Reading file %s\n", filename.c_str());
+ while (std::getline(file, line))
+ {
+ // Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
+ if (line == "[tilemap]")
+ {
+ do
+ {
+ std::getline(file, line);
+ if (line.find(".tmx") != std::string::npos)
+ {
+ std::ifstream file2(asset->get(line)); // Abre el fichero tmx
+ if (file2.good())
+ {
+ bool data_read = false;
+ while (std::getline(file2, line)) // Lee el fichero linea a linea
+ {
+ if (!data_read)
+ { // Lee lineas hasta que encuentre donde empiezan los datos del mapa
+ int pos = 0;
+ do
+ {
+ std::getline(file2, line);
+ pos = line.find("data encoding");
+ } while (pos == std::string::npos);
+
+ do
+ { // Se introducen los valores separados por comas en un vector
+ data_read = true;
+ std::getline(file2, line);
+ if (line != "")
+ {
+ std::stringstream ss(line);
+ std::string tmp;
+ while (getline(ss, tmp, ','))
+ {
+ tilemap.push_back(std::stoi(tmp));
+ }
+ }
+ } while (line != "");
+ }
+ }
+ }
+ }
+ } while (line != "[tilemap-end]");
+ }
+
+ // En caso contrario se parsea el fichero para buscar las variables y los valores
+ else
+ {
+ // Encuentra la posición del caracter '='
+ int pos = line.find("=");
+ // Procesa las dos subcadenas
+ if (!setVars(line.substr(0, pos), line.substr(pos + 1, line.length())))
+ {
+ printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
+ success = false;
+ }
+ }
+ }
+
+ // Cierra el fichero
+ printf("Closing file %s\n", filename.c_str());
+ file.close();
+ }
+ // El fichero no se puede abrir
+ else
+ {
+ printf("Warning: Unable to open %s file\n", filename.c_str());
+ success = false;
+ }
+
+ return success;
+}
+
+// Asigna variables a partir de dos cadenas
+bool Map::setVars(std::string var, std::string value)
+{
+ // Indicador de éxito en la asignación
+ bool success = true;
+
+ if (var == "bg_img")
+ {
+ bg_img = value;
+ }
+ else if (var == "tileset_img")
+ {
+ tileset_img = value;
+ }
+ else if (var == "room_up")
+ {
+ room_up = value;
+ }
+ else if (var == "room_down")
+ {
+ room_down = value;
+ }
+ else if (var == "room_left")
+ {
+ room_left = value;
+ }
+ else if (var == "room_right")
+ {
+ room_right = value;
+ }
+ else if (var == "tilemap")
+ {
+ // Se introducen los valores separados por comas en un vector
+ std::stringstream ss(value);
+ std::string tmp;
+ while (getline(ss, tmp, ','))
+ {
+ tilemap.push_back(std::stoi(tmp));
+ }
+ }
+ else if (var == "")
+ {
+ }
+ else
+ {
+ success = false;
+ }
+
+ return success;
+}
+
+// Crea la textura con el mapeado de la habitación
+void Map::fillMapTexture()
+{
+ SDL_SetRenderTarget(renderer, map_texture);
+ SDL_SetTextureBlendMode(map_texture, SDL_BLENDMODE_BLEND);
+ SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
+ SDL_RenderClear(renderer);
+
+ const int tile_size = 16;
+ const int map_width_in_tiles = 20;
+ const int map_height_in_tiles = 13;
+
+ SDL_Rect clip = {0, 0, tile_size, tile_size};
+
+ for (int y = 0; y < map_height_in_tiles; y++)
+ for (int x = 0; x < map_width_in_tiles; x++)
+ {
+ clip.x = ((tilemap[(y * map_width_in_tiles) + x] - 1) % 16) * tile_size;
+ clip.y = ((tilemap[(y * map_width_in_tiles) + x] - 1) / 16) * tile_size;
+ texture_tile->render(renderer, x * tile_size, y * tile_size, &clip);
+ }
+
+ SDL_SetRenderTarget(renderer, nullptr);
+}
+
+// Dibuja el mapa en pantalla
+void Map::render()
+{
+ // Dibuja el fondo
+
+ // Dibuja la textura con el mapa en pantalla
+ SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
+ SDL_RenderCopy(renderer, map_texture, &rect, NULL);
+}
\ No newline at end of file
diff --git a/source/map.h b/source/map.h
index da2c0ce..485af7f 100644
--- a/source/map.h
+++ b/source/map.h
@@ -1,4 +1,14 @@
#pragma once
+
+#include
+#include "utils.h"
+#include "asset.h"
+#include "const.h"
+#include
+#include
+#include
+#include
+
#ifndef MAP_H
#define MAP_H
@@ -6,13 +16,40 @@
class Map
{
private:
+ Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
+ SDL_Renderer *renderer; // El renderizador de la ventana
+ std::string room_up; // Identificador de la habitación que se encuentra arriba
+ std::string room_down; // Identificador de la habitación que se encuentra abajp
+ std::string room_left; // Identificador de la habitación que se encuentra a la izquierda
+ std::string room_right; // Identificador de la habitación que se encuentra a la derecha
+ std::string tileset_img; // Imagen con los graficos para la habitación
+ std::string bg_img; // Imagen con los graficos para la habitación
+ std::vector tilemap; // Indice de los tiles a dibujar en la habitación
+ LTexture *texture_tile; // Textura con los graficos de los tiles habitación
+ LTexture *texture_bg; // Textura con los graficos de fondo de la habitación
+ SDL_Texture *map_texture; // Textura para dibujar el mapa de la habitación
+
+ // Carga las variables desde un fichero
+ bool load(std::string file);
+
+ // Asigna variables a partir de dos cadenas
+ bool setVars(std::string var, std::string value);
+
+ // Pinta el mapa de la habitación en la textura
+ void fillMapTexture();
public:
// Constructor
- Map();
+ Map(std::string file, SDL_Renderer *renderer, Asset *asset);
// Destructor
~Map();
+
+ // Actualiza todas las variables
+ void update();
+
+ // Dibuja el objeto
+ void render();
};
#endif
diff --git a/source/prog.cpp b/source/prog.cpp
index 09b5ecc..fe25417 100644
--- a/source/prog.cpp
+++ b/source/prog.cpp
@@ -29,7 +29,7 @@ Prog::Prog(std::string executablePath)
section.name = SECTION_PROG_GAME;
}
input = new Input(asset->get("gamecontrollerdb.txt"));
- screen = new Screen(window, renderer, options->screenWidth, options->screenWidth, GAME_WIDTH, GAME_HEIGHT);
+ screen = new Screen(window, renderer, options);
}
Prog::~Prog()
@@ -115,7 +115,8 @@ bool Prog::initSDL()
bool Prog::setFileList()
{
// Ficheros binarios
- asset->add("/data/volcano.map", data);
+ asset->add("/data/map/01.map", data);
+ asset->add("/data/map/01.tmx", data);
asset->add("/data/config.bin", data, false);
asset->add("/data/gamecontrollerdb.txt", data);
diff --git a/source/screen.cpp b/source/screen.cpp
index e9f4a0e..4f71934 100644
--- a/source/screen.cpp
+++ b/source/screen.cpp
@@ -1,20 +1,25 @@
#include "screen.h"
+#include "const.h"
+#include
+#include
// Constructor
-Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, int scr_w, int scr_h, int gc_w, int gc_h)
+Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options)
{
// Inicializa variables
this->window = window;
this->renderer = renderer;
+ this->options = options;
- screenWidth = scr_w;
- screenHeight = scr_h;
- gameCanvasWidth = gc_w;
- gameCanvasHeight = gc_h;
- gameCanvasPosX = (scr_w - gc_w) / 2;
- gameCanvasPosY = (scr_h - gc_h) / 2;
- dest = {gameCanvasPosX, gameCanvasPosY, gameCanvasWidth, gameCanvasHeight};
+ gameCanvasWidth = SCREEN_WIDTH;
+ gameCanvasHeight = SCREEN_HEIGHT;
+
+ // 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
gameCanvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, gameCanvasWidth, gameCanvasHeight);
@@ -56,4 +61,73 @@ void Screen::blit()
// Muestra por pantalla el renderizador
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 014b1bc..baa7699 100644
--- a/source/screen.h
+++ b/source/screen.h
@@ -9,23 +9,21 @@
class Screen
{
private:
- SDL_Window *window; // Ventana de la aplicación
- SDL_Renderer *renderer; // El renderizador de la ventana
+ 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 screenWidth; // Ancho de la pantalla
- int screenHeight; // Alto de 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
- int gameCanvasPosX; // Posicion en el eje X donde se dibujará la textura del juego dentro de la pantalla
- int gameCanvasPosY; // Posicion en el eje Y donde se dibujará la textura del juego dentro de la pantalla
-
- SDL_Rect dest; // Rectangulo de destino donde se dibujarà la textura con el juego
- color_t borderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla
+ 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 *window, SDL_Renderer *renderer, int scr_w = 0, int scr_h = 0, int gc_w = 0, int gc_h = 0);
+ Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options);
// Destructor
~Screen();
@@ -38,6 +36,9 @@ public:
// Vuelca el contenido del renderizador en pantalla
void blit();
+
+ // Establece el modo de video
+ void setVideoMode(int fullScreenMode);
};
#endif