Compare commits

4 Commits

8 changed files with 174 additions and 76 deletions

View File

@@ -270,7 +270,7 @@ bool setOptions(const std::string &var, const std::string &value)
} }
else else
{ {
options.video.palette = DEFAULT_PALETTE; options.video.palette = val;
} }
}}}; }}};

View File

@@ -403,6 +403,7 @@ void Resource::calculateTotal()
AssetType::SOUND, AssetType::SOUND,
AssetType::MUSIC, AssetType::MUSIC,
AssetType::BITMAP, AssetType::BITMAP,
AssetType::PALETTE,
AssetType::FONT, AssetType::FONT,
AssetType::ANIMATION, AssetType::ANIMATION,
AssetType::TILEMAP, AssetType::TILEMAP,
@@ -431,12 +432,12 @@ void Resource::renderProgress()
auto surface = Screen::get()->getRendererSurface(); auto surface = Screen::get()->getRendererSurface();
const int wired_bar_width = options.game.width - (X_PADDING * 2); const int wired_bar_width = options.game.width - (X_PADDING * 2);
SDL_Rect rect_wired = {X_PADDING, bar_position, wired_bar_width, X_PADDING}; SDL_Rect rect_wired = {X_PADDING, bar_position, wired_bar_width, X_PADDING};
surface->fillRect(&rect_wired, stringToColor("blue")); surface->drawRectBorder(&rect_wired, stringToColor("white"));
const int full_bar_width = wired_bar_width * count_.getPercentage(); const int full_bar_width = wired_bar_width * count_.getPercentage();
SDL_Rect rect_full = {X_PADDING, bar_position, full_bar_width, X_PADDING}; SDL_Rect rect_full = {X_PADDING, bar_position, full_bar_width, X_PADDING};
surface->fillRect(&rect_full, stringToColor("white")); surface->fillRect(&rect_full, stringToColor("white"));
Screen::get()->render(); Screen::get()->render();
} }

View File

@@ -46,6 +46,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
// Ajusta los tamaños // Ajusta los tamaños
adjustGameCanvasRect(); adjustGameCanvasRect();
adjustWindowSize(); adjustWindowSize();
current_palette_ = findPalette(options.video.palette);
// Define el color del borde para el modo de pantalla completa // Define el color del borde para el modo de pantalla completa
border_color_ = 1; border_color_ = 1;
@@ -75,13 +76,24 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
} }
} }
// Crea la textura donde se dibuja el borde que rodea el area de juego
shaders_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);
if (!shaders_texture_)
{
// Registrar el error si está habilitado
if (options.console)
{
std::cerr << "Error: shaders_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
// Crea la surface donde se dibujan los graficos del juego // Crea la surface donde se dibujan los graficos del juego
game_surface_ = std::make_shared<Surface>(options.game.width, options.game.height); game_surface_ = std::make_shared<Surface>(options.game.width, options.game.height);
game_surface_->loadPalette(palettes_.front()); game_surface_->loadPalette(palettes_.at(current_palette_));
// Crea la surface donde se dibujan los graficos del juego // Crea la surface donde se dibujan los graficos del juego
border_surface_ = std::make_shared<Surface>(options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); border_surface_ = std::make_shared<Surface>(options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2);
border_surface_->loadPalette(palettes_.front()); border_surface_->loadPalette(palettes_.at(current_palette_));
// Establece la surface que actuará como renderer para recibir las llamadas a render() // Establece la surface que actuará como renderer para recibir las llamadas a render()
renderer_surface_ = std::make_shared<std::shared_ptr<Surface>>(game_surface_); renderer_surface_ = std::make_shared<std::shared_ptr<Surface>>(game_surface_);
@@ -102,6 +114,7 @@ Screen::~Screen()
{ {
SDL_DestroyTexture(game_texture_); SDL_DestroyTexture(game_texture_);
SDL_DestroyTexture(border_texture_); SDL_DestroyTexture(border_texture_);
SDL_DestroyTexture(shaders_texture_);
} }
// Limpia la pantalla // Limpia la pantalla
@@ -127,23 +140,14 @@ void Screen::start()
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::render() void Screen::render()
{ {
// Renderiza sobre game_surface_ los overlays // Renderiza todos los overlays
renderNotifications(); renderOverlays();
// Si está el borde activo, vuelca gameCanvas sobre borderCanvas // Copia la surface a la textura
if (options.video.border.enabled) surfaceToTexture();
{
setRendererSurface(border_surface_);
game_surface_->render(options.video.border.width, options.video.border.height);
border_surface_->copyToTexture(renderer_, border_texture_);
}
else
{
game_surface_->copyToTexture(renderer_, game_texture_);
}
// Muestra el contenido por pantalla // Copia la textura al renderizador
renderPresent(); textureToRenderer();
} }
// Establece el modo de video // Establece el modo de video
@@ -233,6 +237,7 @@ 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;
createShadersTexture();
setVideoMode(options.video.mode); setVideoMode(options.video.mode);
} }
@@ -245,32 +250,6 @@ void Screen::renderNotifications()
} }
} }
// Muestra el contenido de Screen por pantalla
void Screen::renderPresent()
{
SDL_SetRenderTarget(renderer_, nullptr);
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer_);
if (options.video.shaders)
{
// Aplica shaders y renderiza el contenido
shader::render();
}
else
{
if (options.video.border.enabled)
{
SDL_RenderCopy(renderer_, border_texture_, nullptr, nullptr);
}
else
{
SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_rect_);
}
SDL_RenderPresent(renderer_);
}
}
// Cambia el estado de los shaders // Cambia el estado de los shaders
void Screen::toggleShaders() void Screen::toggleShaders()
{ {
@@ -354,7 +333,7 @@ void Screen::resetShaders()
std::ifstream f(Asset::get()->get(GLSL_FILE).c_str()); std::ifstream f(Asset::get()->get(GLSL_FILE).c_str());
std::string source((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>()); 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()); shader::init(window_, shaders_texture_, source.c_str());
} }
} }
@@ -396,4 +375,83 @@ void Screen::processPaletteList()
{ {
palette = getFileName(palette); palette = getFileName(palette);
} }
}
// Copia la surface a la textura
void Screen::surfaceToTexture()
{
// Si está el borde activo, vuelca gameCanvas sobre borderCanvas
if (options.video.border.enabled)
{
setRendererSurface(border_surface_);
game_surface_->render(options.video.border.width, options.video.border.height);
border_surface_->copyToTexture(renderer_, border_texture_);
}
else
{
game_surface_->copyToTexture(renderer_, game_texture_);
}
}
// Copia la textura al renderizador
void Screen::textureToRenderer()
{
SDL_Texture *texture_to_render = options.video.border.enabled ? border_texture_ : game_texture_;
if (options.video.shaders)
{
SDL_SetRenderTarget(renderer_, shaders_texture_);
SDL_RenderCopy(renderer_, texture_to_render, nullptr, nullptr);
SDL_SetRenderTarget(renderer_, nullptr);
shader::render();
}
else
{
SDL_SetRenderTarget(renderer_, nullptr);
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer_);
SDL_RenderCopy(renderer_, texture_to_render, nullptr, nullptr);
SDL_RenderPresent(renderer_);
}
}
// Renderiza todos los overlays
void Screen::renderOverlays()
{
renderNotifications();
}
// Localiza la paleta dentro del vector de paletas
size_t Screen::findPalette(const std::string &name)
{
std::string upper_name = toUpper(name + ".gif");
for (size_t i = 0; i < palettes_.size(); ++i)
{
if (toUpper(getFileName(palettes_[i])) == upper_name)
{
return i;
}
}
return static_cast<size_t>(0);
}
// Recrea la textura para los shaders
void Screen::createShadersTexture()
{
if (shaders_texture_)
{
SDL_DestroyTexture(shaders_texture_);
}
// Crea la textura donde se dibuja el borde que rodea el area de juego
shaders_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);
if (!shaders_texture_)
{
// Registrar el error si está habilitado
if (options.console)
{
std::cerr << "Error: shaders_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
}
}
} }

View File

@@ -30,6 +30,7 @@ private:
SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Renderer *renderer_; // El renderizador de la ventana
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
SDL_Texture *shaders_texture_; // Textura para aplicar los shaders
std::shared_ptr<Surface> game_surface_; // Surface principal para manejar game_surface_data_ std::shared_ptr<Surface> game_surface_; // Surface principal para manejar game_surface_data_
std::shared_ptr<Surface> border_surface_; // Surface para pintar el el borde de la pantalla std::shared_ptr<Surface> border_surface_; // Surface para pintar el el borde de la pantalla
std::shared_ptr<std::shared_ptr<Surface>> renderer_surface_; // Puntero a la Surface que actua std::shared_ptr<std::shared_ptr<Surface>> renderer_surface_; // Puntero a la Surface que actua
@@ -46,9 +47,6 @@ private:
// Dibuja las notificaciones // Dibuja las notificaciones
void renderNotifications(); void renderNotifications();
// Muestra el contenido de Screen por pantalla
void renderPresent();
// Calcula el tamaño de la ventana // Calcula el tamaño de la ventana
void adjustWindowSize(); void adjustWindowSize();
@@ -64,6 +62,21 @@ private:
// Extrae los nombres de las paletas // Extrae los nombres de las paletas
void processPaletteList(); void processPaletteList();
// Copia la surface a la textura
void surfaceToTexture();
// Copia la textura al renderizador
void textureToRenderer();
// Renderiza todos los overlays
void renderOverlays();
// Localiza la paleta dentro del vector de paletas
size_t findPalette(const std::string &name);
// Recrea la textura para los shaders
void createShadersTexture();
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer); Screen(SDL_Window *window, SDL_Renderer *renderer);

View File

@@ -137,7 +137,7 @@ 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 // Dibuja un rectangulo relleno
void Surface::fillRect(SDL_Rect *rect, Uint8 color) void Surface::fillRect(SDL_Rect *rect, Uint8 color)
{ {
// Limitar los valores del rectángulo al tamaño de la superficie // Limitar los valores del rectángulo al tamaño de la superficie
@@ -157,6 +157,40 @@ void Surface::fillRect(SDL_Rect *rect, Uint8 color)
} }
} }
// Dibuja el borde de un rectangulo
void Surface::drawRectBorder(SDL_Rect *rect, Uint8 color)
{
// 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));
// Dibujar bordes horizontales
for (int x = x_start; x < x_end; ++x)
{
// Borde superior
const int top_index = x + y_start * surface_data_->width;
surface_data_->data[top_index] = color;
// Borde inferior
const int bottom_index = x + (y_end - 1) * surface_data_->width;
surface_data_->data[bottom_index] = color;
}
// Dibujar bordes verticales
for (int y = y_start; y < y_end; ++y)
{
// Borde izquierdo
const int left_index = x_start + y * surface_data_->width;
surface_data_->data[left_index] = color;
// Borde derecho
const int right_index = (x_end - 1) + y * surface_data_->width;
surface_data_->data[right_index] = color;
}
}
// Dibuja una linea // Dibuja una linea
void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color) void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color)
{ {
@@ -277,7 +311,6 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
} }
} }
// 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(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip) void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip)
{ {

View File

@@ -110,9 +110,12 @@ public:
// Obtiene el color de un pixel de la surface_data // Obtiene el color de un pixel de la surface_data
Uint8 getPixel(int x, int y); Uint8 getPixel(int x, int y);
// Dibuja un rectangulo // Dibuja un rectangulo relleno
void fillRect(SDL_Rect *rect, Uint8 color); void fillRect(SDL_Rect *rect, Uint8 color);
// Dibuja el borde de un rectangulo
void drawRectBorder(SDL_Rect *rect, Uint8 color);
// Dibuja una linea // Dibuja una linea
void drawLine(int x1, int y1, int x2, int y2, Uint8 color); void drawLine(int x1, int y1, int x2, int y2, Uint8 color);

View File

@@ -431,30 +431,20 @@ bool colorAreEqual(Color color1, Color color2)
return (r && g && b); return (r && g && b);
} }
// Convierte una cadena a minúsculas // Función para convertir un string a minúsculas
std::string toLower(std::string str) std::string toLower(const std::string &str)
{ {
for (char &c : str) std::string lower_str = str;
{ std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(), ::tolower);
if (c >= 'A' && c <= 'Z') return lower_str;
{
c += 32; // Convierte a minúscula
}
}
return str;
} }
// Convierte una cadena a mayúsculas // Función para convertir un string a mayúsculas
std::string toUpper(std::string str) std::string toUpper(const std::string &str)
{ {
for (char &c : str) std::string upper_str = str;
{ std::transform(upper_str.begin(), upper_str.end(), upper_str.begin(), ::toupper);
if (c >= 'a' && c <= 'z') return upper_str;
{
c -= 32; // Convierte a mayúscula
}
}
return str;
} }
// Obtiene el nombre de un fichero a partir de una ruta completa // Obtiene el nombre de un fichero a partir de una ruta completa

View File

@@ -105,10 +105,10 @@ std::string boolToString(bool value);
bool colorAreEqual(Color color1, Color color2); bool colorAreEqual(Color color1, Color color2);
// Convierte una cadena a minusculas // Convierte una cadena a minusculas
std::string toLower(std::string str); std::string toLower(const std::string& str);
// Convierte una cadena a mayúsculas // Convierte una cadena a mayúsculas
std::string toUpper(std::string str); std::string toUpper(const std::string& str);
// Obtiene el nombre de un fichero a partir de una ruta // Obtiene el nombre de un fichero a partir de una ruta
std::string getFileName(const std::string &path); std::string getFileName(const std::string &path);