Merge remote-tracking branch 'origin/master' into next

This commit is contained in:
James R 2019-12-30 13:16:53 -08:00
commit fc8c0f8a9a
44 changed files with 1308 additions and 625 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

@ -20,6 +20,11 @@
// Command buffer & command execution
//===================================
enum
{
COM_SAFE = 1,
};
typedef void (*com_func_t)(void);
void COM_AddCommand(const char *name, com_func_t func);
@ -36,10 +41,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);
@ -71,6 +78,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
//==================
@ -100,7 +108,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

@ -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

@ -9746,6 +9746,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

@ -627,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);
@ -6656,7 +6656,13 @@ void HWR_AddCommands(void)
void HWR_AddSessionCommands(void)
{
static boolean alreadycalled = false;
if (alreadycalled)
return;
CV_RegisterVar(&cv_granisotropicmode);
alreadycalled = true;
}
// --------------------------------------------------------------------------
@ -6692,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

@ -245,7 +245,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;
}
@ -262,7 +262,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

@ -3225,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
@ -3321,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

@ -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

@ -729,9 +729,7 @@ typedef struct
{
patch_t *patch[8][ROTANGLES];
boolean cached[8];
#ifdef HWRENDER
aatree_t *hardware_patch[8];
#endif
} rotsprite_t;
#endif
@ -745,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)

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