From 7903b3b871493425be4b6573d3609abe98408af6 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 26 Feb 2018 21:25:11 -0800 Subject: sdl_fb: add fullscreen= and size= settings fullscreen takes either "on" or "off" size expects WxH arguments, defaults still to 640x480 size is optional when fullscreen=on. Through the setup machinery, when fullscreen has been selected it will not ask for a size - a "fullscreen desktop" mode is presumed. However, thorugh the explicit commandline flags, a mixed mode can be achieved by specifying both "fullscreen=on,size=WxH". This instructs SDL to attempt a video mode switch to the specified size if needed. I've found it to be pretty unreliable on my Xorg/linux system, unless I choose the same video mode as my desktop is already in. Then I get what looks like rendering into the root window or something, it's weird. Hence there's no effort made to expose that in the interactive setup, but it's technically possible and some effort was made to wire it up. --- src/sdl_fb.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 10 deletions(-) diff --git a/src/sdl_fb.c b/src/sdl_fb.c index 77c62bf..80a63dd 100644 --- a/src/sdl_fb.c +++ b/src/sdl_fb.c @@ -10,6 +10,9 @@ /* sdl fb backend, everything sdl-specific in rototiller resides here. */ typedef struct sdl_fb_t { + unsigned width, height; + Uint32 flags; + SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *texture; @@ -24,25 +27,104 @@ struct sdl_fb_page_t { int sdl_fb_setup(const settings_t *settings, setting_desc_t **next_setting) { - /* TODO: window size? fullscreen? vsync? etc. */ + const char *fullscreen; + + fullscreen = settings_get_value(settings, "fullscreen"); + if (!fullscreen) { + const char *values[] = { + "off", + "on", + NULL + }; + setting_desc_t *desc; + + desc = setting_desc_new("SDL Fullscreen Mode", + "fullscreen", + NULL, + values[0], + values, + NULL); + if (!desc) + return -ENOMEM; + + *next_setting = desc; + + return 1; + } + + if (!strcasecmp(fullscreen, "off")) { + const char *size; + + size = settings_get_value(settings, "size"); + if (!size) { + setting_desc_t *desc; + + desc = setting_desc_new("SDL Window size", + "size", + "[1-9][0-9]*[xX][1-9][0-9]*", + "640x480", + NULL, + NULL); + if (!desc) + return -ENOMEM; + + *next_setting = desc; + + return 1; + } + } + return 0; } void * sdl_fb_init(const settings_t *settings) { + const char *fullscreen; + const char *size; sdl_fb_t *c; + fullscreen = settings_get_value(settings, "fullscreen"); + if (!fullscreen) + return NULL; + + size = settings_get_value(settings, "size"); + if (!size && !strcasecmp(fullscreen, "off")) + return NULL; + c = calloc(1, sizeof(sdl_fb_t)); if (!c) return NULL; + if (!strcasecmp(fullscreen, "on")) { + if (!size) + c->flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + else + c->flags = SDL_WINDOW_FULLSCREEN; + } + + if (size) /* TODO: errors */ + sscanf(size, "%u%*[xX]%u", &c->width, &c->height); + SDL_SetMainReady(); if (SDL_Init(SDL_INIT_VIDEO) < 0) { free(c); return NULL; } + if (c->flags == SDL_WINDOW_FULLSCREEN_DESKTOP) { + SDL_DisplayMode mode; + + if (SDL_GetDesktopDisplayMode(0, &mode) != 0) { + SDL_Quit(); + free(c); + return NULL; + } + + c->width = mode.w; + c->height = mode.h; + } + return c; } @@ -61,7 +143,7 @@ static int sdl_fb_acquire(void *context, void *page) sdl_fb_t *c = context; sdl_fb_page_t *p = page; - c->window = SDL_CreateWindow("rototiller", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); + c->window = SDL_CreateWindow("rototiller", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, c->width, c->height, c->flags); if (!c->window) return -1; @@ -69,7 +151,7 @@ static int sdl_fb_acquire(void *context, void *page) if (!c->renderer) return -1; - c->texture = SDL_CreateTexture(c->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 640, 480); + c->texture = SDL_CreateTexture(c->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, c->width, c->height); if (!c->texture) return -1; @@ -96,15 +178,14 @@ static void * sdl_fb_page_alloc(void *context, fb_page_t *res_page) if (!p) return NULL; - - p->surface = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 32, SDL_PIXELFORMAT_RGB888); + p->surface = SDL_CreateRGBSurfaceWithFormat(0, c->width, c->height, 32, SDL_PIXELFORMAT_RGB888); res_page->fragment.buf = p->surface->pixels; - res_page->fragment.width = 640; - res_page->fragment.frame_width = 640; - res_page->fragment.height = 480; - res_page->fragment.frame_height = 480; - res_page->fragment.stride = p->surface->pitch - (640 * 4); + res_page->fragment.width = c->width; + res_page->fragment.frame_width = c->width; + res_page->fragment.height = c->height; + res_page->fragment.frame_height = c->height; + res_page->fragment.stride = p->surface->pitch - (c->width * 4); return p; } -- cgit v1.2.3