Refactor renderer switching

This commit is contained in:
Jaime Passos 2020-08-14 22:27:16 -03:00
parent 1751d7afed
commit 78cc4a78d0
24 changed files with 343 additions and 271 deletions

View file

@ -9,6 +9,7 @@
#include "utils/Log.h"
rendermode_t rendermode = render_soft;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
@ -52,8 +53,15 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
boolean VID_CheckRenderer(void)
{
return false;
}
void VID_CheckGLLoaded(rendermode_t oldrender)
{
(void)oldrender;
}
const char *VID_GetModeName(INT32 modenum)
{

View file

@ -45,7 +45,8 @@
#define MAXHUDLINES 20
static boolean con_started = false; // console has been initialised
boolean con_startup = false; // true at game startup, screen need refreshing
boolean con_startup = false; // true at game startup
boolean con_refresh = false; // screen needs refreshing
static boolean con_forcepic = true; // at startup toggle console translucency when first off
boolean con_recalc; // set true when screen size has changed
@ -406,7 +407,8 @@ void CON_Init(void)
if (!dedicated)
{
con_started = true;
con_startup = true; // need explicit screen refresh until we are in Doom loop
con_startup = true;
con_refresh = true; // needs explicit screen refresh until we are in the main game loop
consoletoggle = false;
CV_RegisterVar(&cons_msgtimeout);
CV_RegisterVar(&cons_hudlines);
@ -419,7 +421,8 @@ void CON_Init(void)
else
{
con_started = true;
con_startup = false; // need explicit screen refresh until we are in Doom loop
con_startup = false;
con_refresh = false; // disable explicit screen refresh
consoletoggle = true;
}
}
@ -1293,16 +1296,19 @@ void CONS_Printf(const char *fmt, ...)
con_scrollup = 0;
// if not in display loop, force screen update
if (con_startup && (!setrenderneeded))
if (con_refresh)
{
#ifdef _WINDOWS
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
#if defined(_WINDOWS)
if (con_startup)
{
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawScaledPatch(0, 0, 0, con_backpic);
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawScaledPatch(0, 0, 0, con_backpic);
W_UnlockCachedPatch(con_backpic);
I_LoadingScreen(txt); // Win32/OS2 only
W_UnlockCachedPatch(con_backpic);
I_LoadingScreen(txt); // Win32/OS2 only
}
#else
// here we display the console text
CON_Drawer();
@ -1369,7 +1375,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...)
//
void CONS_Error(const char *msg)
{
#ifdef RPC_NO_WINDOWS_H
#if defined(RPC_NO_WINDOWS_H) && defined(_WINDOWS)
if (!graphics_started)
{
MessageBoxA(vid.WndParent, msg, "SRB2 Warning", MB_OK);

View file

@ -20,8 +20,12 @@ boolean CON_Responder(event_t *ev);
// set true when screen size has changed, to adapt console
extern boolean con_recalc;
// console being displayed at game startup
extern boolean con_startup;
// needs explicit screen refresh until we are in the main game loop
extern boolean con_refresh;
// top clip value for view render: do not draw part of view hidden by console
extern INT32 con_clipviewtop;

View file

@ -220,7 +220,6 @@ INT16 wipetypepost = -1;
static void D_Display(void)
{
INT32 setrenderstillneeded = 0;
boolean forcerefresh = false;
static boolean wipe = false;
INT32 wipedefindex = 0;
@ -245,36 +244,21 @@ static void D_Display(void)
// modes (resolution) are called.
// 4. The frame is ready to be drawn!
// stop movie if needs to change renderer
if (setrenderneeded && (moviemode == MM_APNG))
M_StopMovie();
// check for change of renderer or screen size (video mode)
// Check for change of renderer or screen size (video mode)
if ((setrenderneeded || setmodeneeded) && !wipe)
{
if (setrenderneeded)
{
CONS_Debug(DBG_RENDER, "setrenderneeded set (%d)\n", setrenderneeded);
setrenderstillneeded = setrenderneeded;
}
SCR_SetMode(); // change video mode
}
if (vid.recalc || setrenderstillneeded)
{
// Recalc the screen
if (vid.recalc)
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
#ifdef HWRENDER
// Shoot! The screen texture was flushed!
if ((rendermode == render_opengl) && (gamestate == GS_INTERMISSION))
usebuffer = false;
#endif
}
// View morph
if (rendermode == render_soft && !splitscreen)
R_CheckViewMorph();
// change the view size if needed
if (setsizeneeded || setrenderstillneeded)
// Change the view size if needed
// Set by changing video mode or renderer
if (setsizeneeded)
{
R_ExecuteSetViewSize();
forcerefresh = true; // force background redraw
@ -697,6 +681,7 @@ void D_SRB2Loop(void)
oldentertics = I_GetTime();
// end of loading screen: CONS_Printf() will no more call FinishUpdate()
con_refresh = false;
con_startup = false;
// make sure to do a d_display to init mode _before_ load a level
@ -1402,14 +1387,20 @@ void D_SRB2Main(void)
// set user default mode or mode set at cmdline
SCR_CheckDefaultMode();
// Lactozilla: Does the render mode need to change?
if ((setrenderneeded != 0) && (setrenderneeded != rendermode))
// Lactozilla: Check if the render mode needs to change.
if (setrenderneeded)
{
CONS_Printf(M_GetText("Switching the renderer...\n"));
// Switch the renderer in the interface
if (VID_CheckRenderer())
con_refresh = true; // Allow explicit screen refresh again
// Set cv_renderer to the new render mode
VID_CheckRenderer();
SCR_ChangeRendererCVars(rendermode);
CV_StealthSetValue(&cv_renderer, rendermode);
#ifdef HWRENDER
CV_StealthSetValue(&cv_newrenderer, rendermode);
#endif
}
wipegamestate = gamestate;

View file

@ -3,6 +3,7 @@
#include "../i_video.h"
rendermode_t rendermode = render_none;
rendermode_t chosenrendermode = render_none;
boolean highcolor = false;
@ -40,8 +41,15 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void) {}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
boolean VID_CheckRenderer(void)
{
return false;
}
void VID_CheckGLLoaded(rendermode_t oldrender)
{
(void)oldrender;
}
const char *VID_GetModeName(INT32 modenum)
{

View file

@ -585,23 +585,27 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
static size_t gl_numtextures = 0; // Texture count
static GLMapTexture_t *gl_textures; // For all textures
static GLMapTexture_t *gl_flats; // For all (texture) flats, as normal flats don't need to be cached
void HWR_InitTextureCache(void)
{
gl_textures = NULL;
gl_flats = NULL;
}
boolean gl_maptexturesloaded = false;
void HWR_FreeTexture(patch_t *patch)
{
if (!patch)
return;
if (patch->hardware)
{
GLPatch_t *grPatch = patch->hardware;
HWR_FreeTextureColormaps(patch);
if (grPatch->mipmap && (rendermode == render_opengl))
HWD.pfnDeleteTexture(grPatch->mipmap);
if (grPatch->mipmap)
{
if (vid.glstate == VID_GL_LIBRARY_LOADED)
HWD.pfnDeleteTexture(grPatch->mipmap);
if (grPatch->mipmap->data)
Z_Free(grPatch->mipmap->data);
Z_Free(grPatch->mipmap);
}
Z_Free(patch->hardware);
}
@ -609,7 +613,7 @@ void HWR_FreeTexture(patch_t *patch)
patch->hardware = NULL;
}
// Called by HWR_FreeTextureCache.
// Called by HWR_FreePatchCache.
void HWR_FreeTextureColormaps(patch_t *patch)
{
GLPatch_t *pat;
@ -653,10 +657,22 @@ void HWR_FreeTextureColormaps(patch_t *patch)
}
}
void HWR_FreeMipmapCache(void)
static void HWR_FreePatchCache(boolean freeall)
{
INT32 i;
for (i = 0; i < numwadfiles; i++)
{
INT32 j = 0;
for (; j < wadfiles[i]->numlumps; j++)
(freeall ? HWR_FreeTexture : HWR_FreeTextureColormaps)(wadfiles[i]->patchcache[j]);
}
}
void HWR_ClearAllTextures(void)
{
HWR_FreeMapTextures();
// free references to the textures
HWD.pfnClearMipMapCache();
@ -666,19 +682,38 @@ void HWR_FreeMipmapCache(void)
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
// Alam: free the Z_Blocks before freeing it's users
// free all patch colormaps after each level: must be done after ClearMipMapCache!
for (i = 0; i < numwadfiles; i++)
{
INT32 j = 0;
for (; j < wadfiles[i]->numlumps; j++)
HWR_FreeTextureColormaps(wadfiles[i]->patchcache[j]);
}
HWR_FreePatchCache(true);
}
void HWR_FreeTextureCache(void)
// free all patch colormaps after each level: must be done after ClearMipMapCache!
void HWR_FreeColormapCache(void)
{
// free references to the textures
HWR_FreeMipmapCache();
HWR_FreePatchCache(false);
}
void HWR_InitMapTextures(void)
{
gl_textures = NULL;
gl_flats = NULL;
gl_maptexturesloaded = false;
}
static void FreeMapTexture(GLMapTexture_t *tex)
{
HWD.pfnDeleteTexture(&tex->mipmap);
if (tex->mipmap.data)
Z_Free(tex->mipmap.data);
}
void HWR_FreeMapTextures(void)
{
size_t i;
for (i = 0; i < gl_numtextures; i++)
{
FreeMapTexture(&gl_textures[i]);
FreeMapTexture(&gl_flats[i]);
}
// now the heap don't have any 'user' pointing to our
// texturecache info, we can free it
@ -689,12 +724,13 @@ void HWR_FreeTextureCache(void)
gl_textures = NULL;
gl_flats = NULL;
gl_numtextures = 0;
gl_maptexturesloaded = false;
}
void HWR_LoadTextures(size_t pnumtextures)
void HWR_LoadMapTextures(size_t pnumtextures)
{
// we must free it since numtextures changed
HWR_FreeTextureCache();
HWR_FreeMapTextures();
// Why not Z_Malloc?
gl_numtextures = pnumtextures;
@ -704,7 +740,9 @@ void HWR_LoadTextures(size_t pnumtextures)
// Doesn't tell you which it _is_, but hopefully
// should never ever happen (right?!)
if ((gl_textures == NULL) || (gl_flats == NULL))
I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!");
I_Error("HWR_LoadMapTextures: ran out of memory for OpenGL textures. Sad!");
gl_maptexturesloaded = true;
}
void HWR_SetPalette(RGBA_t *palette)
@ -814,10 +852,13 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum)
{
GLMipmap_t *grmip;
patch_t *patch;
if (flatlumpnum == LUMPERROR)
return;
grmip = ((GLPatch_t *)HWR_GetCachedGLPatch(flatlumpnum)->hardware)->mipmap;
patch = HWR_GetCachedGLPatch(flatlumpnum);
grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap;
if (!grmip->downloaded && !grmip->data)
HWR_CacheFlat(grmip, flatlumpnum);
@ -933,7 +974,7 @@ void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap)
//BP: WARNING: don't free it manually without clearing the cache of harware renderer
// (it have a liste of mipmap)
// this malloc is cleared in HWR_FreeTextureCache
// this malloc is cleared in HWR_FreeColormapCache
// (...) unfortunately z_malloc fragment alot the memory :(so malloc is better
newMipmap = calloc(1, sizeof (*newMipmap));
if (newMipmap == NULL)
@ -1190,7 +1231,8 @@ static void HWR_CacheFadeMask(GLMipmap_t *grMipmap, lumpnum_t fademasklumpnum)
void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
{
GLMipmap_t *grmip = ((GLPatch_t *)HWR_GetCachedGLPatch(fademasklumpnum)->hardware)->mipmap;
patch_t *patch = HWR_GetCachedGLPatch(fademasklumpnum);
GLMipmap_t *grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap;
if (!grmip->downloaded && !grmip->data)
HWR_CacheFadeMask(grmip, fademasklumpnum);

View file

@ -90,9 +90,11 @@ void HWR_FreeExtraSubsectors(void);
// --------
// hw_cache.c
// --------
void HWR_InitTextureCache(void);
void HWR_FreeTextureCache(void);
void HWR_FreeMipmapCache(void);
void HWR_InitMapTextures(void);
void HWR_LoadMapTextures(size_t pnumtextures);
void HWR_FreeMapTextures(void);
extern boolean gl_maptexturesloaded;
patch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
patch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
@ -108,6 +110,8 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum);
void HWR_FreeTexture(patch_t *patch);
void HWR_FreeTextureColormaps(patch_t *patch);
void HWR_ClearAllTextures(void);
void HWR_FreeColormapCache(void);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
void HWR_SetPalette(RGBA_t *palette);

View file

@ -5930,7 +5930,7 @@ void HWR_Startup(void)
HWR_InitPolyPool();
HWR_AddSessionCommands();
HWR_InitTextureCache();
HWR_InitMapTextures();
HWR_InitModels();
#ifdef ALAM_LIGHTING
HWR_InitLight();
@ -5954,9 +5954,20 @@ void HWR_Startup(void)
// --------------------------------------------------------------------------
void HWR_Switch(void)
{
// Add session commands
HWR_AddSessionCommands();
// Set special states from CVARs
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
// Load textures
if (!gl_maptexturesloaded)
HWR_LoadMapTextures(numtextures);
// Create plane polygons
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
HWR_LoadLevel();
}
// --------------------------------------------------------------------------
@ -5967,7 +5978,7 @@ void HWR_Shutdown(void)
CONS_Printf("HWR_Shutdown()\n");
HWR_FreeExtraSubsectors();
HWR_FreePolyPool();
HWR_FreeTextureCache();
HWR_FreeMapTextures();
HWD.pfnFlushScreenTextures();
}

View file

@ -41,7 +41,6 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale,
void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_CreatePlanePolygons(INT32 bspnum);
void HWR_CreateStaticLightmaps(INT32 bspnum);
void HWR_LoadTextures(size_t pnumtextures);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 actualcolor); // Lat: separate flags from color since color needs to be an uint to work right.

View file

@ -1094,7 +1094,7 @@ static void HWR_GetBlendedTexture(patch_t *patch, patch_t *blendpatch, INT32 ski
//BP: WARNING: don't free it manually without clearing the cache of harware renderer
// (it have a liste of mipmap)
// this malloc is cleared in HWR_FreeTextureCache
// this malloc is cleared in HWR_FreeColormapCache
// (...) unfortunately z_malloc fragment alot the memory :(so malloc is better
newMipmap = calloc(1, sizeof (*newMipmap));
if (newMipmap == NULL)

View file

@ -36,10 +36,9 @@ typedef enum
*/
extern rendermode_t rendermode;
/** \brief OpenGL state
0 = never loaded, 1 = loaded successfully, -1 = failed loading
/** \brief render mode set by command line arguments
*/
extern INT32 vid_opengl_state;
extern rendermode_t chosenrendermode;
/** \brief use highcolor modes if true
*/
@ -90,8 +89,9 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h);
INT32 VID_SetMode(INT32 modenum);
/** \brief Checks the render state
\return true if the renderer changed
*/
void VID_CheckRenderer(void);
boolean VID_CheckRenderer(void);
/** \brief Load OpenGL mode
*/

View file

@ -2149,15 +2149,22 @@ menu_t OP_PlaystyleDef = {
static void M_VideoOptions(INT32 choice)
{
(void)choice;
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
OP_VideoOptionsMenu[op_video_renderer].text = "Software";
#ifdef HWRENDER
if (vid_opengl_state == -1)
if (vid.glstate != VID_GL_LIBRARY_ERROR)
{
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
OP_VideoOptionsMenu[op_video_renderer].text = "Software";
OP_VideoOptionsMenu[op_video_renderer].status = (IT_STRING | IT_CVAR);
OP_VideoOptionsMenu[op_video_renderer].patch = NULL;
OP_VideoOptionsMenu[op_video_renderer].text = "Renderer";
}
CV_StealthSetValue(&cv_newrenderer, cv_renderer.value);
#endif
M_SetupNextMenu(&OP_VideoOptionsDef);
}

View file

@ -4146,13 +4146,11 @@ boolean P_LoadLevel(boolean fromnetsave)
#ifdef HWRENDER // not win32 only 19990829 by Kin
// Lactozilla: Free extrasubsectors regardless of renderer.
// Maybe we're not in OpenGL anymore.
if (extrasubsectors)
free(extrasubsectors);
extrasubsectors = NULL;
// stuff like HWR_CreatePlanePolygons is called there
HWR_FreeExtraSubsectors();
// Create plane polygons.
if (rendermode == render_opengl)
HWR_SetupLevel();
HWR_LoadLevel();
#endif
// oh god I hope this helps
@ -4238,7 +4236,7 @@ boolean P_LoadLevel(boolean fromnetsave)
}
#ifdef HWRENDER
void HWR_SetupLevel(void)
void HWR_LoadLevel(void)
{
// Lactozilla (December 8, 2019)
// Level setup used to free EVERY mipmap from memory.
@ -4249,7 +4247,7 @@ void HWR_SetupLevel(void)
// when the texture list is loaded.
// Sal: Unfortunately, NOT freeing them causes the dreaded Color Bug.
HWR_FreeMipmapCache();
HWR_FreeColormapCache();
#ifdef ALAM_LIGHTING
// BP: reset light between levels (we draw preview frame lights on current frame)

View file

@ -99,7 +99,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
void P_RespawnThings(void);
boolean P_LoadLevel(boolean fromnetsave);
#ifdef HWRENDER
void HWR_SetupLevel(void);
void HWR_LoadLevel(void);
#endif
boolean P_AddWadFile(const char *wadfilename);
boolean P_RunSOC(const char *socfilename);

View file

@ -33,7 +33,7 @@
#endif
#ifdef HWRENDER
#include "hardware/hw_main.h" // HWR_LoadTextures
#include "hardware/hw_main.h" // HWR_LoadMapTextures
#endif
#if defined(_MSC_VER)
@ -1084,7 +1084,7 @@ void R_LoadTextures(void)
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_LoadTextures(numtextures);
HWR_LoadMapTextures(numtextures);
#endif
}

View file

@ -1560,18 +1560,6 @@ void R_RenderPlayerView(player_t *player)
free(masks);
}
// Lactozilla: Renderer switching
#ifdef HWRENDER
void R_InitHardwareMode(void)
{
HWR_AddSessionCommands();
HWR_Switch();
HWR_LoadTextures(numtextures);
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
HWR_SetupLevel();
}
#endif
// =========================================================================
// ENGINE COMMANDS & VARS
// =========================================================================

View file

@ -112,9 +112,6 @@ extern consvar_t cv_tailspickup;
// Called by startup code.
void R_Init(void);
#ifdef HWRENDER
void R_InitHardwareMode(void);
#endif
void R_CheckViewMorph(void);
void R_ApplyViewMorph(void);

View file

@ -28,6 +28,7 @@
#include "d_main.h"
#include "d_clisrv.h"
#include "f_finale.h"
#include "y_inter.h" // usebuffer
#include "i_sound.h" // closed captions
#include "s_sound.h" // ditto
#include "g_game.h" // ditto
@ -63,7 +64,6 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N
consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void SCR_ActuallyChangeRenderer(void);
CV_PossibleValue_t cv_renderer_t[] = {
{1, "Software"},
#ifdef HWRENDER
@ -71,7 +71,7 @@ CV_PossibleValue_t cv_renderer_t[] = {
#endif
{0, NULL}
};
consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_SetTargetRenderer, 0, NULL, NULL, 0, 0, NULL};
static void SCR_ChangeFullscreen(void);
@ -202,11 +202,15 @@ void SCR_SetMode(void)
// Lactozilla: Renderer switching
if (setrenderneeded)
{
// stop recording movies (APNG only)
if (setrenderneeded && (moviemode == MM_APNG))
M_StopMovie();
VID_CheckRenderer();
if (!setmodeneeded)
VID_SetMode(vid.modenum);
vid.recalc = 1;
}
// Set the video mode in the video interface.
if (setmodeneeded)
VID_SetMode(--setmodeneeded);
@ -276,34 +280,9 @@ void SCR_Startup(void)
vid.modenum = 0;
vid.dupx = vid.width / BASEVIDWIDTH;
vid.dupy = vid.height / BASEVIDHEIGHT;
vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT);
vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
#ifdef HWRENDER
if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
#endif
vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy);
vid.meddupx = (UINT8)(vid.dupx >> 1) + 1;
vid.meddupy = (UINT8)(vid.dupy >> 1) + 1;
#ifdef HWRENDER
vid.fmeddupx = vid.meddupx*FRACUNIT;
vid.fmeddupy = vid.meddupy*FRACUNIT;
#endif
vid.smalldupx = (UINT8)(vid.dupx / 3) + 1;
vid.smalldupy = (UINT8)(vid.dupy / 3) + 1;
#ifdef HWRENDER
vid.fsmalldupx = vid.smalldupx*FRACUNIT;
vid.fsmalldupy = vid.smalldupy*FRACUNIT;
#endif
vid.baseratio = FRACUNIT;
V_Init();
V_Recalc();
CV_RegisterVar(&cv_ticrate);
CV_RegisterVar(&cv_constextsize);
@ -320,38 +299,7 @@ void SCR_Recalc(void)
// bytes per pixel quick access
scr_bpp = vid.bpp;
// scale 1,2,3 times in x and y the patches for the menus and overlays...
// calculated once and for all, used by routines in v_video.c
vid.dupx = vid.width / BASEVIDWIDTH;
vid.dupy = vid.height / BASEVIDHEIGHT;
vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT);
vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
#ifdef HWRENDER
//if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
// 13/11/18:
// The above is no longer necessary, since we want OpenGL to be just like software now
// -- Monster Iestyn
#endif
vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy);
//vid.baseratio = FixedDiv(vid.height << FRACBITS, BASEVIDHEIGHT << FRACBITS);
vid.baseratio = FRACUNIT;
vid.meddupx = (UINT8)(vid.dupx >> 1) + 1;
vid.meddupy = (UINT8)(vid.dupy >> 1) + 1;
#ifdef HWRENDER
vid.fmeddupx = vid.meddupx*FRACUNIT;
vid.fmeddupy = vid.meddupy*FRACUNIT;
#endif
vid.smalldupx = (UINT8)(vid.dupx / 3) + 1;
vid.smalldupy = (UINT8)(vid.dupy / 3) + 1;
#ifdef HWRENDER
vid.fsmalldupx = vid.smalldupx*FRACUNIT;
vid.fsmalldupy = vid.smalldupy*FRACUNIT;
#endif
V_Recalc();
// toggle off (then back on) the automap because some screensize-dependent values will
// be calculated next time the automap is activated.
@ -371,6 +319,12 @@ void SCR_Recalc(void)
// vid.recalc lasts only for the next refresh...
con_recalc = true;
am_recalc = true;
#ifdef HWRENDER
// Shoot! The screen texture was flushed!
if ((rendermode == render_opengl) && (gamestate == GS_INTERMISSION))
usebuffer = false;
#endif
}
// Check for screen cmd-line parms: to force a resolution.
@ -408,7 +362,19 @@ void SCR_CheckDefaultMode(void)
setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1;
}
SCR_ActuallyChangeRenderer();
if (cv_renderer.value != (signed)rendermode)
{
if (chosenrendermode == render_none) // nothing set at command line
SCR_ChangeRenderer();
else
{
// Set cv_renderer to the current render mode
CV_StealthSetValue(&cv_renderer, rendermode);
#ifdef HWRENDER
CV_StealthSetValue(&cv_newrenderer, rendermode);
#endif
}
}
}
// sets the modenum as the new default video mode to be saved in the config file
@ -438,67 +404,33 @@ void SCR_ChangeFullscreen(void)
#endif
}
static int target_renderer = 0;
void SCR_ActuallyChangeRenderer(void)
void SCR_SetTargetRenderer(void)
{
setrenderneeded = target_renderer;
if (!con_refresh)
SCR_ChangeRenderer();
}
void SCR_ChangeRenderer(void)
{
if ((signed)rendermode == cv_renderer.value)
return;
#ifdef HWRENDER
// Well, it didn't even load anyway.
if ((vid_opengl_state == -1) && (setrenderneeded == render_opengl))
// Check if OpenGL loaded successfully (or wasn't disabled) before switching to it.
if ((vid.glstate == VID_GL_LIBRARY_ERROR)
&& (cv_renderer.value == render_opengl))
{
if (M_CheckParm("-nogl"))
CONS_Alert(CONS_ERROR, "OpenGL rendering was disabled!\n");
else
CONS_Alert(CONS_ERROR, "OpenGL never loaded\n");
setrenderneeded = 0;
return;
}
#endif
// setting the same renderer twice WILL crash your game, so let's not, please
if (rendermode == setrenderneeded)
setrenderneeded = 0;
}
// Lactozilla: Renderer switching
void SCR_ChangeRenderer(void)
{
setrenderneeded = 0;
if (con_startup)
{
target_renderer = cv_renderer.value;
#ifdef HWRENDER
if (M_CheckParm("-opengl") && (vid_opengl_state == 1))
target_renderer = rendermode = render_opengl;
else
#endif
if (M_CheckParm("-software"))
target_renderer = rendermode = render_soft;
// set cv_renderer back
SCR_ChangeRendererCVars(rendermode);
return;
}
if (cv_renderer.value == 1)
target_renderer = render_soft;
else if (cv_renderer.value == 2)
target_renderer = render_opengl;
SCR_ActuallyChangeRenderer();
}
void SCR_ChangeRendererCVars(INT32 mode)
{
// set cv_renderer back
if (mode == render_soft)
CV_StealthSetValue(&cv_renderer, 1);
else if (mode == render_opengl)
CV_StealthSetValue(&cv_renderer, 2);
#ifdef HWRENDER
CV_StealthSetValue(&cv_newrenderer, cv_renderer.value);
#endif
// Set the new render mode
setrenderneeded = cv_renderer.value;
con_refresh = false;
}
boolean SCR_IsAspectCorrect(INT32 width, INT32 height)

View file

@ -72,10 +72,16 @@ typedef struct viddef_s
#ifdef HWRENDER
INT32/*fixed_t*/ fsmalldupx, fsmalldupy;
INT32/*fixed_t*/ fmeddupx, fmeddupy;
INT32 glstate;
#endif
} viddef_t;
#define VIDWIDTH vid.width
#define VIDHEIGHT vid.height
enum
{
VID_GL_LIBRARY_NOTLOADED = 0,
VID_GL_LIBRARY_LOADED = 1,
VID_GL_LIBRARY_ERROR = -1,
};
// internal additional info for vesa modes only
typedef struct
@ -171,10 +177,10 @@ extern boolean R_SSE2;
extern viddef_t vid;
extern INT32 setmodeneeded; // mode number to set if needed, or 0
extern UINT8 setrenderneeded;
void SCR_ChangeRenderer(void);
void SCR_ChangeRendererCVars(INT32 mode);
extern UINT8 setrenderneeded;
void SCR_SetTargetRenderer(void);
extern INT32 scr_bpp;
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
@ -188,17 +194,23 @@ extern consvar_t cv_newrenderer;
// wait for page flipping to end or not
extern consvar_t cv_vidwait;
// Initialize the screen
void SCR_Startup(void);
// Change video mode, only at the start of a refresh.
void SCR_SetMode(void);
// Set drawer functions for Software
void SCR_SetDrawFuncs(void);
// Recalc screen size dependent stuff
void SCR_Recalc(void);
// Check parms once at startup
void SCR_CheckDefaultMode(void);
// Set the mode number which is saved in the config
void SCR_SetDefaultMode (void);
void SCR_Startup (void);
// Set the mode number which is saved in the config
void SCR_SetDefaultMode(void);
FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);

View file

@ -95,7 +95,7 @@ static INT32 numVidModes = -1;
static char vidModeName[33][32]; // allow 33 different modes
rendermode_t rendermode = render_soft;
static rendermode_t chosenrendermode = render_soft; // set by command line arguments
rendermode_t chosenrendermode = render_none; // set by command line arguments
boolean highcolor = false;
@ -105,7 +105,6 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff
static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
UINT8 graphics_started = 0; // Is used in console.c and screen.c
INT32 vid_opengl_state = 0;
// To disable fullscreen at startup; is set in VID_PrepareModeList
boolean allow_fullscreen = false;
@ -1443,7 +1442,8 @@ static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
#ifdef HWRENDER
if ((rendermode == render_opengl) && (vid_opengl_state != -1))
if ((rendermode == render_opengl)
&& (vid.glstate != VID_GL_LIBRARY_ERROR))
{
if (!sdlglcontext)
sdlglcontext = SDL_GL_CreateContext(window);
@ -1479,30 +1479,29 @@ static SDL_bool Impl_CreateContext(void)
void VID_CheckGLLoaded(rendermode_t oldrender)
{
#ifdef HWRENDER
if (vid_opengl_state == -1) // Well, it didn't work the first time anyway.
if (vid.glstate == VID_GL_LIBRARY_ERROR) // Well, it didn't work the first time anyway.
{
CONS_Alert(CONS_ERROR, "OpenGL never loaded\n");
rendermode = oldrender;
if (chosenrendermode == render_opengl) // fallback to software
rendermode = render_soft;
if (setrenderneeded)
{
CV_StealthSetValue(&cv_renderer, oldrender);
CV_StealthSetValue(&cv_newrenderer, oldrender);
setrenderneeded = 0;
}
CV_StealthSetValue(&cv_renderer, oldrender);
CV_StealthSetValue(&cv_newrenderer, oldrender);
}
#endif
}
void VID_CheckRenderer(void)
boolean VID_CheckRenderer(void)
{
boolean rendererchanged = false;
boolean contextcreated = false;
#ifdef HWRENDER
rendermode_t oldrenderer = rendermode;
#endif
if (dedicated)
return;
return false;
if (setrenderneeded)
{
@ -1516,11 +1515,12 @@ void VID_CheckRenderer(void)
// Initialise OpenGL before calling SDLSetMode!!!
// This is because SDLSetMode calls OglSdlSurface.
if (vid_opengl_state == 0)
if (vid.glstate == VID_GL_LIBRARY_NOTLOADED)
{
VID_StartupOpenGL();
// Loaded successfully!
if (vid_opengl_state == 1)
if (vid.glstate == VID_GL_LIBRARY_LOADED)
{
// Destroy the current window, if it exists.
if (window)
@ -1543,7 +1543,7 @@ void VID_CheckRenderer(void)
contextcreated = true;
}
}
else if (vid_opengl_state == -1)
else if (vid.glstate == VID_GL_LIBRARY_ERROR)
rendererchanged = false;
}
#endif
@ -1565,27 +1565,22 @@ void VID_CheckRenderer(void)
bufSurface = NULL;
}
if (rendererchanged)
{
#ifdef HWRENDER
if (vid_opengl_state == 1) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
if (rendererchanged && vid.glstate == VID_GL_LIBRARY_LOADED) // Only if OpenGL ever loaded!
HWR_ClearAllTextures();
#endif
SCR_SetDrawFuncs();
}
SCR_SetDrawFuncs();
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
else if (rendermode == render_opengl && rendererchanged)
{
if (rendererchanged)
{
R_InitHardwareMode();
V_SetPalette(0);
}
HWR_Switch();
V_SetPalette(0);
}
#else
(void)oldrenderer;
#endif
return rendererchanged;
}
INT32 VID_SetMode(INT32 modeNum)
@ -1626,7 +1621,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
flags |= SDL_WINDOW_BORDERLESS;
#ifdef HWRENDER
if (vid_opengl_state == 1)
if (vid.glstate == VID_GL_LIBRARY_LOADED)
flags |= SDL_WINDOW_OPENGL;
#endif
@ -1747,12 +1742,44 @@ void I_StartupGraphics(void)
framebuffer = SDL_TRUE;
}
#ifdef HWRENDER
if (M_CheckParm("-opengl"))
chosenrendermode = rendermode = render_opengl;
// Renderer choices
// Takes priority over the config.
if (M_CheckParm("-renderer"))
{
INT32 i = 0;
CV_PossibleValue_t *renderer_list = cv_renderer_t;
const char *modeparm = M_GetNextParm();
while (renderer_list[i].strvalue)
{
if (!stricmp(modeparm, renderer_list[i].strvalue))
{
chosenrendermode = renderer_list[i].value;
break;
}
i++;
}
}
// Choose Software renderer
else if (M_CheckParm("-software"))
chosenrendermode = render_soft;
#ifdef HWRENDER
// Choose OpenGL renderer
else if (M_CheckParm("-opengl"))
chosenrendermode = render_opengl;
// Don't startup OpenGL
if (M_CheckParm("-nogl"))
{
vid.glstate = VID_GL_LIBRARY_ERROR;
if (chosenrendermode == render_opengl)
chosenrendermode = render_none;
}
#endif
chosenrendermode = rendermode = render_soft;
if (chosenrendermode != render_none)
rendermode = chosenrendermode;
usesdl2soft = M_CheckParm("-softblit");
borderlesswindow = M_CheckParm("-borderless");
@ -1761,9 +1788,7 @@ void I_StartupGraphics(void)
VID_Command_ModeList_f();
#ifdef HWRENDER
if (M_CheckParm("-nogl"))
vid_opengl_state = -1; // Don't startup OpenGL
else if (chosenrendermode == render_opengl)
if (rendermode == render_opengl)
VID_StartupOpenGL();
#endif
@ -1865,9 +1890,9 @@ void VID_StartupOpenGL(void)
HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL);
HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL);
vid_opengl_state = HWD.pfnInit() ? 1 : -1; // let load the OpenGL library
vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library
if (vid_opengl_state == -1)
if (vid.glstate == VID_GL_LIBRARY_ERROR)
{
rendermode = render_soft;
setrenderneeded = 0;

View file

@ -3719,3 +3719,36 @@ void V_Init(void)
CONS_Debug(DBG_RENDER, " screens[%d] = %x\n", i, screens[i]);
#endif
}
void V_Recalc(void)
{
// scale 1,2,3 times in x and y the patches for the menus and overlays...
// calculated once and for all, used by routines in v_video.c and v_draw.c
vid.dupx = vid.width / BASEVIDWIDTH;
vid.dupy = vid.height / BASEVIDHEIGHT;
vid.dupx = vid.dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
vid.fdupx = FixedDiv(vid.width*FRACUNIT, BASEVIDWIDTH*FRACUNIT);
vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
#ifdef HWRENDER
//if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
// 13/11/18:
// The above is no longer necessary, since we want OpenGL to be just like software now
// -- Monster Iestyn
#endif
vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy);
vid.meddupx = (UINT8)(vid.dupx >> 1) + 1;
vid.meddupy = (UINT8)(vid.dupy >> 1) + 1;
#ifdef HWRENDER
vid.fmeddupx = vid.meddupx*FRACUNIT;
vid.fmeddupy = vid.meddupy*FRACUNIT;
#endif
vid.smalldupx = (UINT8)(vid.dupx / 3) + 1;
vid.smalldupy = (UINT8)(vid.dupy / 3) + 1;
#ifdef HWRENDER
vid.fsmalldupx = vid.smalldupx*FRACUNIT;
vid.fsmalldupy = vid.smalldupy*FRACUNIT;
#endif
}

View file

@ -37,6 +37,9 @@ cv_allcaps;
// Allocates buffer screens, call before R_Init.
void V_Init(void);
// Recalculates the viddef (dupx, dupy, etc.) according to the current screen resolution.
void V_Recalc(void);
// Color look-up table
#define COLORBITS 6
#define SHIFTCOLORBITS (8-COLORBITS)

View file

@ -845,7 +845,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
#ifdef HWRENDER
// Read shaders from file
if (rendermode == render_opengl && (vid_opengl_state == 1))
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
{
HWR_ReadShaders(numwadfiles - 1, (type == RET_PK3));
HWR_LoadShaders();

View file

@ -48,6 +48,7 @@
// this is the CURRENT rendermode!! very important: used by w_wad, and much other code
rendermode_t rendermode = render_soft;
rendermode_t chosenrendermode = render_none; // set by command line arguments
static void OnTop_OnChange(void);
// synchronize page flipping with screen refresh
static CV_PossibleValue_t CV_NeverOnOff[] = {{-1, "Never"}, {0, "Off"}, {1, "On"}, {0, NULL}};
@ -56,7 +57,6 @@ static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff,
static consvar_t cv_ontop = {"ontop", "Never", 0, CV_NeverOnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
boolean highcolor;
int vid_opengl_state = 0;
static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces
static LPBITMAPINFO bmiMain = NULL;
@ -952,7 +952,11 @@ INT32 VID_SetMode(INT32 modenum)
return 1;
}
void VID_CheckRenderer(void) {}
boolean VID_CheckRenderer(void)
{
return false;
}
void VID_CheckGLLoaded(rendermode_t oldrender)
{
(void)oldrender;