From 454791fe9686dbe52127ad190bfc079c261238e0 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 15 Sep 2021 11:48:57 +0200 Subject: [PATCH] =?UTF-8?q?A=C3=B1adidos=20modos=20en=20pantalla=20complet?= =?UTF-8?q?a=20para=20el=20escalado=20entero=20y=20mantener=20la=20relaci?= =?UTF-8?q?=C3=B3n=20de=20aspecto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/director.cpp | 17 +++--- source/screen.cpp | 122 +++++++++++++++++++++++++++----------------- source/screen.h | 12 +++-- source/title.cpp | 7 +-- source/utils.h | 3 +- 5 files changed, 99 insertions(+), 62 deletions(-) diff --git a/source/director.cpp b/source/director.cpp index 7ab4db6..305e06f 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -51,15 +51,16 @@ Director::Director(std::string path) // Crea el objeto para dibujar en pantalla (Requiere initSDL) mScreen = new Screen(mWindow, mRenderer, mOptions); - + // Inicializa JailAudio initJailAudio(); // Aplica las opciones - SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); + //SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); //SDL_SetWindowSize(mWindow, REAL_SCREEN_WIDTH * mOptions->windowSize, REAL_SCREEN_HEIGHT * mOptions->windowSize); mLang->setLang(mOptions->language); + #ifdef __MIPSEL__ DIR *dir = opendir("/media/data/local/home/.coffee_crisis"); if (dir) @@ -165,7 +166,7 @@ bool Director::initSDL() // Inicia el generador de numeros aleatorios std::srand(static_cast(SDL_GetTicks())); - // Establece el filtro de la textura a nearest + // Establece el filtro de la textura if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, std::to_string(mOptions->filter).c_str())) { printf("Warning: Nearest texture filtering not enabled!\n"); @@ -368,9 +369,10 @@ bool Director::loadConfigFile() mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER; mOptions->filter = FILTER_NEAREST; mOptions->vSync = true; - mOptions->screenWidth = 2560/4; - mOptions->screenHeight = 1600/4; - mOptions->integerScale = false; + mOptions->screenWidth = SCREEN_WIDTH; + mOptions->screenHeight = SCREEN_HEIGHT; + mOptions->integerScale = true; + mOptions->keepAspect = true; // Indicador de éxito en la carga bool success = true; @@ -402,6 +404,7 @@ bool Director::loadConfigFile() SDL_RWwrite(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1); SDL_RWwrite(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1); SDL_RWwrite(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1); + SDL_RWwrite(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1); // Cierra el fichero SDL_RWclose(file); @@ -428,6 +431,7 @@ bool Director::loadConfigFile() SDL_RWread(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1); SDL_RWread(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1); SDL_RWread(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1); + SDL_RWread(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1); // Normaliza los valores if (!((mOptions->fullScreenMode == 0) || @@ -467,6 +471,7 @@ bool Director::saveConfigFile() SDL_RWwrite(file, &mOptions->screenWidth, sizeof(mOptions->screenWidth), 1); SDL_RWwrite(file, &mOptions->screenHeight, sizeof(mOptions->screenHeight), 1); SDL_RWwrite(file, &mOptions->integerScale, sizeof(mOptions->integerScale), 1); + SDL_RWwrite(file, &mOptions->keepAspect, sizeof(mOptions->keepAspect), 1); printf("Writing file %s\n", filename.c_str()); diff --git a/source/screen.cpp b/source/screen.cpp index 5179e55..47d6ffa 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -1,5 +1,7 @@ #include "screen.h" #include "const.h" +#include +#include // Constructor Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options) @@ -9,56 +11,13 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer, options_t *options) mRenderer = renderer; mOptions = options; - mScreenWidth = mOptions->screenWidth; - mScreenHeight = mOptions->screenHeight; - mGameCanvasWidth = SCREEN_WIDTH; + mGameCanvasWidth = SCREEN_WIDTH; mGameCanvasHeight = SCREEN_HEIGHT; - - mDest.x = (mScreenWidth - mGameCanvasWidth) / 2; - mDest.y = (mScreenHeight - mGameCanvasHeight) / 2; - mIntegerScale = mOptions->integerScale; - //mIntegerScale = true; - /* - - Si el juego es en pantalla completa, calcular la resolución del escritorio y ponerla a las variables - con un método nuevo. - - Si el juego es en ventana, se aplica el gamecanvas multiplicado por el window size, para jugar - sin bordes - - Hacer método setRes(w,h) - - */ - - - // Calcula el tamaño de la escala máxima - int scale = 0; - while (((mGameCanvasWidth * (scale + 1)) <= mScreenWidth) && ((mGameCanvasHeight * (scale + 1)) <= mScreenHeight)) - { - scale++; - } - - if (mIntegerScale) - { - mDest.w = mGameCanvasWidth * scale; - mDest.h = mGameCanvasHeight * scale; - mDest.x = (mScreenWidth - mDest.w) / 2; - mDest.y = (mScreenHeight - mDest.h) / 2; - } - else - { - mDest.w = mScreenWidth; - mDest.h = mScreenHeight; - mDest.x = mDest.y = 0; - } - - if (mOptions->fullScreenMode == 0) - { - mOptions->screenWidth = mScreenWidth = mGameCanvasWidth; - mOptions->screenHeight = mScreenHeight = mGameCanvasHeight; - } + // Establece el modo de video + setVideoMode(mOptions->fullScreenMode); + // Define el color del borde para el modo de pantalla completa mBorderColor = {0x27, 0x27, 0x36}; mBorderColor = {0x00, 0x00, 0x00}; @@ -102,4 +61,73 @@ void Screen::blit() // Muestra por pantalla el renderizador SDL_RenderPresent(mRenderer); +} + +// Establece el modo de video +void Screen::setVideoMode(int fullScreenMode) +{ + // Aplica el modo de video + SDL_SetWindowFullscreen(mWindow, fullScreenMode); + + // Si está activo el modo ventana quita el borde + if (fullScreenMode == 0) + { + mScreenWidth = mGameCanvasWidth; + mScreenHeight = mGameCanvasHeight; + mDest = {0, 0, mGameCanvasWidth, mGameCanvasHeight}; + + // Modifica el tamaño del renderizador y de la ventana + SDL_RenderSetLogicalSize(mRenderer, mScreenWidth, mScreenHeight); + SDL_SetWindowSize(mWindow, mScreenWidth * mOptions->windowSize, mScreenHeight * mOptions->windowSize); + } + + // Si está activo el modo de pantalla completa añade el borde + if (fullScreenMode == SDL_WINDOW_FULLSCREEN_DESKTOP) + { + // Obten el alto y el ancho de la ventana + SDL_GetWindowSize(mWindow, &mScreenWidth, &mScreenHeight); + + // Aplica el escalado al rectangulo donde se pinta la textura del juego + if (mOptions->integerScale) + { + // Calcula el tamaño de la escala máxima + int scale = 0; + while (((mGameCanvasWidth * (scale + 1)) <= mScreenWidth) && ((mGameCanvasHeight * (scale + 1)) <= mScreenHeight)) + { + scale++; + } + + mDest.w = mGameCanvasWidth * scale; + mDest.h = mGameCanvasHeight * scale; + mDest.x = (mScreenWidth - mDest.w) / 2; + mDest.y = (mScreenHeight - mDest.h) / 2; + } + else if (mOptions->keepAspect) + { + float ratio = (float)mGameCanvasWidth / (float)mGameCanvasHeight; + if ((mScreenWidth - mGameCanvasWidth) >= (mScreenHeight - mGameCanvasHeight)) + { + mDest.h = mScreenHeight; + mDest.w = (int)((mScreenHeight * ratio) + 0.5f); + mDest.x = (mScreenWidth - mDest.w) / 2; + mDest.y = (mScreenHeight - mDest.h) / 2; + } + else + { + mDest.w = mScreenWidth; + mDest.h = (int)((mScreenWidth / ratio) + 0.5f); + mDest.x = (mScreenWidth - mDest.w) / 2; + mDest.y = (mScreenHeight - mDest.h) / 2; + } + } + else + { + mDest.w = mScreenWidth; + mDest.h = mScreenHeight; + mDest.x = mDest.y = 0; + } + + // Modifica el tamaño del renderizador + SDL_RenderSetLogicalSize(mRenderer, mScreenWidth, mScreenHeight); + } } \ No newline at end of file diff --git a/source/screen.h b/source/screen.h index d7cb35f..a7aa31d 100644 --- a/source/screen.h +++ b/source/screen.h @@ -9,16 +9,15 @@ class Screen { private: - SDL_Window *mWindow; // Ventana de la aplicación - SDL_Renderer *mRenderer; // El renderizador de la ventana - SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa - options_t *mOptions; // Variable con todas las opciones del programa + SDL_Window *mWindow; // Ventana de la aplicación + SDL_Renderer *mRenderer; // El renderizador de la ventana + SDL_Texture *mGameCanvas; // Textura para completar la ventana de juego hasta la pantalla completa + options_t *mOptions; // Variable con todas las opciones del programa int mScreenWidth; // Ancho de la pantalla int mScreenHeight; // Alto de la pantalla int mGameCanvasWidth; // Ancho de la textura donde se dibuja el juego int mGameCanvasHeight; // Alto de la textura donde se dibuja el juego - bool mIntegerScale; // Indica si la textura se escala en multiplos enteros SDL_Rect mDest; // Coordenadas donde se va a dibujar la textura del juego color_t mBorderColor; // Color del borde añadido a la textura de juego para rellenar la pantalla @@ -37,6 +36,9 @@ public: // Vuelca el contenido del renderizador en pantalla void blit(); + + // Establece el modo de video + void setVideoMode(int fullScreenMode); }; #endif diff --git a/source/title.cpp b/source/title.cpp index c007f5e..b7ceff9 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -516,10 +516,11 @@ void Title::updateMenuLabels() // Aplica las opciones de menu seleccionadas void Title::applyOptions() { - SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); - if (mOptions->fullScreenMode == 0) - SDL_SetWindowSize(mWindow, mOptions->screenWidth * mOptions->windowSize, mOptions->screenHeight * mOptions->windowSize); + //SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); + //if (mOptions->fullScreenMode == 0) + // SDL_SetWindowSize(mWindow, mOptions->screenWidth * mOptions->windowSize, mOptions->screenHeight * mOptions->windowSize); //SDL_RenderSetLogicalSize(mRenderer, mOptions->screenWidth, mOptions->screenHeight); + mScreen->setVideoMode(mOptions->fullScreenMode); mLang->setLang(mOptions->language); diff --git a/source/utils.h b/source/utils.h index 0d21654..0669bd4 100644 --- a/source/utils.h +++ b/source/utils.h @@ -69,7 +69,8 @@ struct options_t bool vSync; // Indica si se quiere usar vsync o no int screenWidth; // Ancho de la pantalla/ventana int screenHeight; // Alto de la pantalla/ventana - bool integerScale; // Indica si el escalado de la imagen ha de ser entero + bool integerScale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa + bool keepAspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa }; // Calcula el cuadrado de la distancia entre dos puntos