SDL: Border rendering

This commit is contained in:
Vicki Pfau 2023-02-28 23:34:55 -08:00
parent 48c9261b05
commit 44fb887737
4 changed files with 89 additions and 9 deletions

View File

@ -9,6 +9,11 @@
#include <mgba/core/thread.h>
#include <mgba/core/version.h>
#ifdef USE_PNG
#include <mgba-util/png-io.h>
#include <mgba-util/vfs.h>
#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);

View File

@ -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

View File

@ -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;
}

View File

@ -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