Files
mini/source/backends/SDL3/video.cpp
T

134 lines
4.9 KiB
C++

#if BACKEND == SDL3
#include "backends/backend.h"
#include "state.h"
#include "mini/win/win.h"
#include "mini/surf/surf.h"
#include "mini/pal/pal.h"
#include "mini/shader/shader.h"
#include "other/log.h"
namespace backend
{
namespace video
{
SDL_Window *window { nullptr };
SDL_Renderer *renderer { nullptr };
SDL_Texture *tex_back { nullptr };
SDL_Texture *tex_shader { nullptr };
int fullscreen_scale;
SDL_FRect dest_rect;
void init() {
const auto &title = mini::win::state.title;
const auto &width = mini::win::state.width;
const auto &height = mini::win::state.height;
auto &zoom = mini::win::state.zoom;
// Ajustar el zoom a un valor vàlid
if (zoom <= 0) zoom = 1;
const SDL_DisplayMode *dm = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay());
while ( width * zoom > dm->w || height * zoom > dm->h) zoom--;
log_msg(LOG_INFO, "Display size: %ix%i\n", dm->w, dm->h);
const int z = mini::win::state.fullscreen ? 1 : zoom;
// Crear SDL_Window i SDL_Renderer
window = SDL_CreateWindow(title, width*z, height*z, SDL_WINDOW_OPENGL|(mini::win::state.fullscreen?SDL_WINDOW_FULLSCREEN:0));
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
renderer = SDL_CreateRenderer(window, NULL);
SDL_SetRenderVSync(renderer, SDL_RENDERER_VSYNC_DISABLED);
// Mostrar o ocultar el cursor
if (mini::win::state.cursor) SDL_ShowCursor(); else SDL_HideCursor();
// Crear textura backbuffer
tex_back = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height);
SDL_SetTextureScaleMode(tex_back, SDL_SCALEMODE_NEAREST);
// Crear textura shaders i inicialitzar shaders
int w = width*z;
int h = height*z;
if (mini::win::state.fullscreen) {
fullscreen_scale = SDL_min(dm->w/width, dm->h/height);
w = width * fullscreen_scale;
h = height * fullscreen_scale;
log_msg(LOG_INFO, "fullscreen_scale: %i\n", fullscreen_scale);
}
tex_shader = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h);
SDL_SetTextureScaleMode(tex_shader, SDL_SCALEMODE_NEAREST);
int ww, wh;
SDL_GetWindowSize(window, &ww, &wh);
printf("window: %ix%i\n", ww, wh);
if (mini::win::state.fullscreen)
{
dest_rect.w = width * fullscreen_scale;
dest_rect.h = height * fullscreen_scale;
dest_rect.x = (dm->w - dest_rect.w)/2;
dest_rect.y = (dm->h - dest_rect.h)/2;
printf("width: %i, height: %i\n", width, height);
printf("screen: %ix%i\n", dm->w, dm->h);
printf("dest_rect: (%i,%i)-(%i,%i)\n", (int)dest_rect.x, (int)dest_rect.y, (int)dest_rect.w, (int)dest_rect.h);
}
else
{
dest_rect.w = width * zoom;
dest_rect.h = height * zoom;
dest_rect.x = (ww - dest_rect.w)/2;
dest_rect.y = (wh - dest_rect.h)/2;
printf("dest_rect: (%i,%i)-(%i,%i)\n", (int)dest_rect.x, (int)dest_rect.y, (int)dest_rect.w, (int)dest_rect.h);
}
shader::reinit();
}
void quit() {
shader::quit();
SDL_DestroyTexture(tex_shader);
SDL_DestroyTexture(tex_back);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
}
void render() {
// Render frame
SDL_SetRenderTarget(renderer, tex_shader);
//SDL_SetRenderDrawColor(win::state.renderer, 0, 0, 0, 255);
//SDL_RenderClear(win::state.renderer);
uint32_t *pixels;
int pitch;
SDL_LockTexture(tex_back, NULL, (void**)&pixels, &pitch);
auto &s = mini::surf::state.surfaces[SCREEN];
uint8_t *p = s.p;
for (uint32_t i=0;i<s.size;++i) pixels[i] = mini::pal::palette[p[i]];
SDL_UnlockTexture(tex_back);
if (mini::win::state.fullscreen)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
}
SDL_RenderTexture(renderer, tex_back, NULL, NULL); //NEW
backend::shader::render();
//SDL_RenderTexture(mini_ren, mini_bak, NULL, NULL);
//SDL_RenderPresent(mini_ren);
}
void raise_window() {
SDL_RaiseWindow(window);
}
void cursor(const bool value) {
if (value) SDL_ShowCursor(); else SDL_HideCursor();
}
}
}
#endif