diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2018-02-26 21:25:11 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2018-02-26 23:02:16 -0800 |
commit | 7903b3b871493425be4b6573d3609abe98408af6 (patch) | |
tree | f30a2babf3b975a3b233312d4945f11afb854983 | |
parent | 5a165aacd17de845d34da7a222133d22642bc7ca (diff) |
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.
-rw-r--r-- | src/sdl_fb.c | 101 |
1 files 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; } |