Compare commits

..
Author SHA1 Message Date
alufolie91 926c1de52a software: make R_DrawWallColumn being able to render "holey" textures
not the most efficient but idk a better solution to this, and clipping code may cause some other undesired effects, but well were not supposed to be drawing textures with holes on single sided walls eitherways, but here we are
basically this copies columns into a buffer filled with cyan pixels, so the holes become cyan instead of nothing, which we can cut again using the twomultipatch drawers
fixes the "melt" effect on some things like spelunky or music plant (and well reading/writing oob)
2026-04-05 20:37:15 +02:00
indev 489a58f9fd Allocate all colormaps with PU_STATIC 2026-04-05 18:31:55 +02:00
alufolie91 b26effa241 Merge pull request #223 from Indev450/bluaopti2
Some optimizations and fixes for BLUA from LUA
2026-04-05 18:28:50 +02:00
alufolie91 efd8c20d26 enable lto by default on makefile builds
change flag to NOLTO to disable lto
at this point we shouldnt have any issues anymore since the utter crapton of bugfixes
2026-04-05 18:26:16 +02:00
11 changed files with 204 additions and 330 deletions

No files matched your search

+2 -2
View File
@@ -93,7 +93,7 @@
# NOLDWARNING=1 - ?
# NOSDLMAIN=1 - ?
# SDLMAIN=1 - ?
# USELTO=1 - Enable building with LTO.
# NOLTO=1 - Disable link time optimizations
#
# Library configuration flags:
# Everything here is an override.
@@ -260,7 +260,7 @@ debug_opts=-D_DEBUG
else # build a normal optimized version
debug_opts=-DNDEBUG
opts+=-O3
ifdef USELTO
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
-11
View File
@@ -115,10 +115,6 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h)
return -1;
}
void VID_RefreshModeList(void)
{
}
void VID_PrepareModeList(void)
{
}
@@ -129,13 +125,6 @@ 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 -2
View File
@@ -130,8 +130,8 @@ extern char logfilename[1024];
#else
#define VERSION 1 // Game version
#define SUBVERSION 6 // more precise version number
#define VERSIONSTRING "Saturn v9.3 - Testing"
#define VERSIONSTRINGW L"Saturn v9.3 - Testing"
#define VERSIONSTRING "Saturn v9.2"
#define VERSIONSTRINGW L"Saturn v9.2"
#define SATURN_TESTING // comment out for saturn release builds!
-2
View File
@@ -95,7 +95,6 @@ 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
@@ -122,7 +121,6 @@ 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);
+50 -43
View File
@@ -308,6 +308,7 @@ 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);
@@ -9747,11 +9748,14 @@ 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];
void M_VideoModeMenu(INT32 choice)
static void M_VideoModeMenu(INT32 choice)
{
INT32 i, nummodes, width, height;
INT32 i, j, vdup, nummodes, width, height;
const char *desc;
(void)choice;
@@ -9765,30 +9769,54 @@ void M_VideoModeMenu(INT32 choice)
nummodes = VID_NumModes();
// DOS does not skip mode 0, because mode 0 is ALWAYS present
for (i = 0; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++)
i = 0;
for (; i < nummodes && vidm_nummodes < MAXMODEDESCS; i++)
{
desc = VID_GetModeName(i);
if (desc)
{
vdup = 0;
if (!desc)
continue;
// 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;
modedescs[vidm_nummodes].modenum = i;
modedescs[vidm_nummodes].desc = desc;
if (i == vid.modenum)
vidm_selected = j;
}
else
vdup = 1;
if (i == vid.modenum)
vidm_selected = vidm_nummodes;
break;
}
}
// Pull out the width and height
sscanf(desc, "%u%*c%u", &width, &height);
if (!vdup)
{
modedescs[vidm_nummodes].modenum = i;
modedescs[vidm_nummodes].desc = desc;
// 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;
if (i == vid.modenum)
vidm_selected = vidm_nummodes;
vidm_nummodes++;
// 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_column_size = (vidm_nummodes+2) / 3;
@@ -10005,11 +10033,7 @@ static void M_DrawVideoMode(void)
V_DrawString(row, col, highlightflags|MENUCAPS, modedescs[i].desc);
// Show multiples of 320x200 as green.
else
{
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);
}
V_DrawString(row, col, ((modedescs[i].goodratio) ? recommendedflags : 0)|MENUCAPS, modedescs[i].desc);
col += 8;
if ((i % vidm_column_size) == (vidm_column_size-1))
@@ -10048,26 +10072,9 @@ 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,
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.");
}
highlightflags|MENUCAPS, "Other modes may have visual errors.");
V_DrawCenteredString(BASEVIDWIDTH/2, OP_VideoModeDef.y + 158,
highlightflags|MENUCAPS, "Larger modes may have performance issues.");
}
// Draw the cursor for the VidMode menu
-5
View File
@@ -223,11 +223,6 @@ 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;
-2
View File
@@ -515,8 +515,6 @@ void R_FlushTranslationColormapCache(void)
// in reality, the few routines that can work for either mode, are
// put here
enum columncontext_e columncontext = COLUMNCONTEXT_DIRECT;
enum ColumnFlushType
{
FLUSH_NONE = 0x0000,
+2 -1
View File
@@ -105,7 +105,6 @@ enum columncontext_e
COLUMNCONTEXT_FLUSH,
};
extern enum columncontext_e columncontext;
void R_SetColumnContext(enum columncontext_e _columncontext);
void R_ResetColumnBuffer(void);
@@ -124,6 +123,8 @@ enum
COLDRAWFUNC_TRANSTRANS,
COLDRAWFUNC_TWOSMULTIPATCH,
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
COLDRAWFUNC_TWOSMULTIPATCH_DIRECT,
COLDRAWFUNC_TWOSMULTIPATCHTRANS_DIRECT,
COLDRAWFUNC_FOG,
COLDRAWFUNC_MAX
+56 -2
View File
@@ -16,6 +16,7 @@
#include "r_sky.h"
#include <algorithm>
#include <vector>
#include "r_portal.h"
#include "r_splats.h"
@@ -1166,6 +1167,37 @@ static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bott
// CALLED: CORE LOOPING ROUTINE.
//
static std::vector<UINT8> holecol(256);
// used for R_DrawWallColumn
// convert "holey" columns into contigous columns
// filled with cyan in place of holes
static UINT8 *R_GetHoleColumn(drawcolumndata_t* dc)
{
column_t *col = (column_t *)(dc->source - 3);
const INT32 texheight = dc->texheight;
holecol.resize(texheight);
// fill in everything with cyan so we can skip it
memset(holecol.data(), TRANSPARENTPIXEL, texheight);
// shamelessly copy pasted from R_GenerateTexture
INT32 topdelta, prevdelta = -1;
while (col->topdelta != 0xff)
{
topdelta = col->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
memcpy(holecol.data() + topdelta, (UINT8*)col + 4, col->length);
col = (column_t *)((UINT8*)col + col->length + 4);
}
return holecol.data();
}
static void R_DrawWallColumn(drawcolumndata_t* dc, INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, boolean remap)
{
const INT32 itexturecolumn = texturecolumn >> FRACBITS;
@@ -1175,13 +1207,35 @@ static void R_DrawWallColumn(drawcolumndata_t* dc, INT32 yl, INT32 yh, fixed_t m
dc->source = R_GetColumn(texture, itexturecolumn);
dc->texheight = textureheight[texture] >> FRACBITS;
dc->sourcelength = dc->texheight;
R_SetColumnFunc(colfunctype);
coldrawfunc_t* colfunccopy = colfunc;
if (textures[texture]->holes)
{
dc->source = R_GetHoleColumn(dc);
if (cv_softcyancut.value)
{
// need to use multipatch drawers to cut cyan pixels
if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true)
{
colfunccopy = colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS_DIRECT];
}
else
{
colfunccopy = colfuncs[COLDRAWFUNC_TWOSMULTIPATCH_DIRECT];
}
}
}
drawcolumndata_t dc_copy = *dc;
if (remap)
{
dc_copy.colormap += COLORMAP_REMAPOFFSET;
}
colfunccopy(const_cast<drawcolumndata_t*>(&dc_copy));
}
@@ -1390,7 +1444,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
// calculate lighting
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
dc->colormap = walllights[pindex];
@@ -1425,7 +1479,7 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE)
if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1;
if (dc->lightlist[i].extra_colormap)
+8 -6
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_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_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_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};
@@ -120,6 +120,10 @@ static void SCR_SetDrawFuncs(enum columncontext_e _columncontext)
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn;
}
// gotta keep a copy of those for R_DrawWallColumn.....
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH_DIRECT] = R_Draw2sMultiPatchColumn;
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS_DIRECT] = R_Draw2sMultiPatchTranslucentColumn;
colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn;
R_SetColumnFunc(BASEDRAWFUNC);
@@ -154,7 +158,6 @@ void SCR_SetMode(void)
// effectively adding massive overhead due to excessive flushing, so we draw our masked thing directly to screen instead
void R_SetColumnContext(enum columncontext_e _columncontext)
{
columncontext = _columncontext;
SCR_SetDrawFuncs(_columncontext); // set our column drawers
}
@@ -315,9 +318,8 @@ void SCR_CheckDefaultMode(void)
void SCR_SetDefaultMode(void)
{
// remember the default screen size
CV_StealthSetValue(&cv_scr_width, vid.width);
CV_StealthSetValue(&cv_scr_height, vid.height);
VID_RefreshModeList(); // probably not needed but justin käs
CV_SetValue(&cv_scr_width, vid.width);
CV_SetValue(&cv_scr_height, vid.height);
}
// Change fullscreen on/off according to cv_fullscreen
+84 -254
View File
@@ -84,20 +84,15 @@
#endif
// maximum number of windowed modes (see windowedModes[][])
#define MAXWINMODES (128)
#define MAXWINMODES (22)
static void I_FillScreenResolutionsList(boolean force);
/** \brief
*/
static INT32 numVidModes = -1;
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;
/** \brief
*/
static char vidModeName[33][32]; // allow 33 different modes
rendermode_t rendermode = render_none;
@@ -144,6 +139,9 @@ 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;
@@ -164,6 +162,38 @@ 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);
@@ -489,20 +519,11 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
return;
}
if (windowmoved)
if (windowmoved && rendermode == render_opengl)
{
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
if (rendermode == render_opengl)
{
I_DownSample();
}
#endif
I_DownSample();
#endif
windowmoved = SDL_FALSE;
}
@@ -519,8 +540,7 @@ 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)
@@ -1214,9 +1234,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 < vid_nummodes; i++)
for (i = 0; i < MAXWINMODES; i++)
{
CONS_Printf("%2d: %dx%d\n", i, windowedModes[i].w, windowedModes[i].h);
CONS_Printf("%2d: %dx%d\n", i, windowedModes[i][0], windowedModes[i][1]);
}
}
@@ -1255,7 +1275,7 @@ static void I_CheckDesktopRes(void)
return;
}
if (SDL_GetCurrentDisplayMode(currentDisplayIndex, &curmode) != 0)
if (SDL_GetDesktopDisplayMode(currentDisplayIndex, &curmode) != 0)
{
return;
}
@@ -1270,11 +1290,6 @@ 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)
@@ -1505,207 +1520,13 @@ 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)
{
return vid_nummodes;
if (USE_FULLSCREEN && numVidModes != -1)
return numVidModes - firstEntry;
else
return MAXWINMODES;
}
const char *VID_GetModeName(INT32 modeNum)
@@ -1715,32 +1536,40 @@ const char *VID_GetModeName(INT32 modeNum)
return fallback_resolution_name;
}
if (modeNum > vid_nummodes)
if (modeNum > MAXWINMODES)
return NULL;
return windowedModes[modeNum].name;
sprintf(&vidModeName[modeNum][0], "%dx%d",
windowedModes[modeNum][0],
windowedModes[modeNum][1]);
return &vidModeName[modeNum][0];
}
INT32 VID_GetModeForSize(INT32 w, INT32 h)
{
int i;
for (i = 0; i < vid_nummodes; i++)
for (i = 0; i < MAXWINMODES; i++)
{
if (windowedModes[i].w == w && windowedModes[i].h == h)
if (windowedModes[i][0] == w && windowedModes[i][1] == h)
{
return i;
}
}
return -1;
}
// 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;
}
void VID_RefreshModeList(void)
{
// check if we even need to rebuild the list
if (IsCustomResolutionInList(vid_nummodes) == 0)
I_FillScreenResolutionsList(true);
return -1;
}
void VID_PrepareModeList(void)
@@ -1774,10 +1603,17 @@ INT32 VID_SetMode(INT32 modeNum)
{
vid.recalc = true;
if (modeNum >= 0 && modeNum < vid_nummodes)
if (modeNum >= 0 && modeNum < MAXWINMODES)
{
vid.width = windowedModes[modeNum].w;
vid.height = windowedModes[modeNum].h;
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.modenum = modeNum;
}
else
@@ -1810,6 +1646,7 @@ INT32 VID_SetMode(INT32 modeNum)
return SDL_TRUE;
}
static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
@@ -1832,9 +1669,6 @@ 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
@@ -1876,9 +1710,6 @@ 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;
}
@@ -2116,6 +1947,8 @@ void I_StartupGraphics(void)
usesdl2soft = M_CheckParm("-softblit");
borderlesswindow = M_CheckParm("-borderless");
VID_Command_ModeList_f();
#ifdef HWRENDER
if (rendermode == render_opengl)
{
@@ -2139,9 +1972,6 @@ 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