Merge remote-tracking branch 'origin/next' into local-lua-commands

This commit is contained in:
James R 2019-12-30 15:08:34 -08:00
commit e3fcd860de
50 changed files with 1695 additions and 685 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){}
@ -51,6 +52,11 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
const char *VID_GetModeName(INT32 modenum)
{
return "A320x240";

View file

@ -61,6 +61,8 @@ static consvar_t *consvar_vars; // list of registered console variables
static char com_token[1024];
static char *COM_Parse(char *data);
static char * COM_Purge (char *text, int *lenp);
CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}};
@ -100,31 +102,61 @@ static cmdalias_t *com_alias; // aliases list
static vsbuf_t com_text; // variable sized buffer
/** Purges control characters out of some text.
*
* \param s The text.
* \param np Optionally a pointer to fill with the new string length.
* \return The text.
* \sa COM_ExecuteString
*/
static char *
COM_Purge (char *s, int *np)
{
char *t;
char *p;
int n;
n = strlen(s);
t = s + n + 1;
p = s;
while (( p = strchr(p, '\033') ))
{
memmove(p, &p[1], t - p - 1);
n--;
}
if (np)
(*np) = n;
return s;
}
/** Adds text into the command buffer for later execution.
*
* \param ptext The text to add.
* \sa COM_BufInsertText
* \sa COM_BufInsertTextEx
*/
void COM_BufAddText(const char *ptext)
void COM_BufAddTextEx(const char *ptext, int flags)
{
size_t l;
int l;
char *text;
l = strlen(ptext);
text = COM_Purge(Z_StrDup(ptext), &l);
if (com_text.cursize + l >= com_text.maxsize)
if (com_text.cursize + 2 + l >= com_text.maxsize)
{
CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n"));
return;
}
VS_Write(&com_text, ptext, l);
VS_WriteEx(&com_text, text, l, flags);
Z_Free(text);
}
/** Adds command text and executes it immediately.
*
* \param ptext The text to execute. A newline is automatically added.
* \sa COM_BufAddText
* \sa COM_BufAddTextEx
*/
void COM_BufInsertText(const char *ptext)
void COM_BufInsertTextEx(const char *ptext, int flags)
{
char *temp = NULL;
size_t templen;
@ -138,7 +170,7 @@ void COM_BufInsertText(const char *ptext)
}
// add the entire text of the file (or alias)
COM_BufAddText(ptext);
COM_BufAddTextEx(ptext, flags);
COM_BufExecute(); // do it right away
// add the copied off data
@ -272,6 +304,7 @@ static size_t com_argc;
static char *com_argv[MAX_ARGS];
static const char *com_null_string = "";
static char *com_args = NULL; // current command args or NULL
static int com_flags;
static void Got_NetVar(UINT8 **p, INT32 playernum);
@ -395,6 +428,14 @@ static void COM_TokenizeString(char *ptext)
com_argc = 0;
com_args = NULL;
if (ptext[0] == '\033')
{
com_flags = (unsigned)ptext[1];
ptext += 2;
}
else
com_flags = 0;
while (com_argc < MAX_ARGS)
{
// Skip whitespace up to a newline.
@ -1016,6 +1057,15 @@ void VS_Write(vsbuf_t *buf, const void *data, size_t length)
M_Memcpy(VS_GetSpace(buf, length), data, length);
}
void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags)
{
char *p;
p = VS_GetSpace(buf, 2 + length);
p[0] = '\033';
p[1] = flags;
M_Memcpy(&p[2], data, length);
}
/** Prints text in a variable buffer. Like VS_Write() plus a
* trailing NUL.
*
@ -2015,6 +2065,9 @@ static boolean CV_Command(void)
if (!v)
return false;
if (( com_flags & COM_SAFE ) && ( v->flags & CV_NOLUA ))
return false;
// perform a variable print or set
if (COM_Argc() == 1)
{

View file

@ -28,6 +28,12 @@ enum
COM_LOCAL = 4,
};
/* Command buffer flags. */
enum
{
COM_SAFE = 1,
};
typedef void (*com_func_t)(void);
void COM_AddCommand(const char *name, com_func_t func);
@ -44,10 +50,12 @@ size_t COM_FirstOption(void);
const char *COM_CompleteCommand(const char *partial, INT32 skips);
// insert at queu (at end of other command)
void COM_BufAddText(const char *btext);
#define COM_BufAddText(s) COM_BufAddTextEx(s, 0)
void COM_BufAddTextEx(const char *btext, int flags);
// insert in head (before other command)
void COM_BufInsertText(const char *btext);
#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0)
void COM_BufInsertTextEx(const char *btext, int flags);
// don't bother inserting, just do immediately
void COM_ImmedExecute(const char *ptext);
@ -79,6 +87,7 @@ void VS_Free(vsbuf_t *buf);
void VS_Clear(vsbuf_t *buf);
void *VS_GetSpace(vsbuf_t *buf, size_t length);
void VS_Write(vsbuf_t *buf, const void *data, size_t length);
void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags);
void VS_Print(vsbuf_t *buf, const char *data); // strcats onto the sizebuf
//==================
@ -108,7 +117,8 @@ typedef enum
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
// can only be set when we have the pointer to it
// used on menus
CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on.
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on.
CV_NOLUA = 4096,/* don't let this be called from Lua */
} cvflags_t;
typedef struct CV_PossibleValue_s

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,10 +1286,10 @@ 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_CACHE);
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawScaledPatch(0, 0, 0, con_backpic);
@ -1545,7 +1546,7 @@ static void CON_DrawConsole(void)
// draw console background
if (cons_backpic.value || con_forcepic)
{
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE);
patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH);
// Jimita: CON_DrawBackpic just called V_DrawScaledPatch
V_DrawScaledPatch(0, 0, 0, con_backpic);
@ -1602,8 +1603,18 @@ void CON_Drawer(void)
if (!con_started || !graphics_started)
return;
if (needpatchrecache)
{
W_FlushCachedPatches();
HU_LoadGraphics();
}
if (con_recalc)
{
CON_RecalcSize();
if (con_curlines <= 0)
CON_ClearHUD();
}
if (con_curlines > 0)
CON_DrawConsole();

View file

@ -1265,8 +1265,12 @@ static boolean CL_SendJoin(void)
if (splitscreen || botingame)
localplayers++;
netbuffer->u.clientcfg.localplayers = localplayers;
netbuffer->u.clientcfg._255 = 255;
netbuffer->u.clientcfg.packetversion = PACKETVERSION;
netbuffer->u.clientcfg.version = VERSION;
netbuffer->u.clientcfg.subversion = SUBVERSION;
strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION,
sizeof netbuffer->u.clientcfg.application);
strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME);
strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME);
return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak));
@ -1277,8 +1281,12 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
UINT8 *p;
netbuffer->packettype = PT_SERVERINFO;
netbuffer->u.serverinfo._255 = 255;
netbuffer->u.serverinfo.packetversion = PACKETVERSION;
netbuffer->u.serverinfo.version = VERSION;
netbuffer->u.serverinfo.subversion = SUBVERSION;
strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION,
sizeof netbuffer->u.serverinfo.application);
// return back the time value so client can compute their ping
netbuffer->u.serverinfo.time = (tic_t)LONG(servertime);
netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime);
@ -1712,12 +1720,21 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node)
if (serverlistcount >= MAXSERVERLIST)
return; // list full
if (info->_255 != 255)
return;/* old packet format */
if (info->packetversion != PACKETVERSION)
return;/* old new packet format */
if (info->version != VERSION)
return; // Not same version.
if (info->subversion != SUBVERSION)
return; // Close, but no cigar.
if (strcmp(info->application, SRB2APPLICATION))
return;/* that's a different mod */
i = serverlistcount++;
}
@ -3509,6 +3526,12 @@ static void HandleConnect(SINT8 node)
if (bannednode && bannednode[node])
SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server"));
else if (netbuffer->u.clientcfg._255 != 255 ||
netbuffer->u.clientcfg.packetversion != PACKETVERSION)
SV_SendRefuse(node, "Incompatible packet formats.");
else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION,
sizeof netbuffer->u.clientcfg.application))
SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible.");
else if (netbuffer->u.clientcfg.version != VERSION
|| netbuffer->u.clientcfg.subversion != SUBVERSION)
SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION));
@ -3631,6 +3654,8 @@ static void HandleServerInfo(SINT8 node)
const tic_t ticdiff = (ticnow - ticthen)*1000/NEWTICRATE;
netbuffer->u.serverinfo.time = (tic_t)LONG(ticdiff);
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0;
netbuffer->u.serverinfo.application
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
SL_InsertServer(&netbuffer->u.serverinfo, node);
}

View file

@ -19,6 +19,16 @@
#include "tables.h"
#include "d_player.h"
/*
The 'packet version' may be used with packets whose
format is expected to change between versions.
This version is independent of the mod name, and standard
version and subversion. It should only account for the
basic fields of the packet, and change infrequently.
*/
#define PACKETVERSION 0
// Network play related stuff.
// There is a data struct that stores network
// communication related stuff, and another
@ -320,8 +330,13 @@ typedef struct {
#pragma warning(default : 4200)
#endif
#define MAXAPPLICATION 16
typedef struct
{
UINT8 _255;/* see serverinfo_pak */
UINT8 packetversion;
char application[MAXAPPLICATION];
UINT8 version; // Different versions don't work
UINT8 subversion; // Contains build version
UINT8 localplayers;
@ -334,6 +349,14 @@ typedef struct
// This packet is too large
typedef struct
{
/*
In the old packet, 'version' is the first field. Now that field is set
to 255 always, so older versions won't be confused with the new
versions or vice-versa.
*/
UINT8 _255;
UINT8 packetversion;
char application[MAXAPPLICATION];
UINT8 version;
UINT8 subversion;
UINT8 numberofplayer;

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;
@ -212,6 +214,7 @@ INT16 wipetypepost = -1;
static void D_Display(void)
{
INT32 setrenderstillneeded = 0;
boolean forcerefresh = false;
static boolean wipe = false;
INT32 wipedefindex = 0;
@ -222,11 +225,38 @@ static void D_Display(void)
if (nodrawers)
return; // for comparative timing/profiling
// check for change of screen size (video mode)
if (setmodeneeded && !wipe)
SCR_SetMode(); // change video mode
// Lactozilla: 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!
if (vid.recalc)
// stop movie if needs to change renderer
if (setrenderneeded && (moviemode == MM_APNG))
M_StopMovie();
// 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()
#ifdef HWRENDER
@ -237,12 +267,15 @@ static void D_Display(void)
}
// change the view size if needed
if (setsizeneeded)
if (setsizeneeded || setrenderstillneeded)
{
R_ExecuteSetViewSize();
forcerefresh = true; // force background redraw
}
// Lactozilla: Renderer switching
D_CheckRendererState();
// draw buffered stuff to screen
// Used only by linux GGI version
I_UpdateNoBlit();
@ -457,7 +490,7 @@ static void D_Display(void)
py = 4;
else
py = viewwindowy + 4;
patch = W_CachePatchName("M_PAUSE", PU_CACHE);
patch = W_CachePatchName("M_PAUSE", PU_PATCH);
V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch);
#else
INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2));
@ -557,6 +590,25 @@ static void D_Display(void)
I_FinishUpdate(); // page flip or blit buffer
}
needpatchflush = false;
needpatchrecache = false;
}
// Lactozilla: 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();
}
// =========================================================================
@ -600,8 +652,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 (;;)
@ -1239,6 +1290,16 @@ 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))
{
needpatchflush = true;
needpatchrecache = true;
VID_CheckRenderer();
SCR_ChangeRendererCVars(setrenderneeded);
}
D_CheckRendererState();
wipegamestate = gamestate;
savedata.lives = 0; // flag this as not-used

View file

@ -848,6 +848,8 @@ void D_RegisterClientCommands(void)
// screen.c
CV_RegisterVar(&cv_fullscreen);
CV_RegisterVar(&cv_renderview);
CV_RegisterVar(&cv_renderer);
CV_RegisterVar(&cv_newrenderer);
CV_RegisterVar(&cv_scr_depth);
CV_RegisterVar(&cv_scr_width);
CV_RegisterVar(&cv_scr_height);

View file

@ -9751,6 +9751,7 @@ struct {
{"CV_HIDEN",CV_HIDEN},
{"CV_HIDDEN",CV_HIDEN},
{"CV_CHEAT",CV_CHEAT},
{"CV_NOLUA",CV_NOLUA},
// v_video flags
{"V_NOSCALEPATCH",V_NOSCALEPATCH},

View file

@ -338,3 +338,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

@ -378,6 +378,11 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette)
return 1;
}
void VID_CheckRenderer(void)
{
// ..............
}
// converts a segm:offs 32bit pair to a 32bit flat ptr

View file

@ -130,6 +130,9 @@ extern FILE *logstream;
extern char logfilename[1024];
#endif
/* A mod name to further distinguish versions. */
#define SRB2APPLICATION "SRB2"
//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
#ifdef DEVELOP
#define VERSION 0 // Game version
@ -624,6 +627,9 @@ 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
/// Sprite rotation
#define ROTSPRITE
#define ROTANGLES 72 // Needs to be a divisor of 360 (45, 60, 90, 120...)

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){}
@ -39,6 +40,11 @@ INT32 VID_SetMode(INT32 modenum)
return 0;
}
void VID_CheckRenderer(void)
{
// ..............
}
const char *VID_GetModeName(INT32 modenum)
{
(void)modenum;

View file

@ -530,78 +530,78 @@ static void F_IntroDrawScene(void)
case 0:
break;
case 1:
background = W_CachePatchName("INTRO1", PU_CACHE);
background = W_CachePatchName("INTRO1", PU_PATCH);
break;
case 2:
background = W_CachePatchName("INTRO2", PU_CACHE);
background = W_CachePatchName("INTRO2", PU_PATCH);
break;
case 3:
background = W_CachePatchName("INTRO3", PU_CACHE);
background = W_CachePatchName("INTRO3", PU_PATCH);
break;
case 4:
background = W_CachePatchName("INTRO4", PU_CACHE);
background = W_CachePatchName("INTRO4", PU_PATCH);
break;
case 5:
if (intro_curtime >= 5*TICRATE)
background = W_CachePatchName("RADAR", PU_CACHE);
background = W_CachePatchName("RADAR", PU_PATCH);
else
background = W_CachePatchName("DRAT", PU_CACHE);
background = W_CachePatchName("DRAT", PU_PATCH);
break;
case 6:
background = W_CachePatchName("INTRO6", PU_CACHE);
background = W_CachePatchName("INTRO6", PU_PATCH);
cx = 180;
cy = 8;
break;
case 7:
{
if (intro_curtime >= 7*TICRATE + ((TICRATE/7)*2))
background = W_CachePatchName("SGRASS5", PU_CACHE);
background = W_CachePatchName("SGRASS5", PU_PATCH);
else if (intro_curtime >= 7*TICRATE + (TICRATE/7))
background = W_CachePatchName("SGRASS4", PU_CACHE);
background = W_CachePatchName("SGRASS4", PU_PATCH);
else if (intro_curtime >= 7*TICRATE)
background = W_CachePatchName("SGRASS3", PU_CACHE);
background = W_CachePatchName("SGRASS3", PU_PATCH);
else if (intro_curtime >= 6*TICRATE)
background = W_CachePatchName("SGRASS2", PU_CACHE);
background = W_CachePatchName("SGRASS2", PU_PATCH);
else
background = W_CachePatchName("SGRASS1", PU_CACHE);
background = W_CachePatchName("SGRASS1", PU_PATCH);
break;
}
case 8:
background = W_CachePatchName("WATCHING", PU_CACHE);
background = W_CachePatchName("WATCHING", PU_PATCH);
break;
case 9:
background = W_CachePatchName("ZOOMING", PU_CACHE);
background = W_CachePatchName("ZOOMING", PU_PATCH);
break;
case 10:
break;
case 11:
background = W_CachePatchName("INTRO5", PU_CACHE);
background = W_CachePatchName("INTRO5", PU_PATCH);
break;
case 12:
background = W_CachePatchName("REVENGE", PU_CACHE);
background = W_CachePatchName("REVENGE", PU_PATCH);
cx = 208;
cy = 8;
break;
case 13:
background = W_CachePatchName("CONFRONT", PU_CACHE);
background = W_CachePatchName("CONFRONT", PU_PATCH);
cy += 48;
break;
case 14:
background = W_CachePatchName("TAILSSAD", PU_CACHE);
background = W_CachePatchName("TAILSSAD", PU_PATCH);
bgxoffs = 144;
cx = 8;
cy = 8;
break;
case 15:
if (intro_curtime >= 7*TICRATE)
background = W_CachePatchName("SONICDO2", PU_CACHE);
background = W_CachePatchName("SONICDO2", PU_PATCH);
else
background = W_CachePatchName("SONICDO1", PU_CACHE);
background = W_CachePatchName("SONICDO1", PU_PATCH);
cx = 224;
cy = 8;
break;
case 16:
background = W_CachePatchName("INTRO7", PU_CACHE);
background = W_CachePatchName("INTRO7", PU_PATCH);
break;
default:
break;
@ -631,30 +631,30 @@ static void F_IntroDrawScene(void)
S_ChangeMusicInternal("_stjr", false);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2;
y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2;
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect);
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
if (finalecount > 6) {
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH2", PU_CACHE)), aspect);
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH2", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
}
if (finalecount > 10) {
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH3", PU_CACHE)), aspect);
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH3", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
}
if (finalecount > 14) {
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH4", PU_CACHE)), aspect);
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH4", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
}
}
else if (finalecount-30 < 20) { // Big eggy
background = W_CachePatchName("FEEDIN", PU_CACHE);
background = W_CachePatchName("FEEDIN", PU_PATCH);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(560<<FRACBITS, aspect)/2;
y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(477<<FRACBITS, aspect);
V_DrawSciencePatch(x, y, V_SNAPTOBOTTOM, background, aspect);
}
else if (finalecount-50 < 30) { // Zoom out
fixed_t scale = FixedDiv(aspect, FixedDiv((finalecount-50)<<FRACBITS, (15<<FRACBITS))+FRACUNIT);
background = W_CachePatchName("FEEDIN", PU_CACHE);
background = W_CachePatchName("FEEDIN", PU_PATCH);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(560<<FRACBITS, aspect)/2 + (FixedMul(560<<FRACBITS, aspect) - FixedMul(560<<FRACBITS, scale));
y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(477<<FRACBITS, scale);
V_DrawSciencePatch(x, y, V_SNAPTOBOTTOM, background, scale);
@ -664,7 +664,7 @@ static void F_IntroDrawScene(void)
{
// Draw tiny eggy
fixed_t scale = FixedMul(FRACUNIT/3, aspect);
background = W_CachePatchName("FEEDIN", PU_CACHE);
background = W_CachePatchName("FEEDIN", PU_PATCH);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(560<<FRACBITS, aspect)/2 + (FixedMul(560<<FRACBITS, aspect) - FixedMul(560<<FRACBITS, scale));
y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(477<<FRACBITS, scale);
V_DrawSciencePatch(x, y, V_SNAPTOBOTTOM, background, scale);
@ -675,34 +675,34 @@ static void F_IntroDrawScene(void)
x = (-189*FRACUNIT) + (FixedMul((6<<FRACBITS)+FRACUNIT/3, ftime<<FRACBITS) - FixedMul((6<<FRACBITS)+FRACUNIT/3, FixedDiv(FixedMul(ftime<<FRACBITS, ftime<<FRACBITS), 120<<FRACBITS)));
y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(417<<FRACBITS, aspect);
// Draw the body
V_DrawSciencePatch(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT1", PU_CACHE)), aspect);
V_DrawSciencePatch(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT1", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
// Draw the door
V_DrawSciencePatch(x+FixedMul(344<<FRACBITS, aspect), y+FixedMul(292<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT2", PU_CACHE)), aspect);
V_DrawSciencePatch(x+FixedMul(344<<FRACBITS, aspect), y+FixedMul(292<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT2", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
// Draw the wheel
V_DrawSciencePatch(x+FixedMul(178<<FRACBITS, aspect), y+FixedMul(344<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName(va("TYRE%02u",(abs(finalecount-144)/3)%16), PU_CACHE)), aspect);
V_DrawSciencePatch(x+FixedMul(178<<FRACBITS, aspect), y+FixedMul(344<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName(va("TYRE%02u",(abs(finalecount-144)/3)%16), PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
// Draw the wheel cover
V_DrawSciencePatch(x+FixedMul(88<<FRACBITS, aspect), y+FixedMul(238<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT3", PU_CACHE)), aspect);
V_DrawSciencePatch(x+FixedMul(88<<FRACBITS, aspect), y+FixedMul(238<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT3", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
} else { // Pure Fat has stopped!
y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(417<<FRACBITS, aspect);
// Draw the body
V_DrawSciencePatch(0, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT1", PU_CACHE)), aspect);
V_DrawSciencePatch(0, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT1", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
// Draw the wheel
V_DrawSciencePatch(FixedMul(178<<FRACBITS, aspect), y+FixedMul(344<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("TYRE00", PU_CACHE)), aspect);
V_DrawSciencePatch(FixedMul(178<<FRACBITS, aspect), y+FixedMul(344<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("TYRE00", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
// Draw the wheel cover
V_DrawSciencePatch(FixedMul(88<<FRACBITS, aspect), y+FixedMul(238<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT3", PU_CACHE)), aspect);
V_DrawSciencePatch(FixedMul(88<<FRACBITS, aspect), y+FixedMul(238<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT3", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
// Draw the door
if (finalecount-TICRATE/2 > 4*TICRATE) { // Door is being raised!
int ftime = (finalecount-TICRATE/2-4*TICRATE);
y -= FixedDiv((ftime*ftime)<<FRACBITS, 23<<FRACBITS);
}
V_DrawSciencePatch(FixedMul(344<<FRACBITS, aspect), y+FixedMul(292<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT2", PU_CACHE)), aspect);
V_DrawSciencePatch(FixedMul(344<<FRACBITS, aspect), y+FixedMul(292<<FRACBITS, aspect), V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT2", PU_PATCH)), aspect);
W_UnlockCachedPatch(patch);
}
}
@ -716,27 +716,27 @@ static void F_IntroDrawScene(void)
if (timetonext > 5*TICRATE && timetonext < 6*TICRATE)
{
if (!(finalecount & 3))
background = W_CachePatchName("BRITEGG1", PU_CACHE);
background = W_CachePatchName("BRITEGG1", PU_PATCH);
else
background = W_CachePatchName("DARKEGG1", PU_CACHE);
background = W_CachePatchName("DARKEGG1", PU_PATCH);
V_DrawSmallScaledPatch(0, 0, 0, background);
}
else if (timetonext > 3*TICRATE && timetonext < 4*TICRATE)
{
if (!(finalecount & 3))
background = W_CachePatchName("BRITEGG2", PU_CACHE);
background = W_CachePatchName("BRITEGG2", PU_PATCH);
else
background = W_CachePatchName("DARKEGG2", PU_CACHE);
background = W_CachePatchName("DARKEGG2", PU_PATCH);
V_DrawSmallScaledPatch(0, 0, 0, background);
}
else if (timetonext > 1*TICRATE && timetonext < 2*TICRATE)
{
if (!(finalecount & 3))
background = W_CachePatchName("BRITEGG3", PU_CACHE);
background = W_CachePatchName("BRITEGG3", PU_PATCH);
else
background = W_CachePatchName("DARKEGG3", PU_CACHE);
background = W_CachePatchName("DARKEGG3", PU_PATCH);
V_DrawSmallScaledPatch(0, 0, 0, background);
}
@ -768,79 +768,79 @@ static void F_IntroDrawScene(void)
knucklesx += sonicx;
sonicx += P_ReturnThrustX(NULL, finalecount * ANG10, 3);
V_DrawSmallScaledPatch(skyx, 0, 0, (patch = W_CachePatchName("INTROSKY", PU_CACHE)));
V_DrawSmallScaledPatch(skyx, 0, 0, (patch = W_CachePatchName("INTROSKY", PU_PATCH)));
V_DrawSmallScaledPatch(skyx - 320, 0, 0, patch);
W_UnlockCachedPatch(patch);
V_DrawSmallScaledPatch(grassx, 0, 0, (patch = W_CachePatchName("INTROGRS", PU_CACHE)));
V_DrawSmallScaledPatch(grassx, 0, 0, (patch = W_CachePatchName("INTROGRS", PU_PATCH)));
V_DrawSmallScaledPatch(grassx - 320, 0, 0, patch);
W_UnlockCachedPatch(patch);
if (finalecount & 1)
{
// Sonic
V_DrawSmallScaledPatch(sonicx, 54, 0, (patch = W_CachePatchName("RUN2", PU_CACHE)));
V_DrawSmallScaledPatch(sonicx, 54, 0, (patch = W_CachePatchName("RUN2", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Appendages
if (finalecount & 2)
{
// Sonic's feet
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT4", PU_CACHE)));
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT4", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Tails' tails
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP2", PU_CACHE)));
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP2", PU_PATCH)));
W_UnlockCachedPatch(patch);
}
else
{
// Sonic's feet
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT2", PU_CACHE)));
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT2", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Tails' tails
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP1", PU_CACHE)));
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP1", PU_PATCH)));
W_UnlockCachedPatch(patch);
}
// Tails
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("FLY2", PU_CACHE)));
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("FLY2", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Knuckles
V_DrawSmallScaledPatch(knucklesx, knucklesy, 0, (patch = W_CachePatchName("GLIDE2", PU_CACHE)));
V_DrawSmallScaledPatch(knucklesx, knucklesy, 0, (patch = W_CachePatchName("GLIDE2", PU_PATCH)));
W_UnlockCachedPatch(patch);
}
else
{
// Sonic
V_DrawSmallScaledPatch(sonicx, 54, 0, (patch = W_CachePatchName("RUN1", PU_CACHE)));
V_DrawSmallScaledPatch(sonicx, 54, 0, (patch = W_CachePatchName("RUN1", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Appendages
if (finalecount & 2)
{
// Sonic's feet
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT3", PU_CACHE)));
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT3", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Tails' tails
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP2", PU_CACHE)));
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP2", PU_PATCH)));
W_UnlockCachedPatch(patch);
}
else
{
// Sonic's feet
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT1", PU_CACHE)));
V_DrawSmallScaledPatch(sonicx - 8, 92, 0, (patch = W_CachePatchName("PEELOUT1", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Tails' tails
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP1", PU_CACHE)));
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("HELICOP1", PU_PATCH)));
W_UnlockCachedPatch(patch);
}
// Tails
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("FLY1", PU_CACHE)));
V_DrawSmallScaledPatch(tailsx, tailsy, 0, (patch = W_CachePatchName("FLY1", PU_PATCH)));
W_UnlockCachedPatch(patch);
// Knuckles
V_DrawSmallScaledPatch(knucklesx, knucklesy, 0, (patch = W_CachePatchName("GLIDE1", PU_CACHE)));
V_DrawSmallScaledPatch(knucklesx, knucklesy, 0, (patch = W_CachePatchName("GLIDE1", PU_PATCH)));
W_UnlockCachedPatch(patch);
}
@ -873,8 +873,8 @@ static void F_IntroDrawScene(void)
y += (30*(FRACUNIT-scale));
}
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_LEVEL);
glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_LEVEL);
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_PATCH);
glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_PATCH);
if (worktics >= 5)
trans = (worktics-5)>>1;
@ -988,7 +988,7 @@ void F_IntroDrawer(void)
{
if (intro_scenenum == 5 && intro_curtime == 5*TICRATE)
{
patch_t *radar = W_CachePatchName("RADAR", PU_CACHE);
patch_t *radar = W_CachePatchName("RADAR", PU_PATCH);
F_WipeStartScreen();
F_WipeColorFill(31);
@ -1001,7 +1001,7 @@ void F_IntroDrawer(void)
}
else if (intro_scenenum == 7 && intro_curtime == 6*TICRATE) // Force a wipe here
{
patch_t *grass = W_CachePatchName("SGRASS2", PU_CACHE);
patch_t *grass = W_CachePatchName("SGRASS2", PU_PATCH);
F_WipeStartScreen();
F_WipeColorFill(31);
@ -1014,7 +1014,7 @@ void F_IntroDrawer(void)
}
/*else if (intro_scenenum == 12 && intro_curtime == 7*TICRATE)
{
patch_t *confront = W_CachePatchName("CONFRONT", PU_CACHE);
patch_t *confront = W_CachePatchName("CONFRONT", PU_PATCH);
F_WipeStartScreen();
F_WipeColorFill(31);
@ -1027,7 +1027,7 @@ void F_IntroDrawer(void)
}*/
if (intro_scenenum == 15 && intro_curtime == 7*TICRATE)
{
patch_t *sdo = W_CachePatchName("SONICDO2", PU_CACHE);
patch_t *sdo = W_CachePatchName("SONICDO2", PU_PATCH);
F_WipeStartScreen();
F_WipeColorFill(31);
@ -1359,14 +1359,14 @@ void F_CreditDrawer(void)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
// Zig Zagz
V_DrawScaledPatch(-16, zagpos, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_CACHE));
V_DrawScaledPatch(-16, zagpos - 320, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_CACHE));
V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_CACHE));
V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos - 320, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_CACHE));
V_DrawScaledPatch(-16, zagpos, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH));
V_DrawScaledPatch(-16, zagpos - 320, V_SNAPTOLEFT, W_CachePatchName("LTZIGZAG", PU_PATCH));
V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH));
V_DrawScaledPatch(BASEVIDWIDTH + 16, zagpos - 320, V_SNAPTORIGHT|V_FLIP, W_CachePatchName("LTZIGZAG", PU_PATCH));
// Draw background pictures first
for (i = 0; credits_pics[i].patch; i++)
V_DrawSciencePatch(credits_pics[i].x<<FRACBITS, (280<<FRACBITS) + (((i*credits_height)<<FRACBITS)/(credits_numpics)) - 4*(animtimer<<FRACBITS)/5, 0, W_CachePatchName(credits_pics[i].patch, PU_CACHE), FRACUNIT>>1);
V_DrawSciencePatch(credits_pics[i].x<<FRACBITS, (280<<FRACBITS) + (((i*credits_height)<<FRACBITS)/(credits_numpics)) - 4*(animtimer<<FRACBITS)/5, 0, W_CachePatchName(credits_pics[i].patch, PU_PATCH), FRACUNIT>>1);
// Dim the background
V_DrawFadeScreen(0xFF00, 16);
@ -1574,14 +1574,14 @@ void F_GameEvaluationDrawer(void)
if (goodending)
{
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_LEVEL);
glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_LEVEL);
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_PATCH);
glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_PATCH);
x -= FRACUNIT;
}
else
{
rockpat = W_CachePatchName("ROID0000", PU_LEVEL);
glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_LEVEL);
glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_PATCH);
}
if (finalecount >= 5)
@ -1613,20 +1613,20 @@ void F_GameEvaluationDrawer(void)
// if j == 0 - alternate between 0 and 1
// 1 - 1 and 2
// 2 - 2 and not rendered
V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_LEVEL), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE));
V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE));
}
j--;
}
}
else
{
patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_LEVEL);
patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_PATCH);
V_DrawFixedPatch(x, y, scale, 0, eggrock, colormap[0]);
if (trans < 10)
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, eggrock, colormap[1]);
else if (sparklloop)
V_DrawFixedPatch(x, y, scale, (10-sparklloop)<<V_ALPHASHIFT,
W_CachePatchName("ENDEGRK0", PU_LEVEL), colormap[1]);
W_CachePatchName("ENDEGRK0", PU_PATCH), colormap[1]);
}
}
@ -1640,7 +1640,7 @@ void F_GameEvaluationDrawer(void)
eemeralds_cur += (360<<FRACBITS)/7;
patchname[4] = 'A'+(char)i;
V_DrawFixedPatch(x, y, FRACUNIT, ((emeralds & (1<<i)) ? 0 : V_80TRANS), W_CachePatchName(patchname, PU_LEVEL), NULL);
V_DrawFixedPatch(x, y, FRACUNIT, ((emeralds & (1<<i)) ? 0 : V_80TRANS), W_CachePatchName(patchname, PU_PATCH), NULL);
}
V_DrawCreditString((BASEVIDWIDTH - V_CreditStringWidth(endingtext))<<(FRACBITS-1), (BASEVIDHEIGHT-100)<<(FRACBITS-1), 0, endingtext);
@ -1753,6 +1753,83 @@ void F_GameEvaluationTicker(void)
#define STOPPINGPOINT (14*TICRATE)
#define SPARKLLOOPTIME 15 // must be odd
static void F_CacheEnding(void)
{
endbrdr[1] = W_CachePatchName("ENDBRDR1", PU_PATCH);
endegrk[0] = W_CachePatchName("ENDEGRK0", PU_PATCH);
endegrk[1] = W_CachePatchName("ENDEGRK1", PU_PATCH);
endglow[0] = W_CachePatchName("ENDGLOW0", PU_PATCH);
endglow[1] = W_CachePatchName("ENDGLOW1", PU_PATCH);
endbgsp[0] = W_CachePatchName("ENDBGSP0", PU_PATCH);
endbgsp[1] = W_CachePatchName("ENDBGSP1", PU_PATCH);
endbgsp[2] = W_CachePatchName("ENDBGSP2", PU_PATCH);
endspkl[0] = W_CachePatchName("ENDSPKL0", PU_PATCH);
endspkl[1] = W_CachePatchName("ENDSPKL1", PU_PATCH);
endspkl[2] = W_CachePatchName("ENDSPKL2", PU_PATCH);
endxpld[0] = W_CachePatchName("ENDXPLD0", PU_PATCH);
endxpld[1] = W_CachePatchName("ENDXPLD1", PU_PATCH);
endxpld[2] = W_CachePatchName("ENDXPLD2", PU_PATCH);
endxpld[3] = W_CachePatchName("ENDXPLD3", PU_PATCH);
endescp[0] = W_CachePatchName("ENDESCP0", PU_PATCH);
endescp[1] = W_CachePatchName("ENDESCP1", PU_PATCH);
endescp[2] = W_CachePatchName("ENDESCP2", PU_PATCH);
endescp[3] = W_CachePatchName("ENDESCP3", PU_PATCH);
endescp[4] = W_CachePatchName("ENDESCP4", PU_PATCH);
// so we only need to check once
if ((goodending = ALL7EMERALDS(emeralds)))
{
UINT8 skinnum = players[consoleplayer].skin;
spritedef_t *sprdef;
spriteframe_t *sprframe;
if (skins[skinnum].sprites[SPR2_XTRA].numframes > (XTRA_ENDING+2))
{
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
// character head, skin specific
sprframe = &sprdef->spriteframes[XTRA_ENDING];
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
sprframe = &sprdef->spriteframes[XTRA_ENDING+1];
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
sprframe = &sprdef->spriteframes[XTRA_ENDING+2];
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
}
else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this)
{
endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_PATCH);
endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_PATCH);
endfwrk[2] = W_CachePatchName("ENDFWRK5", PU_PATCH);
}
endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_PATCH);
}
else
{
// eggman, skin nonspecific
endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_PATCH);
endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_PATCH);
endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_PATCH);
endbrdr[0] = W_CachePatchName("ENDBRDR0", PU_LEVEL);
}
}
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);
@ -1768,7 +1845,7 @@ void F_StartEnding(void)
gameaction = ga_nothing;
paused = false;
CON_ToggleOff();
S_StopMusic();
S_StopMusic(); // todo: placeholder
S_StopSounds();
finalecount = -10; // what? this totally isn't a hack. why are you asking?
@ -1776,68 +1853,7 @@ void F_StartEnding(void)
memset(sparkloffs, 0, sizeof(INT32)*3*2);
sparklloop = 0;
endbrdr[1] = W_CachePatchName("ENDBRDR1", PU_LEVEL);
endegrk[0] = W_CachePatchName("ENDEGRK0", PU_LEVEL);
endegrk[1] = W_CachePatchName("ENDEGRK1", PU_LEVEL);
endglow[0] = W_CachePatchName("ENDGLOW0", PU_LEVEL);
endglow[1] = W_CachePatchName("ENDGLOW1", PU_LEVEL);
endbgsp[0] = W_CachePatchName("ENDBGSP0", PU_LEVEL);
endbgsp[1] = W_CachePatchName("ENDBGSP1", PU_LEVEL);
endbgsp[2] = W_CachePatchName("ENDBGSP2", PU_LEVEL);
endspkl[0] = W_CachePatchName("ENDSPKL0", PU_LEVEL);
endspkl[1] = W_CachePatchName("ENDSPKL1", PU_LEVEL);
endspkl[2] = W_CachePatchName("ENDSPKL2", PU_LEVEL);
endxpld[0] = W_CachePatchName("ENDXPLD0", PU_LEVEL);
endxpld[1] = W_CachePatchName("ENDXPLD1", PU_LEVEL);
endxpld[2] = W_CachePatchName("ENDXPLD2", PU_LEVEL);
endxpld[3] = W_CachePatchName("ENDXPLD3", PU_LEVEL);
endescp[0] = W_CachePatchName("ENDESCP0", PU_LEVEL);
endescp[1] = W_CachePatchName("ENDESCP1", PU_LEVEL);
endescp[2] = W_CachePatchName("ENDESCP2", PU_LEVEL);
endescp[3] = W_CachePatchName("ENDESCP3", PU_LEVEL);
endescp[4] = W_CachePatchName("ENDESCP4", PU_LEVEL);
// so we only need to check once
if ((goodending = ALL7EMERALDS(emeralds)))
{
UINT8 skinnum = players[consoleplayer].skin;
spritedef_t *sprdef;
spriteframe_t *sprframe;
if (skins[skinnum].sprites[SPR2_XTRA].numframes > (XTRA_ENDING+2))
{
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
// character head, skin specific
sprframe = &sprdef->spriteframes[XTRA_ENDING];
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
sprframe = &sprdef->spriteframes[XTRA_ENDING+1];
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
sprframe = &sprdef->spriteframes[XTRA_ENDING+2];
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
}
else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this)
{
endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_LEVEL);
endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_LEVEL);
endfwrk[2] = W_CachePatchName("ENDFWRK5", PU_LEVEL);
}
endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_LEVEL);
}
else
{
// eggman, skin nonspecific
endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL);
endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL);
endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL);
endbrdr[0] = W_CachePatchName("ENDBRDR0", PU_LEVEL);
}
F_CacheEnding();
}
void F_EndingTicker(void)
@ -1853,15 +1869,7 @@ void F_EndingTicker(void)
S_ChangeMusicInternal((goodending ? "_endg" : "_endb"), false);
if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets
{
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_LEVEL);
endegrk[1] = W_CachePatchName("ENDEGRK3", PU_LEVEL);
endglow[0] = W_CachePatchName("ENDGLOW2", PU_LEVEL);
endglow[1] = W_CachePatchName("ENDGLOW3", PU_LEVEL);
endxpld[0] = W_CachePatchName("ENDEGRK4", PU_LEVEL);
}
F_CacheGoodEnding();
if (++sparklloop == SPARKLLOOPTIME) // time to roll the randomisation again
{
@ -1880,10 +1888,17 @@ 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_LEVEL);
rockpat = W_CachePatchName("ROID0000", PU_PATCH);
else
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_LEVEL);
rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_PATCH);
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
@ -2367,11 +2382,11 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
if (!scrollxspeed && !scrollyspeed)
{
V_DrawPatchFill(W_CachePatchName(patchname, PU_CACHE));
V_DrawPatchFill(W_CachePatchName(patchname, PU_PATCH));
return;
}
pat = W_CachePatchName(patchname, PU_CACHE);
pat = W_CachePatchName(patchname, PU_PATCH);
patwidth = SHORT(pat->width);
patheight = SHORT(pat->height);
@ -2432,6 +2447,45 @@ else if (strlen(name) <= 6) \
else \
arr[0] = 0;
static void F_CacheTitleScreen(void)
{
switch(curttmode)
{
case TTMODE_OLD:
case TTMODE_NONE:
ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL);
ttwing = W_CachePatchName("TTWING", PU_LEVEL);
ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL);
ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL);
ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL);
ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL);
ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL);
ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL);
ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL);
ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL);
ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL);
ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL);
ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL);
ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL);
ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL);
break;
// don't load alacroix gfx yet; we do that upon first draw.
case TTMODE_ALACROIX:
break;
case TTMODE_USER:
{
UINT16 i;
lumpnum_t lumpnum;
char lumpname[9];
LOADTTGFX(ttuser, curttname, TTMAX_USER)
break;
}
}
}
void F_StartTitleScreen(void)
{
if (menupres[MN_MAIN].musname[0])
@ -2528,41 +2582,7 @@ void F_StartTitleScreen(void)
demoDelayLeft = demoDelayTime;
demoIdleLeft = demoIdleTime;
switch(curttmode)
{
case TTMODE_OLD:
case TTMODE_NONE:
ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL);
ttwing = W_CachePatchName("TTWING", PU_LEVEL);
ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL);
ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL);
ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL);
ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL);
ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL);
ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL);
ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL);
ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL);
ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL);
ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL);
ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL);
ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL);
ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL);
break;
// don't load alacroix gfx yet; we do that upon first draw.
case TTMODE_ALACROIX:
break;
case TTMODE_USER:
{
UINT16 i;
lumpnum_t lumpnum;
char lumpname[9];
LOADTTGFX(ttuser, curttname, TTMAX_USER)
break;
}
}
F_CacheTitleScreen();
}
static void F_UnloadAlacroixGraphics(SINT8 oldttscale)
@ -2711,6 +2731,9 @@ void F_TitleScreenDrawer(void)
if (modeattacking)
return; // We likely came here from retrying. Don't do a damn thing.
if (needpatchrecache && (curttmode != TTMODE_ALACROIX))
F_CacheTitleScreen();
// Draw that sky!
if (curbgcolor >= 0)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor);
@ -2734,6 +2757,12 @@ void F_TitleScreenDrawer(void)
return;
#endif
if (needpatchrecache && (curttmode == TTMODE_ALACROIX))
{
ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
F_LoadAlacroixGraphics(activettscale);
}
switch(curttmode)
{
case TTMODE_OLD:
@ -3681,7 +3710,7 @@ void F_ContinueDrawer(void)
V_DrawLevelTitle(x - (V_LevelNameWidth("Continue?")>>1), 16, 0, "Continue?");
// Two stars...
patch = W_CachePatchName("CONTSTAR", PU_CACHE);
patch = W_CachePatchName("CONTSTAR", PU_PATCH);
V_DrawScaledPatch(x-32, 160, 0, patch);
V_DrawScaledPatch(x+32, 160, 0, patch);
@ -3689,14 +3718,14 @@ void F_ContinueDrawer(void)
if (timeleft > 9)
{
numbuf[7] = '1';
V_DrawScaledPatch(x - 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
V_DrawScaledPatch(x - 10, 160, 0, W_CachePatchName(numbuf, PU_PATCH));
numbuf[7] = '0';
V_DrawScaledPatch(x + 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
V_DrawScaledPatch(x + 10, 160, 0, W_CachePatchName(numbuf, PU_PATCH));
}
else
{
numbuf[7] = '0'+timeleft;
V_DrawScaledPatch(x, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
V_DrawScaledPatch(x, 160, 0, W_CachePatchName(numbuf, PU_PATCH));
}
// Draw the continue markers! Show continues.
@ -3723,7 +3752,7 @@ void F_ContinueDrawer(void)
}
// Spotlight
V_DrawScaledPatch(x, 140, 0, W_CachePatchName("CONTSPOT", PU_CACHE));
V_DrawScaledPatch(x, 140, 0, W_CachePatchName("CONTSPOT", PU_PATCH));
// warping laser
if (continuetime)
@ -3760,7 +3789,7 @@ void F_ContinueDrawer(void)
#define drawchar(dx, dy, n) {\
sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\
sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_CACHE);\
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_PATCH);\
V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);\
}
@ -4024,10 +4053,10 @@ void F_CutsceneDrawer(void)
{
if (cutscenes[cutnum]->scene[scenenum].pichires[picnum])
V_DrawSmallScaledPatch(picxpos, picypos, 0,
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_CACHE));
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_PATCH));
else
V_DrawScaledPatch(picxpos,picypos, 0,
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_CACHE));
W_CachePatchName(cutscenes[cutnum]->scene[scenenum].picname[picnum], PU_PATCH));
}
if (dofadenow && rendermode != render_none)
@ -4513,10 +4542,10 @@ void F_TextPromptDrawer(void)
{
if (textprompts[cutnum]->page[scenenum].pichires[picnum])
V_DrawSmallScaledPatch(picxpos, picypos, 0,
W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_CACHE));
W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_PATCH));
else
V_DrawScaledPatch(picxpos,picypos, 0,
W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_CACHE));
W_CachePatchName(textprompts[cutnum]->page[scenenum].picname[picnum], PU_PATCH));
}
// Draw background
@ -4526,7 +4555,7 @@ void F_TextPromptDrawer(void)
if (iconlump != LUMPERROR)
{
INT32 iconx, icony, scale, scaledsize;
patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_CACHE);
patch = W_CachePatchName(textprompts[cutnum]->page[scenenum].iconname, PU_PATCH);
// scale and center
if (patch->width > patch->height)

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

@ -764,13 +764,12 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
// CACHING HANDLING
// =================================================
static size_t gr_numtextures; // Texture count
static size_t gr_numtextures = 0; // Texture count
static GLTexture_t *gr_textures; // For all textures
static GLTexture_t *gr_flats; // For all (texture) flats, as normal flats don't need to be cached
void HWR_InitTextureCache(void)
{
gr_numtextures = 0;
gr_textures = NULL;
gr_flats = NULL;
}
@ -958,6 +957,9 @@ static void HWR_CacheTextureAsFlat(GLMipmap_t *grMipmap, INT32 texturenum)
{
UINT8 *flat;
if (needpatchflush)
W_FlushCachedPatches();
// setup the texture info
#ifdef GLIDE_API_COMPATIBILITY
grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64;
@ -983,6 +985,9 @@ void HWR_LiterallyGetFlat(lumpnum_t flatlumpnum)
if (flatlumpnum == LUMPERROR)
return;
if (needpatchflush)
W_FlushCachedPatches();
grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
if (!grmip->downloaded && !grmip->grInfo.data)
HWR_CacheFlat(grmip, flatlumpnum);
@ -1061,6 +1066,9 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
// -----------------+
void HWR_GetPatch(GLPatch_t *gpatch)
{
if (needpatchflush)
W_FlushCachedPatches();
// is it in hardware cache
if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data)
{
@ -1091,6 +1099,9 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
{
GLMipmap_t *grmip, *newmip;
if (needpatchflush)
W_FlushCachedPatches();
if (colormap == colormaps || colormap == NULL)
{
// Load the default (green) color in doom cache (temporary?) AND hardware cache
@ -1216,6 +1227,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
{
GLPatch_t *grpatch;
if (needpatchflush)
W_FlushCachedPatches();
grpatch = HWR_GetCachedGLPatch(lumpnum);
if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data)
@ -1419,6 +1433,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
{
GLMipmap_t *grmip;
if (needpatchflush)
W_FlushCachedPatches();
grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
if (!grmip->downloaded && !grmip->grInfo.data)

View file

@ -992,7 +992,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// top edge
if (clearlines > basewindowy - 8)
{
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE);
patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8,
0);
@ -1001,7 +1001,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// bottom edge
if (clearlines > basewindowy + baseviewheight)
{
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE);
patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH);
for (x = 0; x < baseviewwidth; x += 8)
HWR_DrawPatch(patch, basewindowx + x,
basewindowy + baseviewheight, 0);
@ -1010,7 +1010,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// left edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE);
patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
for (y = 0; y < baseviewheight && basewindowy + y < clearlines;
y += 8)
{
@ -1022,7 +1022,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
// right edge
if (clearlines > basewindowy)
{
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE);
patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
for (y = 0; y < baseviewheight && basewindowy+y < clearlines;
y += 8)
{
@ -1034,22 +1034,22 @@ void HWR_DrawViewBorder(INT32 clearlines)
// Draw beveled corners.
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL],
PU_CACHE),
PU_PATCH),
basewindowx - 8, basewindowy - 8, 0);
if (clearlines > basewindowy - 8)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR],
PU_CACHE),
PU_PATCH),
basewindowx + baseviewwidth, basewindowy - 8, 0);
if (clearlines > basewindowy+baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL],
PU_CACHE),
PU_PATCH),
basewindowx - 8, basewindowy + baseviewheight, 0);
if (clearlines > basewindowy + baseviewheight)
HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR],
PU_CACHE),
PU_PATCH),
basewindowx + baseviewwidth,
basewindowy + baseviewheight, 0);
}

View file

@ -832,7 +832,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
if (!M_PointInBox(segbbox,splat->v1.x,splat->v1.y) && !M_PointInBox(segbbox,splat->v2.x,splat->v2.y))
continue;
gpatch = W_CachePatchNum(splat->patch, PU_CACHE);
gpatch = W_CachePatchNum(splat->patch, PU_PATCH);
HWR_GetPatch(gpatch);
wallVerts[0].x = wallVerts[3].x = FIXED_TO_FLOAT(splat->v1.x);
@ -2714,6 +2714,8 @@ static void HWR_AddLine(seg_t * line)
static sector_t tempsec;
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
if (line->glseg)
return;
#ifdef POLYOBJECTS
if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES))
return;
@ -6654,7 +6656,13 @@ void HWR_AddCommands(void)
void HWR_AddSessionCommands(void)
{
static boolean alreadycalled = false;
if (alreadycalled)
return;
CV_RegisterVar(&cv_granisotropicmode);
alreadycalled = true;
}
// --------------------------------------------------------------------------
@ -6690,6 +6698,17 @@ void HWR_Startup(void)
startupdone = true;
}
// --------------------------------------------------------------------------
// Called after switching to the hardware renderer
// --------------------------------------------------------------------------
void HWR_Switch(void)
{
// Set special states from CVARs
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value);
HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value);
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value);
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value);
}
// --------------------------------------------------------------------------
// Free resources allocated by the hardware renderer

View file

@ -29,6 +29,7 @@
// Startup & Shutdown the hardware mode renderer
void HWR_Startup(void);
void HWR_Switch(void);
void HWR_Shutdown(void);
void HWR_drawAMline(const fline_t *fl, INT32 color);

View file

@ -2117,6 +2117,9 @@ static void HU_DrawDemoInfo(void)
//
void HU_Drawer(void)
{
if (needpatchrecache)
R_ReloadHUDGraphics();
#ifndef NONET
// draw chat string plus cursor
if (chat_on)

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
*/
@ -84,6 +85,7 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h);
\return currect video mode
*/
INT32 VID_SetMode(INT32 modenum);
void VID_CheckRenderer(void);
/** \brief The VID_GetModeName function

View file

@ -253,7 +253,7 @@ static int lib_comBufAddText(lua_State *L)
return LUA_ErrInvalid(L, "player_t");
if (plr != &players[consoleplayer])
return 0;
COM_BufAddText(va("%s\n", luaL_checkstring(L, 2)));
COM_BufAddTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE);
return 0;
}
@ -270,7 +270,7 @@ static int lib_comBufInsertText(lua_State *L)
return LUA_ErrInvalid(L, "player_t");
if (plr != &players[consoleplayer])
return 0;
COM_BufInsertText(va("%s\n", luaL_checkstring(L, 2)));
COM_BufInsertTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE);
return 0;
}

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",
@ -256,12 +261,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)
{
@ -358,8 +368,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;
}
@ -415,7 +476,7 @@ static int libd_getSpritePatch(lua_State *L)
return 0;
// push both the patch and it's "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH);
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
return 2;
}
@ -510,7 +571,7 @@ static int libd_getSprite2Patch(lua_State *L)
return 0;
// push both the patch and it's "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH);
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
return 2;
}
@ -519,12 +580,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));
@ -540,6 +611,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
@ -548,7 +622,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));
@ -1047,6 +1128,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);

File diff suppressed because it is too large Load diff

View file

@ -14225,7 +14225,7 @@ void A_SaloonDoorSpawn(mobj_t *actor)
fixed_t c = FINECOSINE(fa)*locvar2;
fixed_t s = FINESINE(fa)*locvar2;
mobj_t *door;
mobjflag2_t ambush = (actor->flags & MF2_AMBUSH);
mobjflag2_t ambush = (actor->flags2 & MF2_AMBUSH);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_SaloonDoorSpawn", actor))

View file

@ -995,7 +995,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_SALOONDOOR && tmthing->player)
{
mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing;
if ((thing->flags & MF2_AMBUSH) || ref != tmthing)
if ((thing->flags2 & MF2_AMBUSH) || ref != tmthing)
{
fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT);
angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle;
@ -1008,7 +1008,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_SALOONDOORCENTER && tmthing->player)
{
if ((thing->flags & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
if ((thing->flags2 & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)))
return true;
}

View file

@ -400,6 +400,8 @@ static void Polyobj_findSegs(polyobj_t *po, seg_t *seg)
// Find backfacings
for (s = 0; s < numsegs; s++)
{
if (segs[s].glseg)
continue;
if (segs[s].linedef == seg->linedef
&& segs[s].side == 1)
{
@ -436,6 +438,8 @@ newseg:
// seg's ending vertex.
for (i = 0; i < numsegs; ++i)
{
if (segs[i].glseg)
continue;
if (segs[i].side != 0) // needs to be frontfacing
continue;
if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y)
@ -460,6 +464,9 @@ newseg:
// Find backfacings
for (q = 0; q < numsegs; q++)
{
if (segs[q].glseg)
continue;
if (segs[q].linedef == segs[i].linedef
&& segs[q].side == 1)
{
@ -606,6 +613,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES;
INT32 parentID = 0, potrans = 0;
if (seg->glseg)
continue;
if (seg->side != 0) // needs to be frontfacing
continue;

View file

@ -1343,6 +1343,15 @@ static void P_LoadMapData(const virtres_t *virt)
memcpy(spawnsides, sides, numsides * sizeof (*sides));
}
static void P_InitializeSubsector(subsector_t *ss)
{
ss->sector = NULL;
#ifdef FLOORSPLATS
ss->splats = NULL;
#endif
ss->validcount = 0;
}
static inline void P_LoadSubsectors(UINT8 *data)
{
mapsubsector_t *ms = (mapsubsector_t*)data;
@ -1351,13 +1360,9 @@ static inline void P_LoadSubsectors(UINT8 *data)
for (i = 0; i < numsubsectors; i++, ss++, ms++)
{
ss->sector = NULL;
ss->numlines = SHORT(ms->numsegs);
ss->firstline = SHORT(ms->firstseg);
#ifdef FLOORSPLATS
ss->splats = NULL;
#endif
ss->validcount = 0;
P_InitializeSubsector(ss);
}
}
@ -1414,73 +1419,324 @@ static inline float P_SegLengthFloat(seg_t *seg)
}
#endif
static void P_LoadSegs(UINT8 *data)
static void P_InitializeSeg(seg_t *seg)
{
INT32 linedef, side;
mapseg_t *ml = (mapseg_t*)data;
seg_t *li = segs;
line_t *ldef;
size_t i;
seg->sidedef = &sides[seg->linedef->sidenum[seg->side]];
for (i = 0; i < numsegs; i++, li++, ml++)
{
li->v1 = &vertexes[SHORT(ml->v1)];
li->v2 = &vertexes[SHORT(ml->v2)];
seg->frontsector = seg->sidedef->sector;
seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL;
li->length = P_SegLength(li);
#ifdef HWRENDER
if (rendermode == render_opengl)
{
li->flength = P_SegLengthFloat(li);
//Hurdler: 04/12/2000: for now, only used in hardware mode
li->lightmaps = NULL; // list of static lightmap for this seg
}
li->pv1 = li->pv2 = NULL;
seg->pv1 = seg->pv2 = NULL;
//Hurdler: 04/12/2000: for now, only used in hardware mode
seg->lightmaps = NULL; // list of static lightmap for this seg
#endif
li->angle = (SHORT(ml->angle))<<FRACBITS;
li->offset = (SHORT(ml->offset))<<FRACBITS;
linedef = SHORT(ml->linedef);
ldef = &lines[linedef];
li->linedef = ldef;
li->side = side = SHORT(ml->side);
li->sidedef = &sides[ldef->sidenum[side]];
li->frontsector = sides[ldef->sidenum[side]].sector;
if (ldef->flags & ML_TWOSIDED)
li->backsector = sides[ldef->sidenum[side^1]].sector;
else
li->backsector = 0;
seg->numlights = 0;
seg->rlights = NULL;
#ifdef POLYOBJECTS
seg->polyseg = NULL;
seg->dontrenderme = false;
#endif
}
li->numlights = 0;
li->rlights = NULL;
static void P_LoadSegs(UINT8 *data)
{
mapseg_t *ms = (mapseg_t*)data;
seg_t *seg = segs;
size_t i;
for (i = 0; i < numsegs; i++, seg++, ms++)
{
seg->v1 = &vertexes[SHORT(ms->v1)];
seg->v2 = &vertexes[SHORT(ms->v2)];
seg->side = SHORT(ms->side);
seg->offset = (SHORT(ms->offset)) << FRACBITS;
seg->angle = (SHORT(ms->angle)) << FRACBITS;
seg->linedef = &lines[SHORT(ms->linedef)];
seg->length = P_SegLength(seg);
#ifdef HWRENDER
seg->flength = (rendermode == render_opengl) ? P_SegLengthFloat(seg) : 0;
#endif
seg->glseg = false;
P_InitializeSeg(seg);
}
}
typedef enum {
NT_DOOM,
NT_XNOD,
NT_ZNOD,
NT_XGLN,
NT_ZGLN,
NT_XGL2,
NT_ZGL2,
NT_XGL3,
NT_ZGL3,
NT_UNSUPPORTED,
NUMNODETYPES
} nodetype_t;
// Find out the BSP format.
static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
{
boolean supported[NUMNODETYPES] = {0};
nodetype_t nodetype = NT_UNSUPPORTED;
char signature[4 + 1];
if (vres_Find(virt, "TEXTMAP"))
{
*nodedata = vres_Find(virt, "ZNODES")->data;
supported[NT_XGLN] = supported[NT_XGL3] = true;
}
else
{
virtlump_t *virtsegs = vres_Find(virt, "SEGS");
virtlump_t *virtssectors;
if (virtsegs && virtsegs->size)
{
*nodedata = vres_Find(virt, "NODES")->data;
return NT_DOOM; // Traditional map format BSP tree.
}
virtssectors = vres_Find(virt, "SSECTORS");
if (virtssectors && virtssectors->size)
{ // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature.
*nodedata = virtssectors->data;
supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true;
}
else
{ // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature.
*nodedata = vres_Find(virt, "NODES")->data;
supported[NT_XNOD] = supported[NT_ZNOD] = true;
}
}
M_Memcpy(signature, *nodedata, 4);
signature[4] = '\0';
(*nodedata) += 4;
if (!strcmp(signature, "XNOD"))
nodetype = NT_XNOD;
else if (!strcmp(signature, "ZNOD"))
nodetype = NT_ZNOD;
else if (!strcmp(signature, "XGLN"))
nodetype = NT_XGLN;
else if (!strcmp(signature, "ZGLN"))
nodetype = NT_ZGLN;
else if (!strcmp(signature, "XGL3"))
nodetype = NT_XGL3;
return supported[nodetype] ? nodetype : NT_UNSUPPORTED;
}
// Extended node formats feature additional vertices; useful for OpenGL, but totally useless in gamelogic.
static boolean P_LoadExtraVertices(UINT8 **data)
{
UINT32 origvrtx = READUINT32((*data));
UINT32 xtrvrtx = READUINT32((*data));
line_t* ld = lines;
vertex_t *oldpos = vertexes;
ssize_t offset;
size_t i;
if (numvertexes != origvrtx) // If native vertex count doesn't match node original vertex count, bail out (broken data?).
{
CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n");
return false;
}
if (!xtrvrtx)
return true;
// If extra vertexes were generated, reallocate the vertex array and fix the pointers.
numvertexes += xtrvrtx;
vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL);
offset = (size_t)(vertexes - oldpos);
for (i = 0, ld = lines; i < numlines; i++, ld++)
{
ld->v1 += offset;
ld->v2 += offset;
}
// Read extra vertex data.
for (i = origvrtx; i < numvertexes; i++)
{
vertexes[i].x = READFIXED((*data));
vertexes[i].y = READFIXED((*data));
}
return true;
}
static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype)
{
size_t i, k;
INT16 m;
seg_t *seg;
// Subsectors
numsubsectors = READUINT32((*data));
subsectors = Z_Calloc(numsubsectors*sizeof(*subsectors), PU_LEVEL, NULL);
for (i = 0; i < numsubsectors; i++)
subsectors[i].numlines = READUINT32((*data));
// Segs
numsegs = READUINT32((*data));
segs = Z_Calloc(numsegs*sizeof(*segs), PU_LEVEL, NULL);
for (i = 0, k = 0; i < numsubsectors; i++)
{
subsectors[i].firstline = k;
P_InitializeSubsector(&subsectors[i]);
switch (nodetype)
{
case NT_XGLN:
case NT_XGL3:
for (m = 0; m < subsectors[i].numlines; m++, k++)
{
UINT16 linenum;
UINT32 vert = READUINT32((*data));
segs[k].v1 = &vertexes[vert];
if (m == 0)
segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert];
else
segs[k - 1].v2 = segs[k].v1;
(*data) += 4; // partner, can be ignored by software renderer
if (nodetype == NT_XGL3)
(*data) += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits.
linenum = READUINT16((*data));
segs[k].glseg = (linenum == 0xFFFF);
segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum];
segs[k].side = READUINT8((*data));
}
break;
case NT_XNOD:
for (m = 0; m < subsectors[i].numlines; m++, k++)
{
segs[k].v1 = &vertexes[READUINT32((*data))];
segs[k].v2 = &vertexes[READUINT32((*data))];
segs[k].linedef = &lines[READUINT16((*data))];
segs[k].side = READUINT8((*data));
segs[k].glseg = false;
}
break;
default:
return false;
}
}
for (i = 0, seg = segs; i < numsegs; i++, seg++)
{
vertex_t *v1 = seg->v1;
vertex_t *v2 = seg->v2;
P_InitializeSeg(seg);
seg->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y);
seg->offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y);
}
return true;
}
// Auxiliary function: Shrink node ID from 32-bit to 16-bit.
static UINT16 ShrinkNodeID(UINT32 x) {
UINT16 mask = (x >> 16) & 0xC000;
UINT16 result = x;
return result | mask;
}
static void P_LoadExtendedNodes(UINT8 **data, nodetype_t nodetype)
{
node_t *mn;
size_t i, j, k;
boolean xgl3 = (nodetype == NT_XGL3);
numnodes = READINT32((*data));
nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL);
for (i = 0, mn = nodes; i < numnodes; i++, mn++)
{
// Splitter
mn->x = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS);
mn->y = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS);
mn->dx = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS);
mn->dy = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS);
// Bounding boxes
for (j = 0; j < 2; j++)
for (k = 0; k < 4; k++)
mn->bbox[j][k] = READINT16((*data)) << FRACBITS;
//Children
mn->children[0] = ShrinkNodeID(READUINT32((*data))); /// \todo Use UINT32 for node children in a future, instead?
mn->children[1] = ShrinkNodeID(READUINT32((*data)));
}
}
static void P_LoadMapBSP(const virtres_t *virt)
{
virtlump_t* virtssectors = vres_Find(virt, "SSECTORS");
virtlump_t* virtsegs = vres_Find(virt, "SEGS");
virtlump_t* virtnodes = vres_Find(virt, "NODES");
UINT8 *nodedata = NULL;
nodetype_t nodetype = P_GetNodetype(virt, &nodedata);
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
numnodes = virtnodes->size / sizeof(mapnode_t);
numsegs = virtsegs->size / sizeof(mapseg_t);
switch (nodetype)
{
case NT_DOOM:
{
virtlump_t *virtssectors = vres_Find(virt, "SSECTORS");
virtlump_t* virtnodes = vres_Find(virt, "NODES");
virtlump_t *virtsegs = vres_Find(virt, "SEGS");
if (numsubsectors <= 0)
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
if (numnodes <= 0)
I_Error("Level has no nodes");
if (numsegs <= 0)
I_Error("Level has no segs");
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
numnodes = virtnodes->size / sizeof(mapnode_t);
numsegs = virtsegs->size / sizeof(mapseg_t);
subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL);
nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL);
segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL);
if (numsubsectors <= 0)
I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)");
if (numnodes <= 0)
I_Error("Level has no nodes");
if (numsegs <= 0)
I_Error("Level has no segs");
// Nodes
P_LoadSubsectors(virtssectors->data);
P_LoadNodes(virtnodes->data);
P_LoadSegs(virtsegs->data);
subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL);
nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL);
segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL);
P_LoadSubsectors(virtssectors->data);
P_LoadNodes(virtnodes->data);
P_LoadSegs(virtsegs->data);
break;
}
case NT_XNOD:
case NT_XGLN:
case NT_XGL3:
if (!P_LoadExtraVertices(&nodedata))
return;
if (!P_LoadExtendedSubsectorsAndSegs(&nodedata, nodetype))
return;
P_LoadExtendedNodes(&nodedata, nodetype);
break;
default:
CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n");
return;
}
return;
}
// Split from P_LoadBlockMap for convenience
@ -2969,23 +3225,14 @@ boolean P_LoadLevel(boolean fromnetsave)
P_SpawnPrecipitation();
#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
if (rendermode == render_opengl)
{
// Lactozilla (December 8, 2019)
// Level setup used to free EVERY mipmap from memory.
// Even mipmaps that aren't related to level textures.
// Presumably, the hardware render code used to store textures as level data.
// Meaning, they had memory allocated and marked with the PU_LEVEL tag.
// Level textures are only reloaded after R_LoadTextures, which is
// when the texture list is loaded.
#ifdef ALAM_LIGHTING
// BP: reset light between levels (we draw preview frame lights on current frame)
HWR_ResetLights();
#endif
// Correct missing sidedefs & deep water trick
HWR_CorrectSWTricks();
HWR_CreatePlanePolygons((INT32)numnodes - 1);
}
HWR_SetupLevel();
#endif
// oh god I hope this helps
@ -3065,6 +3312,26 @@ boolean P_LoadLevel(boolean fromnetsave)
return true;
}
#ifdef HWRENDER
void HWR_SetupLevel(void)
{
// Lactozilla (December 8, 2019)
// Level setup used to free EVERY mipmap from memory.
// Even mipmaps that aren't related to level textures.
// Presumably, the hardware render code used to store textures as level data.
// Meaning, they had memory allocated and marked with the PU_LEVEL tag.
// Level textures are only reloaded after R_LoadTextures, which is
// when the texture list is loaded.
#ifdef ALAM_LIGHTING
// BP: reset light between levels (we draw preview frame lights on current frame)
HWR_ResetLights();
#endif
// Correct missing sidedefs & deep water trick
HWR_CorrectSWTricks();
HWR_CreatePlanePolygons((INT32)numnodes - 1);
}
#endif
//
// P_RunSOC
//

View file

@ -98,6 +98,9 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
#endif
void P_RespawnThings(void);
boolean P_LoadLevel(boolean fromnetsave);
#ifdef HWRENDER
void HWR_SetupLevel(void);
#endif
boolean P_AddWadFile(const char *wadfilename);
boolean P_RunSOC(const char *socfilename);
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num);

View file

@ -1169,9 +1169,11 @@ static void R_Subsector(size_t num)
while (count--)
{
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
if (!line->glseg
#ifdef POLYOBJECTS
if (!line->polyseg) // ignore segs that belong to polyobjects
&& !line->polyseg // ignore segs that belong to polyobjects
#endif
)
R_AddLine(line);
line++;
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */

View file

@ -2095,7 +2095,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;
@ -2717,7 +2716,7 @@ void R_PrecacheLevel(void)
lump = sf->lumppat[k];
if (devparm)
spritememory += W_LumpLength(lump);
W_CachePatchNum(lump, PU_CACHE);
W_CachePatchNum(lump, PU_PATCH);
}
}
}

View file

@ -586,6 +586,7 @@ typedef struct seg_s
polyobj_t *polyseg;
boolean dontrenderme;
#endif
boolean glseg;
} seg_t;
//
@ -728,9 +729,7 @@ typedef struct
{
patch_t *patch[8][ROTANGLES];
boolean cached[8];
#ifdef HWRENDER
aatree_t *hardware_patch[8];
#endif
} rotsprite_t;
#endif
@ -744,6 +743,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

@ -19,6 +19,7 @@
#include "r_local.h"
#include "r_splats.h" // faB(21jan): testing
#include "r_sky.h"
#include "hu_stuff.h"
#include "st_stuff.h"
#include "p_local.h"
#include "keys.h"
@ -28,6 +29,7 @@
#include "d_main.h"
#include "v_video.h"
#include "p_spec.h" // skyboxmo
#include "p_setup.h"
#include "z_zone.h"
#include "m_random.h" // quake camera shake
#include "r_portal.h"
@ -1154,6 +1156,26 @@ 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
void R_ReloadHUDGraphics(void)
{
CONS_Debug(DBG_RENDER, "R_ReloadHUDGraphics()...\n");
ST_LoadGraphics();
HU_LoadGraphics();
ST_ReloadSkinFaceGraphics();
}
// =========================================================================
// ENGINE COMMANDS & VARS
// =========================================================================

View file

@ -89,6 +89,10 @@ extern consvar_t cv_tailspickup;
// Called by startup code.
void R_Init(void);
#ifdef HWRENDER
void R_InitHardwareMode(void);
#endif
void R_ReloadHUDGraphics(void);
// just sets setsizeneeded true
extern boolean setsizeneeded;

View file

@ -1396,4 +1396,19 @@ void R_FreeSkinRotSprite(size_t skinnum)
skinsprites++;
}
}
//
// R_FreeAllRotSprite
//
// Free ALL sprite rotation data from memory.
//
void R_FreeAllRotSprite(void)
{
INT32 i;
size_t s;
for (s = 0; s < numsprites; s++)
R_FreeSingleRotSprite(&sprites[s]);
for (i = 0; i < numskins; ++i)
R_FreeSkinRotSprite(i);
}
#endif

View file

@ -68,6 +68,7 @@ void R_FreeSingleRotSprite(spritedef_t *spritedef);
void R_FreeSkinRotSprite(size_t skinnum);
extern fixed_t rollcosang[ROTANGLES];
extern fixed_t rollsinang[ROTANGLES];
void R_FreeAllRotSprite(void);
#endif
#endif // __R_PATCH__

View file

@ -165,7 +165,7 @@ static void R_DrawWallSplats(void)
mfloorclip = floorclip;
mceilingclip = ceilingclip;
patch = W_CachePatchNum(splat->patch, PU_CACHE);
patch = W_CachePatchNum(splat->patch, PU_PATCH);
dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz;
if (splat->yoffset)
@ -308,6 +308,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// for horizontal / vertical / diagonal. Diagonal?
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
curline = ds->curline;
if (curline->glseg)
return;
frontsector = curline->frontsector;
backsector = curline->backsector;
texnum = R_GetTextureNum(curline->sidedef->midtexture);

View file

@ -147,7 +147,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f
splat->flags = flags;
// bad.. but will be needed for drawing anyway..
patch = W_CachePatchNum(splat->patch, PU_CACHE);
patch = W_CachePatchNum(splat->patch, PU_PATCH);
// offset needed by draw code for texture mapping
linelength = P_SegLength((seg_t *)wallline);

View file

@ -125,10 +125,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
sprtemp[frame].rotsprite.cached[r] = false;
for (ang = 0; ang < ROTANGLES; ang++)
sprtemp[frame].rotsprite.patch[r][ang] = NULL;
#ifdef HWRENDER
if (rendermode == render_opengl)
sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
#endif // HWRENDER
sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER);
}
#endif

View file

@ -53,6 +53,7 @@ void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void);
// ------------------
viddef_t vid;
INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1)
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}};
@ -62,7 +63,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_ChangeFullscreen (void);
static void SCR_ActuallyChangeRenderer(void);
CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {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};
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};
@ -87,19 +92,8 @@ boolean R_3DNow = false;
boolean R_MMXExt = false;
boolean R_SSE2 = false;
void SCR_SetMode(void)
void SCR_SetDrawFuncs(void)
{
if (dedicated)
return;
if (!setmodeneeded || WipeInAction)
return; // should never happen and don't change it during a wipe, BAD!
VID_SetMode(--setmodeneeded);
V_SetPalette(0);
//
// setup the right draw routines for either 8bpp or 16bpp
//
@ -193,9 +187,37 @@ void SCR_SetMode(void)
if (SCR_IsAspectCorrect(vid.width, vid.height))
CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT);
*/
}
void SCR_SetMode(void)
{
if (dedicated)
return;
if (!(setmodeneeded || setrenderneeded) || WipeInAction)
return; // should never happen and don't change it during a wipe, BAD!
// Lactozilla: Renderer switching
if (setrenderneeded)
{
Z_PreparePatchFlush();
needpatchflush = true;
needpatchrecache = true;
VID_CheckRenderer();
if (!setmodeneeded)
VID_SetMode(vid.modenum);
}
if (setmodeneeded)
VID_SetMode(--setmodeneeded);
V_SetPalette(0);
SCR_SetDrawFuncs();
// set the apprpriate drawer for the sky (tall or INT16)
setmodeneeded = 0;
setrenderneeded = 0;
}
// do some initial settings for the game loading screen
@ -383,6 +405,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
@ -412,6 +436,50 @@ 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;
}
// Lactozilla: Renderer switching
void SCR_ChangeRenderer(void)
{
setrenderneeded = 0;
if (con_startup)
{
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)
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);
CV_StealthSetValue(&cv_newrenderer, cv_renderer.value);
}
boolean SCR_IsAspectCorrect(INT32 width, INT32 height)
{
return

View file

@ -170,18 +170,27 @@ extern boolean R_SSE2;
// ----------------
// screen variables
// ----------------
extern viddef_t vid;
extern INT32 setmodeneeded; // mode number to set if needed, or 0
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
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen;
extern CV_PossibleValue_t cv_renderer_t[];
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen;
extern consvar_t cv_newrenderer;
// wait for page flipping to end or not
extern consvar_t cv_vidwait;
// Change video mode, only at the start of a refresh.
void SCR_SetMode(void);
void SCR_SetDrawFuncs(void);
// Recalc screen size dependent stuff
void SCR_Recalc(void);
// Check parms once at startup

View file

@ -71,6 +71,7 @@
#include "../i_video.h"
#include "../console.h"
#include "../command.h"
#include "../r_main.h"
#include "sdlmain.h"
#ifdef HWRENDER
#include "../hardware/hw_main.h"
@ -1208,7 +1209,6 @@ void I_FinishUpdate(void)
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
@ -1408,37 +1408,53 @@ void VID_PrepareModeList(void)
#endif
}
INT32 VID_SetMode(INT32 modeNum)
static SDL_bool Impl_CreateContext(void)
{
SDLdoUngrabMouse();
vid.recalc = 1;
vid.bpp = 1;
if (modeNum >= 0 && modeNum < MAXWINMODES)
// Renderer-specific stuff
#ifdef HWRENDER
if (rendermode == render_opengl)
{
vid.width = windowedModes[modeNum][0];
vid.height = windowedModes[modeNum][1];
vid.modenum = modeNum;
if (!sdlglcontext)
sdlglcontext = SDL_GL_CreateContext(window);
if (sdlglcontext == NULL)
{
SDL_DestroyWindow(window);
I_Error("Failed to create a GL context: %s\n", SDL_GetError());
}
SDL_GL_MakeCurrent(window, sdlglcontext);
}
else
#endif
if (rendermode == render_soft)
{
// just set the desktop resolution as a fallback
SDL_DisplayMode mode;
SDL_GetWindowDisplayMode(window, &mode);
if (mode.w >= 2048)
int flags = 0; // Use this to set SDL_RENDERER_* flags now
if (usesdl2soft)
flags |= SDL_RENDERER_SOFTWARE;
else if (cv_vidwait.value)
flags |= SDL_RENDERER_PRESENTVSYNC;
if (!renderer)
renderer = SDL_CreateRenderer(window, -1, flags);
if (renderer == NULL)
{
vid.width = 1920;
vid.height = 1200;
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
return SDL_FALSE;
}
else
{
vid.width = mode.w;
vid.height = mode.h;
}
vid.modenum = -1;
SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT);
}
return SDL_TRUE;
}
void VID_CheckRenderer(void)
{
if (dedicated)
return;
if (setrenderneeded)
{
rendermode = setrenderneeded;
Impl_CreateContext();
}
//Impl_SetWindowName("SRB2 "VERSIONSTRING);
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
Impl_VideoSetupBuffer();
@ -1450,8 +1466,39 @@ INT32 VID_SetMode(INT32 modeNum)
SDL_FreeSurface(bufSurface);
bufSurface = NULL;
}
#ifdef HWRENDER
HWR_FreeTextureCache();
#endif
SCR_SetDrawFuncs();
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
I_StartupHardwareGraphics();
R_InitHardwareMode();
HWR_Switch();
}
#endif
}
INT32 VID_SetMode(INT32 modeNum)
{
SDLdoUngrabMouse();
vid.recalc = 1;
vid.bpp = 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;
}
@ -1472,8 +1519,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
@ -1486,38 +1532,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
return SDL_FALSE;
}
// Renderer-specific stuff
#ifdef HWRENDER
if (rendermode == render_opengl)
{
sdlglcontext = SDL_GL_CreateContext(window);
if (sdlglcontext == NULL)
{
SDL_DestroyWindow(window);
I_Error("Failed to create a GL context: %s\n", SDL_GetError());
}
SDL_GL_MakeCurrent(window, sdlglcontext);
}
else
#endif
if (rendermode == render_soft)
{
flags = 0; // Use this to set SDL_RENDERER_* flags now
if (usesdl2soft)
flags |= SDL_RENDERER_SOFTWARE;
else if (cv_vidwait.value)
flags |= SDL_RENDERER_PRESENTVSYNC;
renderer = SDL_CreateRenderer(window, -1, flags);
if (renderer == NULL)
{
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
return SDL_FALSE;
}
SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT);
}
return SDL_TRUE;
return Impl_CreateContext();
}
/*
@ -1572,17 +1587,14 @@ static void Impl_VideoSetupSDLBuffer(void)
static void Impl_VideoSetupBuffer(void)
{
// Set up game's software render buffer
//if (rendermode == render_soft)
vid.rowbytes = vid.width * vid.bpp;
vid.direct = NULL;
if (vid.buffer)
free(vid.buffer);
vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS);
if (!vid.buffer)
{
vid.rowbytes = vid.width * vid.bpp;
vid.direct = NULL;
if (vid.buffer)
free(vid.buffer);
vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS);
if (!vid.buffer)
{
I_Error("%s", M_GetText("Not enough memory for video buffer\n"));
}
I_Error("%s", M_GetText("Not enough memory for video buffer\n"));
}
}
@ -1626,10 +1638,13 @@ void I_StartupGraphics(void)
))
framebuffer = SDL_TRUE;
}
if (M_CheckParm("-software"))
{
#ifdef HWRENDER
if (M_CheckParm("-opengl"))
rendermode = render_opengl;
else if (M_CheckParm("-software"))
#endif
rendermode = render_soft;
}
usesdl2soft = M_CheckParm("-softblit");
borderlesswindow = M_CheckParm("-borderless");
@ -1637,44 +1652,7 @@ void I_StartupGraphics(void)
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2);
VID_Command_ModeList_f();
#ifdef HWRENDER
if (M_CheckParm("-opengl") || rendermode == render_opengl)
{
rendermode = render_opengl;
HWD.pfnInit = hwSym("Init",NULL);
HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL);
HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",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.pfnDrawModel = hwSym("DrawModel",NULL);
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
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;
}
}
I_StartupHardwareGraphics();
#endif
// Fury: we do window initialization after GL setup to allow
@ -1734,6 +1712,50 @@ 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.pfnRenderSkyDome = hwSym("RenderSkyDome",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.pfnDrawModel = hwSym("DrawModel",NULL);
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
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

@ -2766,6 +2766,9 @@ static void ST_overlayDrawer(void)
void ST_Drawer(void)
{
if (needpatchrecache)
R_ReloadHUDGraphics();
#ifdef SEENAMES
if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo)
{

View file

@ -1045,13 +1045,13 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin
{
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CONTINUE];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
V_DrawMappedPatch(x, y, flags, patch, colormap);
}
else
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_PATCH));
}
//

View file

@ -55,6 +55,7 @@
#include "dehacked.h"
#include "d_clisrv.h"
#include "r_defs.h"
#include "r_data.h"
#include "i_system.h"
#include "md5.h"
#include "lua_script.h"
@ -1375,7 +1376,6 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
void *W_CacheLumpNum(lumpnum_t lumpnum, INT32 tag)
{
return W_CacheLumpNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
@ -1488,12 +1488,31 @@ void *W_CacheLumpName(const char *name, INT32 tag)
// Cache a patch into heap memory, convert the patch format as necessary
//
void W_FlushCachedPatches(void)
{
if (needpatchflush)
{
Z_FreeTag(PU_CACHE);
Z_FreeTag(PU_PATCH);
Z_FreeTag(PU_HUDGFX);
Z_FreeTag(PU_HWRPATCHINFO);
Z_FreeTag(PU_HWRMODELTEXTURE);
Z_FreeTag(PU_HWRCACHE);
Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED);
}
needpatchflush = false;
}
// Software-only compile cache the data without conversion
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
#ifdef HWRENDER
GLPatch_t *grPatch;
#endif
if (needpatchflush)
W_FlushCachedPatches();
if (!TestValidLump(wad, lump))
return NULL;

View file

@ -196,6 +196,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag); // return a patch
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t
void W_UnlockCachedPatch(void *patch);
void W_FlushCachedPatches(void);
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);

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.
@ -946,6 +951,11 @@ INT32 VID_SetMode(INT32 modenum)
return 1;
}
void VID_CheckRenderer(void)
{
// ..............
}
// ========================================================================
// Free the video buffer of the last video mode,
// allocate a new buffer for the video mode to set.

View file

@ -161,6 +161,7 @@ typedef struct
boolean usebuffer = false;
static boolean useinterpic;
static boolean safetorender = true;
static y_buffer_t *y_buffer;
static INT32 intertic;
@ -177,6 +178,7 @@ static void Y_CalculateCompetitionWinners(void);
static void Y_CalculateTimeRaceWinners(void);
static void Y_CalculateMatchWinners(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)
@ -335,8 +337,19 @@ void Y_IntermissionDrawer(void)
}
if (!usebuffer)
// Lactozilla: Renderer switching
if (needpatchrecache)
{
Y_CleanupData();
safetorender = false;
}
if (!usebuffer || !safetorender)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
if (!safetorender)
goto dontdrawbg;
if (useinterpic)
V_DrawScaledPatch(0, 0, 0, interpic);
else if (!usetile)
@ -377,6 +390,7 @@ void Y_IntermissionDrawer(void)
goto skiptallydrawer;
#endif
dontdrawbg:
if (intertype == int_coop)
{
INT32 bonusy;
@ -426,14 +440,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);
@ -662,7 +679,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);
@ -1194,6 +1212,8 @@ void Y_StartIntermission(void)
I_Error("endtic is dirty");
#endif
safetorender = true;
if (!multiplayer)
{
timer = 0;
@ -1249,20 +1269,20 @@ void Y_StartIntermission(void)
data.coop.tics = players[consoleplayer].realtime;
for (i = 0; i < 4; ++i)
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC);
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC);
data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH);
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH);
// get act number
data.coop.actnum = mapheaderinfo[gamemap-1]->actnum;
// get background patches
widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC);
bgpatch = W_CachePatchName("INTERSCR", PU_STATIC);
widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH);
bgpatch = W_CachePatchName("INTERSCR", PU_PATCH);
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
{
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC);
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
useinterpic = true;
usebuffer = false;
}
@ -1320,18 +1340,18 @@ void Y_StartIntermission(void)
Y_AwardSpecialStageBonus();
for (i = 0; i < 2; ++i)
data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_STATIC);
data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_PATCH);
data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC);
data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC);
data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH);
data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH);
// get background tile
bgtile = W_CachePatchName("SPECTILE", PU_STATIC);
bgtile = W_CachePatchName("SPECTILE", PU_PATCH);
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
{
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC);
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
useinterpic = true;
}
else
@ -1343,14 +1363,14 @@ void Y_StartIntermission(void)
// get special stage specific patches
/* if (!stagefailed && ALL7EMERALDS(emeralds))
{
data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_STATIC);
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
{
data.spec.cemerald = W_CachePatchName("CEMERALD", PU_STATIC);
data.spec.cemerald = W_CachePatchName("CEMERALD", PU_PATCH);
data.spec.headx = 48;
data.spec.nowsuper = NULL;
} */
@ -1428,9 +1448,9 @@ void Y_StartIntermission(void)
// get RESULT header
data.match.result =
W_CachePatchName("RESULT", PU_STATIC);
W_CachePatchName("RESULT", PU_PATCH);
bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -1456,9 +1476,9 @@ void Y_StartIntermission(void)
data.match.levelstring[sizeof data.match.levelstring - 1] = '\0';
// get RESULT header
data.match.result = W_CachePatchName("RESULT", PU_STATIC);
data.match.result = W_CachePatchName("RESULT", PU_PATCH);
bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -1495,7 +1515,7 @@ void Y_StartIntermission(void)
data.match.blueflag = bmatcico;
}
bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -1521,7 +1541,7 @@ void Y_StartIntermission(void)
data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0';
// get background tile
bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -2059,7 +2079,8 @@ void Y_EndIntermission(void)
usebuffer = false;
}
#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
@ -2110,5 +2131,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

@ -27,6 +27,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "r_patch.h"
#include "i_system.h" // I_GetFreeMem
#include "i_video.h" // rendermode
#include "z_zone.h"
@ -497,6 +498,35 @@ 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_HWRMODELTEXTURE);
Z_FreeTag(PU_HWRCACHE);
Z_FreeTag(PU_HWRCACHE_UNLOCKED);
Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED);
}
// happens before a renderer switch
void Z_PreparePatchFlush(void)
{
CONS_Debug(DBG_RENDER, "Z_PreparePatchFlush()...\n");
#ifdef ROTSPRITE
R_FreeAllRotSprite();
#endif
}
// starting value of nextcleanup
#define CLEANUPCOUNT 2000

View file

@ -43,6 +43,7 @@ enum
PU_SOUND = 11, // static while playing
PU_MUSIC = 12, // static while playing
PU_HUDGFX = 13, // static until WAD added
PU_PATCH = 14, // static until renderer change
PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache
PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch
@ -142,4 +143,10 @@ 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);
void Z_PreparePatchFlush(void);
#endif