14 Commits

63 changed files with 1932 additions and 2857 deletions

View File

@@ -2,7 +2,7 @@ executable = jaildoctors_dilemma
source = source/*.cpp source = source/*.cpp
appName = JailDoctor's Dilemma appName = JailDoctor's Dilemma
releaseFolder = jdd_release releaseFolder = jdd_release
version = v1.09 version = v1.10
# Release names # Release names
windowsRelease = $(executable)-$(version)-win32-x64.zip windowsRelease = $(executable)-$(version)-win32-x64.zip
@@ -90,7 +90,7 @@ macos_release:
ln -s /Applications "$(releaseFolder)"/Applications ln -s /Applications "$(releaseFolder)"/Applications
# Build INTEL # Build INTEL
clang++ $(source) -D MACOS_BUNDLE -std=$(cpp_standard) -Wall -Os -framework SDL2 -F ./Frameworks -framework OpenGL -Wno-deprecated -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12 clang++ $(source) -D MACOS_BUNDLE -std=$(cpp_standard) -Wall -Os -framework SDL2 -F ./Frameworks -framework OpenGL -Wno-deprecated -ffunction-sections -fdata-sections -o "$(releaseFolder)/$(appName).app/Contents/MacOS/$(executable)" -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.15
# Build INTEL DMG # Build INTEL DMG
hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)" hdiutil create tmp.dmg -ov -volname "$(appName)" -fs HFS+ -srcfolder "$(releaseFolder)"

View File

@@ -23,11 +23,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.09</string> <string>1.10</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.09</string> <string>1.10</string>
<key>CSResourcesFileMapped</key> <key>CSResourcesFileMapped</key>
<true/> <true/>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>

View File

@@ -77,31 +77,31 @@ int Cheevos::find(int id)
// Desbloquea un logro // Desbloquea un logro
void Cheevos::unlock(int id) void Cheevos::unlock(int id)
{ {
const int index = find(id); const int INDEX = find(id);
// Si el índice es inválido, el logro no es válido, ya está completado o el sistema de logros no está habilitado, no hacemos nada // Si el índice es inválido, el logro no es válido, ya está completado o el sistema de logros no está habilitado, no hacemos nada
if (index == -1 || !cheevos_list_.at(index).valid || cheevos_list_.at(index).completed || !enabled_) if (INDEX == -1 || !cheevos_list_.at(INDEX).obtainable || cheevos_list_.at(INDEX).completed || !enabled_)
{ {
return; return;
} }
// Marcar el logro como completado // Marcar el logro como completado
cheevos_list_.at(index).completed = true; cheevos_list_.at(INDEX).completed = true;
// Mostrar notificación en la pantalla // Mostrar notificación en la pantalla
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", cheevos_list_.at(index).caption}, NotificationText::LEFT, cheevos_list_.at(index).icon); Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", cheevos_list_.at(INDEX).caption}, NotificationText::LEFT, cheevos_list_.at(INDEX).icon);
// Guardar el estado de los logros // Guardar el estado de los logros
saveToFile(); saveToFile();
} }
// Invalida un logro // Invalida un logro
void Cheevos::invalidate(int id) void Cheevos::setUnobtainable(int id)
{ {
const int index = find(id); const int index = find(id);
// Si el índice es válido, se invalida el logro // Si el índice es válido, se invalida el logro
if (index != -1) if (index != -1)
{ {
cheevos_list_.at(index).valid = false; cheevos_list_.at(index).obtainable = false;
} }
} }
@@ -184,10 +184,10 @@ void Cheevos::saveToFile()
} }
// Devuelve el número total de logros desbloqueados // Devuelve el número total de logros desbloqueados
int Cheevos::unlocked() int Cheevos::getTotalUnlockedAchievements()
{ {
int count = 0; int count = 0;
for (auto cheevo : cheevos_list_) for (const auto &cheevo : cheevos_list_)
{ {
if (cheevo.completed) if (cheevo.completed)
{ {
@@ -195,4 +195,13 @@ int Cheevos::unlocked()
} }
} }
return count; return count;
}
// Elimina el estado "no obtenible"
void Cheevos::clearUnobtainableState()
{
for (auto &cheevo : cheevos_list_)
{
cheevo.obtainable = true;
}
} }

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
// Struct para los logros // Struct para los logros
struct Achievement struct Achievement
@@ -11,14 +11,14 @@ struct Achievement
std::string description; // Texto que describe el logro std::string description; // Texto que describe el logro
int icon; // Indice del icono a utilizar en la notificación int icon; // Indice del icono a utilizar en la notificación
bool completed; // Indica si se ha obtenido el logro bool completed; // Indica si se ha obtenido el logro
bool valid; // Indica si se puede obtener el logro bool obtainable; // Indica si se puede obtener el logro
// Constructor vacío // Constructor vacío
Achievement() : id(0), icon(0), completed(false), valid(true) {} Achievement() : id(0), icon(0), completed(false), obtainable(true) {}
// Constructor parametrizado // Constructor parametrizado
Achievement(int id, const std::string &caption, const std::string &description, int icon, bool completed = false, bool valid = true) Achievement(int id, const std::string &caption, const std::string &description, int icon, bool completed = false, bool obtainable = true)
: id(id), caption(caption), description(description), icon(icon), completed(completed), valid(valid) {} : id(id), caption(caption), description(description), icon(icon), completed(completed), obtainable(obtainable) {}
}; };
class Cheevos class Cheevos
@@ -45,7 +45,7 @@ private:
void saveToFile(); void saveToFile();
// Constructor // Constructor
Cheevos(const std::string &file); explicit Cheevos(const std::string &file);
// Destructor // Destructor
~Cheevos(); ~Cheevos();
@@ -64,7 +64,10 @@ public:
void unlock(int id); void unlock(int id);
// Invalida un logro // Invalida un logro
void invalidate(int id); void setUnobtainable(int id);
// Elimina el estado "no obtenible"
void clearUnobtainableState();
// Habilita o deshabilita los logros // Habilita o deshabilita los logros
void enable(bool value) { enabled_ = value; } void enable(bool value) { enabled_ = value; }
@@ -73,8 +76,8 @@ public:
std::vector<Achievement> list() { return cheevos_list_; } std::vector<Achievement> list() { return cheevos_list_; }
// Devuelve el número total de logros desbloqueados // Devuelve el número total de logros desbloqueados
int unlocked(); int getTotalUnlockedAchievements();
// Devuelve el número total de logros // Devuelve el número total de logros
int count() { return cheevos_list_.size(); } int size() { return cheevos_list_.size(); }
}; };

View File

@@ -8,11 +8,9 @@
#include <algorithm> // for min #include <algorithm> // for min
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen #include "screen.h" // for Screen
@@ -20,44 +18,21 @@
// Constructor // Constructor
Credits::Credits() Credits::Credits()
: screen_(Screen::get()), : shining_sprite_(std::make_shared<AnimatedSprite>(Resource::get()->getTexture("shine.png"), Resource::get()->getAnimations("shine.ani")))
renderer_(Screen::get()->getRenderer()),
resource_(Resource::get()),
asset_(Asset::get()),
input_(Input::get())
{ {
// Reserva memoria para los punteros
text_ = resource_->getText("smb2");
sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("shine.png"), resource_->getAnimations("shine.ani"));
// Inicializa variables // Inicializa variables
options.section.section = Section::CREDITS; options.section.section = Section::CREDITS;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
sprite_->setPosition({194, 174, 8, 8}); shining_sprite_->setPosition({194, 174, 8, 8});
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
// Crea la textura para el texto que se escribe en pantalla // 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); text_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height);
if (text_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
SDL_SetTextureBlendMode(text_texture_, SDL_BLENDMODE_BLEND);
// Crea la textura para cubrir el rexto // Crea la textura para cubrir el rexto
cover_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); cover_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height);
if (cover_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND);
// Escribe el texto en la textura // Escribe el texto en la textura
@@ -90,21 +65,24 @@ void Credits::checkInput()
// Inicializa los textos // Inicializa los textos
void Credits::iniTexts() void Credits::iniTexts()
{ {
#ifndef GAME_CONSOLE
std::string keys = ""; std::string keys = "";
if (options.keys == ControlScheme::CURSOR)
switch (options.keys)
{ {
case ControlScheme::CURSOR:
keys = "CURSORS"; keys = "CURSORS";
} break;
else if (options.keys == ControlScheme::OPQA) case ControlScheme::OPQA:
{
keys = "O,P AND Q"; keys = "O,P AND Q";
} break;
else case ControlScheme::WASD:
{
keys = "A,D AND W"; keys = "A,D AND W";
break;
default:
break;
} }
#ifndef GAME_CONSOLE
texts_.clear(); texts_.clear();
texts_.push_back({"", stringToColor(options.video.palette, "white")}); texts_.push_back({"", stringToColor(options.video.palette, "white")});
texts_.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")}); texts_.push_back({"INSTRUCTIONS:", stringToColor(options.video.palette, "yellow")});
@@ -172,54 +150,56 @@ void Credits::fillTexture()
iniTexts(); iniTexts();
// Rellena la textura de texto // Rellena la textura de texto
SDL_SetRenderTarget(renderer_, text_texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), text_texture_);
Color c = stringToColor(options.video.palette, "black"); Color color = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
auto text = Resource::get()->getText("smb2");
// Escribe el texto en la textura // Escribe el texto en la textura
const int size = text_->getCharacterSize(); const int SIZE = text->getCharacterSize();
int i = 0; int pos_y = 0;
for (auto t : texts_) for (const auto &t : texts_)
{ {
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, i * size, t.label, 1, t.color); text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, pos_y * SIZE, t.label, 1, t.color);
i++; pos_y++;
} }
// Escribe el corazón // 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 TEXT_LENGHT = 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; const int POS_X = ((PLAY_AREA_WIDTH - TEXT_LENGHT) / 2) + TEXT_LENGHT;
text_->writeColored(posX, 176, "}", stringToColor(options.video.palette, "bright_red")); text->writeColored(POS_X, 176, "}", stringToColor(options.video.palette, "bright_red"));
// Recoloca el sprite del brillo // Recoloca el sprite del brillo
sprite_->setPosX(posX + 2); shining_sprite_->setPosX(POS_X + 2);
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
// Rellena la textura que cubre el texto con color transparente // Rellena la textura que cubre el texto con color transparente
SDL_SetRenderTarget(renderer_, cover_texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), cover_texture_);
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0x00); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0x00);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
for (int i = 0; i < 256; i += 2) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(renderer_, i, 0); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 0);
SDL_RenderDrawPoint(renderer_, i, 2); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 2);
SDL_RenderDrawPoint(renderer_, i, 4); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 4);
SDL_RenderDrawPoint(renderer_, i, 6); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 6);
SDL_RenderDrawPoint(renderer_, i + 1, 5); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 5);
SDL_RenderDrawPoint(renderer_, i + 1, 7); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, 256, 192}; SDL_Rect rect = {0, 8, 256, 192};
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
} }
// Actualiza el contador // Actualiza el contador
@@ -266,12 +246,12 @@ void Credits::update()
// Actualiza el contador // Actualiza el contador
updateCounter(); updateCounter();
screen_->update(); Screen::get()->update();
// Actualiza el sprite con el brillo // Actualiza el sprite con el brillo
if (counter_ > 770) if (counter_ > 770)
{ {
sprite_->update(); shining_sprite_->update();
} }
} }
} }
@@ -280,28 +260,28 @@ void Credits::update()
void Credits::render() void Credits::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); Screen::get()->start();
// Limpia la pantalla // Limpia la pantalla
screen_->clean(); Screen::get()->clean();
if (counter_ < 1150) if (counter_ < 1150)
{ {
// Dibuja la textura con el texto en pantalla // Dibuja la textura con el texto en pantalla
SDL_RenderCopy(renderer_, text_texture_, nullptr, nullptr); SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, nullptr, nullptr);
// Dibuja la textura que cubre el texto // Dibuja la textura que cubre el texto
const int offset = std::min(counter_ / 8, 192 / 2); const int offset = std::min(counter_ / 8, 192 / 2);
SDL_Rect srcRect = {0, 0, 256, 192 - (offset * 2)}; SDL_Rect srcRect = {0, 0, 256, 192 - (offset * 2)};
SDL_Rect dstRect = {0, offset * 2, 256, 192 - (offset * 2)}; SDL_Rect dstRect = {0, offset * 2, 256, 192 - (offset * 2)};
SDL_RenderCopy(renderer_, cover_texture_, &srcRect, &dstRect); SDL_RenderCopy(Screen::get()->getRenderer(), cover_texture_, &srcRect, &dstRect);
// Dibuja el sprite con el brillo // Dibuja el sprite con el brillo
sprite_->render(); shining_sprite_->render();
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Bucle para el logo del juego // Bucle para el logo del juego
@@ -313,11 +293,4 @@ void Credits::run()
checkEvents(); checkEvents();
render(); render();
} }
}
// Cambia la paleta
void Credits::switchPalette()
{
options.video.palette = options.video.palette == Palette::ZXSPECTRUM ? Palette::ZXARNE : Palette::ZXSPECTRUM;
fillTexture();
} }

View File

@@ -1,44 +1,33 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Texture, SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "utils.h" // for Color #include "utils.h" // for Color
class AnimatedSprite; // lines 10-10 class AnimatedSprite; // lines 9-9
class Asset; // lines 11-11
class Input; // lines 12-12
class Resource; // lines 13-13
class Screen; // lines 14-14
class Text; // lines 15-15
class Credits class Credits
{ {
private: private:
struct captions_t struct Captions
{ {
std::string label; // Texto a escribir std::string label; // Texto a escribir
Color color; // Color del texto Color color; // Color del texto
}; };
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla SDL_Texture *text_texture_; // Textura para dibujar el texto
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Texture *cover_texture_; // Textura para cubrir el texto
Resource *resource_; // Objeto con los recursos std::shared_ptr<AnimatedSprite> shining_sprite_; // Sprite para el brillo del corazón
Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
SDL_Texture *text_texture_; // Textura para dibujar el texto
SDL_Texture *cover_texture_; // Textura para cubrir el texto
std::shared_ptr<AnimatedSprite> sprite_; // Sprite para el brillo del corazón
// Variables // Variables
int counter_ = 0; // Contador int counter_ = 0; // Contador
bool counter_enabled_ = true; // Indica si esta activo el contador bool counter_enabled_ = true; // Indica si esta activo el contador
int sub_counter_ = 0; // Contador secundario int sub_counter_ = 0; // Contador secundario
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::vector<captions_t> texts_; // Vector con los textos std::vector<Captions> texts_; // Vector con los textos
// Actualiza las variables // Actualiza las variables
void update(); void update();
@@ -61,9 +50,6 @@ private:
// Escribe el texto en la textura // Escribe el texto en la textura
void fillTexture(); void fillTexture();
// Cambia la paleta
void switchPalette();
public: public:
// Constructor // Constructor
Credits(); Credits();

View File

@@ -1,7 +1,7 @@
#include "debug.h" #include "debug.h"
#include <algorithm> // for max #include <algorithm> // for max
#include <memory> // for __shared_ptr_access, shared_ptr
#include "resource.h" // for Resource #include "resource.h" // for Resource
#include "screen.h" // for Screen
#include "text.h" // for Text #include "text.h" // for Text
#include "utils.h" // for Color #include "utils.h" // for Color
@@ -26,45 +26,30 @@ Debug *Debug::get()
return Debug::debug_; return Debug::debug_;
} }
// Constructor
Debug::Debug()
// Copia la dirección de los objetos
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer())
{
// Reserva memoria para los punteros
texture_ = Resource::get()->getTexture("debug.png");
text_ = Resource::get()->getText("debug");
}
// Actualiza las variables
void Debug::update()
{
}
// Dibuja en pantalla // Dibuja en pantalla
void Debug::render() void Debug::render()
{ {
auto text = Resource::get()->getText("debug");
int y = y_; int y = y_;
int w = 0; int w = 0;
for (auto s : slot_) for (const auto &s : slot_)
{ {
text_->write(x_, y, s); text->write(x_, y, s);
w = (std::max(w, (int)s.length())); w = (std::max(w, (int)s.length()));
y += text_->getCharacterSize() + 1; y += text->getCharacterSize() + 1;
if (y > 192 - text_->getCharacterSize()) if (y > 192 - text->getCharacterSize())
{ {
y = y_; y = y_;
x_ += w * text_->getCharacterSize() + 2; x_ += w * text->getCharacterSize() + 2;
} }
} }
y = 0; y = 0;
for (auto l : log_) for (const auto &l : log_)
{ {
text_->writeColored(x_ + 10, y, l, Color(255, 255, 255)); text->writeColored(x_ + 10, y, l, Color(255, 255, 255));
y += text_->getCharacterSize() + 1; y += text->getCharacterSize() + 1;
} }
} }

View File

@@ -1,13 +1,8 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Point
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <string> // for string
#include <memory> // for shared_ptr #include <vector> // for vector
#include <string> // for string
#include <vector> // for vector
class Screen; // lines 9-9
class Text; // lines 10-10
class Texture; // lines 11-11
// Clase Debug // Clase Debug
class Debug class Debug
@@ -16,12 +11,6 @@ private:
// [SINGLETON] Objeto privado // [SINGLETON] Objeto privado
static Debug *debug_; static Debug *debug_;
// Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
std::shared_ptr<Text> text_; // Objeto encargado de escribir texto en pantalla
std::shared_ptr<Texture> texture_; // Textura para el texto
// Variables // Variables
std::vector<std::string> slot_; // Vector con los textos a escribir std::vector<std::string> slot_; // Vector con los textos a escribir
std::vector<std::string> log_; // Vector con los textos a escribir std::vector<std::string> log_; // Vector con los textos a escribir
@@ -30,7 +19,7 @@ private:
bool enabled_ = false; // Indica si esta activo el modo debug bool enabled_ = false; // Indica si esta activo el modo debug
// Constructor // Constructor
Debug(); Debug() = default;
// Destructor // Destructor
~Debug() = default; ~Debug() = default;
@@ -45,9 +34,6 @@ public:
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
static Debug *get(); static Debug *get();
// Actualiza las variables
void update();
// Dibuja en pantalla // Dibuja en pantalla
void render(); void render();
@@ -63,5 +49,5 @@ public:
void addToLog(std::string text) { log_.push_back(text); } void addToLog(std::string text) { log_.push_back(text); }
void clearLog() { log_.clear(); } void clearLog() { log_.clear(); }
void setEnabled(bool value) { enabled_ = value; } void setEnabled(bool value) { enabled_ = value; }
void switchEnabled() { enabled_ = !enabled_; } void toggleEnabled() { enabled_ = !enabled_; }
}; };

View File

@@ -7,10 +7,10 @@
// Textos // Textos
constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma"; constexpr const char *WINDOW_CAPTION = "JailDoctor's Dilemma";
constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner"; constexpr const char *TEXT_COPYRIGHT = "@2022 JailDesigner";
constexpr const char *VERSION = "1.09"; constexpr const char *VERSION = "1.10";
// Velocidad del juego // Velocidad del juego
constexpr Uint32 GAME_SPEED = 1000 / 60; constexpr Uint32 GAME_SPEED = 15;
// Tamaño de bloque // Tamaño de bloque
constexpr int BLOCK = 8; constexpr int BLOCK = 8;

View File

@@ -1,235 +0,0 @@
#include "demo.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset
#include "debug.h" // for Debug
#include "defines.h" // for BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_CENT...
#include "global_events.h" // for check
#include "global_inputs.h" // for check
#include "input.h" // for Input
#include "item_tracker.h" // for ItemTracker
#include "options.h" // for Options, options, OptionsVideo, Section...
#include "resource.h" // for Resource
#include "room.h" // for Room
#include "screen.h" // for Screen
#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "utils.h" // for Color, stringToColor, colorAreEqual
// Constructor
Demo::Demo()
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()),
resource_(Resource::get()),
asset_(Asset::get()),
input_(Input::get()),
debug_(Debug::get())
{
// Inicia algunas variables
board_ = std::make_shared<ScoreboardData>();
board_->ini_clock = SDL_GetTicks();
rooms_.push_back("04.room");
rooms_.push_back("54.room");
rooms_.push_back("20.room");
rooms_.push_back("09.room");
rooms_.push_back("05.room");
rooms_.push_back("11.room");
rooms_.push_back("31.room");
rooms_.push_back("44.room");
room_index_ = 0;
current_room_ = rooms_[room_index_];
// Crea los objetos
ItemTracker::init();
scoreboard_ = std::make_shared<Scoreboard>(board_);
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
text_ = resource_->getText("smb2");
// Inicializa el resto de variables
counter_ = 0;
room_time_ = 400;
ticks_ = 0;
board_->lives = 9;
board_->items = 0;
board_->rooms = 1;
board_->jail_is_open = false;
board_->music = true;
setScoreBoardColor();
options.section.section = Section::DEMO;
options.section.subsection = Subsection::NONE;
}
// Destructor
Demo::~Demo()
{
ItemTracker::destroy();
}
// Comprueba los eventos de la cola
void Demo::checkEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
globalEvents::check(event);
}
}
// Comprueba las entradas
void Demo::checkInput()
{
globalInputs::check();
}
// Bucle para el juego
void Demo::run()
{
while (options.section.section == Section::DEMO)
{
update();
checkEvents();
render();
}
}
// Actualiza el juego, las variables, comprueba la entrada, etc.
void Demo::update()
{
// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
if (SDL_GetTicks() - ticks_ > GAME_SPEED)
{
// Actualiza el contador de ticks
ticks_ = SDL_GetTicks();
// Comprueba las entradas
checkInput();
// Actualiza los objetos
room_->update();
scoreboard_->update();
checkRoomChange();
screen_->update();
}
}
// Pinta los objetos en pantalla
void Demo::render()
{
// Prepara para dibujar el frame
screen_->start();
// Dibuja los elementos del juego en orden
room_->renderMap();
room_->renderEnemies();
room_->renderItems();
renderRoomName();
scoreboard_->render();
// Actualiza la pantalla
screen_->render();
}
// Escribe el nombre de la pantalla
void Demo::renderRoomName()
{
// Texto en el centro de la pantalla
SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2};
Color color = stringToColor(options.video.palette, "white");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer_, &rect);
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room_->getName(), 1, room_->getBGColor());
}
// Recarga todas las texturas
void Demo::reLoadTextures()
{
if (options.console)
{
std::cout << "** RELOAD REQUESTED" << std::endl;
}
room_->reLoadTexture();
scoreboard_->reLoadTexture();
text_->reLoadTexture();
}
// Cambia la paleta
void Demo::switchPalette()
{
// Modifica la variable
if (options.video.palette == Palette::ZXSPECTRUM)
{
options.video.palette = Palette::ZXARNE;
}
else
{
options.video.palette = Palette::ZXSPECTRUM;
}
room_->reLoadPalette();
scoreboard_->reLoadPalette();
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();
}
// Cambia de habitación
bool Demo::changeRoom(std::string file)
{
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file != "0")
{
// Verifica que exista el fichero que se va a cargar
if (asset_->get(file) != "")
{
// Crea un objeto habitación a partir del fichero
room_ = std::make_shared<Room>(resource_->getRoom(file), board_);
// Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor();
return true;
}
}
return false;
}
// Comprueba si se ha de cambiar de habitación
void Demo::checkRoomChange()
{
counter_++;
if (counter_ == room_time_)
{
counter_ = 0;
room_index_++;
if (room_index_ == (int)rooms_.size())
{
options.section.section = Section::LOGO;
options.section.subsection = Subsection::LOGO_TO_TITLE;
}
else
{
changeRoom(rooms_[room_index_]);
}
}
}
// Pone el color del marcador en función del color del borde de la habitación
void Demo::setScoreBoardColor()
{
// Obtiene el color del borde
const Color color = room_->getBorderColor();
// Si el color es negro lo cambia a blanco
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 bright_blac_color = stringToColor(options.video.palette, "bright_black");
board_->color = colorAreEqual(color, bright_blac_color) ? stringToColor(options.video.palette, "white") : color;
}

View File

@@ -1,80 +0,0 @@
#pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr
#include <string> // for string
#include <vector> // for vector
#include "scoreboard.h" // for board_t
class Asset; // lines 11-11
class Debug; // lines 12-12
class Input; // lines 13-13
class ItemTracker; // lines 14-14
class Resource; // lines 15-15
class Room; // lines 16-16
class Screen; // lines 17-17
class Text; // lines 18-18
class Demo
{
private:
// Objetos y punteros
Screen *screen_; // Objeto encargado de manejar el renderizador
SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource_; // Objeto con los recursos
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
Debug *debug_; // Objeto para gestionar la información de debug
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Text> text_; // Objeto para los textos del juego
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
// Variables
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
std::string current_room_; // Fichero de la habitación actual
std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
int counter_; // Contador para el modo demo
int room_time_; // Tiempo que se muestra cada habitacion
int room_index_; // Indice para el vector de habitaciones
std::vector<std::string> rooms_; // Listado con los mapas de la demo
// Actualiza el juego, las variables, comprueba la entrada, etc.
void update();
// Pinta los objetos en pantalla
void render();
// Comprueba los eventos de la cola
void checkEvents();
// Comprueba las entradas
void checkInput();
// Escribe el nombre de la pantalla
void renderRoomName();
// Recarga todas las texturas
void reLoadTextures();
// Cambia la paleta
void switchPalette();
// Cambia de habitación
bool changeRoom(std::string file);
// Comprueba si se ha de cambiar de habitación
void checkRoomChange();
// Pone el color del marcador en función del color del borde de la habitación
void setScoreBoardColor();
public:
// Constructor
Demo();
// Destructor
~Demo();
// Bucle para el juego
void run();
};

View File

@@ -22,7 +22,6 @@
#include "credits.h" // for Credits #include "credits.h" // for Credits
#include "debug.h" // for Debug #include "debug.h" // for Debug
#include "defines.h" // for WINDOW_CAPTION, borderColor #include "defines.h" // for WINDOW_CAPTION, borderColor
#include "demo.h" // for Demo
#include "ending.h" // for Ending #include "ending.h" // for Ending
#include "ending2.h" // for Ending2 #include "ending2.h" // for Ending2
#include "game.h" // for Game #include "game.h" // for Game
@@ -110,41 +109,37 @@ Director::~Director()
// Comprueba los parametros del programa // Comprueba los parametros del programa
std::string Director::checkProgramArguments(int argc, const char *argv[]) std::string Director::checkProgramArguments(int argc, const char *argv[])
{ {
// Comprueba los parametros // Iterar sobre los argumentos del programa
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
if (strcmp(argv[i], "--console") == 0) std::string argument(argv[i]);
{
options.console = true;
}
else if (strcmp(argv[i], "--infiniteLives") == 0) if (argument == "--console")
{ {
options.cheats.infinite_lives = Cheat::CheatState::ENABLED; options.console = true;
} }
else if (argument == "--infiniteLives")
{
options.cheats.infinite_lives = Cheat::CheatState::ENABLED;
}
else if (argument == "--invincible")
{
options.cheats.invincible = Cheat::CheatState::ENABLED;
}
else if (argument == "--jailEnabled")
{
options.cheats.jail_is_open = Cheat::CheatState::ENABLED;
}
else if (argument == "--altSkin")
{
options.cheats.alternate_skin = Cheat::CheatState::ENABLED;
}
}
else if (strcmp(argv[i], "--invincible") == 0) return argv[0];
{
options.cheats.invincible = Cheat::CheatState::ENABLED;
;
}
else if (strcmp(argv[i], "--jailEnabled") == 0)
{
options.cheats.jail_is_open = Cheat::CheatState::ENABLED;
;
}
else if (strcmp(argv[i], "--altSkin") == 0)
{
options.cheats.alternate_skin = Cheat::CheatState::ENABLED;
;
}
}
return argv[0];
} }
// Crea la carpeta del sistema donde guardar datos // Crea la carpeta del sistema donde guardar datos
void Director::createSystemFolder(const std::string &folder) void Director::createSystemFolder(const std::string &folder)
{ {
@@ -217,60 +212,60 @@ void Director::initInput()
// Teclado - Movimiento // Teclado - Movimiento
if (options.keys == ControlScheme::CURSOR) if (options.keys == ControlScheme::CURSOR)
{ {
Input::get()->bindKey(input_jump, SDL_SCANCODE_UP); Input::get()->bindKey(InputAction::JUMP, SDL_SCANCODE_UP);
Input::get()->bindKey(input_left, SDL_SCANCODE_LEFT); Input::get()->bindKey(InputAction::LEFT, SDL_SCANCODE_LEFT);
Input::get()->bindKey(input_right, SDL_SCANCODE_RIGHT); Input::get()->bindKey(InputAction::RIGHT, SDL_SCANCODE_RIGHT);
Input::get()->bindKey(input_up, SDL_SCANCODE_UP); Input::get()->bindKey(InputAction::UP, SDL_SCANCODE_UP);
Input::get()->bindKey(input_down, SDL_SCANCODE_DOWN); Input::get()->bindKey(InputAction::DOWN, SDL_SCANCODE_DOWN);
} }
else if (options.keys == ControlScheme::OPQA) else if (options.keys == ControlScheme::OPQA)
{ {
Input::get()->bindKey(input_jump, SDL_SCANCODE_Q); Input::get()->bindKey(InputAction::JUMP, SDL_SCANCODE_Q);
Input::get()->bindKey(input_left, SDL_SCANCODE_O); Input::get()->bindKey(InputAction::LEFT, SDL_SCANCODE_O);
Input::get()->bindKey(input_right, SDL_SCANCODE_P); Input::get()->bindKey(InputAction::RIGHT, SDL_SCANCODE_P);
Input::get()->bindKey(input_up, SDL_SCANCODE_Q); Input::get()->bindKey(InputAction::UP, SDL_SCANCODE_Q);
Input::get()->bindKey(input_down, SDL_SCANCODE_A); Input::get()->bindKey(InputAction::DOWN, SDL_SCANCODE_A);
} }
else if (options.keys == ControlScheme::WASD) else if (options.keys == ControlScheme::WASD)
{ {
Input::get()->bindKey(input_jump, SDL_SCANCODE_W); Input::get()->bindKey(InputAction::JUMP, SDL_SCANCODE_W);
Input::get()->bindKey(input_left, SDL_SCANCODE_A); Input::get()->bindKey(InputAction::LEFT, SDL_SCANCODE_A);
Input::get()->bindKey(input_right, SDL_SCANCODE_D); Input::get()->bindKey(InputAction::RIGHT, SDL_SCANCODE_D);
Input::get()->bindKey(input_up, SDL_SCANCODE_W); Input::get()->bindKey(InputAction::UP, SDL_SCANCODE_W);
Input::get()->bindKey(input_down, SDL_SCANCODE_S); Input::get()->bindKey(InputAction::DOWN, SDL_SCANCODE_S);
} }
// Teclado - Otros // Teclado - Otros
Input::get()->bindKey(input_accept, SDL_SCANCODE_RETURN); Input::get()->bindKey(InputAction::ACCEPT, SDL_SCANCODE_RETURN);
Input::get()->bindKey(input_cancel, SDL_SCANCODE_ESCAPE); Input::get()->bindKey(InputAction::CANCEL, SDL_SCANCODE_ESCAPE);
Input::get()->bindKey(input_pause, SDL_SCANCODE_H); Input::get()->bindKey(InputAction::PAUSE, SDL_SCANCODE_H);
Input::get()->bindKey(input_exit, SDL_SCANCODE_ESCAPE); Input::get()->bindKey(InputAction::EXIT, SDL_SCANCODE_ESCAPE);
Input::get()->bindKey(input_window_dec_size, SDL_SCANCODE_F1); Input::get()->bindKey(InputAction::WINDOW_DEC_ZOOM, SDL_SCANCODE_F1);
Input::get()->bindKey(input_window_inc_size, SDL_SCANCODE_F2); Input::get()->bindKey(InputAction::WINDOW_INC_ZOOM, SDL_SCANCODE_F2);
Input::get()->bindKey(input_toggle_videomode, SDL_SCANCODE_F3); Input::get()->bindKey(InputAction::TOGGLE_VIDEOMODE, SDL_SCANCODE_F3);
Input::get()->bindKey(input_toggle_shaders, SDL_SCANCODE_F4); Input::get()->bindKey(InputAction::TOGGLE_SHADERS, SDL_SCANCODE_F4);
Input::get()->bindKey(input_toggle_palette, SDL_SCANCODE_F5); Input::get()->bindKey(InputAction::TOGGLE_PALETTE, SDL_SCANCODE_F5);
Input::get()->bindKey(input_toggle_music, SDL_SCANCODE_M); Input::get()->bindKey(InputAction::TOGGLE_MUSIC, SDL_SCANCODE_M);
Input::get()->bindKey(input_toggle_border, SDL_SCANCODE_B); Input::get()->bindKey(InputAction::TOGGLE_BORDER, SDL_SCANCODE_B);
// Mando - Movimiento // Mando - Movimiento
Input::get()->bindGameControllerButton(input_jump, SDL_CONTROLLER_BUTTON_B); Input::get()->bindGameControllerButton(InputAction::JUMP, SDL_CONTROLLER_BUTTON_B);
Input::get()->bindGameControllerButton(input_left, SDL_CONTROLLER_BUTTON_DPAD_LEFT); Input::get()->bindGameControllerButton(InputAction::LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
Input::get()->bindGameControllerButton(input_right, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); Input::get()->bindGameControllerButton(InputAction::RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
// Mando - Otros // Mando - Otros
Input::get()->bindGameControllerButton(input_accept, SDL_CONTROLLER_BUTTON_B); Input::get()->bindGameControllerButton(InputAction::ACCEPT, SDL_CONTROLLER_BUTTON_B);
Input::get()->bindGameControllerButton(input_cancel, SDL_CONTROLLER_BUTTON_A); Input::get()->bindGameControllerButton(InputAction::CANCEL, SDL_CONTROLLER_BUTTON_A);
#ifdef GAME_CONSOLE #ifdef GAME_CONSOLE
Input::get()->bindGameControllerButton(input_pause, SDL_CONTROLLER_BUTTON_BACK); Input::get()->bindGameControllerButton(InputAction::input_pause, SDL_CONTROLLER_BUTTON_BACK);
Input::get()->bindGameControllerButton(input_exit, SDL_CONTROLLER_BUTTON_START); Input::get()->bindGameControllerButton(InputAction::input_exit, SDL_CONTROLLER_BUTTON_START);
#else #else
Input::get()->bindGameControllerButton(input_pause, SDL_CONTROLLER_BUTTON_START); Input::get()->bindGameControllerButton(InputAction::PAUSE, SDL_CONTROLLER_BUTTON_START);
Input::get()->bindGameControllerButton(input_exit, SDL_CONTROLLER_BUTTON_BACK); Input::get()->bindGameControllerButton(InputAction::EXIT, SDL_CONTROLLER_BUTTON_BACK);
#endif #endif
Input::get()->bindGameControllerButton(input_toggle_palette, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); Input::get()->bindGameControllerButton(InputAction::TOGGLE_PALETTE, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
Input::get()->bindGameControllerButton(input_toggle_music, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); Input::get()->bindGameControllerButton(InputAction::TOGGLE_MUSIC, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
Input::get()->bindGameControllerButton(input_toggle_border, SDL_CONTROLLER_BUTTON_X); Input::get()->bindGameControllerButton(InputAction::TOGGLE_BORDER, SDL_CONTROLLER_BUTTON_X);
} }
// Inicializa JailAudio // Inicializa JailAudio
@@ -405,7 +400,7 @@ bool Director::setFileList()
// Datos // Datos
Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA); Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA);
// Test // Test
Asset::get()->add(prefix + "/data/test.gif", AssetType::DATA); Asset::get()->add(prefix + "/data/test.gif", AssetType::DATA);
@@ -774,8 +769,8 @@ void Director::runCredits()
// Ejecuta la seccion de la demo, donde se ven pantallas del juego // Ejecuta la seccion de la demo, donde se ven pantallas del juego
void Director::runDemo() void Director::runDemo()
{ {
auto demo = std::make_unique<Demo>(); auto game = std::make_unique<Game>(GameMode::DEMO);
demo->run(); game->run();
} }
// Ejecuta la seccion del final del juego // Ejecuta la seccion del final del juego
@@ -803,7 +798,7 @@ void Director::runGameOver()
void Director::runGame() void Director::runGame()
{ {
JA_StopMusic(); JA_StopMusic();
auto game = std::make_unique<Game>(); auto game = std::make_unique<Game>(GameMode::GAME);
game->run(); game->run();
} }

View File

@@ -3,7 +3,6 @@
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL_video.h> // for SDL_Window #include <SDL2/SDL_video.h> // for SDL_Window
#include <string> // for string #include <string> // for string
struct JA_Music_t; // lines 11-11
class Director class Director
{ {

View File

@@ -7,11 +7,9 @@
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for min #include <algorithm> // for min
#include <iostream> // for basic_ostream, operator<<, cout, endl #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "asset.h" // for Asset #include "defines.h" // for GAMECANVAS_HEIGHT, options.game.width
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input
#include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM... #include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM...
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "resource.h" // for Resource #include "resource.h" // for Resource
@@ -23,24 +21,14 @@
// Constructor // Constructor
Ending::Ending() Ending::Ending()
: screen_(Screen::get()), : counter_(-1),
renderer_(Screen::get()->getRenderer()), pre_counter_(0),
resource_(Resource::get()), cover_counter_(0),
asset_(Asset::get()), ticks_(0),
input_(Input::get()) current_scene_(0)
{ {
// Reserva memoria para los punteros a objetos
text_ = resource_->getText("smb2");
music = resource_->getMusic("ending1.ogg");
// Inicializa variables
counter_ = -1;
pre_counter_ = 0;
cover_counter_ = 0;
options.section.section = Section::ENDING; options.section.section = Section::ENDING;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
ticks_ = 0;
current_scene_ = 0;
// Inicializa los textos // Inicializa los textos
iniTexts(); iniTexts();
@@ -52,17 +40,10 @@ Ending::Ending()
iniScenes(); iniScenes();
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
// Crea la textura para cubrir el rexto // Crea la textura para cubrir el texto
cover_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT + 8); cover_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height + 8);
if (cover_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: canvasTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND);
// Rellena la textura para la cortinilla // Rellena la textura para la cortinilla
@@ -72,7 +53,6 @@ Ending::Ending()
// Destructor // Destructor
Ending::~Ending() Ending::~Ending()
{ {
// Libera la memoria de los objetos
SDL_DestroyTexture(cover_texture_); SDL_DestroyTexture(cover_texture_);
} }
@@ -100,7 +80,7 @@ void Ending::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
screen_->update(); Screen::get()->update();
} }
} }
@@ -108,22 +88,22 @@ void Ending::update()
void Ending::render() void Ending::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); Screen::get()->start();
// Limpia la pantalla // Limpia la pantalla
screen_->clean(stringToColor(options.video.palette, "black")); Screen::get()->clean(stringToColor(options.video.palette, "yellow"));
// Dibuja las imagenes de la escena // Dibuja las imagenes de la escena
sprite_pics_[current_scene_].sprite->render(); sprite_pics_.at(current_scene_).image_sprite->render();
sprite_pics_[current_scene_].cover_sprite->render(); sprite_pics_.at(current_scene_).cover_sprite->render();
// Dibuja los textos de la escena // Dibuja los textos de la escena
for (auto ti : scenes_[current_scene_].text_index) for (const auto &ti : scenes_.at(current_scene_).text_index)
{ {
if (counter_ > ti.trigger) if (counter_ > ti.trigger)
{ {
sprite_texts_[ti.index].sprite->render(); sprite_texts_.at(ti.index).image_sprite->render();
sprite_texts_[ti.index].cover_sprite->render(); sprite_texts_.at(ti.index).cover_sprite->render();
} }
} }
@@ -131,7 +111,7 @@ void Ending::render()
renderCoverTexture(); renderCoverTexture();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -188,62 +168,65 @@ void Ending::iniTexts()
// Crea los sprites // Crea los sprites
sprite_texts_.clear(); sprite_texts_.clear();
for (auto t : texts) for (const auto &txt : texts)
{ {
EndingTexture st; auto text = Resource::get()->getText("smb2");
const int width = text_->lenght(t.caption, 1) + 2 + 2;
const int height = text_->getCharacterSize() + 2 + 2;
Color c = stringToColor(options.video.palette, "black");
// Crea la texture const int WIDTH = text->lenght(txt.caption, 1) + 2 + 2;
st.texture = std::make_shared<Texture>(renderer_); const int HEIGHT = text->getCharacterSize() + 2 + 2;
st.texture->createBlank(width, height); Color color = stringToColor(options.video.palette, "black");
st.texture->setAsRenderTarget(renderer_);
st.texture->setBlendMode(SDL_BLENDMODE_BLEND); EndingTexture st;
text_->writeDX(TEXT_STROKE, 2, 2, t.caption, 1, c, 2, c);
// Crea la textura
st.image_texture = std::make_shared<Texture>(Screen::get()->getRenderer());
st.image_texture->createBlank(WIDTH, HEIGHT);
st.image_texture->setAsRenderTarget(Screen::get()->getRenderer());
st.image_texture->setBlendMode(SDL_BLENDMODE_BLEND);
text->writeDX(TEXT_STROKE, 2, 2, txt.caption, 1, color, 2, color);
// Crea el sprite // Crea el sprite
st.sprite = std::make_shared<Sprite>(st.texture, 0, 0, st.texture->getWidth(), st.texture->getHeight()); st.image_sprite = std::make_shared<Sprite>(st.image_texture, 0, 0, st.image_texture->getWidth(), st.image_texture->getHeight());
st.sprite->setPosition((GAMECANVAS_WIDTH - st.texture->getWidth()) / 2, t.pos); st.image_sprite->setPosition((options.game.width - st.image_texture->getWidth()) / 2, txt.pos);
// Crea la coverTexture // Crea la coverTexture
st.cover_texture = std::make_shared<Texture>(renderer_); st.cover_texture = std::make_shared<Texture>(Screen::get()->getRenderer());
st.cover_texture->createBlank(width, height + 8); st.cover_texture->createBlank(WIDTH, HEIGHT + 8);
st.cover_texture->setAsRenderTarget(renderer_); st.cover_texture->setAsRenderTarget(Screen::get()->getRenderer());
st.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND); st.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la coverTexture con color transparente // Rellena la coverTexture con color transparente
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Los primeros 8 pixels crea una malla // Crea una malla de 8 pixels de alto
c = stringToColor(options.video.palette, "black"); color = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
for (int i = 0; i < width; i += 2) for (int i = 0; i < WIDTH; i += 2)
{ {
SDL_RenderDrawPoint(renderer_, i, 0); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 0);
SDL_RenderDrawPoint(renderer_, i, 2); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 2);
SDL_RenderDrawPoint(renderer_, i, 4); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 4);
SDL_RenderDrawPoint(renderer_, i, 6); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 6);
SDL_RenderDrawPoint(renderer_, i + 1, 5); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 5);
SDL_RenderDrawPoint(renderer_, i + 1, 7); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, width, height}; SDL_Rect rect = {0, 8, WIDTH, HEIGHT};
c = stringToColor(options.video.palette, "black"); color = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
// Crea el sprite // Crea el sprite
st.cover_sprite = std::make_shared<Sprite>(st.cover_texture, 0, 0, st.cover_texture->getWidth(), st.cover_texture->getHeight() - 8); st.cover_sprite = std::make_shared<Sprite>(st.cover_texture, 0, 0, st.cover_texture->getWidth(), st.cover_texture->getHeight() - 8);
st.cover_sprite->setPosition((GAMECANVAS_WIDTH - st.cover_texture->getWidth()) / 2, t.pos); st.cover_sprite->setPosition((options.game.width - st.cover_texture->getWidth()) / 2, txt.pos);
st.cover_sprite->setClip(0, 8, -1, -1); st.cover_sprite->setClip(0, 8, st.cover_texture->getWidth(), st.cover_texture->getHeight());
// Inicializa variables // Inicializa variables
st.clip_desp = 8; st.cover_clip_desp = 8;
st.clip_height = height; st.cover_clip_height = HEIGHT;
sprite_texts_.push_back(st); sprite_texts_.push_back(st);
} }
@@ -275,57 +258,57 @@ void Ending::iniPics()
// Crea los sprites // Crea los sprites
sprite_pics_.clear(); sprite_pics_.clear();
for (auto p : pics) for (const auto &pic : pics)
{ {
EndingTexture sp; EndingTexture sp;
// Crea la texture // Crea la texture
sp.texture = resource_->getTexture(p.caption); sp.image_texture = Resource::get()->getTexture(pic.caption);
const int width = sp.texture->getWidth(); const int WIDTH = sp.image_texture->getWidth();
const int height = sp.texture->getHeight(); const int HEIGHT = sp.image_texture->getHeight();
// Crea el sprite // Crea el sprite
sp.sprite = std::make_shared<Sprite>(sp.texture, 0, 0, width, height); sp.image_sprite = std::make_shared<Sprite>(sp.image_texture, 0, 0, WIDTH, HEIGHT);
sp.sprite->setPosition((GAMECANVAS_WIDTH - width) / 2, p.pos); sp.image_sprite->setPosition((options.game.width - WIDTH) / 2, pic.pos);
// Crea la coverTexture // Crea la coverTexture
sp.cover_texture = std::make_shared<Texture>(renderer_); sp.cover_texture = std::make_shared<Texture>(Screen::get()->getRenderer());
sp.cover_texture->createBlank(width, height + 8); sp.cover_texture->createBlank(WIDTH, HEIGHT + 8);
sp.cover_texture->setAsRenderTarget(renderer_); sp.cover_texture->setAsRenderTarget(Screen::get()->getRenderer());
sp.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND); sp.cover_texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la coverTexture con color transparente // Rellena la coverTexture con color transparente
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Los primeros 8 pixels crea una malla // Crea una malla en los primeros 8 pixels
Color c = stringToColor(options.video.palette, "black"); Color c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), c.r, c.g, c.b, 0xFF);
for (int i = 0; i < width; i += 2) for (int i = 0; i < WIDTH; i += 2)
{ {
SDL_RenderDrawPoint(renderer_, i, 0); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 0);
SDL_RenderDrawPoint(renderer_, i, 2); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 2);
SDL_RenderDrawPoint(renderer_, i, 4); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 4);
SDL_RenderDrawPoint(renderer_, i, 6); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 6);
SDL_RenderDrawPoint(renderer_, i + 1, 5); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 5);
SDL_RenderDrawPoint(renderer_, i + 1, 7); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 7);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 8, width, height}; SDL_Rect rect = {0, 8, WIDTH, HEIGHT};
c = stringToColor(options.video.palette, "black"); c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), c.r, c.g, c.b, 0xFF);
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
// Crea el sprite // Crea el sprite
sp.cover_sprite = std::make_shared<Sprite>(sp.cover_texture, 0, 0, sp.cover_texture->getWidth(), sp.cover_texture->getHeight() - 8); sp.cover_sprite = std::make_shared<Sprite>(sp.cover_texture, 0, 0, sp.cover_texture->getWidth(), sp.cover_texture->getHeight() - 8);
sp.cover_sprite->setPosition((GAMECANVAS_WIDTH - sp.cover_texture->getWidth()) / 2, p.pos); sp.cover_sprite->setPosition((options.game.width - sp.cover_texture->getWidth()) / 2, pic.pos);
sp.cover_sprite->setClip(0, 8, -1, -1); sp.cover_sprite->setClip(0, 8, sp.cover_texture->getWidth(), sp.cover_texture->getHeight());
// Inicializa variables // Inicializa variables
sp.clip_desp = 8; sp.cover_clip_desp = 8;
sp.clip_height = height; sp.cover_clip_height = HEIGHT;
sprite_pics_.push_back(sp); sprite_pics_.push_back(sp);
} }
@@ -336,7 +319,7 @@ void Ending::iniScenes()
{ {
// Variable para los tiempos // Variable para los tiempos
int trigger; int trigger;
const int lapse = 80; constexpr int LAPSE = 80;
// Crea el contenedor // Crea el contenedor
SceneData sc; SceneData sc;
@@ -349,13 +332,13 @@ void Ending::iniScenes()
sc.picture_index = 0; sc.picture_index = 0;
sc.text_index.clear(); sc.text_index.clear();
trigger = 85 * 2; trigger = 85 * 2;
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({0, trigger}); sc.text_index.push_back({0, trigger});
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({1, trigger}); sc.text_index.push_back({1, trigger});
trigger += lapse * 3; trigger += LAPSE * 3;
sc.text_index.push_back({2, trigger}); sc.text_index.push_back({2, trigger});
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({3, trigger}); sc.text_index.push_back({3, trigger});
scenes_.push_back(sc); scenes_.push_back(sc);
@@ -364,17 +347,17 @@ void Ending::iniScenes()
sc.picture_index = 1; sc.picture_index = 1;
sc.text_index.clear(); sc.text_index.clear();
trigger = 140 * 2; trigger = 140 * 2;
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({4, trigger}); sc.text_index.push_back({4, trigger});
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({5, trigger}); sc.text_index.push_back({5, trigger});
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({6, trigger}); sc.text_index.push_back({6, trigger});
trigger += lapse * 3; trigger += LAPSE * 3;
sc.text_index.push_back({7, trigger}); sc.text_index.push_back({7, trigger});
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({8, trigger}); sc.text_index.push_back({8, trigger});
trigger += lapse * 3; trigger += LAPSE * 3;
sc.text_index.push_back({9, trigger}); sc.text_index.push_back({9, trigger});
scenes_.push_back(sc); scenes_.push_back(sc);
@@ -383,9 +366,9 @@ void Ending::iniScenes()
sc.picture_index = 2; sc.picture_index = 2;
sc.text_index.clear(); sc.text_index.clear();
trigger = 148 / 2; trigger = 148 / 2;
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({10, trigger}); sc.text_index.push_back({10, trigger});
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({11, trigger}); sc.text_index.push_back({11, trigger});
scenes_.push_back(sc); scenes_.push_back(sc);
@@ -394,9 +377,9 @@ void Ending::iniScenes()
sc.picture_index = 3; sc.picture_index = 3;
sc.text_index.clear(); sc.text_index.clear();
trigger = 87 / 2; trigger = 87 / 2;
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({12, trigger}); sc.text_index.push_back({12, trigger});
trigger += lapse / 2; trigger += LAPSE / 2;
sc.text_index.push_back({13, trigger}); sc.text_index.push_back({13, trigger});
scenes_.push_back(sc); scenes_.push_back(sc);
@@ -405,11 +388,11 @@ void Ending::iniScenes()
sc.picture_index = 4; sc.picture_index = 4;
sc.text_index.clear(); sc.text_index.clear();
trigger = 91 * 2; trigger = 91 * 2;
trigger += lapse; trigger += LAPSE;
sc.text_index.push_back({14, trigger}); sc.text_index.push_back({14, trigger});
trigger += lapse * 2; trigger += LAPSE * 2;
sc.text_index.push_back({15, trigger}); sc.text_index.push_back({15, trigger});
trigger += lapse * 3; trigger += LAPSE * 3;
sc.text_index.push_back({16, trigger}); sc.text_index.push_back({16, trigger});
scenes_.push_back(sc); scenes_.push_back(sc);
} }
@@ -417,7 +400,7 @@ void Ending::iniScenes()
// Bucle principal // Bucle principal
void Ending::run() void Ending::run()
{ {
JA_PlayMusic(music); JA_PlayMusic(Resource::get()->getMusic("ending1.ogg"));
while (options.section.section == Section::ENDING) while (options.section.section == Section::ENDING)
{ {
@@ -451,44 +434,45 @@ void Ending::updateCounters()
// Actualiza las cortinillas de los elementos // Actualiza las cortinillas de los elementos
void Ending::updateSpriteCovers() void Ending::updateSpriteCovers()
{ // Actualiza la cortinilla de los textos {
// Actualiza la cortinilla de los textos
if (counter_ % 4 == 0) if (counter_ % 4 == 0)
{ {
for (auto ti : scenes_[current_scene_].text_index) for (auto ti : scenes_.at(current_scene_).text_index)
{ {
if (counter_ > ti.trigger) if (counter_ > ti.trigger)
{ {
if (sprite_texts_[ti.index].clip_desp > 0) if (sprite_texts_.at(ti.index).cover_clip_desp > 0)
{ {
sprite_texts_[ti.index].clip_desp -= 2; sprite_texts_.at(ti.index).cover_clip_desp -= 2;
} }
else if (sprite_texts_[ti.index].clip_height > 0) else if (sprite_texts_.at(ti.index).cover_clip_height > 0)
{ {
sprite_texts_[ti.index].clip_height -= 2; sprite_texts_.at(ti.index).cover_clip_height -= 2;
sprite_texts_[ti.index].cover_sprite->setY(sprite_texts_[ti.index].cover_sprite->getY() + 2); sprite_texts_.at(ti.index).cover_sprite->setY(sprite_texts_.at(ti.index).cover_sprite->getY() + 2);
} }
sprite_texts_[ti.index].cover_sprite->setClip(0, sprite_texts_[ti.index].clip_desp, sprite_texts_[ti.index].cover_sprite->getWidth(), sprite_texts_[ti.index].clip_height); sprite_texts_.at(ti.index).cover_sprite->setClip(0, sprite_texts_.at(ti.index).cover_clip_desp, sprite_texts_.at(ti.index).cover_sprite->getWidth(), sprite_texts_.at(ti.index).cover_clip_height);
} }
} }
} }
// Actualiza la cortinilla de las imagenes // Actualiza la cortinilla de las imágenes
if (counter_ % 2 == 0) if (counter_ % 2 == 0)
{ {
if (sprite_pics_[current_scene_].clip_desp > 0) if (sprite_pics_.at(current_scene_).cover_clip_desp > 0)
{ {
sprite_pics_[current_scene_].clip_desp -= 2; sprite_pics_.at(current_scene_).cover_clip_desp -= 2;
} }
else if (sprite_pics_[current_scene_].clip_height > 0) else if (sprite_pics_.at(current_scene_).cover_clip_height > 0)
{ {
sprite_pics_[current_scene_].clip_height -= 2; sprite_pics_.at(current_scene_).cover_clip_height -= 2;
if (sprite_pics_[current_scene_].clip_height < 0) if (sprite_pics_.at(current_scene_).cover_clip_height < 0)
{ {
sprite_pics_[current_scene_].clip_height = 0; sprite_pics_.at(current_scene_).cover_clip_height = 0;
} }
sprite_pics_[current_scene_].cover_sprite->setY(sprite_pics_[current_scene_].cover_sprite->getY() + 2); sprite_pics_.at(current_scene_).cover_sprite->setY(sprite_pics_.at(current_scene_).cover_sprite->getY() + 2);
} }
sprite_pics_[current_scene_].cover_sprite->setClip(0, sprite_pics_[current_scene_].clip_desp, sprite_pics_[current_scene_].cover_sprite->getWidth(), sprite_pics_[current_scene_].clip_height); sprite_pics_.at(current_scene_).cover_sprite->setClip(0, sprite_pics_.at(current_scene_).cover_clip_desp, sprite_pics_.at(current_scene_).cover_sprite->getWidth(), sprite_pics_.at(current_scene_).cover_clip_height);
} }
} }
@@ -516,40 +500,41 @@ void Ending::checkChangeScene()
void Ending::fillCoverTexture() void Ending::fillCoverTexture()
{ {
// Rellena la textura que cubre el texto con color transparente // Rellena la textura que cubre el texto con color transparente
SDL_SetRenderTarget(renderer_, cover_texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), cover_texture_);
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
const Color color = stringToColor(options.video.palette, "black"); const Color color = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
for (int i = 0; i < 256; i += 2) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 0); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 0, GAMECANVAS_HEIGHT + 0);
SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 1); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, GAMECANVAS_HEIGHT + 1);
SDL_RenderDrawPoint(renderer_, i + 0, GAMECANVAS_HEIGHT + 2); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 0, GAMECANVAS_HEIGHT + 2);
SDL_RenderDrawPoint(renderer_, i + 1, GAMECANVAS_HEIGHT + 3); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, GAMECANVAS_HEIGHT + 3);
SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 4); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, GAMECANVAS_HEIGHT + 4);
SDL_RenderDrawPoint(renderer_, i, GAMECANVAS_HEIGHT + 6); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, GAMECANVAS_HEIGHT + 6);
} }
// El resto se rellena de color sólido // El resto se rellena de color sólido
SDL_Rect rect = {0, 0, 256, GAMECANVAS_HEIGHT}; SDL_Rect rect = {0, 0, 256, GAMECANVAS_HEIGHT};
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
} }
// Dibuja la cortinilla de cambio de escena // Dibuja la cortinilla de cambio de escena
void Ending::renderCoverTexture() void Ending::renderCoverTexture()
{ {
if (cover_counter_ > 0) if (cover_counter_ > 0)
{ // Dibuja la textura que cubre el texto {
const int offset = std::min(cover_counter_, 100); // Dibuja la textura que cubre el texto
SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, offset * 2}; const int OFFSET = std::min(cover_counter_, 100);
SDL_Rect dstRect = {0, 0, 256, offset * 2}; SDL_Rect srcRect = {0, 200 - (cover_counter_ * 2), 256, OFFSET * 2};
SDL_RenderCopy(renderer_, cover_texture_, &srcRect, &dstRect); SDL_Rect dstRect = {0, 0, 256, OFFSET * 2};
SDL_RenderCopy(Screen::get()->getRenderer(), cover_texture_, &srcRect, &dstRect);
} }
} }

View File

@@ -1,18 +1,12 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
class Asset; // lines 9-9 class Sprite; // lines 12-12
class Input; // lines 10-10 class Texture; // lines 14-14
class Resource; // lines 11-11
class Screen; // lines 12-12
class Sprite; // lines 13-13
class Text; // lines 14-14
class Texture; // lines 15-15
struct JA_Music_t; // lines 16-16
class Ending class Ending
{ {
@@ -20,12 +14,12 @@ private:
// Estructuras // Estructuras
struct EndingTexture // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla struct EndingTexture // Estructura con dos texturas y sprites, uno para mostrar y el otro hace de cortinilla
{ {
std::shared_ptr<Texture> texture; // Textura a mostrar std::shared_ptr<Texture> image_texture; // Textura a mostrar
std::shared_ptr<Sprite> sprite; // Sprite para mostrar la textura std::shared_ptr<Sprite> image_sprite; // Sprite para mostrar la textura
std::shared_ptr<Texture> cover_texture; // Textura que cubre a la otra textura std::shared_ptr<Texture> cover_texture; // Textura que cubre a la otra textura
std::shared_ptr<Sprite> cover_sprite; // Sprite para mostrar la textura que cubre a la otra textura std::shared_ptr<Sprite> cover_sprite; // Sprite para mostrar la textura que cubre a la otra textura
int clip_desp; // Desplazamiento del spriteClip de la textura de cobertura int cover_clip_desp; // Desplazamiento del spriteClip de la textura de cobertura
int clip_height; // Altura del spriteClip de la textura de cobertura int cover_clip_height; // Altura del spriteClip de la textura de cobertura
}; };
struct TextAndPosition // Estructura con un texto y su posición en el eje Y struct TextAndPosition // Estructura con un texto y su posición en el eje Y
@@ -34,7 +28,7 @@ private:
int pos; // Posición int pos; // Posición
}; };
struct asdhk struct TextIndex
{ {
int index; int index;
int trigger; int trigger;
@@ -42,18 +36,12 @@ private:
struct SceneData // Estructura para crear cada una de las escenas del final struct SceneData // Estructura para crear cada una de las escenas del final
{ {
std::vector<asdhk> text_index; // Indices del vector de textos a mostrar y su disparador std::vector<TextIndex> text_index; // Indices del vector de textos a mostrar y su disparador
int picture_index; // Indice del vector de imagenes a mostrar int picture_index; // Indice del vector de imagenes a mostrar
int counter_end; // Valor del contador en el que finaliza la escena int counter_end; // Valor del contador en el que finaliza la escena
}; };
// Objetos y punteros // 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
Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
SDL_Texture *cover_texture_; // Textura para cubrir el texto SDL_Texture *cover_texture_; // Textura para cubrir el texto
// Variables // Variables
@@ -65,7 +53,6 @@ private:
std::vector<EndingTexture> sprite_pics_; // Vector con los sprites de texto con su cortinilla std::vector<EndingTexture> sprite_pics_; // Vector con los sprites de texto con su cortinilla
int current_scene_; // Escena actual int current_scene_; // Escena actual
std::vector<SceneData> scenes_; // Vector con los textos e imagenes de cada escena std::vector<SceneData> scenes_; // Vector con los textos e imagenes de cada escena
JA_Music_t *music; // Musica que suena durante el final
// Actualiza el objeto // Actualiza el objeto
void update(); void update();

View File

@@ -1,57 +1,44 @@
#include "ending2.h" #include "ending2.h"
#include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_render.h> // for SDL_RenderDrawPoint, SDL_SetRenderDr...
#include <algorithm> // for max, min, replace #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include "animated_sprite.h" // for AnimatedSprite #include <algorithm> // for max, min, replace
#include "asset.h" // for Asset #include "animated_sprite.h" // for AnimatedSprite
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_CENTER_X #include "defines.h" // for options.game.height, GAMECANVAS_CENTER_X
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM...
#include "jail_audio.h" // for JA_SetVolume, JA_PlayMusic, JA_StopM... #include "moving_sprite.h" // for MovingSprite
#include "moving_sprite.h" // for MovingSprite #include "options.h" // for Options, options, OptionsVideo, Sect...
#include "options.h" // for Options, options, OptionsVideo, Sect... #include "resource.h" // for Resource
#include "resource.h" // for Resource #include "screen.h" // for Screen
#include "screen.h" // for Screen #include "text.h" // for Text
#include "text.h" // for Text #include "texture.h" // for Texture
#include "texture.h" // for Texture #include "utils.h" // for Color, stringToColor
#include "utils.h" // for Color, stringToColor #include <iostream>
// Constructor // Constructor
Ending2::Ending2() Ending2::Ending2()
: screen_(Screen::get()), : counter_enabled_(false),
renderer_(Screen::get()->getRenderer()), pre_counter_(0),
resource_(Resource::get()), post_counter_(0),
asset_(Asset::get()), post_counter_enabled_(false),
input_(Input::get()) ticks_(0)
{ {
// Reserva memoria para los punteros a objetos
text_ = resource_->getText("smb2");
music_ = resource_->getMusic("ending2.ogg");
// Inicializa variables
counter_enabled_ = false;
pre_counter_ = 0;
post_counter_ = 0;
post_counter_enabled_ = false;
options.section.section = Section::ENDING2; options.section.section = Section::ENDING2;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
ticks_ = 0;
dist_sprite_text_ = 8;
dist_sprite_sprite_ = 0;
sprite_desp_speed_ = -0.2f;
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> color_list = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto color : color_list) for (const auto &color : color_list)
{ {
colors_.push_back(stringToColor(options.video.palette, color)); colors_.push_back(stringToColor(options.video.palette, color));
} }
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
// Inicializa la lista de sprites // Inicializa la lista de sprites
iniSpriteList(); iniSpriteList();
@@ -102,7 +89,8 @@ void Ending2::update()
// Actualiza el volumen de la musica // Actualiza el volumen de la musica
updateMusicVolume(); updateMusicVolume();
screen_->update(); // Actualiza el objeto
Screen::get()->update();
} }
} }
@@ -110,10 +98,10 @@ void Ending2::update()
void Ending2::render() void Ending2::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); Screen::get()->start();
// Limpia la pantalla // Limpia la pantalla
screen_->clean(stringToColor(options.video.palette, "black")); Screen::get()->clean(stringToColor(options.video.palette, "black"));
// Dibuja los sprites // Dibuja los sprites
renderSprites(); renderSprites();
@@ -124,53 +112,29 @@ void Ending2::render()
// Dibuja los sprites con el texto del final // Dibuja los sprites con el texto del final
renderTexts(); renderTexts();
const std::string txt = std::to_string(post_counter_); // Dibuja una trama arriba y abajo
// text->write(0, 192 - 8, txt); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 0xFF);
for (int i = 0; i < 256; i += 2)
// Dibuja la cuadricula
/*{
SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255);
const int sw = maxSpriteWidth + 6;
const int sh = maxSpriteHeight + 6;
for (int i = 0; i < 256; i += sw)
{
SDL_RenderDrawLine(renderer, i, 0, i, 192);
}
for (int i = 0; i < 192; i += sh)
{
SDL_RenderDrawLine(renderer, 0, i, 255, i);
}
}*/
{ {
// Dibuja una trama arriba y abajo SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 0, 0);
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 0xFF); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 1);
for (int i = 0; i < 256; i += 2) SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 0, 2);
{ SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 3);
SDL_RenderDrawPoint(renderer_, i + 0, 0);
SDL_RenderDrawPoint(renderer_, i + 1, 1);
SDL_RenderDrawPoint(renderer_, i + 0, 2);
SDL_RenderDrawPoint(renderer_, i + 1, 3);
SDL_RenderDrawPoint(renderer_, i, 4); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 4);
SDL_RenderDrawPoint(renderer_, i, 6); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 6);
SDL_RenderDrawPoint(renderer_, i + 0, 191); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 0, 191);
SDL_RenderDrawPoint(renderer_, i + 1, 190); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 190);
SDL_RenderDrawPoint(renderer_, i + 0, 189); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 0, 189);
SDL_RenderDrawPoint(renderer_, i + 1, 188); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 188);
SDL_RenderDrawPoint(renderer_, i, 187); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 187);
SDL_RenderDrawPoint(renderer_, i, 185); SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 185);
}
// SDL_RenderDrawLine(renderer, 0, 1, 255, 1);
// SDL_RenderDrawLine(renderer, 0, 3, 255, 3);
// SDL_RenderDrawLine(renderer, 0, 188, 255, 188);
// SDL_RenderDrawLine(renderer, 0, 190, 255, 190);
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -192,7 +156,7 @@ void Ending2::checkInput()
// Bucle principal // Bucle principal
void Ending2::run() void Ending2::run()
{ {
JA_PlayMusic(music_); JA_PlayMusic(Resource::get()->getMusic("ending2.ogg"));
while (options.section.section == Section::ENDING2) while (options.section.section == Section::ENDING2)
{ {
@@ -316,9 +280,9 @@ void Ending2::loadSprites()
sprite_max_height_ = 0; sprite_max_height_ = 0;
// Carga los sprites // Carga los sprites
for (auto sl : sprite_list_) for (const auto &file : sprite_list_)
{ {
sprites_.emplace_back(std::make_shared<AnimatedSprite>(resource_->getTexture(sl + ".png"), resource_->getAnimations(sl + ".ani"))); sprites_.emplace_back(std::make_shared<AnimatedSprite>(Resource::get()->getTexture(file + ".png"), Resource::get()->getAnimations(file + ".ani")));
sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_); sprite_max_width_ = std::max(sprites_.back()->getWidth(), sprite_max_width_);
sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_); sprite_max_height_ = std::max(sprites_.back()->getHeight(), sprite_max_height_);
} }
@@ -364,9 +328,9 @@ void Ending2::renderSprites()
const Color color = stringToColor(options.video.palette, "red"); const Color color = stringToColor(options.video.palette, "red");
for (auto sprite : sprites_) for (auto sprite : sprites_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool A = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool B = sprite->getRect().y < options.game.height;
if (a && b) if (A && B)
{ {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render(); sprite->render();
@@ -385,9 +349,9 @@ void Ending2::renderSpriteTexts()
const Color color = stringToColor(options.video.palette, "white"); const Color color = stringToColor(options.video.palette, "white");
for (auto sprite : sprite_texts_) for (auto sprite : sprite_texts_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool A = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool B = sprite->getRect().y < options.game.height;
if (a && b) if (A && B)
{ {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render(); sprite->render();
@@ -400,9 +364,9 @@ void Ending2::renderTexts()
{ {
for (auto sprite : texts_) for (auto sprite : texts_)
{ {
const bool a = sprite->getRect().y + sprite->getRect().h > 0; const bool A = sprite->getRect().y + sprite->getRect().h > 0;
const bool b = sprite->getRect().y < GAMECANVAS_HEIGHT; const bool B = sprite->getRect().y < options.game.height;
if (a && b) if (A && B)
{ {
sprite->render(); sprite->render();
} }
@@ -412,25 +376,23 @@ void Ending2::renderTexts()
// Coloca los sprites en su sito // Coloca los sprites en su sito
void Ending2::placeSprites() void Ending2::placeSprites()
{ {
for (int i = 0; i < (int)sprites_.size(); ++i) for (int i = 0; i < static_cast<int>(sprites_.size()); ++i)
{ {
const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_; const int X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int y = (i / 1) * (sprite_max_height_ + dist_sprite_text_ + text_->getCharacterSize() + dist_sprite_sprite_) + GAMECANVAS_HEIGHT + 40; const int Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT_ + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE_) + options.game.height + 40;
const int w = sprites_[i]->getWidth(); const int W = sprites_.at(i)->getWidth();
const int h = sprites_[i]->getHeight(); const int H = sprites_.at(i)->getHeight();
const int dx = -(w / 2); const int DX = -(W / 2);
const int dy = i % 1 == 0 ? sprite_max_height_ - h : (int)(sprite_max_height_ * 1.5f) - h; const int DY = sprite_max_height_ - H;
sprites_[i]->setPosition({x + dx, y + dy, w, h}); sprites_.at(i)->setPos({X + DX, Y + DY, W, H});
sprites_[i]->setVelY(sprite_desp_speed_); sprites_.at(i)->setVelY(SPRITE_DESP_SPEED_);
} }
// Recoloca el último sprite, que es el del jugador // Recoloca el sprite del jugador, que es el último de la lista
const int w = sprites_.back()->getWidth(); const int X = (options.game.width - sprites_.back()->getWidth()) / 2;
const int x = GAMECANVAS_CENTER_X - (w / 2); const int Y = sprites_.back()->getPosY() + sprite_max_height_ * 2;
const int y = sprites_.back()->getPosY() + sprite_max_height_ * 2; sprites_.back()->setPos(X, Y);
sprites_.back()->setPosX(x);
sprites_.back()->setPosY(y);
sprites_.back()->setCurrentAnimation("walk"); sprites_.back()->setCurrentAnimation("walk");
} }
@@ -438,32 +400,41 @@ void Ending2::placeSprites()
void Ending2::createSpriteTexts() void Ending2::createSpriteTexts()
{ {
// Crea los sprites de texto a partir de la lista // Crea los sprites de texto a partir de la lista
for (int i = 0; i < (int)sprite_list_.size(); ++i) for (int i = 0; i < static_cast<int>(sprite_list_.size()); ++i)
{ {
// Calcula constantes auto text = Resource::get()->getText("smb2");
std::string txt = sprite_list_[i];
std::replace(txt.begin(), txt.end(), '_', ' ');
txt = txt == "player" ? "JAILDOCTOR" : txt; // Reemplaza el texto
const int w = text_->lenght(txt, 1);
const int h = text_->getCharacterSize();
const int x = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const int dx = -(w / 2);
const int y = sprites_[i]->getPosY() + sprites_[i]->getHeight() + dist_sprite_text_;
// Cambia la posición del último sprite // Procesa y ajusta el texto del sprite actual
const int X = (i == (int)sprite_list_.size() - 1) ? GAMECANVAS_CENTER_X - (w / 2) : x + dx; std::string txt = sprite_list_[i];
std::replace(txt.begin(), txt.end(), '_', ' '); // Reemplaza '_' por ' '
if (txt == "player")
{
txt = "JAILDOCTOR"; // Reemplaza "player" por "JAILDOCTOR"
}
// Calcula las dimensiones del texto
const int W = text->lenght(txt, 1);
const int H = text->getCharacterSize();
// Determina la columna y la posición X del texto
const int X = (i == static_cast<int>(sprite_list_.size()) - 1)
? (GAMECANVAS_CENTER_X - (W / 2))
: ((i % 2 == 0 ? FIRST_COL_ : SECOND_COL_) - (W / 2));
// Calcula la posición Y del texto en base a la posición y altura del sprite
const int Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT_;
// Crea la textura // Crea la textura
auto texture = std::make_shared<Texture>(renderer_); auto texture = std::make_shared<Texture>(Screen::get()->getRenderer());
texture->createBlank(w, h); texture->createBlank(W, H);
texture->setAsRenderTarget(renderer_); texture->setAsRenderTarget(Screen::get()->getRenderer());
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text_->write(0, 0, txt); text->write(0, 0, txt);
// Crea el sprite // Crea el sprite
SDL_Rect pos = {X, y, w, h}; SDL_Rect pos = {X, Y, W, H};
sprite_texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos)); sprite_texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
sprite_texts_.back()->setVelY(sprite_desp_speed_); sprite_texts_.back()->setVelY(SPRITE_DESP_SPEED_);
} }
} }
@@ -474,32 +445,34 @@ void Ending2::createTexts()
std::vector<std::string> list; std::vector<std::string> list;
list.push_back("STARRING"); list.push_back("STARRING");
auto text = Resource::get()->getText("smb2");
// Crea los sprites de texto a partir de la lista // Crea los sprites de texto a partir de la lista
for (int i = 0; i < (int)list.size(); ++i) for (int i = 0; i < (int)list.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
const int w = text_->lenght(list[i], 1); const int w = text->lenght(list[i], 1);
const int h = text_->getCharacterSize(); const int h = text->getCharacterSize();
const int x = GAMECANVAS_CENTER_X; const int x = GAMECANVAS_CENTER_X;
const int dx = -(w / 2); const int dx = -(w / 2);
const int y = GAMECANVAS_HEIGHT + (text_->getCharacterSize() * (i * 2)); const int y = options.game.height + (text->getCharacterSize() * (i * 2));
// Crea la textura // Crea la textura
auto texture = std::make_shared<Texture>(renderer_); auto texture = std::make_shared<Texture>(Screen::get()->getRenderer());
texture->createBlank(w, h); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer_); texture->setAsRenderTarget(Screen::get()->getRenderer());
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text_->write(0, 0, list[i]); text->write(0, 0, list[i]);
// Crea el sprite // Crea el sprite
SDL_Rect pos = {x + dx, y, w, h}; SDL_Rect pos = {x + dx, y, w, h};
texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos)); texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
texts_.back()->setVelY(sprite_desp_speed_); texts_.back()->setVelY(SPRITE_DESP_SPEED_);
} }
// Crea los últimos textos // Crea los últimos textos
// El primer texto va a continuación del ultimo spriteText // El primer texto va a continuación del ultimo spriteText
const int start = sprite_texts_.back()->getPosY() + text_->getCharacterSize() * 15; const int START = sprite_texts_.back()->getPosY() + text->getCharacterSize() * 15;
list.clear(); list.clear();
list.push_back("THANK YOU"); list.push_back("THANK YOU");
list.push_back("FOR PLAYING!"); list.push_back("FOR PLAYING!");
@@ -508,23 +481,23 @@ void Ending2::createTexts()
for (int i = 0; i < (int)list.size(); ++i) for (int i = 0; i < (int)list.size(); ++i)
{ {
// Calcula constantes // Calcula constantes
const int w = text_->lenght(list[i], 1); const int w = text->lenght(list[i], 1);
const int h = text_->getCharacterSize(); const int h = text->getCharacterSize();
const int x = GAMECANVAS_CENTER_X; const int x = GAMECANVAS_CENTER_X;
const int dx = -(w / 2); const int dx = -(w / 2);
const int y = start + (text_->getCharacterSize() * (i * 2)); const int y = START + (text->getCharacterSize() * (i * 2));
// Crea la textura // Crea la textura
auto texture = std::make_shared<Texture>(renderer_); auto texture = std::make_shared<Texture>(Screen::get()->getRenderer());
texture->createBlank(w, h); texture->createBlank(w, h);
texture->setAsRenderTarget(renderer_); texture->setAsRenderTarget(Screen::get()->getRenderer());
texture->setBlendMode(SDL_BLENDMODE_BLEND); texture->setBlendMode(SDL_BLENDMODE_BLEND);
text_->write(0, 0, list[i]); text->write(0, 0, list[i]);
// Crea el sprite // Crea el sprite
SDL_Rect pos = {x + dx, y, w, h}; SDL_Rect pos = {x + dx, y, w, h};
texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos)); texts_.emplace_back(std::make_shared<MovingSprite>(texture, pos));
texts_.back()->setVelY(sprite_desp_speed_); texts_.back()->setVelY(SPRITE_DESP_SPEED_);
} }
} }
@@ -532,12 +505,12 @@ void Ending2::createTexts()
void Ending2::updateFinalFade() void Ending2::updateFinalFade()
{ {
// La variable step va de 0 a 40 en el tramo de postCounter que va de 500 a 540. Al dividirlo por 40, va de 0.0f a 1.0f // La variable step va de 0 a 40 en el tramo de postCounter que va de 500 a 540. Al dividirlo por 40, va de 0.0f a 1.0f
const float step = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f; const float STEP = std::min(std::max(post_counter_, 500) - 500, 40) / 40.0f;
const int index = (colors_.size() - 1) * step; const int INDEX = (colors_.size() - 1) * STEP;
for (auto t : texts_) for (const auto &text : texts_)
{ {
t->getTexture()->setColor(colors_[index].r, colors_[index].g, colors_[index].b); text->getTexture()->setColor(colors_.at(INDEX).r, colors_.at(INDEX).g, colors_.at(INDEX).b);
} }
} }

View File

@@ -1,35 +1,27 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <memory> // for shared_ptr
#include <memory> // for shared_ptr #include <string> // for string
#include <string> // for string #include <vector> // for vector
#include <vector> // for vector #include "defines.h" // for GAMECANVAS_WIDTH, GAMECANVAS_FIRST_QUAR...
#include "utils.h" // for Color #include "utils.h" // for Color
#include "defines.h" // for GAMECANVAS_FIRST_QUARTER_X, GAMECANVAS_THIRD_QUARTER_X, GAMECANVAS_WIDTH class AnimatedSprite; // lines 10-10
class AnimatedSprite; // lines 9-9 class MovingSprite; // lines 13-13
class Asset; // lines 10-10
class Input; // lines 11-11
class MovingSprite; // lines 12-12
class Resource; // lines 13-13
class Screen; // lines 14-14
class Text; // lines 15-15
struct JA_Music_t; // lines 16-16
class Ending2 class Ending2
{ {
private: private:
// Constantes // Constantes
static constexpr int FIRST_COL_ = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites static constexpr int FIRST_COL_ =
static constexpr int SECOND_COL_ = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites
static constexpr int SECOND_COL_ =
GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites
static constexpr int DIST_SPRITE_TEXT_ = 8; // Distancia entre el sprite y el texto que lo acompaña
static constexpr int DIST_SPRITE_SPRITE_ = 0; // Distancia entre dos sprites de la misma columna
static constexpr float SPRITE_DESP_SPEED_ = -0.2f; // Velocidad de desplazamiento de los sprites
// Objetos y punteros // 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
Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::vector<std::shared_ptr<AnimatedSprite>> sprites_; // Vector con todos los sprites a dibujar std::vector<std::shared_ptr<AnimatedSprite>> sprites_; // Vector con todos los sprites a dibujar
std::vector<std::shared_ptr<MovingSprite>> sprite_texts_; // Vector con los sprites de texto de los sprites std::vector<std::shared_ptr<MovingSprite>> sprite_texts_; // Vector con los sprites de texto de los sprites
std::vector<std::shared_ptr<MovingSprite>> texts_; // Vector con los sprites de texto std::vector<std::shared_ptr<MovingSprite>> texts_; // Vector con los sprites de texto
@@ -40,14 +32,10 @@ private:
int post_counter_; // Contador posterior int post_counter_; // Contador posterior
bool post_counter_enabled_; // Indica si está habilitado el contador bool post_counter_enabled_; // Indica si está habilitado el contador
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa
JA_Music_t *music_; // Musica que suena durante el final
std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar std::vector<std::string> sprite_list_; // Lista con todos los sprites a dibujar
std::vector<Color> colors_; // Vector con los colores para el fade std::vector<Color> colors_; // Vector con los colores para el fade
int sprite_max_width_; // El valor de ancho del sprite mas ancho int sprite_max_width_; // El valor de ancho del sprite mas ancho
int sprite_max_height_; // El valor de alto del sprite mas alto int sprite_max_height_; // El valor de alto del sprite mas alto
int dist_sprite_text_; // Distancia entre el sprite y el texto que lo acompaña
int dist_sprite_sprite_; // Distancia entre dos sprites de la misma columna
float sprite_desp_speed_; // Velocidad de desplazamiento de los sprites
// Actualiza el objeto // Actualiza el objeto
void update(); void update();

View File

@@ -7,17 +7,17 @@
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
Enemy::Enemy(EnemyData enemy) Enemy::Enemy(const EnemyData &enemy)
: sprite_(std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimations(enemy.animation_path))),
color_string_(enemy.color),
x1_(enemy.x1),
x2_(enemy.x2),
y1_(enemy.y1),
y2_(enemy.y2),
should_flip_(enemy.flip),
should_mirror_(enemy.mirror)
{ {
// Crea objetos
sprite_ = std::make_shared<AnimatedSprite>(Resource::get()->getTexture(enemy.texture_path), Resource::get()->getAnimations(enemy.animation_path));
// Obten el resto de valores // Obten el resto de valores
x1_ = enemy.x1;
x2_ = enemy.x2;
y1_ = enemy.y1;
y2_ = enemy.y2;
color_string_ = enemy.color;
setPalette(options.video.palette); setPalette(options.video.palette);
sprite_->setPosX(enemy.x); sprite_->setPosX(enemy.x);
sprite_->setPosY(enemy.y); sprite_->setPosY(enemy.y);
@@ -25,24 +25,16 @@ Enemy::Enemy(EnemyData enemy)
sprite_->setVelY(enemy.vy); sprite_->setVelY(enemy.vy);
sprite_->setWidth(enemy.w); sprite_->setWidth(enemy.w);
sprite_->setHeight(enemy.h); sprite_->setHeight(enemy.h);
should_flip_ = enemy.flip;
should_mirror_ = enemy.mirror;
const SDL_RendererFlip flip = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE; const SDL_RendererFlip FLIP = (should_flip_ && enemy.vx < 0.0f) ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE;
const SDL_RendererFlip mirror = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE; const SDL_RendererFlip MIRROR = should_mirror_ ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE;
sprite_->setFlip(static_cast<SDL_RendererFlip>(flip | mirror)); sprite_->setFlip(static_cast<SDL_RendererFlip>(FLIP | MIRROR));
collider_ = getRect(); collider_ = getRect();
// Coloca un frame al azar o el designado // Coloca un frame al azar o el designado
if (enemy.frame == -1) sprite_->setCurrentAnimationFrame(
{ (enemy.frame == -1) ? (rand() % sprite_->getCurrentAnimationSize()) : enemy.frame);
sprite_->setCurrentAnimationFrame(rand() % sprite_->getCurrentAnimationSize());
}
else
{
sprite_->setCurrentAnimationFrame(enemy.frame);
}
} }
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla

View File

@@ -49,7 +49,7 @@ private:
public: public:
// Constructor // Constructor
Enemy(EnemyData enemy); explicit Enemy(const EnemyData &enemy);
// Destructor // Destructor
~Enemy() = default; ~Enemy() = default;

View File

@@ -8,105 +8,58 @@
#include <vector> // for vector #include <vector> // for vector
#include "asset.h" // for Asset #include "asset.h" // for Asset
#include "cheevos.h" // for Cheevos #include "cheevos.h" // for Cheevos
#include "defines.h" // for PLAY_AREA_HEIGHT, GAMECANVAS_WIDTH
#include "debug.h" // for Debug #include "debug.h" // for Debug
#include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "defines.h" // for BLOCK, PLAY_AREA_HEIGHT, GAMECANVAS_...
#include "global_events.h" // for check
#include "global_inputs.h" // for check
#include "input.h" // for Input, InputAction, REPEAT_FALSE
#include "item_tracker.h" // for ItemTracker #include "item_tracker.h" // for ItemTracker
#include "jail_audio.h" // for JA_PauseMusic, JA_PlaySound, JA_Resu... #include "jail_audio.h" // for JA_PauseMusic, JA_PlaySound, JA_Resu...
#include "resource.h" // for Resource, res_room_t #include "notifier.h" // for Notifier, NotificationText
#include "room.h" // for Room, room_t #include "options.h" // for Options, options, Cheat, OptionsVideo
#include "resource.h" // for ResourceRoom, Resource
#include "room.h" // for Room, RoomData
#include "room_tracker.h" // for RoomTracker #include "room_tracker.h" // for RoomTracker
#include "scoreboard.h" // for ScoreboardData, Scoreboard
#include "screen.h" // for Screen #include "screen.h" // for Screen
#include "stats.h" // for Stats #include "stats.h" // for Stats
#include "text.h" // for Text, TXT_CENTER, TXT_COLOR #include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "utils.h" // for options_t, cheat_t, stringToColor #include "utils.h" // for Color, stringToColor, colorAreEqual
#include "options.h"
#include "notifier.h"
#include "global_inputs.h"
#include "global_events.h"
//#include "surface.h"
// Constructor // Constructor
Game::Game() Game::Game(GameMode mode)
: screen_(Screen::get()), : board_(std::make_shared<ScoreboardData>(0, 9, 0, true, Color(0, 0, 0), SDL_GetTicks(), options.cheats.jail_is_open == Cheat::CheatState::ENABLED)),
renderer_(Screen::get()->getRenderer()), scoreboard_(std::make_shared<Scoreboard>(board_)),
asset_(Asset::get()), room_tracker_(std::make_shared<RoomTracker>()),
input_(Input::get()), stats_(std::make_shared<Stats>(Asset::get()->get("stats.csv"), Asset::get()->get("stats_buffer.csv"))),
resource_(Resource::get()), mode_(mode),
debug_(Debug::get()),
cheevos_(Cheevos::get())
{
// Inicia algunas variables
//test_surface_ = std::make_shared<Surface>(Screen::get()->getSurface(), "test.gif");
board_ = std::make_shared<ScoreboardData>();
board_->ini_clock = SDL_GetTicks();
#ifdef DEBUG #ifdef DEBUG
current_room_ = "03.room"; current_room_("03.room"),
constexpr int X = 25; spawn_point_(PlayerSpawn(25 * BLOCK, 13 * BLOCK, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL))
constexpr int Y = 13;
spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
debug_->setEnabled(false);
#else #else
current_room_ = "03.room"; current_room_("03.room"),
constexpr int X = 25; spawn_point_(PlayerSpawn(25 * BLOCK, 13 * BLOCK, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL))
constexpr int Y = 13;
spawn_point_ = PlayerSpawn(X * 8, Y * 8, 0, 0, 0, PlayerState::STANDING, SDL_FLIP_HORIZONTAL);
#endif #endif
{
// Crea los objetos
ItemTracker::init();
scoreboard_ = std::make_shared<Scoreboard>(board_);
room_tracker_ = std::make_shared<RoomTracker>();
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_);
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point_, player_texture, player_animations, room_);
player_ = std::make_shared<Player>(player);
text_ = resource_->getText("smb2");
music_ = resource_->getMusic("game.ogg");
death_sound_ = resource_->getSound("death.wav");
stats_ = std::make_shared<Stats>(asset_->get("stats.csv"), asset_->get("stats_buffer.csv"));
// Crea la textura para poner el nombre de la habitación
room_name_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2);
if (room_name_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: roomNameTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Establece el blend mode de la textura
SDL_SetTextureBlendMode(room_name_texture_, SDL_BLENDMODE_BLEND);
// Establece el destino de la textura
room_name_rect_ = {0, PLAY_AREA_HEIGHT, GAMECANVAS_WIDTH, text_->getCharacterSize() * 2};
// Pone el nombre de la habitación en la textura
fillRoomNameTexture();
// Inicializa el resto de variables
ticks_ = 0;
board_->lives = 9;
#ifdef DEBUG #ifdef DEBUG
board_->lives = 9; Debug::get()->setEnabled(false);
#endif #endif
board_->items = 0;
board_->rooms = 1;
board_->music = true;
board_->jail_is_open = options.cheats.jail_is_open == Cheat::CheatState::ENABLED;
setScoreBoardColor();
room_tracker_->addRoom(current_room_);
paused_ = false;
black_screen_ = false;
black_screen_counter_ = 0;
total_items_ = getTotalItems();
initStats();
stats_->addVisit(room_->getName());
cheevos_->enable(!options.cheats.enabled()); // Deshabilita los logros si hay trucos activados
options.section.section = Section::GAME; // Crea objetos e inicializa variables
ItemTracker::init();
DEMO_init();
room_ = std::make_shared<Room>(current_room_, board_);
initPlayer(spawn_point_, room_);
initStats();
total_items_ = getTotalItems();
createRoomNameTexture();
changeRoom(current_room_);
Cheevos::get()->enable(!options.cheats.enabled()); // Deshabilita los logros si hay trucos activados
Cheevos::get()->clearUnobtainableState();
options.section.section = (mode_ == GameMode::GAME) ? Section::GAME : Section::DEMO;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
} }
@@ -123,58 +76,8 @@ void Game::checkEvents()
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
{ {
globalEvents::check(event); globalEvents::check(event);
#ifdef DEBUG #ifdef DEBUG
if (event.type == SDL_KEYDOWN && event.key.repeat == 0) checkDebugEvents(event);
{
switch (event.key.keysym.scancode)
{
case SDL_SCANCODE_G:
debug_->switchEnabled();
options.cheats.invincible = static_cast<Cheat::CheatState>(debug_->getEnabled());
board_->music = !debug_->getEnabled();
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
break;
case SDL_SCANCODE_R:
resource_->reload();
break;
case SDL_SCANCODE_W:
goToRoom(BORDER_TOP);
break;
case SDL_SCANCODE_A:
goToRoom(BORDER_LEFT);
break;
case SDL_SCANCODE_S:
goToRoom(BORDER_BOTTOM);
break;
case SDL_SCANCODE_D:
goToRoom(BORDER_RIGHT);
break;
case SDL_SCANCODE_F6:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 2, false, "F6");
break;
case SDL_SCANCODE_F7:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 3, false, "F7");
break;
case SDL_SCANCODE_F8:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
break;
case SDL_SCANCODE_F9:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
break;
default:
break;
}
}
#endif #endif
} }
} }
@@ -182,16 +85,16 @@ void Game::checkEvents()
// Comprueba el teclado // Comprueba el teclado
void Game::checkInput() void Game::checkInput()
{ {
if (input_->checkInput(input_toggle_music, REPEAT_FALSE)) if (Input::get()->checkInput(InputAction::TOGGLE_MUSIC, REPEAT_FALSE))
{ {
board_->music = !board_->music; board_->music = !board_->music;
board_->music ? JA_ResumeMusic() : JA_PauseMusic(); board_->music ? JA_ResumeMusic() : JA_PauseMusic();
Notifier::get()->show({"MUSIC " + std::string(board_->music ? "ENABLED" : "DISABLED")}, NotificationText::CENTER); Notifier::get()->show({"MUSIC " + std::string(board_->music ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
} }
else if (input_->checkInput(input_pause, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::PAUSE, REPEAT_FALSE))
{ {
switchPause(); togglePause();
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER); Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
} }
@@ -201,13 +104,13 @@ void Game::checkInput()
// Bucle para el juego // Bucle para el juego
void Game::run() void Game::run()
{ {
JA_PlayMusic(music_); JA_PlayMusic(Resource::get()->getMusic("game.ogg"));
if (!board_->music) if (!board_->music)
{ {
JA_PauseMusic(); JA_PauseMusic();
} }
while (options.section.section == Section::GAME) while (options.section.section == Section::GAME || options.section.section == Section::DEMO)
{ {
update(); update();
checkEvents(); checkEvents();
@@ -230,26 +133,29 @@ void Game::update()
checkInput(); checkInput();
#ifdef DEBUG #ifdef DEBUG
debug_->clear(); Debug::get()->clear();
#endif #endif
// Actualiza los objetos // Actualiza los objetos
room_->update(); room_->update();
player_->update(); if (mode_ == GameMode::GAME)
checkPlayerOnBorder(); {
checkPlayerAndItems(); player_->update();
checkPlayerAndEnemies(); checkPlayerOnBorder();
checkIfPlayerIsAlive(); checkPlayerAndItems();
checkGameOver(); checkPlayerAndEnemies();
checkEndGame(); checkIfPlayerIsAlive();
checkRestoringJail(); checkGameOver();
checkSomeCheevos(); checkEndGame();
checkRestoringJail();
checkSomeCheevos();
}
DEMO_checkRoomChange();
scoreboard_->update(); scoreboard_->update();
input_->update();
updateBlackScreen(); updateBlackScreen();
screen_->update(); Screen::get()->update();
#ifdef DEBUG #ifdef DEBUG
updateDebugInfo(); updateDebugInfo();
@@ -261,14 +167,16 @@ void Game::update()
void Game::render() void Game::render()
{ {
// Prepara para dibujar el frame // Prepara para dibujar el frame
screen_->start(); Screen::get()->start();
//test_surface_->render(0, 0, 10, 10, 64, 64);
// Dibuja los elementos del juego en orden // Dibuja los elementos del juego en orden
room_->renderMap(); room_->renderMap();
room_->renderEnemies(); room_->renderEnemies();
room_->renderItems(); room_->renderItems();
player_->render(); if (mode_ == GameMode::GAME)
{
player_->render();
}
renderRoomName(); renderRoomName();
scoreboard_->render(); scoreboard_->render();
renderBlackScreen(); renderBlackScreen();
@@ -279,45 +187,100 @@ void Game::render()
#endif #endif
// Actualiza la pantalla // Actualiza la pantalla
screen_->render(); Screen::get()->render();
} }
#ifdef DEBUG #ifdef DEBUG
// Pasa la información de debug // Pasa la información de debug
void Game::updateDebugInfo() void Game::updateDebugInfo()
{ {
debug_->add("X = " + std::to_string(static_cast<int>(player_->x_)) + ", Y = " + std::to_string(static_cast<int>(player_->y_))); Debug::get()->add("X = " + std::to_string(static_cast<int>(player_->x_)) + ", Y = " + std::to_string(static_cast<int>(player_->y_)));
debug_->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4)); Debug::get()->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4));
debug_->add("STATE = " + std::to_string(static_cast<int>(player_->state_))); Debug::get()->add("STATE = " + std::to_string(static_cast<int>(player_->state_)));
} }
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
void Game::renderDebugInfo() void Game::renderDebugInfo()
{ {
if (!debug_->getEnabled()) if (!Debug::get()->getEnabled())
{ {
return; return;
} }
// Borra el marcador // Borra el marcador
SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT}; SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255);
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
// Pinta la rejilla // Pinta la rejilla
SDL_SetRenderDrawColor(renderer_, 255, 255, 255, 32); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 255, 255, 255, 32);
for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8) for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8)
{ // Lineas horizontales { // Lineas horizontales
SDL_RenderDrawLine(renderer_, 0, i, PLAY_AREA_RIGHT, i); SDL_RenderDrawLine(Screen::get()->getRenderer(), 0, i, PLAY_AREA_RIGHT, i);
} }
for (int i = 0; i < PLAY_AREA_RIGHT; i += 8) for (int i = 0; i < PLAY_AREA_RIGHT; i += 8)
{ // Lineas verticales { // Lineas verticales
SDL_RenderDrawLine(renderer_, i, 0, i, PLAY_AREA_BOTTOM - 1); SDL_RenderDrawLine(Screen::get()->getRenderer(), i, 0, i, PLAY_AREA_BOTTOM - 1);
} }
// Pinta el texto // Pinta el texto
debug_->setPos({1, 18 * 8}); Debug::get()->setPos({1, 18 * 8});
debug_->render(); Debug::get()->render();
}
// Comprueba los eventos
void Game::checkDebugEvents(const SDL_Event &event)
{
if (event.type == SDL_KEYDOWN && event.key.repeat == 0)
{
switch (event.key.keysym.scancode)
{
case SDL_SCANCODE_G:
Debug::get()->toggleEnabled();
options.cheats.invincible = static_cast<Cheat::CheatState>(Debug::get()->getEnabled());
board_->music = !Debug::get()->getEnabled();
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
break;
case SDL_SCANCODE_R:
Resource::get()->reload();
break;
case SDL_SCANCODE_W:
changeRoom(room_->getRoom(BORDER_TOP));
break;
case SDL_SCANCODE_A:
changeRoom(room_->getRoom(BORDER_LEFT));
break;
case SDL_SCANCODE_S:
changeRoom(room_->getRoom(BORDER_BOTTOM));
break;
case SDL_SCANCODE_D:
changeRoom(room_->getRoom(BORDER_RIGHT));
break;
case SDL_SCANCODE_F6:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 2, false, "F6");
break;
case SDL_SCANCODE_F7:
Notifier::get()->show({"ACHIEVEMENT UNLOCKED!", "I LIKE MY MULTICOLOURED FRIENDS"}, NotificationText::LEFT, 3, false, "F7");
break;
case SDL_SCANCODE_F8:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 4, false);
break;
case SDL_SCANCODE_F9:
Notifier::get()->show({"JAILDESIGNER", "IS LOGGED IN"}, NotificationText::LEFT, 5, false);
break;
default:
break;
}
}
} }
#endif #endif
@@ -325,23 +288,23 @@ void Game::renderDebugInfo()
void Game::renderRoomName() void Game::renderRoomName()
{ {
// Dibuja la textura con el nombre de la habitación // Dibuja la textura con el nombre de la habitación
SDL_RenderCopy(renderer_, room_name_texture_, nullptr, &room_name_rect_); SDL_RenderCopy(Screen::get()->getRenderer(), room_name_texture_, nullptr, &room_name_rect_);
} }
// Cambia de habitación // Cambia de habitación
bool Game::changeRoom(std::string file) bool Game::changeRoom(const std::string &room_path)
{ {
// En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada // En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada
if (file == "0") if (room_path == "0")
{ {
return false; return false;
} }
// Verifica que exista el fichero que se va a cargar // Verifica que exista el fichero que se va a cargar
if (asset_->get(file) != "") if (Asset::get()->get(room_path) != "")
{ {
// Crea un objeto habitación nuevo a partir del fichero // Crea un objeto habitación nuevo a partir del fichero
room_ = std::make_shared<Room>(resource_->getRoom(file), board_); room_ = std::make_shared<Room>(room_path, board_);
// Pone el nombre de la habitación en la textura // Pone el nombre de la habitación en la textura
fillRoomNameTexture(); fillRoomNameTexture();
@@ -349,7 +312,7 @@ bool Game::changeRoom(std::string file)
// Pone el color del marcador en función del color del borde de la habitación // Pone el color del marcador en función del color del borde de la habitación
setScoreBoardColor(); setScoreBoardColor();
if (room_tracker_->addRoom(file)) if (room_tracker_->addRoom(room_path))
{ {
// Incrementa el contador de habitaciones visitadas // Incrementa el contador de habitaciones visitadas
board_->rooms++; board_->rooms++;
@@ -362,6 +325,9 @@ bool Game::changeRoom(std::string file)
// Pasa la nueva habitación al jugador // Pasa la nueva habitación al jugador
player_->setRoom(room_); player_->setRoom(room_);
// Cambia la habitación actual
current_room_ = room_path;
return true; return true;
} }
@@ -377,7 +343,6 @@ void Game::checkPlayerOnBorder()
if (changeRoom(roomName)) if (changeRoom(roomName))
{ {
player_->switchBorders(); player_->switchBorders();
current_room_ = roomName;
spawn_point_ = player_->getSpawnParams(); spawn_point_ = player_->getSpawnParams();
} }
} }
@@ -436,37 +401,21 @@ void Game::killPlayer()
stats_->addDeath(room_->getName()); stats_->addDeath(room_->getName());
// Invalida el logro de pasarse el juego sin morir // Invalida el logro de pasarse el juego sin morir
cheevos_->invalidate(11); Cheevos::get()->setUnobtainable(11);
// Sonido // Sonido
JA_PlaySound(death_sound_); JA_PlaySound(Resource::get()->getSound("death.wav"));
// Pone la pantalla en negro un tiempo // Pone la pantalla en negro un tiempo
setBlackScreen(); setBlackScreen();
// Crea la nueva habitación y el nuevo jugador // Crea la nueva habitación y el nuevo jugador
room_ = std::make_shared<Room>(resource_->getRoom(current_room_), board_); room_ = std::make_shared<Room>(current_room_, board_);
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"; initPlayer(spawn_point_, room_);
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point_, player_texture, player_animations, room_);
player_ = std::make_shared<Player>(player);
// Pone los objetos en pausa mientras esta la habitación en negro // Pone los objetos en pausa mientras esta la habitación en negro
room_->pause(); room_->setPaused(true);
player_->pause(); player_->setPaused(true);
}
// Recarga todas las texturas
void Game::reLoadTextures()
{
if (options.console)
{
std::cout << "** RELOAD REQUESTED" << std::endl;
}
player_->reLoadTexture();
room_->reLoadTexture();
scoreboard_->reLoadTexture();
text_->reLoadTexture();
} }
// Establece la pantalla en negro // Establece la pantalla en negro
@@ -486,9 +435,9 @@ void Game::updateBlackScreen()
black_screen_ = false; black_screen_ = false;
black_screen_counter_ = 0; black_screen_counter_ = 0;
player_->resume(); player_->setPaused(false);
room_->resume(); room_->setPaused(false);
screen_->setBorderColor(room_->getBorderColor()); Screen::get()->setBorderColor(room_->getBorderColor());
} }
} }
} }
@@ -498,8 +447,8 @@ void Game::renderBlackScreen()
{ {
if (black_screen_) if (black_screen_)
{ {
screen_->clean(); Screen::get()->clean();
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
} }
} }
@@ -544,9 +493,9 @@ bool Game::checkEndGame()
int Game::getTotalItems() int Game::getTotalItems()
{ {
int items = 0; int items = 0;
auto rooms = resource_->getRooms(); auto rooms = Resource::get()->getRooms();
for (auto room : rooms) for (const auto &room : rooms)
{ {
items += room.room->items.size(); items += room.room->items.size();
} }
@@ -554,33 +503,14 @@ int Game::getTotalItems()
return items; return items;
} }
// Va a la habitación designada
void Game::goToRoom(int border)
{
const std::string roomName = room_->getRoom(border);
if (changeRoom(roomName))
{
current_room_ = roomName;
}
}
// Pone el juego en pausa // Pone el juego en pausa
void Game::switchPause() void Game::togglePause()
{ {
if (paused_) paused_ = !paused_;
{
player_->resume(); player_->setPaused(paused_);
room_->resume(); room_->setPaused(paused_);
scoreboard_->resume(); scoreboard_->setPaused(paused_);
paused_ = false;
}
else
{
player_->pause();
room_->pause();
scoreboard_->pause();
paused_ = true;
}
} }
// Da vidas al jugador cuando está en la Jail // Da vidas al jugador cuando está en la Jail
@@ -603,13 +533,13 @@ void Game::checkRestoringJail()
{ {
counter = 0; counter = 0;
board_->lives++; board_->lives++;
JA_PlaySound(death_sound_); JA_PlaySound(Resource::get()->getSound("death.wav"));
// Invalida el logro de completar el juego sin entrar a la jail // Invalida el logro de completar el juego sin entrar a la jail
const bool haveTheItems = board_->items >= int(total_items_ * 0.9f); const bool haveTheItems = board_->items >= int(total_items_ * 0.9f);
if (!haveTheItems) if (!haveTheItems)
{ {
cheevos_->invalidate(9); Cheevos::get()->setUnobtainable(9);
} }
} }
} }
@@ -617,9 +547,9 @@ void Game::checkRestoringJail()
// Inicializa el diccionario de las estadísticas // Inicializa el diccionario de las estadísticas
void Game::initStats() void Game::initStats()
{ {
auto rooms = resource_->getRooms(); auto rooms = Resource::get()->getRooms();
for (auto room : rooms) for (const auto &room : rooms)
{ {
stats_->addDictionary(room.room->number, room.room->name); stats_->addDictionary(room.room->number, room.room->name);
} }
@@ -631,86 +561,144 @@ void Game::initStats()
void Game::fillRoomNameTexture() void Game::fillRoomNameTexture()
{ {
// Pone la textura como destino de renderizado // Pone la textura como destino de renderizado
SDL_SetRenderTarget(renderer_, room_name_texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), room_name_texture_);
// Rellena la textura de color // Rellena la textura de color
const Color color = stringToColor(options.video.palette, "white"); const Color color = stringToColor(options.video.palette, "white");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Escribe el texto en la textura // Escribe el texto en la textura
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text_->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor()); auto text = Resource::get()->getText("smb2");
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor());
// Deja el renderizador por defecto // Deja el renderizador por defecto
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
} }
// Comprueba algunos logros // Comprueba algunos logros
void Game::checkSomeCheevos() void Game::checkSomeCheevos()
{ {
auto cheevos = Cheevos::get();
// Logros sobre la cantidad de items // Logros sobre la cantidad de items
if (board_->items == total_items_) if (board_->items == total_items_)
{ {
cheevos_->unlock(4); cheevos->unlock(4);
cheevos_->unlock(3); cheevos->unlock(3);
cheevos_->unlock(2); cheevos->unlock(2);
cheevos_->unlock(1); cheevos->unlock(1);
} }
else if (board_->items >= total_items_ * 0.75f) else if (board_->items >= total_items_ * 0.75f)
{ {
cheevos_->unlock(3); cheevos->unlock(3);
cheevos_->unlock(2); cheevos->unlock(2);
cheevos_->unlock(1); cheevos->unlock(1);
} }
else if (board_->items >= total_items_ * 0.5f) else if (board_->items >= total_items_ * 0.5f)
{ {
cheevos_->unlock(2); cheevos->unlock(2);
cheevos_->unlock(1); cheevos->unlock(1);
} }
else if (board_->items >= total_items_ * 0.25f) else if (board_->items >= total_items_ * 0.25f)
{ {
cheevos_->unlock(1); cheevos->unlock(1);
} }
// Logros sobre las habitaciones visitadas // Logros sobre las habitaciones visitadas
if (board_->rooms >= 60) if (board_->rooms >= 60)
{ {
cheevos_->unlock(7); cheevos->unlock(7);
cheevos_->unlock(6); cheevos->unlock(6);
cheevos_->unlock(5); cheevos->unlock(5);
} }
else if (board_->rooms >= 40) else if (board_->rooms >= 40)
{ {
cheevos_->unlock(6); cheevos->unlock(6);
cheevos_->unlock(5); cheevos->unlock(5);
} }
else if (board_->rooms >= 20) else if (board_->rooms >= 20)
{ {
cheevos_->unlock(5); cheevos->unlock(5);
} }
} }
// Comprueba los logros de completar el juego // Comprueba los logros de completar el juego
void Game::checkEndGameCheevos() void Game::checkEndGameCheevos()
{ {
auto cheevos = Cheevos::get();
// "Complete the game" // "Complete the game"
cheevos_->unlock(8); cheevos->unlock(8);
// "Complete the game without entering the jail" // "Complete the game without entering the jail"
cheevos_->unlock(9); cheevos->unlock(9);
// "Complete the game with all items" // "Complete the game with all items"
if (board_->items == total_items_) if (board_->items == total_items_)
{ {
cheevos_->unlock(10); cheevos->unlock(10);
} }
// "Complete the game without dying" // "Complete the game without dying"
cheevos_->unlock(11); cheevos->unlock(11);
// "Complete the game in under 30 minutes" // "Complete the game in under 30 minutes"
if (scoreboard_->getMinutes() < 30) if (scoreboard_->getMinutes() < 30)
{ {
cheevos_->unlock(12); cheevos->unlock(12);
}
}
// Inicializa al jugador
void Game::initPlayer(const PlayerSpawn &spawn_point, std::shared_ptr<Room> room)
{
std::string player_texture = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png";
std::string player_animations = options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point, player_texture, player_animations, room);
player_ = std::make_shared<Player>(player);
}
// Crea la textura para poner el nombre de la habitación
void Game::createRoomNameTexture()
{
auto text = Resource::get()->getText("smb2");
room_name_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, text->getCharacterSize() * 2);
SDL_SetTextureBlendMode(room_name_texture_, SDL_BLENDMODE_BLEND);
// Establece el destino de la textura
room_name_rect_ = {0, PLAY_AREA_HEIGHT, options.game.width, text->getCharacterSize() * 2};
}
// DEMO MODE: Inicializa las variables para el modo demo
void Game::DEMO_init()
{
if (mode_ == GameMode::DEMO)
{
demo_ = DemoData(0, 400, 0, {"04.room", "54.room", "20.room", "09.room", "05.room", "11.room", "31.room", "44.room"});
current_room_ = demo_.rooms.front();
}
}
// DEMO MODE: Comprueba si se ha de cambiar de habitación
void Game::DEMO_checkRoomChange()
{
if (mode_ == GameMode::DEMO)
{
demo_.counter++;
if (demo_.counter == demo_.room_time)
{
demo_.counter = 0;
demo_.room_index++;
if (demo_.room_index == (int)demo_.rooms.size())
{
options.section.section = Section::LOGO;
options.section.subsection = Subsection::LOGO_TO_TITLE;
}
else
{
changeRoom(demo_.rooms[demo_.room_index]);
}
}
} }
} }

View File

@@ -1,62 +1,65 @@
#pragma once #pragma once
#include <SDL2/SDL_events.h> // Para SDL_Event #include <SDL2/SDL_events.h> // for SDL_Event
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Texture
#include <SDL2/SDL_stdinc.h> // Para Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <string> // Para string, basic_string #include <memory> // for shared_ptr
#include "player.h" // Para playerSpawn_t #include <string> // for string
#include "scoreboard.h" // Para board_t #include <vector> // for vector
#include "room.h" #include "player.h" // for PlayerSpawn
//#include "surface.h" class Room; // lines 10-10
class Asset; class RoomTracker; // lines 11-11
class Cheevos; class Scoreboard; // lines 12-12
class Debug; class Stats; // lines 13-13
class Input; struct ScoreboardData; // lines 14-14
class ItemTracker;
class Resource; enum class GameMode
class Room; {
class RoomTracker; DEMO,
class Screen; GAME
class Stats; };
class Text;
struct JA_Music_t;
struct JA_Sound_t;
struct Options;
struct SectionState;
class Game class Game
{ {
private: private:
// Estructuras
struct DemoData
{
int counter; // Contador para el modo demo
int room_time; // Tiempo que se muestra cada habitación
int room_index; // Índice para el vector de habitaciones
std::vector<std::string> rooms; // Listado con los mapas de la demo
// Constructor por defecto
DemoData()
: counter(0), room_time(0), room_index(0), rooms({}) {}
// Constructor parametrizado
DemoData(int counter, int room_time, int room_index, const std::vector<std::string> &rooms)
: counter(counter), room_time(room_time), room_index(room_index), rooms(rooms) {}
};
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de manejar el renderizador std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
SDL_Renderer *renderer_; // El renderizador de la ventana std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
Input *input_; // Objeto pata gestionar la entrada
Resource *resource_; // Objeto con los recursos
Debug *debug_; // Objeto para gestionar la información de debug
Cheevos *cheevos_; // Objeto encargado de gestionar los logros del juego
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<Player> player_; // Objeto con el jugador std::shared_ptr<Player> player_; // Objeto con el jugador
std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
std::shared_ptr<Text> text_; // Objeto para los textos del juego
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas std::shared_ptr<Stats> stats_; // Objeto encargado de gestionar las estadísticas
SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación
//std::shared_ptr<Surface> test_surface_;
// Variables // Variables
JA_Music_t *music_; // Musica que suena durante el juego GameMode mode_; // Modo del juego
Uint32 ticks_; // Contador de ticks para ajustar la velocidad del programa DemoData demo_; // Variables para el modo demo
std::string current_room_; // Fichero de la habitación actual Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece el jugador std::string current_room_; // Fichero de la habitación actual
JA_Sound_t *death_sound_; // Sonido a reproducir cuando muere el jugador PlayerSpawn spawn_point_; // Lugar de la habitación donde aparece el jugador
std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador bool paused_ = false; // Indica si el juego se encuentra en pausa
bool paused_; // Indica si el juego se encuentra en pausa bool black_screen_ = false; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador
bool black_screen_; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador int black_screen_counter_ = 0; // Contador para temporizar la pantalla en negro
int black_screen_counter_; // Contador para temporizar la pantalla en negro int total_items_; // Cantidad total de items que hay en el mapeado del juego
int total_items_; // Cantidad total de items que hay en el mapeado del juego SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
SDL_Rect room_name_rect_; // Rectangulo donde pintar la textura con el nombre de la habitación
// Actualiza el juego, las variables, comprueba la entrada, etc. // Actualiza el juego, las variables, comprueba la entrada, etc.
void update(); void update();
@@ -73,13 +76,16 @@ private:
// Pone la información de debug en pantalla // Pone la información de debug en pantalla
void renderDebugInfo(); void renderDebugInfo();
// Comprueba los eventos
void checkDebugEvents(const SDL_Event &event);
#endif #endif
// Escribe el nombre de la pantalla // Escribe el nombre de la pantalla
void renderRoomName(); void renderRoomName();
// Cambia de habitación // Cambia de habitación
bool changeRoom(std::string file); bool changeRoom(const std::string &file);
// Comprueba el teclado // Comprueba el teclado
void checkInput(); void checkInput();
@@ -102,9 +108,6 @@ private:
// Mata al jugador // Mata al jugador
void killPlayer(); void killPlayer();
// Recarga todas las texturas
void reLoadTextures();
// Establece la pantalla en negro // Establece la pantalla en negro
void setBlackScreen(); void setBlackScreen();
@@ -123,11 +126,8 @@ private:
// Obtiene la cantidad total de items que hay en el mapeado del juego // Obtiene la cantidad total de items que hay en el mapeado del juego
int getTotalItems(); int getTotalItems();
// Va a la habitación designada
void goToRoom(int border);
// Pone el juego en pausa // Pone el juego en pausa
void switchPause(); void togglePause();
// Da vidas al jugador cuando está en la Jail // Da vidas al jugador cuando está en la Jail
void checkRestoringJail(); void checkRestoringJail();
@@ -144,9 +144,21 @@ private:
// Comprueba los logros de completar el juego // Comprueba los logros de completar el juego
void checkEndGameCheevos(); void checkEndGameCheevos();
// Inicializa al jugador
void initPlayer(const PlayerSpawn &spawn_point, std::shared_ptr<Room> room);
// Crea la textura para poner el nombre de la habitación
void createRoomNameTexture();
// DEMO MODE: Inicializa las variables para el modo demo
void DEMO_init();
// DEMO MODE: Comprueba si se ha de cambiar de habitación
void DEMO_checkRoomChange();
public: public:
// Constructor // Constructor
Game(); Game(GameMode mode);
// Destructor // Destructor
~Game(); ~Game();

View File

@@ -1,51 +1,40 @@
#include "game_over.h" #include "game_over.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <algorithm> // for min, max #include <algorithm> // for min, max
#include <string> // for basic_string, operator+, to_string, cha... #include <string> // for basic_string, operator+, to_string, cha...
#include "animated_sprite.h" // for AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // for Asset #include "defines.h" // for GAMECANVAS_CENTER_X, GAME_SPEED
#include "defines.h" // for GAMECANVAS_CENTER_X #include "global_events.h" // for check
#include "global_events.h" // for check #include "global_inputs.h" // for check
#include "global_inputs.h" // for check #include "jail_audio.h" // for JA_PlayMusic
#include "input.h" // for Input #include "options.h" // for Options, options, OptionsStats, Section...
#include "jail_audio.h" // for JA_PlayMusic #include "resource.h" // for Resource
#include "options.h" // for Options, options, OptionsStats, Section... #include "screen.h" // for Screen
#include "resource.h" // for Resource #include "text.h" // for TEXT_CENTER, TEXT_COLOR, Text
#include "screen.h" // for Screen #include "texture.h" // for Texture
#include "text.h" // for TEXT_CENTER, TEXT_COLOR, Text
#include "texture.h" // for Texture
// Constructor // Constructor
GameOver::GameOver() GameOver::GameOver()
: screen_(Screen::get()), : player_sprite_(std::make_shared<AnimatedSprite>(Resource::get()->getTexture("player_game_over.png"), Resource::get()->getAnimations("player_game_over.ani"))),
renderer_(Screen::get()->getRenderer()), tv_sprite_(std::make_shared<AnimatedSprite>(Resource::get()->getTexture("tv.png"), Resource::get()->getAnimations("tv.ani"))),
resource_(Resource::get()), pre_counter_(0),
asset_(Asset::get()), counter_(0),
input_(Input::get()) ticks_(0)
{ {
// Reserva memoria para los punteros a objetos
text_ = resource_->getText("smb2");
player_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("player_game_over.png"), resource_->getAnimations("player_game_over.ani"));
tv_sprite_ = std::make_shared<AnimatedSprite>(resource_->getTexture("tv.png"), resource_->getAnimations("tv.ani"));
music_ = resource_->getMusic("game_over.ogg");
// Inicializa variables
pre_counter_ = 0;
counter_ = 0;
options.section.section = Section::GAME_OVER; options.section.section = Section::GAME_OVER;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
ticks_ = 0;
player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10); player_sprite_->setPosX(GAMECANVAS_CENTER_X + 10);
player_sprite_->setPosY(30); player_sprite_->setPosY(30);
tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10); tv_sprite_->setPosX(GAMECANVAS_CENTER_X - tv_sprite_->getWidth() - 10);
tv_sprite_->setPosY(30); tv_sprite_->setPosY(30);
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> colorList = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"}; const std::vector<std::string> COLORS = {"white", "yellow", "cyan", "green", "magenta", "red", "blue", "black"};
for (auto cl : colorList) for (const auto &color : COLORS)
{ {
colors_.push_back(stringToColor(options.video.palette, cl)); colors_.push_back(stringToColor(options.video.palette, color));
} }
color_ = colors_.back(); color_ = colors_.back();
} }
@@ -72,7 +61,7 @@ void GameOver::update()
player_sprite_->update(); player_sprite_->update();
tv_sprite_->update(); tv_sprite_->update();
screen_->update(); Screen::get()->update();
} }
} }
@@ -81,11 +70,13 @@ void GameOver::render()
{ {
constexpr int Y = 32; constexpr int Y = 32;
screen_->start(); Screen::get()->start();
screen_->clean(); Screen::get()->clean();
auto text = Resource::get()->getText("smb2");
// Escribe el texto de GAME OVER // Escribe el texto de GAME OVER
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y, "G A M E O V E R", 1, color_); text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y, "G A M E O V E R", 1, color_);
// Dibuja los sprites // Dibuja los sprites
player_sprite_->setPosY(Y + 30); player_sprite_->setPosY(Y + 30);
@@ -95,15 +86,15 @@ void GameOver::render()
// Escribe el texto con las habitaciones y los items // Escribe el texto con las habitaciones y los items
const std::string itemsTxt = std::to_string(options.stats.items / 100) + std::to_string((options.stats.items % 100) / 10) + std::to_string(options.stats.items % 10); const std::string itemsTxt = std::to_string(options.stats.items / 100) + std::to_string((options.stats.items % 100) / 10) + std::to_string(options.stats.items % 10);
const std::string roomsTxt = std::to_string(options.stats.rooms / 100) + std::to_string((options.stats.rooms % 100) / 10) + std::to_string(options.stats.rooms % 10); const std::string roomsTxt = std::to_string(options.stats.rooms / 100) + std::to_string((options.stats.rooms % 100) / 10) + std::to_string(options.stats.rooms % 10);
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 80, "ITEMS: " + itemsTxt, 1, color_); text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 80, "ITEMS: " + itemsTxt, 1, color_);
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 90, "ROOMS: " + roomsTxt, 1, color_); text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 90, "ROOMS: " + roomsTxt, 1, color_);
// Escribe el texto con "Tu peor pesadilla" // Escribe el texto con "Tu peor pesadilla"
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 110, "YOUR WORST NIGHTMARE IS", 1, color_); text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 110, "YOUR WORST NIGHTMARE IS", 1, color_);
text_->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 120, options.stats.worst_nightmare, 1, color_); text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, Y + 120, options.stats.worst_nightmare, 1, color_);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -178,7 +169,7 @@ void GameOver::updateCounters()
// Hace sonar la música // Hace sonar la música
if (counter_ == 1) if (counter_ == 1)
{ {
JA_PlayMusic(music_, 0); JA_PlayMusic(Resource::get()->getMusic("game_over.ogg"), 0);
} }
// Comprueba si ha terminado la sección // Comprueba si ha terminado la sección

View File

@@ -1,17 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <memory> // for shared_ptr
#include <memory> // for shared_ptr #include <vector> // for vector
#include <vector> // for vector #include "utils.h" // for Color
#include "utils.h" // for Color class AnimatedSprite; // lines 8-8
class AnimatedSprite; // lines 9-9
class Asset; // lines 10-10
class Input; // lines 11-11
class Resource; // lines 12-12
class Screen; // lines 13-13
class Text; // lines 14-14
struct JA_Music_t; // lines 15-15
class GameOver class GameOver
{ {
@@ -22,12 +15,6 @@ private:
static constexpr int COUNTER_FADE_LENGHT_ = 20; // Contador: duración del fade static constexpr int COUNTER_FADE_LENGHT_ = 20; // Contador: duración del fade
// Objetos y punteros // 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
Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite con el jugador std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite con el jugador
std::shared_ptr<AnimatedSprite> tv_sprite_; // Sprite con el televisor std::shared_ptr<AnimatedSprite> tv_sprite_; // Sprite con el televisor
@@ -37,7 +24,6 @@ private:
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::vector<Color> colors_; // Vector con los colores para el fade std::vector<Color> colors_; // Vector con los colores para el fade
Color color_; // Color usado para el texto y los sprites Color color_; // Color usado para el texto y los sprites
JA_Music_t *music_; // Musica que suena durante el juego
// Actualiza el objeto // Actualiza el objeto
void update(); void update();

View File

@@ -1,8 +1,6 @@
#include "gif.h" #include "gif.h"
#include <stdio.h> #include <stdio.h> // for NULL, fprintf, stderr
#include <stdlib.h> #include <stdlib.h> // for malloc, realloc, exit, calloc, free
#include <string.h>
#include <fcntl.h>
void uncompress( int code_length, void uncompress( int code_length,
const unsigned char *input, const unsigned char *input,

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h> // for uint32_t
#include <string.h> // for memcpy
#define EXTENSION_INTRODUCER 0x21 #define EXTENSION_INTRODUCER 0x21
#define IMAGE_DESCRIPTOR 0x2C #define IMAGE_DESCRIPTOR 0x2C

View File

@@ -54,29 +54,29 @@ namespace globalInputs
// Comprueba los inputs que se pueden introducir en cualquier sección del juego // Comprueba los inputs que se pueden introducir en cualquier sección del juego
void check() void check()
{ {
if (Input::get()->checkInput(input_exit, REPEAT_FALSE)) if (Input::get()->checkInput(InputAction::EXIT, REPEAT_FALSE))
{ {
quit(); quit();
} }
else if (Input::get()->checkInput(input_accept, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
{ {
skip_section(); skip_section();
} }
else if (Input::get()->checkInput(input_toggle_border, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::TOGGLE_BORDER, REPEAT_FALSE))
{ {
Screen::get()->toggleBorder(); Screen::get()->toggleBorder();
Notifier::get()->show({"BORDER " + std::string(options.video.border.enabled ? "ENABLED" : "DISABLED")}, NotificationText::CENTER); Notifier::get()->show({"BORDER " + std::string(options.video.border.enabled ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
} }
else if (Input::get()->checkInput(input_toggle_videomode, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::TOGGLE_VIDEOMODE, REPEAT_FALSE))
{ {
Screen::get()->toggleVideoMode(); Screen::get()->toggleVideoMode();
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER); Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
} }
else if (Input::get()->checkInput(input_window_dec_size, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::WINDOW_DEC_ZOOM, REPEAT_FALSE))
{ {
if (Screen::get()->decWindowZoom()) if (Screen::get()->decWindowZoom())
{ {
@@ -84,7 +84,7 @@ namespace globalInputs
} }
} }
else if (Input::get()->checkInput(input_window_inc_size, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::WINDOW_INC_ZOOM, REPEAT_FALSE))
{ {
if (Screen::get()->incWindowZoom()) if (Screen::get()->incWindowZoom())
{ {
@@ -92,13 +92,13 @@ namespace globalInputs
} }
} }
else if (Input::get()->checkInput(input_toggle_shaders, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::TOGGLE_SHADERS, REPEAT_FALSE))
{ {
Screen::get()->toggleShaders(); Screen::get()->toggleShaders();
Notifier::get()->show({"SHADERS " + std::string(options.video.shaders ? "ENABLED" : "DISABLED")}, NotificationText::CENTER); Notifier::get()->show({"SHADERS " + std::string(options.video.shaders ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
} }
else if (Input::get()->checkInput(input_toggle_palette, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::TOGGLE_PALETTE, REPEAT_FALSE))
{ {
switchPalette(); switchPalette();
Notifier::get()->show({"PALETTE " + std::string(options.video.palette == Palette::ZXSPECTRUM ? "ZX SPECTRUM" : "ZX ARNE")}, NotificationText::CENTER); Notifier::get()->show({"PALETTE " + std::string(options.video.palette == Palette::ZXSPECTRUM ? "ZX SPECTRUM" : "ZX ARNE")}, NotificationText::CENTER);

View File

@@ -32,40 +32,31 @@ Input::Input(const std::string &game_controller_db_path)
: db_path_(game_controller_db_path) : db_path_(game_controller_db_path)
{ {
// Inicializa las variables // Inicializa las variables
keyBindings_t kb; KeyBindings kb;
kb.scancode = 0; kb.scancode = 0;
kb.active = false; kb.active = false;
key_bindings_.resize(input_number_of_inputs, kb); key_bindings_.resize(static_cast<int>(InputAction::SIZE), kb);
GameControllerBindings_t gcb; GameControllerBindings gcb;
gcb.button = SDL_CONTROLLER_BUTTON_INVALID; gcb.button = SDL_CONTROLLER_BUTTON_INVALID;
gcb.active = false; gcb.active = false;
game_controller_bindings_.resize(input_number_of_inputs, gcb); game_controller_bindings_.resize(static_cast<int>(InputAction::SIZE), gcb);
}
// Actualiza el estado del objeto
void Input::update()
{
if (disabled_until_ == d_keyPressed && !checkAnyInput())
{
enable();
}
} }
// Asigna inputs a teclas // Asigna inputs a teclas
void Input::bindKey(Uint8 input, SDL_Scancode code) void Input::bindKey(InputAction input, SDL_Scancode code)
{ {
key_bindings_[input].scancode = code; key_bindings_.at(static_cast<int>(input)).scancode = code;
} }
// Asigna inputs a botones del mando // Asigna inputs a botones del mando
void Input::bindGameControllerButton(Uint8 input, SDL_GameControllerButton button) void Input::bindGameControllerButton(InputAction input, SDL_GameControllerButton button)
{ {
game_controller_bindings_[input].button = button; game_controller_bindings_.at(static_cast<int>(input)).button = button;
} }
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool Input::checkInput(Uint8 input, bool repeat, int device, int index) bool Input::checkInput(InputAction input, bool repeat, int device, int index)
{ {
if (!enabled_) if (!enabled_)
{ {
@@ -86,7 +77,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
if (repeat) if (repeat)
{ {
if (keyStates[key_bindings_[input].scancode] != 0) if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] != 0)
{ {
successKeyboard = true; successKeyboard = true;
} }
@@ -97,11 +88,11 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (!key_bindings_[input].active) if (!key_bindings_.at(static_cast<int>(input)).active)
{ {
if (keyStates[key_bindings_[input].scancode] != 0) if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] != 0)
{ {
key_bindings_[input].active = true; key_bindings_.at(static_cast<int>(input)).active = true;
successKeyboard = true; successKeyboard = true;
} }
else else
@@ -111,9 +102,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (keyStates[key_bindings_[input].scancode] == 0) if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] == 0)
{ {
key_bindings_[input].active = false; key_bindings_.at(static_cast<int>(input)).active = false;
successKeyboard = false; successKeyboard = false;
} }
else else
@@ -129,7 +120,7 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
{ {
if (repeat) if (repeat)
{ {
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[input].button) != 0) if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) != 0)
{ {
successGameController = true; successGameController = true;
} }
@@ -140,11 +131,11 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (!game_controller_bindings_[input].active) if (!game_controller_bindings_.at(static_cast<int>(input)).active)
{ {
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[input].button) != 0) if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) != 0)
{ {
game_controller_bindings_[input].active = true; game_controller_bindings_.at(static_cast<int>(input)).active = true;
successGameController = true; successGameController = true;
} }
else else
@@ -154,9 +145,9 @@ bool Input::checkInput(Uint8 input, bool repeat, int device, int index)
} }
else else
{ {
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[input].button) == 0) if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) == 0)
{ {
game_controller_bindings_[input].active = false; game_controller_bindings_.at(static_cast<int>(input)).active = false;
successGameController = false; successGameController = false;
} }
else else
@@ -197,7 +188,7 @@ bool Input::checkAnyInput(int device, int index)
{ {
for (int i = 0; i < (int)game_controller_bindings_.size(); ++i) for (int i = 0; i < (int)game_controller_bindings_.size(); ++i)
{ {
if (SDL_GameControllerGetButton(connected_controllers_[index], game_controller_bindings_[i].button) != 0) if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_[i].button) != 0)
{ {
return true; return true;
} }
@@ -316,18 +307,4 @@ int Input::getNumControllers()
void Input::setVerbose(bool value) void Input::setVerbose(bool value)
{ {
verbose_ = value; verbose_ = value;
}
// Deshabilita las entradas durante un periodo de tiempo
void Input::disableUntil(i_disable_e value)
{
disabled_until_ = value;
enabled_ = false;
}
// Hablita las entradas
void Input::enable()
{
enabled_ = true;
disabled_until_ = d_notDisabled;
} }

View File

@@ -15,38 +15,31 @@ constexpr int INPUT_USE_KEYBOARD = 0;
constexpr int INPUT_USE_GAMECONTROLLER = 1; constexpr int INPUT_USE_GAMECONTROLLER = 1;
constexpr int INPUT_USE_ANY = 2; constexpr int INPUT_USE_ANY = 2;
enum inputs_e enum class InputAction
{ {
// Inputs obligatorios // Inputs obligatorios
input_null, NONE,
input_up, UP,
input_down, DOWN,
input_left, LEFT,
input_right, RIGHT,
input_pause, PAUSE,
input_exit, EXIT,
input_accept, ACCEPT,
input_cancel, CANCEL,
// Inputs personalizados // Inputs personalizados
input_jump, JUMP,
input_window_inc_size, WINDOW_INC_ZOOM,
input_window_dec_size, WINDOW_DEC_ZOOM,
input_toggle_videomode, TOGGLE_VIDEOMODE,
input_toggle_border, TOGGLE_BORDER,
input_toggle_music, TOGGLE_MUSIC,
input_toggle_palette, TOGGLE_PALETTE,
input_toggle_shaders, TOGGLE_SHADERS,
// Input obligatorio // Input obligatorio
input_number_of_inputs SIZE
};
enum i_disable_e
{
d_notDisabled,
d_forever,
d_keyPressed
}; };
class Input class Input
@@ -55,13 +48,13 @@ private:
// [SINGLETON] Objeto privado // [SINGLETON] Objeto privado
static Input *input_; static Input *input_;
struct keyBindings_t struct KeyBindings
{ {
Uint8 scancode; // Scancode asociado Uint8 scancode; // Scancode asociado
bool active; // Indica si está activo bool active; // Indica si está activo
}; };
struct GameControllerBindings_t struct GameControllerBindings
{ {
SDL_GameControllerButton button; // GameControllerButton asociado SDL_GameControllerButton button; // GameControllerButton asociado
bool active; // Indica si está activo bool active; // Indica si está activo
@@ -71,14 +64,13 @@ private:
std::vector<SDL_GameController *> connected_controllers_; // Vector con todos los mandos conectados std::vector<SDL_GameController *> connected_controllers_; // Vector con todos los mandos conectados
// Variables // Variables
std::vector<keyBindings_t> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<GameControllerBindings_t> game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos std::vector<GameControllerBindings> game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
int num_gamepads_; // Numero de mandos conectados int num_gamepads_ = 0; // Numero de mandos conectados
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
bool verbose_ = true; // Indica si ha de mostrar mensajes bool verbose_ = true; // Indica si ha de mostrar mensajes
i_disable_e disabled_until_; // Tiempo que esta deshabilitado bool enabled_ = true; // Indica si está habilitado
bool enabled_ = true; // Indica si está habilitado
// Constructor // Constructor
explicit Input(const std::string &game_controller_db_path); explicit Input(const std::string &game_controller_db_path);
@@ -96,17 +88,14 @@ public:
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
static Input *get(); static Input *get();
// Actualiza el estado del objeto
void update();
// Asigna inputs a teclas // Asigna inputs a teclas
void bindKey(Uint8 input, SDL_Scancode code); void bindKey(InputAction input, SDL_Scancode code);
// Asigna inputs a botones del mando // Asigna inputs a botones del mando
void bindGameControllerButton(Uint8 input, SDL_GameControllerButton button); void bindGameControllerButton(InputAction input, SDL_GameControllerButton button);
// Comprueba si un input esta activo // Comprueba si un input esta activo
bool checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0); bool checkInput(InputAction input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0);
// Comprueba si hay almenos un input activo // Comprueba si hay almenos un input activo
bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0); bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0);
@@ -125,10 +114,4 @@ public:
// Establece si ha de mostrar mensajes // Establece si ha de mostrar mensajes
void setVerbose(bool value); void setVerbose(bool value);
// Deshabilita las entradas durante un periodo de tiempo
void disableUntil(i_disable_e value);
// Hablita las entradas
void enable();
}; };

View File

@@ -5,16 +5,12 @@
// Constructor // Constructor
Item::Item(ItemData item) Item::Item(ItemData item)
: sprite_(std::make_shared<Sprite>(Resource::get()->getTexture(item.tile_set_file), item.x, item.y, ITEM_SIZE_, ITEM_SIZE_)),
change_color_speed(4)
{ {
constexpr int ITEMSIZE = 8;
// Crea objetos;
sprite_ = std::make_shared<Sprite>(Resource::get()->getTexture(item.tile_set_file), item.x, item.y, ITEMSIZE, ITEMSIZE);
// Inicia variables // Inicia variables
sprite_->setClip((item.tile % 10) * ITEMSIZE, (item.tile / 10) * ITEMSIZE, ITEMSIZE, ITEMSIZE); sprite_->setClip((item.tile % 10) * ITEM_SIZE_, (item.tile / 10) * ITEM_SIZE_, ITEM_SIZE_, ITEM_SIZE_);
collider_ = sprite_->getRect(); collider_ = sprite_->getRect();
change_color_speed = 4;
counter_ = item.counter * change_color_speed; counter_ = item.counter * change_color_speed;
// Inicializa los colores // Inicializa los colores
@@ -28,8 +24,8 @@ Item::Item(ItemData item)
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void Item::render() void Item::render()
{ {
const int index = (counter_ / change_color_speed) % color_.size(); const int INDEX = (counter_ / change_color_speed) % color_.size();
sprite_->getTexture()->setColor(color_[index].r, color_[index].g, color_[index].b); sprite_->getTexture()->setColor(color_.at(INDEX).r, color_.at(INDEX).g, color_.at(INDEX).b);
sprite_->render(); sprite_->render();
sprite_->getTexture()->setColor(255, 255, 255); sprite_->getTexture()->setColor(255, 255, 255);
} }

View File

@@ -1,23 +1,22 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <memory> // for shared_ptr, __shared_ptr_access
#include <memory> // for shared_ptr, __shared_ptr_access #include <string> // for string
#include <string> // for string #include <vector> // for vector
#include <vector> // for vector #include "sprite.h" // for Sprite
#include "sprite.h" // for Sprite #include "texture.h" // for Texture
#include "texture.h" // for Texture #include "utils.h" // for Color
#include "utils.h" // for Color
struct ItemData struct ItemData
{ {
std::string tile_set_file; // Ruta al fichero con los gráficos del item std::string tile_set_file; // Ruta al fichero con los gráficos del item
int x; // Posición del item en pantalla int x; // Posición del item en pantalla
int y; // Posición del item en pantalla int y; // Posición del item en pantalla
int tile; // Número de tile dentro de la textura int tile; // Número de tile dentro de la textura
int counter; // Contador inicial. Es el que lo hace cambiar de color int counter; // Contador inicial. Es el que lo hace cambiar de color
Color color1; // 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 Color color2; // Uno de los dos colores que se utiliza para el item
// Constructor // Constructor
ItemData() : x(0), y(0), tile(0), counter(0), color1(), color2() {} ItemData() : x(0), y(0), tile(0), counter(0), color1(), color2() {}
@@ -26,6 +25,9 @@ struct ItemData
class Item class Item
{ {
private: private:
// Constantes
static constexpr int ITEM_SIZE_ = 8;
// Objetos y punteros // Objetos y punteros
std::shared_ptr<Sprite> sprite_; // Sprite del objeto std::shared_ptr<Sprite> sprite_; // Sprite del objeto
@@ -37,7 +39,7 @@ private:
public: public:
// Constructor // Constructor
Item(ItemData item); explicit Item(ItemData item);
// Destructor // Destructor
~Item() = default; ~Item() = default;

View File

@@ -57,7 +57,7 @@ void ItemTracker::addItem(const std::string &name, SDL_Point pos)
} }
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int ItemTracker::findByName(std::string name) int ItemTracker::findByName(const std::string &name)
{ {
int i = 0; int i = 0;

View File

@@ -27,7 +27,7 @@ private:
std::vector<ItemTrackerData> item_list_; // Lista con todos los objetos recogidos std::vector<ItemTrackerData> item_list_; // Lista con todos los objetos recogidos
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int findByName(std::string name); int findByName(const std::string &name);
// Busca una entrada en la lista por posición // Busca una entrada en la lista por posición
int findByPos(int index, SDL_Point pos); int findByPos(int index, SDL_Point pos);

View File

@@ -1,12 +1,13 @@
#include "loading_screen.h" #include "loading_screen.h"
#include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <stdlib.h> // for rand #include <stdlib.h> // for rand
#include "asset.h" // for Asset #include <iostream> // for char_traits, basic_ostream, operator<<
#include "defines.h" // for GAMECANVAS_HEIGHT, GAMECANVAS_WIDTH #include "defines.h" // for GAME_SPEED
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input
#include "jail_audio.h" // for JA_PlayMusic, JA_SetVolume, JA_StopMusic #include "jail_audio.h" // for JA_PlayMusic, JA_SetVolume, JA_StopMusic
#include "options.h" // for Options, options, OptionsVideo, Section... #include "options.h" // for Options, options, OptionsVideo, Section...
#include "resource.h" // for Resource #include "resource.h" // for Resource
@@ -14,41 +15,25 @@
#include "sprite.h" // for Sprite #include "sprite.h" // for Sprite
#include "texture.h" // for Texture #include "texture.h" // for Texture
#include "utils.h" // for Color, stringToColor, Palette #include "utils.h" // for Color, stringToColor, Palette
#include <iostream>
// Constructor // Constructor
LoadingScreen::LoadingScreen() LoadingScreen::LoadingScreen()
: screen_(Screen::get()),
renderer_(Screen::get()->getRenderer()),
resource_(Resource::get()),
asset_(Asset::get()),
input_(Input::get())
{ {
// Reserva memoria para los punteros // Reserva memoria para los punteros
if (options.video.palette == Palette::ZXSPECTRUM) if (options.video.palette == Palette::ZXSPECTRUM)
{ {
mono_loading_screen_texture_ = resource_->getTexture("loading_screen_bn.png"); mono_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_bn.png");
color_loading_screen_texture_ = resource_->getTexture("loading_screen_color.png"); color_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_color.png");
} }
else if (options.video.palette == Palette::ZXARNE) else if (options.video.palette == Palette::ZXARNE)
{ {
mono_loading_screen_texture_ = resource_->getTexture("loading_screen_bn_zxarne.png"); mono_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_bn_zxarne.png");
color_loading_screen_texture_ = resource_->getTexture("loading_screen_color_zxarne.png"); color_loading_screen_texture_ = Resource::get()->getTexture("loading_screen_color_zxarne.png");
} }
mono_loading_screen_sprite_ = std::make_shared<Sprite>(mono_loading_screen_texture_, 0, 0, mono_loading_screen_texture_->getWidth(), mono_loading_screen_texture_->getHeight()); mono_loading_screen_sprite_ = std::make_shared<Sprite>(mono_loading_screen_texture_, 0, 0, mono_loading_screen_texture_->getWidth(), mono_loading_screen_texture_->getHeight());
color_loading_screen_sprite_ = std::make_shared<Sprite>(color_loading_screen_texture_, 0, 0, color_loading_screen_texture_->getWidth(), color_loading_screen_texture_->getHeight()); color_loading_screen_sprite_ = std::make_shared<Sprite>(color_loading_screen_texture_, 0, 0, color_loading_screen_texture_->getWidth(), color_loading_screen_texture_->getHeight());
loading_sound1_ = resource_->getMusic("loading_sound1.ogg");
loading_sound2_ = resource_->getMusic("loading_sound2.ogg");
loading_sound3_ = resource_->getMusic("loading_sound3.ogg");
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height); texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height);
if (texture_ == nullptr)
{
if (options.console)
{
std::cout << "LoadingScreen::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
clearTexture(); clearTexture();
// Inicializa variables // Inicializa variables
@@ -62,20 +47,18 @@ LoadingScreen::LoadingScreen()
{ // Primer bloque de 2K { // Primer bloque de 2K
line_index_[i] = ((i % 8) * 8) + (i / 8); line_index_[i] = ((i % 8) * 8) + (i / 8);
} }
else if (i < 128)
else if (i >= 64 && i < 128)
{ // Segundo bloque de 2K { // Segundo bloque de 2K
line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8); line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8);
} }
else
else if (i >= 128 && i < 192) { // Tercer bloque de 2K
{ // tercer bloque de 2K
line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8); line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8);
} }
} }
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
} }
// Destructor // Destructor
@@ -127,7 +110,7 @@ void LoadingScreen::updateLoad()
load_rect_ = {0, 0, 16, 8}; load_rect_ = {0, 0, 16, 8};
color_loading_screen_sprite_->setClip(load_rect_); color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_); color_loading_screen_sprite_->setPosition(load_rect_);
JA_PlayMusic(loading_sound3_); JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg"));
} }
} }
// Segunda parte de la carga, la parte de los bloques en color // Segunda parte de la carga, la parte de los bloques en color
@@ -156,7 +139,7 @@ void LoadingScreen::updateCounter()
if (counter_ == 1) if (counter_ == 1)
{ {
JA_PlayMusic(loading_sound2_); JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg"));
} }
} }
@@ -169,30 +152,32 @@ void LoadingScreen::renderLoad()
// Dibuja el efecto de carga en el borde // Dibuja el efecto de carga en el borde
void LoadingScreen::renderBorder() void LoadingScreen::renderBorder()
{ {
// Pinta el borde de colro azul // Pinta el borde de colro azul
Color color = stringToColor(options.video.palette, "blue"); Color color = stringToColor(options.video.palette, "blue");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Añade lineas amarillas // Añade lineas amarillas
color = stringToColor(options.video.palette, "yellow"); color = stringToColor(options.video.palette, "yellow");
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
const int width = options.game.width + (options.video.border.width * 2); const int WIDTH = options.game.width + (options.video.border.width * 2);
const int height = options.game.height + (options.video.border.height * 2); const int HEIGHT = options.game.height + (options.video.border.height * 2);
bool drawEnabled = rand() % 2 == 0 ? true : false; bool drawEnabled = rand() % 2 == 0 ? true : false;
int row = 0;
int rowSize = 1; int row = 0;
while (row < height) while (row < HEIGHT)
{ {
rowSize = (rand() % 4) + 3; const int ROW_HEIGHT = (rand() % 4) + 3;
if (drawEnabled) if (drawEnabled)
for (int i = row; i < row + rowSize; ++i) {
{ for (int i = row; i < row + ROW_HEIGHT; ++i)
SDL_RenderDrawLine(renderer_, 0, i, width, i); {
} SDL_RenderDrawLine(Screen::get()->getRenderer(), 0, i, WIDTH, i);
row += rowSize; }
drawEnabled = !drawEnabled; }
} row += ROW_HEIGHT;
drawEnabled = !drawEnabled;
}
} }
// Actualiza las variables // Actualiza las variables
@@ -206,7 +191,7 @@ void LoadingScreen::update()
updateCounter(); updateCounter();
updateLoad(); updateLoad();
fillTexture(); fillTexture();
screen_->update(); Screen::get()->update();
} }
} }
@@ -216,20 +201,20 @@ void LoadingScreen::render()
if (options.video.border.enabled) if (options.video.border.enabled)
{ {
// Prepara para empezar a dibujar en la textura del borde // Prepara para empezar a dibujar en la textura del borde
screen_->startDrawOnBorder(); Screen::get()->startDrawOnBorder();
// Dibuja el efecto de carga en el borde // Dibuja el efecto de carga en el borde
renderBorder(); renderBorder();
} }
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); Screen::get()->start();
// Copila la textura a la pantalla // Copila la textura a la pantalla
SDL_RenderCopy(renderer_, texture_, nullptr, nullptr); SDL_RenderCopy(Screen::get()->getRenderer(), texture_, nullptr, nullptr);
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Bucle para el logo del juego // Bucle para el logo del juego
@@ -237,12 +222,12 @@ void LoadingScreen::run()
{ {
// Inicia el sonido de carga // Inicia el sonido de carga
JA_SetVolume(64); JA_SetVolume(64);
JA_PlayMusic(loading_sound1_); JA_PlayMusic(Resource::get()->getMusic("loading_sound1.ogg"));
// Limpia la pantalla // Limpia la pantalla
screen_->start(); Screen::get()->start();
screen_->clean(); Screen::get()->clean();
screen_->render(); Screen::get()->render();
while (options.section.section == Section::LOADING_SCREEN) while (options.section.section == Section::LOADING_SCREEN)
{ {
@@ -254,70 +239,31 @@ void LoadingScreen::run()
JA_SetVolume(128); JA_SetVolume(128);
} }
// Reconstruye la pantalla de carga
void LoadingScreen::recreateLoadingScreen()
{
// Prepara para empezar a dibujar en la textura de juego
screen_->start();
// Primera parte de la carga, la parte en blanco y negro
if (loading_first_part_)
{
const int numSteps = 5;
const int step = 51;
for (int i = 0; i <= counter_; i++)
{
load_counter_ = i / numSteps;
load_rect_.x = step * (i % numSteps);
load_rect_.y = line_index_[load_counter_];
mono_loading_screen_sprite_->setClip(load_rect_);
mono_loading_screen_sprite_->setPosition(load_rect_);
mono_loading_screen_sprite_->render();
}
}
// Segunda parte de la carga, la parte de los bloques en color
else
{
for (int i = 0; i <= load_counter_; i++)
{
load_rect_.x = (i * 8) % 256;
load_rect_.y = (i / 32) * 8;
color_loading_screen_sprite_->setClip(load_rect_);
color_loading_screen_sprite_->setPosition(load_rect_);
color_loading_screen_sprite_->render();
}
}
// Vuelca el contenido del renderizador en pantalla
screen_->render();
}
// Dibuja sobre la textura // Dibuja sobre la textura
void LoadingScreen::fillTexture() void LoadingScreen::fillTexture()
{ {
// Empieza a dibujar en la textura // Empieza a dibujar en la textura
auto temp = SDL_GetRenderTarget(renderer_); auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
SDL_SetRenderTarget(renderer_, texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), texture_);
// Dibuja la pantalla de carga // Dibuja la pantalla de carga
renderLoad(); renderLoad();
// Deja el renderizador como estaba // Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp); SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
} }
// Limpia la textura // Limpia la textura
void LoadingScreen::clearTexture() void LoadingScreen::clearTexture()
{ {
// Empieza a dibujar en la textura // Empieza a dibujar en la textura
auto temp = SDL_GetRenderTarget(renderer_); auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
SDL_SetRenderTarget(renderer_, texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), texture_);
// Limpia // Limpia
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Deja el renderizador como estaba // Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp); SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
} }

View File

@@ -1,26 +1,16 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
class Asset; // lines 8-8 class Sprite; // lines 11-11
class Input; // lines 9-9 class Texture; // lines 12-12
class Resource; // lines 10-10
class Screen; // lines 11-11
class Sprite; // lines 12-12
class Texture; // lines 13-13
struct JA_Music_t; // lines 14-14
class LoadingScreen class LoadingScreen
{ {
private: private:
// Objetos y punteros // 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
Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Texture> mono_loading_screen_texture_; // Textura con la pantalla de carga en blanco y negro std::shared_ptr<Texture> mono_loading_screen_texture_; // Textura con la pantalla de carga en blanco y negro
std::shared_ptr<Texture> color_loading_screen_texture_; // Textura con la pantalla de carga en color std::shared_ptr<Texture> color_loading_screen_texture_; // Textura con la pantalla de carga en color
std::shared_ptr<Sprite> mono_loading_screen_sprite_; // Sprite para manejar la textura loadingScreenTexture1 std::shared_ptr<Sprite> mono_loading_screen_sprite_; // Sprite para manejar la textura loadingScreenTexture1
@@ -32,9 +22,6 @@ private:
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
int load_counter_ = 0; // Contador para controlar las cargas int load_counter_ = 0; // Contador para controlar las cargas
bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra
JA_Music_t *loading_sound1_; // Sonidos para imitar la carga tipo spectrum
JA_Music_t *loading_sound2_; // Sonidos para imitar la carga tipo spectrum
JA_Music_t *loading_sound3_; // Sonidos para imitar la carga tipo spectrum
int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga
SDL_Rect load_rect_ = {0, 0, 51, 1}; // Rectangulo para dibujar la pantalla de carga SDL_Rect load_rect_ = {0, 0, 51, 1}; // Rectangulo para dibujar la pantalla de carga
SDL_Texture *texture_; // Textura para dibujar la pantalla de carga SDL_Texture *texture_; // Textura para dibujar la pantalla de carga
@@ -63,9 +50,6 @@ private:
// Dibuja el efecto de carga en el borde // Dibuja el efecto de carga en el borde
void renderBorder(); void renderBorder();
// Reconstruye la pantalla de carga
void recreateLoadingScreen();
// Dibuja sobre la textura // Dibuja sobre la textura
void fillTexture(); void fillTexture();

View File

@@ -1,32 +1,24 @@
#include "logo.h" #include "logo.h"
#include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include <string> // for basic_string, string #include <string> // for basic_string, string
#include "asset.h" // for Asset #include "defines.h" // for GAME_SPEED
#include "global_events.h" // for check #include "global_events.h" // for check
#include "global_inputs.h" // for check #include "global_inputs.h" // for check
#include "input.h" // for Input #include "jail_audio.h" // for JA_StopMusic
#include "jail_audio.h" // for JA_StopMusic #include "options.h" // for Options, options, SectionState, Section
#include "options.h" // for Options, options, SectionState, Section #include "resource.h" // for Resource
#include "resource.h" // for Resource #include "screen.h" // for Screen
#include "screen.h" // for Screen #include "sprite.h" // for Sprite
#include "sprite.h" // for Sprite #include "texture.h" // for Texture
#include "texture.h" // for Texture #include "utils.h" // for Color, stringToColor
#include "utils.h" // for Color, stringToColor
#include "defines.h"
// Constructor // Constructor
Logo::Logo() Logo::Logo()
: screen_(Screen::get()), : jailgames_texture_(Resource::get()->getTexture("jailgames.png")),
renderer_(Screen::get()->getRenderer()), since_1998_texture_(Resource::get()->getTexture("since_1998.png")),
resource_(Resource::get()), since_1998_sprite_(std::make_shared<Sprite>(since_1998_texture_, (256 - since_1998_texture_->getWidth()) / 2, 83 + jailgames_texture_->getHeight() + 5, since_1998_texture_->getWidth(), since_1998_texture_->getHeight()))
asset_(Asset::get()),
input_(Input::get())
{ {
// Reserva memoria para los punteros
jailgames_texture_ = resource_->getTexture("jailgames.png");
since_1998_texture_ = resource_->getTexture("since_1998.png");
since_1998_sprite_ = std::make_shared<Sprite>(since_1998_texture_, (256 - since_1998_texture_->getWidth()) / 2, 83 + jailgames_texture_->getHeight() + 5, since_1998_texture_->getWidth(), since_1998_texture_->getHeight());
since_1998_sprite_->setClip(0, 0, since_1998_texture_->getWidth(), since_1998_texture_->getHeight()); since_1998_sprite_->setClip(0, 0, since_1998_texture_->getWidth(), since_1998_texture_->getHeight());
since_1998_texture_->setColor(0, 0, 0); since_1998_texture_->setColor(0, 0, 0);
@@ -35,29 +27,22 @@ Logo::Logo()
{ {
jailgames_sprite_.push_back(std::make_shared<Sprite>(jailgames_texture_, 0, i, jailgames_texture_->getWidth(), 1)); jailgames_sprite_.push_back(std::make_shared<Sprite>(jailgames_texture_, 0, i, jailgames_texture_->getWidth(), 1));
jailgames_sprite_.back()->setClip(0, i, jailgames_texture_->getWidth(), 1); jailgames_sprite_.back()->setClip(0, i, jailgames_texture_->getWidth(), 1);
if (i % 2 == 0) jailgames_sprite_.at(i)->setX((i % 2 == 0) ? (256 + (i * 3)) : (-181 - (i * 3)));
{ jailgames_sprite_.at(i)->setY(83 + i);
jailgames_sprite_[i]->setX(256 + (i * 3));
}
else
{
jailgames_sprite_[i]->setX(-181 - (i * 3));
}
jailgames_sprite_[i]->setY(83 + i);
} }
// Inicializa variables // Inicializa variables
options.section.section = Section::LOGO; options.section.section = Section::LOGO;
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> vColors = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"}; const std::vector<std::string> COLORS = {"black", "blue", "red", "magenta", "green", "cyan", "yellow", "bright_white"};
for (auto v : vColors) for (const auto &color : COLORS)
{ {
color_.push_back(stringToColor(options.video.palette, v)); color_.push_back(stringToColor(options.video.palette, color));
} }
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
} }
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
@@ -83,24 +68,24 @@ void Logo::updateJAILGAMES()
{ {
for (int i = 1; i < (int)jailgames_sprite_.size(); ++i) for (int i = 1; i < (int)jailgames_sprite_.size(); ++i)
{ {
const int speed = 8; constexpr int SPEED = 8;
const int dest = 37; constexpr int DEST = 37;
if (jailgames_sprite_[i]->getX() != 37) if (jailgames_sprite_.at(i)->getX() != 37)
{ {
if (i % 2 == 0) if (i % 2 == 0)
{ {
jailgames_sprite_[i]->incX(-speed); jailgames_sprite_.at(i)->incX(-SPEED);
if (jailgames_sprite_[i]->getX() < dest) if (jailgames_sprite_.at(i)->getX() < DEST)
{ {
jailgames_sprite_[i]->setX(dest); jailgames_sprite_.at(i)->setX(DEST);
} }
} }
else else
{ {
jailgames_sprite_[i]->incX(speed); jailgames_sprite_.at(i)->incX(SPEED);
if (jailgames_sprite_[i]->getX() > dest) if (jailgames_sprite_.at(i)->getX() > DEST)
{ {
jailgames_sprite_[i]->setX(dest); jailgames_sprite_.at(i)->setX(DEST);
} }
} }
} }
@@ -111,89 +96,89 @@ void Logo::updateJAILGAMES()
// Gestiona el color de las texturas // Gestiona el color de las texturas
void Logo::updateTextureColors() void Logo::updateTextureColors()
{ {
const int ini = 70; constexpr int INI = 70;
const int inc = 4; constexpr int INC = 4;
if (counter_ == ini + inc * 0) if (counter_ == INI + INC * 0)
{ {
since_1998_texture_->setColor(color_[0].r, color_[0].g, color_[0].b); since_1998_texture_->setColor(color_.at(0).r, color_.at(0).g, color_.at(0).b);
} }
else if (counter_ == ini + inc * 1) else if (counter_ == INI + INC * 1)
{ {
since_1998_texture_->setColor(color_[1].r, color_[1].g, color_[1].b); since_1998_texture_->setColor(color_.at(1).r, color_.at(1).g, color_.at(1).b);
} }
else if (counter_ == ini + inc * 2) else if (counter_ == INI + INC * 2)
{ {
since_1998_texture_->setColor(color_[2].r, color_[2].g, color_[2].b); since_1998_texture_->setColor(color_.at(2).r, color_.at(2).g, color_.at(2).b);
} }
else if (counter_ == ini + inc * 3) else if (counter_ == INI + INC * 3)
{ {
since_1998_texture_->setColor(color_[3].r, color_[3].g, color_[3].b); since_1998_texture_->setColor(color_.at(3).r, color_.at(3).g, color_.at(3).b);
} }
else if (counter_ == ini + inc * 4) else if (counter_ == INI + INC * 4)
{ {
since_1998_texture_->setColor(color_[4].r, color_[4].g, color_[4].b); since_1998_texture_->setColor(color_.at(4).r, color_.at(4).g, color_.at(4).b);
} }
else if (counter_ == ini + inc * 5) else if (counter_ == INI + INC * 5)
{ {
since_1998_texture_->setColor(color_[5].r, color_[5].g, color_[5].b); since_1998_texture_->setColor(color_.at(5).r, color_.at(5).g, color_.at(5).b);
} }
else if (counter_ == ini + inc * 6) else if (counter_ == INI + INC * 6)
{ {
since_1998_texture_->setColor(color_[6].r, color_[6].g, color_[6].b); since_1998_texture_->setColor(color_.at(6).r, color_.at(6).g, color_.at(6).b);
} }
else if (counter_ == ini + inc * 7) else if (counter_ == INI + INC * 7)
{ {
since_1998_texture_->setColor(color_[7].r, color_[7].g, color_[7].b); since_1998_texture_->setColor(color_.at(7).r, color_.at(7).g, color_.at(7).b);
} }
else if (counter_ == INIT_FADE_ + inc * 0) else if (counter_ == INIT_FADE_ + INC * 0)
{ {
jailgames_texture_->setColor(color_[6].r, color_[6].g, color_[6].b); jailgames_texture_->setColor(color_.at(6).r, color_.at(6).g, color_.at(6).b);
since_1998_texture_->setColor(color_[6].r, color_[6].g, color_[6].b); since_1998_texture_->setColor(color_.at(6).r, color_.at(6).g, color_.at(6).b);
} }
else if (counter_ == INIT_FADE_ + inc * 1) else if (counter_ == INIT_FADE_ + INC * 1)
{ {
jailgames_texture_->setColor(color_[5].r, color_[5].g, color_[5].b); jailgames_texture_->setColor(color_.at(5).r, color_.at(5).g, color_.at(5).b);
since_1998_texture_->setColor(color_[5].r, color_[5].g, color_[5].b); since_1998_texture_->setColor(color_.at(5).r, color_.at(5).g, color_.at(5).b);
} }
else if (counter_ == INIT_FADE_ + inc * 2) else if (counter_ == INIT_FADE_ + INC * 2)
{ {
jailgames_texture_->setColor(color_[4].r, color_[4].g, color_[4].b); jailgames_texture_->setColor(color_.at(4).r, color_.at(4).g, color_.at(4).b);
since_1998_texture_->setColor(color_[4].r, color_[4].g, color_[4].b); since_1998_texture_->setColor(color_.at(4).r, color_.at(4).g, color_.at(4).b);
} }
else if (counter_ == INIT_FADE_ + inc * 3) else if (counter_ == INIT_FADE_ + INC * 3)
{ {
jailgames_texture_->setColor(color_[3].r, color_[3].g, color_[3].b); jailgames_texture_->setColor(color_.at(3).r, color_.at(3).g, color_.at(3).b);
since_1998_texture_->setColor(color_[3].r, color_[3].g, color_[3].b); since_1998_texture_->setColor(color_.at(3).r, color_.at(3).g, color_.at(3).b);
} }
else if (counter_ == INIT_FADE_ + inc * 4) else if (counter_ == INIT_FADE_ + INC * 4)
{ {
jailgames_texture_->setColor(color_[2].r, color_[2].g, color_[2].b); jailgames_texture_->setColor(color_.at(2).r, color_.at(2).g, color_.at(2).b);
since_1998_texture_->setColor(color_[2].r, color_[2].g, color_[2].b); since_1998_texture_->setColor(color_.at(2).r, color_.at(2).g, color_.at(2).b);
} }
else if (counter_ == INIT_FADE_ + inc * 5) else if (counter_ == INIT_FADE_ + INC * 5)
{ {
jailgames_texture_->setColor(color_[1].r, color_[1].g, color_[1].b); jailgames_texture_->setColor(color_.at(1).r, color_.at(1).g, color_.at(1).b);
since_1998_texture_->setColor(color_[1].r, color_[1].g, color_[1].b); since_1998_texture_->setColor(color_.at(1).r, color_.at(1).g, color_.at(1).b);
} }
else if (counter_ == INIT_FADE_ + inc * 6) else if (counter_ == INIT_FADE_ + INC * 6)
{ {
jailgames_texture_->setColor(color_[0].r, color_[0].g, color_[0].b); jailgames_texture_->setColor(color_.at(0).r, color_.at(0).g, color_.at(0).b);
since_1998_texture_->setColor(color_[0].r, color_[0].g, color_[0].b); since_1998_texture_->setColor(color_.at(0).r, color_.at(0).g, color_.at(0).b);
} }
} }
@@ -218,7 +203,7 @@ void Logo::update()
// Gestiona el color de las texturas // Gestiona el color de las texturas
updateTextureColors(); updateTextureColors();
screen_->update(); Screen::get()->update();
// Comprueba si ha terminado el logo // Comprueba si ha terminado el logo
if (counter_ == END_LOGO_ + POST_LOGO_) if (counter_ == END_LOGO_ + POST_LOGO_)
@@ -232,20 +217,20 @@ void Logo::update()
void Logo::render() void Logo::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); Screen::get()->start();
// Limpia la pantalla // Limpia la pantalla
screen_->clean(); Screen::get()->clean();
// Dibuja los objetos // Dibuja los objetos
for (auto s : jailgames_sprite_) for (const auto &s : jailgames_sprite_)
{ {
s->render(); s->render();
} }
since_1998_sprite_->render(); since_1998_sprite_->render();
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Bucle para el logo del juego // Bucle para el logo del juego

View File

@@ -1,16 +1,11 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // for SDL_Renderer #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <memory> // for shared_ptr
#include <memory> // for shared_ptr #include <vector> // for vector
#include <vector> // for vector #include "utils.h" // for Color
#include "utils.h" // for Color class Sprite; // lines 12-12
class Asset; // lines 8-8 class Texture; // lines 13-13
class Input; // lines 9-9
class Resource; // lines 10-10
class Screen; // lines 11-11
class Sprite; // lines 12-12
class Texture; // lines 13-13
class Logo class Logo
{ {
@@ -21,11 +16,6 @@ private:
static constexpr int POST_LOGO_ = 20; // Tiempo que dura el logo con el fade al maximo static constexpr int POST_LOGO_ = 20; // Tiempo que dura el logo con el fade al maximo
// Objetos y punteros // 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
Asset *asset_; // Objeto con los ficheros de recursos
Input *input_; // Objeto pata gestionar la entrada
std::shared_ptr<Texture> jailgames_texture_; // Textura con los graficos "JAILGAMES" std::shared_ptr<Texture> jailgames_texture_; // Textura con los graficos "JAILGAMES"
std::shared_ptr<Texture> since_1998_texture_; // Textura con los graficos "Since 1998" std::shared_ptr<Texture> since_1998_texture_; // Textura con los graficos "Since 1998"
std::vector<std::shared_ptr<Sprite>> jailgames_sprite_; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES std::vector<std::shared_ptr<Sprite>> jailgames_sprite_; // Vector con los sprites de cada linea que forman el bitmap JAILGAMES

View File

@@ -1,5 +1,5 @@
#include "moving_sprite.h" #include "moving_sprite.h"
#include "texture.h" // for Texture #include "texture.h" // for Texture
// Constructor // Constructor
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos, Rotate rotate, float zoom_w, float zoom_h, SDL_RendererFlip flip) MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos, Rotate rotate, float zoom_w, float zoom_h, SDL_RendererFlip flip)
@@ -9,7 +9,7 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos, Rotat
rotate_(rotate), rotate_(rotate),
zoom_w_(zoom_w), zoom_w_(zoom_w),
zoom_h_(zoom_h), zoom_h_(zoom_h),
flip_(flip) {} flip_(flip) { Sprite::pos_ = pos; }
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos) MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos)
: Sprite(texture, pos), : Sprite(texture, pos),
@@ -18,7 +18,7 @@ MovingSprite::MovingSprite(std::shared_ptr<Texture> texture, SDL_Rect pos)
rotate_(Rotate()), rotate_(Rotate()),
zoom_w_(1.0f), zoom_w_(1.0f),
zoom_h_(1.0f), zoom_h_(1.0f),
flip_(SDL_FLIP_NONE) {} flip_(SDL_FLIP_NONE) { Sprite::pos_ = pos; }
MovingSprite::MovingSprite(std::shared_ptr<Texture> texture) MovingSprite::MovingSprite(std::shared_ptr<Texture> texture)
: Sprite(texture), : Sprite(texture),

View File

@@ -1,16 +1,17 @@
#include "notifier.h" #include "notifier.h"
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <string> // Para string #include <SDL2/SDL_render.h> // for SDL_RenderFillRect, SDL_RenderClear
#include <algorithm> #include <algorithm> // for remove_if
#include <vector> #include <string> // for string, basic_string
#include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla... #include <vector> // for vector
#include "screen.h" // Para Screen #include "jail_audio.h" // for JA_PlaySound
#include "sprite.h" // Para Sprite #include "options.h" // for Options, options, OptionsNotification
#include "text.h" // Para Text #include "resource.h" // for Resource
#include "texture.h" // Para Texture #include "screen.h" // for Screen
#include "resource.h" #include "sprite.h" // for Sprite
#include "options.h" #include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR
#include "texture.h" // for Texture
// [SINGLETON] // [SINGLETON]
Notifier *Notifier::notifier_ = nullptr; Notifier *Notifier::notifier_ = nullptr;
@@ -35,8 +36,7 @@ Notifier *Notifier::get()
// Constructor // Constructor
Notifier::Notifier(const std::string &icon_file, const std::string &text) Notifier::Notifier(const std::string &icon_file, const std::string &text)
: renderer_(Screen::get()->getRenderer()), : icon_texture_(!icon_file.empty() ? Resource::get()->getTexture(icon_file) : nullptr),
icon_texture_(!icon_file.empty() ? Resource::get()->getTexture(icon_file) : nullptr),
text_(Resource::get()->getText(text)), text_(Resource::get()->getText(text)),
bg_color_(options.notifications.color), bg_color_(options.notifications.color),
wait_time_(150), wait_time_(150),
@@ -84,8 +84,8 @@ void Notifier::update()
// Comprueba los estados // Comprueba los estados
if (notifications_[i].state == NotificationStatus::RISING) if (notifications_[i].state == NotificationStatus::RISING)
{ {
//const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist); // const float step = ((float)notifications_[i].counter / notifications_[i].travel_dist);
//const int alpha = 255 * step; // const int alpha = 255 * step;
constexpr int ALPHA = 255; constexpr int ALPHA = 255;
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP) if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
@@ -117,11 +117,10 @@ void Notifier::update()
else if (notifications_[i].state == NotificationStatus::VANISHING) else if (notifications_[i].state == NotificationStatus::VANISHING)
{ {
//const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist); // const float step = (notifications_[i].counter / (float)notifications_[i].travel_dist);
//const int ALPHA = 255 * (1 - step); // const int ALPHA = 255 * (1 - step);
constexpr int ALPHA = 255; constexpr int ALPHA = 255;
if (options.notifications.getVerticalPosition() == NotificationPosition::TOP) if (options.notifications.getVerticalPosition() == NotificationPosition::TOP)
{ {
notifications_[i].rect.y--; notifications_[i].rect.y--;
@@ -235,34 +234,34 @@ void Notifier::show(std::vector<std::string> texts, NotificationText text_is, in
n.rect = {desp_h, y_pos, width, height}; n.rect = {desp_h, y_pos, width, height};
// Crea la textura // Crea la textura
n.texture = std::make_shared<Texture>(renderer_); n.texture = std::make_shared<Texture>(Screen::get()->getRenderer());
n.texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET); n.texture->createBlank(width, height, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
n.texture->setBlendMode(SDL_BLENDMODE_BLEND); n.texture->setBlendMode(SDL_BLENDMODE_BLEND);
// Prepara para dibujar en la textura // Prepara para dibujar en la textura
n.texture->setAsRenderTarget(renderer_); n.texture->setAsRenderTarget(Screen::get()->getRenderer());
// Dibuja el fondo de la notificación // Dibuja el fondo de la notificación
SDL_SetRenderDrawColor(renderer_, bg_color_.r, bg_color_.g, bg_color_.b, 255); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), bg_color_.r, bg_color_.g, bg_color_.b, 255);
SDL_Rect rect; SDL_Rect rect;
if (shape == NotificationShape::ROUNDED) if (shape == NotificationShape::ROUNDED)
{ {
rect = {4, 0, width - (4 * 2), height}; rect = {4, 0, width - (4 * 2), height};
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
rect = {4 / 2, 1, width - 4, height - 2}; rect = {4 / 2, 1, width - 4, height - 2};
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
rect = {1, 4 / 2, width - 2, height - 4}; rect = {1, 4 / 2, width - 2, height - 4};
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
rect = {0, 4, width, height - (4 * 2)}; rect = {0, 4, width, height - (4 * 2)};
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect);
} }
else if (shape == NotificationShape::SQUARED) else if (shape == NotificationShape::SQUARED)
{ {
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
} }
// Dibuja el icono de la notificación // Dibuja el icono de la notificación
@@ -291,7 +290,7 @@ void Notifier::show(std::vector<std::string> texts, NotificationText text_is, in
} }
// Deja de dibujar en la textura // Deja de dibujar en la textura
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
// Crea el sprite de la notificación // Crea el sprite de la notificación
n.sprite = std::make_shared<Sprite>(n.texture, n.rect); n.sprite = std::make_shared<Sprite>(n.texture, n.rect);

View File

@@ -1,14 +1,13 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <memory> // for shared_ptr
#include <memory> // Para shared_ptr #include <string> // for string, basic_string
#include <string> // Para string, basic_string #include <vector> // for vector
#include <vector> // Para vector #include "utils.h" // for Color
#include "utils.h" // Para Color class Sprite; // lines 9-9
class Sprite; // lines 9-9 class Text; // lines 10-10
class Text; // lines 10-10 class Texture; // lines 11-11
class Texture; // lines 11-11
enum class NotificationText enum class NotificationText
{ {
@@ -62,9 +61,6 @@ private:
can_be_removed(true), height(0) {} can_be_removed(true), height(0) {}
}; };
// Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
std::shared_ptr<Text> text_; // Objeto para dibujar texto std::shared_ptr<Text> text_; // Objeto para dibujar texto

View File

@@ -1,13 +1,14 @@
#include "options.h" #include "options.h"
#include <SDL2/SDL_video.h> // for SDL_WINDOW_FULLSCREEN, SDL_WINDOW_FULLSC... #include <SDL2/SDL_video.h> // for SDL_WINDOW_FULLSCREEN_DESKTOP
#include <fstream> // for basic_ostream, operator<<, basic_ofstream #include <algorithm> // for find_if
#include <functional> // for function #include <cctype> // for isspace
#include <iostream> // for cout, cerr #include <fstream> // for basic_ostream, operator<<, basic_ofstream
#include <unordered_map> // for unordered_map, operator==, _Node_const_i... #include <functional> // for function
#include <utility> // for pair #include <iostream> // for cout, cerr
#include <sstream> #include <sstream> // for basic_istringstream
#include <string> #include <string> // for char_traits, string, operator<<, hash
#include <algorithm> #include <unordered_map> // for unordered_map, operator==, _Node_const_i...
#include <utility> // for pair
// Variables // Variables
Options options; Options options;
@@ -20,7 +21,7 @@ void initOptions()
options = Options(); options = Options();
#ifdef DEBUG #ifdef DEBUG
options.section = SectionState(Section::TITLE, Subsection::NONE); options.section = SectionState(Section::DEMO, Subsection::NONE);
options.console = true; options.console = true;
#else #else
options.section = SectionState(Section::LOGO, Subsection::LOGO_TO_INTRO); options.section = SectionState(Section::LOGO, Subsection::LOGO_TO_INTRO);
@@ -39,9 +40,8 @@ bool loadOptionsFromFile(const std::string &file_path)
options.version = ""; options.version = "";
// Variables para manejar el fichero // Variables para manejar el fichero
std::string line;
std::ifstream file(file_path); std::ifstream file(file_path);
// Si el fichero se puede abrir // Si el fichero se puede abrir
if (file.good()) if (file.good())
{ {
@@ -50,6 +50,7 @@ bool loadOptionsFromFile(const std::string &file_path)
{ {
std::cout << "Reading file config.txt\n"; std::cout << "Reading file config.txt\n";
} }
std::string line;
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// Elimina espacios en blanco iniciales y finales // Elimina espacios en blanco iniciales y finales

View File

@@ -71,7 +71,7 @@ constexpr int DEFAULT_BORDER_WIDTH = 32;
constexpr int DEFAULT_BORDER_HEIGHT = 24; // Alto del borde por defecto constexpr int DEFAULT_BORDER_HEIGHT = 24; // Alto del borde por defecto
constexpr int DEFAULT_SOUND_VOLUME = 100; // Volumen por defecto de los efectos de sonido constexpr int DEFAULT_SOUND_VOLUME = 100; // Volumen por defecto de los efectos de sonido
constexpr bool DEFAULT_SOUND_ENABLED = true; // Sonido habilitado por defecto constexpr bool DEFAULT_SOUND_ENABLED = true; // Sonido habilitado por defecto
constexpr int DEFAULT_MUSIC_VOLUME = 80; // Volumen por defecto de la musica constexpr int DEFAULT_MUSIC_VOLUME = 80; // Volumen por defecto de la musica
constexpr bool DEFAULT_MUSIC_ENABLED = true; // Musica habilitada por defecto constexpr bool DEFAULT_MUSIC_ENABLED = true; // Musica habilitada por defecto
constexpr int DEFAULT_AUDIO_VOLUME = 100; // Volumen por defecto constexpr int DEFAULT_AUDIO_VOLUME = 100; // Volumen por defecto
constexpr bool DEFAULT_AUDIO_ENABLED = true; // Audio por defecto constexpr bool DEFAULT_AUDIO_ENABLED = true; // Audio por defecto
@@ -83,7 +83,7 @@ constexpr NotificationPosition DEFAULT_NOTIFICATION_POSITION = NotificationPosit
constexpr bool DEFAULT_NOTIFICATION_SOUND = true; // Sonido de las notificaciones por defecto constexpr bool DEFAULT_NOTIFICATION_SOUND = true; // Sonido de las notificaciones por defecto
const Color DEFAULT_NOTIFICATION_COLOR = Color(48, 48, 48); // Color de las notificaciones por defecto const Color DEFAULT_NOTIFICATION_COLOR = Color(48, 48, 48); // Color de las notificaciones por defecto
constexpr bool DEFAULT_CONSOLE = false; // Consola desactivada por defecto constexpr bool DEFAULT_CONSOLE = false; // Consola desactivada por defecto
constexpr const char *DEFAULT_VERSION = "1.09"; // Versión por defecto constexpr const char *DEFAULT_VERSION = "1.10"; // Versión por defecto
// Estructura para las opciones de las notificaciones // Estructura para las opciones de las notificaciones
struct OptionsNotification struct OptionsNotification
@@ -212,10 +212,10 @@ struct OptionsStats
worst_nightmare("") {} worst_nightmare("") {}
// Constructor // Constructor
OptionsStats(int r, int i, std::string wn) OptionsStats(int rooms, int items, const std::string &worst_nightmare)
: rooms(r), : rooms(rooms),
items(i), items(items),
worst_nightmare(wn) {} worst_nightmare(worst_nightmare) {}
}; };
// Estructura con opciones de la ventana // Estructura con opciones de la ventana

View File

@@ -82,21 +82,44 @@ jSurface pLoadSurface(const char *filename)
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
long size = ftell(f); long size = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
Uint8 *buffer = (Uint8 *)malloc(size); Uint8 *buffer = (Uint8 *)malloc(size);
fread(buffer, size, 1, f); if (!buffer) // Verificar que la memoria se asignó correctamente
{
fclose(f);
return NULL;
}
// Verificar el retorno de fread
if (fread(buffer, size, 1, f) != 1)
{
free(buffer); // Liberar memoria si falla la lectura
fclose(f);
return NULL;
}
fclose(f); fclose(f);
Uint16 w, h; Uint16 w, h;
Uint8 *pixels = LoadGif(buffer, &w, &h); Uint8 *pixels = LoadGif(buffer, &w, &h);
free(buffer); // Liberar memoria después de usar el buffer
if (pixels == NULL) if (pixels == NULL)
{ {
return NULL; return NULL;
} }
jSurface surf = (jSurface)malloc(sizeof(jSurface_s)); jSurface surf = (jSurface)malloc(sizeof(jSurface_s));
if (!surf) // Verificar que la memoria se asignó correctamente
{
free(pixels); // Liberar los píxeles si falla
return NULL;
}
surf->w = w; surf->w = w;
surf->h = h; surf->h = h;
surf->data = pixels; surf->data = pixels;
free(buffer);
return surf; return surf;
} }
@@ -110,15 +133,30 @@ void pLoadPal(const char *filename)
long size = ftell(f); long size = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
Uint8 *buffer = (Uint8 *)malloc(size); Uint8 *buffer = (Uint8 *)malloc(size);
fread(buffer, size, 1, f); if (!buffer) // Verificar que la asignación de memoria fue exitosa
{
fclose(f);
return;
}
// Verificar el resultado de fread
if (fread(buffer, size, 1, f) != 1)
{
free(buffer); // Liberar memoria si falla la lectura
fclose(f);
return;
}
fclose(f); fclose(f);
Uint32 *pal = LoadPalette(buffer); Uint32 *pal = LoadPalette(buffer);
free(buffer); // Liberar memoria después de usar el buffer
if (pal == NULL) if (pal == NULL)
{ {
return; return;
} }
free(buffer);
for (int i = 0; i < 256; ++i) for (int i = 0; i < 256; ++i)
{ {
paleta[i] = pal[i]; paleta[i] = pal[i];

View File

@@ -1,27 +1,22 @@
// IWYU pragma: no_include <bits/std_abs.h> // IWYU pragma: no_include <bits/std_abs.h>
#include "player.h" #include "player.h"
#include <stdlib.h> // Para rand #include <stdlib.h> // for rand
#include <algorithm> // Para max, min #include <algorithm> // for max, min
#include <cmath> // Para ceil, abs #include <cmath> // for ceil, abs
#include "animated_sprite.h" // Para AnimatedSprite #include "animated_sprite.h" // for AnimatedSprite
#include "asset.h" // Para Asset #include "debug.h" // for Debug
#include "defines.h" // Para BORDER_TOP, BLOCK, BORDER_BOTTOM, BORDER... #include "defines.h" // for BORDER_BOTTOM, BORDER_LEFT, BORDER_RIGHT
#include "debug.h" // Para Debug #include "input.h" // for Input, InputAction
#include "input.h" // Para Input, inputs_e #include "jail_audio.h" // for JA_PlaySound
#include "jail_audio.h" // Para JA_LoadSound, JA_Sound_t, JA_PlaySound #include "options.h" // for Options, options, Cheat, OptionsVideo
#include "resource.h" // Para Resource #include "resource.h" // for Resource
#include "room.h" // Para Room, tile_e #include "room.h" // for Room, JA_Sound_t, TileType
#include "texture.h" // Para Texture #include "screen.h" // for Screen
#include "options.h" #include "texture.h" // for Texture
#include "screen.h"
// Constructor // Constructor
Player::Player(PlayerData player) Player::Player(const PlayerData &player)
: renderer_(Screen::get()->getRenderer()), : room_(player.room)
input_(Input::get()),
asset_(Asset::get()),
debug_(Debug::get()),
room_(player.room)
{ {
// Inicializa algunas variables // Inicializa algunas variables
initSprite(player.texture_path, player.animations_path); initSprite(player.texture_path, player.animations_path);
@@ -82,13 +77,13 @@ void Player::checkInput()
if (!auto_movement_) if (!auto_movement_)
{ {
// Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica // Comprueba las entradas de desplazamiento lateral solo en el caso de no estar enganchado a una superficie automatica
if (input_->checkInput(input_left)) if (Input::get()->checkInput(InputAction::LEFT))
{ {
vx_ = -0.6f; vx_ = -0.6f;
sprite_->setFlip(SDL_FLIP_HORIZONTAL); sprite_->setFlip(SDL_FLIP_HORIZONTAL);
} }
else if (input_->checkInput(input_right)) else if (Input::get()->checkInput(InputAction::RIGHT))
{ {
vx_ = 0.6f; vx_ = 0.6f;
sprite_->setFlip(SDL_FLIP_NONE); sprite_->setFlip(SDL_FLIP_NONE);
@@ -119,7 +114,7 @@ void Player::checkInput()
} }
} }
if (input_->checkInput(input_jump)) if (Input::get()->checkInput(InputAction::JUMP))
{ {
// Solo puede saltar si ademas de estar (state == s_standing) // Solo puede saltar si ademas de estar (state == s_standing)
// Esta sobre el suelo, rampa o suelo que se mueve // Esta sobre el suelo, rampa o suelo que se mueve
@@ -293,7 +288,7 @@ void Player::move()
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende // Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state_ != PlayerState::JUMPING) if (state_ != PlayerState::JUMPING)
{ {
v_line_t leftSide = {static_cast<int>(x_), static_cast<int>(y_) + HEIGHT_ - 2, static_cast<int>(y_) + HEIGHT_ - 1}; // Comprueba solo los dos pixels de abajo LineVertical leftSide = {static_cast<int>(x_), static_cast<int>(y_) + HEIGHT_ - 2, static_cast<int>(y_) + HEIGHT_ - 1}; // Comprueba solo los dos pixels de abajo
const int ly = room_->checkLeftSlopes(&leftSide); const int ly = room_->checkLeftSlopes(&leftSide);
if (ly > -1) if (ly > -1)
{ {
@@ -340,7 +335,7 @@ void Player::move()
// Si ha tocado alguna rampa mientras camina (sin saltar), asciende // Si ha tocado alguna rampa mientras camina (sin saltar), asciende
if (state_ != PlayerState::JUMPING) if (state_ != PlayerState::JUMPING)
{ {
v_line_t rightSide = {static_cast<int>(x_) + WIDTH_ - 1, static_cast<int>(y_) + HEIGHT_ - 2, static_cast<int>(y_) + HEIGHT_ - 1}; // Comprueba solo los dos pixels de abajo LineVertical rightSide = {static_cast<int>(x_) + WIDTH_ - 1, static_cast<int>(y_) + HEIGHT_ - 2, static_cast<int>(y_) + HEIGHT_ - 1}; // Comprueba solo los dos pixels de abajo
const int ry = room_->checkRightSlopes(&rightSide); const int ry = room_->checkRightSlopes(&rightSide);
if (ry > -1) if (ry > -1)
{ {
@@ -432,8 +427,8 @@ void Player::move()
// Si no hay colisión con los muros, comprueba la colisión con las rampas // Si no hay colisión con los muros, comprueba la colisión con las rampas
if (state_ != PlayerState::JUMPING) if (state_ != PlayerState::JUMPING)
{ // Las rampas no se miran si se está saltando { // Las rampas no se miran si se está saltando
v_line_t leftSide = {proj.x, proj.y, proj.y + proj.h - 1}; LineVertical leftSide = {proj.x, proj.y, proj.y + proj.h - 1};
v_line_t rightSide = {proj.x + proj.w - 1, proj.y, proj.y + proj.h - 1}; LineVertical rightSide = {proj.x + proj.w - 1, proj.y, proj.y + proj.h - 1};
const int p = std::max(room_->checkRightSlopes(&rightSide), room_->checkLeftSlopes(&leftSide)); const int p = std::max(room_->checkRightSlopes(&rightSide), room_->checkLeftSlopes(&leftSide));
if (p > -1) if (p > -1)
{ {
@@ -469,8 +464,8 @@ void Player::move()
collider_box_ = getRect(); // Actualiza el rectangulo de colisión collider_box_ = getRect(); // Actualiza el rectangulo de colisión
#ifdef DEBUG #ifdef DEBUG
debug_->add("RECT_X: " + std::to_string(debug_rect_x_.x) + "," + std::to_string(debug_rect_x_.y) + "," + std::to_string(debug_rect_x_.w) + "," + std::to_string(debug_rect_x_.h)); Debug::get()->add("RECT_X: " + std::to_string(debug_rect_x_.x) + "," + std::to_string(debug_rect_x_.y) + "," + std::to_string(debug_rect_x_.w) + "," + std::to_string(debug_rect_x_.h));
debug_->add("RECT_Y: " + std::to_string(debug_rect_y_.x) + "," + std::to_string(debug_rect_y_.y) + "," + std::to_string(debug_rect_y_.w) + "," + std::to_string(debug_rect_y_.h)); Debug::get()->add("RECT_Y: " + std::to_string(debug_rect_y_.x) + "," + std::to_string(debug_rect_y_.y) + "," + std::to_string(debug_rect_y_.w) + "," + std::to_string(debug_rect_y_.h));
#endif #endif
} }
@@ -510,7 +505,7 @@ void Player::playJumpSound()
} }
#ifdef DEBUG #ifdef DEBUG
debug_->add("JUMP: " + std::to_string(jumping_counter_ / 4)); Debug::get()->add("JUMP: " + std::to_string(jumping_counter_ / 4));
#endif #endif
} }
@@ -523,7 +518,7 @@ void Player::playFallSound()
} }
#ifdef DEBUG #ifdef DEBUG
debug_->add("FALL: " + std::to_string(falling_counter_ / 4)); Debug::get()->add("FALL: " + std::to_string(falling_counter_ / 4));
#endif #endif
} }
@@ -550,17 +545,17 @@ bool Player::isOnFloor()
#ifdef DEBUG #ifdef DEBUG
if (onFloor) if (onFloor)
{ {
debug_->add("ON_FLOOR"); Debug::get()->add("ON_FLOOR");
} }
if (onSlopeL) if (onSlopeL)
{ {
debug_->add("ON_SLOPE_L: " + std::to_string(under_feet_[0].x) + "," + std::to_string(under_feet_[0].y)); Debug::get()->add("ON_SLOPE_L: " + std::to_string(under_feet_[0].x) + "," + std::to_string(under_feet_[0].y));
} }
if (onSlopeR) if (onSlopeR)
{ {
debug_->add("ON_SLOPE_R: " + std::to_string(under_feet_[1].x) + "," + std::to_string(under_feet_[1].y)); Debug::get()->add("ON_SLOPE_R: " + std::to_string(under_feet_[1].x) + "," + std::to_string(under_feet_[1].y));
} }
#endif #endif
@@ -583,7 +578,7 @@ bool Player::isOnAutoSurface()
#ifdef DEBUG #ifdef DEBUG
if (onAutoSurface) if (onAutoSurface)
{ {
debug_->add("ON_AUTO_SURFACE"); Debug::get()->add("ON_AUTO_SURFACE");
} }
#endif #endif
@@ -609,7 +604,7 @@ bool Player::isOnDownSlope()
#ifdef DEBUG #ifdef DEBUG
if (onSlope) if (onSlope)
{ {
debug_->add("ON_DOWN_SLOPE"); Debug::get()->add("ON_DOWN_SLOPE");
} }
#endif #endif
@@ -622,21 +617,17 @@ bool Player::checkKillingTiles()
// Actualiza los puntos de colisión // Actualiza los puntos de colisión
updateColliderPoints(); updateColliderPoints();
// Comprueba si hay contacto // Comprueba si hay contacto y retorna en cuanto se encuentra colisión
bool check = false; for (const auto &c : collider_points_)
for (auto c : collider_points_)
{ {
check |= (room_->getTile(c) == t_kill); if (room_->getTile(c) == TileType::KILL)
{
is_alive_ = false; // Mata al jugador inmediatamente
return true; // Retorna en cuanto se detecta una colisión
}
} }
// Mata al jugador si hay colisión return false; // No se encontró ninguna colisión
if (check)
{
is_alive_ = false;
}
return check;
} }
// Establece el color del jugador // Establece el color del jugador
@@ -709,13 +700,6 @@ void Player::initSounds()
} }
} }
// Coloca el sprite en la posición del jugador
void Player::placeSprite()
{
sprite_->setPosX(x_);
sprite_->setPosY(y_);
}
// Aplica los valores de spawn al jugador // Aplica los valores de spawn al jugador
void Player::applySpawnValues(const PlayerSpawn &spawn) void Player::applySpawnValues(const PlayerSpawn &spawn)
{ {
@@ -744,34 +728,36 @@ void Player::initSprite(const std::string &texture_path, const std::string &anim
// Pinta la información de debug del jugador // Pinta la información de debug del jugador
void Player::renderDebugInfo() void Player::renderDebugInfo()
{ {
if (debug_->getEnabled()) if (Debug::get()->getEnabled())
{ {
auto renderer = Screen::get()->getRenderer();
// Pinta los underfeet // Pinta los underfeet
SDL_SetRenderDrawColor(renderer_, 255, 0, 255, 255); SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_RenderDrawPoint(renderer_, under_feet_[0].x, under_feet_[0].y); SDL_RenderDrawPoint(renderer, under_feet_[0].x, under_feet_[0].y);
SDL_RenderDrawPoint(renderer_, under_feet_[1].x, under_feet_[1].y); SDL_RenderDrawPoint(renderer, under_feet_[1].x, under_feet_[1].y);
// Pinta rectangulo del jugador // Pinta rectangulo del jugador
SDL_SetRenderDrawColor(renderer_, debug_color_.r, debug_color_.g, debug_color_.b, 192); SDL_SetRenderDrawColor(renderer, debug_color_.r, debug_color_.g, debug_color_.b, 192);
SDL_Rect rect = getRect(); SDL_Rect rect = getRect();
SDL_RenderFillRect(renderer_, &rect); SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer_, 0, 255, 255, 255); SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
SDL_RenderDrawRect(renderer_, &rect); SDL_RenderDrawRect(renderer, &rect);
// Pinta el rectangulo de movimiento // Pinta el rectangulo de movimiento
SDL_SetRenderDrawColor(renderer_, 255, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
if (vx_ != 0.0f) if (vx_ != 0.0f)
{ {
SDL_RenderFillRect(renderer_, &debug_rect_x_); SDL_RenderFillRect(renderer, &debug_rect_x_);
} }
if (vy_ != 0.0f) if (vy_ != 0.0f)
{ {
SDL_RenderFillRect(renderer_, &debug_rect_y_); SDL_RenderFillRect(renderer, &debug_rect_y_);
} }
// Pinta el punto de debug // Pinta el punto de debug
SDL_SetRenderDrawColor(renderer_, rand() % 256, rand() % 256, rand() % 256, 255); SDL_SetRenderDrawColor(renderer, rand() % 256, rand() % 256, rand() % 256, 255);
SDL_RenderDrawPoint(renderer_, debug_point_.x, debug_point_.y); SDL_RenderDrawPoint(renderer, debug_point_.x, debug_point_.y);
} }
} }
#endif #endif

View File

@@ -1,20 +1,16 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // Para SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <SDL2/SDL_render.h> // for SDL_RendererFlip, SDL_FLIP_NONE
#include <string> // Para basic_string, string #include <memory> // for shared_ptr, __shared_ptr_access
#include <vector> // Para vector #include <string> // for string
#include <memory> // Para shared_ptr #include <vector> // for vector
#include "utils.h" // Para color_t #include "animated_sprite.h" // for AnimatedSprite
#include "defines.h" // Para BLOCK #include "defines.h" // for BORDER_TOP, BLOCK
#include "room.h" #include "texture.h" // for Texture
#include "animated_sprite.h" #include "utils.h" // for Color
class Asset; class Room; // lines 16-16
class Debug; struct JA_Sound_t; // lines 17-17
class Input;
class Resource;
class Room;
struct JA_Sound_t;
enum class PlayerState enum class PlayerState
{ {
@@ -63,10 +59,6 @@ public:
static constexpr float MAX_VY_ = 1.2f; // Velocidad máxima que puede alcanzar al desplazarse en vertical static constexpr float MAX_VY_ = 1.2f; // Velocidad máxima que puede alcanzar al desplazarse en vertical
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
Input *input_; // Objeto para gestionar la entrada
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug_; // Objeto para gestionar la información de debug
std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego std::shared_ptr<Room> room_; // Objeto encargado de gestionar cada habitación del juego
std::shared_ptr<AnimatedSprite> sprite_; // Sprite del jugador std::shared_ptr<AnimatedSprite> sprite_; // Sprite del jugador
@@ -153,7 +145,7 @@ public:
void initSounds(); void initSounds();
// Coloca el sprite en la posición del jugador // Coloca el sprite en la posición del jugador
void placeSprite(); void placeSprite() { sprite_->setPos(x_, y_); }
// Aplica los valores de spawn al jugador // Aplica los valores de spawn al jugador
void applySpawnValues(const PlayerSpawn &spawn); void applySpawnValues(const PlayerSpawn &spawn);
@@ -168,7 +160,7 @@ public:
public: public:
// Constructor // Constructor
Player(PlayerData player); explicit Player(const PlayerData &player);
// Destructor // Destructor
~Player() = default; ~Player() = default;
@@ -210,8 +202,5 @@ public:
bool isAlive() { return is_alive_; } bool isAlive() { return is_alive_; }
// Pone el jugador en modo pausa // Pone el jugador en modo pausa
void pause() { is_paused_ = true; } void setPaused(bool value) { is_paused_ = value; }
// Quita el modo pausa del jugador
void resume() { is_paused_ = false; }
}; };

View File

@@ -1,16 +1,20 @@
#include "resource.h" #include "resource.h"
#include <algorithm> // for find_if #include <SDL2/SDL_events.h> // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN
#include <iostream> // for basic_ostream, operator<<, endl, cout, cerr #include <SDL2/SDL_keycode.h> // for SDLK_ESCAPE
#include <stdexcept> // for runtime_error #include <SDL2/SDL_rect.h> // for SDL_Rect
#include "asset.h" // for Asset, AssetType #include <SDL2/SDL_render.h> // for SDL_RenderDrawRect, SDL_RenderFillRect
#include "jail_audio.h" // for JA_DeleteMusic, JA_DeleteSound, JA_LoadMusic #include <stdlib.h> // for exit, size_t
#include "screen.h" // for Screen #include <algorithm> // for find_if
#include "text.h" // for Text, loadTextFile #include <iostream> // for basic_ostream, operator<<, endl, cout
#include "utils.h" // for getFileName, printWithDots #include <stdexcept> // for runtime_error
#include "options.h" // for getFileName, printWithDots #include "asset.h" // for AssetType, Asset
#include <SDL2/SDL_events.h> // for SDL_PollEvent #include "jail_audio.h" // for JA_DeleteMusic, JA_DeleteSound, JA_Loa...
struct JA_Music_t; // lines 10-10 #include "options.h" // for Options, OptionsGame, options
struct JA_Sound_t; // lines 11-11 #include "screen.h" // for Screen
#include "text.h" // for Text, loadTextFile
#include "utils.h" // for getFileName, printWithDots, Color
struct JA_Music_t; // lines 12-12
struct JA_Sound_t; // lines 13-13
// [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado
Resource *Resource::resource_ = nullptr; Resource *Resource::resource_ = nullptr;

View File

@@ -1,34 +1,35 @@
#include "room.h" #include "room.h"
#include <SDL2/SDL_blendmode.h> // Para SDL_BLENDMODE_BLEND #include <SDL2/SDL_blendmode.h> // for SDL_BLENDMODE_BLEND
#include <SDL2/SDL_error.h> // Para SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888 #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include <stdlib.h> // Para rand #include <stdlib.h> // for rand
#include <fstream> // Para basic_ostream, operator<<, basic_ist... #include <exception> // for exception
#include <iostream> // Para cout #include <fstream> // for basic_ostream, operator<<, basic_ist...
#include <sstream> // Para basic_stringstream #include <iostream> // for cout, cerr
#include "asset.h" // Para Asset #include <sstream> // for basic_stringstream
#include "defines.h" // Para BLOCK, PLAY_AREA_HEIGHT, PLAY_AREA_W... #include "debug.h" // for Debug
#include "debug.h" // Para Debug #include "defines.h" // for BLOCK, PLAY_AREA_HEIGHT, PLAY_AREA_W...
#include "item_tracker.h" // Para ItemTracker #include "item_tracker.h" // for ItemTracker
#include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla... #include "jail_audio.h" // for JA_PlaySound
#include "screen.h" // Para Screen #include "options.h" // for Options, options, OptionsVideo, Opti...
#include "sprite.h" // Para Sprite #include "resource.h" // for Resource
#include "texture.h" // Para Texture #include "scoreboard.h" // for ScoreboardData
#include "options.h" #include "screen.h" // for Screen
#include "utils.h" // Para stringToBool, stringToColor #include "sprite.h" // for Sprite
#include "resource.h" #include "texture.h" // for Texture
#include "utils.h" // for LineHorizontal, LineDiagonal, LineVe...
// Carga las variables y texturas desde un fichero de mapa de tiles // Carga las variables y texturas desde un fichero de mapa de tiles
std::vector<int> loadRoomTileFile(const std::string &file_path, bool verbose) std::vector<int> loadRoomTileFile(const std::string &file_path, bool verbose)
{ {
std::vector<int> tileMapFile; std::vector<int> tileMapFile;
const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1); const std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
std::string line;
std::ifstream file(file_path); std::ifstream file(file_path);
// El fichero se puede abrir // El fichero se puede abrir
if (file.good()) if (file.good())
{ {
std::string line;
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
while (std::getline(file, line)) while (std::getline(file, line))
{ // Lee el fichero linea a linea { // Lee el fichero linea a linea
@@ -81,12 +82,12 @@ RoomData loadRoomFile(const std::string &file_path, bool verbose)
const std::string fileName = file_path.substr(file_path.find_last_of("\\/") + 1); const std::string fileName = file_path.substr(file_path.find_last_of("\\/") + 1);
room.number = fileName.substr(0, fileName.find_last_of(".")); room.number = fileName.substr(0, fileName.find_last_of("."));
std::string line;
std::ifstream file(file_path); std::ifstream file(file_path);
// El fichero se puede abrir // El fichero se puede abrir
if (file.good()) if (file.good())
{ {
std::string line;
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
while (std::getline(file, line)) while (std::getline(file, line))
{ {
@@ -398,124 +399,87 @@ bool setItem(ItemData *item, const std::string &key, const std::string &value)
} }
// Constructor // Constructor
Room::Room(std::shared_ptr<RoomData> room, std::shared_ptr<ScoreboardData> data) Room::Room(const std::string &room_path, std::shared_ptr<ScoreboardData> data)
: screen_(Screen::get()), : data_(data)
renderer_(Screen::get()->getRenderer()),
asset_(Asset::get()),
debug_(Debug::get()),
data_(data)
{ {
number_ = room->number; auto room = Resource::get()->getRoom(room_path);
name_ = room->name; initializeRoom(*room);
bg_color_ = room->bg_color;
border_color_ = room->border_color;
item_color1_ = room->item_color1 == "" ? "yellow" : room->item_color1;
item_color2_ = room->item_color2 == "" ? "magenta" : room->item_color2;
room_top_ = room->room_top;
room_bottom_ = room->room_bottom;
room_left_ = room->room_left;
room_right_ = room->room_right;
tile_set_file_ = room->tile_set_file;
tile_map_file_ = room->tile_map_file;
auto_surface_direction_ = room->auto_surface_direction;
tile_map_ = Resource::get()->getTileMap(room->tile_map_file);
texture_ = (options.video.palette == Palette::ZXSPECTRUM) ? Resource::get()->getTexture(room->tile_set_file) : Resource::get()->getTexture(room->tile_set_file);
// Inicializa variables // Abre la Jail si se da el caso
tile_set_width_ = texture_->getWidth() / TILE_SIZE_; openTheJail();
paused_ = false;
counter_ = 0;
// Crea los enemigos // Inicializa las superficies de colision
for (auto &enemy_data : room->enemies) initRoomSurfaces();
{
enemies_.emplace_back(std::make_shared<Enemy>(enemy_data));
}
// Crea los items
for (auto &item : room->items)
{
const SDL_Point itemPos = {item.x, item.y};
if (!ItemTracker::get()->hasBeenPicked(room->name, itemPos))
{
item.color1 = stringToColor(options.video.palette, item_color1_);
item.color2 = stringToColor(options.video.palette, item_color2_);
items_.emplace_back(std::make_shared<Item>(item));
}
}
// Carga los sonidos
item_sound_ = Resource::get()->getSound("item.wav");
// Abre la jail para poder entrar
if (data_->jail_is_open)
{
openTheJail();
}
// Calcula las superficies
setBottomSurfaces();
setTopSurfaces();
setLeftSurfaces();
setRightSurfaces();
setLeftSlopes();
setRightSlopes();
setAutoSurfaces();
// Busca los tiles animados // Busca los tiles animados
setAnimatedTiles(); setAnimatedTiles();
// Crea la textura para el mapa de tiles de la habitación // Crea la textura para el mapa de tiles de la habitación
map_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT); map_texture_ = createTexture(Screen::get()->getRenderer(), PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT);
if (map_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: mapTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
SDL_SetTextureBlendMode(map_texture_, SDL_BLENDMODE_BLEND);
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
fillMapTexture(); fillMapTexture();
// Establece el color del borde // Establece el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, room->border_color)); Screen::get()->setBorderColor(stringToColor(options.video.palette, border_color_));
} }
// Destructor // Destructor
Room::~Room() Room::~Room() { SDL_DestroyTexture(map_texture_); }
{
// Reclama la memoria utilizada por los objetos
SDL_DestroyTexture(map_texture_);
}
// Devuelve el nombre de la habitación void Room::initializeRoom(const RoomData &room)
std::string Room::getName()
{ {
return name_; // Asignar valores a las variables miembro
} number_ = room.number;
name_ = room.name;
bg_color_ = room.bg_color;
border_color_ = room.border_color;
item_color1_ = room.item_color1.empty() ? "yellow" : room.item_color1;
item_color2_ = room.item_color2.empty() ? "magenta" : room.item_color2;
room_top_ = room.room_top;
room_bottom_ = room.room_bottom;
room_left_ = room.room_left;
room_right_ = room.room_right;
tile_set_file_ = room.tile_set_file;
tile_map_file_ = room.tile_map_file;
auto_surface_direction_ = room.auto_surface_direction;
tile_map_ = Resource::get()->getTileMap(room.tile_map_file);
texture_ = Resource::get()->getTexture(room.tile_set_file);
tile_set_width_ = texture_->getWidth() / TILE_SIZE_;
is_paused_ = false;
counter_ = 0;
// Devuelve el color de la habitación // Crear los enemigos
Color Room::getBGColor() for (auto &enemy_data : room.enemies)
{ {
return stringToColor(options.video.palette, bg_color_); enemies_.emplace_back(std::make_shared<Enemy>(enemy_data));
} }
// Devuelve el color del borde // Crear los items
Color Room::getBorderColor() for (const auto &item : room.items)
{ {
return stringToColor(options.video.palette, border_color_); const SDL_Point itemPos = {item.x, item.y};
if (!ItemTracker::get()->hasBeenPicked(room.name, itemPos))
{
// Crear una copia local de los datos del item
ItemData itemCopy = item;
itemCopy.color1 = stringToColor(options.video.palette, item_color1_);
itemCopy.color2 = stringToColor(options.video.palette, item_color2_);
// Crear el objeto Item usando la copia modificada
items_.emplace_back(std::make_shared<Item>(itemCopy));
}
}
} }
// Crea la textura con el mapeado de la habitación // Crea la textura con el mapeado de la habitación
void Room::fillMapTexture() void Room::fillMapTexture()
{ {
const Color color = stringToColor(options.video.palette, bg_color_); const Color color = stringToColor(options.video.palette, bg_color_);
SDL_SetRenderTarget(renderer_, map_texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), map_texture_);
SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Los tileSetFiles son de 20x20 tiles. El primer tile es el 0. Cuentan hacia la derecha y hacia abajo // Los tileSetFiles son de 20x20 tiles. El primer tile es el 0. Cuentan hacia la derecha y hacia abajo
@@ -537,14 +501,14 @@ void Room::fillMapTexture()
texture_->render(x * TILE_SIZE_, y * TILE_SIZE_, &clip); texture_->render(x * TILE_SIZE_, y * TILE_SIZE_, &clip);
#ifdef DEBUG #ifdef DEBUG
if (debug_->getEnabled()) if (Debug::get()->getEnabled())
{ {
if (clip.x != -TILE_SIZE_) if (clip.x != -TILE_SIZE_)
{ {
clip.x = x * TILE_SIZE_; clip.x = x * TILE_SIZE_;
clip.y = y * TILE_SIZE_; clip.y = y * TILE_SIZE_;
SDL_SetRenderDrawColor(renderer_, 64, 64, 64, 224); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 64, 64, 64, 224);
SDL_RenderFillRect(renderer_, &clip); SDL_RenderFillRect(Screen::get()->getRenderer(), &clip);
} }
} }
#endif #endif
@@ -552,16 +516,16 @@ void Room::fillMapTexture()
} }
#ifdef DEBUG #ifdef DEBUG
if (debug_->getEnabled()) if (Debug::get()->getEnabled())
{ {
// BottomSurfaces // BottomSurfaces
if (true) if (true)
{ {
for (auto l : bottom_surfaces_) for (auto l : bottom_surfaces_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_SetRenderDrawColor(renderer_, 255, 0, 0, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 255, 0, 0, 0xFF);
SDL_RenderDrawLine(renderer_, l.x1, l.y, l.x2, l.y); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x1, l.y, l.x2, l.y);
} }
} }
@@ -570,9 +534,9 @@ void Room::fillMapTexture()
{ {
for (auto l : top_surfaces_) for (auto l : top_surfaces_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_SetRenderDrawColor(renderer_, 0, 255, 0, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 255, 0, 0xFF);
SDL_RenderDrawLine(renderer_, l.x1, l.y, l.x2, l.y); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x1, l.y, l.x2, l.y);
} }
} }
@@ -581,9 +545,9 @@ void Room::fillMapTexture()
{ {
for (auto l : left_surfaces_) for (auto l : left_surfaces_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_SetRenderDrawColor(renderer_, 128, 128, 255, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 128, 128, 255, 0xFF);
SDL_RenderDrawLine(renderer_, l.x, l.y1, l.x, l.y2); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x, l.y1, l.x, l.y2);
} }
} }
@@ -592,9 +556,9 @@ void Room::fillMapTexture()
{ {
for (auto l : right_surfaces_) for (auto l : right_surfaces_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_SetRenderDrawColor(renderer_, 255, 255, 0, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 255, 255, 0, 0xFF);
SDL_RenderDrawLine(renderer_, l.x, l.y1, l.x, l.y2); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x, l.y1, l.x, l.y2);
} }
} }
@@ -603,9 +567,9 @@ void Room::fillMapTexture()
{ {
for (auto l : left_slopes_) for (auto l : left_slopes_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_SetRenderDrawColor(renderer_, 0, 255, 255, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 255, 255, 0xFF);
SDL_RenderDrawLine(renderer_, l.x1, l.y1, l.x2, l.y2); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x1, l.y1, l.x2, l.y2);
} }
} }
@@ -614,9 +578,9 @@ void Room::fillMapTexture()
{ {
for (auto l : right_slopes_) for (auto l : right_slopes_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_SetRenderDrawColor(renderer_, 255, 0, 255, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 255, 0, 255, 0xFF);
SDL_RenderDrawLine(renderer_, l.x1, l.y1, l.x2, l.y2); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x1, l.y1, l.x2, l.y2);
} }
} }
@@ -625,14 +589,14 @@ void Room::fillMapTexture()
{ {
for (auto l : auto_surfaces_) for (auto l : auto_surfaces_)
{ {
SDL_SetRenderDrawColor(renderer_, (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), (rand() % 128) + 96, (rand() % 128) + 96, (rand() % 128) + 96, 0xFF);
SDL_RenderDrawLine(renderer_, l.x1, l.y, l.x2, l.y); SDL_RenderDrawLine(Screen::get()->getRenderer(), l.x1, l.y, l.x2, l.y);
} }
} }
} }
#endif #endif
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr);
} }
// Dibuja el mapa en pantalla // Dibuja el mapa en pantalla
@@ -640,11 +604,11 @@ void Room::renderMap()
{ {
// Dibuja la textura con el mapa en pantalla // Dibuja la textura con el mapa en pantalla
SDL_Rect dest = {0, 0, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT}; SDL_Rect dest = {0, 0, PLAY_AREA_WIDTH, PLAY_AREA_HEIGHT};
SDL_RenderCopy(renderer_, map_texture_, nullptr, &dest); SDL_RenderCopy(Screen::get()->getRenderer(), map_texture_, nullptr, &dest);
// Dibuja los tiles animados // Dibuja los tiles animados
#ifdef DEBUG #ifdef DEBUG
if (!debug_->getEnabled()) if (!Debug::get()->getEnabled())
{ {
renderAnimatedTiles(); renderAnimatedTiles();
} }
@@ -656,7 +620,7 @@ void Room::renderMap()
// Dibuja los enemigos en pantalla // Dibuja los enemigos en pantalla
void Room::renderEnemies() void Room::renderEnemies()
{ {
for (auto enemy : enemies_) for (const auto &enemy : enemies_)
{ {
enemy->render(); enemy->render();
} }
@@ -665,7 +629,7 @@ void Room::renderEnemies()
// Dibuja los objetos en pantalla // Dibuja los objetos en pantalla
void Room::renderItems() void Room::renderItems()
{ {
for (auto item : items_) for (const auto &item : items_)
{ {
item->render(); item->render();
} }
@@ -674,8 +638,9 @@ void Room::renderItems()
// Actualiza las variables y objetos de la habitación // Actualiza las variables y objetos de la habitación
void Room::update() void Room::update()
{ {
if (paused_) if (is_paused_)
{ // Si está en modo pausa no se actualiza nada {
// Si está en modo pausa no se actualiza nada
return; return;
} }
@@ -686,12 +651,14 @@ void Room::update()
updateAnimatedTiles(); updateAnimatedTiles();
for (auto enemy : enemies_) for (auto enemy : enemies_)
{ // Actualiza los enemigos {
// Actualiza los enemigos
enemy->update(); enemy->update();
} }
for (auto item : items_) for (auto item : items_)
{ // Actualiza los items {
// Actualiza los items
item->update(); item->update();
} }
} }
@@ -724,14 +691,14 @@ std::string Room::getRoom(int border)
} }
// Devuelve el tipo de tile que hay en ese pixel // Devuelve el tipo de tile que hay en ese pixel
tile_e Room::getTile(SDL_Point point) TileType Room::getTile(SDL_Point point)
{ {
const int pos = ((point.y / TILE_SIZE_) * MAP_WIDTH_) + (point.x / TILE_SIZE_); const int pos = ((point.y / TILE_SIZE_) * MAP_WIDTH_) + (point.x / TILE_SIZE_);
return getTile(pos); return getTile(pos);
} }
// Devuelve el tipo de tile que hay en ese indice // Devuelve el tipo de tile que hay en ese indice
tile_e Room::getTile(int index) TileType Room::getTile(int index)
{ {
// const bool onRange = (index > -1) && (index < mapWidth * mapHeight); // const bool onRange = (index > -1) && (index < mapWidth * mapHeight);
const bool onRange = (index > -1) && (index < (int)tile_map_.size()); const bool onRange = (index > -1) && (index < (int)tile_map_.size());
@@ -741,66 +708,66 @@ tile_e Room::getTile(int index)
// Las filas 0-8 son de tiles t_wall // Las filas 0-8 son de tiles t_wall
if ((tile_map_[index] >= 0) && (tile_map_[index] < 9 * tile_set_width_)) if ((tile_map_[index] >= 0) && (tile_map_[index] < 9 * tile_set_width_))
{ {
return t_wall; return TileType::WALL;
} }
// Las filas 9-17 son de tiles t_passable // Las filas 9-17 son de tiles t_passable
else if ((tile_map_[index] >= 9 * tile_set_width_) && (tile_map_[index] < 18 * tile_set_width_)) else if ((tile_map_[index] >= 9 * tile_set_width_) && (tile_map_[index] < 18 * tile_set_width_))
{ {
return t_passable; return TileType::PASSABLE;
} }
// Las filas 18-20 es de tiles t_animated // Las filas 18-20 es de tiles t_animated
else if ((tile_map_[index] >= 18 * tile_set_width_) && (tile_map_[index] < 21 * tile_set_width_)) else if ((tile_map_[index] >= 18 * tile_set_width_) && (tile_map_[index] < 21 * tile_set_width_))
{ {
return t_animated; return TileType::ANIMATED;
} }
// La fila 21 es de tiles t_slope_r // La fila 21 es de tiles t_slope_r
else if ((tile_map_[index] >= 21 * tile_set_width_) && (tile_map_[index] < 22 * tile_set_width_)) else if ((tile_map_[index] >= 21 * tile_set_width_) && (tile_map_[index] < 22 * tile_set_width_))
{ {
return t_slope_r; return TileType::SLOPE_R;
} }
// La fila 22 es de tiles t_slope_l // La fila 22 es de tiles t_slope_l
else if ((tile_map_[index] >= 22 * tile_set_width_) && (tile_map_[index] < 23 * tile_set_width_)) else if ((tile_map_[index] >= 22 * tile_set_width_) && (tile_map_[index] < 23 * tile_set_width_))
{ {
return t_slope_l; return TileType::SLOPE_L;
} }
// La fila 23 es de tiles t_kill // La fila 23 es de tiles t_kill
else if ((tile_map_[index] >= 23 * tile_set_width_) && (tile_map_[index] < 24 * tile_set_width_)) else if ((tile_map_[index] >= 23 * tile_set_width_) && (tile_map_[index] < 24 * tile_set_width_))
{ {
return t_kill; return TileType::KILL;
} }
} }
return t_empty; return TileType::EMPTY;
} }
// Indica si hay colision con un enemigo a partir de un rectangulo // Indica si hay colision con un enemigo a partir de un rectangulo
bool Room::enemyCollision(SDL_Rect &rect) bool Room::enemyCollision(SDL_Rect &rect)
{ {
bool collision = false; for (const auto &enemy : enemies_)
for (auto enemy : enemies_)
{ {
collision |= checkCollision(rect, enemy->getCollider()); if (checkCollision(rect, enemy->getCollider()))
{
return true;
}
} }
return false;
return collision;
} }
// Indica si hay colision con un objeto a partir de un rectangulo // Indica si hay colision con un objeto a partir de un rectangulo
bool Room::itemCollision(SDL_Rect &rect) bool Room::itemCollision(SDL_Rect &rect)
{ {
for (int i = 0; i < (int)items_.size(); ++i) for (int i = 0; i < static_cast<int>(items_.size()); ++i)
{ {
if (checkCollision(rect, items_[i]->getCollider())) if (checkCollision(rect, items_.at(i)->getCollider()))
{ {
ItemTracker::get()->addItem(name_, items_[i]->getPos()); ItemTracker::get()->addItem(name_, items_.at(i)->getPos());
items_.erase(items_.begin() + i); items_.erase(items_.begin() + i);
JA_PlaySound(item_sound_); JA_PlaySound(Resource::get()->getSound("item.wav"));
data_->items++; data_->items++;
options.stats.items = data_->items; options.stats.items = data_->items;
return true; return true;
@@ -810,88 +777,34 @@ bool Room::itemCollision(SDL_Rect &rect)
return false; return false;
} }
// Recarga la textura
void Room::reLoadTexture()
{
texture_->reLoad();
fillMapTexture();
for (auto enemy : enemies_)
{
enemy->reLoadTexture();
}
for (auto item : items_)
{
item->reLoadTexture();
}
}
// Recarga la paleta
void Room::reLoadPalette()
{
// Cambia el color de los items
for (auto item : items_)
{
item->setColors(stringToColor(options.video.palette, item_color1_), stringToColor(options.video.palette, item_color2_));
}
// Cambia el color de los enemigos
for (auto enemy : enemies_)
{
enemy->setPalette(options.video.palette);
}
// Establece el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, border_color_));
// Cambia la textura
//texture_ = (options.video.palette == Palette::ZXSPECTRUM) ? Resource::get()->getTexture(room->tile_set_file) : Resource::get()->getTexture(room->tile_set_file);
// Pone la nueva textura a los tiles animados
for (auto tile : animated_tiles_)
{
tile.sprite->setTexture(texture_);
}
// Recarga las texturas
reLoadTexture();
}
// Obten el tamaño del tile
int Room::getTileSize()
{
return TILE_SIZE_;
}
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
int Room::getSlopeHeight(SDL_Point p, tile_e slope) int Room::getSlopeHeight(SDL_Point p, TileType slope)
{ {
// Calcula la base del tile // Calcula la base del tile
int base = ((p.y / TILE_SIZE_) * TILE_SIZE_) + TILE_SIZE_; int base = ((p.y / TILE_SIZE_) * TILE_SIZE_) + TILE_SIZE_;
#ifdef DEBUG #ifdef DEBUG
debug_->add("BASE = " + std::to_string(base)); Debug::get()->add("BASE = " + std::to_string(base));
#endif #endif
// Calcula cuanto se ha entrado en el tile horizontalmente // Calcula cuanto se ha entrado en el tile horizontalmente
const int pos = (p.x % TILE_SIZE_); // Esto da un valor entre 0 y 7 const int pos = (p.x % TILE_SIZE_); // Esto da un valor entre 0 y 7
#ifdef DEBUG #ifdef DEBUG
debug_->add("POS = " + std::to_string(pos)); Debug::get()->add("POS = " + std::to_string(pos));
#endif #endif
// Se resta a la base la cantidad de pixeles pos en funcion de la rampa // Se resta a la base la cantidad de pixeles pos en funcion de la rampa
if (slope == t_slope_r) if (slope == TileType::SLOPE_R)
{ {
base -= pos + 1; base -= pos + 1;
#ifdef DEBUG #ifdef DEBUG
debug_->add("BASE_R = " + std::to_string(base)); Debug::get()->add("BASE_R = " + std::to_string(base));
#endif #endif
} }
else else
{ {
base -= (TILE_SIZE_ - pos); base -= (TILE_SIZE_ - pos);
#ifdef DEBUG #ifdef DEBUG
debug_->add("BASE_L = " + std::to_string(base)); Debug::get()->add("BASE_L = " + std::to_string(base));
#endif #endif
} }
@@ -907,7 +820,7 @@ void Room::setBottomSurfaces()
// Hay que recorrer la habitación por filas (excepto los de la última fila) // Hay que recorrer la habitación por filas (excepto los de la última fila)
for (int i = 0; i < (int)tile_map_.size() - MAP_WIDTH_; ++i) for (int i = 0; i < (int)tile_map_.size() - MAP_WIDTH_; ++i)
{ {
if (getTile(i) == t_wall && getTile(i + MAP_WIDTH_) != t_wall) if (getTile(i) == TileType::WALL && getTile(i + MAP_WIDTH_) != TileType::WALL)
{ {
tile.push_back(i); tile.push_back(i);
@@ -926,20 +839,19 @@ void Room::setBottomSurfaces()
if ((int)tile.size() > 1) if ((int)tile.size() > 1)
{ {
int i = 0; int i = 0;
int lastOne = 0;
do do
{ {
h_line_t line; LineHorizontal line;
line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_; line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1; line.y = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
lastOne = i; int last_one = i;
i++; i++;
if (i <= (int)tile.size() - 1) if (i <= (int)tile.size() - 1)
{ {
while (tile[i] == tile[i - 1] + 1) while (tile[i] == tile[i - 1] + 1)
{ {
lastOne = i; last_one = i;
if (i == (int)tile.size() - 1) if (i == (int)tile.size() - 1)
{ {
break; break;
@@ -948,7 +860,7 @@ void Room::setBottomSurfaces()
} }
} }
line.x2 = ((tile[lastOne] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1; line.x2 = ((tile[last_one] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
bottom_surfaces_.push_back(line); bottom_surfaces_.push_back(line);
if (i <= (int)tile.size() - 1) if (i <= (int)tile.size() - 1)
{ {
@@ -970,7 +882,7 @@ void Room::setTopSurfaces()
// Hay que recorrer la habitación por filas (excepto los de la primera fila) // Hay que recorrer la habitación por filas (excepto los de la primera fila)
for (int i = MAP_WIDTH_; i < (int)tile_map_.size(); ++i) for (int i = MAP_WIDTH_; i < (int)tile_map_.size(); ++i)
{ {
if ((getTile(i) == t_wall || getTile(i) == t_passable) && getTile(i - MAP_WIDTH_) != t_wall) if ((getTile(i) == TileType::WALL || getTile(i) == TileType::PASSABLE) && getTile(i - MAP_WIDTH_) != TileType::WALL)
{ {
tile.push_back(i); tile.push_back(i);
@@ -989,20 +901,19 @@ void Room::setTopSurfaces()
if ((int)tile.size() > 1) if ((int)tile.size() > 1)
{ {
int i = 0; int i = 0;
int lastOne = 0;
do do
{ {
h_line_t line; LineHorizontal line;
line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_; line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y = (tile[i] / MAP_WIDTH_) * TILE_SIZE_; line.y = (tile[i] / MAP_WIDTH_) * TILE_SIZE_;
lastOne = i; int last_one = i;
i++; i++;
if (i <= (int)tile.size() - 1) if (i <= (int)tile.size() - 1)
{ {
while (tile[i] == tile[i - 1] + 1) while (tile[i] == tile[i - 1] + 1)
{ {
lastOne = i; last_one = i;
if (i == (int)tile.size() - 1) if (i == (int)tile.size() - 1)
{ {
break; break;
@@ -1011,7 +922,7 @@ void Room::setTopSurfaces()
} }
} }
line.x2 = ((tile[lastOne] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1; line.x2 = ((tile[last_one] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
top_surfaces_.push_back(line); top_surfaces_.push_back(line);
if (i <= (int)tile.size() - 1) if (i <= (int)tile.size() - 1)
{ {
@@ -1036,7 +947,7 @@ void Room::setLeftSurfaces()
for (int j = 0; j < MAP_HEIGHT_; ++j) for (int j = 0; j < MAP_HEIGHT_; ++j)
{ {
const int pos = (j * MAP_WIDTH_ + i); const int pos = (j * MAP_WIDTH_ + i);
if (getTile(pos) == t_wall && getTile(pos - 1) != t_wall) if (getTile(pos) == TileType::WALL && getTile(pos - 1) != TileType::WALL)
{ {
tile.push_back(pos); tile.push_back(pos);
} }
@@ -1054,7 +965,7 @@ void Room::setLeftSurfaces()
int i = 0; int i = 0;
do do
{ {
v_line_t line; LineVertical line;
line.x = (tile[i] % MAP_WIDTH_) * TILE_SIZE_; line.x = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y1 = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_); line.y1 = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_);
while (tile[i] + MAP_WIDTH_ == tile[i + 1]) while (tile[i] + MAP_WIDTH_ == tile[i + 1])
@@ -1084,7 +995,7 @@ void Room::setRightSurfaces()
for (int j = 0; j < MAP_HEIGHT_; ++j) for (int j = 0; j < MAP_HEIGHT_; ++j)
{ {
const int pos = (j * MAP_WIDTH_ + i); const int pos = (j * MAP_WIDTH_ + i);
if (getTile(pos) == t_wall && getTile(pos + 1) != t_wall) if (getTile(pos) == TileType::WALL && getTile(pos + 1) != TileType::WALL)
{ {
tile.push_back(pos); tile.push_back(pos);
} }
@@ -1102,7 +1013,7 @@ void Room::setRightSurfaces()
int i = 0; int i = 0;
do do
{ {
v_line_t line; LineVertical line;
line.x = ((tile[i] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1; line.x = ((tile[i] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
line.y1 = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_); line.y1 = ((tile[i] / MAP_WIDTH_) * TILE_SIZE_);
while (tile[i] + MAP_WIDTH_ == tile[i + 1]) while (tile[i] + MAP_WIDTH_ == tile[i + 1])
@@ -1127,7 +1038,7 @@ void Room::setLeftSlopes()
std::vector<int> found; std::vector<int> found;
for (int i = 0; i < (int)tile_map_.size(); ++i) for (int i = 0; i < (int)tile_map_.size(); ++i)
{ {
if (getTile(i) == t_slope_l) if (getTile(i) == TileType::SLOPE_L)
{ {
found.push_back(i); found.push_back(i);
} }
@@ -1139,7 +1050,7 @@ void Room::setLeftSlopes()
while (found.size() > 0) while (found.size() > 0)
{ {
d_line_t line; LineDiagonal line;
line.x1 = (found[0] % MAP_WIDTH_) * TILE_SIZE_; line.x1 = (found[0] % MAP_WIDTH_) * TILE_SIZE_;
line.y1 = (found[0] / MAP_WIDTH_) * TILE_SIZE_; line.y1 = (found[0] / MAP_WIDTH_) * TILE_SIZE_;
int lookingFor = found[0] + MAP_WIDTH_ + 1; int lookingFor = found[0] + MAP_WIDTH_ + 1;
@@ -1168,7 +1079,7 @@ void Room::setRightSlopes()
std::vector<int> found; std::vector<int> found;
for (int i = 0; i < (int)tile_map_.size(); ++i) for (int i = 0; i < (int)tile_map_.size(); ++i)
{ {
if (getTile(i) == t_slope_r) if (getTile(i) == TileType::SLOPE_R)
{ {
found.push_back(i); found.push_back(i);
} }
@@ -1180,7 +1091,7 @@ void Room::setRightSlopes()
while (found.size() > 0) while (found.size() > 0)
{ {
d_line_t line; LineDiagonal line;
line.x1 = ((found[0] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1; line.x1 = ((found[0] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
line.y1 = (found[0] / MAP_WIDTH_) * TILE_SIZE_; line.y1 = (found[0] / MAP_WIDTH_) * TILE_SIZE_;
int lookingFor = found[0] + MAP_WIDTH_ - 1; int lookingFor = found[0] + MAP_WIDTH_ - 1;
@@ -1211,7 +1122,7 @@ void Room::setAutoSurfaces()
// Hay que recorrer la habitación por filas (excepto los de la primera fila) // Hay que recorrer la habitación por filas (excepto los de la primera fila)
for (int i = MAP_WIDTH_; i < (int)tile_map_.size(); ++i) for (int i = MAP_WIDTH_; i < (int)tile_map_.size(); ++i)
{ {
if (getTile(i) == t_animated) if (getTile(i) == TileType::ANIMATED)
{ {
tile.push_back(i); tile.push_back(i);
@@ -1224,23 +1135,22 @@ void Room::setAutoSurfaces()
} }
// Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies // Recorre el vector de tiles buscando tiles consecutivos para localizar las superficies
int i = 0;
int lastOne = 0;
if ((int)tile.size() > 0) if ((int)tile.size() > 0)
{ {
int i = 0;
do do
{ {
h_line_t line; LineHorizontal line;
line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_; line.x1 = (tile[i] % MAP_WIDTH_) * TILE_SIZE_;
line.y = (tile[i] / MAP_WIDTH_) * TILE_SIZE_; line.y = (tile[i] / MAP_WIDTH_) * TILE_SIZE_;
lastOne = i; int last_one = i;
i++; i++;
if (i <= (int)tile.size() - 1) if (i <= (int)tile.size() - 1)
{ {
while (tile[i] == tile[i - 1] + 1) while (tile[i] == tile[i - 1] + 1)
{ {
lastOne = i; last_one = i;
if (i == (int)tile.size() - 1) if (i == (int)tile.size() - 1)
{ {
break; break;
@@ -1249,7 +1159,7 @@ void Room::setAutoSurfaces()
} }
} }
line.x2 = ((tile[lastOne] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1; line.x2 = ((tile[last_one] % MAP_WIDTH_) * TILE_SIZE_) + TILE_SIZE_ - 1;
auto_surfaces_.push_back(line); auto_surfaces_.push_back(line);
if (i <= (int)tile.size() - 1) if (i <= (int)tile.size() - 1)
{ {
@@ -1268,7 +1178,7 @@ void Room::setAnimatedTiles()
// Recorre la habitación entera por filas buscando tiles de tipo t_animated // Recorre la habitación entera por filas buscando tiles de tipo t_animated
for (int i = 0; i < (int)tile_map_.size(); ++i) for (int i = 0; i < (int)tile_map_.size(); ++i)
{ {
if (getTile(i) == t_animated) if (getTile(i) == TileType::ANIMATED)
{ {
// La i es la ubicación // La i es la ubicación
const int x = (i % MAP_WIDTH_) * TILE_SIZE_; const int x = (i % MAP_WIDTH_) * TILE_SIZE_;
@@ -1278,7 +1188,7 @@ void Room::setAnimatedTiles()
const int xc = (tile_map_[i] % tile_set_width_) * TILE_SIZE_; const int xc = (tile_map_[i] % tile_set_width_) * TILE_SIZE_;
const int yc = (tile_map_[i] / tile_set_width_) * TILE_SIZE_; const int yc = (tile_map_[i] / tile_set_width_) * TILE_SIZE_;
aTile_t at; AnimatedTile at;
at.sprite = std::make_shared<Sprite>(texture_, x, y, 8, 8); at.sprite = std::make_shared<Sprite>(texture_, x, y, 8, 8);
at.sprite->setClip(xc, yc, 8, 8); at.sprite->setClip(xc, yc, 8, 8);
at.x_orig = xc; at.x_orig = xc;
@@ -1312,7 +1222,7 @@ void Room::updateAnimatedTiles()
// Pinta los tiles animados en pantalla // Pinta los tiles animados en pantalla
void Room::renderAnimatedTiles() void Room::renderAnimatedTiles()
{ {
for (auto a : animated_tiles_) for (const auto &a : animated_tiles_)
{ {
a.sprite->render(); a.sprite->render();
} }
@@ -1321,7 +1231,7 @@ void Room::renderAnimatedTiles()
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkRightSurfaces(SDL_Rect *rect) int Room::checkRightSurfaces(SDL_Rect *rect)
{ {
for (auto s : right_surfaces_) for (const auto &s : right_surfaces_)
{ {
if (checkCollision(s, *rect)) if (checkCollision(s, *rect))
{ {
@@ -1335,7 +1245,7 @@ int Room::checkRightSurfaces(SDL_Rect *rect)
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkLeftSurfaces(SDL_Rect *rect) int Room::checkLeftSurfaces(SDL_Rect *rect)
{ {
for (auto s : left_surfaces_) for (const auto &s : left_surfaces_)
{ {
if (checkCollision(s, *rect)) if (checkCollision(s, *rect))
{ {
@@ -1349,7 +1259,7 @@ int Room::checkLeftSurfaces(SDL_Rect *rect)
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkTopSurfaces(SDL_Rect *rect) int Room::checkTopSurfaces(SDL_Rect *rect)
{ {
for (auto s : top_surfaces_) for (const auto &s : top_surfaces_)
{ {
if (checkCollision(s, *rect)) if (checkCollision(s, *rect))
{ {
@@ -1363,7 +1273,7 @@ int Room::checkTopSurfaces(SDL_Rect *rect)
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkBottomSurfaces(SDL_Rect *rect) int Room::checkBottomSurfaces(SDL_Rect *rect)
{ {
for (auto s : bottom_surfaces_) for (const auto &s : bottom_surfaces_)
{ {
if (checkCollision(s, *rect)) if (checkCollision(s, *rect))
{ {
@@ -1377,7 +1287,7 @@ int Room::checkBottomSurfaces(SDL_Rect *rect)
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkAutoSurfaces(SDL_Rect *rect) int Room::checkAutoSurfaces(SDL_Rect *rect)
{ {
for (auto s : auto_surfaces_) for (const auto &s : auto_surfaces_)
{ {
if (checkCollision(s, *rect)) if (checkCollision(s, *rect))
{ {
@@ -1391,7 +1301,7 @@ int Room::checkAutoSurfaces(SDL_Rect *rect)
// Comprueba las colisiones // Comprueba las colisiones
bool Room::checkTopSurfaces(SDL_Point *p) bool Room::checkTopSurfaces(SDL_Point *p)
{ {
for (auto s : top_surfaces_) for (const auto &s : top_surfaces_)
{ {
if (checkCollision(s, *p)) if (checkCollision(s, *p))
{ {
@@ -1405,7 +1315,7 @@ bool Room::checkTopSurfaces(SDL_Point *p)
// Comprueba las colisiones // Comprueba las colisiones
bool Room::checkAutoSurfaces(SDL_Point *p) bool Room::checkAutoSurfaces(SDL_Point *p)
{ {
for (auto s : auto_surfaces_) for (const auto &s : auto_surfaces_)
{ {
if (checkCollision(s, *p)) if (checkCollision(s, *p))
{ {
@@ -1417,11 +1327,11 @@ bool Room::checkAutoSurfaces(SDL_Point *p)
} }
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkLeftSlopes(v_line_t *line) int Room::checkLeftSlopes(const LineVertical *line)
{ {
for (auto s : left_slopes_) for (const auto &slope : left_slopes_)
{ {
const SDL_Point p = checkCollision(s, *line); const SDL_Point p = checkCollision(slope, *line);
if (p.x != -1) if (p.x != -1)
{ {
return p.y; return p.y;
@@ -1434,9 +1344,9 @@ int Room::checkLeftSlopes(v_line_t *line)
// Comprueba las colisiones // Comprueba las colisiones
bool Room::checkLeftSlopes(SDL_Point *p) bool Room::checkLeftSlopes(SDL_Point *p)
{ {
for (auto s : left_slopes_) for (const auto &slope : left_slopes_)
{ {
if (checkCollision(*p, s)) if (checkCollision(*p, slope))
{ {
return true; return true;
} }
@@ -1446,11 +1356,11 @@ bool Room::checkLeftSlopes(SDL_Point *p)
} }
// Comprueba las colisiones // Comprueba las colisiones
int Room::checkRightSlopes(v_line_t *line) int Room::checkRightSlopes(const LineVertical *line)
{ {
for (auto s : right_slopes_) for (const auto &slope : right_slopes_)
{ {
const SDL_Point p = checkCollision(s, *line); const SDL_Point p = checkCollision(slope, *line);
if (p.x != -1) if (p.x != -1)
{ {
return p.y; return p.y;
@@ -1463,9 +1373,9 @@ int Room::checkRightSlopes(v_line_t *line)
// Comprueba las colisiones // Comprueba las colisiones
bool Room::checkRightSlopes(SDL_Point *p) bool Room::checkRightSlopes(SDL_Point *p)
{ {
for (auto s : right_slopes_) for (const auto &slope : right_slopes_)
{ {
if (checkCollision(*p, s)) if (checkCollision(*p, slope))
{ {
return true; return true;
} }
@@ -1474,36 +1384,39 @@ bool Room::checkRightSlopes(SDL_Point *p)
return false; return false;
} }
// Pone el mapa en modo pausa // Abre la Jail si se da el caso
void Room::pause()
{
paused_ = true;
}
// Quita el modo pausa del mapa
void Room::resume()
{
paused_ = false;
}
// Obten la direccion de las superficies automaticas
int Room::getAutoSurfaceDirection()
{
return auto_surface_direction_;
}
// Abre la jail para poder entrar
void Room::openTheJail() void Room::openTheJail()
{ {
if (name_ == "THE JAIL") if (data_->jail_is_open && name_ == "THE JAIL")
{ {
// Elimina el último enemigo (Bry debe ser el ultimo enemigo definido en el fichero) // Elimina el último enemigo (Bry debe ser el último enemigo definido en el fichero)
enemies_.pop_back(); if (!enemies_.empty())
{
enemies_.pop_back();
}
// Abre las puertas // Abre las puertas
const int tileA = 16 + (13 * 32); constexpr int TILE_A = 16 + (13 * 32);
const int tileB = 16 + (14 * 32); constexpr int TILE_B = 16 + (14 * 32);
tile_map_[tileA] = -1; if (TILE_A < tile_map_.size())
tile_map_[tileB] = -1; {
tile_map_[TILE_A] = -1;
}
if (TILE_B < tile_map_.size())
{
tile_map_[TILE_B] = -1;
}
} }
}
// Inicializa las superficies de colision
void Room::initRoomSurfaces()
{
setBottomSurfaces();
setTopSurfaces();
setLeftSurfaces();
setRightSurfaces();
setLeftSlopes();
setRightSlopes();
setAutoSurfaces();
} }

View File

@@ -1,34 +1,33 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Texture
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "enemy.h" // for EnemyData #include "enemy.h" // for EnemyData
#include "item.h" // for item_t #include "item.h" // for ItemData
#include "utils.h" // for Color #include "options.h" // for Options, OptionsVideo, options
#include "scoreboard.h" #include "utils.h" // for stringToColor, Color
class Asset; // lines 12-12 class Sprite; // lines 17-17
class Debug; // lines 13-13 class Texture; // lines 18-18
class ItemTracker; struct JA_Sound_t; // lines 19-19
class Screen; // lines 14-14 struct ScoreboardData; // lines 20-20
class Sprite; // lines 15-15
class Texture; // lines 16-16
struct JA_Sound_t; // lines 17-17
enum tile_e
enum class TileType
{ {
t_empty, EMPTY,
t_wall, WALL,
t_passable, PASSABLE,
t_slope_l, SLOPE_L,
t_slope_r, SLOPE_R,
t_kill, KILL,
t_animated ANIMATED
}; };
struct aTile_t struct AnimatedTile
{ {
std::shared_ptr<Sprite> sprite; // Sprite para dibujar el tile std::shared_ptr<Sprite> sprite; // Sprite para dibujar el tile
int x_orig; // Poicion X donde se encuentra el primer tile de la animacion en la tilesheet int x_orig; // Poicion X donde se encuentra el primer tile de la animacion en la tilesheet
@@ -48,8 +47,8 @@ struct RoomData
std::string room_right; // Identificador de la habitación que se encuentra a la derecha std::string room_right; // Identificador de la habitación que se encuentra a la derecha
std::string tile_set_file; // Imagen con los graficos para la habitación std::string tile_set_file; // Imagen con los graficos para la habitación
std::string tile_map_file; // Fichero con el mapa de indices de tile std::string tile_map_file; // Fichero con el mapa de indices de tile
std::vector<int> tile_map; // Indice de los tiles a dibujar en la habitación
int auto_surface_direction; // Sentido en el que arrastran las superficies automáticas de la habitación int auto_surface_direction; // Sentido en el que arrastran las superficies automáticas de la habitación
std::vector<int> tile_map; // Indice de los tiles a dibujar en la habitación
std::vector<EnemyData> enemies; // Listado con los enemigos de la habitación std::vector<EnemyData> enemies; // Listado con los enemigos de la habitación
std::vector<ItemData> items; // Listado con los items que hay en la habitación std::vector<ItemData> items; // Listado con los items que hay en la habitación
}; };
@@ -78,10 +77,6 @@ private:
static constexpr int MAP_HEIGHT_ = 16; // Alto del mapa en tiles static constexpr int MAP_HEIGHT_ = 16; // Alto del mapa en tiles
// Objetos y punteros // Objetos y punteros
Screen *screen_; // Objeto encargado de dibujar en pantalla
SDL_Renderer *renderer_; // El renderizador de la ventana
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
Debug *debug_; // Objeto para gestionar la información de debug
std::vector<std::shared_ptr<Enemy>> enemies_; // Listado con los enemigos de la habitación std::vector<std::shared_ptr<Enemy>> enemies_; // Listado con los enemigos de la habitación
std::vector<std::shared_ptr<Item>> items_; // Listado con los items que hay en la habitación std::vector<std::shared_ptr<Item>> items_; // Listado con los items que hay en la habitación
std::shared_ptr<Texture> texture_; // Textura con los graficos de la habitación std::shared_ptr<Texture> texture_; // Textura con los graficos de la habitación
@@ -89,32 +84,34 @@ private:
std::shared_ptr<ScoreboardData> data_; // Puntero a los datos del marcador std::shared_ptr<ScoreboardData> data_; // Puntero a los datos del marcador
// Variables // Variables
std::string number_; // Numero de la habitación std::string number_; // Numero de la habitación
std::string name_; // Nombre de la habitación std::string name_; // Nombre de la habitación
std::string bg_color_; // Color de fondo de la habitación std::string bg_color_; // Color de fondo de la habitación
std::string border_color_; // Color del borde de la pantalla std::string border_color_; // Color del borde de la pantalla
std::string item_color1_; // Color 1 para los items de la habitación std::string item_color1_; // Color 1 para los items de la habitación
std::string item_color2_; // Color 2 para los items de la habitación std::string item_color2_; // Color 2 para los items de la habitación
std::string room_top_; // Identificador de la habitación que se encuentra arriba std::string room_top_; // Identificador de la habitación que se encuentra arriba
std::string room_bottom_; // Identificador de la habitación que se encuentra abajp std::string room_bottom_; // 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_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 room_right_; // Identificador de la habitación que se encuentra a la derecha
std::string tile_set_file_; // Imagen con los graficos para la habitación std::string tile_set_file_; // Imagen con los graficos para la habitación
std::string tile_map_file_; // Fichero con el mapa de indices de tile std::string tile_map_file_; // Fichero con el mapa de indices de tile
std::vector<int> tile_map_; // Indice de los tiles a dibujar en la habitación std::vector<int> tile_map_; // Indice de los tiles a dibujar en la habitación
int auto_surface_direction_; // Sentido en el que arrastran las superficies automáticas de la habitación int auto_surface_direction_; // Sentido en el que arrastran las superficies automáticas de la habitación
JA_Sound_t *item_sound_; // Sonido producido al coger un objeto JA_Sound_t *item_sound_; // Sonido producido al coger un objeto
std::vector<h_line_t> bottom_surfaces_; // Lista con las superficies inferiores de la habitación std::vector<LineHorizontal> bottom_surfaces_; // Lista con las superficies inferiores de la habitación
std::vector<h_line_t> top_surfaces_; // Lista con las superficies superiores de la habitación std::vector<LineHorizontal> top_surfaces_; // Lista con las superficies superiores de la habitación
std::vector<v_line_t> left_surfaces_; // Lista con las superficies laterales de la parte izquierda de la habitación std::vector<LineVertical> left_surfaces_; // Lista con las superficies laterales de la parte izquierda de la habitación
std::vector<v_line_t> right_surfaces_; // Lista con las superficies laterales de la parte derecha de la habitación std::vector<LineVertical> right_surfaces_; // Lista con las superficies laterales de la parte derecha de la habitación
std::vector<d_line_t> left_slopes_; // Lista con todas las rampas que suben hacia la izquierda std::vector<LineDiagonal> left_slopes_; // Lista con todas las rampas que suben hacia la izquierda
std::vector<d_line_t> right_slopes_; // Lista con todas las rampas que suben hacia la derecha std::vector<LineDiagonal> right_slopes_; // Lista con todas las rampas que suben hacia la derecha
int counter_; // Contador para lo que haga falta int counter_; // Contador para lo que haga falta
bool paused_; // Indica si el mapa esta en modo pausa bool is_paused_; // Indica si el mapa esta en modo pausa
std::vector<aTile_t> animated_tiles_; // Vector con los indices de tiles animados std::vector<AnimatedTile> animated_tiles_; // Vector con los indices de tiles animados
std::vector<h_line_t> auto_surfaces_; // Lista con las superficies automaticas de la habitación std::vector<LineHorizontal> auto_surfaces_; // Lista con las superficies automaticas de la habitación
int tile_set_width_; // Ancho del tileset en tiles int tile_set_width_; // Ancho del tileset en tiles
void initializeRoom(const RoomData &room);
// Pinta el mapa de la habitación en la textura // Pinta el mapa de la habitación en la textura
void fillMapTexture(); void fillMapTexture();
@@ -150,26 +147,29 @@ private:
void renderAnimatedTiles(); void renderAnimatedTiles();
// Devuelve el tipo de tile que hay en ese indice // Devuelve el tipo de tile que hay en ese indice
tile_e getTile(int index); TileType getTile(int index);
// Abre la jail para poder entrar // Abre la jail para poder entrar
void openTheJail(); void openTheJail();
// Inicializa las superficies de colision
void initRoomSurfaces();
public: public:
// Constructor // Constructor
Room(std::shared_ptr<RoomData> room, std::shared_ptr<ScoreboardData> data); Room(const std::string &room_path, std::shared_ptr<ScoreboardData> data);
// Destructor // Destructor
~Room(); ~Room();
// Devuelve el nombre de la habitación // Devuelve el nombre de la habitación
std::string getName(); std::string getName() const { return name_; }
// Devuelve el color de la habitación // Devuelve el color de la habitación
Color getBGColor(); Color getBGColor() const { return stringToColor(options.video.palette, bg_color_); }
// Devuelve el color del borde // Devuelve el color del borde
Color getBorderColor(); Color getBorderColor() const { return stringToColor(options.video.palette, border_color_); }
// Dibuja el mapa en pantalla // Dibuja el mapa en pantalla
void renderMap(); void renderMap();
@@ -187,7 +187,7 @@ public:
std::string getRoom(int border); std::string getRoom(int border);
// Devuelve el tipo de tile que hay en ese pixel // Devuelve el tipo de tile que hay en ese pixel
tile_e getTile(SDL_Point point); TileType getTile(SDL_Point point);
// Indica si hay colision con un enemigo a partir de un rectangulo // Indica si hay colision con un enemigo a partir de un rectangulo
bool enemyCollision(SDL_Rect &rect); bool enemyCollision(SDL_Rect &rect);
@@ -195,17 +195,11 @@ public:
// Indica si hay colision con un objeto a partir de un rectangulo // Indica si hay colision con un objeto a partir de un rectangulo
bool itemCollision(SDL_Rect &rect); bool itemCollision(SDL_Rect &rect);
// Recarga la textura
void reLoadTexture();
// Recarga la paleta
void reLoadPalette();
// Obten el tamaño del tile // Obten el tamaño del tile
int getTileSize(); int getTileSize() const { return TILE_SIZE_; }
// Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile // Obten la coordenada de la cuesta a partir de un punto perteneciente a ese tile
int getSlopeHeight(SDL_Point p, tile_e slope); int getSlopeHeight(SDL_Point p, TileType slope);
// Comprueba las colisiones // Comprueba las colisiones
int checkRightSurfaces(SDL_Rect *rect); int checkRightSurfaces(SDL_Rect *rect);
@@ -229,23 +223,20 @@ public:
bool checkAutoSurfaces(SDL_Point *p); bool checkAutoSurfaces(SDL_Point *p);
// Comprueba las colisiones // Comprueba las colisiones
int checkLeftSlopes(v_line_t *line); int checkLeftSlopes(const LineVertical *line);
// Comprueba las colisiones // Comprueba las colisiones
bool checkLeftSlopes(SDL_Point *p); bool checkLeftSlopes(SDL_Point *p);
// Comprueba las colisiones // Comprueba las colisiones
int checkRightSlopes(v_line_t *line); int checkRightSlopes(const LineVertical *line);
// Comprueba las colisiones // Comprueba las colisiones
bool checkRightSlopes(SDL_Point *p); bool checkRightSlopes(SDL_Point *p);
// Pone el mapa en modo pausa // Pone el mapa en modo pausa
void pause(); void setPaused(bool value) { is_paused_ = value; };
// Quita el modo pausa del mapa
void resume();
// Obten la direccion de las superficies automaticas // Obten la direccion de las superficies automaticas
int getAutoSurfaceDirection(); int getAutoSurfaceDirection() const { return auto_surface_direction_; }
}; };

View File

@@ -1,20 +1,9 @@
#include "room_tracker.h" #include "room_tracker.h"
// Constructor
RoomTracker::RoomTracker()
{
}
// Destructor
RoomTracker::~RoomTracker()
{
list.clear();
}
// Comprueba si la habitación ya ha sido visitada // Comprueba si la habitación ya ha sido visitada
bool RoomTracker::hasBeenVisited(std::string name) bool RoomTracker::hasBeenVisited(const std::string &name)
{ {
for (auto l : list) for (const auto &l : list)
{ {
if (l == name) if (l == name)
{ {
@@ -26,7 +15,7 @@ bool RoomTracker::hasBeenVisited(std::string name)
} }
// Añade la habitación a la lista // Añade la habitación a la lista
bool RoomTracker::addRoom(std::string name) bool RoomTracker::addRoom(const std::string &name)
{ {
// Comprueba si la habitación ya ha sido visitada // Comprueba si la habitación ya ha sido visitada
if (!hasBeenVisited(name)) if (!hasBeenVisited(name))

View File

@@ -10,15 +10,15 @@ private:
std::vector<std::string> list; // Lista con las habitaciones visitadas std::vector<std::string> list; // Lista con las habitaciones visitadas
// Comprueba si la habitación ya ha sido visitada // Comprueba si la habitación ya ha sido visitada
bool hasBeenVisited(std::string name); bool hasBeenVisited(const std::string &name);
public: public:
// Constructor // Constructor
RoomTracker(); RoomTracker() = default;
// Destructor // Destructor
~RoomTracker(); ~RoomTracker() = default;
// Añade la habitación a la lista // Añade la habitación a la lista
bool addRoom(std::string name); bool addRoom(const std::string &name);
}; };

View File

@@ -1,42 +1,33 @@
#include "scoreboard.h" #include "scoreboard.h"
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_timer.h> // for SDL_GetTicks #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888
#include "animated_sprite.h" // for AnimatedSprite #include <SDL2/SDL_rect.h> // for SDL_Rect
#include "asset.h" // for Asset #include <SDL2/SDL_timer.h> // for SDL_GetTicks
#include "defines.h" // for BLOCK, GAMECANVAS_HEIGHT, PLAY_AREA_HEIGHT #include <iostream> // for basic_ostream, operator<<, cout, endl
#include "options.h" // for Options, options, OptionsVideo, Cheat #include "animated_sprite.h" // for AnimatedSprite
#include "resource.h" // for Resource #include "defines.h" // for BLOCK
#include "screen.h" // for Screen #include "options.h" // for Options, options, OptionsVideo, Cheat
#include "text.h" // for Text #include "resource.h" // for Resource
#include "texture.h" // for Texture #include "screen.h" // for Screen
#include <iostream> #include "text.h" // for Text
#include "texture.h" // for Texture
// Constructor // Constructor
Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data) Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
: renderer_(Screen::get()->getRenderer()), : data_(data),
resource_(Resource::get()), clock_(ClockData())
asset_(Asset::get()),
data_(data)
{ {
const int TEXTURE_WIDTH_ = options.game.width; const int TEXTURE_WIDTH_ = options.game.width;
constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK; constexpr int TEXTURE_HEIGHT_ = 6 * BLOCK;
// Reserva memoria para los objetos // Reserva memoria para los objetos
item_texture_ = resource_->getTexture("items.png"); item_texture_ = Resource::get()->getTexture("items.png");
auto player_texture = resource_->getTexture(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png"); auto player_texture = Resource::get()->getTexture(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.png" : "player.png");
auto player_animations = resource_->getAnimations(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani"); auto player_animations = Resource::get()->getAnimations(options.cheats.alternate_skin == Cheat::CheatState::ENABLED ? "player2.ani" : "player.ani");
player_sprite_ = std::make_shared<AnimatedSprite>(player_texture, player_animations); player_sprite_ = std::make_shared<AnimatedSprite>(player_texture, player_animations);
player_sprite_->setCurrentAnimation("walk_menu"); player_sprite_->setCurrentAnimation("walk_menu");
text_ = resource_->getText("smb2");
texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, TEXTURE_WIDTH_, TEXTURE_HEIGHT_); texture_ = createTexture(Screen::get()->getRenderer(), TEXTURE_WIDTH_, TEXTURE_HEIGHT_);
if (texture_ == nullptr)
{
if (options.console)
{
std::cout << "Scorebard::texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
texture_dest_ = {0, options.game.height - TEXTURE_HEIGHT_, TEXTURE_WIDTH_, TEXTURE_HEIGHT_}; texture_dest_ = {0, options.game.height - TEXTURE_HEIGHT_, TEXTURE_WIDTH_, TEXTURE_HEIGHT_};
// Inicializa las variables // Inicializa las variables
@@ -48,10 +39,10 @@ Scoreboard::Scoreboard(std::shared_ptr<ScoreboardData> data)
items_color_ = stringToColor(options.video.palette, "white"); items_color_ = stringToColor(options.video.palette, "white");
// Inicializa el vector de colores // Inicializa el vector de colores
const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"}; const std::vector<std::string> COLORS = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
for (auto v : vColors) for (const auto &color : COLORS)
{ {
color_.push_back(stringToColor(options.video.palette, v)); color_.push_back(stringToColor(options.video.palette, color));
} }
} }
@@ -64,7 +55,7 @@ Scoreboard::~Scoreboard()
// Pinta el objeto en pantalla // Pinta el objeto en pantalla
void Scoreboard::render() void Scoreboard::render()
{ {
SDL_RenderCopy(renderer_, texture_, nullptr, &texture_dest_); SDL_RenderCopy(Screen::get()->getRenderer(), texture_, nullptr, &texture_dest_);
} }
// Actualiza las variables del objeto // Actualiza las variables del objeto
@@ -100,39 +91,27 @@ Scoreboard::ClockData Scoreboard::getTime()
return time; return time;
} }
// Recarga la textura
void Scoreboard::reLoadTexture()
{
player_sprite_->getTexture()->reLoad();
// playerTexture->reLoad();
item_texture_->reLoad();
text_->reLoadTexture();
}
// Recarga la paleta
void Scoreboard::reLoadPalette()
{
// Reinicia el vector de colores
const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
color_.clear();
for (auto v : vColors)
{
color_.push_back(stringToColor(options.video.palette, v));
}
}
// Pone el marcador en modo pausa // Pone el marcador en modo pausa
void Scoreboard::pause() void Scoreboard::setPaused(bool value)
{ {
is_paused_ = true; if (is_paused_ == value)
paused_time_ = SDL_GetTicks(); {
} // Evita ejecutar lógica si el estado no cambia
return;
}
// Quita el modo pausa del marcador is_paused_ = value;
void Scoreboard::resume()
{ if (is_paused_)
is_paused_ = false; {
paused_time_elapsed_ += SDL_GetTicks() - paused_time_; // Guarda el tiempo actual al pausar
paused_time_ = SDL_GetTicks();
}
else
{
// Calcula el tiempo pausado acumulado al reanudar
paused_time_elapsed_ += SDL_GetTicks() - paused_time_;
}
} }
// Actualiza el color de la cantidad de items recogidos // Actualiza el color de la cantidad de items recogidos
@@ -163,12 +142,12 @@ int Scoreboard::getMinutes()
void Scoreboard::fillTexture() void Scoreboard::fillTexture()
{ {
// Empieza a dibujar en la textura // Empieza a dibujar en la textura
auto temp = SDL_GetRenderTarget(renderer_); auto temp = SDL_GetRenderTarget(Screen::get()->getRenderer());
SDL_SetRenderTarget(renderer_, texture_); SDL_SetRenderTarget(Screen::get()->getRenderer(), texture_);
// Limpia la textura // Limpia la textura
SDL_SetRenderDrawColor(renderer_, 0, 0, 0, 255); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 255);
SDL_RenderFillRect(renderer_, nullptr); SDL_RenderFillRect(Screen::get()->getRenderer(), nullptr);
// Anclas // Anclas
constexpr int LINE1 = BLOCK; constexpr int LINE1 = BLOCK;
@@ -197,17 +176,18 @@ void Scoreboard::fillTexture()
} }
// Escribe los textos // Escribe los textos
const std::string timeTxt = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10); auto text = Resource::get()->getText("smb2");
const std::string itemsTxt = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10); const std::string TIME_TEXT = std::to_string((clock_.minutes % 100) / 10) + std::to_string(clock_.minutes % 10) + clock_.separator + std::to_string((clock_.seconds % 60) / 10) + std::to_string(clock_.seconds % 10);
text_->writeColored(BLOCK, LINE1, "Items collected ", data_->color); const std::string ITEMS_TEXT = std::to_string(data_->items / 100) + std::to_string((data_->items % 100) / 10) + std::to_string(data_->items % 10);
text_->writeColored(17 * BLOCK, LINE1, itemsTxt, items_color_); text->writeColored(BLOCK, LINE1, "Items collected ", data_->color);
text_->writeColored(20 * BLOCK, LINE1, " Time ", data_->color); text->writeColored(17 * BLOCK, LINE1, ITEMS_TEXT, items_color_);
text_->writeColored(26 * BLOCK, LINE1, timeTxt, stringToColor(options.video.palette, "white")); text->writeColored(20 * BLOCK, LINE1, " Time ", data_->color);
text->writeColored(26 * BLOCK, LINE1, TIME_TEXT, stringToColor(options.video.palette, "white"));
const std::string roomsTxt = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10); const std::string ROOMS_TEXT = std::to_string(data_->rooms / 100) + std::to_string((data_->rooms % 100) / 10) + std::to_string(data_->rooms % 10);
text_->writeColored(22 * BLOCK, LINE2, "Rooms", stringToColor(options.video.palette, "white")); text->writeColored(22 * BLOCK, LINE2, "Rooms", stringToColor(options.video.palette, "white"));
text_->writeColored(28 * BLOCK, LINE2, roomsTxt, stringToColor(options.video.palette, "white")); text->writeColored(28 * BLOCK, LINE2, ROOMS_TEXT, stringToColor(options.video.palette, "white"));
// Deja el renderizador como estaba // Deja el renderizador como estaba
SDL_SetRenderTarget(renderer_, temp); SDL_SetRenderTarget(Screen::get()->getRenderer(), temp);
} }

View File

@@ -1,30 +1,32 @@
#pragma once #pragma once
#include <SDL2/SDL_render.h> // Para SDL_Renderer #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_stdinc.h> // Para Uint32 #include <SDL2/SDL_render.h> // for SDL_Texture
#include <string> // Para basic_string, string #include <SDL2/SDL_stdinc.h> // for Uint32
#include <vector> // Para vector #include <memory> // for shared_ptr
#include "utils.h" // Para color_t #include <string> // for string, basic_string
#include <memory> // Para shared_ptr #include <vector> // for vector
class AnimatedSprite; #include "utils.h" // for Color
class Asset; class AnimatedSprite; // lines 9-9
class Resource; class Texture; // lines 13-13
class Text;
class Texture;
struct ScoreboardData struct ScoreboardData
{ {
int items; // Lleva la cuenta de los objetos recogidos int items; // Lleva la cuenta de los objetos recogidos
int lives; // Lleva la cuenta de ls vidas restantes del jugador int lives; // Lleva la cuenta de las vidas restantes del jugador
int rooms; // Lleva la cuenta de las habitaciones visitadas int rooms; // Lleva la cuenta de las habitaciones visitadas
bool music; // Indica si ha de sonar la musica durante el juego bool music; // Indica si ha de sonar la música durante el juego
Color color; // Color para escribir el texto del marcador Color color; // Color para escribir el texto del marcador
Uint32 ini_clock; // Tiempo inicial para calcular el tiempo transcurrido Uint32 ini_clock; // Tiempo inicial para calcular el tiempo transcurrido
bool jail_is_open; // Indica si se puede entrar a la Jail bool jail_is_open; // Indica si se puede entrar a la Jail
// Constructor // Constructor por defecto
ScoreboardData() ScoreboardData()
: items(0), lives(3), rooms(0), music(true), color({0, 0, 0}), ini_clock(0), jail_is_open(false) {} : items(0), lives(0), rooms(0), music(true), color({0, 0, 0}), ini_clock(0), jail_is_open(false) {}
// Constructor parametrizado
ScoreboardData(int items, int lives, int rooms, bool music, Color color, Uint32 ini_clock, bool jail_is_open)
: items(items), lives(lives), rooms(rooms), music(music), color(color), ini_clock(ini_clock), jail_is_open(jail_is_open) {}
}; };
class Scoreboard class Scoreboard
@@ -36,13 +38,17 @@ private:
int minutes; int minutes;
int seconds; int seconds;
std::string separator; std::string separator;
// Constructor por defecto
ClockData()
: hours(0), minutes(0), seconds(0), separator(":") {}
// Constructor parametrizado
ClockData(int h, int m, int s, const std::string &sep)
: hours(h), minutes(m), seconds(s), separator(sep) {}
}; };
// Objetos y punteros // Objetos y punteros
SDL_Renderer *renderer_; // El renderizador de la ventana
Resource *resource_; // Objeto con los recursos
Asset *asset_; // Objeto con la ruta a todos los ficheros de recursos
std::shared_ptr<Text> text_; // Objeto para escribir texto
std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite para mostrar las vidas en el marcador std::shared_ptr<AnimatedSprite> player_sprite_; // Sprite para mostrar las vidas en el marcador
std::shared_ptr<Texture> item_texture_; // Textura con los graficos para las vidas std::shared_ptr<Texture> item_texture_; // Textura con los graficos para las vidas
std::shared_ptr<ScoreboardData> data_; // Contiene las variables a mostrar en el marcador std::shared_ptr<ScoreboardData> data_; // Contiene las variables a mostrar en el marcador
@@ -70,7 +76,7 @@ private:
public: public:
// Constructor // Constructor
Scoreboard(std::shared_ptr<ScoreboardData> data); explicit Scoreboard(std::shared_ptr<ScoreboardData> data);
// Destructor // Destructor
~Scoreboard(); ~Scoreboard();
@@ -81,17 +87,8 @@ public:
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); void update();
// Recarga la textura
void reLoadTexture();
// Recarga la paleta
void reLoadPalette();
// Pone el marcador en modo pausa // Pone el marcador en modo pausa
void pause(); void setPaused(bool value);
// Quita el modo pausa del marcador
void resume();
// Devuelve la cantidad de minutos de juego transcurridos // Devuelve la cantidad de minutos de juego transcurridos
int getMinutes(); int getMinutes();

View File

@@ -13,7 +13,7 @@
#include "notifier.h" // Para Notify #include "notifier.h" // Para Notify
#include "options.h" #include "options.h"
#include "mouse.h" #include "mouse.h"
//#include "surface.h" // #include "surface.h"
// [SINGLETON] // [SINGLETON]
Screen *Screen::screen_ = nullptr; Screen *Screen::screen_ = nullptr;
@@ -52,41 +52,15 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE); SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
// Crea la textura donde se vuelcan las surfaces // Crea la textura donde se vuelcan las surfaces
surface_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height); surface_texture_ = createTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height);
if (surface_texture_ == nullptr)
{
if (options.console)
{
std::cout << "surface_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
//SDL_SetTextureBlendMode(surface_texture_, SDL_BLENDMODE_BLEND);
// Crea la textura donde se dibujan los graficos del juego // Crea la textura donde se dibujan los graficos del juego
game_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height); game_texture_ = createTexture(renderer, options.game.width, options.game.height);
if (game_texture_ == nullptr)
{
if (options.console)
{
std::cout << "game_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Crea la textura donde se dibuja el borde que rodea el area de juego // Crea la textura donde se dibuja el borde que rodea el area de juego
border_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); border_texture_ = createTexture(renderer, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2);
if (border_texture_ == nullptr)
{
if (options.console)
{
std::cout << "border_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
setBorderColor(border_color_); setBorderColor(border_color_);
// Crea la surface donde se pinta el juego
//surface_ = std::make_shared<Surface>(nullptr, options.game.width, options.game.height);
//surface_->loadPalette(Asset::get()->get("test.gif"));
// Establece el modo de video // Establece el modo de video
setVideoMode(options.video.mode); setVideoMode(options.video.mode);
@@ -111,17 +85,10 @@ void Screen::clean(Color color)
} }
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void Screen::start() void Screen::start() { SDL_SetRenderTarget(renderer_, game_texture_); }
{
//surface_->clear(surface_->getSurface(), surface_->getTransparentColor());
SDL_SetRenderTarget(renderer_, game_texture_);
}
// Prepara para empezar a dibujar en la textura del borde // Prepara para empezar a dibujar en la textura del borde
void Screen::startDrawOnBorder() void Screen::startDrawOnBorder() { SDL_SetRenderTarget(renderer_, border_texture_); }
{
SDL_SetRenderTarget(renderer_, border_texture_);
}
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::render() void Screen::render()
@@ -129,10 +96,6 @@ void Screen::render()
// Renderiza sobre gameCanvas los overlays // Renderiza sobre gameCanvas los overlays
renderNotifications(); renderNotifications();
//fillTextureWithColor(renderer_, surface_texture_, 0xFF, 0x00, 0xFF, 0xFF);
//surface_->copyToTexture(renderer_, surface_texture_);
//SDL_RenderCopy(renderer_, surface_texture_, nullptr, nullptr);
// Si está el borde activo, vuelca gameCanvas sobre borderCanvas // Si está el borde activo, vuelca gameCanvas sobre borderCanvas
if (options.video.border.enabled) if (options.video.border.enabled)
{ {
@@ -157,52 +120,22 @@ void Screen::renderWithoutNotifier()
} }
// Establece el modo de video // Establece el modo de video
void Screen::setVideoMode(int videoMode) void Screen::setVideoMode(int video_mode)
{ {
// Aplica el modo de video
// Modo ventana
if (videoMode == 0)
{
// Muestra el puntero
SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowFullscreen(window_, videoMode);
adjustWindowSize();
adjustGameCanvasRect();
adjustRenderLogicalSize();
}
// Modo pantalla completa
else
{
// Oculta el puntero
SDL_ShowCursor(SDL_DISABLE);
adjustWindowSize();
adjustGameCanvasRect();
SDL_SetWindowFullscreen(window_, videoMode);
}
// Actualiza las opciones // Actualiza las opciones
options.video.mode = videoMode; options.video.mode = video_mode;
// Mostrar u ocultar el cursor según el modo
SDL_ShowCursor(options.video.mode == 0 ? SDL_ENABLE : SDL_DISABLE);
// Configura el modo de pantalla y ajusta la ventana
SDL_SetWindowFullscreen(window_, options.video.mode);
adjustWindowSize();
adjustGameCanvasRect();
adjustRenderLogicalSize();
// Reinicia los shaders // Reinicia los shaders
if (options.video.shaders) resetShaders();
{
const std::string glsl_file = 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<char>(f)), std::istreambuf_iterator<char>());
if (options.video.border.enabled)
{
shader::init(window_, border_texture_, source.c_str());
}
else
{
shader::init(window_, game_texture_, source.c_str());
}
}
} }
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
@@ -217,13 +150,13 @@ bool Screen::decWindowZoom()
{ {
if (options.video.mode == 0) if (options.video.mode == 0)
{ {
int previous_zoom = options.window.zoom; const int PREVIOUS_ZOOM = options.window.zoom;
--options.window.zoom; --options.window.zoom;
options.window.zoom = std::max(options.window.zoom, 1); options.window.zoom = std::max(options.window.zoom, 1);
if (options.window.zoom != previous_zoom) if (options.window.zoom != PREVIOUS_ZOOM)
{ {
adjustWindowSize(); setVideoMode(options.video.mode);
return true; return true;
} }
} }
@@ -236,13 +169,13 @@ bool Screen::incWindowZoom()
{ {
if (options.video.mode == 0) if (options.video.mode == 0)
{ {
int previous_zoom = options.window.zoom; const int PREVIOUS_ZOOM = options.window.zoom;
++options.window.zoom; ++options.window.zoom;
options.window.zoom = std::min(options.window.zoom, options.window.max_zoom); options.window.zoom = std::min(options.window.zoom, options.window.max_zoom);
if (options.window.zoom != previous_zoom) if (options.window.zoom != PREVIOUS_ZOOM)
{ {
adjustWindowSize(); setVideoMode(options.video.mode);
return true; return true;
} }
} }
@@ -262,22 +195,13 @@ void Screen::setBorderColor(Color color)
} }
// Cambia el tipo de mezcla // Cambia el tipo de mezcla
void Screen::setBlendMode(SDL_BlendMode blendMode) void Screen::setBlendMode(SDL_BlendMode blendMode) { SDL_SetRenderDrawBlendMode(renderer_, blendMode); }
{
SDL_SetRenderDrawBlendMode(renderer_, blendMode);
}
// Establece el tamaño del borde // Establece el tamaño del borde
void Screen::setBorderWidth(int s) void Screen::setBorderWidth(int s) { options.video.border.width = s; }
{
options.video.border.width = s;
}
// Establece el tamaño del borde // Establece el tamaño del borde
void Screen::setBorderHeight(int s) void Screen::setBorderHeight(int s) { options.video.border.height = s; }
{
options.video.border.height = s;
}
// Establece si se ha de ver el borde en el modo ventana // Establece si se ha de ver el borde en el modo ventana
void Screen::setBorderEnabled(bool value) { options.video.border.enabled = value; } void Screen::setBorderEnabled(bool value) { options.video.border.enabled = value; }
@@ -286,16 +210,11 @@ void Screen::setBorderEnabled(bool value) { options.video.border.enabled = value
void Screen::toggleBorder() void Screen::toggleBorder()
{ {
options.video.border.enabled = !options.video.border.enabled; options.video.border.enabled = !options.video.border.enabled;
adjustWindowSize(); setVideoMode(options.video.mode);
adjustGameCanvasRect();
adjustRenderLogicalSize();
} }
// Dibuja las notificaciones // Dibuja las notificaciones
void Screen::renderNotifications() void Screen::renderNotifications() { Notifier::get()->render(); }
{
Notifier::get()->render();
}
// Copia el gameCanvas en el borderCanvas // Copia el gameCanvas en el borderCanvas
void Screen::gameCanvasToBorderCanvas() void Screen::gameCanvasToBorderCanvas()
@@ -347,16 +266,10 @@ void Screen::update()
} }
// Muestra la ventana // Muestra la ventana
void Screen::show() void Screen::show() { SDL_ShowWindow(window_); }
{
SDL_ShowWindow(window_);
}
// Oculta la ventana // Oculta la ventana
void Screen::hide() void Screen::hide() { SDL_HideWindow(window_); }
{
SDL_HideWindow(window_);
}
// Calcula el tamaño de la ventana // Calcula el tamaño de la ventana
void Screen::adjustWindowSize() void Screen::adjustWindowSize()
@@ -375,11 +288,11 @@ void Screen::adjustWindowSize()
int old_pos_x, old_pos_y; int old_pos_x, old_pos_y;
SDL_GetWindowPosition(window_, &old_pos_x, &old_pos_y); SDL_GetWindowPosition(window_, &old_pos_x, &old_pos_y);
int new_pos_x = old_pos_x + (old_width - (window_width_ * options.window.zoom)) / 2; const int NEW_POS_X = old_pos_x + (old_width - (window_width_ * options.window.zoom)) / 2;
int new_pos_y = old_pos_y + (old_height - (window_height_ * options.window.zoom)) / 2; const int NEW_POS_Y = old_pos_y + (old_height - (window_height_ * options.window.zoom)) / 2;
SDL_SetWindowSize(window_, window_width_ * options.window.zoom, window_height_ * options.window.zoom); SDL_SetWindowSize(window_, window_width_ * options.window.zoom, window_height_ * options.window.zoom);
SDL_SetWindowPosition(window_, std::max(new_pos_x, WINDOWS_DECORATIONS_), std::max(new_pos_y, 0)); SDL_SetWindowPosition(window_, std::max(NEW_POS_X, WINDOWS_DECORATIONS_), std::max(NEW_POS_Y, 0));
} }
} }
@@ -394,12 +307,7 @@ void Screen::adjustGameCanvasRect()
} }
// Ajusta el tamaño lógico del renderizador // Ajusta el tamaño lógico del renderizador
void Screen::adjustRenderLogicalSize() void Screen::adjustRenderLogicalSize() { SDL_RenderSetLogicalSize(renderer_, window_width_, window_height_); }
{
const int extra_width = options.video.border.enabled ? options.video.border.width * 2 : 0;
const int extra_height = options.video.border.enabled ? options.video.border.height * 2 : 0;
SDL_RenderSetLogicalSize(renderer_, options.game.width + extra_width, options.game.height + extra_height);
}
// Obtiene el tamaño máximo de zoom posible para la ventana // Obtiene el tamaño máximo de zoom posible para la ventana
int Screen::getMaxZoom() int Screen::getMaxZoom()
@@ -409,19 +317,23 @@ int Screen::getMaxZoom()
SDL_GetCurrentDisplayMode(0, &DM); SDL_GetCurrentDisplayMode(0, &DM);
// Calcula el máximo factor de zoom que se puede aplicar a la pantalla // Calcula el máximo factor de zoom que se puede aplicar a la pantalla
const int max_zoom = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_); const int MAX_ZOOM = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_);
// Normaliza los valores de zoom // Normaliza los valores de zoom
options.window.zoom = std::min(options.window.zoom, max_zoom); options.window.zoom = std::min(options.window.zoom, MAX_ZOOM);
return max_zoom; return MAX_ZOOM;
} }
// Renderiza un frame negro // Reinicia los shaders
void Screen::renderBlackFrame() void Screen::resetShaders()
{ {
SDL_SetRenderTarget(renderer_, nullptr); if (options.video.shaders)
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); {
SDL_RenderClear(renderer_); const std::string GLSL_FILE = window_height_ == 192 ? "crtpi_192.glsl" : "crtpi_240.glsl";
SDL_RenderPresent(renderer_); std::ifstream f(Asset::get()->get(GLSL_FILE).c_str());
} std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());
shader::init(window_, options.video.border.enabled ? border_texture_ : game_texture_, source.c_str());
}
}

View File

@@ -2,13 +2,10 @@
#include <SDL2/SDL_blendmode.h> // for SDL_BlendMode #include <SDL2/SDL_blendmode.h> // for SDL_BlendMode
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Texture, SDL_Renderer
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <SDL2/SDL_video.h> // for SDL_Window #include <SDL2/SDL_video.h> // for SDL_Window
#include <vector> // for vector
#include <memory> // for shared_ptr
#include "utils.h" // for Color #include "utils.h" // for Color
//#include "surface.h"
// Tipos de filtro // Tipos de filtro
enum class ScreenFilter : Uint32 enum class ScreenFilter : Uint32
@@ -27,12 +24,12 @@ private:
static Screen *screen_; static Screen *screen_;
// Objetos y punteros // Objetos y punteros
SDL_Window *window_; // Ventana de la aplicación SDL_Window *window_; // Ventana de la aplicación
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
SDL_Texture *surface_texture_; // Textura donde se dibuja el juego SDL_Texture *surface_texture_; // Textura donde se dibuja el juego
SDL_Texture *game_texture_; // Textura donde se dibuja el juego SDL_Texture *game_texture_; // Textura donde se dibuja el juego
SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego
//std::shared_ptr<Surface> surface_; // Objeto para trabajar con surfaces // std::shared_ptr<Surface> surface_; // Objeto para trabajar con surfaces
// Variables // Variables
int window_width_; // Ancho de la pantalla o ventana int window_width_; // Ancho de la pantalla o ventana
@@ -58,9 +55,9 @@ private:
// Ajusta el tamaño lógico del renderizador // Ajusta el tamaño lógico del renderizador
void adjustRenderLogicalSize(); void adjustRenderLogicalSize();
// Renderiza un frame negro // Reinicia los shaders
void renderBlackFrame(); void resetShaders();
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer); Screen(SDL_Window *window, SDL_Renderer *renderer);
@@ -135,7 +132,7 @@ public:
// Getters // Getters
SDL_Renderer *getRenderer() { return renderer_; } SDL_Renderer *getRenderer() { return renderer_; }
//std::shared_ptr<SurfaceData> getSurface() { return surface_->getSurface(); } // std::shared_ptr<SurfaceData> getSurface() { return surface_->getSurface(); }
SDL_Texture *getGameTexture() { return game_texture_; }; SDL_Texture *getGameTexture() { return game_texture_; };
SDL_Texture *getBorderTexture() { return border_texture_; } SDL_Texture *getBorderTexture() { return border_texture_; }
}; };

View File

@@ -1,17 +1,12 @@
#include "stats.h" #include "stats.h"
#include <fstream> // for basic_ostream, basic_ifstream, basic_istream #include <fstream> // for basic_ostream, basic_ifstream, basic_istream
#include <sstream> // for basic_stringstream #include <sstream> // for basic_stringstream
#include "options.h" // for Options, OptionsStats, options #include "options.h" // for Options, OptionsStats, options
// Constructor // Constructor
Stats::Stats(std::string file, std::string buffer) Stats::Stats(const std::string &file, const std::string &buffer)
{ : bufferPath(buffer),
bufferPath = buffer; filePath(file) {}
filePath = file;
bufferList.clear();
list.clear();
dictionary.clear();
}
// Destructor // Destructor
Stats::~Stats() Stats::~Stats()
@@ -43,7 +38,7 @@ void Stats::init()
} }
// Añade una muerte a las estadisticas // Añade una muerte a las estadisticas
void Stats::addDeath(std::string name) void Stats::addDeath(const std::string &name)
{ {
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name, bufferList); const int index = findByName(name, bufferList);
@@ -55,7 +50,7 @@ void Stats::addDeath(std::string name)
// En caso contrario crea la entrada // En caso contrario crea la entrada
else else
{ {
stats_t item; StatsData item;
item.name = name; item.name = name;
item.visited = 0; item.visited = 0;
item.died = 1; item.died = 1;
@@ -64,7 +59,7 @@ void Stats::addDeath(std::string name)
} }
// Añade una visita a las estadisticas // Añade una visita a las estadisticas
void Stats::addVisit(std::string name) void Stats::addVisit(const std::string &name)
{ {
// Primero busca si ya hay una entrada con ese nombre // Primero busca si ya hay una entrada con ese nombre
const int index = findByName(name, bufferList); const int index = findByName(name, bufferList);
@@ -76,7 +71,7 @@ void Stats::addVisit(std::string name)
// En caso contrario crea la entrada // En caso contrario crea la entrada
else else
{ {
stats_t item; StatsData item;
item.name = name; item.name = name;
item.visited = 1; item.visited = 1;
item.died = 0; item.died = 0;
@@ -85,11 +80,11 @@ void Stats::addVisit(std::string name)
} }
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int Stats::findByName(std::string name, std::vector<stats_t> &list) int Stats::findByName(const std::string &name, const std::vector<StatsData> &list)
{ {
int i = 0; int i = 0;
for (auto l : list) for (const auto &l : list)
{ {
if (l.name == name) if (l.name == name)
{ {
@@ -102,7 +97,7 @@ int Stats::findByName(std::string name, std::vector<stats_t> &list)
} }
// Carga las estadisticas desde un fichero // Carga las estadisticas desde un fichero
bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list) bool Stats::loadFromFile(const std::string &file_path, std::vector<StatsData> &list)
{ {
list.clear(); list.clear();
@@ -110,19 +105,19 @@ bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
bool success = true; bool success = true;
// Variables para manejar el fichero // Variables para manejar el fichero
std::string line; std::ifstream file(file_path);
std::ifstream file(filePath);
// Si el fichero se puede abrir // Si el fichero se puede abrir
if (file.good()) if (file.good())
{ {
std::string line;
// Procesa el fichero linea a linea // Procesa el fichero linea a linea
while (std::getline(file, line)) while (std::getline(file, line))
{ {
// Comprueba que la linea no sea un comentario // Comprueba que la linea no sea un comentario
if (line.substr(0, 1) != "#") if (line.substr(0, 1) != "#")
{ {
stats_t stat; StatsData stat;
std::stringstream ss(line); std::stringstream ss(line);
std::string tmp; std::string tmp;
@@ -150,21 +145,21 @@ bool Stats::loadFromFile(std::string filePath, std::vector<stats_t> &list)
else else
{ {
// Crea el fichero con los valores por defecto // Crea el fichero con los valores por defecto
saveToFile(filePath, list); saveToFile(file_path, list);
} }
return success; return success;
} }
// Guarda las estadisticas en un fichero // Guarda las estadisticas en un fichero
void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list) void Stats::saveToFile(const std::string &file_path, const std::vector<StatsData> &list)
{ {
// Crea y abre el fichero de texto // Crea y abre el fichero de texto
std::ofstream file(filePath); std::ofstream file(file_path);
// Escribe en el fichero // Escribe en el fichero
file << "# ROOM NAME;VISITS;DEATHS" << std::endl; file << "# ROOM NAME;VISITS;DEATHS" << std::endl;
for (auto item : list) for (const auto &item : list)
{ {
file << item.name << ";" << item.visited << ";" << item.died << std::endl; file << item.name << ";" << item.visited << ";" << item.died << std::endl;
} }
@@ -177,7 +172,7 @@ void Stats::saveToFile(std::string filePath, std::vector<stats_t> &list)
void Stats::checkWorstNightmare() void Stats::checkWorstNightmare()
{ {
int deaths = 0; int deaths = 0;
for (auto item : list) for (const auto &item : list)
{ {
if (item.died > deaths) if (item.died > deaths)
{ {
@@ -188,42 +183,16 @@ void Stats::checkWorstNightmare()
} }
// Añade una entrada al diccionario // Añade una entrada al diccionario
void Stats::addDictionary(std::string number, std::string name) void Stats::addDictionary(const std::string &number, const std::string &name)
{ {
dictionary.push_back({number, name}); dictionary.push_back({number, name});
} }
// Obtiene el nombre de una habitación a partir del número
std::string Stats::numberToName(std::string number)
{
for (auto l : dictionary)
{
if (l.number == number)
{
return l.name;
}
}
return "";
}
// Obtiene el número de una habitación a partir del nombre
std::string Stats::nameToNumber(std::string name)
{
for (auto l : dictionary)
{
if (l.name == name)
{
return l.number;
}
}
return "";
}
// Vuelca los datos del buffer en la lista de estadisticas // Vuelca los datos del buffer en la lista de estadisticas
void Stats::updateListFromBuffer() void Stats::updateListFromBuffer()
{ {
// Actualiza list desde bufferList // Actualiza list desde bufferList
for (auto buffer : bufferList) for (const auto &buffer : bufferList)
{ {
int index = findByName(buffer.name, list); int index = findByName(buffer.name, list);
@@ -234,7 +203,7 @@ void Stats::updateListFromBuffer()
} }
else else
{ // En caso contrario crea la entrada { // En caso contrario crea la entrada
stats_t item; StatsData item;
item.name = buffer.name; item.name = buffer.name;
item.visited = buffer.visited; item.visited = buffer.visited;
item.died = buffer.died; item.died = buffer.died;

View File

@@ -1,55 +1,49 @@
#pragma once #pragma once
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
class Stats class Stats
{ {
private: private:
struct stats_t struct StatsData
{ {
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
int visited; // Cuenta las veces que se ha visitado una habitación int visited; // Cuenta las veces que se ha visitado una habitación
int died; // Cuenta las veces que se ha muerto en una habitación int died; // Cuenta las veces que se ha muerto en una habitación
}; };
struct stats_dictionary_t struct StatsDictionary
{ {
std::string number; // Numero de la habitación std::string number; // Numero de la habitación
std::string name; // Nombre de la habitación std::string name; // Nombre de la habitación
}; };
// Variables // Variables
std::vector<stats_dictionary_t> dictionary; // Lista con la equivalencia nombre-numero de habitacion std::vector<StatsDictionary> dictionary; // Lista con la equivalencia nombre-numero de habitacion
std::vector<stats_t> bufferList; // Lista con las estadisticas temporales por habitación std::vector<StatsData> bufferList; // Lista con las estadisticas temporales por habitación
std::vector<stats_t> list; // Lista con las estadisticas completas por habitación std::vector<StatsData> list; // Lista con las estadisticas completas por habitación
std::string bufferPath; // Fichero con las estadísticas temporales std::string bufferPath; // Fichero con las estadísticas temporales
std::string filePath; // Fichero con las estadísticas completas std::string filePath; // Fichero con las estadísticas completas
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int findByName(std::string name, std::vector<stats_t> &list); int findByName(const std::string &name, const std::vector<StatsData> &list);
// Carga las estadisticas desde un fichero // Carga las estadisticas desde un fichero
bool loadFromFile(std::string filePath, std::vector<stats_t> &list); bool loadFromFile(const std::string &filePath, std::vector<StatsData> &list);
// Guarda las estadisticas en un fichero // Guarda las estadisticas en un fichero
void saveToFile(std::string filePath, std::vector<stats_t> &list); void saveToFile(const std::string &filePath, const std::vector<StatsData> &list);
// Calcula cual es la habitación con más muertes // Calcula cual es la habitación con más muertes
void checkWorstNightmare(); void checkWorstNightmare();
// Obtiene el nombre de una habitación a partir del número
std::string numberToName(std::string number);
// Obtiene el número de una habitación a partir del nombre
std::string nameToNumber(std::string name);
// Vuelca los datos del buffer en la lista de estadisticas // Vuelca los datos del buffer en la lista de estadisticas
void updateListFromBuffer(); void updateListFromBuffer();
public: public:
// Constructor // Constructor
Stats(std::string file, std::string buffer); Stats(const std::string &file, const std::string &buffer);
// Destructor // Destructor
~Stats(); ~Stats();
@@ -59,11 +53,11 @@ public:
void init(); void init();
// Añade una muerte a las estadisticas // Añade una muerte a las estadisticas
void addDeath(std::string name); void addDeath(const std::string &name);
// Añade una visita a las estadisticas // Añade una visita a las estadisticas
void addVisit(std::string name); void addVisit(const std::string &name);
// Añade una entrada al diccionario // Añade una entrada al diccionario
void addDictionary(std::string number, std::string name); void addDictionary(const std::string &number, const std::string &name);
}; };

View File

@@ -1,26 +1,24 @@
#include "surface.h" #include "surface.h"
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_ARGB8888 #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_rect.h> // Para SDL_Rect #include <stddef.h> // for size_t
#include <fstream> // Para std::ifstream #include <algorithm> // for min, copy, fill
#include <iostream> // Para std::cerr #include <fstream> // for basic_ostream, basic_ifstream, basic_ios
#include <vector> // Para std::vector #include <iostream> // for cerr, cout
#include <stdexcept> // For exceptions #include <memory> // for shared_ptr, __shared_ptr_access, unique_ptr
#include "gif.h" // Para LoadGif, LoadPalette #include <stdexcept> // for runtime_error
#include <memory> // Para std::shared_ptr #include <vector> // for vector
#include <algorithm> // Para std::copy #include "asset.h" // for Asset
#include "asset.h" #include "gif.h" // for LoadGif, LoadPalette
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h) Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h)
: surface_dest_(surface_dest), : surface_dest_(surface_dest),
surface_(std::make_shared<SurfaceData>(w, h)), surface_(std::make_shared<SurfaceData>(w, h)),
transparent_color_(0) {} transparent_color_(0) {}
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path) Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, const std::string &file_path)
: surface_dest_(surface_dest), : surface_dest_(surface_dest),
surface_(std::make_shared<SurfaceData>(loadSurface(Asset::get()->get(file_path)))), surface_(std::make_shared<SurfaceData>(loadSurface(Asset::get()->get(file_path)))),
transparent_color_(0) { transparent_color_(0) {}
std::cout << "surface loaded: "<< surface_->width << "x" << surface_->height << std::endl;
}
Surface::~Surface() {} Surface::~Surface() {}
@@ -137,7 +135,7 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
{ {
throw std::runtime_error("Surface source or destination is null."); throw std::runtime_error("Surface source or destination is null.");
} }
// Limitar la región para evitar accesos fuera de rango // Limitar la región para evitar accesos fuera de rango
w = std::min(w, surface_->width - sx); w = std::min(w, surface_->width - sx);
h = std::min(h, surface_->height - sy); h = std::min(h, surface_->height - sy);

View File

@@ -74,7 +74,7 @@ private:
public: public:
// Constructor // Constructor
Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h); Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h);
Surface(std::shared_ptr<SurfaceData> surface_dest, std::string file_path); Surface(std::shared_ptr<SurfaceData> surface_dest, const std::string &file_path);
// Destructor // Destructor
~Surface(); ~Surface();

View File

@@ -1,14 +1,12 @@
#include "texture.h" #include "texture.h"
#include <SDL2/SDL_error.h> // Para SDL_GetError #include <SDL2/SDL_error.h> // for SDL_GetError
#include <SDL2/SDL_surface.h> // Para SDL_CreateRGBSurfaceWithFormatFrom #include <SDL2/SDL_surface.h> // for SDL_CreateRGBSurfaceWithFormatFrom
#include <fstream> // Para basic_ostream, operator<<, basic_ifstream #include <iostream> // for basic_ostream, operator<<, endl, cout
#include <iostream> // Para cerr, cout #include <stdexcept> // for runtime_error
#include <stdexcept> // Para runtime_error #include <string> // for char_traits, operator<<, string, opera...
#include <string> // Para char_traits, operator<<, operator+ #include <vector> // for vector
#include <vector> // Para vector #include "utils.h" // for getFileName, Color, printWithDots
#include "stb_image.h" // Para stbi_image_free, stbi_load, STBI_rgb_a...
#include "utils.h" // Para getFileName, printWithDots
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h" // para stbi_failure_reason, stbi_image_free #include "stb_image.h" // para stbi_failure_reason, stbi_image_free

View File

@@ -1,14 +1,13 @@
#pragma once #pragma once
#include <SDL2/SDL_blendmode.h> // Para SDL_BlendMode #include <SDL2/SDL_blendmode.h> // for SDL_BlendMode
#include <SDL2/SDL_pixels.h> // Para SDL_PIXELFORMAT_RGBA8888, SDL_PixelF... #include <SDL2/SDL_pixels.h> // for SDL_PIXELFORMAT_RGBA8888, SDL_PixelF...
#include <SDL2/SDL_rect.h> // Para SDL_Point, SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Point, SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer, SDL_FLIP_NONE, SDL_TEX... #include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_FLIP_NONE, SDL_TEX...
#include <SDL2/SDL_stdinc.h> // Para Uint8, Uint16, Uint32 #include <SDL2/SDL_stdinc.h> // for Uint8, Uint32
#include <memory> // Para shared_ptr #include <string> // for string
#include <string> // Para string #include <vector> // for vector
#include <vector> // Para vector struct Color; // lines 11-11
struct Color;
// Definiciones de tipos // Definiciones de tipos
/*struct Surface /*struct Surface

View File

@@ -23,43 +23,21 @@
// Constructor // Constructor
Title::Title() Title::Title()
: screen_(Screen::get()), : texture_(Resource::get()->getTexture("title_logo.png")),
renderer_(Screen::get()->getRenderer()), sprite_(std::make_shared<Sprite>(texture_, 0, 0, texture_->getWidth(), texture_->getHeight()))
resource_(Resource::get()),
input_(Input::get())
{ {
// Reserva memoria para los punteros
if (options.video.palette == Palette::ZXSPECTRUM)
{
texture_ = resource_->getTexture("title_logo.png");
}
else if (options.video.palette == Palette::ZXARNE)
{
texture_ = resource_->getTexture("title_logo.png");
}
sprite_ = std::make_shared<Sprite>(texture_, 0, 0, texture_->getWidth(), texture_->getHeight());
text_ = resource_->getText("smb2");
info_text_ = resource_->getText("subatomic");
// Crea la textura para los graficos que aparecen en el fondo de la pantalla de titulo // Crea la textura para los graficos que aparecen en el fondo de la pantalla de titulo
bg_texture_ = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); bg_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height);
if (bg_texture_ == nullptr)
{
if (options.console)
{
std::cout << "Error: bgTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
SDL_SetTextureBlendMode(bg_texture_, SDL_BLENDMODE_BLEND); SDL_SetTextureBlendMode(bg_texture_, SDL_BLENDMODE_BLEND);
// Carga la surface con los gráficos de la pantalla de carga // Carga la surface con los gráficos de la pantalla de carga
pInit(renderer_, 256, 128); pInit(Screen::get()->getRenderer(), 256, 128);
loading_screen_ = pLoadSurface(Asset::get()->get("loading_screen_color.gif").c_str()); loading_screen_ = pLoadSurface(Asset::get()->get("loading_screen_color.gif").c_str());
pLoadPal(Asset::get()->get("loading_screen_color.gif").c_str()); pLoadPal(Asset::get()->get("loading_screen_color.gif").c_str());
pSetSource(loading_screen_); pSetSource(loading_screen_);
// Inicializa variables // Inicializa variables
state_ = options.section.subsection == Subsection::TITLE_WITH_LOADING_SCREEN ? show_loading_screen : show_menu; state_ = options.section.subsection == Subsection::TITLE_WITH_LOADING_SCREEN ? TitleState::SHOW_LOADING_SCREEN : TitleState::SHOW_MENU;
options.section.section = Section::TITLE; options.section.section = Section::TITLE;
options.section.subsection = Subsection::NONE; options.section.subsection = Subsection::NONE;
initMarquee(); initMarquee();
@@ -68,7 +46,7 @@ Title::Title()
createCheevosTexture(); createCheevosTexture();
// Cambia el color del borde // Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "black")); Screen::get()->setBorderColor(stringToColor(options.video.palette, "black"));
// Rellena la textura de fondo con todos los gráficos // Rellena la textura de fondo con todos los gráficos
fillTexture(); fillTexture();
@@ -91,7 +69,7 @@ void Title::initMarquee()
long_text_ = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?"; long_text_ = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
for (int i = 0; i < (int)long_text_.length(); ++i) for (int i = 0; i < (int)long_text_.length(); ++i)
{ {
letter_t l; TitleLetter l;
l.letter = long_text_.substr(i, 1); l.letter = long_text_.substr(i, 1);
l.x = 256; l.x = 256;
l.enabled = false; l.enabled = false;
@@ -137,26 +115,26 @@ void Title::checkInput()
{ {
if (show_cheevos_) if (show_cheevos_)
{ {
if (input_->checkInput(input_down, REPEAT_TRUE)) if (Input::get()->checkInput(InputAction::DOWN, REPEAT_TRUE))
{ {
moveCheevosList(1); moveCheevosList(1);
} }
else if (input_->checkInput(input_up, REPEAT_TRUE)) else if (Input::get()->checkInput(InputAction::UP, REPEAT_TRUE))
{ {
moveCheevosList(0); moveCheevosList(0);
} }
else if (input_->checkInput(input_accept, REPEAT_FALSE)) else if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
{ {
hideCheevosList(); hideCheevosList();
counter_ = 0; counter_ = 0;
} }
} }
if (input_->checkInput(input_accept, REPEAT_FALSE)) if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
{ {
if (state_ == show_loading_screen) if (state_ == TitleState::SHOW_LOADING_SCREEN)
{ {
state_ = fade_loading_screen; state_ = TitleState::FADE_LOADING_SCREEN;
} }
} }
@@ -166,6 +144,8 @@ void Title::checkInput()
// Actualiza la marquesina // Actualiza la marquesina
void Title::updateMarquee() void Title::updateMarquee()
{ {
const auto TEXT = Resource::get()->getText("smb2");
for (int i = 0; i < (int)letters_.size(); ++i) for (int i = 0; i < (int)letters_.size(); ++i)
{ {
if (letters_[i].enabled) if (letters_[i].enabled)
@@ -181,7 +161,7 @@ void Title::updateMarquee()
if (i > 0 && letters_[i - 1].x < 256 && letters_[i - 1].enabled) if (i > 0 && letters_[i - 1].x < 256 && letters_[i - 1].enabled)
{ {
letters_[i].enabled = true; letters_[i].enabled = true;
letters_[i].x = letters_[i - 1].x + text_->lenght(letters_[i - 1].letter) + 1; letters_[i].x = letters_[i - 1].x + TEXT->lenght(letters_[i - 1].letter) + 1;
} }
} }
} }
@@ -196,23 +176,16 @@ void Title::updateMarquee()
// Dibuja la marquesina // Dibuja la marquesina
void Title::renderMarquee() void Title::renderMarquee()
{ {
for (auto l : letters_) const auto TEXT = Resource::get()->getText("smb2");
for (const auto &l : letters_)
{ {
if (l.enabled) if (l.enabled)
{ {
text_->writeColored(l.x, 184, l.letter, stringToColor(options.video.palette, "white")); TEXT->writeColored(l.x, 184, l.letter, stringToColor(options.video.palette, "white"));
} }
} }
} }
// Dibuja la linea de información inferior
void Title::renderInfo()
{
const std::string version = "v.1.09";
const int x = GAMECANVAS_WIDTH - info_text_->lenght(version) - 1;
info_text_->write(x, 1, version);
}
// Actualiza las variables // Actualiza las variables
void Title::update() void Title::update()
{ {
@@ -225,31 +198,33 @@ void Title::update()
// Comprueba las entradas // Comprueba las entradas
checkInput(); checkInput();
screen_->update(); Screen::get()->update();
// Incrementa el contador // Incrementa el contador
counter_++; counter_++;
switch (state_) switch (state_)
{ {
case show_loading_screen: case TitleState::SHOW_LOADING_SCREEN:
if (counter_ == 500) if (counter_ == 500)
{ {
counter_ = 0; counter_ = 0;
state_ = fade_loading_screen; state_ = TitleState::FADE_LOADING_SCREEN;
} }
break; break;
case fade_loading_screen: case TitleState::FADE_LOADING_SCREEN:
if (counter_ % 4 == 0) if (counter_ % 4 == 0)
{
if (pFadePal()) if (pFadePal())
{ {
counter_ = 0; counter_ = 0;
state_ = show_menu; state_ = TitleState::SHOW_MENU;
} }
}
break; break;
case show_menu: case TitleState::SHOW_MENU:
// Actualiza la marquesina // Actualiza la marquesina
updateMarquee(); updateMarquee();
@@ -274,13 +249,13 @@ void Title::update()
void Title::render() void Title::render()
{ {
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
screen_->start(); Screen::get()->start();
screen_->clean(stringToColor(options.video.palette, "black")); Screen::get()->clean(stringToColor(options.video.palette, "black"));
if (state_ == show_menu) if (state_ == TitleState::SHOW_MENU)
{ {
// Dibuja la textura de fondo // Dibuja la textura de fondo
SDL_RenderCopy(renderer_, bg_texture_, nullptr, nullptr); SDL_RenderCopy(Screen::get()->getRenderer(), bg_texture_, nullptr, nullptr);
// Dibuja la marquesina // Dibuja la marquesina
renderMarquee(); renderMarquee();
@@ -296,14 +271,14 @@ void Title::render()
// Dibuja la pantalla de carga // Dibuja la pantalla de carga
pCls(4); pCls(4);
pBlit(0, 0, 0, 0, 256, 128); pBlit(0, 0, 0, 0, 256, 128);
pFlip(renderer_); pFlip(Screen::get()->getRenderer());
// Dibuja el logo del título // Dibuja el logo del título
sprite_->render(); sprite_->render();
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
screen_->render(); Screen::get()->render();
} }
// Bucle para el logo del juego // Bucle para el logo del juego
@@ -317,40 +292,6 @@ void Title::run()
} }
} }
// Recarga las texturas
void Title::reLoadTextures()
{
// Carga la textura adecuada
if (options.video.palette == Palette::ZXSPECTRUM)
{
texture_ = resource_->getTexture("loading_screen_color.png");
}
else if (options.video.palette == Palette::ZXARNE)
{
texture_ = resource_->getTexture("loading_screen_color_zxarne.png");
}
texture_->reLoad();
}
// Cambia la paleta
void Title::switchPalette()
{
if (options.video.palette == Palette::ZXSPECTRUM)
{
options.video.palette = Palette::ZXARNE;
sprite_->setTexture(resource_->getTexture("loading_screen_color_zxarne.png"));
}
else
{
options.video.palette = Palette::ZXSPECTRUM;
sprite_->setTexture(resource_->getTexture("loading_screen_color.png"));
}
// Cambia el color del borde
screen_->setBorderColor(stringToColor(options.video.palette, "bright_blue"));
}
// Desplaza la lista de logros // Desplaza la lista de logros
void Title::moveCheevosList(int direction) void Title::moveCheevosList(int direction)
{ {
@@ -373,78 +314,82 @@ void Title::moveCheevosList(int direction)
// Rellena la textura de fondo con todos los gráficos // Rellena la textura de fondo con todos los gráficos
void Title::fillTexture() void Title::fillTexture()
{ {
auto renderer = Screen::get()->getRenderer();
// Coloca el puntero del renderizador sobre la textura // Coloca el puntero del renderizador sobre la textura
SDL_SetRenderTarget(renderer_, bg_texture_); SDL_SetRenderTarget(renderer, bg_texture_);
// Rellena la textura de color // Rellena la textura de color
const Color c = stringToColor(options.video.palette, "black"); const Color c = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, c.r, c.g, c.b, 0xFF); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(renderer);
// Pinta el gráfico del titulo a partir del sprite // Pinta el gráfico del titulo a partir del sprite
sprite_->render(); sprite_->render();
// Escribe el texto en la textura // Escribe el texto en la textura
const Color textColor = stringToColor(options.video.palette, "green"); auto text = Resource::get()->getText("smb2");
const int textSize = text_->getCharacterSize(); const Color COLOR = stringToColor(options.video.palette, "green");
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * textSize, "1.PLAY", 1, textColor); const int TEXT_SIZE = text->getCharacterSize();
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * textSize, "2.ACHIEVEMENTS", 1, textColor); text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1.PLAY", 1, COLOR);
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 15 * textSize, "3.REDEFINE KEYS", 1, textColor); text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2.ACHIEVEMENTS", 1, COLOR);
text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 20 * textSize, "ESC.EXIT GAME", 1, textColor); text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 15 * TEXT_SIZE, "3.REDEFINE KEYS", 1, COLOR);
text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 20 * TEXT_SIZE, "ESC.EXIT GAME", 1, COLOR);
// Devuelve el puntero del renderizador a su sitio // Devuelve el puntero del renderizador a su sitio
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(renderer, nullptr);
} }
// Crea y rellena la textura para mostrar los logros // Crea y rellena la textura para mostrar los logros
void Title::createCheevosTexture() void Title::createCheevosTexture()
{ {
// Crea la textura con el listado de logros // Crea la textura con el listado de logros
const auto cheevosList = Cheevos::get()->list(); const auto CHEEVOS_LIST = Cheevos::get()->list();
const int cheevosTextureWidth = 200; const auto TEXT = Resource::get()->getText("subatomic");
const int cheevosTextureViewHeight = 110; constexpr int CHEEVOS_TEXTURE_WIDTH = 200;
const int cheevosTexturePosY = 73; constexpr int CHEEVOS_TEXTURE_VIEW_HEIGHT = 110;
const int cheevosPadding = 10; constexpr int CHEEVOS_TEXTURE_POS_Y = 73;
const int cheevoHeight = cheevosPadding + (info_text_->getCharacterSize() * 2) + 1; constexpr int CHEEVOS_PADDING = 10;
const int cheevosTextureHeight = (cheevoHeight * cheevosList.size()) + 2 + info_text_->getCharacterSize() + 8; const int CHEEVO_HEIGHT = CHEEVOS_PADDING + (TEXT->getCharacterSize() * 2) + 1;
cheevos_texture_ = std::make_shared<Texture>(renderer_); const int CHEEVOS_TEXTURE_HEIGHT = (CHEEVO_HEIGHT * CHEEVOS_LIST.size()) + 2 + TEXT->getCharacterSize() + 8;
cheevos_texture_->createBlank(cheevosTextureWidth, cheevosTextureHeight, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET); cheevos_texture_ = std::make_shared<Texture>(Screen::get()->getRenderer());
cheevos_texture_->setAsRenderTarget(renderer_); cheevos_texture_->createBlank(CHEEVOS_TEXTURE_WIDTH, CHEEVOS_TEXTURE_HEIGHT, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET);
cheevos_texture_->setAsRenderTarget(Screen::get()->getRenderer());
cheevos_texture_->setBlendMode(SDL_BLENDMODE_BLEND); cheevos_texture_->setBlendMode(SDL_BLENDMODE_BLEND);
// Rellena la textura con color sólido // Rellena la textura con color sólido
const Color cheevosBGColor = stringToColor(options.video.palette, "black"); const Color CHEEVOS_BG_COLOR = stringToColor(options.video.palette, "black");
SDL_SetRenderDrawColor(renderer_, cheevosBGColor.r, cheevosBGColor.g, cheevosBGColor.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), CHEEVOS_BG_COLOR.r, CHEEVOS_BG_COLOR.g, CHEEVOS_BG_COLOR.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(Screen::get()->getRenderer());
// Escribe la lista de logros en la textura // Escribe la lista de logros en la textura
const std::string cheevosOwner = "ACHIEVEMENTS"; const std::string CHEEVOS_OWNER = "ACHIEVEMENTS";
const std::string cheevosListCaption = cheevosOwner + " (" + std::to_string(Cheevos::get()->unlocked()) + " / " + std::to_string(Cheevos::get()->count()) + ")"; const std::string CHEEVOS_LIST_CAPTION = CHEEVOS_OWNER + " (" + std::to_string(Cheevos::get()->getTotalUnlockedAchievements()) + " / " + std::to_string(Cheevos::get()->size()) + ")";
int pos = 2; int pos = 2;
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevos_texture_->getWidth() / 2, pos, cheevosListCaption, 1, stringToColor(options.video.palette, "bright_green")); TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, cheevos_texture_->getWidth() / 2, pos, CHEEVOS_LIST_CAPTION, 1, stringToColor(options.video.palette, "bright_green"));
pos += info_text_->getCharacterSize(); pos += TEXT->getCharacterSize();
const Color cheevoLockedColor = stringToColor(options.video.palette, "white"); const Color CHEEVO_LOCKED_COLOR = stringToColor(options.video.palette, "white");
const Color cheevoUnlockedColor = stringToColor(options.video.palette, "bright_green"); const Color CHEEVO_UNLOCKED_COLOR = stringToColor(options.video.palette, "bright_green");
Color cheevoColor; Color cheevoColor;
SDL_SetRenderDrawColor(renderer_, cheevoLockedColor.r, cheevoLockedColor.g, cheevoLockedColor.b, 0xFF); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), CHEEVO_LOCKED_COLOR.r, CHEEVO_LOCKED_COLOR.g, CHEEVO_LOCKED_COLOR.b, 0xFF);
const int lineX1 = (cheevosTextureWidth / 7) * 3; constexpr int LINE_X1 = (CHEEVOS_TEXTURE_WIDTH / 7) * 3;
const int lineX2 = lineX1 + ((cheevosTextureWidth / 7) * 1); constexpr int LINE_X2 = LINE_X1 + ((CHEEVOS_TEXTURE_WIDTH / 7) * 1);
for (auto cheevo : cheevosList) for (const auto &cheevo : CHEEVOS_LIST)
{ {
cheevoColor = cheevo.completed ? cheevoUnlockedColor : cheevoLockedColor; cheevoColor = cheevo.completed ? CHEEVO_UNLOCKED_COLOR : CHEEVO_LOCKED_COLOR;
pos += cheevosPadding; pos += CHEEVOS_PADDING;
int half = cheevosPadding / 2; constexpr int HALF = CHEEVOS_PADDING / 2;
SDL_RenderDrawLine(renderer_, lineX1, pos - half - 1, lineX2, pos - half - 1); SDL_RenderDrawLine(Screen::get()->getRenderer(), LINE_X1, pos - HALF - 1, LINE_X2, pos - HALF - 1);
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevosTextureWidth / 2, pos, cheevo.caption, 1, cheevoColor); TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.caption, 1, cheevoColor);
pos += info_text_->getCharacterSize() + 1; pos += TEXT->getCharacterSize() + 1;
info_text_->writeDX(TEXT_CENTER | TEXT_COLOR, cheevosTextureWidth / 2, pos, cheevo.description, 1, cheevoColor); TEXT->writeDX(TEXT_CENTER | TEXT_COLOR, CHEEVOS_TEXTURE_WIDTH / 2, pos, cheevo.description, 1, cheevoColor);
pos += info_text_->getCharacterSize(); pos += TEXT->getCharacterSize();
} }
// Crea el sprite para el listado de logros // Crea el sprite para el listado de logros
cheevos_sprite_ = std::make_shared<Sprite>(cheevos_texture_, (GAMECANVAS_WIDTH - cheevos_texture_->getWidth()) / 2, cheevosTexturePosY, cheevos_texture_->getWidth(), cheevos_texture_->getHeight()); cheevos_sprite_ = std::make_shared<Sprite>(cheevos_texture_, (GAMECANVAS_WIDTH - cheevos_texture_->getWidth()) / 2, CHEEVOS_TEXTURE_POS_Y, cheevos_texture_->getWidth(), cheevos_texture_->getHeight());
cheevos_texture_view_ = {0, 0, cheevos_texture_->getWidth(), cheevosTextureViewHeight}; cheevos_texture_view_ = {0, 0, cheevos_texture_->getWidth(), CHEEVOS_TEXTURE_VIEW_HEIGHT};
cheevos_sprite_->setClip(cheevos_texture_view_); cheevos_sprite_->setClip(cheevos_texture_view_);
} }

View File

@@ -1,59 +1,49 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect #include <SDL2/SDL_rect.h> // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture #include <SDL2/SDL_render.h> // for SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint32 #include <SDL2/SDL_stdinc.h> // for Uint32
#include <memory> // for shared_ptr #include <memory> // for shared_ptr
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "paleta.h" // for jSurface #include "paleta.h" // for jSurface
class Input; // lines 13-13 class Sprite; // lines 13-13
class Resource; // lines 14-14 class Texture; // lines 15-15
class Screen; // lines 15-15
class Sprite; // lines 16-16
class Text; // lines 17-17
class Texture; // lines 18-18
class Title class Title
{ {
private: private:
struct letter_t struct TitleLetter
{ {
std::string letter; // Letra a escribir std::string letter; // Letra a escribir
int x; // Posición en el eje x int x; // Posición en el eje x
bool enabled; // Solo se escriben y mueven si estan habilitadas bool enabled; // Solo se escriben y mueven si estan habilitadas
}; };
enum states_e enum class TitleState
{ {
show_loading_screen, SHOW_LOADING_SCREEN,
fade_loading_screen, FADE_LOADING_SCREEN,
show_menu SHOW_MENU
}; };
// Objetos y punteros // 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
std::shared_ptr<Texture> texture_; // Textura con los graficos std::shared_ptr<Texture> texture_; // Textura con los graficos
std::shared_ptr<Sprite> sprite_; // Sprite para manejar la textura std::shared_ptr<Sprite> sprite_; // Sprite para manejar la textura
SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla
std::shared_ptr<Text> text_; // Objeto para escribir texto en pantalla
std::shared_ptr<Text> info_text_; // Objeto para escribir texto en pantalla
std::shared_ptr<Texture> cheevos_texture_; // Textura con la lista de logros std::shared_ptr<Texture> cheevos_texture_; // Textura con la lista de logros
std::shared_ptr<Sprite> cheevos_sprite_; // Sprite para manejar la textura con la lista de logros std::shared_ptr<Sprite> cheevos_sprite_; // Sprite para manejar la textura con la lista de logros
// Variables // Variables
int counter_ = 0; // Contador int counter_ = 0; // Contador
std::string long_text_; // Texto que aparece en la parte inferior del titulo std::string long_text_; // Texto que aparece en la parte inferior del titulo
Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa
std::vector<letter_t> letters_; // Vector con las letras de la marquesina std::vector<TitleLetter> letters_; // Vector con las letras de la marquesina
int marquee_speed_ = 3; // Velocidad de desplazamiento de la marquesina int marquee_speed_ = 3; // Velocidad de desplazamiento de la marquesina
bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros
SDL_Rect cheevos_texture_view_; // Zona visible de la textura con el listado de logros SDL_Rect cheevos_texture_view_; // Zona visible de la textura con el listado de logros
states_e state_; // Estado en el que se encuentra el bucle principal TitleState state_; // Estado en el que se encuentra el bucle principal
jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga
// Actualiza las variables // Actualiza las variables
void update(); void update();
@@ -76,15 +66,6 @@ private:
// Dibuja la marquesina // Dibuja la marquesina
void renderMarquee(); void renderMarquee();
// Dibuja la linea de información inferior
void renderInfo();
// Recarga las texturas
void reLoadTextures();
// Cambia la paleta
void switchPalette();
// Desplaza la lista de logros // Desplaza la lista de logros
void moveCheevosList(int direction); void moveCheevosList(int direction);

View File

@@ -1,15 +1,16 @@
#include "utils.h" #include "utils.h"
#include <stdlib.h> // for free, malloc, abs #include <stdlib.h> // for abs
#include <algorithm> // for transform #include <algorithm> // for find, transform
#include <cctype> // for tolower #include <cctype> // for tolower
#include <cmath> // for round, abs #include <cmath> // for round, abs
#include <exception> // for exception #include <exception> // for exception
#include <filesystem> // for path #include <filesystem> // for path
#include <iostream> // for basic_ostream, cout, basic_ios, ios, endl #include <iostream> // for basic_ostream, cout, basic_ios, ios, endl
#include <unordered_map> // for unordered_map #include <string> // for basic_string, string, char_traits, allocator
#include <string> // for string #include <unordered_map> // for unordered_map, operator==, _Node_const_iter...
#include "jail_audio.h" #include <utility> // for pair
#include "resource.h" #include "jail_audio.h" // for JA_GetMusicState, JA_Music_state, JA_PlayMusic
#include "resource.h" // for Resource
// Calcula el cuadrado de la distancia entre dos puntos // Calcula el cuadrado de la distancia entre dos puntos
double distanceSquared(int x1, int y1, int x2, int y2) double distanceSquared(int x1, int y1, int x2, int y2)
@@ -20,7 +21,7 @@ double distanceSquared(int x1, int y1, int x2, int y2)
} }
// Detector de colisiones entre dos circulos // Detector de colisiones entre dos circulos
bool checkCollision(Circle &a, Circle &b) bool checkCollision(const Circle &a, const Circle &b)
{ {
// Calcula el radio total al cuadrado // Calcula el radio total al cuadrado
int totalRadiusSquared = a.r + b.r; int totalRadiusSquared = a.r + b.r;
@@ -38,7 +39,7 @@ bool checkCollision(Circle &a, Circle &b)
} }
// Detector de colisiones entre un circulo y un rectangulo // Detector de colisiones entre un circulo y un rectangulo
bool checkCollision(Circle &a, SDL_Rect &b) bool checkCollision(const Circle &a, const SDL_Rect &b)
{ {
// Closest point on collision box // Closest point on collision box
int cX, cY; int cX, cY;
@@ -83,7 +84,7 @@ bool checkCollision(Circle &a, SDL_Rect &b)
} }
// Detector de colisiones entre dos rectangulos // Detector de colisiones entre dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b) bool checkCollision(const SDL_Rect &a, const SDL_Rect &b)
{ {
// Calcula las caras del rectangulo a // Calcula las caras del rectangulo a
const int leftA = a.x; const int leftA = a.x;
@@ -123,7 +124,7 @@ bool checkCollision(SDL_Rect &a, SDL_Rect &b)
} }
// Detector de colisiones entre un punto y un rectangulo // Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r) bool checkCollision(const SDL_Point &p, const SDL_Rect &r)
{ {
// Comprueba si el punto está a la izquierda del rectangulo // Comprueba si el punto está a la izquierda del rectangulo
if (p.x < r.x) if (p.x < r.x)
@@ -154,7 +155,7 @@ bool checkCollision(SDL_Point &p, SDL_Rect &r)
} }
// Detector de colisiones entre una linea horizontal y un rectangulo // Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r) bool checkCollision(const LineHorizontal &l, const SDL_Rect &r)
{ {
// Comprueba si la linea esta por encima del rectangulo // Comprueba si la linea esta por encima del rectangulo
if (l.y < r.y) if (l.y < r.y)
@@ -185,7 +186,7 @@ bool checkCollision(h_line_t &l, SDL_Rect &r)
} }
// Detector de colisiones entre una linea vertical y un rectangulo // Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r) bool checkCollision(const LineVertical &l, const SDL_Rect &r)
{ {
// Comprueba si la linea esta por la izquierda del rectangulo // Comprueba si la linea esta por la izquierda del rectangulo
if (l.x < r.x) if (l.x < r.x)
@@ -216,7 +217,7 @@ bool checkCollision(v_line_t &l, SDL_Rect &r)
} }
// Detector de colisiones entre una linea horizontal y un punto // Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p) bool checkCollision(const LineHorizontal &l, const SDL_Point &p)
{ {
// Comprueba si el punto esta sobre la linea // Comprueba si el punto esta sobre la linea
if (p.y > l.y) if (p.y > l.y)
@@ -247,7 +248,7 @@ bool checkCollision(h_line_t &l, SDL_Point &p)
} }
// Detector de colisiones entre dos lineas // Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2) SDL_Point checkCollision(const Line &l1, const Line &l2)
{ {
const float x1 = l1.x1; const float x1 = l1.x1;
const float y1 = l1.y1; const float y1 = l1.y1;
@@ -276,7 +277,7 @@ SDL_Point checkCollision(line_t &l1, line_t &l2)
} }
// Detector de colisiones entre dos lineas // Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2) SDL_Point checkCollision(const LineDiagonal &l1, const LineVertical &l2)
{ {
const float x1 = l1.x1; const float x1 = l1.x1;
const float y1 = l1.y1; const float y1 = l1.y1;
@@ -305,7 +306,7 @@ SDL_Point checkCollision(d_line_t &l1, v_line_t &l2)
} }
// Normaliza una linea diagonal // Normaliza una linea diagonal
void normalizeLine(d_line_t &l) void normalizeLine(LineDiagonal &l)
{ {
// Las lineas diagonales van de izquierda a derecha // Las lineas diagonales van de izquierda a derecha
// x2 mayor que x1 // x2 mayor que x1
@@ -321,7 +322,7 @@ void normalizeLine(d_line_t &l)
} }
// Detector de colisiones entre un punto y una linea diagonal // Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l) bool checkCollision(const SDL_Point &p, const LineDiagonal &l)
{ {
// Comprueba si el punto está en alineado con la linea // Comprueba si el punto está en alineado con la linea
if (abs(p.x - l.x1) != abs(p.y - l.y1)) if (abs(p.x - l.x1) != abs(p.y - l.y1))
@@ -464,36 +465,30 @@ bool colorAreEqual(Color color1, Color color2)
return (r && g && b); return (r && g && b);
} }
// Convierte una cadena a minusculas // Convierte una cadena a minúsculas
std::string toLower(std::string str) std::string toLower(std::string str)
{ {
const char *original = str.c_str(); for (char &c : str)
char *lower = (char *)malloc(str.size() + 1);
for (int i = 0; i < (int)str.size(); ++i)
{ {
char c = original[i]; if (c >= 'A' && c <= 'Z')
lower[i] = (c >= 65 && c <= 90) ? c + 32 : c; {
c += 32; // Convierte a minúscula
}
} }
lower[str.size()] = 0; return str;
std::string result(lower);
free(lower);
return result;
} }
// Convierte una cadena a mayúsculas // Convierte una cadena a mayúsculas
std::string toUpper(std::string str) std::string toUpper(std::string str)
{ {
const char *original = str.c_str(); for (char &c : str)
char *upper = (char *)malloc(str.size() + 1);
for (int i = 0; i < (int)str.size(); ++i)
{ {
char c = original[i]; if (c >= 'a' && c <= 'z')
upper[i] = (c >= 97 && c <= 122) ? c - 32 : c; {
c -= 32; // Convierte a mayúscula
}
} }
upper[str.size()] = 0; return str;
std::string result(upper);
free(upper);
return result;
} }
// Obtiene el nombre de un fichero a partir de una ruta completa // Obtiene el nombre de un fichero a partir de una ruta completa
@@ -531,18 +526,18 @@ bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
// Hace sonar la música // Hace sonar la música
void playMusic(const std::string &music_path) void playMusic(const std::string &music_path)
{ {
// Si la música no está sonando // Si la música no está sonando
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED) if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED)
{ {
JA_PlayMusic(Resource::get()->getMusic(music_path)); JA_PlayMusic(Resource::get()->getMusic(music_path));
} }
} }
// Rellena una textura de un color // Rellena una textura de un color
void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a) void fillTextureWithColor(SDL_Renderer *renderer, SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{ {
// Guardar el render target actual // Guardar el render target actual
SDL_Texture* previous_target = SDL_GetRenderTarget(renderer); SDL_Texture *previous_target = SDL_GetRenderTarget(renderer);
// Establecer la textura como el render target // Establecer la textura como el render target
SDL_SetRenderTarget(renderer, texture); SDL_SetRenderTarget(renderer, texture);
@@ -556,3 +551,21 @@ void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r,
// Restaurar el render target previo // Restaurar el render target previo
SDL_SetRenderTarget(renderer, previous_target); SDL_SetRenderTarget(renderer, previous_target);
} }
// Crea un SDL_Texture
SDL_Texture *createTexture(SDL_Renderer *renderer, int width, int height, Uint32 format, int access, bool logError)
{
// Crear la textura
SDL_Texture *texture = SDL_CreateTexture(renderer, format, access, width, height);
if (texture == nullptr)
{
// Registrar el error si está habilitado
if (logError)
{
std::cerr << "Error: Texture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
return nullptr;
}
return texture;
}

View File

@@ -1,12 +1,10 @@
#pragma once #pragma once
#include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point #include <SDL2/SDL_rect.h> // for SDL_Rect, SDL_Point
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint8 #include <SDL2/SDL_stdinc.h> // for Uint8
#include <string> // for string #include <string> // for string
#include <vector> #include <vector> // for vector
#include <SDL2/SDL_render.h> // for SDL_Renderer
#include <SDL2/SDL.h> // for SDL_Texture
// Tipos de paleta // Tipos de paleta
enum class Palette : int enum class Palette : int
@@ -24,25 +22,25 @@ struct Circle
}; };
// Estructura para definir una linea horizontal // Estructura para definir una linea horizontal
struct h_line_t struct LineHorizontal
{ {
int x1, x2, y; int x1, x2, y;
}; };
// Estructura para definir una linea vertical // Estructura para definir una linea vertical
struct v_line_t struct LineVertical
{ {
int x, y1, y2; int x, y1, y2;
}; };
// Estructura para definir una linea diagonal // Estructura para definir una linea diagonal
struct d_line_t struct LineDiagonal
{ {
int x1, y1, x2, y2; int x1, y1, x2, y2;
}; };
// Estructura para definir una linea // Estructura para definir una linea
struct line_t struct Line
{ {
int x1, y1, x2, y2; int x1, y1, x2, y2;
}; };
@@ -66,37 +64,37 @@ struct Color
double distanceSquared(int x1, int y1, int x2, int y2); double distanceSquared(int x1, int y1, int x2, int y2);
// Detector de colisiones entre dos circulos // Detector de colisiones entre dos circulos
bool checkCollision(Circle &a, Circle &b); bool checkCollision(const Circle &a, const Circle &b);
// Detector de colisiones entre un circulo y un rectangulo // Detector de colisiones entre un circulo y un rectangulo
bool checkCollision(Circle &a, SDL_Rect &b); bool checkCollision(const Circle &a, const SDL_Rect &b);
// Detector de colisiones entre un dos rectangulos // Detector de colisiones entre un dos rectangulos
bool checkCollision(SDL_Rect &a, SDL_Rect &b); bool checkCollision(const SDL_Rect &a, const SDL_Rect &b);
// Detector de colisiones entre un punto y un rectangulo // Detector de colisiones entre un punto y un rectangulo
bool checkCollision(SDL_Point &p, SDL_Rect &r); bool checkCollision(const SDL_Point &p, const SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un rectangulo // Detector de colisiones entre una linea horizontal y un rectangulo
bool checkCollision(h_line_t &l, SDL_Rect &r); bool checkCollision(const LineHorizontal &l, const SDL_Rect &r);
// Detector de colisiones entre una linea vertical y un rectangulo // Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r); bool checkCollision(const LineVertical &l, const SDL_Rect &r);
// Detector de colisiones entre una linea horizontal y un punto // Detector de colisiones entre una linea horizontal y un punto
bool checkCollision(h_line_t &l, SDL_Point &p); bool checkCollision(const LineHorizontal &l, const SDL_Point &p);
// Detector de colisiones entre dos lineas // Detector de colisiones entre dos lineas
SDL_Point checkCollision(line_t &l1, line_t &l2); SDL_Point checkCollision(const Line &l1, const Line &l2);
// Detector de colisiones entre dos lineas // Detector de colisiones entre dos lineas
SDL_Point checkCollision(d_line_t &l1, v_line_t &l2); SDL_Point checkCollision(const LineDiagonal &l1, const LineVertical &l2);
// Detector de colisiones entre un punto y una linea diagonal // Detector de colisiones entre un punto y una linea diagonal
bool checkCollision(SDL_Point &p, d_line_t &l); bool checkCollision(const SDL_Point &p, const LineDiagonal &l);
// Normaliza una linea diagonal // Normaliza una linea diagonal
void normalizeLine(d_line_t &l); void normalizeLine(LineDiagonal &l);
// Devuelve un Color a partir de un string // Devuelve un Color a partir de un string
Color stringToColor(Palette pal, const std::string &str); Color stringToColor(Palette pal, const std::string &str);
@@ -135,4 +133,7 @@ bool stringInVector(const std::vector<std::string> &vec, const std::string &str)
void playMusic(const std::string &music_path); void playMusic(const std::string &music_path);
// Rellena una textura de un color // Rellena una textura de un color
void fillTextureWithColor(SDL_Renderer* renderer, SDL_Texture* texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a); void fillTextureWithColor(SDL_Renderer *renderer, SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
// Crea un SDL_Texture
SDL_Texture *createTexture(SDL_Renderer *renderer, int width, int height, Uint32 format = SDL_PIXELFORMAT_RGBA8888, int access = SDL_TEXTUREACCESS_TARGET, bool logError = false);