diff options
-rw-r--r-- | setup/configfile.c | 3 | ||||
-rw-r--r-- | setup/display.c | 258 | ||||
-rw-r--r-- | setup/display.h | 2 | ||||
-rw-r--r-- | textscreen/txt_table.c | 19 | ||||
-rw-r--r-- | textscreen/txt_table.h | 1 |
5 files changed, 198 insertions, 85 deletions
diff --git a/setup/configfile.c b/setup/configfile.c index b1db1a09..bbde0bbb 100644 --- a/setup/configfile.c +++ b/setup/configfile.c @@ -254,7 +254,8 @@ static default_t extra_defaults_list[] = {"fullscreen", &fullscreen, DEFAULT_INT, 0, 0}, {"aspect_ratio_correct", &aspect_ratio_correct, DEFAULT_INT, 0, 0}, {"startup_delay", &startup_delay, DEFAULT_INT, 0, 0}, - {"screenmultiply", &screenmultiply, DEFAULT_INT, 0, 0}, + {"screen_width", &screen_width, DEFAULT_INT, 0, 0}, + {"screen_height", &screen_height, DEFAULT_INT, 0, 0}, {"grabmouse", &grabmouse, DEFAULT_INT, 0, 0}, {"novert", &novert, DEFAULT_INT, 0, 0}, {"mouse_acceleration", &mouse_acceleration, DEFAULT_FLOAT, 0, 0}, diff --git a/setup/display.c b/setup/display.c index 07be4be9..f4e38d56 100644 --- a/setup/display.c +++ b/setup/display.c @@ -27,44 +27,50 @@ typedef struct { - char *description; - char *description_4_3; - int screenmultiply; - txt_radiobutton_t *widget; -} vidmode_t; + int w, h; +} screen_mode_t; -enum -{ - RATIO_CORRECT_NONE, - RATIO_CORRECT_LETTERBOX, - RATIO_CORRECT_STRETCH, - NUM_RATIO_CORRECT, -}; +// List of aspect ratio-uncorrected modes -static vidmode_t modes[] = +static screen_mode_t screen_modes_unscaled[] = { - { "320x200", "320x240", 1, NULL }, - { "960x600", "960x720", 3, NULL }, - { "640x400", "640x480", 2, NULL }, - { "1280x800", "1280x960", 4, NULL }, - { "1600x1000", "1600x1200", 5, NULL }, - { NULL, NULL, 0, NULL }, + { 320, 200 }, + { 640, 400 }, + { 960, 600 }, + { 1280, 800 }, + { 1600, 1000 }, + { 0, 0}, }; -static char *aspect_ratio_strings[] = +// List of aspect ratio-corrected modes + +static screen_mode_t screen_modes_scaled[] = { - "Disabled", - "Letterbox mode", - "Stretch to 4:3", + { 256, 200 }, + { 320, 240 }, + { 512, 400 }, + { 640, 480 }, + { 800, 600 }, + { 960, 720 }, + { 1024, 800 }, + { 1280, 960 }, + { 1280, 1000 }, + { 1600, 1200 }, + { 0, 0}, }; +// List of fullscreen modes generated at runtime + +static screen_mode_t *screen_modes_fullscreen = NULL; + static int vidmode = 0; char *video_driver = ""; int autoadjust_video_settings = 1; -int aspect_ratio_correct = RATIO_CORRECT_NONE; +int aspect_ratio_correct = 1; int fullscreen = 1; -int screenmultiply = 1; +int screen_width = 320; +int screen_height = 200; int startup_delay = 0; int show_endoom = 1; @@ -103,81 +109,182 @@ static void UpdateVideoDriver(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused)) #endif -// Given the video settings (fullscreen, screenmultiply, etc), find the -// current video mode +static void ModeSelected(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(mode)) +{ + TXT_CAST_ARG(screen_mode_t, mode); -static void SetCurrentMode(void) + screen_width = mode->w; + screen_height = mode->h; +} + +static int GoodFullscreenMode(screen_mode_t *mode) { - int i; + int w, h; - vidmode = 0; + w = mode->w; + h = mode->h; - for (i=0; modes[i].description != NULL; ++i) + // 320x200 and 640x400 are always good + + if ((w == 320 && h == 200) || (w == 640 && h == 400)) { - if (screenmultiply == modes[i].screenmultiply) - { - vidmode = i; - break; - } + return 1; } + + return w >= 640 && h >= 480; } -static void ModeSelected(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(mode)) +// Build screen_modes_fullscreen + +static void BuildFullscreenModesList(void) { - TXT_CAST_ARG(vidmode_t, mode); + SDL_Rect **modes; + screen_mode_t *m1; + screen_mode_t *m2; + screen_mode_t m; + int num_modes; + int i; + + if (screen_modes_fullscreen != NULL) + { + return; + } - screenmultiply = mode->screenmultiply; + // Get a list of fullscreen modes and find out how many + // modes are in the list. + + modes = SDL_ListModes(NULL, SDL_FULLSCREEN); + + for (num_modes=0; modes[num_modes] != NULL; ++num_modes); + + // Build the screen_modes_fullscreen array + + screen_modes_fullscreen = malloc(sizeof(screen_mode_t) * (num_modes + 1)); + + for (i=0; i<num_modes; ++i) + { + screen_modes_fullscreen[i].w = modes[i]->w; + screen_modes_fullscreen[i].h = modes[i]->h; + } + + screen_modes_fullscreen[i].w = 0; + screen_modes_fullscreen[i].h = 0; + + // Reverse the order of the modes list (smallest modes first) + + for (i=0; i<num_modes / 2; ++i) + { + m1 = &screen_modes_fullscreen[i]; + m2 = &screen_modes_fullscreen[num_modes - 1 - i]; + + memcpy(&m, m1, sizeof(screen_mode_t)); + memcpy(m1, m2, sizeof(screen_mode_t)); + memcpy(m2, &m, sizeof(screen_mode_t)); + } } -static void UpdateModes(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused)) +static int FindBestMode(screen_mode_t *modes) { int i; + int best_mode; + int best_mode_diff; + int diff; - for (i=0; modes[i].description != NULL; ++i) + best_mode = -1; + best_mode_diff = 0; + + for (i=0; modes[i].w != 0; ++i) { - if (aspect_ratio_correct == RATIO_CORRECT_NONE) + diff = (screen_width - modes[i].w) * (screen_width - modes[i].w) + + (screen_height - modes[i].h) * (screen_height - modes[i].h); + + if (best_mode == -1 || diff < best_mode_diff) { - TXT_SetRadioButtonLabel(modes[i].widget, modes[i].description); + best_mode_diff = diff; + best_mode = i; } - else + } + + return best_mode; +} + +static void GenerateModesTable(TXT_UNCAST_ARG(widget), + TXT_UNCAST_ARG(modes_table)) +{ + TXT_CAST_ARG(txt_table_t, modes_table); + char buf[15]; + screen_mode_t *modes; + txt_radiobutton_t *rbutton; + int i; + + // Pick which modes list to use + + if (fullscreen) + { + BuildFullscreenModesList(); + modes = screen_modes_fullscreen; + } + else if (aspect_ratio_correct) + { + modes = screen_modes_scaled; + } + else + { + modes = screen_modes_unscaled; + } + + // Build the table + + TXT_ClearTable(modes_table); + TXT_SetColumnWidths(modes_table, 14, 14, 14); + + for (i=0; modes[i].w != 0; ++i) + { + // Skip bad fullscreen modes + + if (fullscreen && !GoodFullscreenMode(&modes[i])) { - TXT_SetRadioButtonLabel(modes[i].widget, modes[i].description_4_3); + continue; } + + sprintf(buf, "%ix%i", modes[i].w, modes[i].h); + rbutton = TXT_NewRadioButton(buf, &vidmode, i); + TXT_AddWidget(modes_table, rbutton); + TXT_SignalConnect(rbutton, "selected", ModeSelected, &modes[i]); } + + // Find the nearest mode in the list that matches the current + // settings + + vidmode = FindBestMode(modes); } void ConfigDisplay(void) { txt_window_t *window; - txt_table_t *ar_table; txt_table_t *modes_table; - txt_radiobutton_t *rbutton; - txt_dropdown_list_t *ar_dropdown; - int i; - - // Find the current mode - - SetCurrentMode(); + txt_checkbox_t *fs_checkbox; + txt_checkbox_t *ar_checkbox; // Open the window window = TXT_NewWindow("Display Configuration"); TXT_AddWidgets(window, - TXT_NewCheckBox("Fullscreen", &fullscreen), - ar_table = TXT_NewTable(2), - TXT_NewSeparator("Screen mode"), - modes_table = TXT_NewTable(2), - TXT_NewSeparator("Misc."), - TXT_NewCheckBox("Show ENDOOM screen", &show_endoom), + fs_checkbox = TXT_NewCheckBox("Fullscreen", &fullscreen), + ar_checkbox = TXT_NewCheckBox("Correct aspect ratio", + &aspect_ratio_correct), NULL); - TXT_SetColumnWidths(ar_table, 25, 0); - #ifdef _WIN32 { + txt_table_t *driver_table; txt_dropdown_list_t *driver_list; + driver_table = TXT_NewTable(2); + + TXT_SetColumnWidths(driver_table, 25, 0); + driver_list = TXT_NewDropdownList(&win32_video_driver, win32_video_drivers, 2); @@ -185,32 +292,25 @@ void ConfigDisplay(void) TXT_SignalConnect(driver_list, "changed", UpdateVideoDriver, NULL); SetWin32VideoDriver(); - TXT_AddWidgets(ar_table, + TXT_AddWidgets(driver_table, TXT_NewLabel("Video driver"), driver_list, NULL); + + TXT_AddWidget(window, driver_table); } #endif - TXT_AddWidgets(ar_table, - TXT_NewLabel("Aspect ratio correction"), - ar_dropdown = TXT_NewDropdownList(&aspect_ratio_correct, - aspect_ratio_strings, - NUM_RATIO_CORRECT), + TXT_AddWidgets(window, + TXT_NewSeparator("Screen mode"), + modes_table = TXT_NewTable(3), + TXT_NewSeparator("Misc."), + TXT_NewCheckBox("Show ENDOOM screen", &show_endoom), NULL); - TXT_SignalConnect(ar_dropdown, "changed", UpdateModes, NULL); - - TXT_SetColumnWidths(modes_table, 14, 14); - - for (i=0; modes[i].description != NULL; ++i) - { - rbutton = TXT_NewRadioButton(modes[i].description, &vidmode, i); - modes[i].widget = rbutton; - TXT_AddWidget(modes_table, rbutton); - TXT_SignalConnect(rbutton, "selected", ModeSelected, &modes[i]); - } + TXT_SignalConnect(fs_checkbox, "changed", GenerateModesTable, modes_table); + TXT_SignalConnect(ar_checkbox, "changed", GenerateModesTable, modes_table); - UpdateModes(NULL, NULL); + GenerateModesTable(NULL, modes_table); } diff --git a/setup/display.h b/setup/display.h index c82f70b3..d8dcce7f 100644 --- a/setup/display.h +++ b/setup/display.h @@ -25,7 +25,7 @@ extern int autoadjust_video_settings; extern int aspect_ratio_correct; extern int fullscreen; -extern int screenmultiply; +extern int screen_width, screen_height; extern int startup_delay; extern int show_endoom; extern char *video_driver; diff --git a/textscreen/txt_table.c b/textscreen/txt_table.c index 8b31af24..29798906 100644 --- a/textscreen/txt_table.c +++ b/textscreen/txt_table.c @@ -33,14 +33,18 @@ #include "txt_strut.h" #include "txt_table.h" -static void TXT_TableDestructor(TXT_UNCAST_ARG(table)) +// Remove all entries from a table + +void TXT_ClearTable(TXT_UNCAST_ARG(table)) { TXT_CAST_ARG(txt_table_t, table); int i; // Free all widgets + // Skip over the first (num_columns) widgets in the array, as these + // are the column struts used to control column width - for (i=0; i<table->num_widgets; ++i) + for (i=table->columns; i<table->num_widgets; ++i) { if (table->widgets[i] != NULL) { @@ -48,9 +52,16 @@ static void TXT_TableDestructor(TXT_UNCAST_ARG(table)) } } - // Free table resources + // Shrink the table to just the column strut widgets + + table->num_widgets = table->columns; +} + +static void TXT_TableDestructor(TXT_UNCAST_ARG(table)) +{ + TXT_CAST_ARG(txt_table_t, table); - free(table->widgets); + TXT_ClearTable(table); } static int TableRows(txt_table_t *table) diff --git a/textscreen/txt_table.h b/textscreen/txt_table.h index c3a3c5a8..d42e9adb 100644 --- a/textscreen/txt_table.h +++ b/textscreen/txt_table.h @@ -53,6 +53,7 @@ void TXT_AddWidget(TXT_UNCAST_ARG(table), TXT_UNCAST_ARG(widget)); void TXT_AddWidgets(TXT_UNCAST_ARG(table), ...); int TXT_SelectWidget(TXT_UNCAST_ARG(table), TXT_UNCAST_ARG(widget)); void TXT_SetColumnWidths(TXT_UNCAST_ARG(table), ...); +void TXT_ClearTable(TXT_UNCAST_ARG(table)); #endif /* #ifndef TXT_TABLE_T */ |