mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-25 09:17:12 +01:00
rpi: env options, gravity, scale
This commit is contained in:
parent
f4f3b07b14
commit
66e076b1cb
@ -76,6 +76,81 @@ RPI_GetRefreshRate()
|
||||
return 60; /* Failed to get display state, default to 60 */
|
||||
}
|
||||
|
||||
/* TODO: follow SDL coding convention (naming, braces, etc...) */
|
||||
|
||||
static struct GravityEntry {
|
||||
const char *label;
|
||||
unsigned int gravity;
|
||||
} gravity_map[] = {
|
||||
{ "topleft", RPI_GRAVITY_TOP | RPI_GRAVITY_LEFT },
|
||||
{ "topright", RPI_GRAVITY_TOP | RPI_GRAVITY_RIGHT },
|
||||
{ "bottomleft", RPI_GRAVITY_BOTTOM | RPI_GRAVITY_LEFT },
|
||||
{ "bottomright", RPI_GRAVITY_BOTTOM | RPI_GRAVITY_RIGHT },
|
||||
{ "top", RPI_GRAVITY_TOP | RPI_GRAVITY_HCENTER },
|
||||
{ "bottom", RPI_GRAVITY_BOTTOM | RPI_GRAVITY_HCENTER },
|
||||
{ "left", RPI_GRAVITY_VCENTER | RPI_GRAVITY_LEFT },
|
||||
{ "right", RPI_GRAVITY_VCENTER | RPI_GRAVITY_RIGHT },
|
||||
{ "center", RPI_GRAVITY_VCENTER | RPI_GRAVITY_HCENTER }
|
||||
};
|
||||
|
||||
static void parse_gravity(SDL_VideoData *videodata, const char *value) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sizeof(gravity_map) / sizeof(struct GravityEntry); i++) {
|
||||
if (SDL_strcmp(value, gravity_map[i].label) == 0) {
|
||||
videodata->gravity = gravity_map[i].gravity;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_scale(SDL_VideoData *videodata, const char *value) {
|
||||
if (SDL_strcmp(value, "native") == 0)
|
||||
videodata->scale = RPI_NATIVE;
|
||||
else if (SDL_strcmp(value, "letterbox") == 0)
|
||||
videodata->scale = RPI_LETTERBOX;
|
||||
else if (SDL_strcmp(value, "no") == 0)
|
||||
videodata->scale = RPI_NO;
|
||||
}
|
||||
|
||||
static void parse_background(SDL_VideoData *videodata, const char *value) {
|
||||
if (SDL_strcmp(value, "0") == 0)
|
||||
videodata->background = 0;
|
||||
else if (SDL_strcmp(value, "1") == 0)
|
||||
videodata->background = 1;
|
||||
}
|
||||
|
||||
static void parse_option(SDL_VideoData *videodata, char *option) {
|
||||
char *state, *key, *value;
|
||||
|
||||
if (option == NULL)
|
||||
return;
|
||||
if ((key = SDL_strtokr(option, "=", &state)) == NULL)
|
||||
return;
|
||||
if ((value = SDL_strtokr(NULL, "=", &state)) == NULL)
|
||||
return;
|
||||
if (SDL_strcmp(key, "gravity") == 0)
|
||||
parse_gravity(videodata, value);
|
||||
else if (SDL_strcmp(key, "scale") == 0)
|
||||
parse_scale(videodata, value);
|
||||
else if (SDL_strcmp(key, "background") == 0)
|
||||
parse_background(videodata, value);
|
||||
}
|
||||
|
||||
static void parse_env(SDL_VideoData *videodata) {
|
||||
char *env, *s, *state, *option;
|
||||
|
||||
env = SDL_getenv("SDL_VIDEO_RPI_OPTIONS");
|
||||
if (env == NULL)
|
||||
return;
|
||||
s = SDL_strdup(env);
|
||||
option = SDL_strtokr(s, ",", &state);
|
||||
parse_option(videodata, option);
|
||||
while ((option = SDL_strtokr(NULL, ",", &state)) != NULL)
|
||||
parse_option(videodata, option);
|
||||
SDL_free(s);
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
RPI_Create()
|
||||
{
|
||||
@ -101,6 +176,11 @@ RPI_Create()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
phdata->gravity = RPI_GRAVITY_HCENTER | RPI_GRAVITY_VCENTER;
|
||||
phdata->scale = RPI_NATIVE;
|
||||
phdata->background = 0;
|
||||
parse_env(phdata);
|
||||
|
||||
device->driverdata = phdata;
|
||||
|
||||
/* Setup amount of available displays */
|
||||
@ -259,6 +339,7 @@ RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data)
|
||||
int
|
||||
RPI_CreateWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *videodata;
|
||||
SDL_WindowData *wdata;
|
||||
SDL_VideoDisplay *display;
|
||||
SDL_DisplayData *displaydata;
|
||||
@ -271,6 +352,8 @@ RPI_CreateWindow(_THIS, SDL_Window * window)
|
||||
float display_aspect;
|
||||
float window_aspect;
|
||||
|
||||
videodata = (SDL_VideoData *)SDL_GetVideoDevice()->driverdata;
|
||||
|
||||
/* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
|
||||
dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
|
||||
dispman_alpha.opacity = 0xFF;
|
||||
@ -284,11 +367,11 @@ RPI_CreateWindow(_THIS, SDL_Window * window)
|
||||
display = SDL_GetDisplayForWindow(window);
|
||||
displaydata = (SDL_DisplayData *) display->driverdata;
|
||||
|
||||
/* Basic scaler support - TODO: mouse, env options, background layer */
|
||||
if (!window->w) {
|
||||
/* Basic scaler support - TODO: mouse, background layer */
|
||||
if (!window->w || videodata->scale == RPI_NATIVE) {
|
||||
window->w = display->desktop_mode.w;
|
||||
}
|
||||
if (!window->h) {
|
||||
if (!window->h || videodata->scale == RPI_NATIVE) {
|
||||
window->h = display->desktop_mode.h;
|
||||
}
|
||||
display_aspect = (float)display->desktop_mode.w / display->desktop_mode.h;
|
||||
@ -298,16 +381,42 @@ RPI_CreateWindow(_THIS, SDL_Window * window)
|
||||
window->flags |= SDL_WINDOW_OPENGL;
|
||||
|
||||
/* Create a dispman element and associate a window to it */
|
||||
if (window_aspect >= display_aspect) {
|
||||
dst_rect.width = display->desktop_mode.w;
|
||||
dst_rect.height = display->desktop_mode.w / window_aspect;
|
||||
if (videodata->scale == RPI_LETTERBOX) {
|
||||
if (window_aspect >= display_aspect) {
|
||||
dst_rect.width = display->desktop_mode.w;
|
||||
dst_rect.height = display->desktop_mode.w / window_aspect;
|
||||
} else {
|
||||
dst_rect.width = display->desktop_mode.h * window_aspect;
|
||||
dst_rect.height = display->desktop_mode.h;
|
||||
}
|
||||
} else {
|
||||
dst_rect.width = display->desktop_mode.h * window_aspect;
|
||||
dst_rect.height = display->desktop_mode.h;
|
||||
dst_rect.width = window->w;
|
||||
dst_rect.height = window->h;
|
||||
}
|
||||
|
||||
/* Position the dispman element */
|
||||
switch (videodata->gravity & RPI_GRAVITY_H_MASK) {
|
||||
case RPI_GRAVITY_LEFT:
|
||||
dst_rect.x = 0;
|
||||
break;
|
||||
case RPI_GRAVITY_RIGHT:
|
||||
dst_rect.x = display->desktop_mode.w - dst_rect.width;
|
||||
break;
|
||||
default: /* RPI_GRAVITY_HCENTER */
|
||||
dst_rect.x = (display->desktop_mode.w - dst_rect.width) / 2;
|
||||
break;
|
||||
}
|
||||
switch (videodata->gravity & RPI_GRAVITY_V_MASK) {
|
||||
case RPI_GRAVITY_TOP:
|
||||
dst_rect.y = 0;
|
||||
break;
|
||||
case RPI_GRAVITY_BOTTOM:
|
||||
dst_rect.y = display->desktop_mode.h - dst_rect.height;
|
||||
break;
|
||||
default: /* RPI_GRAVITY_VCENTER */
|
||||
dst_rect.y = (display->desktop_mode.h - dst_rect.height) / 2;
|
||||
break;
|
||||
}
|
||||
/* Center the dispman element */
|
||||
dst_rect.x = (display->desktop_mode.w - dst_rect.width) / 2;
|
||||
dst_rect.y = (display->desktop_mode.h - dst_rect.height) / 2;
|
||||
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
|
@ -32,9 +32,31 @@
|
||||
|
||||
#include "SDL_rpidyn.h"
|
||||
|
||||
#define RPI_GRAVITY_LEFT 0x00000001u
|
||||
#define RPI_GRAVITY_RIGHT 0x00000002u
|
||||
#define RPI_GRAVITY_HCENTER 0x00000004u
|
||||
#define RPI_GRAVITY_H_MASK 0x0000000fu
|
||||
|
||||
#define RPI_GRAVITY_TOP 0x00000010u
|
||||
#define RPI_GRAVITY_BOTTOM 0x00000020u
|
||||
#define RPI_GRAVITY_VCENTER 0x00000040u
|
||||
#define RPI_GRAVITY_V_MASK 0x000000f0u
|
||||
|
||||
typedef enum RPI_Scale {
|
||||
RPI_NATIVE,
|
||||
RPI_LETTERBOX,
|
||||
RPI_NO
|
||||
} RPI_scale;
|
||||
|
||||
typedef struct SDL_VideoData
|
||||
{
|
||||
uint32_t egl_refcount; /* OpenGL ES reference count */
|
||||
|
||||
/* RPI options */
|
||||
unsigned int gravity;
|
||||
RPI_scale scale;
|
||||
int background;
|
||||
|
||||
} SDL_VideoData;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user