Treballant en els modes de video

This commit is contained in:
2025-02-27 21:05:01 +01:00
parent 59e766f5c3
commit 212b2b481c
3 changed files with 75 additions and 89 deletions

View File

@@ -350,8 +350,10 @@ bool Director::initSDL()
// Inicializa el color de renderizado // Inicializa el color de renderizado
SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF); SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
// Establece el tamaño del buffer de renderizado // Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(renderer_, options.game.width, options.game.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);
// Establece el modo de mezcla // Establece el modo de mezcla
SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND); SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);

View File

@@ -40,10 +40,8 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
: window_(window), : window_(window),
renderer_(renderer) renderer_(renderer)
{ {
game_canvas_width_ = options.game.width; adjustGameCanvasRect();
game_canvas_height_ = options.game.height; calculateWindowSize();
notification_logical_width_ = game_canvas_width_;
notification_logical_height_ = game_canvas_height_;
iniFade(); iniFade();
iniSpectrumFade(); iniSpectrumFade();
@@ -52,7 +50,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
border_color_ = {0x00, 0x00, 0x00}; border_color_ = {0x00, 0x00, 0x00};
// Crea la textura donde se dibujan los graficos del juego // Crea la textura donde se dibujan los graficos del juego
game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_, game_canvas_height_); game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height);
if (game_canvas_ == nullptr) if (game_canvas_ == nullptr)
{ {
if (options.console) if (options.console)
@@ -62,7 +60,7 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer)
} }
// 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_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, game_canvas_width_ + options.video.border.width * 2, game_canvas_height_ + options.video.border.height * 2); border_canvas_ = 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 (border_canvas_ == nullptr) if (border_canvas_ == nullptr)
{ {
if (options.console) if (options.console)
@@ -121,7 +119,6 @@ void Screen::render()
renderPresent(); renderPresent();
} }
// Vuelca el contenido del renderizador en pantalla // Vuelca el contenido del renderizador en pantalla
void Screen::renderWithoutNotifier() void Screen::renderWithoutNotifier()
{ {
@@ -139,86 +136,43 @@ void Screen::renderWithoutNotifier()
void Screen::setVideoMode(int videoMode) void Screen::setVideoMode(int videoMode)
{ {
// Aplica el modo de video // Aplica el modo de video
SDL_SetWindowFullscreen(window_, videoMode);
// Modo ventana // Modo ventana
if (videoMode == 0) if (videoMode == 0)
{ {
// Muestra el puntero // Muestra el puntero
SDL_ShowCursor(SDL_ENABLE); SDL_ShowCursor(SDL_ENABLE);
// Modifica el tamaño de la ventana en función del borde calculateWindowSize();
if (options.video.border.enabled) adjustGameCanvasRect();
{
window_width_ = game_canvas_width_ + options.video.border.width * 2;
window_height_ = game_canvas_height_ + options.video.border.height * 2;
dest_ = {options.video.border.width, options.video.border.height, game_canvas_width_, game_canvas_height_};
}
else
{
window_width_ = game_canvas_width_;
window_height_ = game_canvas_height_;
dest_ = {0, 0, game_canvas_width_, game_canvas_height_};
}
// Modifica el tamaño de la ventana // Modifica el tamaño de la ventana
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_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
// Modifica el tamaño del renderizador
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);
SDL_SetWindowFullscreen(window_, videoMode);
} }
// Si está activo el modo de pantalla completa añade el borde // Modo pantalla completa
else if (videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP) else
{ {
calculateWindowSize();
adjustGameCanvasRect();
// Oculta el puntero // Oculta el puntero
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
// Obten el alto y el ancho de la ventana // Modifica el tamaño del renderizador
SDL_GetWindowSize(window_, &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;
// Aplica el escalado al rectangulo donde se pinta la textura del juego SDL_RenderSetLogicalSize(renderer_, options.game.width + extra_width, options.game.height + extra_height);
if (options.video.integer_scale) // Habilitar el escalado entero
{ SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
// Calcula el tamaño de la escala máxima SDL_SetWindowFullscreen(window_, videoMode);
int scale = 0;
while (((game_canvas_width_ * (scale + 1)) <= window_width_) && ((game_canvas_height_ * (scale + 1)) <= window_height_))
{
scale++;
}
dest_.w = game_canvas_width_ * scale;
dest_.h = game_canvas_height_ * scale;
dest_.x = (window_width_ - dest_.w) / 2;
dest_.y = (window_height_ - dest_.h) / 2;
}
else if (options.video.keep_aspect)
{
float ratio = (float)game_canvas_width_ / (float)game_canvas_height_;
if ((window_width_ - game_canvas_width_) >= (window_height_ - game_canvas_height_))
{
dest_.h = window_height_;
dest_.w = (int)((window_height_ * ratio) + 0.5f);
dest_.x = (window_width_ - dest_.w) / 2;
dest_.y = (window_height_ - dest_.h) / 2;
}
else
{
dest_.w = window_width_;
dest_.h = (int)((window_width_ / ratio) + 0.5f);
dest_.x = (window_width_ - dest_.w) / 2;
dest_.y = (window_height_ - dest_.h) / 2;
}
}
else
{
dest_.w = window_width_;
dest_.h = window_height_;
dest_.x = dest_.y = 0;
}
} }
// Modifica el tamaño del renderizador
SDL_RenderSetLogicalSize(renderer_, window_width_, window_height_);
// Actualiza las opciones // Actualiza las opciones
options.video.mode = videoMode; options.video.mode = videoMode;
@@ -244,7 +198,7 @@ void Screen::setVideoMode(int videoMode)
// Camibia entre pantalla completa y ventana // Camibia entre pantalla completa y ventana
void Screen::toggleVideoMode() void Screen::toggleVideoMode()
{ {
options.video.mode = (options.video.mode == 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0; options.video.mode = (options.video.mode == 0) ? SDL_WINDOW_FULLSCREEN : 0;
setVideoMode(options.video.mode); setVideoMode(options.video.mode);
} }
@@ -307,7 +261,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;
setVideoMode(0); setVideoMode(options.video.mode);
} }
// Activa el fade // Activa el fade
@@ -372,7 +326,7 @@ void Screen::renderFade()
return; return;
} }
const SDL_Rect rect = {0, 0, game_canvas_width_, game_canvas_height_}; const SDL_Rect rect = {0, 0, options.game.width, options.game.height};
Color color = {0, 0, 0}; Color color = {0, 0, 0};
const float step = (float)fade_counter_ / (float)fade_lenght_; const float step = (float)fade_counter_ / (float)fade_lenght_;
const int alpha = 0 + (255 - 0) * step; const int alpha = 0 + (255 - 0) * step;
@@ -455,7 +409,7 @@ void Screen::gameCanvasToBorderCanvas()
SDL_SetRenderTarget(renderer_, border_canvas_); SDL_SetRenderTarget(renderer_, border_canvas_);
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF); SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(renderer_);
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &dest_); SDL_RenderCopy(renderer_, game_canvas_, nullptr, &game_canvas_rect_);
SDL_SetRenderTarget(renderer_, temp); SDL_SetRenderTarget(renderer_, temp);
} }
@@ -463,7 +417,7 @@ void Screen::gameCanvasToBorderCanvas()
void Screen::renderPresent() void Screen::renderPresent()
{ {
SDL_SetRenderTarget(renderer_, nullptr); SDL_SetRenderTarget(renderer_, nullptr);
SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF); SDL_SetRenderDrawColor(renderer_, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderClear(renderer_); SDL_RenderClear(renderer_);
if (options.video.shaders) if (options.video.shaders)
@@ -479,7 +433,7 @@ void Screen::renderPresent()
} }
else else
{ {
SDL_RenderCopy(renderer_, game_canvas_, nullptr, &dest_); SDL_RenderCopy(renderer_, game_canvas_, nullptr, &game_canvas_rect_);
} }
SDL_RenderPresent(renderer_); SDL_RenderPresent(renderer_);
} }
@@ -509,4 +463,32 @@ void Screen::show()
void Screen::hide() void Screen::hide()
{ {
SDL_HideWindow(window_); SDL_HideWindow(window_);
}
// Calcula el tamaño de la ventana
void Screen::calculateWindowSize()
{
if (options.video.border.enabled)
{
window_width_ = options.game.width + options.video.border.width * 2;
window_height_ = options.game.height + options.video.border.height * 2;
}
else
{
window_width_ = options.game.width;
window_height_ = options.game.height;
}
}
// Ajusta game_canvas_rect_
void Screen::adjustGameCanvasRect()
{
if (options.video.border.enabled)
{
game_canvas_rect_ = {options.video.border.width, options.video.border.height, options.game.width, options.game.height};
}
else
{
game_canvas_rect_ = {0, 0, options.game.width, options.game.height};
}
} }

View File

@@ -28,14 +28,10 @@ private:
SDL_Texture *border_canvas_; // Textura donde se dibuja el borde del juego SDL_Texture *border_canvas_; // Textura donde se dibuja el borde del juego
// Variables // Variables
int window_width_; // Ancho de la pantalla o ventana int window_width_; // Ancho de la pantalla o ventana
int window_height_; // Alto de la pantalla o ventana int window_height_; // Alto de la pantalla o ventana
int game_canvas_width_; // Resolución interna del juego. Es el ancho de la textura donde se dibuja el juego SDL_Rect game_canvas_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
int game_canvas_height_; // Resolución interna del juego. Es el alto de la textura donde se dibuja el juego Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
SDL_Rect dest_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana
Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla
int notification_logical_width_; // Ancho lógico de las notificaciones en relación al tamaño de pantalla
int notification_logical_height_; // Alto lógico de las notificaciones en relación al tamaño de pantalla
// Variables - Efectos // Variables - Efectos
bool fade_; // Indica si esta activo el efecto de fade bool fade_; // Indica si esta activo el efecto de fade
@@ -73,6 +69,12 @@ private:
// Muestra el contenido de Screen por pantalla // Muestra el contenido de Screen por pantalla
void renderPresent(); void renderPresent();
// Calcula el tamaño de la ventana
void calculateWindowSize();
// Ajusta game_canvas_rect_
void adjustGameCanvasRect();
// Constructor // Constructor
Screen(SDL_Window *window, SDL_Renderer *renderer); Screen(SDL_Window *window, SDL_Renderer *renderer);