Transició a surface: game.cpp fet

This commit is contained in:
2025-03-03 19:15:24 +01:00
parent c9e75ad5c8
commit d7e0178602
18 changed files with 177 additions and 92 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

View File

@@ -7,7 +7,7 @@
#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 "s_animated_sprite.h" // for AnimatedSprite #include "s_animated_sprite.h" // for SAnimatedSprite
#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
@@ -18,7 +18,7 @@
// Constructor // Constructor
Credits::Credits() Credits::Credits()
: shining_sprite_(std::make_shared<AnimatedSprite>(Resource::get()->getSurface("shine.gif"), Resource::get()->getAnimations("shine.ani"))) : shining_sprite_(std::make_shared<SAnimatedSprite>(Resource::get()->getSurface("shine.gif"), Resource::get()->getAnimations("shine.ani")))
{ {
// Inicializa variables // Inicializa variables
options.section.section = Section::CREDITS; options.section.section = Section::CREDITS;
@@ -29,23 +29,15 @@ Credits::Credits()
Screen::get()->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_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height); text_surface_ = std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), options.game.width, options.game.height);
// Crea la textura para cubrir el rexto // Crea la textura para cubrir el rexto
cover_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, options.game.height); cover_surface_ = std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), options.game.width, options.game.height);
SDL_SetTextureBlendMode(cover_texture_, SDL_BLENDMODE_BLEND);
// Escribe el texto en la textura // Escribe el texto en la textura
fillTexture(); fillTexture();
} }
// Destructor
Credits::~Credits()
{
SDL_DestroyTexture(text_texture_);
SDL_DestroyTexture(cover_texture_);
}
// Comprueba el manejador de eventos // Comprueba el manejador de eventos
void Credits::checkEvents() void Credits::checkEvents()
{ {
@@ -150,10 +142,8 @@ void Credits::fillTexture()
iniTexts(); iniTexts();
// Rellena la textura de texto // Rellena la textura de texto
SDL_SetRenderTarget(Screen::get()->getRenderer(), text_texture_); Screen::get()->setRenderSurfaceData(text_surface_);
Color color = stringToColor(options.video.palette, "black"); Screen::get()->clean(stringToColor("black"));
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(Screen::get()->getRenderer());
auto text = Resource::get()->getText("smb2"); auto text = Resource::get()->getText("smb2");
@@ -178,28 +168,28 @@ void Credits::fillTexture()
SDL_SetRenderTarget(Screen::get()->getRenderer(), 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(Screen::get()->getRenderer(), cover_texture_); Screen::get()->setRenderSurfaceData(text_surface_);
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0x00); Screen::get()->clean(stringToColor("transparent"));
SDL_RenderClear(Screen::get()->getRenderer());
// Los primeros 8 pixels crea una malla // Los primeros 8 pixels crea una malla
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF); auto surface = Screen::get()->getRenderSurfaceData();
auto color = stringToColor("black");
for (int i = 0; i < 256; i += 2) for (int i = 0; i < 256; i += 2)
{ {
SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 0); text_surface_->putPixel(surface, i, 0, color);
SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 2); text_surface_->putPixel(surface, i, 2, color);
SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 4); text_surface_->putPixel(surface, i, 4, color);
SDL_RenderDrawPoint(Screen::get()->getRenderer(), i, 6); text_surface_->putPixel(surface, i, 6, color);
SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 5); text_surface_->putPixel(surface, i + 1, 5, color);
SDL_RenderDrawPoint(Screen::get()->getRenderer(), i + 1, 7); text_surface_->putPixel(surface, i + 1, 7, color);
} }
// 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(Screen::get()->getRenderer(), &rect); text_surface_->fillRect(surface, &rect, color);
SDL_SetRenderTarget(Screen::get()->getRenderer(), nullptr); Screen::get()->setRenderSurfaceData(nullptr);
} }
// Actualiza el contador // Actualiza el contador
@@ -263,18 +253,17 @@ void Credits::render()
Screen::get()->start(); Screen::get()->start();
// Limpia la pantalla // Limpia la pantalla
Screen::get()->clean(); Screen::get()->clean(1);
if (counter_ < 1150) if (counter_ < 1150)
{ {
// Dibuja la textura con el texto en pantalla // Dibuja la textura con el texto en pantalla
SDL_RenderCopy(Screen::get()->getRenderer(), text_texture_, nullptr, nullptr); text_surface_->render(0, 0);
// 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)}; cover_surface_->render(0, offset * 2, &srcRect);
SDL_RenderCopy(Screen::get()->getRenderer(), cover_texture_, &srcRect, &dstRect);
// Dibuja el sprite con el brillo // Dibuja el sprite con el brillo
shining_sprite_->render(); shining_sprite_->render();

View File

@@ -6,7 +6,9 @@
#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 9-9 #include <memory>
#include "surface.h"
class SAnimatedSprite; // lines 9-9
class Credits class Credits
{ {
@@ -18,9 +20,9 @@ private:
}; };
// Objetos y punteros // Objetos y punteros
SDL_Texture *text_texture_; // Textura para dibujar el texto std::shared_ptr<Surface> text_surface_; // Textura para dibujar el texto
SDL_Texture *cover_texture_; // Textura para cubrir el texto std::shared_ptr<Surface> cover_surface_; // Textura para cubrir el texto
std::shared_ptr<AnimatedSprite> shining_sprite_; // Sprite para el brillo del corazón std::shared_ptr<SAnimatedSprite> shining_sprite_; // Sprite para el brillo del corazón
// Variables // Variables
int counter_ = 0; // Contador int counter_ = 0; // Contador
@@ -55,7 +57,7 @@ public:
Credits(); Credits();
// Destructor // Destructor
~Credits(); ~Credits() = default;
// Bucle principal // Bucle principal
void run(); void run();

View File

@@ -394,6 +394,13 @@ bool Director::setFileList()
Asset::get()->add(prefix + "/data/font/8bithud.gif", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/8bithud.gif", AssetType::BITMAP);
Asset::get()->add(prefix + "/data/font/8bithud.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/8bithud.txt", AssetType::FONT);
// Paletas
Asset::get()->add(prefix + "/data/palette/ruzx-spectrum-8x.gif", AssetType::DATA);
Asset::get()->add(prefix + "/data/palette/ruzx-spectrum-revision-2-8x.gif", AssetType::DATA);
Asset::get()->add(prefix + "/data/palette/zxarne-5-2-8x.gif", AssetType::DATA);
Asset::get()->add(prefix + "/data/palette/zx-spectrum-8x.gif", AssetType::DATA);
Asset::get()->add(prefix + "/data/palette/zx-spectrum-adjusted-8x.gif", AssetType::DATA);
// Shaders // Shaders
Asset::get()->add(prefix + "/data/shaders/crtpi_192.glsl", AssetType::DATA); Asset::get()->add(prefix + "/data/shaders/crtpi_192.glsl", AssetType::DATA);
Asset::get()->add(prefix + "/data/shaders/crtpi_240.glsl", AssetType::DATA); Asset::get()->add(prefix + "/data/shaders/crtpi_240.glsl", AssetType::DATA);

View File

@@ -66,7 +66,6 @@ Game::Game(GameMode mode)
Game::~Game() Game::~Game()
{ {
ItemTracker::destroy(); ItemTracker::destroy();
SDL_DestroyTexture(room_name_texture_);
} }
// Comprueba los eventos de la cola // Comprueba los eventos de la cola
@@ -288,7 +287,7 @@ void Game::checkDebugEvents(const SDL_Event &event)
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(Screen::get()->getRenderer(), room_name_texture_, nullptr, &room_name_rect_); room_name_surface_->render(nullptr, &room_name_rect_);
} }
// Cambia de habitación // Cambia de habitación
@@ -561,19 +560,17 @@ 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(Screen::get()->getRenderer(), room_name_texture_); Screen::get()->setRenderSurfaceData(room_name_surface_);
// Rellena la textura de color // Rellena la textura de color
const Color color = stringToColor(options.video.palette, "white"); Screen::get()->clean(stringToColor("white"));
SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF);
SDL_RenderClear(Screen::get()->getRenderer());
// Escribe el texto en la textura // Escribe el texto en la textura
auto text = Resource::get()->getText("smb2"); auto text = Resource::get()->getText("smb2");
text->writeDX(TEXT_CENTER | TEXT_COLOR, GAMECANVAS_CENTER_X, text->getCharacterSize() / 2, room_->getName(), 1, room_->getBGColor()); 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(Screen::get()->getRenderer(), nullptr); Screen::get()->setRenderSurfaceData(nullptr);
} }
// Comprueba algunos logros // Comprueba algunos logros
@@ -663,8 +660,7 @@ void Game::initPlayer(const PlayerSpawn &spawn_point, std::shared_ptr<Room> room
void Game::createRoomNameTexture() void Game::createRoomNameTexture()
{ {
auto text = Resource::get()->getText("smb2"); auto text = Resource::get()->getText("smb2");
room_name_texture_ = createTexture(Screen::get()->getRenderer(), options.game.width, text->getCharacterSize() * 2); room_name_surface_ = std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), options.game.width, text->getCharacterSize() * 2);
SDL_SetTextureBlendMode(room_name_texture_, SDL_BLENDMODE_BLEND);
// Establece el destino de la textura // Establece el destino de la textura
room_name_rect_ = {0, PLAY_AREA_HEIGHT, options.game.width, text->getCharacterSize() * 2}; room_name_rect_ = {0, PLAY_AREA_HEIGHT, options.game.width, text->getCharacterSize() * 2};

View File

@@ -8,11 +8,12 @@
#include <string> // for string #include <string> // for string
#include <vector> // for vector #include <vector> // for vector
#include "player.h" // for PlayerSpawn #include "player.h" // for PlayerSpawn
class Room; // lines 10-10 #include "surface.h"
class RoomTracker; // lines 11-11 class Room; // lines 10-10
class Scoreboard; // lines 12-12 class RoomTracker; // lines 11-11
class Stats; // lines 13-13 class Scoreboard; // lines 12-12
struct ScoreboardData; // lines 14-14 class Stats; // lines 13-13
struct ScoreboardData; // lines 14-14
enum class GameMode enum class GameMode
{ {
@@ -41,13 +42,13 @@ private:
}; };
// Objetos y punteros // Objetos y punteros
std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador std::shared_ptr<ScoreboardData> board_; // Estructura con los datos del marcador
std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador std::shared_ptr<Scoreboard> scoreboard_; // Objeto encargado de gestionar el marcador
std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas std::shared_ptr<RoomTracker> room_tracker_; // Lleva el control de las habitaciones visitadas
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<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 std::shared_ptr<Surface> room_name_surface_; // Textura para escribir el nombre de la habitación
// Variables // Variables
GameMode mode_; // Modo del juego GameMode mode_; // Modo del juego

View File

@@ -22,7 +22,7 @@ LoadingScreen::LoadingScreen()
color_loading_screen_surface_(Resource::get()->getSurface("loading_screen_color.gif")), color_loading_screen_surface_(Resource::get()->getSurface("loading_screen_color.gif")),
mono_loading_screen_sprite_(std::make_shared<SSprite>(mono_loading_screen_surface_, 0, 0, mono_loading_screen_surface_->getWidth(), mono_loading_screen_surface_->getHeight())), mono_loading_screen_sprite_(std::make_shared<SSprite>(mono_loading_screen_surface_, 0, 0, mono_loading_screen_surface_->getWidth(), mono_loading_screen_surface_->getHeight())),
color_loading_screen_sprite_(std::make_shared<SSprite>(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_loading_screen_surface_->getHeight())), color_loading_screen_sprite_(std::make_shared<SSprite>(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_loading_screen_surface_->getHeight())),
screen_surface_(std::make_shared<Surface>(Screen::get()->getRenderSurface(), options.game.width, options.game.height)) screen_surface_(std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), options.game.width, options.game.height))
{ {
// Cambia el destino de las surfaces // Cambia el destino de las surfaces
mono_loading_screen_surface_->setSurfaceDataDest(screen_surface_->getSurfaceData()); mono_loading_screen_surface_->setSurfaceDataDest(screen_surface_->getSurfaceData());

View File

@@ -247,7 +247,7 @@ void Resource::loadSurfaces()
for (const auto &l : list) for (const auto &l : list)
{ {
auto name = getFileName(l); auto name = getFileName(l);
surfaces_.emplace_back(ResourceSurface(name, std::make_shared<Surface>(Screen::get()->getRenderSurface(), l))); surfaces_.emplace_back(ResourceSurface(name, std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), l)));
updateLoadingProgress(); updateLoadingProgress();
} }
} }

View File

@@ -61,6 +61,10 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
border_texture_ = createTexture(renderer, 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);
setBorderColor(border_color_); setBorderColor(border_color_);
// Crea la surface donde se vuelcan los datos
surface_ = std::make_shared<Surface>(nullptr, options.game.width, options.game.height);
surface_->loadPalette(Asset::get()->get("zx-spectrum-8x.gif"));
// Establece el modo de video // Establece el modo de video
setVideoMode(options.video.mode); setVideoMode(options.video.mode);
@@ -91,7 +95,11 @@ void Screen::clean(Uint8 index)
} }
// Prepara para empezar a dibujar en la textura de juego // Prepara para empezar a dibujar en la textura de juego
void Screen::start() { SDL_SetRenderTarget(renderer_, game_texture_); } void Screen::start()
{
SDL_SetRenderTarget(renderer_, game_texture_);
setRenderSurfaceData(nullptr);
}
// Prepara para empezar a dibujar en la textura del borde // Prepara para empezar a dibujar en la textura del borde
void Screen::startDrawOnBorder() { SDL_SetRenderTarget(renderer_, border_texture_); } void Screen::startDrawOnBorder() { SDL_SetRenderTarget(renderer_, border_texture_); }
@@ -348,7 +356,7 @@ void Screen::resetShaders()
} }
// Establece el renderizador para las surfaces // Establece el renderizador para las surfaces
void Screen::setRenderSurface(std::shared_ptr<Surface> surface) void Screen::setRenderSurfaceData(std::shared_ptr<Surface> surface)
{ {
(surface) ? surface_->redirectSurfaceDataTo(surface) : surface_->restoreOriginalSurfaceData(); (surface) ? surface_->redirectSurfaceDataTo(surface) : surface_->restoreOriginalSurfaceData();
} }

View File

@@ -134,13 +134,13 @@ public:
int getMaxZoom(); int getMaxZoom();
// Establece el renderizador para las surfaces // Establece el renderizador para las surfaces
void setRenderSurface(std::shared_ptr<Surface> surface); void setRenderSurfaceData(std::shared_ptr<Surface> surface = nullptr);
// Limpia // Limpia
// Getters // Getters
SDL_Renderer *getRenderer() { return renderer_; } SDL_Renderer *getRenderer() { return renderer_; }
std::shared_ptr<SurfaceData> getRenderSurface() { return surface_->getSurfaceData(); } std::shared_ptr<SurfaceData> getRenderSurfaceData() { return surface_->getSurfaceData(); }
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

@@ -107,21 +107,16 @@ void Surface::clear(Uint8 color)
std::fill(surface_data_->data, surface_data_->data + total_pixels, color); std::fill(surface_data_->data, surface_data_->data + total_pixels, color);
} }
// Pone un pixel en la superficie de destino // Pone un pixel en la SurfaceData
void Surface::putPixel(int x, int y, Uint8 color) void Surface::putPixel(std::shared_ptr<SurfaceData> surface_data, int x, int y, Uint8 color)
{ {
if (color == transparent_color_) if (x < 0 || y < 0 || x >= surface_data->width || y >= surface_data->height)
{
return; // Color transparente, no dibujar
}
if (x < 0 || y < 0 || x >= surface_data_dest_->width || y >= surface_data_dest_->height)
{ {
return; // Coordenadas fuera de rango return; // Coordenadas fuera de rango
} }
const int index = x + y * surface_data_dest_->width; const int index = x + y * surface_data->width;
surface_data_dest_->data[index] = color; surface_data->data[index] = color;
} }
// Obtiene el color de un pixel de la superficie de origen // Obtiene el color de un pixel de la superficie de origen
@@ -130,6 +125,29 @@ Uint8 Surface::getPixel(int x, int y)
return surface_data_->data[x + y * surface_data_->width]; return surface_data_->data[x + y * surface_data_->width];
} }
// Dibuja un rectangulo
void Surface::fillRect(std::shared_ptr<SurfaceData> surface_data, SDL_Rect *rect, Uint8 color)
{
if (!rect) return; // Verificar si el rectángulo es válido
// Limitar los valores del rectángulo al tamaño de la superficie
int x_start = std::max(0, rect->x);
int y_start = std::max(0, rect->y);
int x_end = std::min(rect->x + rect->w, static_cast<int>(surface_data->width));
int y_end = std::min(rect->y + rect->h, static_cast<int>(surface_data->height));
// Recorrer cada píxel dentro del rectángulo directamente
for (int y = y_start; y < y_end; ++y)
{
for (int x = x_start; x < x_end; ++x)
{
const int index = x + y * surface_data->width;
surface_data->data[index] = color;
}
}
}
// Copia una región de la superficie de origen a la de destino // Copia una región de la superficie de origen a la de destino
void Surface::render(int dx, int dy, int sx, int sy, int w, int h) void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
{ {
@@ -158,7 +176,7 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
} }
// Copia una región de la superficie de origen a la de destino // Copia una región de la superficie de origen a la de destino
void Surface::render(int x, int y, SDL_Rect *clip, SDL_RendererFlip flip) void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
{ {
if (!surface_data_ || !surface_data_dest_) if (!surface_data_ || !surface_data_dest_)
{ {
@@ -166,10 +184,10 @@ void Surface::render(int x, int y, SDL_Rect *clip, SDL_RendererFlip flip)
} }
// Determina la región de origen (clip) a renderizar // Determina la región de origen (clip) a renderizar
int sx = (clip) ? clip->x : 0; int sx = (srcRect) ? srcRect->x : 0;
int sy = (clip) ? clip->y : 0; int sy = (srcRect) ? srcRect->y : 0;
int w = (clip) ? clip->w : surface_data_->width; int w = (srcRect) ? srcRect->w : surface_data_->width;
int h = (clip) ? clip->h : surface_data_->height; int h = (srcRect) ? srcRect->h : surface_data_->height;
// 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_data_->width - sx); w = std::min(w, surface_data_->width - sx);
@@ -200,6 +218,65 @@ void Surface::render(int x, int y, SDL_Rect *clip, SDL_RendererFlip flip)
} }
} }
// Copia una región de la superficie de origen a la de destino
void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip)
{
if (!surface_data_ || !surface_data_dest_)
{
throw std::runtime_error("Surface source or destination is null.");
}
// Si srcRect es nullptr, tomar toda la superficie fuente
int sx = (srcRect) ? srcRect->x : 0;
int sy = (srcRect) ? srcRect->y : 0;
int sw = (srcRect) ? srcRect->w : surface_data_->width;
int sh = (srcRect) ? srcRect->h : surface_data_->height;
// Si dstRect es nullptr, asignar las mismas dimensiones que srcRect
int dx = (dstRect) ? dstRect->x : 0;
int dy = (dstRect) ? dstRect->y : 0;
int dw = (dstRect) ? dstRect->w : sw;
int dh = (dstRect) ? dstRect->h : sh;
// Asegurarse de que srcRect y dstRect tienen las mismas dimensiones
if (sw != dw || sh != dh)
{
dw = sw; // Respetar las dimensiones de srcRect
dh = sh;
}
// Limitar la región para evitar accesos fuera de rango en src y dst
sw = std::min(sw, surface_data_->width - sx);
sh = std::min(sh, surface_data_->height - sy);
dw = std::min(dw, surface_data_dest_->width - dx);
dh = std::min(dh, surface_data_dest_->height - dy);
int final_width = std::min(sw, dw);
int final_height = std::min(sh, dh);
// Renderiza píxel por píxel aplicando el flip si es necesario
for (int iy = 0; iy < final_height; ++iy)
{
for (int ix = 0; ix < final_width; ++ix)
{
// Coordenadas de origen
int src_x = (flip == SDL_FLIP_HORIZONTAL) ? (sx + final_width - 1 - ix) : (sx + ix);
int src_y = (flip == SDL_FLIP_VERTICAL) ? (sy + final_height - 1 - iy) : (sy + iy);
// Coordenadas de destino
int dest_x = dx + ix;
int dest_y = dy + iy;
// Copiar el píxel si no es transparente
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = color;
}
}
}
}
// Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro // Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro
void Surface::renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE) void Surface::renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE)
{ {

View File

@@ -66,12 +66,6 @@ private:
std::array<Uint32, 256> palette_; // Paleta para volcar la SurfaceData a una Textura std::array<Uint32, 256> palette_; // Paleta para volcar la SurfaceData a una Textura
int transparent_color_; // Indice de la paleta que se omite en la copia de datos int transparent_color_; // Indice de la paleta que se omite en la copia de datos
// Pone un pixel en la superficie de destino
void putPixel(int x, int y, Uint8 color);
// Obtiene el color de un pixel de la superficie de origen
Uint8 getPixel(int x, int y);
public: public:
// Constructor // Constructor
Surface(std::shared_ptr<SurfaceData> surface_data_dest, int w, int h); Surface(std::shared_ptr<SurfaceData> surface_data_dest, int w, int h);
@@ -89,6 +83,7 @@ public:
// Copia una región de la SurfaceData de origen a la SurfaceData de destino // Copia una región de la SurfaceData de origen a la SurfaceData de destino
void render(int dx, int dy, int sx, int sy, int w, int h); void render(int dx, int dy, int sx, int sy, int w, int h);
void render(int x, int y, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE); void render(int x, int y, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
void render(SDL_Rect *srcRect = nullptr, SDL_Rect *dstRect = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
// Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro // Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro
void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE); void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE);
@@ -105,6 +100,15 @@ public:
// Realiza un efecto de fundido en la paleta // Realiza un efecto de fundido en la paleta
bool fadePalette(); bool fadePalette();
// Pone un pixel en la SurfaceData
void putPixel(std::shared_ptr<SurfaceData> surface_data, int x, int y, Uint8 color);
// Obtiene el color de un pixel de la superficie de origen
Uint8 getPixel(int x, int y);
// Dibuja un rectangulo
void fillRect(std::shared_ptr<SurfaceData> surface_data, SDL_Rect *rect, Uint8 color);
// Getters // Getters
std::shared_ptr<SurfaceData> getSurfaceData() const { return surface_data_; } std::shared_ptr<SurfaceData> getSurfaceData() const { return surface_data_; }
int getTransparentColor() const { return transparent_color_; } int getTransparentColor() const { return transparent_color_; }

View File

@@ -25,7 +25,7 @@
Title::Title() Title::Title()
: surface_(Resource::get()->getSurface("title_logo.gif")), : surface_(Resource::get()->getSurface("title_logo.gif")),
sprite_(std::make_shared<SSprite>(surface_, 0, 0, surface_->getWidth(), surface_->getHeight())), sprite_(std::make_shared<SSprite>(surface_, 0, 0, surface_->getWidth(), surface_->getHeight())),
bg_surface_(std::make_shared<Surface>(Screen::get()->getRenderSurface(), options.game.width, options.game.height)) bg_surface_(std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), options.game.width, options.game.height))
{ {
// 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(Screen::get()->getRenderer(), 256, 128); pInit(Screen::get()->getRenderer(), 256, 128);
@@ -251,7 +251,7 @@ void Title::render()
if (state_ == TitleState::SHOW_MENU) if (state_ == TitleState::SHOW_MENU)
{ {
// Dibuja la textura de fondo // Dibuja la textura de fondo
SDL_RenderCopy(Screen::get()->getRenderer(), bg_surface_, nullptr, nullptr); bg_surface_->render(0, 0);
// Dibuja la marquesina // Dibuja la marquesina
renderMarquee(); renderMarquee();
@@ -311,7 +311,7 @@ void Title::moveCheevosList(int direction)
void Title::fillSurface() void Title::fillSurface()
{ {
// Coloca el puntero del renderizador sobre la textura // Coloca el puntero del renderizador sobre la textura
Screen::get()->setRenderSurface(bg_surface_); Screen::get()->setRenderSurfaceData(bg_surface_);
// Rellena la textura de color // Rellena la textura de color
bg_surface_->setColor(255, 0xFF000000); bg_surface_->setColor(255, 0xFF000000);
@@ -330,7 +330,7 @@ void Title::fillSurface()
text->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 20 * TEXT_SIZE, "ESC.EXIT GAME", 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
Screen::get()->setRenderSurface(nullptr); Screen::get()->setRenderSurfaceData(nullptr);
} }
// Crea y rellena la textura para mostrar los logros // Crea y rellena la textura para mostrar los logros
@@ -345,10 +345,10 @@ void Title::createCheevosTexture()
constexpr int CHEEVOS_PADDING = 10; constexpr int CHEEVOS_PADDING = 10;
const int CHEEVO_HEIGHT = CHEEVOS_PADDING + (TEXT->getCharacterSize() * 2) + 1; const int CHEEVO_HEIGHT = CHEEVOS_PADDING + (TEXT->getCharacterSize() * 2) + 1;
const int CHEEVOS_TEXTURE_HEIGHT = (CHEEVO_HEIGHT * CHEEVOS_LIST.size()) + 2 + TEXT->getCharacterSize() + 8; const int CHEEVOS_TEXTURE_HEIGHT = (CHEEVO_HEIGHT * CHEEVOS_LIST.size()) + 2 + TEXT->getCharacterSize() + 8;
cheevos_surface_ = std::make_shared<Surface>(Screen::get()->getRenderSurface(), CHEEVOS_TEXTURE_WIDTH, CHEEVOS_TEXTURE_HEIGHT); cheevos_surface_ = std::make_shared<Surface>(Screen::get()->getRenderSurfaceData(), CHEEVOS_TEXTURE_WIDTH, CHEEVOS_TEXTURE_HEIGHT);
// Prepara para dibujar sobre la textura // Prepara para dibujar sobre la textura
Screen::get()->setRenderSurface(cheevos_surface_); Screen::get()->setRenderSurfaceData(cheevos_surface_);
// Rellena la textura con color sólido // Rellena la textura con color sólido
const Color CHEEVOS_BG_COLOR = stringToColor(options.video.palette, "black"); const Color CHEEVOS_BG_COLOR = stringToColor(options.video.palette, "black");
@@ -381,7 +381,7 @@ void Title::createCheevosTexture()
} }
// Restablece el RenderSurface // Restablece el RenderSurface
Screen::get()->setRenderSurface(nullptr); Screen::get()->setRenderSurfaceData(nullptr);
// Crea el sprite para el listado de logros // Crea el sprite para el listado de logros
cheevos_sprite_ = std::make_shared<SSprite>(cheevos_surface_, (GAMECANVAS_WIDTH - cheevos_surface_->getWidth()) / 2, CHEEVOS_TEXTURE_POS_Y, cheevos_surface_->getWidth(), cheevos_surface_->getHeight()); cheevos_sprite_ = std::make_shared<SSprite>(cheevos_surface_, (GAMECANVAS_WIDTH - cheevos_surface_->getWidth()) / 2, CHEEVOS_TEXTURE_POS_Y, cheevos_surface_->getWidth(), cheevos_surface_->getHeight());

View File

@@ -433,6 +433,7 @@ Uint8 stringToColor(const std::string &str)
{ {
// Mapas de colores para cada paleta // Mapas de colores para cada paleta
static const std::unordered_map<std::string, Uint8> paletteMap = { static const std::unordered_map<std::string, Uint8> paletteMap = {
{"transparent", 0},
{"black", 1}, {"black", 1},
{"bright_black", 2}, {"bright_black", 2},
{"blue", 3}, {"blue", 3},