From: DeaDDooMER Date: Fri, 10 Apr 2020 11:48:42 +0000 (+0400) Subject: menu: change videomode at runtime X-Git-Url: https://deadsoftware.ru/gitweb?p=flatwaifu.git;a=commitdiff_plain;h=4a0a2f1f4922d5346c4aee584e7d4a13803bffab menu: change videomode at runtime --- diff --git a/src/gl/render.c b/src/gl/render.c index 2b5d531..c057b90 100644 --- a/src/gl/render.c +++ b/src/gl/render.c @@ -1837,18 +1837,7 @@ void R_set_videomode (int w, int h, int fullscreen) { if (was == 0) { ERR_failinit("Unable to set video mode\n"); } - } else { - Y_get_videomode(&SCRW, &SCRH); - root = R_cache_new(); - assert(root); - R_alloc(); - R_reload_textures(); } -} - -static void R_fullscreen (int yes) { - R_cache_free(root, 0); - Y_set_fullscreen(yes); Y_get_videomode(&SCRW, &SCRH); root = R_cache_new(); assert(root); @@ -1857,23 +1846,57 @@ static void R_fullscreen (int yes) { } static int R_video_menu_handler (new_msg_t *msg, const new_menu_t *m, void *data) { + const videomode_t *v; intptr_t i = (intptr_t)data; + static int w, h; + static int vmode; static int fullscreen; + static char str[16]; switch (i) { case -1: switch (msg->type) { - case GM_ENTER: fullscreen = Y_get_fullscreen(); return 1; + case GM_ENTER: + Y_get_videomode(&w, &h); + fullscreen = Y_get_fullscreen(); + v = Y_get_videomode_list_opengl(fullscreen); + vmode = 0; + while (vmode < v->n && v->modes[vmode].w != w && v->modes[vmode].h != h) { + vmode += 1; + } + if (vmode < v->n) { + w = v->modes[vmode].w; + h = v->modes[vmode].h; + } + snprintf(str, 16, "%ix%i", w, h); + return 1; } break; case 0: + switch (msg->type) { + case GM_SELECT: + v = Y_get_videomode_list_opengl(fullscreen); + vmode = vmode + 1 >= v->n ? 0 : vmode + 1; + if (v->n > 0) { + w = v->modes[vmode].w; + h = v->modes[vmode].h; + } else { + Y_get_videomode(&w, &h); + } + snprintf(str, 16, "%ix%i", w, h); + return 1; + case GM_GETSTR: + return GM_init_str(msg, str, 16); + } + break; + case 1: switch (msg->type) { case GM_SELECT: fullscreen = !fullscreen; return 1; case GM_GETSTR: return GM_init_str(msg, fullscreen ? "Yes" : "No", 3); } break; - case 1: + case 2: switch (msg->type) { - case GM_SELECT: R_fullscreen(fullscreen); return 1; + case GM_SELECT: R_set_videomode(w, h, fullscreen); return 1; } } return 0; @@ -1882,8 +1905,9 @@ static int R_video_menu_handler (new_msg_t *msg, const new_menu_t *m, void *data static const new_menu_t video_menu = { GM_BIG, "Video", (void*)-1, &R_video_menu_handler, { - { GM_BUTTON, "Fullscreen: ", (void*)0, &R_video_menu_handler, NULL }, - { GM_BUTTON, "Apply", (void*)1, &R_video_menu_handler, NULL }, + { GM_BUTTON, "Videomode: ", (void*)0, &R_video_menu_handler, NULL }, + { GM_BUTTON, "Fullscreen: ", (void*)1, &R_video_menu_handler, NULL }, + { GM_BUTTON, "Apply", (void*)2, &R_video_menu_handler, NULL }, { 0, NULL, NULL, NULL, NULL } // end } }; diff --git a/src/sdl/main.c b/src/sdl/main.c index 36b3279..9227725 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -56,6 +56,7 @@ static int quit = 0; static SDL_Surface *surf = NULL; static int mode = MODE_NONE; static int text_input; +static videomode_t vlist; /* --- error.h --- */ @@ -151,6 +152,47 @@ int Y_set_videomode_software (int w, int h, int fullscreen) { return s != NULL; } +static void init_videomode_list (Uint32 flags) { + int i, n; + SDL_Rect **r; + if (vlist.modes != NULL) { + free(vlist.modes); + vlist.modes = NULL; + vlist.n = 0; + } + r = SDL_ListModes(NULL, flags); + if (r == (SDL_Rect **)-1) { + if ((flags & SDL_FULLSCREEN) == 0) { + init_videomode_list(flags | SDL_FULLSCREEN); + } + } else if (r != (SDL_Rect**)0) { + n = 0; + while (r[n] != NULL) { + n++; + } + vlist.modes = malloc(n * sizeof(videomode_size_t)); + if (vlist.modes != NULL) { + vlist.n = n; + for (i = 0; i < n; i++) { + vlist.modes[i] = (videomode_size_t) { + .w = r[i]->w, + .h = r[i]->h + }; + } + } + } +} + +const videomode_t *Y_get_videomode_list_opengl (int fullscreen) { + init_videomode_list(SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0)); + return &vlist; +} + +const videomode_t *Y_get_videomode_list_software (int fullscreen) { + init_videomode_list(SDL_SWSURFACE | SDL_HWPALETTE | (fullscreen ? SDL_FULLSCREEN : 0)); + return &vlist; +} + void Y_get_videomode (int *w, int *h) { if (mode != MODE_NONE) { *w = surf->w; diff --git a/src/sdl2/main.c b/src/sdl2/main.c index a6b98d6..1a25886 100644 --- a/src/sdl2/main.c +++ b/src/sdl2/main.c @@ -31,6 +31,7 @@ static int quit = 0; static SDL_Window *window; static SDL_GLContext context; static SDL_Surface *surf; +static videomode_t vlist; /* --- error.h --- */ @@ -201,6 +202,48 @@ void Y_unset_videomode (void) { } } +static void init_videomode_list (void) { + int i, j, k; + SDL_DisplayMode m; + int n = SDL_GetNumDisplayModes(0); + if (vlist.modes != NULL) { + free(vlist.modes); + vlist.modes = NULL; + vlist.n = 0; + } + if (n > 0) { + vlist.modes = malloc(n * sizeof(videomode_size_t)); + if (vlist.modes != NULL) { + j = 0; + for (i = 0; i < n; i++) { + SDL_GetDisplayMode(0, i, &m); + k = 0; + while (k < j && (m.w != vlist.modes[k].w || m.h != vlist.modes[k].h)) { + k++; + } + if (k >= j) { + vlist.modes[j] = (videomode_size_t) { + .w = m.w, + .h = m.h + }; + j++; + } + } + vlist.n = j; + } + } +} + +const videomode_t *Y_get_videomode_list_opengl (int fullscreen) { + init_videomode_list(); + return &vlist; +} + +const videomode_t *Y_get_videomode_list_software (int fullscreen) { + init_videomode_list(); + return &vlist; +} + void Y_set_fullscreen (int yes) { if (window != NULL) { SDL_SetWindowFullscreen(window, yes ? SDL_WINDOW_FULLSCREEN : 0); diff --git a/src/system.h b/src/system.h index 41cf079..0de8d42 100644 --- a/src/system.h +++ b/src/system.h @@ -3,8 +3,14 @@ #include "glob.h" -#define SYSTEM_USE_OPENGL (1 << 0) -#define SYSTEM_USE_FULLSCREEN (1 << 1) +typedef struct videomode_size_t { + int w, h, r; +} videomode_size_t; + +typedef struct videomode_t { + int n; + videomode_size_t *modes; +} videomode_t; /* common video subsystem routines */ void Y_get_videomode (int *w, int *h); @@ -15,10 +21,12 @@ int Y_get_fullscreen (void); /* hardware specific rendering */ int Y_set_videomode_opengl (int w, int h, int fullscreen); +const videomode_t *Y_get_videomode_list_opengl (int fullscreen); void Y_swap_buffers (void); /* software specific rendering */ int Y_set_videomode_software (int w, int h, int fullscreen); +const videomode_t *Y_get_videomode_list_software (int fullscreen); void Y_get_buffer (byte **buf, int *w, int *h, int *pitch); void Y_set_vga_palette (byte *vgapal); void Y_repaint_rect (int x, int y, int w, int h);