Merge remote-tracking branch 'jimita/renderswitch' into renderswitch

This commit is contained in:
Jaime Passos 2019-09-10 18:12:01 -03:00
commit 8057eeaaca
27 changed files with 520 additions and 201 deletions

View File

@ -19,6 +19,7 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}

View File

@ -20,6 +20,7 @@
#include "g_input.h"
#include "hu_stuff.h"
#include "keys.h"
#include "r_main.h"
#include "r_defs.h"
#include "sounds.h"
#include "st_stuff.h"
@ -1285,7 +1286,7 @@ void CONS_Printf(const char *fmt, ...)
con_scrollup = 0;
// if not in display loop, force screen update
if (con_startup)
if (con_startup && (!setrenderneeded))
{
#ifdef _WINDOWS
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
@ -1609,7 +1610,11 @@ void CON_Drawer(void)
}
if (con_recalc)
{
CON_RecalcSize();
if (con_curlines <= 0)
CON_ClearHUD();
}
if (con_curlines > 0)
CON_DrawConsole();

View File

@ -108,6 +108,8 @@ boolean devparm = false; // started game with -devparm
boolean singletics = false; // timedemo
boolean lastdraw = false;
static void D_CheckRendererState(void);
postimg_t postimgtype = postimg_none;
INT32 postimgparam;
postimg_t postimgtype2 = postimg_none;
@ -211,7 +213,7 @@ INT16 wipetypepost = -1;
static void D_Display(void)
{
INT32 setrenderstillneeded = setrenderneeded;
INT32 setrenderstillneeded = 0;
boolean forcerefresh = false;
static boolean wipe = false;
INT32 wipedefindex = 0;
@ -222,13 +224,36 @@ static void D_Display(void)
if (nodrawers)
return; // for comparative timing/profiling
// Jimita: Switching renderers works by checking
// if the game has to do it right when the frame
// needs to render. If so, five things will happen:
// 1. Interface functions will be called so
// that switching to OpenGL creates a
// GL context, and switching to Software
// allocates screen buffers.
// 2. Software will set drawer functions,
// and OpenGL will load textures and
// create plane polygons, if necessary.
// 3. Functions related to switching video
// modes (resolution) are called.
// 4. Patch data is freed from memory,
// and recached if necessary.
// 5. The frame is ready to be drawn!
// stop movie if needs to change renderer
if (setrenderneeded && (moviemode != MM_OFF))
M_StopMovie();
// check for change of screen size (video mode)
if ((setmodeneeded || setrenderneeded) && !wipe)
// 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)
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
@ -240,6 +265,9 @@ static void D_Display(void)
forcerefresh = true; // force background redraw
}
// Jimita
D_CheckRendererState();
// draw buffered stuff to screen
// Used only by linux GGI version
I_UpdateNoBlit();
@ -526,13 +554,26 @@ static void D_Display(void)
I_FinishUpdate(); // page flip or blit buffer
}
if (needpatchrecache)
R_ReloadHUDGraphics();
needpatchflush = false;
needpatchrecache = false;
}
// Jimita: Check the renderer's state
// after a possible renderer switch.
void D_CheckRendererState(void)
{
// flush all patches from memory
// (also frees memory tagged with PU_CACHE)
// (which are not necessarily patches but I don't care)
if (needpatchflush)
Z_FlushCachedPatches();
// some patches have been freed,
// so cache them again
if (needpatchrecache)
R_ReloadHUDGraphics();
}
// =========================================================================
// D_SRB2Loop
// =========================================================================
@ -580,8 +621,7 @@ void D_SRB2Loop(void)
// hack to start on a nice clear console screen.
COM_ImmedExecute("cls;version");
if (rendermode == render_soft)
V_DrawScaledPatch(0, 0, 0, (patch_t *)W_CacheLumpNum(W_GetNumForName("CONSBACK"), PU_CACHE));
V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE));
I_FinishUpdate(); // page flip or blit buffer
for (;;)
@ -1225,6 +1265,16 @@ void D_SRB2Main(void)
// set user default mode or mode set at cmdline
SCR_CheckDefaultMode();
// Jimita: Does the render mode need to change?
if ((setrenderneeded != 0) && (setrenderneeded != rendermode))
{
needpatchflush = true;
needpatchrecache = true;
VID_CheckRenderer();
SCR_ChangeRendererCVars(setrenderneeded);
}
D_CheckRendererState();
wipegamestate = gamestate;
savedata.lives = 0; // flag this as not-used

View File

@ -335,3 +335,8 @@ void I_StartupGraphics(void)
graphics_started = true;
}
void I_StartupHardwareGraphics(void)
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}

View File

@ -616,4 +616,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// Cache patches in Lua in a way that renderer switching will work flawlessly.
//#define LUA_PATCH_SAFETY
#endif // __DOOMDEF__

View File

@ -11,6 +11,7 @@ boolean allow_fullscreen = false;
consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_StartupGraphics(void){}
void I_StartupHardwareGraphics(void){}
void I_ShutdownGraphics(void){}

View File

@ -1528,29 +1528,8 @@ void F_GameEvaluationTicker(void)
#define INFLECTIONPOINT (6*TICRATE)
#define SPARKLLOOPTIME 15 // must be odd
void F_StartEnding(void)
static void F_CacheEnding(void)
{
G_SetGamestate(GS_ENDING);
wipetypepost = INT16_MAX;
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save before the credits sequence.
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
S_StopMusic(); // todo: placeholder
S_StopSounds();
finalecount = -10; // what? this totally isn't a hack. why are you asking?
memset(sparkloffs, 0, sizeof(INT32)*3*2);
sparklloop = 0;
endbrdr[1] = W_CachePatchName("ENDBRDR1", PU_PATCH);
endegrk[0] = W_CachePatchName("ENDEGRK0", PU_PATCH);
@ -1615,6 +1594,43 @@ void F_StartEnding(void)
}
}
static void F_CacheGoodEnding(void)
{
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_PATCH);
endegrk[1] = W_CachePatchName("ENDEGRK3", PU_PATCH);
endglow[0] = W_CachePatchName("ENDGLOW2", PU_PATCH);
endglow[1] = W_CachePatchName("ENDGLOW3", PU_PATCH);
endxpld[0] = W_CachePatchName("ENDEGRK4", PU_PATCH);
}
void F_StartEnding(void)
{
G_SetGamestate(GS_ENDING);
wipetypepost = INT16_MAX;
// Just in case they're open ... somehow
M_ClearMenus(true);
// Save before the credits sequence.
if ((!modifiedgame || savemoddata) && !(netgame || multiplayer) && cursaveslot > 0)
G_SaveGame((UINT32)cursaveslot);
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
S_StopMusic(); // todo: placeholder
S_StopSounds();
finalecount = -10; // what? this totally isn't a hack. why are you asking?
memset(sparkloffs, 0, sizeof(INT32)*3*2);
sparklloop = 0;
F_CacheEnding();
}
void F_EndingTicker(void)
{
if (++finalecount > INFLECTIONPOINT*2)
@ -1625,15 +1641,7 @@ void F_EndingTicker(void)
}
if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets
{
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_PATCH);
endegrk[1] = W_CachePatchName("ENDEGRK3", PU_PATCH);
endglow[0] = W_CachePatchName("ENDGLOW2", PU_PATCH);
endglow[1] = W_CachePatchName("ENDGLOW3", PU_PATCH);
endxpld[0] = W_CachePatchName("ENDEGRK4", PU_PATCH);
}
F_CacheGoodEnding();
if (++sparklloop == SPARKLLOOPTIME) // time to roll the randomisation again
{
@ -1652,6 +1660,13 @@ void F_EndingDrawer(void)
INT32 x, y, i, j, parallaxticker;
patch_t *rockpat;
if (needpatchrecache)
{
F_CacheEnding();
if (goodending && finalecount >= INFLECTIONPOINT) // time to swap some assets
F_CacheGoodEnding();
}
if (!goodending || finalecount < INFLECTIONPOINT)
rockpat = W_CachePatchName("ROID0000", PU_PATCH);
else

View File

@ -836,8 +836,10 @@ static INT32 SolveTProblem(void)
return 0;
CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n");
#ifdef HWR_LOADING_SCREEN
CON_Drawer(); //let the user know what we are doing
I_FinishUpdate(); // page flip or blit buffer
#endif
numsplitpoly = 0;
@ -964,9 +966,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n");
#ifdef HWR_LOADING_SCREEN
ls_count = ls_percent = 0; // reset the loading status
#endif
CON_Drawer(); //let the user know what we are doing
I_FinishUpdate(); // page flip or blit buffer
#endif
HWR_ClearPolys();

View File

@ -776,9 +776,18 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch)
}
}
void HWR_FreeTextureCache(void)
void HWR_FreeColormaps(void)
{
INT32 i;
// Alam: free the Z_Blocks before freeing it's users
// free all skin after each level: must be done after pfnClearMipMapCache!
for (i = 0; i < numwadfiles; i++)
M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap);
}
void HWR_FreeTextureCache(void)
{
// free references to the textures
HWD.pfnClearMipMapCache();
@ -787,15 +796,6 @@ void HWR_FreeTextureCache(void)
Z_FreeTag(PU_HWRCACHE);
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
// Alam: free the Z_Blocks before freeing it's users
// free all skin after each level: must be done after pfnClearMipMapCache!
// temp fix, idk why this crashes
// is it because the colormaps were already freed anyway?
if (!needpatchrecache)
for (i = 0; i < numwadfiles; i++)
M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap);
// now the heap don't have any 'user' pointing to our
// texturecache info, we can free it
if (gr_textures)
@ -849,6 +849,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex)
if ((unsigned)tex >= gr_numtextures)
I_Error("HWR_GetTexture: tex >= numtextures\n");
#endif
// Jimita
if (needpatchrecache && (!gr_textures))
HWR_PrepLevelCache(gr_numtextures);

View File

@ -98,6 +98,7 @@ void HWR_FreePolyPool(void);
// --------
void HWR_InitTextureCache(void);
void HWR_FreeTextureCache(void);
void HWR_FreeColormaps(void);
void HWR_FreeExtraSubsectors(void);
void HWR_GetFlat(lumpnum_t flatlumpnum);

View File

@ -6442,13 +6442,18 @@ static void Command_GrStats_f(void)
//added by Hurdler: console varibale that are saved
void HWR_AddCommands(void)
{
CV_RegisterVar(&cv_grrounddown);
CV_RegisterVar(&cv_grfov);
CV_RegisterVar(&cv_grfogdensity);
CV_RegisterVar(&cv_grfiltermode);
CV_RegisterVar(&cv_granisotropicmode);
CV_RegisterVar(&cv_grcorrecttricks);
CV_RegisterVar(&cv_grsolvetjoin);
static boolean alreadycalled = false;
if (!alreadycalled)
{
CV_RegisterVar(&cv_grrounddown);
CV_RegisterVar(&cv_grfov);
CV_RegisterVar(&cv_grfogdensity);
CV_RegisterVar(&cv_grfiltermode);
CV_RegisterVar(&cv_granisotropicmode);
CV_RegisterVar(&cv_grcorrecttricks);
CV_RegisterVar(&cv_grsolvetjoin);
}
alreadycalled = true;
}
static inline void HWR_AddEngineCommands(void)
@ -6515,6 +6520,7 @@ void HWR_Shutdown(void)
HWR_FreeExtraSubsectors();
HWR_FreePolyPool();
HWR_FreeTextureCache();
HWR_FreeColormaps();
HWD.pfnFlushScreenTextures();
}

View File

@ -887,7 +887,7 @@ void HWR_InitMD2(void)
}
}
// no sprite/player skin name found?!?
CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name);
//CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name);
md2found:
// move on to next line...
continue;

View File

@ -44,6 +44,7 @@ extern boolean highcolor;
/** \brief setup video mode
*/
void I_StartupGraphics(void);
void I_StartupHardwareGraphics(void);
/** \brief restore old video mode
*/

View File

@ -36,6 +36,11 @@ static UINT8 hud_enabled[(hud_MAX/8)+1];
static UINT8 hudAvailable; // hud hooks field
#ifdef LUA_PATCH_SAFETY
static patchinfo_t *patchinfo, *patchinfohead;
static int numluapatches;
#endif
// must match enum hud in lua_hud.h
static const char *const hud_disable_options[] = {
"stagetitle",
@ -248,12 +253,17 @@ static int colormap_get(lua_State *L)
static int patch_get(lua_State *L)
{
#ifdef LUA_PATCH_SAFETY
patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH));
#else
patchinfo_t *patch = *((patchinfo_t **)luaL_checkudata(L, 1, META_PATCH));
#endif
enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);
// patches are CURRENTLY always valid, expected to be cached with PU_STATIC
// this may change in the future, so patch.valid still exists
I_Assert(patch != NULL);
if (!patch)
return LUA_ErrInvalid(L, "patch_t");
switch (field)
{
@ -350,8 +360,59 @@ static int libd_patchExists(lua_State *L)
static int libd_cachePatch(lua_State *L)
{
#ifdef LUA_PATCH_SAFETY
int i;
lumpnum_t lumpnum;
patchinfo_t *luapat;
patch_t *realpatch;
HUDONLY
LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_STATIC), META_PATCH);
luapat = patchinfohead;
lumpnum = W_CheckNumForName(luaL_checkstring(L, 1));
if (lumpnum == LUMPERROR)
lumpnum = W_GetNumForName("MISSING");
for (i = 0; i < numluapatches; i++)
{
// check if already cached
if (luapat->wadnum == WADFILENUM(lumpnum) && luapat->lumpnum == LUMPNUM(lumpnum))
{
LUA_PushUserdata(L, luapat, META_PATCH);
return 1;
}
luapat = luapat->next;
if (!luapat)
break;
}
if (numluapatches > 0)
{
patchinfo->next = Z_Malloc(sizeof(patchinfo_t), PU_STATIC, NULL);
patchinfo = patchinfo->next;
}
else
{
patchinfo = Z_Malloc(sizeof(patchinfo_t), PU_STATIC, NULL);
patchinfohead = patchinfo;
}
realpatch = W_CachePatchNum(lumpnum, PU_PATCH);
patchinfo->width = realpatch->width;
patchinfo->height = realpatch->height;
patchinfo->leftoffset = realpatch->leftoffset;
patchinfo->topoffset = realpatch->topoffset;
patchinfo->wadnum = WADFILENUM(lumpnum);
patchinfo->lumpnum = LUMPNUM(lumpnum);
LUA_PushUserdata(L, patchinfo, META_PATCH);
numluapatches++;
#else
HUDONLY
LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
#endif
return 1;
}
@ -511,12 +572,22 @@ static int libd_draw(lua_State *L)
{
INT32 x, y, flags;
patch_t *patch;
#ifdef LUA_PATCH_SAFETY
patchinfo_t *luapat;
#endif
const UINT8 *colormap = NULL;
HUDONLY
x = luaL_checkinteger(L, 1);
y = luaL_checkinteger(L, 2);
#ifdef LUA_PATCH_SAFETY
luapat = *((patchinfo_t **)luaL_checkudata(L, 3, META_PATCH));
patch = W_CachePatchNum((luapat->wadnum<<16)+luapat->lumpnum, PU_PATCH);
#else
patch = *((patch_t **)luaL_checkudata(L, 3, META_PATCH));
if (!patch)
return LUA_ErrInvalid(L, "patch_t");
#endif
flags = luaL_optinteger(L, 4, 0);
if (!lua_isnoneornil(L, 5))
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
@ -532,6 +603,9 @@ static int libd_drawScaled(lua_State *L)
fixed_t x, y, scale;
INT32 flags;
patch_t *patch;
#ifdef LUA_PATCH_SAFETY
patchinfo_t *luapat;
#endif
const UINT8 *colormap = NULL;
HUDONLY
@ -540,7 +614,14 @@ static int libd_drawScaled(lua_State *L)
scale = luaL_checkinteger(L, 3);
if (scale < 0)
return luaL_error(L, "negative scale");
#ifdef LUA_PATCH_SAFETY
luapat = *((patchinfo_t **)luaL_checkudata(L, 4, META_PATCH));
patch = W_CachePatchNum((luapat->wadnum<<16)+luapat->lumpnum, PU_PATCH);
#else
patch = *((patch_t **)luaL_checkudata(L, 4, META_PATCH));
if (!patch)
return LUA_ErrInvalid(L, "patch_t");
#endif
flags = luaL_optinteger(L, 5, 0);
if (!lua_isnoneornil(L, 6))
colormap = *((UINT8 **)luaL_checkudata(L, 6, META_COLORMAP));
@ -930,6 +1011,10 @@ int LUA_HudLib(lua_State *L)
{
memset(hud_enabled, 0xff, (hud_MAX/8)+1);
#ifdef LUA_PATCH_SAFETY
numluapatches = 0;
#endif
lua_newtable(L); // HUD registry table
lua_newtable(L);
luaL_register(L, NULL, lib_draw);

View File

@ -289,6 +289,7 @@ static void M_ChangeControl(INT32 choice);
// Video & Sound
menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef;
#ifdef HWRENDER
static void M_OpenGLOptionsMenu(void);
menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef;
#endif
menu_t OP_SoundOptionsDef;
@ -1202,7 +1203,7 @@ static menuitem_t OP_VideoOptionsMenu[] =
#ifdef HWRENDER
{IT_HEADER, NULL, "Renderer", NULL, 200},
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 206},
{IT_CALL|IT_STRING, NULL, "OpenGL Options...", M_OpenGLOptionsMenu, 206},
#endif
};
@ -1950,6 +1951,14 @@ menu_t OP_MonitorToggleDef =
};
#ifdef HWRENDER
static void M_OpenGLOptionsMenu(void)
{
if (rendermode == render_opengl)
M_SetupNextMenu(&OP_OpenGLOptionsDef);
else
M_StartMessage(M_GetText("You must be in OpenGL mode\nto access this menu.\n\n(Press a key)\n"), NULL, MM_NOTHING);
}
menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE(
MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12),
"M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
@ -3523,9 +3532,7 @@ void M_Init(void)
#ifdef HWRENDER
// Permanently hide some options based on render mode
if (rendermode == render_soft)
OP_VideoOptionsMenu[4].status = IT_DISABLED;
else if (rendermode == render_opengl)
if (rendermode == render_opengl)
OP_ScreenshotOptionsMenu[op_screenshot_colorprofile].status = IT_GRAYEDOUT;
#endif
@ -5647,6 +5654,7 @@ static void M_DrawAddons(void)
return;
}
// Jimita: Load addons menu patches.
if (needpatchrecache)
M_LoadAddonsPatches();

View File

@ -2955,6 +2955,12 @@ boolean P_SetupLevel(boolean skipprecip)
P_SpawnPrecipitation();
#ifdef HWRENDER // not win32 only 19990829 by Kin
// Jimita: 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
if (rendermode == render_opengl)
HWR_SetupLevel();
#endif
@ -3219,7 +3225,9 @@ void HWR_SetupLevel(void)
#endif
// Correct missing sidedefs & deep water trick
HWR_CorrectSWTricks();
HWR_CreatePlanePolygons((INT32)numnodes - 1);
// Jimita: Don't call this more than once!
if (!extrasubsectors)
HWR_CreatePlanePolygons((INT32)numnodes - 1);
}
#endif

View File

@ -95,8 +95,6 @@ size_t numspritelumps, max_spritelumps;
// textures
INT32 numtextures = 0; // total number of textures found,
boolean needpatchflush = false;
boolean needpatchrecache = false;
// size of following tables
texture_t **textures = NULL;
@ -1674,7 +1672,6 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap)
/////////////////////
// This code creates the colormap array used by software renderer
/////////////////////
//if (rendermode == render_soft)
{
double r, g, b, cbrightness;
int p;

View File

@ -149,7 +149,5 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap);
#define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a))
extern INT32 numtextures;
extern boolean needpatchflush;
extern boolean needpatchrecache;
#endif

View File

@ -723,6 +723,7 @@ typedef struct
#pragma pack()
#endif
typedef enum
{
SRF_SINGLE = 0, // 0-angle for all rotations
@ -733,6 +734,24 @@ typedef enum
SRF_NONE = 0xff // Initial value
} spriterotateflags_t; // SRF's up!
// Same as a patch_t, except just the header
// and the wadnum/lumpnum combination that points
// to wherever the patch is in memory.
struct patchinfo_s
{
INT16 width; // bounding box size
INT16 height;
INT16 leftoffset; // pixels to the left of origin
INT16 topoffset; // pixels below the origin
UINT16 wadnum; // the software patch lump num for when the patch
UINT16 lumpnum; // was flushed, and we need to re-create it
// next patchinfo_t in memory
struct patchinfo_s *next;
};
typedef struct patchinfo_s patchinfo_t;
//
// Sprites are patches with a special naming convention so they can be
// recognized by R_InitSprites.

View File

@ -1150,9 +1150,11 @@ void R_RenderPlayerView(player_t *player)
free(masks);
}
// Jimita
#ifdef HWRENDER
void R_InitHardwareMode(void)
{
HWR_AddCommands();
if (gamestate == GS_LEVEL)
{
HWR_SetupLevel();
@ -1163,7 +1165,7 @@ void R_InitHardwareMode(void)
void R_ReloadHUDGraphics(void)
{
W_FlushCachedPatches();
CONS_Debug(DBG_RENDER, "R_ReloadHUDGraphics()...\n");
ST_LoadGraphics();
HU_LoadGraphics();
ST_ReloadSkinFaceGraphics();
@ -1239,7 +1241,7 @@ void R_RegisterEngineStuff(void)
#endif
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
if (rendermode == render_opengl)
HWR_AddCommands();
#endif
}

View File

@ -60,7 +60,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t
// ------------------
viddef_t vid;
INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1)
INT32 setrenderneeded = 0;
UINT8 setrenderneeded = 0;
static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}};
@ -70,11 +70,11 @@ 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_ChangeRenderer (void);
static void SCR_ActuallyChangeRenderer(void);
static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}};
consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL};
static void SCR_ChangeFullscreen (void);
static void SCR_ChangeFullscreen(void);
consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL};
@ -170,6 +170,7 @@ void SCR_SetMode(void)
if (!(setmodeneeded || setrenderneeded) || WipeInAction)
return; // should never happen and don't change it during a wipe, BAD!
// Jimita
if (setrenderneeded)
{
needpatchflush = true;
@ -374,6 +375,8 @@ void SCR_CheckDefaultMode(void)
// see note above
setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1;
}
SCR_ActuallyChangeRenderer();
}
// sets the modenum as the new default video mode to be saved in the config file
@ -403,27 +406,47 @@ void SCR_ChangeFullscreen(void)
#endif
}
static int target_renderer = 0;
void SCR_ActuallyChangeRenderer(void)
{
setrenderneeded = target_renderer;
// setting the same renderer twice WILL crash your game, so let's not, please
if (rendermode == setrenderneeded)
setrenderneeded = 0;
}
// Jimita
void SCR_ChangeRenderer(void)
{
setrenderneeded = 0;
if (con_startup)
{
if (rendermode == render_soft)
CV_StealthSetValue(&cv_renderer, 1);
else if (rendermode == render_opengl)
CV_StealthSetValue(&cv_renderer, 2);
target_renderer = cv_renderer.value;
if (M_CheckParm("-opengl"))
target_renderer = rendermode = render_opengl;
else if (M_CheckParm("-software"))
target_renderer = rendermode = render_soft;
// set cv_renderer back
SCR_ChangeRendererCVars(rendermode);
return;
}
if (cv_renderer.value == 1)
setrenderneeded = render_soft;
target_renderer = render_soft;
else if (cv_renderer.value == 2)
setrenderneeded = render_opengl;
target_renderer = render_opengl;
SCR_ActuallyChangeRenderer();
}
// setting the same renderer twice WILL crash your game, so let's not, please
if (rendermode == setrenderneeded)
setrenderneeded = 0;
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);
}
boolean SCR_IsAspectCorrect(INT32 width, INT32 height)

View File

@ -144,7 +144,10 @@ extern boolean R_SSE2;
// ----------------
extern viddef_t vid;
extern INT32 setmodeneeded; // mode number to set if needed, or 0
extern INT32 setrenderneeded;
void SCR_ChangeRenderer(void);
void SCR_ChangeRendererCVars(INT32 mode);
extern UINT8 setrenderneeded;
extern INT32 scr_bpp;
extern UINT8 *scr_borderpatch; // patch used to fill the view borders

View File

@ -170,7 +170,6 @@ static void Impl_VideoSetupBuffer(void);
static SDL_bool Impl_CreateWindow(SDL_bool fullscreen);
//static void Impl_SetWindowName(const char *title);
static void Impl_SetWindowIcon(void);
static void I_StartupGraphicsGL(void);
static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
{
@ -1263,12 +1262,7 @@ void VID_PrepareModeList(void)
#endif
}
// SOMETIME IN
// THE FUTURE
// WHEN I ACTUALLY RENDER
// THIS FRAME
static int renderflags;
static SDL_bool Impl_CreateContext(int flags)
static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
#ifdef HWRENDER
@ -1287,7 +1281,7 @@ static SDL_bool Impl_CreateContext(int flags)
#endif
if (rendermode == render_soft)
{
flags = 0; // Use this to set SDL_RENDERER_* flags now
int flags = 0; // Use this to set SDL_RENDERER_* flags now
if (usesdl2soft)
flags |= SDL_RENDERER_SOFTWARE;
else if (cv_vidwait.value)
@ -1307,17 +1301,13 @@ static SDL_bool Impl_CreateContext(int flags)
void VID_CheckRenderer(void)
{
if (dedicated)
return;
if (setrenderneeded)
{
rendermode = setrenderneeded;
Impl_CreateContext(renderflags);
if (rendermode == render_soft)
{
#ifdef HWRENDER
HWR_FreeTextureCache();
#endif
SCR_SetDrawFuncs();
}
Impl_CreateContext();
}
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
@ -1330,12 +1320,18 @@ void VID_CheckRenderer(void)
bufSurface = NULL;
}
Impl_VideoSetupBuffer();
#ifdef HWRENDER
HWR_FreeTextureCache();
#endif
SCR_SetDrawFuncs();
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
I_StartupGraphicsGL();
I_StartupHardwareGraphics();
R_InitHardwareMode();
}
#endif
}
INT32 VID_SetMode(INT32 modeNum)
@ -1345,29 +1341,15 @@ INT32 VID_SetMode(INT32 modeNum)
vid.recalc = 1;
vid.bpp = 1;
if (modeNum >= 0 && modeNum < MAXWINMODES)
{
vid.width = windowedModes[modeNum][0];
vid.height = windowedModes[modeNum][1];
vid.modenum = modeNum;
}
else
{
// just set the desktop resolution as a fallback
SDL_DisplayMode mode;
SDL_GetWindowDisplayMode(window, &mode);
if (mode.w >= 2048)
{
vid.width = 1920;
vid.height = 1200;
}
else
{
vid.width = mode.w;
vid.height = mode.h;
}
vid.modenum = -1;
}
if (modeNum < 0)
modeNum = 0;
if (modeNum >= MAXWINMODES)
modeNum = MAXWINMODES-1;
vid.width = windowedModes[modeNum][0];
vid.height = windowedModes[modeNum][1];
vid.modenum = modeNum;
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
VID_CheckRenderer();
return SDL_TRUE;
@ -1390,8 +1372,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
flags |= SDL_WINDOW_BORDERLESS;
#ifdef HWRENDER
if (rendermode == render_opengl)
flags |= SDL_WINDOW_OPENGL;
flags |= SDL_WINDOW_OPENGL;
#endif
// Create a window
@ -1404,8 +1385,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
return SDL_FALSE;
}
renderflags = flags;
return Impl_CreateContext(flags);
return Impl_CreateContext();
}
/*
@ -1474,51 +1454,6 @@ static void Impl_VideoSetupBuffer(void)
}
}
static void I_StartupGraphicsGL(void)
{
#ifdef HWRENDER
static boolean glstartup = false;
if (!glstartup)
{
HWD.pfnInit = hwSym("Init",NULL);
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL);
HWD.pfnSetBlend = hwSym("SetBlend",NULL);
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL);
HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
#ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);
HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL);
HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION)
I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n"));
if (!HWD.pfnInit(I_Error)) // let load the OpenGL library
rendermode = render_soft;
else
glstartup = true;
}
#endif
}
void I_StartupGraphics(void)
{
if (dedicated)
@ -1560,9 +1495,11 @@ void I_StartupGraphics(void)
framebuffer = SDL_TRUE;
}
#ifdef HWRENDER
if (M_CheckParm("-opengl"))
rendermode = render_opengl;
else if (M_CheckParm("software"))
#endif
rendermode = render_soft;
usesdl2soft = M_CheckParm("-softblit");
@ -1571,7 +1508,7 @@ void I_StartupGraphics(void)
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2);
VID_Command_ModeList_f();
#ifdef HWRENDER
I_StartupGraphicsGL();
I_StartupHardwareGraphics();
#endif
// Fury: we do window initialization after GL setup to allow
@ -1631,6 +1568,51 @@ void I_StartupGraphics(void)
graphics_started = true;
}
void I_StartupHardwareGraphics(void)
{
#ifdef HWRENDER
static boolean glstartup = false;
if (!glstartup)
{
HWD.pfnInit = hwSym("Init",NULL);
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL);
HWD.pfnSetBlend = hwSym("SetBlend",NULL);
HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL);
HWD.pfnSetTexture = hwSym("SetTexture",NULL);
HWD.pfnReadRect = hwSym("ReadRect",NULL);
HWD.pfnGClipRect = hwSym("GClipRect",NULL);
HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL);
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL);
HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
#ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);
HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);
HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL);
HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION)
I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n"));
if (!HWD.pfnInit(I_Error)) // let load the OpenGL library
rendermode = render_soft;
else
glstartup = true;
}
#endif
}
void I_ShutdownGraphics(void)
{
const rendermode_t oldrendermode = rendermode;

View File

@ -239,6 +239,11 @@ void I_StartupGraphics(void)
if (!dedicated) graphics_started = true;
}
void I_StartupHardwareGraphics(void)
{
// oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y
}
// ------------------
// I_ShutdownGraphics
// Close the screen, restore previous video mode.

View File

@ -144,6 +144,7 @@ static patch_t *interpic = NULL; // custom picture defined in map header
static boolean usetile;
boolean usebuffer = false;
static boolean useinterpic;
static boolean safetorender = true;
static INT32 timer;
static INT32 intertic;
@ -159,6 +160,7 @@ static void Y_CalculateTimeRaceWinners(void);
static void Y_CalculateMatchWinners(void);
static void Y_FollowIntermission(void);
static void Y_UnloadData(void);
static void Y_CleanupData(void);
// Stuff copy+pasted from st_stuff.c
#define ST_DrawNumFromHud(h,n) V_DrawTallNum(hudinfo[h].x, hudinfo[h].y, hudinfo[h].f, n)
@ -220,31 +222,41 @@ void Y_IntermissionDrawer(void)
if (intertype == int_none || rendermode == render_none)
return;
if (!usebuffer)
// Jimita
if (needpatchrecache)
{
Y_CleanupData();
safetorender = false;
}
if (!usebuffer || !safetorender)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
if (useinterpic)
V_DrawScaledPatch(0, 0, 0, interpic);
else if (!usetile)
if (safetorender)
{
if (rendermode == render_soft && usebuffer)
VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
if (useinterpic)
V_DrawScaledPatch(0, 0, 0, interpic);
else if (!usetile)
{
if (rendermode == render_soft && usebuffer)
VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
#ifdef HWRENDER
else if(rendermode != render_soft && usebuffer)
{
HWR_DrawIntermissionBG();
}
else if(rendermode != render_soft && usebuffer)
{
HWR_DrawIntermissionBG();
}
#endif
else
{
if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400)
V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch);
else
V_DrawScaledPatch(0, 0, 0, bgpatch);
{
if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400)
V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch);
else
V_DrawScaledPatch(0, 0, 0, bgpatch);
}
}
else
V_DrawPatchFill(bgtile);
}
else
V_DrawPatchFill(bgtile);
if (intertype == int_coop)
{
@ -293,14 +305,17 @@ void Y_IntermissionDrawer(void)
bonusy = 150;
// Total
V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal);
V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total);
if (safetorender)
{
V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal);
V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total);
}
bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1;
// Draw bonuses
for (i = 3; i >= 0; --i)
{
if (data.coop.bonuses[i].display)
if (data.coop.bonuses[i].display && safetorender)
{
V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]);
V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points);
@ -516,7 +531,8 @@ void Y_IntermissionDrawer(void)
char strtime[10];
// draw the header
V_DrawScaledPatch(112, 2, 0, data.match.result);
if (safetorender)
V_DrawScaledPatch(112, 2, 0, data.match.result);
// draw the level name
V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring);
@ -1126,6 +1142,8 @@ void Y_StartIntermission(void)
I_Error("endtic is dirty");
#endif
safetorender = true;
if (!multiplayer)
{
timer = 0;
@ -1350,7 +1368,7 @@ void Y_StartIntermission(void)
data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH);
data.spec.headx = 70;
data.spec.nowsuper = players[consoleplayer].skin
? NULL : W_CachePatchName("NOWSUPER", PU_STATIC);
? NULL : W_CachePatchName("NOWSUPER", PU_PATCH);
}
else
{
@ -2077,7 +2095,8 @@ static void Y_FollowIntermission(void)
G_AfterIntermission();
}
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL
#define UNLOAD(x) if (x) {Z_ChangeTag(x, PU_CACHE);} x = NULL;
#define CLEANUP(x) x = NULL;
//
// Y_UnloadData
@ -2128,5 +2147,47 @@ static void Y_UnloadData(void)
//are not handled
break;
}
}
static void Y_CleanupData(void)
{
// unload the background patches
CLEANUP(bgpatch);
CLEANUP(widebgpatch);
CLEANUP(bgtile);
CLEANUP(interpic);
switch (intertype)
{
case int_coop:
// unload the coop and single player patches
CLEANUP(data.coop.bonuspatches[3]);
CLEANUP(data.coop.bonuspatches[2]);
CLEANUP(data.coop.bonuspatches[1]);
CLEANUP(data.coop.bonuspatches[0]);
CLEANUP(data.coop.ptotal);
break;
case int_spec:
// unload the special stage patches
//CLEANUP(data.spec.cemerald);
//CLEANUP(data.spec.nowsuper);
CLEANUP(data.spec.bonuspatches[1]);
CLEANUP(data.spec.bonuspatches[0]);
CLEANUP(data.spec.pscore);
CLEANUP(data.spec.pcontinues);
break;
case int_match:
case int_race:
CLEANUP(data.match.result);
break;
case int_ctf:
CLEANUP(data.match.blueflag);
CLEANUP(data.match.redflag);
break;
default:
//without this default,
//int_none, int_tag, int_chaos, and int_classicrace
//are not handled
break;
}
}

View File

@ -490,6 +490,38 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
// Utility functions
// -----------------
// for renderer switching, free a bunch of stuff
boolean needpatchflush = false;
boolean needpatchrecache = false;
// flush all patches from memory
// (also frees memory tagged with PU_CACHE)
// (which are not necessarily patches but I don't care)
void Z_FlushCachedPatches(void)
{
CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n");
Z_FreeTag(PU_CACHE);
Z_FreeTag(PU_PATCH);
Z_FreeTag(PU_HUDGFX);
Z_FreeTag(PU_HWRPATCHINFO);
Z_FreeTag(PU_HWRPATCHCOLMIPMAP);
Z_FreeTag(PU_HWRCACHE);
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED);
}
//
// Z_CheckMemCleanup
//
// TODO: Currently blocks >= PU_PURGELEVEL are freed every
// CLEANUPCOUNT. It might be better to keep track of
// the total size of all purgable memory and free it when the
// size exceeds some value.
//
// This was in Z_Malloc, but was freeing data at
// unsafe times. Now it is only called when it is safe
// to cleanup memory.
// starting value of nextcleanup
#define CLEANUPCOUNT 2000

View File

@ -142,4 +142,9 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag);
char *Z_StrDup(const char *in);
#define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed
// For renderer switching
extern boolean needpatchflush;
extern boolean needpatchrecache;
void Z_FlushCachedPatches(void);
#endif