From 44fb887737a1b742b6349fb63716677993073b84 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 28 Feb 2023 23:34:55 -0800 Subject: [PATCH] SDL: Border rendering --- src/platform/sdl/gl-common.c | 77 ++++++++++++++++++++++++++++++++++++ src/platform/sdl/gl-common.h | 1 + src/platform/video-backend.c | 19 ++++----- src/platform/video-backend.h | 1 + 4 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/platform/sdl/gl-common.c b/src/platform/sdl/gl-common.c index 47988497d..53219a7bb 100644 --- a/src/platform/sdl/gl-common.c +++ b/src/platform/sdl/gl-common.c @@ -9,6 +9,11 @@ #include #include +#ifdef USE_PNG +#include +#include +#endif + void mSDLGLDoViewport(int w, int h, struct VideoBackend* v) { v->contextResized(v, w, h); v->clear(v); @@ -26,6 +31,60 @@ void mSDLGLCommonSwap(struct VideoBackend* context) { #endif } +bool mSDLGLCommonLoadBackground(struct VideoBackend* context) { +#ifdef USE_PNG + struct mSDLRenderer* renderer = context->user; + const char* bgImage = mCoreConfigGetValue(&renderer->core->config, "backgroundImage"); + if (!bgImage) { + return false; + } + struct VFile* vf = VFileOpen(bgImage, O_RDONLY); + if (!vf) { + return false; + } + + bool ok = false; + png_structp png = PNGReadOpen(vf, 0); + png_infop info = png_create_info_struct(png); + png_infop end = png_create_info_struct(png); + if (!png || !info || !end) { + goto done; + } + + if (!PNGReadHeader(png, info)) { + goto done; + } + unsigned width = png_get_image_width(png, info); + unsigned height = png_get_image_height(png, info); + uint32_t* pixels = malloc(width * height * 4); + if (!pixels) { + goto done; + } + + if (!PNGReadPixels(png, info, pixels, width, height, width) || !PNGReadFooter(png, end)) { + free(pixels); + goto done; + } + + struct Rectangle dims = { + .width = width, + .height = height + }; + context->setLayerDimensions(context, VIDEO_LAYER_BACKGROUND, &dims); + context->setImage(context, VIDEO_LAYER_BACKGROUND, pixels); + free(pixels); + ok = true; + +done: + PNGReadClose(png, info, end); + vf->close(vf); + return ok; +#else + UNUSED(context); + return false; +#endif +} + bool mSDLGLCommonInit(struct mSDLRenderer* renderer) { #ifndef COLOR_16_BIT SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); @@ -74,6 +133,24 @@ void mSDLGLCommonRunloop(struct mSDLRenderer* renderer, void* user) { SDL_Event event; struct VideoBackend* v = renderer->backend; + if (mSDLGLCommonLoadBackground(v)) { + renderer->player.windowUpdated = true; + + struct Rectangle frame; + VideoBackendGetFrame(v, &frame); + int i; + for (i = 0; i <= VIDEO_LAYER_IMAGE; ++i) { + struct Rectangle dims; + v->layerDimensions(v, i, &dims); + RectangleCenter(&frame, &dims); + v->setLayerDimensions(v, i, &dims); + } + +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_SetWindowSize(renderer->window, frame.width * renderer->ratio, frame.height * renderer->ratio); +#endif + } + while (mCoreThreadIsActive(context)) { while (SDL_PollEvent(&event)) { mSDLHandleEvent(context, &renderer->player, &event); diff --git a/src/platform/sdl/gl-common.h b/src/platform/sdl/gl-common.h index 5658abee4..f52cfd633 100644 --- a/src/platform/sdl/gl-common.h +++ b/src/platform/sdl/gl-common.h @@ -16,6 +16,7 @@ void mSDLGLDoViewport(int w, int h, struct VideoBackend* v); void mSDLGLCommonSwap(struct VideoBackend* context); bool mSDLGLCommonInit(struct mSDLRenderer* renderer); void mSDLGLCommonRunloop(struct mSDLRenderer* renderer, void* user); +bool mSDLGLCommonLoadBackground(struct VideoBackend* context); CXX_GUARD_END diff --git a/src/platform/video-backend.c b/src/platform/video-backend.c index 3447fcdd8..998764d0d 100644 --- a/src/platform/video-backend.c +++ b/src/platform/video-backend.c @@ -5,18 +5,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "video-backend.h" -void VideoBackendGetFrameSize(const struct VideoBackend* v, unsigned* width, unsigned* height) { - *width = 0; - *height = 0; +void VideoBackendGetFrame(const struct VideoBackend* v, struct Rectangle* frame) { + memset(frame, 0, sizeof(*frame)); int i; for (i = 0; i < VIDEO_LAYER_MAX; ++i) { struct Rectangle dims; v->layerDimensions(v, i, &dims); - if (dims.x + dims.width > *width) { - *width = dims.x + dims.width; - } - if (dims.y + dims.height > *height) { - *height = dims.y + dims.height; - } + RectangleUnion(frame, &dims); } } + +void VideoBackendGetFrameSize(const struct VideoBackend* v, unsigned* width, unsigned* height) { + struct Rectangle frame; + VideoBackendGetFrame(v, &frame); + *width = frame.width; + *height = frame.height; +} diff --git a/src/platform/video-backend.h b/src/platform/video-backend.h index 3bb1c0a69..5a3319721 100644 --- a/src/platform/video-backend.h +++ b/src/platform/video-backend.h @@ -56,6 +56,7 @@ struct VideoShader { size_t nPasses; }; +void VideoBackendGetFrame(const struct VideoBackend*, struct Rectangle* frame); void VideoBackendGetFrameSize(const struct VideoBackend*, unsigned* width, unsigned* height); CXX_GUARD_END