Handle Videomodes better #211

Closed
alufolie91 wants to merge 28 commits from vidmodestuff into Saturn-Next
pull from: vidmodestuff
6 changed files with 320 additions and 139 deletions

No files matched your search

+11
View File
@@ -115,6 +115,10 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h)
return -1;
}
void VID_RefreshModeList(void)
{
}
void VID_PrepareModeList(void)
{
}
@@ -125,6 +129,13 @@ INT32 VID_SetMode(INT32 modeNum)
return true;
}
boolean I_CheckAboveDesktopRes(INT32 width, INT32 height)
{
(void)width;
(void)height;
return false;
}
void I_StartupGraphics(void)
{
}
+2
View File
@@ -95,6 +95,7 @@ INT32 VID_SetMode(INT32 modenum);
*/
const char *VID_GetModeName(INT32 modenum);
void VID_RefreshModeList(void);
void VID_PrepareModeList(void);
/** \brief can video system do fullscreen
@@ -121,6 +122,7 @@ void I_ReadScreen(UINT8 * restrict scr, INT32 scale);
UINT32 I_GetRefreshRate(void);
boolean I_CheckAboveDesktopRes(INT32 width, INT32 height);
boolean I_CheckNativeRes(void);
void I_SetBorderlessWindow(void);
+43 -51
View File
@@ -306,7 +306,6 @@ static void M_SetupMultiHandler(INT32 choice);
// Options
// Split into multiple parts due to size
static void M_VideoModeMenu(INT32 choice);
static void M_Setup1PControlsMenu(void);
static void M_Setup2PControlsMenu(void);
static void M_Setup3PControlsMenu(void);
@@ -9713,14 +9712,11 @@ static void M_ResetControls(INT32 choice)
// ===============
//added : 30-01-98:
#define MAXCOLUMNMODES 12 //max modes displayed in one column
#define MAXMODEDESCS (MAXCOLUMNMODES*3)
static modedesc_t modedescs[MAXMODEDESCS];
static void M_VideoModeMenu(INT32 choice)
void M_VideoModeMenu(INT32 choice)
{
INT32 i, j, vdup, nummodes, width, height;
INT32 i, nummodes, width, height;
const char *desc;
(void)choice;
@@ -9734,54 +9730,30 @@ static void M_VideoModeMenu(INT32 choice)
nummodes = VID_NumModes();
// DOS does not skip mode 0, because mode 0 is ALWAYS present
i = 0;
for (; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++)
for (i = 0; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++)
{
desc = VID_GetModeName(i);
if (desc)
{
vdup = 0;
// when a resolution exists both under VGA and VESA, keep the
// VESA mode, which is always a higher modenum
for (j = 0; j < vidm_nummodes; j++)
{
if (fastcmp(modedescs[j].desc, desc))
{
// mode(0): 320x200 is always standard VGA, not vesa
if (modedescs[j].modenum)
{
modedescs[j].modenum = i;
vdup = 1;
if (!desc)
continue;
if (i == vid.modenum)
vidm_selected = j;
}
else
vdup = 1;
modedescs[vidm_nummodes].modenum = i;
modedescs[vidm_nummodes].desc = desc;
break;
}
}
if (i == vid.modenum)
vidm_selected = vidm_nummodes;
if (!vdup)
{
modedescs[vidm_nummodes].modenum = i;
modedescs[vidm_nummodes].desc = desc;
// Pull out the width and height
sscanf(desc, "%u%*c%u", &width, &height);
if (i == vid.modenum)
vidm_selected = vidm_nummodes;
// Show resolutions above desktop res as red.
if (I_CheckAboveDesktopRes(width, height))
modedescs[vidm_nummodes].goodratio = 2;
// Show multiples of 320x200 as green.
else if (SCR_IsAspectCorrect(width, height))
modedescs[vidm_nummodes].goodratio = 1;
// Pull out the width and height
sscanf(desc, "%u%*c%u", &width, &height);
// Show multiples of 320x200 as green.
if (SCR_IsAspectCorrect(width, height))
modedescs[vidm_nummodes].goodratio = 1;
vidm_nummodes++;
}
}
vidm_nummodes++;
}
vidm_column_size = (vidm_nummodes+2) / 3;
@@ -9977,7 +9949,11 @@ static void M_DrawVideoMode(void)
V_DrawString(row, col, highlightflags|MENUCAPS, modedescs[i].desc);
// Show multiples of 320x200 as green.
else
V_DrawString(row, col, ((modedescs[i].goodratio) ? recommendedflags : 0)|MENUCAPS, modedescs[i].desc);
{
const UINT8 goodratio = modedescs[i].goodratio;
const INT32 goodflag = ((goodratio == 2) ? warningflags : (goodratio == 1) ? recommendedflags : 0);
V_DrawString(row, col, goodflag|MENUCAPS, modedescs[i].desc);
}
col += 8;
if ((i % vidm_column_size) == (vidm_column_size-1))
@@ -10001,7 +9977,6 @@ static void M_DrawVideoMode(void)
va("Wait %d second%s", testtime, (testtime > 1) ? "s" : ""));
M_CentreText(OP_VideoModeDef.y + 158,
"or press ESC to return");
}
else
{
@@ -10017,9 +9992,26 @@ static void M_DrawVideoMode(void)
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 138,
recommendedflags|MENUCAPS, "Marked modes are recommended.");
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 146,
highlightflags|MENUCAPS, "Other modes may have visual errors.");
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 158,
highlightflags|MENUCAPS, "Larger modes may have performance issues.");
warningflags|MENUCAPS, "Marked modes are above Desktop resolution");
if (rendermode == render_opengl)
{
#ifdef USE_FBO_OGL
if (!cv_glframebuffer.value)
#endif
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 154,
warningflags|MENUCAPS, "and will have visual errors in OpenGL mode.");
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 166,
highlightflags|MENUCAPS, "Other modes may have visual errors.");
}
else
{
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 154,
highlightflags|MENUCAPS, "Other modes may have visual errors.");
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 166,
highlightflags|MENUCAPS, "Larger modes may have performance issues.");
}
}
// Draw the cursor for the VidMode menu
+5
View File
@@ -223,6 +223,11 @@ extern menu_t *currentMenu;
extern menu_t MainDef;
extern menu_t SP_LoadDef;
#define MAXCOLUMNMODES 12 //max modes displayed in one column
#define MAXMODEDESCS (MAXCOLUMNMODES*3)
extern menu_t OP_VideoModeDef;
void M_VideoModeMenu(INT32 choice);
// Call upon joystick hotplug
void M_SetupJoystickMenu(INT32 choice);
extern menu_t OP_JoystickSetDef;
+5 -4
View File
@@ -42,8 +42,8 @@ INT32 setmodeneeded = 0; // video mode change needed if > 0 (the mode number to
static CV_PossibleValue_t shittyscreen_cons_t[] = {{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}, {0, NULL}};
//added : 03-02-98: default screen mode, as loaded/saved in config
consvar_t cv_scr_width = {"scr_width", "1280", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_scr_width = {"scr_width", "1280", CV_SAVE|CV_CALL, CV_Unsigned, VID_RefreshModeList, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE|CV_CALL, CV_Unsigned, VID_RefreshModeList, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_frameskip = {"frameskip", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -315,8 +315,9 @@ void SCR_CheckDefaultMode(void)
void SCR_SetDefaultMode(void)
{
// remember the default screen size
CV_SetValue(&cv_scr_width, vid.width);
CV_SetValue(&cv_scr_height, vid.height);
CV_StealthSetValue(&cv_scr_width, vid.width);
CV_StealthSetValue(&cv_scr_height, vid.height);
VID_RefreshModeList(); // probably not needed but justin käs
}
// Change fullscreen on/off according to cv_fullscreen
+254 -84
View File
@@ -84,15 +84,20 @@
#endif
// maximum number of windowed modes (see windowedModes[][])
#define MAXWINMODES (22)
#define MAXWINMODES (128)
/** \brief
*/
static INT32 numVidModes = -1;
static void I_FillScreenResolutionsList(boolean force);
/** \brief
*/
static char vidModeName[33][32]; // allow 33 different modes
typedef struct
{
char name[10];
INT32 w;
INT32 h;
} video_mode_t;
static video_mode_t windowedModes[MAXWINMODES] = {{"320x200", 320, 200}}; // make sure the default mode exists
static const char *fallback_resolution_name = "Fallback";
static int vid_nummodes = 1;
rendermode_t rendermode = render_none;
@@ -139,9 +144,6 @@ static SDL_bool disable_mouse = SDL_FALSE;
#define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN)
#define MOUSEBUTTONS_MAX MOUSEBUTTONS
// first entry in the modelist which is not bigger than MAXVIDWIDTHxMAXVIDHEIGHT
static INT32 firstEntry = 0;
// Total mouse motion X/Y offsets
static INT32 mousemovex = 0, mousemovey = 0;
@@ -162,38 +164,6 @@ static SDL_Texture *texture = NULL;
static SDL_GLContext sdlglcontext = NULL;
#endif
static SDL_bool havefocus = SDL_TRUE;
static const char *fallback_resolution_name = "Fallback";
// windowed video modes from which to choose from.
static INT32 windowedModes[MAXWINMODES][2] =
{
{2560,1440}, // 1.66
{1920,1200}, // 1.60,6.00
{1920,1080}, // 1.66
{1680,1050}, // 1.60,5.25
{1600,1200}, // 1.33
{1600, 900}, // 1.66
{1366, 768}, // 1.66
{1440, 900}, // 1.60,4.50
{1280,1024}, // 1.33?
{1280, 960}, // 1.33,4.00
{1280, 800}, // 1.60,4.00
{1280, 720}, // 1.66
{1152, 864}, // 1.33,3.60
{1024, 768}, // 1.33,3.20
{ 960, 600}, // 1.33,3.20
{ 800, 600}, // 1.33,2.50
{ 735, 415}, // 1.33,2.50
{ 640, 480}, // 1.33,2.00
{ 640, 400}, // 1.60,2.00
{ 500, 300}, // 1.33
{ 320, 240}, // 1.33,1.00
{ 320, 200}, // 1.60,1.00
};
#define CUSTOMMODENUM 9999
static INT32 custom_width = 0;
static INT32 custom_height = 0;
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
static void Impl_SetWindowIcon(void);
@@ -519,11 +489,20 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
return;
}
if (windowmoved && rendermode == render_opengl)
if (windowmoved)
{
I_CheckDesktopRes();
// if we say moved our game window to a different screen
// refetch our resolutions
I_FillScreenResolutionsList(false);
#ifdef HWRENDER
#ifdef USE_FBO_OGL
I_DownSample();
if (rendermode == render_opengl)
{
I_DownSample();
}
#endif
#endif
windowmoved = SDL_FALSE;
}
@@ -540,7 +519,8 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
if (!firsttimeonmouse)
{
if (cv_usemouse.value) I_StartupMouse();
if (cv_usemouse.value)
I_StartupMouse();
}
}
else if (!mousefocus && !kbfocus)
@@ -1222,9 +1202,9 @@ static void VID_Command_ModeList_f(void)
"Under opengl, fullscreen only supports native desktop resolution.\n"
"Under software, the mode is stretched up to desktop resolution.\n");
for (i = 0; i < MAXWINMODES; i++)
for (i = 0; i < vid_nummodes; i++)
{
CONS_Printf("%2d: %dx%d\n", i, windowedModes[i][0], windowedModes[i][1]);
CONS_Printf("%2d: %dx%d\n", i, windowedModes[i].w, windowedModes[i].h);
}
}
@@ -1263,7 +1243,7 @@ static void I_CheckDesktopRes(void)
return;
}
if (SDL_GetDesktopDisplayMode(currentDisplayIndex, &curmode) != 0)
if (SDL_GetCurrentDisplayMode(currentDisplayIndex, &curmode) != 0)
{
return;
}
@@ -1278,6 +1258,11 @@ boolean I_CheckNativeRes(void)
return (vid.width == desktopwidth && vid.height == desktopheight);
}
boolean I_CheckAboveDesktopRes(INT32 width, INT32 height)
{
return (width > desktopwidth || height > desktopheight);
}
#ifdef USE_FBO_OGL
void RefreshOGLSDLSurface(void)
@@ -1508,13 +1493,207 @@ void I_SetPalette(RGBA_t *palette)
}
}
// make sure the canonical resolutions are always available
static const struct {
const int w, h;
} canonicals[] = {
{1920, 1200}, // 16:10
{1280, 800}, // 16:10
{ 960, 600}, // 16:10
{ 640, 400}, // 16:10
{ 320, 200}, // Vanilla Doom
};
static const int num_canonicals = sizeof(canonicals)/sizeof(*canonicals);
// [FG] sort resolutions by width first and height second
static int cmp_resolutions(const void *a, const void *b)
{
const video_mode_t *ma = (const video_mode_t *) a;
const video_mode_t *mb = (const video_mode_t *) b;
return (ma->w == mb->w) ? mb->h - ma->h : mb->w - ma->w;
}
static void I_AppendResolution(SDL_DisplayMode *mode, int *list_size)
{
int i;
for (i = 0; i < *list_size; i++)
if (windowedModes[i].w == mode->w
&& windowedModes[i].h == mode->h)
return;
snprintf(windowedModes[*list_size].name,
sizeof(windowedModes[*list_size].name),
"%dx%d", mode->w, mode->h);
windowedModes[*list_size].w = mode->w;
windowedModes[*list_size].h = mode->h;
(*list_size)++;
}
// small helper to check if a video mode is canonical
static boolean IsModeCanonical(int w, int h)
{
for (int i = 0; i < num_canonicals; i++)
{
if (canonicals[i].w == w && canonicals[i].h == h)
return true;
}
return false;
}
// check if our desired resolution already is in the videomode list
static int IsCustomResolutionInList(int list_size)
{
INT32 custom_w = cv_scr_width.value;
INT32 custom_h = cv_scr_height.value;
// startup
if (!custom_w || !custom_h)
return -2;
// invalid resolution
// dont even attempt to add it
if (custom_w < BASEVIDWIDTH || custom_w > MAXVIDWIDTH
|| custom_h < BASEVIDHEIGHT || custom_h > MAXVIDHEIGHT)
return -1;
for (int i = 0; i < list_size; i++)
{
if (windowedModes[i].w == custom_w && windowedModes[i].h == custom_h)
{
return 1;
}
}
return 0;
}
//
// I_FillScreenResolutionsList
// Get all the supported screen resolutions
// and fill the list with them
//
static void I_FillScreenResolutionsList(boolean force)
{
int currentDisplayIndex = -1;
static int oldDisplayIndex = -1;
SDL_DisplayMode mode;
int i = 0, list_size = 0;
int count = 0;
char custom_resolution[10];
currentDisplayIndex = SDL_GetWindowDisplayIndex(window);
// No valid index
if (currentDisplayIndex < 0)
{
return;
}
// didnt change screen, no need to redo the list
if (!force && currentDisplayIndex == oldDisplayIndex)
{
return;
}
oldDisplayIndex = currentDisplayIndex;
// Don't call SDL_ListModes if SDL has not been initialized
count = SDL_GetNumDisplayModes(currentDisplayIndex);
list_size = 0;
// on success, SDL_GetNumDisplayModes() always returns at least 1
if (count > 0)
{
// -2 for the desired resolution and for NULL
count = min(count, MAXWINMODES - 2 - num_canonicals);
for (i = count - 1 + num_canonicals; i >= 0; i--)
{
// make sure the canonical resolutions are always available
if (i > count - 1)
{
mode.w = canonicals[i - count].w;
mode.h = canonicals[i - count].h;
}
else
{
SDL_GetDisplayMode(currentDisplayIndex, i, &mode);
}
I_AppendResolution(&mode, &list_size);
}
windowedModes[list_size].name[0] = '\0';
}
const int customresinlist = IsCustomResolutionInList(list_size);
if (customresinlist == 0)
{
// did not find mode from list, make custom resolution if the values somewhat make sense
if (list_size < MAXWINMODES)
{
snprintf(custom_resolution, sizeof(custom_resolution), "%dx%d", cv_scr_width.value, cv_scr_height.value);
// [FG] if the desired resolution not in the list, append it
snprintf(windowedModes[list_size].name,
sizeof(windowedModes[list_size].name),
"%dx%d", cv_scr_width.value, cv_scr_height.value);
windowedModes[list_size].w = cv_scr_width.value;
windowedModes[list_size].h = cv_scr_height.value;
list_size++;
}
else
CONS_Alert(CONS_ERROR, "Could not set custom resolution!\n");
}
else if (customresinlist == -1)
CONS_Alert(CONS_ERROR, "Could not set custom resolution!\n");
// [FG] sort the list
SDL_qsort(windowedModes, list_size, sizeof(*windowedModes), cmp_resolutions);
// if we have more video modes than we can list
// try to shrink the list, lowest resolutions first
// whilst keeping the canonicals
if (list_size > MAXMODEDESCS)
{
// list is sorted from largest to smallest, so start at the end
for (i = list_size - 1; i >= 0 && list_size > MAXMODEDESCS; i--)
{
if (IsModeCanonical(windowedModes[i].w, windowedModes[i].h))
continue;
// Should we like, instead prioritize checking for non aspect correct resolutions to remove?
// we gotta shift everything
// due to canonicals we cant just shrink the list
for (int k = i; k < list_size - 1; k++)
{
windowedModes[k] = windowedModes[k + 1];
}
list_size--;
}
}
windowedModes[list_size].name[0] = '\0';
vid_nummodes = list_size;
// be sure to update the video menu
if (menuactive &&
currentMenu == &OP_VideoModeDef)
M_VideoModeMenu(0);
}
// return number of fullscreen + X11 modes
INT32 VID_NumModes(void)
{
if (USE_FULLSCREEN && numVidModes != -1)
return numVidModes - firstEntry;
else
return MAXWINMODES;
return vid_nummodes;
}
const char *VID_GetModeName(INT32 modeNum)
@@ -1524,42 +1703,34 @@ const char *VID_GetModeName(INT32 modeNum)
return fallback_resolution_name;
}
if (modeNum > MAXWINMODES)
if (modeNum > vid_nummodes)
return NULL;
sprintf(&vidModeName[modeNum][0], "%dx%d",
windowedModes[modeNum][0],
windowedModes[modeNum][1]);
return &vidModeName[modeNum][0];
return windowedModes[modeNum].name;
}
INT32 VID_GetModeForSize(INT32 w, INT32 h)
{
int i;
for (i = 0; i < MAXWINMODES; i++)
for (i = 0; i < vid_nummodes; i++)
{
if (windowedModes[i][0] == w && windowedModes[i][1] == h)
if (windowedModes[i].w == w && windowedModes[i].h == h)
{
return i;
}
}
// did not find mode from list, make custom resolution if the values somewhat make sense
// opengl mode does not mind about max resolution defined in screen.h
// if not using opengl, check against the maximum as well
if ((w >= BASEVIDWIDTH && h >= BASEVIDHEIGHT) &&
(rendermode == render_opengl || (w <= MAXVIDWIDTH && h <= MAXVIDHEIGHT)))
{
custom_width = w;
custom_height = h;
return CUSTOMMODENUM;
}
return -1;
}
void VID_RefreshModeList(void)
{
// check if we even need to rebuild the list
if (IsCustomResolutionInList(vid_nummodes) == 0)
I_FillScreenResolutionsList(true);
}
void VID_PrepareModeList(void)
{
// Under SDL2, we just use the windowed modes list, and scale in windowed fullscreen.
@@ -1591,17 +1762,10 @@ INT32 VID_SetMode(INT32 modeNum)
{
vid.recalc = true;
if (modeNum >= 0 && modeNum < MAXWINMODES)
if (modeNum >= 0 && modeNum < vid_nummodes)
{
vid.width = windowedModes[modeNum][0];
vid.height = windowedModes[modeNum][1];
vid.modenum = modeNum;
}
else if (modeNum == CUSTOMMODENUM && custom_width && custom_height)
{
// at this point these values are assumed to be okay
vid.width = custom_width;
vid.height = custom_height;
vid.width = windowedModes[modeNum].w;
vid.height = windowedModes[modeNum].h;
vid.modenum = modeNum;
}
else
@@ -1634,7 +1798,6 @@ INT32 VID_SetMode(INT32 modeNum)
return SDL_TRUE;
}
static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
@@ -1657,6 +1820,9 @@ static SDL_bool Impl_CreateContext(void)
I_Error("Failed to set up GL context: %s\n", SDL_GetError());
}
// be sure to fill the resolution list the moment we have a window
I_FillScreenResolutionsList(false);
return SDL_TRUE;
}
#endif
@@ -1698,6 +1864,9 @@ static SDL_bool Impl_CreateContext(void)
SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT);
// be sure to fill the resolution list the moment we have a window
I_FillScreenResolutionsList(false);
return SDL_TRUE;
}
@@ -1935,8 +2104,6 @@ void I_StartupGraphics(void)
usesdl2soft = M_CheckParm("-softblit");
borderlesswindow = M_CheckParm("-borderless");
VID_Command_ModeList_f();
#ifdef HWRENDER
if (rendermode == render_opengl)
{
@@ -1960,6 +2127,9 @@ void I_StartupGraphics(void)
vid.height = BASEVIDHEIGHT; // BitsPerPixel is the SDL interface's
vid.recalc = true; // Set up the console stufff
// be sure to print AFTER window creation
VID_Command_ModeList_f();
#ifdef HAVE_TTF
I_ShutdownTTF();
#endif