Patch cache + sprite rotation + renderer switching refactor

This commit is contained in:
Jaime Passos 2020-07-17 00:26:16 -03:00
parent d6b831053f
commit df1111c334
56 changed files with 2347 additions and 1793 deletions

View file

@ -127,6 +127,7 @@ set(SRB2_CORE_RENDER_SOURCES
r_splats.c
r_things.c
r_patch.c
r_rotsprite.c
r_portal.c
r_bsp.h
@ -143,6 +144,8 @@ set(SRB2_CORE_RENDER_SOURCES
r_state.h
r_things.h
r_patch.h
r_rotsprite.h
r_patchtrees.h
r_portal.h
)

View file

@ -470,6 +470,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/r_splats.o \
$(OBJDIR)/r_things.o \
$(OBJDIR)/r_patch.o \
$(OBJDIR)/r_rotsprite.o \
$(OBJDIR)/r_portal.o \
$(OBJDIR)/screen.o \
$(OBJDIR)/v_video.o \

View file

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

View file

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

View file

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

View file

@ -110,8 +110,6 @@ 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;
@ -222,7 +220,6 @@ INT16 wipetypepost = -1;
static void D_Display(void)
{
INT32 setrenderstillneeded = 0;
boolean forcerefresh = false;
static boolean wipe = false;
INT32 wipedefindex = 0;
@ -233,60 +230,26 @@ static void D_Display(void)
if (nodrawers)
return; // for comparative timing/profiling
// 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!
// stop movie if needs to change renderer
if (setrenderneeded && (moviemode == MM_APNG))
M_StopMovie();
// check for change of renderer or screen size (video mode)
// Check for change of renderer or screen size (video mode)
if ((setrenderneeded || setmodeneeded) && !wipe)
{
if (setrenderneeded)
{
CONS_Debug(DBG_RENDER, "setrenderneeded set (%d)\n", setrenderneeded);
setrenderstillneeded = setrenderneeded;
}
SCR_SetMode(); // change video mode
}
if (vid.recalc || setrenderstillneeded)
{
// Recalc the screen
if (vid.recalc)
SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc()
#ifdef HWRENDER
// Shoot! The screen texture was flushed!
if ((rendermode == render_opengl) && (gamestate == GS_INTERMISSION))
usebuffer = false;
#endif
}
// View morph
if (rendermode == render_soft && !splitscreen)
R_CheckViewMorph();
// change the view size if needed
if (setsizeneeded || setrenderstillneeded)
// Change the view size if needed
// Set by changing video mode or renderer
if (setsizeneeded)
{
R_ExecuteSetViewSize();
R_SetViewSize();
forcerefresh = true; // force background redraw
}
// Lactozilla: Renderer switching
D_CheckRendererState();
// draw buffered stuff to screen
// Used only by linux GGI version
I_UpdateNoBlit();
@ -426,11 +389,11 @@ static void D_Display(void)
{
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
objectsdrawn = 0;
#ifdef HWRENDER
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(0, &players[displayplayer]);
else
#endif
#endif
if (rendermode != render_none)
R_RenderPlayerView(&players[displayplayer]);
}
@ -438,11 +401,11 @@ static void D_Display(void)
// render the second screen
if (splitscreen && players[secondarydisplayplayer].mo)
{
#ifdef HWRENDER
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
else
#endif
#endif
if (rendermode != render_none)
{
viewwindowy = vid.height / 2;
@ -595,13 +558,13 @@ static void D_Display(void)
s[sizeof s - 1] = '\0';
snprintf(s, sizeof s - 1, "get %d b/s", getbps);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-40, V_YELLOWMAP, s);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-32-40, V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "send %d b/s", sendbps);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-30, V_YELLOWMAP, s);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-32-30, V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "GameMiss %.2f%%", gamelostpercent);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-20, V_YELLOWMAP, s);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-32-20, V_YELLOWMAP, s);
snprintf(s, sizeof s - 1, "SysMiss %.2f%%", lostpercent);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-32-10, V_YELLOWMAP, s);
}
if (cv_renderstats.value)
@ -679,26 +642,6 @@ static void D_Display(void)
I_FinishUpdate(); // page flip or blit buffer
rs_swaptime = I_GetTimeMicros() - rs_swaptime;
}
needpatchflush = false;
needpatchrecache = false;
}
// Check the renderer's state
// after a possible renderer switch.
void D_CheckRendererState(void)
{
// flush all patches from memory
if (needpatchflush)
{
Z_FlushCachedPatches();
needpatchflush = false;
}
// some patches have been freed,
// so cache them again
if (needpatchrecache)
R_ReloadHUDGraphics();
}
// =========================================================================
@ -723,7 +666,8 @@ void D_SRB2Loop(void)
oldentertics = I_GetTime();
// end of loading screen: CONS_Printf() will no more call FinishUpdate()
// end of loading screen: CONS_Printf() will no more call I_FinishUpdate()
con_refresh = false;
con_startup = false;
// make sure to do a d_display to init mode _before_ load a level
@ -1423,28 +1367,27 @@ void D_SRB2Main(void)
G_LoadGameData();
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // Regenerate Modelist according to cv_fullscreen
// Under SDL2, we just use the windowed modes list, and scale in windowed fullscreen.
allow_fullscreen = true;
#endif
// set user default mode or mode set at cmdline
SCR_CheckDefaultMode();
// Lactozilla: Does the render mode need to change?
if ((setrenderneeded != 0) && (setrenderneeded != rendermode))
// Check if the render mode needs to change.
if (setrenderneeded)
{
CONS_Printf(M_GetText("Switching the renderer...\n"));
Z_PreparePatchFlush();
// set needpatchflush / needpatchrecache true for D_CheckRendererState
needpatchflush = true;
needpatchrecache = true;
// Switch the renderer in the interface
if (VID_CheckRenderer())
con_refresh = true; // Allow explicit screen refresh again
// Set cv_renderer to the new render mode
VID_CheckRenderer();
SCR_ChangeRendererCVars(rendermode);
// check the renderer's state
D_CheckRendererState();
CV_StealthSetValue(&cv_renderer, rendermode);
#ifdef HWRENDER
CV_StealthSetValue(&cv_newrenderer, rendermode);
#endif
}
wipegamestate = gamestate;

View file

@ -1041,11 +1041,6 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
spriteinfo_t *info = Z_Calloc(sizeof(spriteinfo_t), PU_STATIC, NULL);
info->available = true;
#ifdef ROTSPRITE
if ((sprites != NULL) && (!sprite2))
R_FreeSingleRotSprite(&sprites[num]);
#endif
do
{
lastline = f->curpos;
@ -1164,19 +1159,18 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
if (sprite2)
{
INT32 i;
if (!foundskins)
{
deh_warning("Sprite2 %s: no skins specified", spr2names[num]);
break;
}
for (i = 0; i < foundskins; i++)
{
size_t skinnum = skinnumbers[i];
skin_t *skin = &skins[skinnum];
spriteinfo_t *sprinfo = skin->sprinfo;
#ifdef ROTSPRITE
R_FreeSkinRotSprite(skinnum);
#endif
M_Memcpy(&sprinfo[num], info, sizeof(spriteinfo_t));
}
}
@ -9951,6 +9945,11 @@ struct {
{"ANGLE_337h",ANGLE_337h},
{"ANGLE_MAX",ANGLE_MAX},
// Sprite rotation
{"ROTANGLES",ROTANGLES},
{"ROTANGDIFF",ROTANGDIFF},
{"FEETADJUST",FEETADJUST},
// P_Chase directions (dirtype_t)
{"DI_NODIR",DI_NODIR},
{"DI_EAST",DI_EAST},
@ -9963,7 +9962,7 @@ struct {
{"DI_SOUTHEAST",DI_SOUTHEAST},
{"NUMDIRS",NUMDIRS},
// Sprite rotation axis (rotaxis_t)
// Sprite rotation axes (rotaxis_t)
{"ROTAXIS_X",ROTAXIS_X},
{"ROTAXIS_Y",ROTAXIS_Y},
{"ROTAXIS_Z",ROTAXIS_Z},

View file

@ -378,11 +378,13 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette)
return 1;
}
void VID_CheckRenderer(void) {}
boolean VID_CheckRenderer(void)
{
return false;
}
void VID_CheckGLLoaded(rendermode_t oldrender) {}
// converts a segm:offs 32bit pair to a 32bit flat ptr
#if 0
void *VID_ExtraFarToLinear (void *ptr)
@ -739,7 +741,7 @@ static INT32 VGA_InitMode (viddef_t *lvid, vmode_t *currentmodep)
// here it is the standard VGA 64k window, not an LFB
// (you could have 320x200x256c with LFB in the vesa modes)
lvid->direct = (UINT8 *) real2ptr (0xa0000);
lvid->u.numpages = 1;
lvid->numpages = 1;
lvid->bpp = currentmodep->bytesperpixel;
return 1;
@ -773,7 +775,7 @@ INT32 VID_VesaInitMode (viddef_t *lvid, vmode_t *currentmodep)
#endif
//added:20-01-98:no page flipping now... TO DO!!!
lvid->u.numpages = 1;
lvid->numpages = 1;
// clean up any old vid buffer lying around, alloc new if needed
if (!VID_FreeAndAllocVidbuffer (lvid))

View file

@ -629,13 +629,11 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
#define SECTORSPECIALSAFTERTHINK
/// 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...)
#define ROTANGDIFF (360 / ROTANGLES)
#define ROTSPRITE_RENDER_PATCHES
/// PNG support
#ifndef HAVE_PNG

View file

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

View file

@ -100,21 +100,21 @@ INT16 curttloop;
UINT16 curtttics;
// ttmode old
static patch_t *ttbanner; // white banner with "robo blast" and "2"
static patch_t *ttwing; // wing background
static patch_t *ttsonic; // "SONIC"
static patch_t *ttswave1; // Title Sonics
static patch_t *ttswave2;
static patch_t *ttswip1;
static patch_t *ttsprep1;
static patch_t *ttsprep2;
static patch_t *ttspop1;
static patch_t *ttspop2;
static patch_t *ttspop3;
static patch_t *ttspop4;
static patch_t *ttspop5;
static patch_t *ttspop6;
static patch_t *ttspop7;
static patch_t **ttbanner; // white banner with "robo blast" and "2"
static patch_t **ttwing; // wing background
static patch_t **ttsonic; // "SONIC"
static patch_t **ttswave1; // Title Sonics
static patch_t **ttswave2;
static patch_t **ttswip1;
static patch_t **ttsprep1;
static patch_t **ttsprep2;
static patch_t **ttspop1;
static patch_t **ttspop2;
static patch_t **ttspop3;
static patch_t **ttspop4;
static patch_t **ttspop5;
static patch_t **ttspop6;
static patch_t **ttspop7;
// ttmode alacroix
static SINT8 testttscale = 0;
@ -122,51 +122,51 @@ static SINT8 activettscale = 0;
boolean ttavailable[6];
boolean ttloaded[6];
static patch_t *ttribb[6][TTMAX_ALACROIX];
static patch_t *ttsont[6][TTMAX_ALACROIX];
static patch_t *ttrobo[6][TTMAX_ALACROIX];
static patch_t *tttwot[6][TTMAX_ALACROIX];
static patch_t *ttembl[6][TTMAX_ALACROIX];
static patch_t *ttrbtx[6][TTMAX_ALACROIX];
static patch_t *ttsoib[6][TTMAX_ALACROIX];
static patch_t *ttsoif[6][TTMAX_ALACROIX];
static patch_t *ttsoba[6][TTMAX_ALACROIX];
static patch_t *ttsobk[6][TTMAX_ALACROIX];
static patch_t *ttsodh[6][TTMAX_ALACROIX];
static patch_t *tttaib[6][TTMAX_ALACROIX];
static patch_t *tttaif[6][TTMAX_ALACROIX];
static patch_t *tttaba[6][TTMAX_ALACROIX];
static patch_t *tttabk[6][TTMAX_ALACROIX];
static patch_t *tttabt[6][TTMAX_ALACROIX];
static patch_t *tttaft[6][TTMAX_ALACROIX];
static patch_t *ttknib[6][TTMAX_ALACROIX];
static patch_t *ttknif[6][TTMAX_ALACROIX];
static patch_t *ttknba[6][TTMAX_ALACROIX];
static patch_t *ttknbk[6][TTMAX_ALACROIX];
static patch_t *ttkndh[6][TTMAX_ALACROIX];
static patch_t **ttribb[6][TTMAX_ALACROIX];
static patch_t **ttsont[6][TTMAX_ALACROIX];
static patch_t **ttrobo[6][TTMAX_ALACROIX];
static patch_t **tttwot[6][TTMAX_ALACROIX];
static patch_t **ttembl[6][TTMAX_ALACROIX];
static patch_t **ttrbtx[6][TTMAX_ALACROIX];
static patch_t **ttsoib[6][TTMAX_ALACROIX];
static patch_t **ttsoif[6][TTMAX_ALACROIX];
static patch_t **ttsoba[6][TTMAX_ALACROIX];
static patch_t **ttsobk[6][TTMAX_ALACROIX];
static patch_t **ttsodh[6][TTMAX_ALACROIX];
static patch_t **tttaib[6][TTMAX_ALACROIX];
static patch_t **tttaif[6][TTMAX_ALACROIX];
static patch_t **tttaba[6][TTMAX_ALACROIX];
static patch_t **tttabk[6][TTMAX_ALACROIX];
static patch_t **tttabt[6][TTMAX_ALACROIX];
static patch_t **tttaft[6][TTMAX_ALACROIX];
static patch_t **ttknib[6][TTMAX_ALACROIX];
static patch_t **ttknif[6][TTMAX_ALACROIX];
static patch_t **ttknba[6][TTMAX_ALACROIX];
static patch_t **ttknbk[6][TTMAX_ALACROIX];
static patch_t **ttkndh[6][TTMAX_ALACROIX];
#define TTEMBL (ttembl[activettscale-1])
#define TTRIBB (ttribb[activettscale-1])
#define TTSONT (ttsont[activettscale-1])
#define TTROBO (ttrobo[activettscale-1])
#define TTTWOT (tttwot[activettscale-1])
#define TTRBTX (ttrbtx[activettscale-1])
#define TTSOIB (ttsoib[activettscale-1])
#define TTSOIF (ttsoif[activettscale-1])
#define TTSOBA (ttsoba[activettscale-1])
#define TTSOBK (ttsobk[activettscale-1])
#define TTSODH (ttsodh[activettscale-1])
#define TTTAIB (tttaib[activettscale-1])
#define TTTAIF (tttaif[activettscale-1])
#define TTTABA (tttaba[activettscale-1])
#define TTTABK (tttabk[activettscale-1])
#define TTTABT (tttabt[activettscale-1])
#define TTTAFT (tttaft[activettscale-1])
#define TTKNIB (ttknib[activettscale-1])
#define TTKNIF (ttknif[activettscale-1])
#define TTKNBA (ttknba[activettscale-1])
#define TTKNBK (ttknbk[activettscale-1])
#define TTKNDH (ttkndh[activettscale-1])
#define TTEMBL *(ttembl[activettscale-1])
#define TTRIBB *(ttribb[activettscale-1])
#define TTSONT *(ttsont[activettscale-1])
#define TTROBO *(ttrobo[activettscale-1])
#define TTTWOT *(tttwot[activettscale-1])
#define TTRBTX *(ttrbtx[activettscale-1])
#define TTSOIB *(ttsoib[activettscale-1])
#define TTSOIF *(ttsoif[activettscale-1])
#define TTSOBA *(ttsoba[activettscale-1])
#define TTSOBK *(ttsobk[activettscale-1])
#define TTSODH *(ttsodh[activettscale-1])
#define TTTAIB *(tttaib[activettscale-1])
#define TTTAIF *(tttaif[activettscale-1])
#define TTTABA *(tttaba[activettscale-1])
#define TTTABK *(tttabk[activettscale-1])
#define TTTABT *(tttabt[activettscale-1])
#define TTTAFT *(tttaft[activettscale-1])
#define TTKNIB *(ttknib[activettscale-1])
#define TTKNIF *(ttknif[activettscale-1])
#define TTKNBA *(ttknba[activettscale-1])
#define TTKNBK *(ttknbk[activettscale-1])
#define TTKNDH *(ttkndh[activettscale-1])
static boolean sonic_blink = false;
static boolean sonic_blink_twice = false;
@ -185,18 +185,18 @@ static INT32 knux_idle_start = 0;
static INT32 knux_idle_end = 0;
// ttmode user
static patch_t *ttuser[TTMAX_USER];
static patch_t **ttuser[TTMAX_USER];
static INT32 ttuser_count = 0;
static boolean goodending;
static patch_t *endbrdr[2]; // border - blue, white, pink - where have i seen those colours before?
static patch_t *endbgsp[3]; // nebula, sun, planet
static patch_t *endegrk[2]; // eggrock - replaced midway through good ending
static patch_t *endfwrk[3]; // firework - replaced with skin when good ending
static patch_t *endspkl[3]; // sparkle
static patch_t *endglow[2]; // glow aura - replaced with black rock's midway through good ending
static patch_t *endxpld[4]; // mini explosion
static patch_t *endescp[5]; // escape pod + flame
static patch_t **endbrdr[2]; // border - blue, white, pink - where have i seen those colours before?
static patch_t **endbgsp[3]; // nebula, sun, planet
static patch_t **endegrk[2]; // eggrock - replaced midway through good ending
static patch_t **endfwrk[3]; // firework - replaced with skin when good ending
static patch_t **endspkl[3]; // sparkle
static patch_t **endglow[2]; // glow aura - replaced with black rock's midway through good ending
static patch_t **endxpld[4]; // mini explosion
static patch_t **endescp[5]; // escape pod + flame
static INT32 sparkloffs[3][2]; // eggrock explosions/blackrock sparkles
static INT32 sparklloop;
@ -1772,32 +1772,32 @@ void F_GameEvaluationTicker(void)
static void F_CacheEnding(void)
{
endbrdr[1] = W_CachePatchName("ENDBRDR1", PU_PATCH);
endbrdr[1] = (patch_t **)W_GetPatchPointerFromName("ENDBRDR1", PU_PATCH);
endegrk[0] = W_CachePatchName("ENDEGRK0", PU_PATCH);
endegrk[1] = W_CachePatchName("ENDEGRK1", PU_PATCH);
endegrk[0] = (patch_t **)W_GetPatchPointerFromName("ENDEGRK0", PU_PATCH);
endegrk[1] = (patch_t **)W_GetPatchPointerFromName("ENDEGRK1", PU_PATCH);
endglow[0] = W_CachePatchName("ENDGLOW0", PU_PATCH);
endglow[1] = W_CachePatchName("ENDGLOW1", PU_PATCH);
endglow[0] = (patch_t **)W_GetPatchPointerFromName("ENDGLOW0", PU_PATCH);
endglow[1] = (patch_t **)W_GetPatchPointerFromName("ENDGLOW1", PU_PATCH);
endbgsp[0] = W_CachePatchName("ENDBGSP0", PU_PATCH);
endbgsp[1] = W_CachePatchName("ENDBGSP1", PU_PATCH);
endbgsp[2] = W_CachePatchName("ENDBGSP2", PU_PATCH);
endbgsp[0] = (patch_t **)W_GetPatchPointerFromName("ENDBGSP0", PU_PATCH);
endbgsp[1] = (patch_t **)W_GetPatchPointerFromName("ENDBGSP1", PU_PATCH);
endbgsp[2] = (patch_t **)W_GetPatchPointerFromName("ENDBGSP2", PU_PATCH);
endspkl[0] = W_CachePatchName("ENDSPKL0", PU_PATCH);
endspkl[1] = W_CachePatchName("ENDSPKL1", PU_PATCH);
endspkl[2] = W_CachePatchName("ENDSPKL2", PU_PATCH);
endspkl[0] = (patch_t **)W_GetPatchPointerFromName("ENDSPKL0", PU_PATCH);
endspkl[1] = (patch_t **)W_GetPatchPointerFromName("ENDSPKL1", PU_PATCH);
endspkl[2] = (patch_t **)W_GetPatchPointerFromName("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);
endxpld[0] = (patch_t **)W_GetPatchPointerFromName("ENDXPLD0", PU_PATCH);
endxpld[1] = (patch_t **)W_GetPatchPointerFromName("ENDXPLD1", PU_PATCH);
endxpld[2] = (patch_t **)W_GetPatchPointerFromName("ENDXPLD2", PU_PATCH);
endxpld[3] = (patch_t **)W_GetPatchPointerFromName("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);
endescp[0] = (patch_t **)W_GetPatchPointerFromName("ENDESCP0", PU_PATCH);
endescp[1] = (patch_t **)W_GetPatchPointerFromName("ENDESCP1", PU_PATCH);
endescp[2] = (patch_t **)W_GetPatchPointerFromName("ENDESCP2", PU_PATCH);
endescp[3] = (patch_t **)W_GetPatchPointerFromName("ENDESCP3", PU_PATCH);
endescp[4] = (patch_t **)W_GetPatchPointerFromName("ENDESCP4", PU_PATCH);
// so we only need to check once
if ((goodending = ALL7EMERALDS(emeralds)))
@ -1810,41 +1810,41 @@ static void F_CacheEnding(void)
sprdef = &skins[skinnum].sprites[SPR2_XTRA];
// character head, skin specific
sprframe = &sprdef->spriteframes[XTRA_ENDING];
endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
endfwrk[0] = (patch_t **)W_GetPatchPointer(sprframe->lumppat[0], PU_PATCH);
sprframe = &sprdef->spriteframes[XTRA_ENDING+1];
endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
endfwrk[1] = (patch_t **)W_GetPatchPointer(sprframe->lumppat[0], PU_PATCH);
sprframe = &sprdef->spriteframes[XTRA_ENDING+2];
endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
endfwrk[2] = (patch_t **)W_GetPatchPointer(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);
endfwrk[0] = (patch_t **)W_GetPatchPointerFromName("ENDFWRK3", PU_PATCH);
endfwrk[1] = (patch_t **)W_GetPatchPointerFromName("ENDFWRK4", PU_PATCH);
endfwrk[2] = (patch_t **)W_GetPatchPointerFromName("ENDFWRK5", PU_PATCH);
}
endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_PATCH);
endbrdr[0] = (patch_t **)W_GetPatchPointerFromName("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);
endfwrk[0] = (patch_t **)W_GetPatchPointerFromName("ENDFWRK0", PU_PATCH);
endfwrk[1] = (patch_t **)W_GetPatchPointerFromName("ENDFWRK1", PU_PATCH);
endfwrk[2] = (patch_t **)W_GetPatchPointerFromName("ENDFWRK2", PU_PATCH);
endbrdr[0] = W_CachePatchName("ENDBRDR0", PU_LEVEL);
endbrdr[0] = (patch_t **)W_GetPatchPointerFromName("ENDBRDR0", PU_LEVEL);
}
}
static void F_CacheGoodEnding(void)
{
endegrk[0] = W_CachePatchName("ENDEGRK2", PU_PATCH);
endegrk[1] = W_CachePatchName("ENDEGRK3", PU_PATCH);
endegrk[0] = (patch_t **)W_GetPatchPointerFromName("ENDEGRK2", PU_PATCH);
endegrk[1] = (patch_t **)W_GetPatchPointerFromName("ENDEGRK3", PU_PATCH);
endglow[0] = W_CachePatchName("ENDGLOW2", PU_PATCH);
endglow[1] = W_CachePatchName("ENDGLOW3", PU_PATCH);
endglow[0] = (patch_t **)W_GetPatchPointerFromName("ENDGLOW2", PU_PATCH);
endglow[1] = (patch_t **)W_GetPatchPointerFromName("ENDGLOW3", PU_PATCH);
endxpld[0] = W_CachePatchName("ENDEGRK4", PU_PATCH);
endxpld[0] = (patch_t **)W_GetPatchPointerFromName("ENDEGRK4", PU_PATCH);
}
void F_StartEnding(void)
@ -1901,13 +1901,6 @@ void F_EndingDrawer(void)
INT32 x, y, i, j, parallaxticker;
patch_t *rockpat;
if (needpatchrecache)
{
F_CacheEnding();
if (goodending && finalecount >= INFLECTIONPOINT) // time to swap some assets
F_CacheGoodEnding();
}
if (!goodending || finalecount < INFLECTIONPOINT)
rockpat = W_CachePatchName("ROID0000", PU_PATCH);
else
@ -1934,25 +1927,25 @@ void F_EndingDrawer(void)
if (trans < 0)
{
trans = -trans;
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[0]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, *endbrdr[0]);
}
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, trans<<V_ALPHASHIFT, endbrdr[1]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, trans<<V_ALPHASHIFT, *endbrdr[1]);
}
else if (finalecount == 20)
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[0]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, *endbrdr[0]);
}
else if (goodending && (parallaxticker == -2 || !parallaxticker))
{
V_DrawFill(24, 24, BASEVIDWIDTH-48, BASEVIDHEIGHT-48, 0);
V_DrawFixedPatch(x+i, y+j, FRACUNIT, 0, endegrk[0],
V_DrawFixedPatch(x+i, y+j, FRACUNIT, 0, *endegrk[0],
R_GetTranslationColormap(TC_BLINK, SKINCOLOR_BLACK, GTC_CACHE));
//V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[1]);
//V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, *endbrdr[1]);
}
else if (goodending && parallaxticker == -1)
{
V_DrawFixedPatch(x+i, y+j, FRACUNIT, 0, rockpat,
R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE));
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, endbrdr[1]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, 0, *endbrdr[1]);
}
else
{
@ -1962,14 +1955,14 @@ void F_EndingDrawer(void)
if (parallaxticker < 75) // f background's supposed to be visible
{
V_DrawFixedPatch(-(x/10), -(y/10), FRACUNIT, 0, endbgsp[0], NULL); // nebula
V_DrawFixedPatch(-(x/5), -(y/5), FRACUNIT, 0, endbgsp[1], NULL); // sun
V_DrawFixedPatch( 0, -(y/2), FRACUNIT, 0, endbgsp[2], NULL); // planet
V_DrawFixedPatch(-(x/10), -(y/10), FRACUNIT, 0, *endbgsp[0], NULL); // nebula
V_DrawFixedPatch(-(x/5), -(y/5), FRACUNIT, 0, *endbgsp[1], NULL); // sun
V_DrawFixedPatch( 0, -(y/2), FRACUNIT, 0, *endbgsp[2], NULL); // planet
// player's escape pod
V_DrawFixedPatch((200<<FRACBITS)+(finalecount<<(FRACBITS-2)),
(100<<FRACBITS)+(finalecount<<(FRACBITS-2)),
FRACUNIT, 0, endescp[4], NULL);
FRACUNIT, 0, *endescp[4], NULL);
if (parallaxticker > -19)
{
INT32 trans = (-parallaxticker)>>1;
@ -1977,7 +1970,7 @@ void F_EndingDrawer(void)
trans = 0;
V_DrawFixedPatch((200<<FRACBITS)+(finalecount<<(FRACBITS-2)),
(100<<FRACBITS)+(finalecount<<(FRACBITS-2)),
FRACUNIT, trans<<V_ALPHASHIFT, endescp[(finalecount/2)&3], NULL);
FRACUNIT, trans<<V_ALPHASHIFT, *endescp[(finalecount/2)&3], NULL);
}
if (goodending && parallaxticker > 0) // gunchedrock
@ -2003,21 +1996,21 @@ void F_EndingDrawer(void)
y <<= 1;
// center detritrus
V_DrawFixedPatch(i-x, j-y, FRACUNIT, 0, endegrk[0], colormap);
V_DrawFixedPatch(i-x, j-y, FRACUNIT, 0, *endegrk[0], colormap);
if (trans < 10)
V_DrawFixedPatch(i-x, j-y, FRACUNIT, trans<<V_ALPHASHIFT, endegrk[0], NULL);
V_DrawFixedPatch(i-x, j-y, FRACUNIT, trans<<V_ALPHASHIFT, *endegrk[0], NULL);
// ring detritrus
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(2*x), (30*(FRACUNIT-scale))+j-(2*y) - ((7<<FRACBITS)/2), scale, 0, endegrk[1], colormap);
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(2*x), (30*(FRACUNIT-scale))+j-(2*y) - ((7<<FRACBITS)/2), scale, 0, *endegrk[1], colormap);
if (trans < 10)
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(2*x), (30*(FRACUNIT-scale))+j-(2*y), scale, trans<<V_ALPHASHIFT, endegrk[1], NULL);
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(2*x), (30*(FRACUNIT-scale))+j-(2*y), scale, trans<<V_ALPHASHIFT, *endegrk[1], NULL);
scale += ((parallaxticker-10)<<7);
// shard detritrus
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(x/2), (30*(FRACUNIT-scale))+j-(y/2) - ((7<<FRACBITS)/2), scale, 0, endxpld[0], colormap);
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(x/2), (30*(FRACUNIT-scale))+j-(y/2) - ((7<<FRACBITS)/2), scale, 0, *endxpld[0], colormap);
if (trans < 10)
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(x/2), (30*(FRACUNIT-scale))+j-(y/2), scale, trans<<V_ALPHASHIFT, endxpld[0], NULL);
V_DrawFixedPatch((30*(FRACUNIT-scale))+i-(x/2), (30*(FRACUNIT-scale))+j-(y/2), scale, trans<<V_ALPHASHIFT, *endxpld[0], NULL);
}
}
else if (goodending)
@ -2071,7 +2064,7 @@ void F_EndingDrawer(void)
trans = (-parallaxticker/4) + 5;
if (trans < 0)
trans = 0;
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, endglow[(finalecount & 1) ? 0 : 1], NULL);
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, *endglow[(finalecount & 1) ? 0 : 1], NULL);
}
if (goodending && finalecount > INFLECTIONPOINT)
@ -2105,7 +2098,7 @@ void F_EndingDrawer(void)
if ((-parallaxticker/2) < -5)
colormap[1] = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
V_DrawFixedPatch(x, y, scale, 0, endegrk[0], colormap[1]);
V_DrawFixedPatch(x, y, scale, 0, *endegrk[0], colormap[1]);
if ((-parallaxticker/2) < 5)
{
@ -2113,7 +2106,7 @@ void F_EndingDrawer(void)
if (trans < 0)
trans = -trans;
if (trans < 10)
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, endegrk[1], NULL);
V_DrawFixedPatch(x, y, scale, trans<<V_ALPHASHIFT, *endegrk[1], NULL);
}
}
}
@ -2139,7 +2132,7 @@ void F_EndingDrawer(void)
colormap = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
if ((frame = ((parallaxticker & 1) ? 1 : 0) + (parallaxticker/TICRATE)) < 3)
V_DrawFixedPatch(x, y, scale, 0, endfwrk[frame], colormap);
V_DrawFixedPatch(x, y, scale, 0, *endfwrk[frame], colormap);
}
// explosions
@ -2151,7 +2144,7 @@ void F_EndingDrawer(void)
y = ((((BASEVIDHEIGHT-82)/2)+12)<<FRACBITS) + ((boomtime*7)<<FRACBITS)/INFLECTIONPOINT;
V_DrawFixedPatch(x + sparkloffs[0][0], y + sparkloffs[0][1],
FRACUNIT, 0, endxpld[sparklloop/4], NULL);
FRACUNIT, 0, *endxpld[sparklloop/4], NULL);
}
// initial fade
@ -2164,11 +2157,11 @@ void F_EndingDrawer(void)
if (borderstuff)
trans = (10*parallaxticker)/(3*TICRATE);
if (trans < 10)
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, trans<<V_ALPHASHIFT, endbrdr[0]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, trans<<V_ALPHASHIFT, *endbrdr[0]);
if (borderstuff && parallaxticker < 11)
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, (parallaxticker-1)<<V_ALPHASHIFT, endbrdr[1]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, (parallaxticker-1)<<V_ALPHASHIFT, *endbrdr[1]);
else if (goodending && finalecount > INFLECTIONPOINT && finalecount < INFLECTIONPOINT+10)
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, (finalecount-INFLECTIONPOINT)<<V_ALPHASHIFT, endbrdr[1]);
V_DrawScaledPatch(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, (finalecount-INFLECTIONPOINT)<<V_ALPHASHIFT, *endbrdr[1]);
}
// emeralds and emerald accessories
@ -2233,7 +2226,7 @@ void F_EndingDrawer(void)
// if j == 0 - alternate between 0 and 1
// 1 - 1 and 2
// 2 - 2 and not rendered
V_DrawFixedPatch(x, y, FRACUNIT, 0, endspkl[(j - ((sparklloop & 1) ? 0 : 1))], colormap);
V_DrawFixedPatch(x, y, FRACUNIT, 0, *endspkl[(j - ((sparklloop & 1) ? 0 : 1))], colormap);
j--;
}
@ -2438,7 +2431,7 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname)
lumpnum = W_CheckNumForName(name); \
if (lumpnum != LUMPERROR) \
{ \
arr[0] = W_CachePatchName(name, PU_LEVEL); \
arr[0] = (patch_t **)W_GetPatchPointerFromName(name, PU_LEVEL); \
arr[min(1, maxf-1)] = 0; \
} \
else if (strlen(name) <= 6) \
@ -2451,7 +2444,7 @@ else if (strlen(name) <= 6) \
lumpname[8] = 0; \
lumpnum = W_CheckNumForName(lumpname); \
if (lumpnum != LUMPERROR) \
arr[i] = W_CachePatchName(lumpname, PU_LEVEL); \
arr[i] = (patch_t **)W_GetPatchPointerFromName(lumpname, PU_LEVEL); \
else \
break; \
} \
@ -2466,21 +2459,21 @@ static void F_CacheTitleScreen(void)
{
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);
ttbanner = (patch_t **)W_GetPatchPointerFromName("TTBANNER", PU_LEVEL);
ttwing = (patch_t **)W_GetPatchPointerFromName("TTWING", PU_LEVEL);
ttsonic = (patch_t **)W_GetPatchPointerFromName("TTSONIC", PU_LEVEL);
ttswave1 = (patch_t **)W_GetPatchPointerFromName("TTSWAVE1", PU_LEVEL);
ttswave2 = (patch_t **)W_GetPatchPointerFromName("TTSWAVE2", PU_LEVEL);
ttswip1 = (patch_t **)W_GetPatchPointerFromName("TTSWIP1", PU_LEVEL);
ttsprep1 = (patch_t **)W_GetPatchPointerFromName("TTSPREP1", PU_LEVEL);
ttsprep2 = (patch_t **)W_GetPatchPointerFromName("TTSPREP2", PU_LEVEL);
ttspop1 = (patch_t **)W_GetPatchPointerFromName("TTSPOP1", PU_LEVEL);
ttspop2 = (patch_t **)W_GetPatchPointerFromName("TTSPOP2", PU_LEVEL);
ttspop3 = (patch_t **)W_GetPatchPointerFromName("TTSPOP3", PU_LEVEL);
ttspop4 = (patch_t **)W_GetPatchPointerFromName("TTSPOP4", PU_LEVEL);
ttspop5 = (patch_t **)W_GetPatchPointerFromName("TTSPOP5", PU_LEVEL);
ttspop6 = (patch_t **)W_GetPatchPointerFromName("TTSPOP6", PU_LEVEL);
ttspop7 = (patch_t **)W_GetPatchPointerFromName("TTSPOP7", PU_LEVEL);
break;
// don't load alacroix gfx yet; we do that upon first draw.
@ -2608,28 +2601,28 @@ static void F_UnloadAlacroixGraphics(SINT8 oldttscale)
oldttscale--; // zero-based index
for (i = 0; i < TTMAX_ALACROIX; i++)
{
if(ttembl[oldttscale][i]) { Z_Free(ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; }
if(ttribb[oldttscale][i]) { Z_Free(ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; }
if(ttsont[oldttscale][i]) { Z_Free(ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; }
if(ttrobo[oldttscale][i]) { Z_Free(ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; }
if(tttwot[oldttscale][i]) { Z_Free(tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; }
if(ttrbtx[oldttscale][i]) { Z_Free(ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; }
if(ttsoib[oldttscale][i]) { Z_Free(ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; }
if(ttsoif[oldttscale][i]) { Z_Free(ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; }
if(ttsoba[oldttscale][i]) { Z_Free(ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; }
if(ttsobk[oldttscale][i]) { Z_Free(ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; }
if(ttsodh[oldttscale][i]) { Z_Free(ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; }
if(tttaib[oldttscale][i]) { Z_Free(tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; }
if(tttaif[oldttscale][i]) { Z_Free(tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; }
if(tttaba[oldttscale][i]) { Z_Free(tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; }
if(tttabk[oldttscale][i]) { Z_Free(tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; }
if(tttabt[oldttscale][i]) { Z_Free(tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; }
if(tttaft[oldttscale][i]) { Z_Free(tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; }
if(ttknib[oldttscale][i]) { Z_Free(ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; }
if(ttknif[oldttscale][i]) { Z_Free(ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; }
if(ttknba[oldttscale][i]) { Z_Free(ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; }
if(ttknbk[oldttscale][i]) { Z_Free(ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; }
if(ttkndh[oldttscale][i]) { Z_Free(ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; }
if(ttembl[oldttscale][i]) { Z_Free(*ttembl[oldttscale][i]); ttembl[oldttscale][i] = 0; }
if(ttribb[oldttscale][i]) { Z_Free(*ttribb[oldttscale][i]); ttribb[oldttscale][i] = 0; }
if(ttsont[oldttscale][i]) { Z_Free(*ttsont[oldttscale][i]); ttsont[oldttscale][i] = 0; }
if(ttrobo[oldttscale][i]) { Z_Free(*ttrobo[oldttscale][i]); ttrobo[oldttscale][i] = 0; }
if(tttwot[oldttscale][i]) { Z_Free(*tttwot[oldttscale][i]); tttwot[oldttscale][i] = 0; }
if(ttrbtx[oldttscale][i]) { Z_Free(*ttrbtx[oldttscale][i]); ttrbtx[oldttscale][i] = 0; }
if(ttsoib[oldttscale][i]) { Z_Free(*ttsoib[oldttscale][i]); ttsoib[oldttscale][i] = 0; }
if(ttsoif[oldttscale][i]) { Z_Free(*ttsoif[oldttscale][i]); ttsoif[oldttscale][i] = 0; }
if(ttsoba[oldttscale][i]) { Z_Free(*ttsoba[oldttscale][i]); ttsoba[oldttscale][i] = 0; }
if(ttsobk[oldttscale][i]) { Z_Free(*ttsobk[oldttscale][i]); ttsobk[oldttscale][i] = 0; }
if(ttsodh[oldttscale][i]) { Z_Free(*ttsodh[oldttscale][i]); ttsodh[oldttscale][i] = 0; }
if(tttaib[oldttscale][i]) { Z_Free(*tttaib[oldttscale][i]); tttaib[oldttscale][i] = 0; }
if(tttaif[oldttscale][i]) { Z_Free(*tttaif[oldttscale][i]); tttaif[oldttscale][i] = 0; }
if(tttaba[oldttscale][i]) { Z_Free(*tttaba[oldttscale][i]); tttaba[oldttscale][i] = 0; }
if(tttabk[oldttscale][i]) { Z_Free(*tttabk[oldttscale][i]); tttabk[oldttscale][i] = 0; }
if(tttabt[oldttscale][i]) { Z_Free(*tttabt[oldttscale][i]); tttabt[oldttscale][i] = 0; }
if(tttaft[oldttscale][i]) { Z_Free(*tttaft[oldttscale][i]); tttaft[oldttscale][i] = 0; }
if(ttknib[oldttscale][i]) { Z_Free(*ttknib[oldttscale][i]); ttknib[oldttscale][i] = 0; }
if(ttknif[oldttscale][i]) { Z_Free(*ttknif[oldttscale][i]); ttknif[oldttscale][i] = 0; }
if(ttknba[oldttscale][i]) { Z_Free(*ttknba[oldttscale][i]); ttknba[oldttscale][i] = 0; }
if(ttknbk[oldttscale][i]) { Z_Free(*ttknbk[oldttscale][i]); ttknbk[oldttscale][i] = 0; }
if(ttkndh[oldttscale][i]) { Z_Free(*ttkndh[oldttscale][i]); ttkndh[oldttscale][i] = 0; }
}
ttloaded[oldttscale] = false;
}
@ -2706,17 +2699,12 @@ static void F_FigureActiveTtScale(void)
SINT8 newttscale = max(1, min(6, vid.dupx));
SINT8 oldttscale = activettscale;
if (needpatchrecache)
ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0;
else
{
if (newttscale == testttscale)
return;
if (newttscale == testttscale)
return;
// We have a new ttscale, so load gfx
if(oldttscale > 0)
F_UnloadAlacroixGraphics(oldttscale);
}
// We have a new ttscale, so load gfx
if(oldttscale > 0)
F_UnloadAlacroixGraphics(oldttscale);
testttscale = newttscale;
@ -2750,9 +2738,6 @@ 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);
@ -2776,42 +2761,42 @@ void F_TitleScreenDrawer(void)
{
case TTMODE_OLD:
case TTMODE_NONE:
V_DrawSciencePatch(30<<FRACBITS, 14<<FRACBITS, 0, ttwing, sc);
V_DrawSciencePatch(30<<FRACBITS, 14<<FRACBITS, 0, *ttwing, sc);
if (finalecount < 57)
{
if (finalecount == 35)
V_DrawSciencePatch(115<<FRACBITS, 15<<FRACBITS, 0, ttspop1, sc);
V_DrawSciencePatch(115<<FRACBITS, 15<<FRACBITS, 0, *ttspop1, sc);
else if (finalecount == 36)
V_DrawSciencePatch(114<<FRACBITS, 15<<FRACBITS, 0,ttspop2, sc);
V_DrawSciencePatch(114<<FRACBITS, 15<<FRACBITS, 0,*ttspop2, sc);
else if (finalecount == 37)
V_DrawSciencePatch(113<<FRACBITS, 15<<FRACBITS, 0,ttspop3, sc);
V_DrawSciencePatch(113<<FRACBITS, 15<<FRACBITS, 0,*ttspop3, sc);
else if (finalecount == 38)
V_DrawSciencePatch(112<<FRACBITS, 15<<FRACBITS, 0,ttspop4, sc);
V_DrawSciencePatch(112<<FRACBITS, 15<<FRACBITS, 0,*ttspop4, sc);
else if (finalecount == 39)
V_DrawSciencePatch(111<<FRACBITS, 15<<FRACBITS, 0,ttspop5, sc);
V_DrawSciencePatch(111<<FRACBITS, 15<<FRACBITS, 0,*ttspop5, sc);
else if (finalecount == 40)
V_DrawSciencePatch(110<<FRACBITS, 15<<FRACBITS, 0, ttspop6, sc);
V_DrawSciencePatch(110<<FRACBITS, 15<<FRACBITS, 0, *ttspop6, sc);
else if (finalecount >= 41 && finalecount <= 44)
V_DrawSciencePatch(109<<FRACBITS, 15<<FRACBITS, 0, ttspop7, sc);
V_DrawSciencePatch(109<<FRACBITS, 15<<FRACBITS, 0, *ttspop7, sc);
else if (finalecount >= 45 && finalecount <= 48)
V_DrawSciencePatch(108<<FRACBITS, 12<<FRACBITS, 0, ttsprep1, sc);
V_DrawSciencePatch(108<<FRACBITS, 12<<FRACBITS, 0, *ttsprep1, sc);
else if (finalecount >= 49 && finalecount <= 52)
V_DrawSciencePatch(107<<FRACBITS, 9<<FRACBITS, 0, ttsprep2, sc);
V_DrawSciencePatch(107<<FRACBITS, 9<<FRACBITS, 0, *ttsprep2, sc);
else if (finalecount >= 53 && finalecount <= 56)
V_DrawSciencePatch(106<<FRACBITS, 6<<FRACBITS, 0, ttswip1, sc);
V_DrawSciencePatch(93<<FRACBITS, 106<<FRACBITS, 0, ttsonic, sc);
V_DrawSciencePatch(106<<FRACBITS, 6<<FRACBITS, 0, *ttswip1, sc);
V_DrawSciencePatch(93<<FRACBITS, 106<<FRACBITS, 0, *ttsonic, sc);
}
else
{
V_DrawSciencePatch(93<<FRACBITS, 106<<FRACBITS, 0,ttsonic, sc);
V_DrawSciencePatch(93<<FRACBITS, 106<<FRACBITS, 0,*ttsonic, sc);
if (finalecount/5 & 1)
V_DrawSciencePatch(100<<FRACBITS, 3<<FRACBITS, 0,ttswave1, sc);
V_DrawSciencePatch(100<<FRACBITS, 3<<FRACBITS, 0,*ttswave1, sc);
else
V_DrawSciencePatch(100<<FRACBITS, 3<<FRACBITS, 0,ttswave2, sc);
V_DrawSciencePatch(100<<FRACBITS, 3<<FRACBITS, 0,*ttswave2, sc);
}
V_DrawSciencePatch(48<<FRACBITS, 142<<FRACBITS, 0,ttbanner, sc);
V_DrawSciencePatch(48<<FRACBITS, 142<<FRACBITS, 0,*ttbanner, sc);
break;
case TTMODE_ALACROIX:
@ -3485,7 +3470,7 @@ void F_TitleScreenDrawer(void)
break; // draw nothing
}
V_DrawSciencePatch(curttx<<FRACBITS, curtty<<FRACBITS, 0, ttuser[ttuser_count], sc);
V_DrawSciencePatch(curttx<<FRACBITS, curtty<<FRACBITS, 0, *ttuser[ttuser_count], sc);
if (!(finalecount % max(1, curtttics)))
ttuser_count++;

View file

@ -4462,7 +4462,7 @@ void G_LoadGame(UINT32 slot, INT16 mapoverride)
// G_DeferedInitNew(sk_medium, G_BuildMapName(1), 0, 0, 1);
if (setsizeneeded)
R_ExecuteSetViewSize();
R_SetViewSize();
M_ClearMenus(true);
CON_ToggleOff();

View file

@ -502,7 +502,6 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
boolean dealloc = true;
size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump);
pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE);
realpatch = (patch_t *)pdata;
@ -517,15 +516,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex)
realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false);
else
#endif
{
(void)lumplength;
dealloc = false;
}
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (dealloc)
Z_Unlock(realpatch);
}
//Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :(
if (format2bpp(grtex->mipmap.format)==4)
@ -601,6 +594,7 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
static size_t gl_numtextures = 0; // Texture count
static GLMapTexture_t *gl_textures; // For all textures
static GLMapTexture_t *gl_flats; // For all (texture) flats, as normal flats don't need to be cached
boolean gl_leveltexturesloaded = false;
void HWR_InitTextureCache(void)
{
@ -663,7 +657,17 @@ void HWR_FreeMipmapCache(void)
// Alam: free the Z_Blocks before freeing it's users
// free all patch colormaps after each level: must be done after ClearMipMapCache!
for (i = 0; i < numwadfiles; i++)
M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap);
{
M_AATreeIterate(Patch_GetRendererBaseSubTree(i, render_opengl), FreeMipmapColormap);
#ifdef ROTSPRITE
// free non-flipped rotated subtree
M_AATreeIterate(Patch_GetRendererRotatedSubTree(i, render_opengl, false), FreeMipmapColormap);
// free flipped rotated subtree
M_AATreeIterate(Patch_GetRendererRotatedSubTree(i, render_opengl, true), FreeMipmapColormap);
#endif
}
}
void HWR_FreeTextureCache(void)
@ -680,6 +684,7 @@ void HWR_FreeTextureCache(void)
gl_textures = NULL;
gl_flats = NULL;
gl_numtextures = 0;
gl_leveltexturesloaded = false;
}
void HWR_LoadTextures(size_t pnumtextures)
@ -696,6 +701,8 @@ void HWR_LoadTextures(size_t pnumtextures)
// should never ever happen (right?!)
if ((gl_textures == NULL) || (gl_flats == NULL))
I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!");
gl_leveltexturesloaded = true;
}
void HWR_SetPalette(RGBA_t *palette)
@ -872,15 +879,18 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
{
if (!grmip->downloaded && !grmip->data)
{
patch_t *patch = gpatch->rawpatch;
if (!patch)
patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(patch, gpatch, grmip, true);
patch_t *lumppatch = NULL;
// You can't free rawpatch for some reason?
// (Obviously I can't, sprite rotation needs that...)
if (!gpatch->rawpatch)
Z_Free(patch);
if (gpatch->patch)
HWR_MakePatch(gpatch->patch, gpatch, grmip, true);
else
{
lumppatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(lumppatch, gpatch, grmip, true);
}
if (lumppatch)
Z_Free(lumppatch);
}
// If hardware does not have the texture, then call pfnSetTexture to upload it
@ -898,20 +908,25 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
// -----------------+
void HWR_GetPatch(GLPatch_t *gpatch)
{
// is it in hardware cache
// is it in hardware cache?
if (!gpatch->mipmap->downloaded && !gpatch->mipmap->data)
{
// load the software patch, PU_STATIC or the Z_Malloc for hardware patch will
// flush the software patch before the conversion! oh yeah I suffered
patch_t *ptr = gpatch->rawpatch;
if (!ptr)
ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(ptr, gpatch, gpatch->mipmap, true);
patch_t *lumppatch = NULL;
if (gpatch->patch)
HWR_MakePatch(gpatch->patch, gpatch, gpatch->mipmap, true);
else
{
lumppatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(lumppatch, gpatch, gpatch->mipmap, true);
}
// this is inefficient.. but the hardware patch in heap is purgeable so it should
// not fragment memory, and besides the REAL cache here is the hardware memory
if (!gpatch->rawpatch)
Z_Free(ptr);
if (lumppatch)
Z_Free(lumppatch);
}
// If hardware does not have the texture, then call pfnSetTexture to upload it
@ -1096,7 +1111,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
pic,
format2bpp(grpatch->mipmap->format));
Z_Unlock(pic);
Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED);
grpatch->mipmap->flags = 0;
@ -1108,18 +1122,17 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
return grpatch;
}
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum, void *hwrcache)
{
aatree_t *hwrcache = wadfiles[wadnum]->hwrcache;
GLPatch_t *grpatch;
if (!(grpatch = M_AATreeGet(hwrcache, lumpnum)))
if (!(grpatch = M_AATreeGet((aatree_t *)hwrcache, lumpnum)))
{
grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
grpatch->wadnum = wadnum;
grpatch->lumpnum = lumpnum;
grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
M_AATreeSet(hwrcache, lumpnum, grpatch);
M_AATreeSet((aatree_t *)hwrcache, lumpnum, grpatch);
}
return grpatch;
@ -1127,7 +1140,8 @@ GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum)
{
return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
UINT16 wad = WADFILENUM(lumpnum);
return HWR_GetCachedGLPatchPwad(wad, LUMPNUM(lumpnum), Patch_GetRendererBaseSubTree(wad, render_opengl));
}
// Need to do this because they aren't powers of 2

View file

@ -89,7 +89,7 @@ struct GLPatch_s
float max_s,max_t;
UINT16 wadnum; // the software patch lump num for when the hardware patch
UINT16 lumpnum; // was flushed, and we need to re-create it
void *rawpatch; // :^)
void *patch;
GLMipmap_t *mipmap;
} ATTRPACK;
typedef struct GLPatch_s GLPatch_t;

View file

@ -62,7 +62,10 @@ typedef struct
typedef struct gl_vissprite_s
{
float x1, x2;
float z1, z2;
float tz, ty;
float originx, originy, originz;
angle_t angle;
float tracertz; // for MF2_LINKDRAW sprites, this contains tracer's tz for use in sorting
//lumpnum_t patchlumpnum;
GLPatch_t *gpatch;
@ -74,7 +77,10 @@ typedef struct gl_vissprite_s
//Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
float z1, z2;
#ifdef ROTSPRITE
angle_t rollangle;
float pivotx, pivoty;
#endif
} gl_vissprite_t;
// --------
@ -102,10 +108,12 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
GLPatch_t *HWR_GetPic(lumpnum_t lumpnum);
void HWR_SetPalette(RGBA_t *palette);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum, void *hwrcache);
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
extern boolean gl_leveltexturesloaded;
// --------
// hw_draw.c
// --------

View file

@ -26,6 +26,7 @@
#include "../p_setup.h"
#include "../r_local.h"
#include "../r_patch.h"
#include "../r_rotsprite.h"
#include "../r_bsp.h"
#include "../d_clisrv.h"
#include "../w_wad.h"
@ -3701,6 +3702,87 @@ static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts
}
}
#if defined(ROTSPRITE) && !defined(ROTSPRITE_RENDER_PATCHES)
static void HWR_ApplyPitchRollYawToSprite(FOutVector *wallVerts, float pitch, float roll, float yaw)
{
size_t i;
float yawcos = cos(yaw);
float yawsin = sin(yaw);
float pitchcos = cos(pitch);
float pitchsin = sin(pitch);
float rollcos = cos(roll);
float rollsin = sin(roll);
float xx = yawcos * pitchcos;
float xy = (yawcos * pitchsin * rollsin) - (yawsin * rollcos);
float xz = (yawcos * pitchsin * rollcos) + (yawsin * rollsin);
float yx = yawsin * pitchcos;
float yy = (yawsin * pitchsin * rollsin) + (yawcos * rollcos);
float yz = (yawsin * pitchsin * rollcos) - (yawcos * rollsin);
float zx = -pitchsin;
float zy = pitchcos * rollsin;
float zz = pitchcos * rollcos;
for (i = 0; i < 4; i++)
{
float x = wallVerts[i].x;
float y = wallVerts[i].y;
float z = wallVerts[i].z;
wallVerts[i].x = xx*x + xy*y + xz*z;
wallVerts[i].y = yx*x + yy*y + yz*z;
wallVerts[i].z = zx*x + zy*y + zz*z;
}
}
static void HWR_RotateSpritePolyToRollAngle(gr_vissprite_t *spr, FOutVector *wallVerts)
{
INT32 i;
float radians = (M_PIl / 180.0f);
float cx = (spr->gpatch->leftoffset - spr->pivotx);
float cy = spr->pivoty;
fixed_t fa = AngleFixed(spr->rollangle);
float rotate = FIXED_TO_FLOAT(fa) * radians;
// Translate sprite by its pivot
for (i = 0; i < 4; i++)
{
wallVerts[i].x -= cx;
wallVerts[i].y -= cy;
}
// Apply sprite roll
HWR_ApplyPitchRollYawToSprite(wallVerts, 0.0f, 0.0f, rotate);
// Translate sprite back
for (i = 0; i < 4; i++)
{
wallVerts[i].x += cx;
wallVerts[i].y += cy;
}
// Apply sprite angle
fa = AngleFixed(spr->angle - ANGLE_180);
rotate = FIXED_TO_FLOAT(fa) * radians;
HWR_ApplyPitchRollYawToSprite(wallVerts, -rotate, 0.0f, 0.0f);
// Translate the sprite to its intended position
for (i = 0; i < 4; i++)
{
wallVerts[i].x += spr->originx;
wallVerts[i].z += spr->originy;
}
// Translate the sprite vertically
for (i = 0; i < 4; i++)
wallVerts[i].y += spr->originz;
}
#endif
static void HWR_SplitSprite(gl_vissprite_t *spr)
{
float this_scale = 1.0f;
@ -3793,6 +3875,12 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
#if defined(ROTSPRITE) && !defined(ROTSPRITE_RENDER_PATCHES)
// Rotate the sprite polygon, then translate it
if (spr->rollangle)
HWR_RotateSpritePolyToRollAngle(spr, baseWallVerts);
#endif
realtop = top = baseWallVerts[3].y;
realbot = bot = baseWallVerts[0].y;
ttop = baseWallVerts[3].t;
@ -4075,6 +4163,12 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
// Let dispoffset work first since this adjust each vertex
HWR_RotateSpritePolyToAim(spr, wallVerts, false);
#if defined(ROTSPRITE) && !defined(ROTSPRITE_RENDER_PATCHES)
// Rotate the sprite polygon, then translate it
if (spr->rollangle)
HWR_RotateSpritePolyToRollAngle(spr, wallVerts);
#endif
// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
// sprite lighting by modulating the RGB components
/// \todo coloured
@ -4760,9 +4854,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
float rightsin, rightcos;
float this_scale;
float gz, gzt;
float topz, bottomz, originz;
spritedef_t *sprdef;
spriteframe_t *sprframe;
#ifdef ROTSPRITE
spriteinfo_t *sprinfo;
#ifdef ROTSPRITE_RENDER_PATCHES
INT32 rollangle;
#endif
#endif
md2_t *md2;
size_t lumpoff;
unsigned rot;
@ -4776,14 +4876,12 @@ static void HWR_ProjectSprite(mobj_t *thing)
INT32 heightsec, phs;
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle);
angle_t spriteangle;
float z1, z2;
GLPatch_t *spr_patch;
fixed_t spr_width, spr_height;
fixed_t spr_offset, spr_topoffset;
#ifdef ROTSPRITE
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
#endif
if (!thing)
return;
@ -4832,12 +4930,16 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->skin && thing->sprite == SPR_PLAY)
{
sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
#ifdef ROTSPRITE
sprinfo = &((skin_t *)thing->skin)->sprinfo[thing->sprite2];
#endif
}
else
{
sprdef = &sprites[thing->sprite];
sprinfo = NULL;
#ifdef ROTSPRITE
sprinfo = &spriteinfo[thing->sprite];
#endif
}
if (rot >= sprdef->numframes)
@ -4847,7 +4949,9 @@ static void HWR_ProjectSprite(mobj_t *thing)
thing->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite];
sprinfo = NULL;
#ifdef ROTSPRITE
sprinfo = &spriteinfo[thing->sprite];
#endif
rot = thing->frame&FF_FRAMEMASK;
thing->state->sprite = thing->sprite;
thing->state->frame = thing->frame;
@ -4900,40 +5004,44 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
spr_patch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
spr_width = spritecachedinfo[lumpoff].width;
spr_height = spritecachedinfo[lumpoff].height;
spr_offset = spritecachedinfo[lumpoff].offset;
spr_topoffset = spritecachedinfo[lumpoff].topoffset;
#ifdef ROTSPRITE
if (thing->rollangle)
#if defined(ROTSPRITE) && defined(ROTSPRITE_RENDER_PATCHES)
rollangle = R_GetRollAngle(thing->rollangle);
if (rollangle)
{
rollangle = R_GetRollAngle(thing->rollangle);
if (!(sprframe->rotsprite.cached & (1<<rot)))
R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip);
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
spriteframepivot_t *pivot = (sprinfo->available) ? &sprinfo->pivot[(thing->frame & FF_FRAMEMASK)] : NULL;
static rotsprite_vars_t rsvars;
patch_t *rotpatch;
rsvars.rollangle = rollangle;
rsvars.sprite = true;
rsvars.pivot = pivot;
rsvars.flip = (flip != 0);
rotpatch = Patch_CacheRotatedForSprite(sprframe->lumppat[rot], PU_LEVEL, rsvars, false);
spr_patch = (GLPatch_t *)rotpatch;
spr_width = SHORT(rotpatch->width) << FRACBITS;
spr_height = SHORT(rotpatch->height) << FRACBITS;
spr_offset = SHORT(rotpatch->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotpatch->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
#endif
if (papersprite)
{
rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT));
rightcos = FIXED_TO_FLOAT(FINECOSINE((mobjangle)>>ANGLETOFINESHIFT));
}
spriteangle = mobjangle;
else
{
rightsin = FIXED_TO_FLOAT(FINESINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT));
rightcos = FIXED_TO_FLOAT(FINECOSINE((viewangle + ANGLE_90)>>ANGLETOFINESHIFT));
}
spriteangle = (viewangle + ANGLE_90);
rightsin = FIXED_TO_FLOAT(FINESINE((spriteangle)>>ANGLETOFINESHIFT));
rightcos = FIXED_TO_FLOAT(FINECOSINE((spriteangle)>>ANGLETOFINESHIFT));
flip = !flip != !hflip;
@ -4948,31 +5056,35 @@ static void HWR_ProjectSprite(mobj_t *thing)
x2 = (FIXED_TO_FLOAT(spr_width - spr_offset) * this_scale);
}
// test if too close
/*
if (papersprite)
originz = FIXED_TO_FLOAT(thing->z);
#if defined(ROTSPRITE) && !defined(ROTSPRITE_RENDER_PATCHES)
// Don't transform the sprite if it has a roll angle.
if (thing->rollangle)
{
z1 = tz - x1 * angle_scalez;
z2 = tz + x2 * angle_scalez;
if (max(z1, z2) < ZCLIP_PLANE)
return;
z1 = z2 = 0.0f;
x1 = -x1;
topz = bottomz = 0.0;
}
else
#endif
{
z1 = tr_y + x1 * rightsin;
z2 = tr_y - x2 * rightsin;
x1 = tr_x + x1 * rightcos;
x2 = tr_x - x2 * rightcos;
topz = originz + FIXED_TO_FLOAT(thing->height);
bottomz = originz;
}
*/
z1 = tr_y + x1 * rightsin;
z2 = tr_y - x2 * rightsin;
x1 = tr_x + x1 * rightcos;
x2 = tr_x - x2 * rightcos;
if (vflip)
{
gz = FIXED_TO_FLOAT(thing->z+thing->height) - FIXED_TO_FLOAT(spr_topoffset) * this_scale;
gz = topz - FIXED_TO_FLOAT(spr_topoffset) * this_scale;
gzt = gz + FIXED_TO_FLOAT(spr_height) * this_scale;
}
else
{
gzt = FIXED_TO_FLOAT(thing->z) + FIXED_TO_FLOAT(spr_topoffset) * this_scale;
gzt = bottomz + FIXED_TO_FLOAT(spr_topoffset) * this_scale;
gz = gzt - FIXED_TO_FLOAT(spr_height) * this_scale;
}
@ -5031,19 +5143,35 @@ static void HWR_ProjectSprite(mobj_t *thing)
vis->x1 = x1;
vis->x2 = x2;
vis->tz = tz; // Keep tz for the simple sprite sorting that happens
vis->gpatch = spr_patch;
vis->tracertz = tracertz;
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
//vis->patchlumpnum = sprframe->lumppat[rot];
#ifdef ROTSPRITE
if (rotsprite)
vis->gpatch = (GLPatch_t *)rotsprite;
else
#endif
vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->flip = flip;
vis->mobj = thing;
vis->z1 = z1;
vis->z2 = z2;
vis->angle = spriteangle;
vis->originx = tr_x;
vis->originy = tr_y;
vis->originz = originz;
#if defined(ROTSPRITE) && !defined(ROTSPRITE_RENDER_PATCHES)
if (thing->rollangle)
{
if (sprinfo->available)
{
spriteframepivot_t *pivot = &sprinfo->pivot[thing->frame & FF_FRAMEMASK];
vis->pivotx = (float)(pivot->x) * this_scale;
vis->pivoty = (float)(pivot->y) * this_scale;
}
else
{
vis->pivotx = (float)(spr_patch->leftoffset) * this_scale;
vis->pivoty = (float)(spr_patch->height / 2) * this_scale;
}
}
vis->rollangle = thing->rollangle;
#endif
//Hurdler: 25/04/2000: now support colormap in hardware mode
if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
@ -5173,8 +5301,11 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->z1 = z1;
vis->z2 = z2;
vis->tz = tz;
vis->angle = 0;
vis->originx = tr_x;
vis->originy = tr_y;
vis->originz = FIXED_TO_FLOAT(thing->z);
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
//vis->patchlumpnum = sprframe->lumppat[rot];
vis->gpatch = (GLPatch_t *)W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->flip = flip;
vis->mobj = (mobj_t *)thing;
@ -5182,10 +5313,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->colormap = colormaps;
// set top/bottom coords
vis->ty = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset);
vis->ty = vis->originz + FIXED_TO_FLOAT(spritecachedinfo[lumpoff].topoffset);
vis->precip = true;
#ifdef ROTSPRITE
vis->rollangle = 0;
vis->pivotx = 0.0f;
vis->pivoty = 0.0f;
#endif
// okay... this is a hack, but weather isn't networked, so it should be ok
if (!(thing->precipflags & PCF_THUNK))
{
@ -5975,9 +6112,20 @@ void HWR_Startup(void)
// --------------------------------------------------------------------------
void HWR_Switch(void)
{
// Add session commands
HWR_AddSessionCommands();
// Set special states from CVARs
HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value);
HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value);
// Load textures
if (!gl_leveltexturesloaded)
HWR_LoadTextures(numtextures);
// Create plane polygons
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
HWR_LoadLevel();
}
// --------------------------------------------------------------------------

View file

@ -240,7 +240,7 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth
static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
{
LPCSTR renderer;
BOOL WantFullScreen = !(lvid->u.windowed); //(lvid->u.windowed ? 0 : CDS_FULLSCREEN);
BOOL WantFullScreen = !(lvid->windowed); //(lvid->windowed ? 0 : CDS_FULLSCREEN);
UNREFERENCED_PARAMETER(pcurrentmode);
GL_DBG_Printf ("SetMode(): %dx%d %d bits (%s)\n",

View file

@ -27,7 +27,7 @@
#include "i_video.h"
#include "i_system.h"
#include "st_stuff.h" // ST_HEIGHT
#include "st_stuff.h"
#include "r_local.h"
#include "keys.h"
@ -82,10 +82,10 @@ static boolean headsupactive = false;
boolean hu_showscores; // draw rankings
static char hu_tick;
patch_t *rflagico;
patch_t *bflagico;
patch_t *rmatcico;
patch_t *bmatcico;
patch_t **rflagico;
patch_t **bflagico;
patch_t **rmatcico;
patch_t **bmatcico;
patch_t *tagico;
patch_t *tallminus;
patch_t *tallinfin;
@ -2038,9 +2038,6 @@ static void HU_DrawDemoInfo(void)
//
void HU_Drawer(void)
{
if (needpatchrecache)
R_ReloadHUDGraphics();
#ifndef NONET
// draw chat string plus cursor
if (chat_on)
@ -2468,9 +2465,9 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (gametyperules & GTR_TEAMFLAGS)
{
if (players[tab[i].num].gotflag & GF_REDFLAG) // Red
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, rflagico, 0);
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, *rflagico, 0);
else if (players[tab[i].num].gotflag & GF_BLUEFLAG) // Blue
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, bflagico, 0);
V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, *bflagico, 0);
}
// Draw emeralds
@ -2596,9 +2593,9 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
if (gametyperules & GTR_TEAMFLAGS)
{
if (players[tab[i].num].gotflag & GF_REDFLAG) // Red
V_DrawSmallScaledPatch(x-28, y-4, 0, rflagico);
V_DrawSmallScaledPatch(x-28, y-4, 0, *rflagico);
else if (players[tab[i].num].gotflag & GF_BLUEFLAG) // Blue
V_DrawSmallScaledPatch(x-28, y-4, 0, bflagico);
V_DrawSmallScaledPatch(x-28, y-4, 0, *bflagico);
}
// Draw emeralds

View file

@ -87,10 +87,10 @@ extern patch_t *ntb_font[NT_FONTSIZE];
extern patch_t *nto_font[NT_FONTSIZE];
extern patch_t *ttlnum[10];
extern patch_t *emeraldpics[3][8];
extern patch_t *rflagico;
extern patch_t *bflagico;
extern patch_t *rmatcico;
extern patch_t *bmatcico;
extern patch_t **rflagico;
extern patch_t **bflagico;
extern patch_t **rmatcico;
extern patch_t **bmatcico;
extern patch_t *tagico;
extern patch_t *tallminus;
extern patch_t *tallinfin;

View file

@ -20,26 +20,33 @@
#pragma interface
#endif
typedef enum
typedef enum rendermode_e
{
/// Software
render_soft = 1,
// No renderer chosen. Used on dedicated mode.
render_none = 0,
/// OpenGL
render_opengl = 2,
// First renderer choice.
// Must start from 1.
render_first = 1,
/// Dedicated
render_none = 3 // for dedicated server
// Main renderer choices.
render_soft = render_first,
render_opengl,
// Last renderer choice.
render_last,
// Renderer count.
num_renderers = (render_last - 1),
} rendermode_t;
/** \brief current render mode
*/
extern rendermode_t rendermode;
/** \brief OpenGL state
0 = never loaded, 1 = loaded successfully, -1 = failed loading
/** \brief render mode set by command line arguments
*/
extern INT32 vid_opengl_state;
extern rendermode_t chosenrendermode;
/** \brief use highcolor modes if true
*/
@ -89,9 +96,19 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h);
*/
INT32 VID_SetMode(INT32 modenum);
/** \brief Checks the render state
/** \brief The VID_GetModeName function
\param modenum video mode number
\return name of video mode
*/
void VID_CheckRenderer(void);
const char *VID_GetModeName(INT32 modenum);
/** \brief Checks the render state
\return true if the renderer changed
*/
boolean VID_CheckRenderer(void);
/** \brief Load OpenGL mode
*/
@ -101,16 +118,6 @@ void VID_StartupOpenGL(void);
*/
void VID_CheckGLLoaded(rendermode_t oldrender);
/** \brief The VID_GetModeName function
\param modenum video mode number
\return name of video mode
*/
const char *VID_GetModeName(INT32 modenum);
void VID_PrepareModeList(void); /// note hack for SDL
/** \brief can video system do fullscreen
*/
extern boolean allow_fullscreen;

View file

@ -19,6 +19,7 @@
#include "r_main.h"
#include "r_draw.h"
#include "r_things.h" // R_Frame2Char etc
#include "r_rotsprite.h" // R_GetRollAngle
#include "m_random.h"
#include "s_sound.h"
#include "g_game.h"
@ -2434,6 +2435,16 @@ static int lib_rPointInSubsectorOrNil(lua_State *L)
return 1;
}
#ifdef ROTSPRITE
// R_ROTSPRITE
////////////
static int lib_rGetRollAngle(lua_State *L)
{
lua_pushinteger(L, R_GetRollAngle(luaL_checkangle(L, 1)));
return 1;
}
#endif
// R_THINGS
////////////
@ -3489,6 +3500,11 @@ static luaL_Reg lib[] = {
{"R_PointInSubsector",lib_rPointInSubsector},
{"R_PointInSubsectorOrNil",lib_rPointInSubsectorOrNil},
#ifdef ROTSPRITE
// r_rotsprite
{"R_GetRollAngle",lib_rGetRollAngle},
#endif
// r_things (sprite)
{"R_Char2Frame",lib_rChar2Frame},
{"R_Frame2Char",lib_rFrame2Char},

View file

@ -14,6 +14,7 @@
#include "fastcmp.h"
#include "r_defs.h"
#include "r_local.h"
#include "r_rotsprite.h"
#include "st_stuff.h" // hudinfo[]
#include "g_game.h"
#include "i_video.h" // rendermode
@ -35,11 +36,6 @@ 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",
@ -292,14 +288,9 @@ 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
patch_t *patch = **((patch_t ***)luaL_checkudata(L, 1, META_PATCH));
enum patch field = luaL_checkoption(L, 2, NULL, patch_opt);
// patches are invalidated when switching renderers
if (!patch) {
if (field == patch_valid) {
lua_pushboolean(L, 0);
@ -403,59 +394,18 @@ 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
luapat = patchinfohead;
lumpnum = W_CheckNumForLongName(luaL_checkstring(L, 1));
if (lumpnum == LUMPERROR)
lumpnum = W_GetNumForLongName("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_CachePatchLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
#ifdef ROTSPRITE
INT32 rollangle = R_GetRollAngle(luaL_optinteger(L, 2, 0));
#endif
HUDONLY
#ifdef ROTSPRITE
if (rollangle)
LUA_PushUserdata(L, W_GetRotatedPatchPointerFromLongName(luaL_checkstring(L, 1), PU_PATCH, rollangle, false, NULL, lua_optboolean(L, 3)), META_PATCH);
else
#endif
LUA_PushUserdata(L, W_GetPatchPointerFromLongName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH);
return 1;
}
@ -517,10 +467,9 @@ static int libd_getSpritePatch(lua_State *L)
angle_t rollangle = luaL_checkangle(L, 4);
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
if (!(sprframe->rotsprite.cached & (1<<angle)))
R_CacheRotSprite(i, frame, NULL, sprframe, angle, sprframe->flip & (1<<angle));
LUA_PushUserdata(L, sprframe->rotsprite.patch[angle][rot], META_PATCH);
if (rot)
{
LUA_PushUserdata(L, W_GetRotatedPatchPointer(sprframe->lumppat[angle], PU_PATCH, rot, true, NULL, sprframe->flip & (1<<angle)), META_PATCH);
lua_pushboolean(L, false);
lua_pushboolean(L, true);
return 3;
@ -528,8 +477,8 @@ static int libd_getSpritePatch(lua_State *L)
}
#endif
// push both the patch and it's "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
// push both the patch and its "flip" value
LUA_PushUserdata(L, W_GetPatchPointer(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
return 2;
}
@ -631,9 +580,9 @@ static int libd_getSprite2Patch(lua_State *L)
INT32 rot = R_GetRollAngle(rollangle);
if (rot) {
if (!(sprframe->rotsprite.cached & (1<<angle)))
R_CacheRotSprite(SPR_PLAY, frame, &skins[i].sprinfo[j], sprframe, angle, sprframe->flip & (1<<angle));
LUA_PushUserdata(L, sprframe->rotsprite.patch[angle][rot], META_PATCH);
spriteinfo_t *sprinfo = &skins[i].sprinfo[j];
spriteframepivot_t *pivot = (sprinfo->available) ? &sprinfo->pivot[frame] : NULL;
LUA_PushUserdata(L, W_GetRotatedPatchPointer(sprframe->lumppat[angle], PU_PATCH, rot, true, pivot, sprframe->flip & (1<<angle)), META_PATCH);
lua_pushboolean(L, false);
lua_pushboolean(L, true);
return 3;
@ -641,8 +590,8 @@ static int libd_getSprite2Patch(lua_State *L)
}
#endif
// push both the patch and it's "flip" value
LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
// push both the patch and its "flip" value
LUA_PushUserdata(L, W_GetPatchPointer(sprframe->lumppat[angle], PU_PATCH), META_PATCH);
lua_pushboolean(L, (sprframe->flip & (1<<angle)) != 0);
return 2;
}
@ -651,22 +600,14 @@ 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));
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));
@ -682,9 +623,6 @@ 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
@ -693,14 +631,9 @@ 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));
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));
@ -727,7 +660,9 @@ static int libd_drawStretched(lua_State *L)
vscale = luaL_checkinteger(L, 4);
if (vscale < 0)
return luaL_error(L, "negative vertical scale");
patch = *((patch_t **)luaL_checkudata(L, 5, META_PATCH));
patch = **((patch_t ***)luaL_checkudata(L, 5, META_PATCH));
if (!patch)
return LUA_ErrInvalid(L, "patch_t");
flags = luaL_optinteger(L, 6, 0);
if (!lua_isnoneornil(L, 7))
colormap = *((UINT8 **)luaL_checkudata(L, 7, META_COLORMAP));
@ -1247,10 +1182,6 @@ int LUA_HudLib(lua_State *L)
{
memset(hud_enabled, 0xff, (hud_MAX/8)+1);
#ifdef LUA_PATCH_SAFETY
numluapatches = 0;
#endif
lua_newtable(L); // HUD registry table
lua_newtable(L);
luaL_register(L, NULL, lib_draw);

View file

@ -18,6 +18,7 @@
#include "p_local.h"
#include "z_zone.h"
#include "r_patch.h"
#include "r_rotsprite.h"
#include "r_things.h"
#include "r_draw.h" // R_GetColorByName
#include "doomstat.h" // luabanks[]
@ -377,10 +378,6 @@ static int lib_setSpriteInfo(lua_State *L)
UINT32 i = luaL_checkinteger(L, 1);
if (i == 0 || i >= NUMSPRITES)
return luaL_error(L, "spriteinfo[] index %d out of range (1 - %d)", i, NUMSPRITES-1);
#ifdef ROTSPRITE
if (sprites != NULL)
R_FreeSingleRotSprite(&sprites[i]);
#endif
info = &spriteinfo[i]; // get the spriteinfo to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
@ -462,11 +459,6 @@ static int spriteinfo_set(lua_State *L)
lua_remove(L, 1); // remove field
lua_settop(L, 1); // leave only one value
#ifdef ROTSPRITE
if (sprites != NULL)
R_FreeSingleRotSprite(&sprites[sprinfo-spriteinfo]);
#endif
if (fastcmp(field, "pivot"))
{
// pivot[] is a table

View file

@ -62,7 +62,7 @@ extern lua_State *gL;
#define META_BBOX "BOUNDING_BOX"
#define META_HUDINFO "HUDINFO_T*"
#define META_PATCH "PATCH_T*"
#define META_PATCH "PATCH_T**"
#define META_COLORMAP "COLORMAP"
#define META_CAMERA "CAMERA_T*"

View file

@ -203,7 +203,7 @@ menu_t SPauseDef;
// Level Select
static levelselect_t levelselect = {0, NULL};
static UINT8 levelselectselect[3];
static patch_t *levselp[2][3];
static patch_t **levselp[2][3];
static INT32 lsoffs[2];
#define lsrow levelselectselect[0]
@ -342,7 +342,7 @@ static void M_EraseData(INT32 choice);
static void M_Addons(INT32 choice);
static void M_AddonsOptions(INT32 choice);
static patch_t *addonsp[NUM_EXT+5];
static patch_t **addonsp[NUM_EXT+5];
#define addonmenusize 9 // number of items actually displayed in the addons menu view, formerly (2*numaddonsshown + 1)
#define numaddonsshown 4 // number of items to each side of the currently selected item, unless at top/bottom ends of directory
@ -1345,11 +1345,7 @@ static menuitem_t OP_VideoOptionsMenu[] =
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11},
#endif
{IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16},
#ifdef HWRENDER
{IT_STRING | IT_CVAR, NULL, "Renderer", &cv_newrenderer, 21},
#else
{IT_TRANSTEXT | IT_PAIR, "Renderer", "Software", &cv_renderer, 21},
#endif
{IT_STRING | IT_CVAR, NULL, "Renderer", &cv_newrenderer, 21},
{IT_HEADER, NULL, "Color Profile", NULL, 30},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36},
@ -2147,15 +2143,21 @@ menu_t OP_PlaystyleDef = {
static void M_VideoOptions(INT32 choice)
{
(void)choice;
#ifdef HWRENDER
if (vid_opengl_state == -1)
{
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
OP_VideoOptionsMenu[op_video_renderer].text = "Software";
}
OP_VideoOptionsMenu[op_video_renderer].status = (IT_TRANSTEXT | IT_PAIR);
OP_VideoOptionsMenu[op_video_renderer].patch = "Renderer";
OP_VideoOptionsMenu[op_video_renderer].text = "Software";
#ifdef HWRENDER
if (vid.glstate != VID_GL_LIBRARY_ERROR)
{
OP_VideoOptionsMenu[op_video_renderer].status = (IT_STRING | IT_CVAR);
OP_VideoOptionsMenu[op_video_renderer].patch = NULL;
OP_VideoOptionsMenu[op_video_renderer].text = "Renderer";
}
CV_StealthSetValue(&cv_newrenderer, cv_renderer.value);
#endif
M_SetupNextMenu(&OP_VideoOptionsDef);
}
@ -5206,13 +5208,13 @@ static INT32 M_CountRowsToShowOnPlatter(INT32 gt)
//
static void M_CacheLevelPlatter(void)
{
levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH);
levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH);
levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH);
levselp[0][0] = (patch_t **)W_GetPatchPointerFromName("SLCT1LVL", PU_PATCH);
levselp[0][1] = (patch_t **)W_GetPatchPointerFromName("SLCT2LVL", PU_PATCH);
levselp[0][2] = (patch_t **)W_GetPatchPointerFromName("BLANKLVL", PU_PATCH);
levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH);
levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH);
levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH);
levselp[1][0] = (patch_t **)W_GetPatchPointerFromName("SLCT1LVW", PU_PATCH);
levselp[1][1] = (patch_t **)W_GetPatchPointerFromName("SLCT2LVW", PU_PATCH);
levselp[1][2] = (patch_t **)W_GetPatchPointerFromName("BLANKLVW", PU_PATCH);
}
//
@ -5591,13 +5593,10 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo
if (map <= 0)
return;
if (needpatchrecache)
M_CacheLevelPlatter();
// A 564x100 image of the level as entry MAPxxW
if (!(levelselect.rows[row].mapavailable[col]))
{
V_DrawSmallScaledPatch(x, y, 0, levselp[1][2]);
V_DrawSmallScaledPatch(x, y, 0, *levselp[1][2]);
M_DrawStaticBox(x, y, V_80TRANS, 282, 50);
}
else
@ -5605,7 +5604,7 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo
if (W_CheckNumForName(va("%sW", G_BuildMapName(map))) != LUMPERROR)
patch = W_CachePatchName(va("%sW", G_BuildMapName(map)), PU_PATCH);
else
patch = levselp[1][2]; // don't static to indicate that it's just a normal level
patch = *levselp[1][2]; // don't static to indicate that it's just a normal level
V_DrawSmallScaledPatch(x, y, 0, patch);
}
@ -5625,13 +5624,10 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea
if (map <= 0)
return;
if (needpatchrecache)
M_CacheLevelPlatter();
// A 160x100 image of the level as entry MAPxxP
if (!(levelselect.rows[row].mapavailable[col]))
{
V_DrawSmallScaledPatch(x, y, 0, levselp[0][2]);
V_DrawSmallScaledPatch(x, y, 0, *levselp[0][2]);
M_DrawStaticBox(x, y, V_80TRANS, 80, 50);
}
else
@ -5639,7 +5635,7 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea
if (W_CheckNumForName(va("%sP", G_BuildMapName(map))) != LUMPERROR)
patch = W_CachePatchName(va("%sP", G_BuildMapName(map)), PU_PATCH);
else
patch = levselp[0][2]; // don't static to indicate that it's just a normal level
patch = *levselp[0][2]; // don't static to indicate that it's just a normal level
V_DrawSmallScaledPatch(x, y, 0, patch);
}
@ -5913,7 +5909,7 @@ static void M_DrawLevelPlatterMenu(void)
// draw cursor box
if (levellistmode != LLM_CREATESERVER || lsrow)
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey+lsoffs[0], 0, (levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
V_DrawSmallScaledPatch(lsbasex + cursorx + lsoffs[1], lsbasey+lsoffs[0], 0, (*levselp[sizeselect][((skullAnimCounter/4) ? 1 : 0)]));
#if 0
if (levelselect.rows[lsrow].maplist[lscol] > 0)
@ -6248,23 +6244,23 @@ static void M_AddonsOptions(INT32 choice)
static void M_LoadAddonsPatches(void)
{
addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_PATCH);
addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_PATCH);
addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_PATCH);
addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_PATCH);
addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_PATCH);
addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_PATCH);
addonsp[EXT_FOLDER] = (patch_t **)W_GetPatchPointerFromName("M_FFLDR", PU_PATCH);
addonsp[EXT_UP] = (patch_t **)W_GetPatchPointerFromName("M_FBACK", PU_PATCH);
addonsp[EXT_NORESULTS] = (patch_t **)W_GetPatchPointerFromName("M_FNOPE", PU_PATCH);
addonsp[EXT_TXT] = (patch_t **)W_GetPatchPointerFromName("M_FTXT", PU_PATCH);
addonsp[EXT_CFG] = (patch_t **)W_GetPatchPointerFromName("M_FCFG", PU_PATCH);
addonsp[EXT_WAD] = (patch_t **)W_GetPatchPointerFromName("M_FWAD", PU_PATCH);
#ifdef USE_KART
addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_PATCH);
addonsp[EXT_KART] = (patch_t **)W_GetPatchPointerFromName("M_FKART", PU_PATCH);
#endif
addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_PATCH);
addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_PATCH);
addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_PATCH);
addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_PATCH);
addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_PATCH);
addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_PATCH);
addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_PATCH);
addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_PATCH);
addonsp[EXT_PK3] = (patch_t **)W_GetPatchPointerFromName("M_FPK3", PU_PATCH);
addonsp[EXT_SOC] = (patch_t **)W_GetPatchPointerFromName("M_FSOC", PU_PATCH);
addonsp[EXT_LUA] = (patch_t **)W_GetPatchPointerFromName("M_FLUA", PU_PATCH);
addonsp[NUM_EXT] = (patch_t **)W_GetPatchPointerFromName("M_FUNKN", PU_PATCH);
addonsp[NUM_EXT+1] = (patch_t **)W_GetPatchPointerFromName("M_FSEL", PU_PATCH);
addonsp[NUM_EXT+2] = (patch_t **)W_GetPatchPointerFromName("M_FLOAD", PU_PATCH);
addonsp[NUM_EXT+3] = (patch_t **)W_GetPatchPointerFromName("M_FSRCH", PU_PATCH);
addonsp[NUM_EXT+4] = (patch_t **)W_GetPatchPointerFromName("M_FSAVE", PU_PATCH);
}
static void M_Addons(INT32 choice)
@ -6450,10 +6446,6 @@ static void M_DrawAddons(void)
return;
}
// Lactozilla: Load addons menu patches.
if (needpatchrecache)
M_LoadAddonsPatches();
if (Playing())
V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems.");
else
@ -6548,16 +6540,16 @@ static void M_DrawAddons(void)
if (type & EXT_LOADED)
{
flags |= V_TRANSLUCENT;
V_DrawSmallScaledPatch(x-(16+4), y, V_TRANSLUCENT, addonsp[(type & ~EXT_LOADED)]);
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[NUM_EXT+2]);
V_DrawSmallScaledPatch(x-(16+4), y, V_TRANSLUCENT, *addonsp[(type & ~EXT_LOADED)]);
V_DrawSmallScaledPatch(x-(16+4), y, 0, *addonsp[NUM_EXT+2]);
}
else
V_DrawSmallScaledPatch(x-(16+4), y, 0, addonsp[(type & ~EXT_LOADED)]);
V_DrawSmallScaledPatch(x-(16+4), y, 0, *addonsp[(type & ~EXT_LOADED)]);
// draw selection box for the item currently selected
if ((size_t)i == dir_on[menudepthleft])
{
V_DrawFixedPatch((x-(16+4))<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, 0, addonsp[NUM_EXT+1], flashcol);
V_DrawFixedPatch((x-(16+4))<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, 0, *addonsp[NUM_EXT+1], flashcol);
flags = V_ALLOWLOWERCASE|highlightflags;
}
@ -6591,14 +6583,14 @@ static void M_DrawAddons(void)
// draw search icon
x -= (21 + 5 + 16);
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+3]);
V_DrawSmallScaledPatch(x, y + 4, (menusearch[0] ? 0 : V_TRANSLUCENT), *addonsp[NUM_EXT+3]);
// draw save icon
x = BASEVIDWIDTH - x - 16;
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), addonsp[NUM_EXT+4]);
V_DrawSmallScaledPatch(x, y + 4, ((!modifiedgame || savemoddata) ? 0 : V_TRANSLUCENT), *addonsp[NUM_EXT+4]);
if (modifiedgame)
V_DrawSmallScaledPatch(x, y + 4, 0, addonsp[NUM_EXT+2]);
V_DrawSmallScaledPatch(x, y + 4, 0, *addonsp[NUM_EXT+2]);
}
static void M_AddonExec(INT32 ch)
@ -7552,8 +7544,8 @@ static void M_HandleEmblemHints(INT32 choice)
static musicdef_t *curplaying = NULL;
static INT32 st_sel = 0, st_cc = 0;
static tic_t st_time = 0;
static patch_t* st_radio[9];
static patch_t* st_launchpad[4];
static patch_t **st_radio[9];
static patch_t **st_launchpad[4];
static void M_CacheSoundTest(void)
{
@ -7564,14 +7556,14 @@ static void M_CacheSoundTest(void)
for (i = 0; i < 9; i++)
{
buf[7] = (char)('0'+i);
st_radio[i] = W_CachePatchName(buf, PU_PATCH);
st_radio[i] = (patch_t **)W_GetPatchPointerFromName(buf, PU_PATCH);
}
STRBUFCPY(buf, "M_LPADn");
for (i = 0; i < 4; i++)
{
buf[6] = (char)('0'+i);
st_launchpad[i] = W_CachePatchName(buf, PU_PATCH);
st_launchpad[i] = (patch_t **)W_GetPatchPointerFromName(buf, PU_PATCH);
}
}
@ -7608,9 +7600,6 @@ static void M_DrawSoundTest(void)
fixed_t hscale = FRACUNIT/2, vscale = FRACUNIT/2, bounce = 0;
UINT8 frame[4] = {0, 0, -1, SKINCOLOR_RUBY};
if (needpatchrecache)
M_CacheSoundTest();
// let's handle the ticker first. ideally we'd tick this somewhere else, BUT...
if (curplaying)
{
@ -7663,19 +7652,19 @@ static void M_DrawSoundTest(void)
V_DrawStretchyFixedPatch(x, y,
hscale, vscale,
0, st_radio[frame[0]], NULL);
0, *st_radio[frame[0]], NULL);
V_DrawFixedPatch(x, y, FRACUNIT/2, 0, st_launchpad[0], NULL);
V_DrawFixedPatch(x, y, FRACUNIT/2, 0, *st_launchpad[0], NULL);
for (i = 0; i < 9; i++)
{
if (i == frame[2])
{
UINT8 *colmap = R_GetTranslationColormap(TC_RAINBOW, frame[3], GTC_CACHE);
V_DrawFixedPatch(x, y + (frame[1]<<FRACBITS), FRACUNIT/2, 0, st_launchpad[frame[1]+1], colmap);
V_DrawFixedPatch(x, y + (frame[1]<<FRACBITS), FRACUNIT/2, 0, *st_launchpad[frame[1]+1], colmap);
}
else
V_DrawFixedPatch(x, y, FRACUNIT/2, 0, st_launchpad[1], NULL);
V_DrawFixedPatch(x, y, FRACUNIT/2, 0, *st_launchpad[1], NULL);
if ((i % 3) == 2)
{
@ -8258,9 +8247,6 @@ static void M_DrawLoadGameData(void)
if (vid.width != BASEVIDWIDTH*vid.dupx)
hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx);
if (needpatchrecache)
M_CacheLoadGameData();
for (i = -2; i <= 2; i++)
{
savetodraw = (saveSlotSelected + i + numsaves)%numsaves;
@ -8964,7 +8950,6 @@ void M_ForceSaveSlotSelected(INT32 sslot)
// CHARACTER SELECT
// ================
// lactozilla: sometimes the renderer changes and these patches don't exist anymore
static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum)
{
if (!(description[i].picname[0]))
@ -8973,32 +8958,16 @@ static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum)
{
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL];
description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH);
description[i].charpic = (patch_t **)W_GetPatchPointer(sprframe->lumppat[0], PU_PATCH);
}
else
description[i].charpic = W_CachePatchName("MISSING", PU_PATCH);
description[i].charpic = (patch_t **)W_GetPatchPointerFromName("MISSING", PU_PATCH);
}
else
description[i].charpic = W_CachePatchName(description[i].picname, PU_PATCH);
description[i].charpic = (patch_t **)W_GetPatchPointerFromName(description[i].picname, PU_PATCH);
if (description[i].nametag[0])
description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH);
}
static void M_CacheCharacterSelect(void)
{
INT32 i, skinnum;
for (i = 0; i < MAXSKINS; i++)
{
if (!description[i].used)
continue;
// Already set in M_SetupChoosePlayer
skinnum = description[i].skinnum[0];
if ((skinnum != -1) && (R_SkinUsable(-1, skinnum)))
M_CacheCharacterSelectEntry(i, skinnum);
}
description[i].namepic = (patch_t **)W_GetPatchPointerFromName(description[i].nametag, PU_PATCH);
}
static UINT8 M_SetupChoosePlayerDirect(INT32 choice)
@ -9207,10 +9176,6 @@ static void M_DrawSetupChoosePlayerMenu(void)
INT32 x, y;
INT32 w = (vid.width/vid.dupx);
// lactozilla: the renderer changed so recache patches
if (needpatchrecache)
M_CacheCharacterSelect();
if (abs(char_scroll) > FRACUNIT)
char_scroll -= (char_scroll>>2);
else // close enough.
@ -9264,11 +9229,11 @@ static void M_DrawSetupChoosePlayerMenu(void)
{
x = 8;
y = (my+16) - FixedInt(char_scroll);
V_DrawScaledPatch(x, y, 0, description[char_on].charpic);
V_DrawScaledPatch(x, y, 0, *description[char_on].charpic);
if (prev != -1)
V_DrawScaledPatch(x, y - 144, 0, description[prev].charpic);
V_DrawScaledPatch(x, y - 144, 0, *description[prev].charpic);
if (next != -1)
V_DrawScaledPatch(x, y + 144, 0, description[next].charpic);
V_DrawScaledPatch(x, y + 144, 0, *description[next].charpic);
}
// Character description
@ -9292,14 +9257,14 @@ static void M_DrawSetupChoosePlayerMenu(void)
curtextcolor = description[char_on].tagtextcolor;
curoutlinecolor = description[char_on].tagoutlinecolor;
if (curtext[0] == '\0')
curpatch = description[char_on].namepic;
curpatch = *description[char_on].namepic;
if (!curtextcolor)
curtextcolor = charskin->prefcolor;
if (!curoutlinecolor)
curoutlinecolor = col = skincolors[charskin->prefcolor].invcolor;
txsh = oxsh;
ox = 8 + SHORT((description[char_on].charpic)->width)/2;
ox = 8 + SHORT((*description[char_on].charpic)->width)/2;
y = my + 144;
// cur
@ -9330,7 +9295,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
prevtextcolor = description[prev].tagtextcolor;
prevoutlinecolor = description[prev].tagoutlinecolor;
if (prevtext[0] == '\0')
prevpatch = description[prev].namepic;
prevpatch = *description[prev].namepic;
charskin = &skins[description[prev].skinnum[0]];
if (!prevtextcolor)
prevtextcolor = charskin->prefcolor;
@ -9360,7 +9325,7 @@ static void M_DrawSetupChoosePlayerMenu(void)
nexttextcolor = description[next].tagtextcolor;
nextoutlinecolor = description[next].tagoutlinecolor;
if (nexttext[0] == '\0')
nextpatch = description[next].namepic;
nextpatch = *description[next].namepic;
charskin = &skins[description[next].skinnum[0]];
if (!nexttextcolor)
nexttextcolor = charskin->prefcolor;
@ -10582,10 +10547,6 @@ void M_DrawMarathon(void)
angle_t fa;
INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy), xspan = (vid.width/dupz), yspan = (vid.height/dupz), diffx = (xspan - BASEVIDWIDTH)/2, diffy = (yspan - BASEVIDHEIGHT)/2, maxy = BASEVIDHEIGHT + diffy;
// lactozilla: the renderer changed so recache patches
if (needpatchrecache)
M_CacheCharacterSelect();
curbgxspeed = 0;
curbgyspeed = 18;
@ -10719,10 +10680,10 @@ void M_DrawMarathon(void)
if (dispstatus == IT_STRING || dispstatus == IT_WHITESTRING)
{
soffset = 68;
if (description[char_on].charpic->width >= 256)
V_DrawTinyScaledPatch(224, 120, 0, description[char_on].charpic);
if ((*description[char_on].charpic)->width >= 256)
V_DrawTinyScaledPatch(224, 120, 0, *description[char_on].charpic);
else
V_DrawSmallScaledPatch(224, 120, 0, description[char_on].charpic);
V_DrawSmallScaledPatch(224, 120, 0, *description[char_on].charpic);
}
else
soffset = 0;
@ -12836,9 +12797,6 @@ static void M_VideoModeMenu(INT32 choice)
memset(modedescs, 0, sizeof(modedescs));
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
VID_PrepareModeList(); // FIXME: hack
#endif
vidm_nummodes = 0;
vidm_selected = 0;
nummodes = VID_NumModes();

View file

@ -351,7 +351,7 @@ typedef struct
char notes[441];
char picname[8];
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
patch_t *charpic;
patch_t **charpic;
UINT8 prev;
UINT8 next;
@ -360,7 +360,7 @@ typedef struct
SINT8 skinnum[2];
UINT16 oppositecolor;
char nametag[8];
patch_t *namepic;
patch_t **namepic;
UINT16 tagtextcolor;
UINT16 tagoutlinecolor;
} description_t;

View file

@ -29,6 +29,7 @@
#include "r_data.h"
#include "r_things.h" // for R_AddSpriteDefs
#include "r_patch.h"
#include "r_rotsprite.h"
#include "r_sky.h"
#include "r_draw.h"
@ -3703,14 +3704,12 @@ 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
// Free extrasubsectors regardless of the renderer.
HWR_FreeExtraSubsectors();
// Create plane polygons.
if (rendermode == render_opengl)
HWR_SetupLevel();
HWR_LoadLevel();
#endif
// oh god I hope this helps
@ -3796,7 +3795,7 @@ boolean P_LoadLevel(boolean fromnetsave)
}
#ifdef HWRENDER
void HWR_SetupLevel(void)
void HWR_LoadLevel(void)
{
// Lactozilla (December 8, 2019)
// Level setup used to free EVERY mipmap from memory.
@ -4054,6 +4053,13 @@ boolean P_AddWadFile(const char *wadfilename)
//
S_LoadMusicDefs(wadnum);
//
// recache sprite rotation data
//
#ifdef ROTSPRITE
RotSprite_RecreateAll();
#endif
//
// search for maps
//

View file

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

View file

@ -471,7 +471,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
// Allocate space for full size texture, either single patch or 'composite'
// Build the full textures from patches.
// The texture caching system is a little more hungry of memory, but has
// been simplified for the sake of highcolor (lol), dynamic ligthing, & speed.
// been simplified for the sake of highcolor, dynamic ligthing, & speed.
//
// This is not optimised, but it's supposed to be executed only once
// per level, when enough memory is available.
@ -838,8 +838,6 @@ Rloadflats (INT32 i, INT32 w)
patch->lump = texstart + j;
patch->flip = 0;
Z_Unlock(flatlump);
texturewidth[i] = texture->width;
textureheight[i] = texture->height << FRACBITS;
i++;
@ -939,8 +937,6 @@ Rloadtextures (INT32 i, INT32 w)
patch->lump = texstart + j;
patch->flip = 0;
Z_Unlock(patchlump);
texturewidth[i] = texture->width;
textureheight[i] = texture->height << FRACBITS;
i++;

View file

@ -688,14 +688,21 @@ typedef struct
#pragma pack()
#endif
// rotsprite
#ifdef ROTSPRITE
typedef struct
{
patch_t *patch[16][ROTANGLES];
UINT16 cached;
} rotsprite_t;
#endif/*ROTSPRITE*/
UINT8 *data;
void **columnofs;
size_t *columnsize;
} pmcache_t;
typedef struct
{
UINT32 width, height;
INT16 leftoffset, topoffset;
size_t size;
INT32 *map;
pmcache_t cache;
} pixelmap_t;
typedef enum
{
@ -709,24 +716,6 @@ 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.
@ -754,10 +743,6 @@ typedef struct
// Flip bits (1 = flip) to use for view angles 0-7/15.
UINT16 flip;
#ifdef ROTSPRITE
rotsprite_t rotsprite;
#endif
} spriteframe_t;
//

View file

@ -18,7 +18,7 @@
#include "doomdef.h"
#include "doomstat.h"
#include "r_local.h"
#include "st_stuff.h" // need ST_HEIGHT
#include "st_stuff.h"
#include "i_video.h"
#include "v_video.h"
#include "m_misc.h"
@ -65,9 +65,11 @@ lighttable_t *dc_colormap;
INT32 dc_x = 0, dc_yl = 0, dc_yh = 0;
fixed_t dc_iscale, dc_texturemid;
UINT8 *dc_source;
UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit,
// soo lets make it a byte on all system for the ASM code
UINT8 *dc_source;
// -----------------------
// translucency stuff here

View file

@ -150,7 +150,7 @@ consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo,
consvar_t cv_shadow = {"shadow", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_ViewSizeChanged, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_translucency = {"translucency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -180,7 +180,7 @@ void SplitScreen_OnChange(void)
}
// recompute screen size
R_ExecuteSetViewSize();
R_SetViewSize();
if (!demoplayback && !botingame)
{
@ -210,7 +210,7 @@ static void Fov_OnChange(void)
//if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT)
// CV_Set(&cv_fov, cv_fov.defaultvalue);
R_SetViewSize();
R_ViewSizeChanged();
}
static void ChaseCam_OnChange(void)
@ -642,7 +642,7 @@ void R_CheckViewMorph(void)
viewmorph.use = false;
viewmorph.x1 = 0;
if (viewmorph.zoomneeded != FRACUNIT)
R_SetViewSize();
R_ViewSizeChanged();
viewmorph.zoomneeded = FRACUNIT;
return;
@ -692,7 +692,7 @@ void R_CheckViewMorph(void)
if (temp != viewmorph.zoomneeded)
{
viewmorph.zoomneeded = temp;
R_SetViewSize();
R_ViewSizeChanged();
}
zoomfactor = FIXED_TO_FLOAT(viewmorph.zoomneeded);
@ -864,22 +864,22 @@ void R_ApplyViewMorph(void)
//
// R_SetViewSize
// R_ViewSizeChanged
// Do not really change anything here,
// because it might be in the middle of a refresh.
// The change will take effect next refresh.
//
boolean setsizeneeded;
void R_SetViewSize(void)
void R_ViewSizeChanged(void)
{
setsizeneeded = true;
}
//
// R_ExecuteSetViewSize
// R_SetViewSize
//
void R_ExecuteSetViewSize(void)
void R_SetViewSize(void)
{
fixed_t dy;
INT32 i;
@ -981,7 +981,7 @@ void R_Init(void)
//I_OutputMsg("\nR_InitViewBorder");
R_InitViewBorder();
R_SetViewSize(); // setsizeneeded is set true
R_ViewSizeChanged(); // setsizeneeded is set true
//I_OutputMsg("\nR_InitPlanes");
R_InitPlanes();
@ -1542,26 +1542,6 @@ void R_RenderPlayerView(player_t *player)
free(masks);
}
// Lactozilla: Renderer switching
#ifdef HWRENDER
void R_InitHardwareMode(void)
{
HWR_AddSessionCommands();
HWR_Switch();
HWR_LoadTextures(numtextures);
if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))
HWR_SetupLevel();
}
#endif
void R_ReloadHUDGraphics(void)
{
CONS_Debug(DBG_RENDER, "R_ReloadHUDGraphics()...\n");
ST_LoadGraphics();
HU_LoadGraphics();
ST_ReloadSkinFaceGraphics();
}
// =========================================================================
// ENGINE COMMANDS & VARS
// =========================================================================

View file

@ -111,21 +111,14 @@ extern consvar_t cv_tailspickup;
// Called by startup code.
void R_Init(void);
#ifdef HWRENDER
void R_InitHardwareMode(void);
#endif
void R_ReloadHUDGraphics(void);
void R_CheckViewMorph(void);
void R_ApplyViewMorph(void);
// just sets setsizeneeded true
extern boolean setsizeneeded;
void R_ViewSizeChanged(void); // sets setsizeneeded true
void R_SetViewSize(void);
// do it (sometimes explicitly called)
void R_ExecuteSetViewSize(void);
void R_SetupFrame(player_t *player);
void R_SkyboxFrame(player_t *player);

File diff suppressed because it is too large Load diff

View file

@ -15,9 +15,53 @@
#define __R_PATCH__
#include "r_defs.h"
#include "r_patchtrees.h"
#include "w_wad.h"
#include "m_aatree.h"
#include "i_video.h"
#include "doomdef.h"
// Structs
void Patch_InitInfo(wadfile_t *wadfile);
void *Patch_CacheSoftware(UINT16 wad, UINT16 lump, INT32 tag, boolean store);
void *Patch_CacheGL(UINT16 wad, UINT16 lump, INT32 tag, boolean store);
patchtreetype_t Patch_GetTreeType(rendermode_t mode);
patchtree_t *Patch_GetRendererTree(UINT16 wadnum, rendermode_t mode);
aatree_t *Patch_GetRendererBaseSubTree(UINT16 wadnum, rendermode_t mode);
#ifdef ROTSPRITE
aatree_t *Patch_GetRendererRotatedSubTree(UINT16 wadnum, rendermode_t mode, boolean flip);
#endif
void *GetRendererPatchInfo(UINT16 wadnum, UINT16 lumpnum, rendermode_t mode);
void SetRendererPatchInfo(UINT16 wadnum, UINT16 lumpnum, rendermode_t mode, void *ptr);
void UpdateCurrentPatchInfo(UINT16 wadnum, UINT16 lumpnum, rendermode_t mode);
#ifdef ROTSPRITE
void *GetRotatedPatchInfo(UINT16 wadnum, UINT16 lumpnum, rendermode_t mode, boolean flip);
void SetRotatedPatchInfo(UINT16 wadnum, UINT16 lumpnum, rendermode_t mode, boolean flip, void *ptr);
void UpdateCurrentRotatedPatchInfo(UINT16 wadnum, UINT16 lumpnum, rendermode_t mode, INT32 rollangle, boolean flip);
#endif
struct patchreference_s
{
struct patchreference_s *prev, *next;
UINT16 wad, lump;
INT32 tag;
boolean flip;
INT32 rollangle;
void *ptr;
};
typedef struct patchreference_s patchreference_t;
patchreference_t *Patch_FindReference(UINT16 wad, UINT16 lump, INT32 rollangle, boolean flip);
patchreference_t *Patch_StoreReference(UINT16 wad, UINT16 lump, INT32 tag, void *ptr, INT32 rollangle, boolean flip);
void Patch_UpdateReferences(void);
void Patch_FreeReferences(void);
// This should be in r_rotsprite.h, but that file
// includes this one, so this file can't include that one.
typedef enum
{
ROTAXIS_X, // Roll (the default)
@ -33,19 +77,21 @@ typedef struct
typedef struct
{
spriteframepivot_t pivot[64];
spriteframepivot_t pivot[64]; // Max number of frames in a sprite.
boolean available;
} spriteinfo_t;
boolean PixelMap_ApplyToColumn(pixelmap_t *pmap, INT32 *map, patch_t *patch, UINT8 *post, size_t *colsize, boolean flipped);
UINT8 *Patch_GetPixel(patch_t *patch, INT32 x, INT32 y, boolean flip);
// Conversions between patches / flats / textures...
boolean R_CheckIfPatch(lumpnum_t lump);
void R_TextureToFlat(size_t tex, UINT8 *flat);
void R_PatchToFlat(patch_t *patch, UINT8 *flat);
void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip);
patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency);
patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize);
patch_t *R_TransparentFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize);
// Portable Network Graphics
// PNGs
boolean R_IsLumpPNG(const UINT8 *d, size_t s);
#define W_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic
@ -62,13 +108,24 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
// Sprite rotation
#ifdef ROTSPRITE
INT32 R_GetRollAngle(angle_t rollangle);
void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip);
void R_FreeSingleRotSprite(spritedef_t *spritedef);
void R_FreeSkinRotSprite(size_t skinnum);
// Arguments for RotSprite_ functions.
typedef struct
{
INT32 rollangle;
boolean flip;
boolean sprite;
spriteframepivot_t *pivot;
} rotsprite_vars_t;
patch_t *Patch_CacheRotated(UINT32 lumpnum, INT32 tag, rotsprite_vars_t rsvars, boolean store);
patch_t *Patch_CacheRotatedForSprite(UINT32 lumpnum, INT32 tag, rotsprite_vars_t rsvars, boolean store);
patch_t *Patch_CacheRotatedPwad(UINT16 wad, UINT16 lump, INT32 tag, rotsprite_vars_t rsvars, boolean store);
patch_t *Patch_CacheRotatedForSpritePwad(UINT16 wad, UINT16 lump, INT32 tag, rotsprite_vars_t rsvars, boolean store);
patch_t *Patch_CacheRotatedName(const char *name, INT32 tag, rotsprite_vars_t rsvars, boolean store);
patch_t *Patch_CacheRotatedLongName(const char *name, INT32 tag, rotsprite_vars_t rsvars, boolean store);
extern fixed_t rollcosang[ROTANGLES];
extern fixed_t rollsinang[ROTANGLES];
void R_FreeAllRotSprite(void);
#endif
#endif // __R_PATCH__

36
src/r_patchtrees.h Normal file
View file

@ -0,0 +1,36 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2020 by Jaime "Lactozilla" Passos.
// Copyright (C) 2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_patchtrees.h
/// \brief Patch tree definitions.
#ifndef __R_PATCHTREES__
#define __R_PATCHTREES__
#include "m_aatree.h"
// Renderer tree types
typedef enum patchtreetype_e
{
patchtree_software, // Software.
patchtree_mipmap, // OpenGL, or any hardware renderer.
num_patchtrees,
} patchtreetype_t;
// Renderer patch trees
typedef struct patchtree_s
{
aatree_t *base;
#ifdef ROTSPRITE
aatree_t *rotated[2]; // Sprite rotation stores flipped and non-flipped variants of a patch.
#endif
} patchtree_t;
#endif // __R_PATCHTREES__

437
src/r_rotsprite.c Normal file
View file

@ -0,0 +1,437 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2019-2020 by Jaime "Lactozilla" Passos.
// Copyright (C) 2019-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_rotsprite.c
/// \brief Rotated patch generation.
#include "byteptr.h"
#include "dehacked.h"
#include "i_video.h"
#include "r_data.h"
#include "r_draw.h"
#include "r_patch.h"
#include "r_rotsprite.h"
#include "r_things.h"
#include "z_zone.h"
#include "w_wad.h"
#ifdef HWRENDER
#include "hardware/hw_glob.h"
#endif
#ifdef ROTSPRITE
fixed_t rollcosang[ROTANGLES];
fixed_t rollsinang[ROTANGLES];
static unsigned char imgbuf[1<<26];
/** Get a rotation angle from a roll angle.
*
* \param rollangle The roll angle.
* \return The rotation angle.
*/
INT32 R_GetRollAngle(angle_t rollangle)
{
INT32 ra = AngleFixed(rollangle)>>FRACBITS;
#if (ROTANGDIFF > 1)
ra += (ROTANGDIFF/2);
#endif
ra /= ROTANGDIFF;
ra %= ROTANGLES;
return ra;
}
/** Get rotated sprite info for a patch.
*
* \param wad The patch's wad number.
* \param lump The patch's lump number.
* \param tag Zone memory tag.
* \param rsvars Sprite rotation variables.
* \param store Store the rotated patch into the patch reference list.
* \return The rotated sprite info.
* \sa Patch_CacheRotatedPwad
*/
rotsprite_t *RotSprite_GetFromPatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag, rotsprite_vars_t rsvars, boolean store)
{
void *cache = GetRotatedPatchInfo(wad, lump, rendermode, rsvars.flip);
if (!GetRotatedPatchInfo(wad, lump, rendermode, rsvars.flip))
{
rotsprite_t *ptr = Z_Calloc(sizeof(rotsprite_t), tag, &cache);
ptr->lumpnum = WADANDLUMP(wad, lump);
SetRotatedPatchInfo(wad, lump, rendermode, rsvars.flip, cache);
return (void *)ptr;
}
else
Z_ChangeTag(cache, tag);
// insert into list
if (store)
Patch_StoreReference(wad, lump, tag, cache, rsvars.rollangle, rsvars.flip);
return cache;
}
rotsprite_t *RotSprite_GetFromPatchNum(lumpnum_t lumpnum, INT32 tag, rotsprite_vars_t rsvars, boolean store)
{
return RotSprite_GetFromPatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag,rsvars,store);
}
rotsprite_t *RotSprite_GetFromPatchName(const char *name, INT32 tag, rotsprite_vars_t rsvars, boolean store)
{
lumpnum_t num = W_CheckNumForName(name);
if (num == LUMPERROR)
return RotSprite_GetFromPatchNum(W_GetNumForName("MISSING"), tag, rsvars, store);
return RotSprite_GetFromPatchNum(num, tag, rsvars, store);
}
rotsprite_t *RotSprite_GetFromPatchLongName(const char *name, INT32 tag, rotsprite_vars_t rsvars, boolean store)
{
lumpnum_t num = W_CheckNumForLongName(name);
if (num == LUMPERROR)
return RotSprite_GetFromPatchNum(W_GetNumForLongName("MISSING"), tag, rsvars, store);
return RotSprite_GetFromPatchNum(num, tag, rsvars, store);
}
/** Creates a rotated sprite by calculating a pixel map.
* Caches column data and patches between levels.
*
* \param rotsprite The rotated sprite info.
* \param rsvars Sprite rotation variables.
* \sa RotSprite_CreatePatch
*/
void RotSprite_Create(rotsprite_t *rotsprite, rotsprite_vars_t rsvars)
{
patch_t *patch;
pixelmap_t *pixelmap = &rotsprite->pixelmap[rsvars.rollangle];
lumpnum_t lump = rotsprite->lumpnum;
// Sprite lump is invalid.
if (lump == LUMPERROR)
return;
// Cache the patch.
patch = (patch_t *)W_CacheSoftwarePatchNum(lump, PU_CACHE);
// If this pixel map was not generated, do it.
if (!rotsprite->cached[rsvars.rollangle])
{
RotSprite_CreatePixelMap(patch, pixelmap, rsvars);
rotsprite->cached[rsvars.rollangle] = true;
}
}
/** Caches columns of a rotated sprite, applying the pixel map.
*
* \param pixelmap The source pixel map.
* \param cache The destination pixel map cache.
* \param patch The source patch.
* \param rsvars Sprite rotation variables.
* \sa RotSprite_CreatePatch
*/
void RotSprite_CreateColumns(pixelmap_t *pixelmap, pmcache_t *cache, patch_t *patch, rotsprite_vars_t rsvars)
{
void **colofs;
UINT8 *data;
boolean *colexists;
size_t *coltbl;
static UINT8 pixelmapcol[0xFFFF];
size_t totalsize = 0, colsize = 0;
INT16 width = pixelmap->width, x;
Z_Malloc(width * sizeof(void **), PU_LEVEL, &cache->columnofs);
Z_Malloc(width * sizeof(void *), PU_LEVEL, &cache->columnsize);
colexists = Z_Calloc(width * sizeof(boolean), PU_STATIC, NULL);
coltbl = Z_Calloc(width * sizeof(size_t), PU_STATIC, NULL);
colofs = cache->columnofs;
for (x = 0; x < width; x++)
{
size_t colpos = totalsize;
colexists[x] = PixelMap_ApplyToColumn(pixelmap, &(pixelmap->map[x * pixelmap->height]), patch, pixelmapcol, &colsize, rsvars.flip);
cache->columnsize[x] = colsize;
totalsize += colsize;
// copy pixels
if (colexists[x])
{
data = Z_Realloc(cache->data, totalsize, PU_LEVEL, &cache->data);
data += colpos;
coltbl[x] = colpos;
M_Memcpy(data, pixelmapcol, colsize);
}
}
for (x = 0; x < width; x++)
{
if (colexists[x])
colofs[x] = &(cache->data[coltbl[x]]);
else
colofs[x] = NULL;
}
Z_Free(colexists);
Z_Free(coltbl);
}
/** Calculates the dimensions of a rotated rectangle.
*
* \param width Rectangle width.
* \param height Rectangle height.
* \param ca Cosine for the angle.
* \param sa Sine for the angle.
* \param pivot Rotation pivot.
* \param newwidth The width for the rotated rectangle.
* \param newheight The height for the rotated rectangle.
* \sa RotSprite_CreatePixelMap
*/
static void CalculateRotatedRectangleDimensions(INT16 width, INT16 height, fixed_t ca, fixed_t sa, spriteframepivot_t *pivot, INT16 *newwidth, INT16 *newheight)
{
if (pivot)
{
*newwidth = width + (height * 2);
*newheight = height + (width * 2);
}
else
{
fixed_t fw = (width * FRACUNIT);
fixed_t fh = (height * FRACUNIT);
INT32 w1 = abs(FixedMul(fw, ca) - FixedMul(fh, sa));
INT32 w2 = abs(FixedMul(-fw, ca) - FixedMul(fh, sa));
INT32 h1 = abs(FixedMul(fw, sa) + FixedMul(fh, ca));
INT32 h2 = abs(FixedMul(-fw, sa) + FixedMul(fh, ca));
w1 = FixedInt(FixedCeil(w1 + (FRACUNIT/2)));
w2 = FixedInt(FixedCeil(w2 + (FRACUNIT/2)));
h1 = FixedInt(FixedCeil(h1 + (FRACUNIT/2)));
h2 = FixedInt(FixedCeil(h2 + (FRACUNIT/2)));
*newwidth = max(width, max(w1, w2));
*newheight = max(height, max(h1, h2));
}
}
/** Creates a pixel map for a rotated patch.
*
* \param patch The source patch.
* \param pixelmap The destination pixel map.
* \param rsvars Sprite rotation variables.
* \sa RotSprite_CreatePixelMap
*/
void RotSprite_CreatePixelMap(patch_t *patch, pixelmap_t *pixelmap, rotsprite_vars_t rsvars)
{
size_t size;
INT32 dx, dy;
INT16 newwidth, newheight;
fixed_t ca = rollcosang[rsvars.rollangle];
fixed_t sa = rollsinang[rsvars.rollangle];
INT16 width = SHORT(patch->width);
INT16 height = SHORT(patch->height);
INT16 leftoffset = SHORT(patch->leftoffset);
spriteframepivot_t pivot;
INT16 rotxcenter, rotycenter;
spriteframepivot_t *spritepivot = rsvars.pivot;
pivot.x = (spritepivot ? spritepivot->x : (rsvars.sprite ? leftoffset : (width / 2)));
pivot.y = (spritepivot ? spritepivot->y : (height / 2));
if (rsvars.flip)
{
pivot.x = width - pivot.x;
leftoffset = width - leftoffset;
}
// Find the dimensions of the rotated patch.
CalculateRotatedRectangleDimensions(width, height, ca, sa, (spritepivot ? &pivot : NULL), &newwidth, &newheight);
rotxcenter = (newwidth / 2);
rotycenter = (newheight / 2);
size = (newwidth * newheight);
// Build pixel map.
if (pixelmap->map)
Z_Free(pixelmap->map);
pixelmap->map = Z_Calloc(size * sizeof(INT32) * 2, PU_STATIC, NULL);
pixelmap->size = size;
pixelmap->width = newwidth;
pixelmap->height = newheight;
// Calculate the position of every pixel.
for (dy = 0; dy < newheight; dy++)
{
for (dx = 0; dx < newwidth; dx++)
{
INT32 dst = (dx*newheight)+dy;
INT32 x = (dx-rotxcenter) << FRACBITS;
INT32 y = (dy-rotycenter) << FRACBITS;
INT32 sx = FixedMul(x, ca) + FixedMul(y, sa) + (pivot.x << FRACBITS);
INT32 sy = -FixedMul(x, sa) + FixedMul(y, ca) + (pivot.y << FRACBITS);
sx >>= FRACBITS;
sy >>= FRACBITS;
pixelmap->map[dst] = sy;
pixelmap->map[dst + size] = sx;
}
}
// Set offsets.
if (rsvars.sprite)
{
pixelmap->leftoffset = (newwidth / 2) + (leftoffset - pivot.x);
pixelmap->topoffset = (newheight / 2) + (SHORT(patch->topoffset) - pivot.y);
pixelmap->topoffset += FEETADJUST>>FRACBITS;
}
else
{
pixelmap->leftoffset = leftoffset;
pixelmap->topoffset = SHORT(patch->topoffset);
}
}
/** Creates a rotated patch from sprite rotation data.
*
* \param rotsprite The rotated sprite info.
* \param rsvars Sprite rotation variables.
* \return The rotated patch.
* \sa RotSprite_CreatePixelMap
*/
patch_t *RotSprite_CreatePatch(rotsprite_t *rotsprite, rotsprite_vars_t rsvars)
{
UINT8 *img, *imgptr = imgbuf;
pixelmap_t *pixelmap = &rotsprite->pixelmap[rsvars.rollangle];
patch_t *patch = (patch_t *)W_CacheSoftwarePatchNum(rotsprite->lumpnum, PU_CACHE);
pmcache_t *pmcache = &pixelmap->cache;
UINT32 x, width = pixelmap->width;
UINT8 *colpointers;
void **colofs;
size_t size = 0;
WRITEINT16(imgptr, (INT16)width);
WRITEINT16(imgptr, (INT16)pixelmap->height);
WRITEINT16(imgptr, pixelmap->leftoffset);
WRITEINT16(imgptr, pixelmap->topoffset);
colpointers = imgptr;
imgptr += width*4;
if (!pmcache->columnofs)
RotSprite_CreateColumns(pixelmap, pmcache, patch, rsvars);
colofs = pmcache->columnofs;
for (x = 0; x < width; x++)
{
column_t *column = (column_t *)(colofs[x]);
WRITEINT32(colpointers, imgptr - imgbuf);
if (column)
{
size = pmcache->columnsize[x];
WRITEMEM(imgptr, column, size);
}
else
WRITEUINT8(imgptr, 0xFF);
}
size = imgptr-imgbuf;
img = Z_Malloc(size, PU_STATIC, NULL);
M_Memcpy(img, imgbuf, size);
#ifdef HWRENDER
// Ugh
if (rendermode == render_opengl)
{
GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
grPatch->patch = (patch_t *)img;
rotsprite->patches[rsvars.rollangle] = (patch_t *)grPatch;
HWR_MakePatch((patch_t *)img, grPatch, grPatch->mipmap, false);
}
else
#endif
rotsprite->patches[rsvars.rollangle] = (patch_t *)img;
return rotsprite->patches[rsvars.rollangle];
}
/** Recreates sprite rotation data in memory.
*
* \param rotsprite The rotated sprite info.
* \sa RotSprite_RecreateAll
* \sa Patch_CacheRotated
* \sa Patch_CacheRotatedForSprite
*/
void RotSprite_Recreate(rotsprite_t *rotsprite, rendermode_t rmode)
{
INT32 ang;
for (ang = 0; ang < ROTANGLES; ang++)
{
if (rotsprite->cached[ang])
{
pixelmap_t *pixelmap = &rotsprite->pixelmap[ang];
pmcache_t *cache = &pixelmap->cache;
rotsprite->cached[ang] = false;
if (pixelmap->map)
Z_Free(pixelmap->map);
if (cache->columnofs)
Z_Free(cache->columnofs);
if (cache->columnsize)
Z_Free(cache->columnsize);
if (cache->data)
Z_Free(cache->data);
pixelmap->map = NULL;
cache->columnofs = NULL;
cache->columnsize = NULL;
cache->data = NULL;
#ifdef HWRENDER
if (rmode == render_opengl)
{
GLPatch_t *grPatch = (GLPatch_t *)(rotsprite->patches[ang]);
if (grPatch && grPatch->patch)
{
Z_Free(grPatch->patch);
grPatch->patch = NULL;
}
}
else
#endif
if (rotsprite->patches[ang])
Z_Free(rotsprite->patches[ang]);
rotsprite->patches[ang] = NULL;
if (rotsprite->vars.sprite)
Patch_CacheRotatedForSprite(rotsprite->lumpnum, rotsprite->tag, rotsprite->vars, false);
else
Patch_CacheRotated(rotsprite->lumpnum, rotsprite->tag, rotsprite->vars, false);
}
}
}
/** Recreates all sprite rotation data in memory.
*
* \sa RotSprite_Recreate
*/
void RotSprite_RecreateAll(void)
{
// TODO: Write this in a more efficient way.
INT32 w, l, r, f;
for (r = render_first; r < render_last; r++)
for (w = 0; w < numwadfiles; w++)
for (l = 0; l < wadfiles[w]->numlumps; l++)
{
for (f = 0; f < 2; f++)
{
rotsprite_t *rotsprite = GetRotatedPatchInfo(w, l, r, (f ? true : false));
if (rotsprite)
RotSprite_Recreate(rotsprite, r);
}
}
}
#endif // ROTSPRITE

53
src/r_rotsprite.h Normal file
View file

@ -0,0 +1,53 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2019-2020 by Jaime "Lactozilla" Passos.
// Copyright (C) 2019-2020 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file r_rotsprite.h
/// \brief Rotated patch generation.
#ifndef __R_ROTSPRITE__
#define __R_ROTSPRITE__
#include "r_defs.h"
#include "r_patch.h"
#include "doomtype.h"
#ifdef ROTSPRITE
INT32 R_GetRollAngle(angle_t rollangle);
typedef struct
{
pixelmap_t pixelmap[ROTANGLES];
patch_t *patches[ROTANGLES];
boolean cached[ROTANGLES];
UINT32 lumpnum;
rotsprite_vars_t vars;
INT32 tag;
} rotsprite_t;
rotsprite_t *RotSprite_GetFromPatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag, rotsprite_vars_t rsvars, boolean store);
rotsprite_t *RotSprite_GetFromPatchNum(lumpnum_t lumpnum, INT32 tag, rotsprite_vars_t rsvars, boolean store);
rotsprite_t *RotSprite_GetFromPatchName(const char *name, INT32 tag, rotsprite_vars_t rsvars, boolean store);
rotsprite_t *RotSprite_GetFromPatchLongName(const char *name, INT32 tag, rotsprite_vars_t rsvars, boolean store);
void RotSprite_Create(rotsprite_t *rotsprite, rotsprite_vars_t rsvars);
void RotSprite_CreateColumns(pixelmap_t *pixelmap, pmcache_t *cache, patch_t *patch, rotsprite_vars_t rsvars);
void RotSprite_CreatePixelMap(patch_t *patch, pixelmap_t *pixelmap, rotsprite_vars_t rsvars);
patch_t *RotSprite_CreatePatch(rotsprite_t *rotsprite, rotsprite_vars_t rsvars);
void RotSprite_Recreate(rotsprite_t *rotsprite, rendermode_t rmode);
void RotSprite_RecreateAll(void);
void RotSprite_InitPatchTree(patchtree_t *rcache);
void RotSprite_AllocCurrentPatchInfo(patchinfo_t *patchinfo, UINT16 lumpnum);
int RotSprite_GetCurrentPatchInfoIdx(INT32 rollangle, boolean flip);
#endif // ROTSPRITE
#endif // __R_ROTSPRITE__

View file

@ -54,9 +54,6 @@ INT32 globallevelskynum;
Called at loadlevel after skytexture is set, or when sky texture changes.
\warning wallcolfunc should be set at R_ExecuteSetViewSize()
I don't bother because we don't use low detail anymore
\return void
*/
void R_SetupSkyDraw(void)

View file

@ -12,6 +12,7 @@
/// \brief Refresh of things, i.e. objects represented by sprites
#include "doomdef.h"
#include "byteptr.h"
#include "console.h"
#include "g_game.h"
#include "r_local.h"
@ -25,6 +26,7 @@
#include "i_system.h"
#include "r_things.h"
#include "r_patch.h"
#include "r_rotsprite.h"
#include "r_plane.h"
#include "r_portal.h"
#include "p_tick.h"
@ -96,7 +98,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
{
char cn = R_Frame2Char(frame), cr = R_Rotation2Char(rotation); // for debugging
INT32 r, ang;
INT32 r;
lumpnum_t lumppat = wad;
lumppat <<= 16;
lumppat += lump;
@ -104,16 +106,6 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
if (maxframe ==(size_t)-1 || frame > maxframe)
maxframe = frame;
// rotsprite
#ifdef ROTSPRITE
sprtemp[frame].rotsprite.cached = 0;
for (r = 0; r < 16; r++)
{
for (ang = 0; ang < ROTANGLES; ang++)
sprtemp[frame].rotsprite.patch[r][ang] = NULL;
}
#endif/*ROTSPRITE*/
if (rotation == 0)
{
// the lump should be used for all rotations
@ -240,9 +232,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
// if so, it might patch only certain frames, not all
if (spritedef->numframes) // (then spriteframes is not null)
{
#ifdef ROTSPRITE
R_FreeSingleRotSprite(spritedef);
#endif
// copy the already defined sprite frames
M_Memcpy(sprtemp, spritedef->spriteframes,
spritedef->numframes * sizeof (spriteframe_t));
@ -397,9 +386,6 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16
if (spritedef->numframes && // has been allocated
spritedef->numframes < maxframe) // more frames are defined ?
{
#ifdef ROTSPRITE
R_FreeSingleRotSprite(spritedef);
#endif
Z_Free(spritedef->spriteframes);
spritedef->spriteframes = NULL;
}
@ -607,7 +593,7 @@ void R_DrawMaskedColumn(column_t *column)
INT32 topscreen;
INT32 bottomscreen;
fixed_t basetexturemid;
INT32 topdelta, prevdelta = 0;
INT32 topdelta = 0, prevdelta = 0;
basetexturemid = dc_texturemid;
@ -671,8 +657,8 @@ void R_DrawFlippedMaskedColumn(column_t *column)
INT32 topscreen;
INT32 bottomscreen;
fixed_t basetexturemid = dc_texturemid;
INT32 topdelta, prevdelta = -1;
UINT8 *d,*s;
INT32 topdelta = 0, prevdelta = -1;
UINT8 *d, *s;
for (; column->topdelta != 0xff ;)
{
@ -744,6 +730,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
fixed_t this_scale = vis->mobj->scale;
INT32 x1, x2;
INT64 overflow_test;
int colfunctype = BASEDRAWFUNC;
if (!patch)
return;
@ -760,12 +747,11 @@ static void R_DrawVisSprite(vissprite_t *vis)
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
}
colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere.
dc_colormap = vis->colormap;
if (!(vis->cut & SC_PRECIP) && (vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash"
{
// translate certain pixels to white
colfunc = colfuncs[COLDRAWFUNC_TRANS];
colfunctype = COLDRAWFUNC_TRANS;
if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized)
dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
else if (vis->mobj->type == MT_METALSONIC_BATTLE)
@ -775,7 +761,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
else if (vis->mobj->color && vis->transmap) // Color mapping
{
colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS];
colfunctype = COLDRAWFUNC_TRANSTRANS;
dc_transmap = vis->transmap;
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
@ -799,13 +785,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
else if (vis->transmap)
{
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
colfunctype = COLDRAWFUNC_FUZZY;
dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table
}
else if (vis->mobj->color)
{
// translate green skin to another color
colfunc = colfuncs[COLDRAWFUNC_TRANS];
colfunctype = COLDRAWFUNC_TRANS;
// New colormap stuff for skins Tails 06-07-2002
if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
@ -830,7 +816,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome.
{
colfunc = colfuncs[COLDRAWFUNC_TRANS];
colfunctype = COLDRAWFUNC_TRANS;
dc_translation = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE);
}
@ -890,6 +876,8 @@ static void R_DrawVisSprite(vissprite_t *vis)
localcolfunc = (vis->cut & SC_VFLIP) ? R_DrawFlippedMaskedColumn : R_DrawMaskedColumn;
lengthcol = SHORT(patch->height);
colfunc = colfuncs[colfunctype];
// Split drawing loops for paper and non-paper to reduce conditional checks per sprite
if (vis->scalestep)
{
@ -925,9 +913,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
{
#ifdef RANGECHECK
texturecolumn = frac>>FRACBITS;
texturecolumn = (frac>>FRACBITS);
if (texturecolumn < 0 || texturecolumn >= pwidth)
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
I_Error("R_DrawVisSprite: bad texturecolumn at %d from end", vis->x2 - dc_x);
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
#else
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS]));
@ -1394,11 +1382,11 @@ static void R_ProjectSprite(mobj_t *thing)
INT32 light = 0;
fixed_t this_scale = thing->scale;
// rotsprite
patch_t *spr_patch = NULL;
fixed_t spr_width, spr_height;
fixed_t spr_offset, spr_topoffset;
#ifdef ROTSPRITE
patch_t *rotsprite = NULL;
INT32 rollangle = 0;
#endif
@ -1443,7 +1431,7 @@ static void R_ProjectSprite(mobj_t *thing)
thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite];
#ifdef ROTSPRITE
sprinfo = NULL;
sprinfo = &spriteinfo[thing->sprite];
#endif
frame = thing->frame&FF_FRAMEMASK;
}
@ -1452,7 +1440,7 @@ static void R_ProjectSprite(mobj_t *thing)
{
sprdef = &sprites[thing->sprite];
#ifdef ROTSPRITE
sprinfo = NULL;
sprinfo = &spriteinfo[thing->sprite];
#endif
if (frame >= sprdef->numframes)
@ -1525,23 +1513,30 @@ static void R_ProjectSprite(mobj_t *thing)
spr_topoffset = spritecachedinfo[lump].topoffset;
#ifdef ROTSPRITE
if (thing->rollangle)
rollangle = R_GetRollAngle(thing->rollangle);
if (rollangle)
{
rollangle = R_GetRollAngle(thing->rollangle);
if (!(sprframe->rotsprite.cached & (1<<rot)))
R_CacheRotSprite(thing->sprite, frame, sprinfo, sprframe, rot, flip);
rotsprite = sprframe->rotsprite.patch[rot][rollangle];
if (rotsprite != NULL)
{
spr_width = SHORT(rotsprite->width) << FRACBITS;
spr_height = SHORT(rotsprite->height) << FRACBITS;
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
spriteframepivot_t *pivot = (sprinfo->available) ? &sprinfo->pivot[(thing->frame & FF_FRAMEMASK)] : NULL;
static rotsprite_vars_t rsvars;
patch_t *rotpatch;
rsvars.rollangle = rollangle;
rsvars.sprite = true;
rsvars.pivot = pivot;
rsvars.flip = (!!flip);
rotpatch = Patch_CacheRotatedForSprite(sprframe->lumppat[rot], PU_LEVEL, rsvars, false);
spr_patch = rotpatch;
spr_width = SHORT(rotpatch->width) << FRACBITS;
spr_height = SHORT(rotpatch->height) << FRACBITS;
spr_offset = SHORT(rotpatch->leftoffset) << FRACBITS;
spr_topoffset = SHORT(rotpatch->topoffset) << FRACBITS;
// flip -> rotate, not rotate -> flip
flip = 0;
}
#endif
#endif // ROTSPRITE
flip = !flip != !hflip;
@ -1794,6 +1789,7 @@ static void R_ProjectSprite(mobj_t *thing)
iscale = FixedDiv(FRACUNIT, xscale);
// Flipping
if (flip)
{
vis->startfrac = spr_width-1;
@ -1813,12 +1809,9 @@ static void R_ProjectSprite(mobj_t *thing)
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
#ifdef ROTSPRITE
if (rotsprite != NULL)
vis->patch = rotsprite;
else
#endif
vis->patch = W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
if (spr_patch == NULL)
spr_patch = W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
vis->patch = spr_patch;
//
// determine the colormap (lightlevel & special effects)

View file

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

View file

@ -30,10 +30,6 @@
#define NUMSCREENS 5
#endif
// Size of statusbar.
#define ST_HEIGHT 32
#define ST_WIDTH 320
// used now as a maximum video mode size for extra vesa modes.
// we try to re-allocate a minimum of buffers for stability of the memory,
@ -48,34 +44,40 @@
typedef struct viddef_s
{
INT32 modenum; // vidmode num indexes videomodes list
UINT8 *buffer; // screen buffers
UINT8 *direct; // direct screen buffer (DOS VGA)
UINT8 *buffer; // invisible screens buffer
INT32 width, height; // screen dimensions
size_t rowbytes; // bytes per scanline of the VIDEO mode
INT32 width; // PIXELS per scanline
INT32 height;
union { // don't need numpages for OpenGL, so we can use it for fullscreen/windowed mode
INT32 numpages; // always 1, page flipping todo
INT32 windowed; // windowed or fullscren mode?
} u;
INT32 recalc; // if true, recalc vid-based stuff
UINT8 *direct; // linear frame buffer, or vga base mem.
INT32 dupx, dupy; // scale 1, 2, 3 value for menus & overlays
INT32/*fixed_t*/ fdupx, fdupy; // same as dupx, dupy, but exact value when aspect ratio isn't 320/200
INT32 bpp; // BYTES per pixel: 1 = 256color, 2 = highcolor
INT32 baseratio; // Used to get the correct value for lighting walls
INT32 recalc; // if true, recalc vid-based stuff
INT32 numpages; // page flipping
INT32 windowed; // windowed or fullscreen mode? (DirectDraw)
// for Win32 version
DNWH WndParent; // handle of the application's window
INT32 dupx, dupy; // scale 1, 2, 3 value for menus & overlays
INT32/*fixed_t*/ fdupx, fdupy; // same as dupx, dupy, but exact value when aspect ratio isn't 320/200
UINT8 smalldupx, smalldupy; // factor for a little bit of scaling
UINT8 meddupx, meddupy; // factor for moderate, but not full, scaling
#ifdef HWRENDER
INT32/*fixed_t*/ fsmalldupx, fsmalldupy;
INT32/*fixed_t*/ fmeddupx, fmeddupy;
INT32 glstate;
#endif
// for Win32 version
#if defined(_WINDOWS)
DNWH WndParent; // handle of the application's window
#endif
} viddef_t;
#define VIDWIDTH vid.width
#define VIDHEIGHT vid.height
enum
{
VID_GL_LIBRARY_NOTLOADED = 0,
VID_GL_LIBRARY_LOADED = 1,
VID_GL_LIBRARY_ERROR = -1,
};
// internal additional info for vesa modes only
typedef struct
@ -83,6 +85,7 @@ typedef struct
INT32 vesamode; // vesa mode number plus LINEAR_MODE bit
void *plinearmem; // linear address of start of frame buffer
} vesa_extra_t;
// a video modes from the video modes list,
// note: video mode 0 is always standard VGA320x200.
typedef struct vmode_s
@ -171,12 +174,11 @@ extern boolean R_SSE2;
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;
void SCR_ChangeRenderer(void);
void SCR_SetTargetRenderer(void);
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
extern CV_PossibleValue_t cv_renderer_t[];
@ -185,20 +187,25 @@ extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_re
#ifdef HWRENDER
extern consvar_t cv_newrenderer;
#endif
// wait for page flipping to end or not
extern consvar_t cv_vidwait;
extern consvar_t cv_vidwait; // wait for page flipping to end or not
// Initialize the screen
void SCR_Startup(void);
// Change video mode, only at the start of a refresh.
void SCR_SetMode(void);
// Set drawer functions for Software
void SCR_SetDrawFuncs(void);
// Recalc screen size dependent stuff
void SCR_Recalc(void);
// Check parms once at startup
void SCR_CheckDefaultMode(void);
// Set the mode number which is saved in the config
void SCR_SetDefaultMode (void);
void SCR_Startup (void);
// Set the mode number which is saved in the config
void SCR_SetDefaultMode(void);
FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);

View file

@ -283,6 +283,8 @@
<ClInclude Include="..\r_main.h" />
<ClInclude Include="..\r_plane.h" />
<ClInclude Include="..\r_patch.h" />
<ClInclude Include="..\r_rotsprite.h" />
<ClInclude Include="..\r_patchtrees.h" />
<ClInclude Include="..\r_portal.h" />
<ClInclude Include="..\r_segs.h" />
<ClInclude Include="..\r_skins.h" />
@ -447,7 +449,8 @@
</ClCompile>
<ClCompile Include="..\r_main.c" />
<ClCompile Include="..\r_plane.c" />
<ClCompile Include="..\r_patch.c" />
<ClCompile Include="..\r_patch.c" />
<ClCompile Include="..\r_rotsprite.c" />
<ClCompile Include="..\r_portal.c" />
<ClCompile Include="..\r_segs.c" />
<ClCompile Include="..\r_skins.c" />

View file

@ -474,6 +474,12 @@
<ClInclude Include="..\r_patch.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\r_rotsprite.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\r_patchtrees.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\r_portal.h">
<Filter>R_Rend</Filter>
</ClInclude>
@ -946,6 +952,9 @@
<ClCompile Include="..\r_patch.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\r_rotsprite.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\r_portal.c">
<Filter>R_Rend</Filter>
</ClCompile>

View file

@ -73,6 +73,7 @@
#include "../console.h"
#include "../command.h"
#include "../r_main.h"
#include "../r_patch.h" // Patch_UpdateReferences
#include "../lua_hook.h"
#include "sdlmain.h"
#ifdef HWRENDER
@ -95,7 +96,7 @@ static INT32 numVidModes = -1;
static char vidModeName[33][32]; // allow 33 different modes
rendermode_t rendermode = render_soft;
static rendermode_t chosenrendermode = render_soft; // set by command line arguments
rendermode_t chosenrendermode = render_none; // set by command line arguments
boolean highcolor = false;
@ -105,9 +106,8 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff
static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
UINT8 graphics_started = 0; // Is used in console.c and screen.c
INT32 vid_opengl_state = 0;
// To disable fullscreen at startup; is set in VID_PrepareModeList
// To disable fullscreen at startup; is set in I_PrepareVideoModeList
boolean allow_fullscreen = false;
static SDL_bool disable_fullscreen = SDL_FALSE;
#define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value
@ -1340,110 +1340,14 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h)
}
}
return -1;
#if 0
INT32 matchMode = -1, i;
VID_PrepareModeList();
if (USE_FULLSCREEN && numVidModes != -1)
{
for (i=firstEntry; i<numVidModes; i++)
{
if (modeList[i]->w == w &&
modeList[i]->h == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smaller mode
{
w -= w%BASEVIDWIDTH;
h -= h%BASEVIDHEIGHT;
for (i=firstEntry; i<numVidModes; i++)
{
if (modeList[i]->w == w &&
modeList[i]->h == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smallest mode
matchMode = numVidModes-1;
}
matchMode -= firstEntry;
}
else
{
for (i=0; i<MAXWINMODES; i++)
{
if (windowedModes[i][0] == w &&
windowedModes[i][1] == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smaller mode
{
w -= w%BASEVIDWIDTH;
h -= h%BASEVIDHEIGHT;
for (i=0; i<MAXWINMODES; i++)
{
if (windowedModes[i][0] == w &&
windowedModes[i][1] == h)
{
matchMode = i;
break;
}
}
if (-1 == matchMode) // use smallest mode
matchMode = MAXWINMODES-1;
}
}
return matchMode;
#endif
}
void VID_PrepareModeList(void)
{
// Under SDL2, we just use the windowed modes list, and scale in windowed fullscreen.
allow_fullscreen = true;
#if 0
INT32 i;
firstEntry = 0;
#ifdef HWRENDER
if (rendermode == render_opengl)
modeList = SDL_ListModes(NULL, SDL_OPENGL|SDL_FULLSCREEN);
else
#endif
modeList = SDL_ListModes(NULL, surfaceFlagsF|SDL_HWSURFACE); //Alam: At least hardware surface
if (disable_fullscreen?0:cv_fullscreen.value) // only fullscreen needs preparation
{
if (-1 != numVidModes)
{
for (i=0; i<numVidModes; i++)
{
if (modeList[i]->w <= MAXVIDWIDTH &&
modeList[i]->h <= MAXVIDHEIGHT)
{
firstEntry = i;
break;
}
}
}
}
allow_fullscreen = true;
#endif
}
static SDL_bool Impl_CreateContext(void)
{
// Renderer-specific stuff
#ifdef HWRENDER
if ((rendermode == render_opengl) && (vid_opengl_state != -1))
if ((rendermode == render_opengl)
&& (vid.glstate != VID_GL_LIBRARY_ERROR))
{
if (!sdlglcontext)
sdlglcontext = SDL_GL_CreateContext(window);
@ -1479,30 +1383,29 @@ static SDL_bool Impl_CreateContext(void)
void VID_CheckGLLoaded(rendermode_t oldrender)
{
#ifdef HWRENDER
if (vid_opengl_state == -1) // Well, it didn't work the first time anyway.
if (vid.glstate == VID_GL_LIBRARY_ERROR) // Well, it didn't work the first time anyway.
{
CONS_Alert(CONS_ERROR, "OpenGL never loaded\n");
rendermode = oldrender;
if (chosenrendermode == render_opengl) // fallback to software
rendermode = render_soft;
if (setrenderneeded)
{
CV_StealthSetValue(&cv_renderer, oldrender);
CV_StealthSetValue(&cv_newrenderer, oldrender);
setrenderneeded = 0;
}
CV_StealthSetValue(&cv_renderer, oldrender);
CV_StealthSetValue(&cv_newrenderer, oldrender);
}
#endif
}
void VID_CheckRenderer(void)
boolean VID_CheckRenderer(void)
{
boolean rendererchanged = false;
boolean contextcreated = false;
#ifdef HWRENDER
rendermode_t oldrenderer = rendermode;
#endif
if (dedicated)
return;
return false;
if (setrenderneeded)
{
@ -1516,11 +1419,12 @@ void VID_CheckRenderer(void)
// Initialise OpenGL before calling SDLSetMode!!!
// This is because SDLSetMode calls OglSdlSurface.
if (vid_opengl_state == 0)
if (vid.glstate == VID_GL_LIBRARY_NOTLOADED)
{
VID_StartupOpenGL();
// Loaded successfully!
if (vid_opengl_state == 1)
if (vid.glstate == VID_GL_LIBRARY_LOADED)
{
// Destroy the current window, if it exists.
if (window)
@ -1543,11 +1447,17 @@ void VID_CheckRenderer(void)
contextcreated = true;
}
}
else if (vid_opengl_state == -1)
else if (vid.glstate == VID_GL_LIBRARY_ERROR)
rendererchanged = false;
}
#endif
if (rendererchanged)
{
Patch_UpdateReferences();
V_ReloadHUDGraphics();
}
if (!contextcreated)
Impl_CreateContext();
@ -1565,27 +1475,22 @@ void VID_CheckRenderer(void)
bufSurface = NULL;
}
if (rendererchanged)
{
#ifdef HWRENDER
if (vid_opengl_state == 1) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
if (rendererchanged && vid.glstate == VID_GL_LIBRARY_LOADED) // Only if OpenGL ever loaded!
HWR_FreeTextureCache();
#endif
SCR_SetDrawFuncs();
}
SCR_SetDrawFuncs();
}
#ifdef HWRENDER
else if (rendermode == render_opengl)
else if (rendermode == render_opengl && rendererchanged)
{
if (rendererchanged)
{
R_InitHardwareMode();
V_SetPalette(0);
}
HWR_Switch();
V_SetPalette(0);
}
#else
(void)oldrenderer;
#endif
return rendererchanged;
}
INT32 VID_SetMode(INT32 modeNum)
@ -1626,7 +1531,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
flags |= SDL_WINDOW_BORDERLESS;
#ifdef HWRENDER
if (vid_opengl_state == 1)
if (vid.glstate == VID_GL_LIBRARY_LOADED)
flags |= SDL_WINDOW_OPENGL;
#endif
@ -1660,7 +1565,7 @@ static void Impl_SetWindowName(const char *title)
static void Impl_SetWindowIcon(void)
{
if (window && icoSurface)
SDL_SetWindowIcon(window, icoSurface);
SDL_SetWindowIcon(window, icoSurface);
}
static void Impl_VideoSetupSDLBuffer(void)
@ -1747,12 +1652,44 @@ void I_StartupGraphics(void)
framebuffer = SDL_TRUE;
}
#ifdef HWRENDER
if (M_CheckParm("-opengl"))
chosenrendermode = rendermode = render_opengl;
// Renderer choices
// Takes priority over the config.
if (M_CheckParm("-renderer"))
{
INT32 i = 0;
CV_PossibleValue_t *renderer_list = cv_renderer_t;
const char *modeparm = M_GetNextParm();
while (renderer_list[i].strvalue)
{
if (!stricmp(modeparm, renderer_list[i].strvalue))
{
chosenrendermode = renderer_list[i].value;
break;
}
i++;
}
}
// Choose Software renderer
else if (M_CheckParm("-software"))
chosenrendermode = render_soft;
#ifdef HWRENDER
// Choose OpenGL renderer
else if (M_CheckParm("-opengl"))
chosenrendermode = render_opengl;
// Don't startup OpenGL
if (M_CheckParm("-nogl"))
{
vid.glstate = VID_GL_LIBRARY_ERROR;
if (chosenrendermode == render_opengl)
chosenrendermode = render_none;
}
#endif
chosenrendermode = rendermode = render_soft;
if (chosenrendermode != render_none)
rendermode = chosenrendermode;
usesdl2soft = M_CheckParm("-softblit");
borderlesswindow = M_CheckParm("-borderless");
@ -1761,16 +1698,14 @@ void I_StartupGraphics(void)
VID_Command_ModeList_f();
#ifdef HWRENDER
if (M_CheckParm("-nogl"))
vid_opengl_state = -1; // Don't startup OpenGL
else if (chosenrendermode == render_opengl)
if (rendermode == render_opengl)
VID_StartupOpenGL();
#endif
// Window icon
#ifdef HAVE_IMAGE
icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm);
#endif
#endif
// Fury: we do window initialization after GL setup to allow
// SDL_GL_LoadLibrary to work well on Windows
@ -1782,10 +1717,9 @@ void I_StartupGraphics(void)
vid.width = BASEVIDWIDTH; // Default size for startup
vid.height = BASEVIDHEIGHT; // BitsPerPixel is the SDL interface's
vid.recalc = true; // Set up the console stufff
vid.recalc = true; // Set up the console stuff
vid.direct = NULL; // Maybe direct access?
vid.bpp = 1; // This is the game engine's Bpp
vid.WndParent = NULL; //For the window?
#ifdef HAVE_TTF
I_ShutdownTTF();
@ -1854,19 +1788,17 @@ void VID_StartupOpenGL(void)
HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
HWD.pfnLoadShaders = hwSym("LoadShaders",NULL);
HWD.pfnKillShaders = hwSym("KillShaders",NULL);
HWD.pfnSetShader = hwSym("SetShader",NULL);
HWD.pfnUnSetShader = hwSym("UnSetShader",NULL);
HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL);
HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL);
HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL);
vid_opengl_state = HWD.pfnInit() ? 1 : -1; // let load the OpenGL library
vid.glstate = HWD.pfnInit() ? VID_GL_LIBRARY_LOADED : VID_GL_LIBRARY_ERROR; // let load the OpenGL library
if (vid_opengl_state == -1)
if (vid.glstate == VID_GL_LIBRARY_ERROR)
{
rendermode = render_soft;
setrenderneeded = 0;

View file

@ -302,13 +302,13 @@ void ST_LoadGraphics(void)
sneakers = W_CachePatchName("TVSSICON", PU_HUDGFX);
gravboots = W_CachePatchName("TVGVICON", PU_HUDGFX);
tagico = W_CachePatchName("TAGICO", PU_HUDGFX);
rflagico = W_CachePatchName("RFLAGICO", PU_HUDGFX);
bflagico = W_CachePatchName("BFLAGICO", PU_HUDGFX);
rmatcico = W_CachePatchName("RMATCICO", PU_HUDGFX);
bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX);
rflagico = (patch_t **)W_GetPatchPointerFromName("RFLAGICO", PU_HUDGFX);
bflagico = (patch_t **)W_GetPatchPointerFromName("BFLAGICO", PU_HUDGFX);
rmatcico = (patch_t **)W_GetPatchPointerFromName("RMATCICO", PU_HUDGFX);
bmatcico = (patch_t **)W_GetPatchPointerFromName("BMATCICO", PU_HUDGFX);
gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX);
gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX);
tagico = W_CachePatchName("TAGICO", PU_HUDGFX);
fnshico = W_CachePatchName("FNSHICO", PU_HUDGFX);
nonicon = W_CachePatchName("NONICON", PU_HUDGFX);
nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX);
@ -2374,17 +2374,17 @@ static void ST_drawTeamHUD(void)
return;
if (gametyperules & GTR_TEAMFLAGS)
p = bflagico;
p = *bflagico;
else
p = bmatcico;
p = *bmatcico;
if (LUA_HudEnabled(hud_teamscores))
V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p);
if (gametyperules & GTR_TEAMFLAGS)
p = rflagico;
p = *rflagico;
else
p = rmatcico;
p = *rmatcico;
if (LUA_HudEnabled(hud_teamscores))
V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p);
@ -2755,9 +2755,6 @@ 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

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

View file

@ -37,6 +37,9 @@ cv_allcaps;
// Allocates buffer screens, call before R_Init.
void V_Init(void);
// Recalculates the viddef (dupx, dupy, etc.) according to the current screen resolution.
void V_Recalc(void);
// Color look-up table
#define COLORBITS 6
#define SHIFTCOLORBITS (8-COLORBITS)
@ -264,6 +267,8 @@ INT32 V_SmallThinStringWidth(const char *string, INT32 option);
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param);
void V_ReloadHUDGraphics(void);
void V_DrawPatchFill(patch_t *pat);
void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes,

View file

@ -56,6 +56,8 @@
#include "d_clisrv.h"
#include "r_defs.h"
#include "r_data.h"
#include "r_patch.h"
#include "r_rotsprite.h"
#include "i_system.h"
#include "md5.h"
#include "lua_script.h"
@ -834,12 +836,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
// set up caching
//
Z_Calloc(numlumps * sizeof (*wadfile->lumpcache), PU_STATIC, &wadfile->lumpcache);
Z_Calloc(numlumps * sizeof (*wadfile->patchcache), PU_STATIC, &wadfile->patchcache);
#ifdef HWRENDER
// allocates GLPatch info structures and store them in a tree
wadfile->hwrcache = M_AATreeAlloc(AATREE_ZUSER);
#endif
Patch_InitInfo(wadfile);
//
// add the wadfile
@ -850,7 +847,7 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
#ifdef HWRENDER
// Read shaders from file
if (rendermode == render_opengl && (vid_opengl_state == 1))
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
{
HWR_ReadShaders(numwadfiles - 1, (type == RET_PK3));
HWR_LoadShaders();
@ -1609,38 +1606,6 @@ boolean W_IsLumpCached(lumpnum_t lumpnum, void *ptr)
return W_IsLumpCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
}
//
// W_IsPatchCached
//
// If a patch is already cached return true, otherwise
// return false.
//
// no outside code uses the PWAD form, for now
static inline boolean W_IsPatchCachedPWAD(UINT16 wad, UINT16 lump, void *ptr)
{
void *lcache;
if (!TestValidLump(wad, lump))
return false;
lcache = wadfiles[wad]->patchcache[lump];
if (ptr)
{
if (ptr == lcache)
return true;
}
else if (lcache)
return true;
return false;
}
boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr)
{
return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr);
}
// ==========================================================================
// W_CacheLumpName
// ==========================================================================
@ -1649,62 +1614,12 @@ void *W_CacheLumpName(const char *name, INT32 tag)
return W_CacheLumpNum(W_GetNumForName(name), tag);
}
// ==========================================================================
// CACHING OF GRAPHIC PATCH RESOURCES
// ==========================================================================
// Graphic 'patches' are loaded, and if necessary, converted into the format
// the most useful for the current rendermode. For software renderer, the
// graphic patches are kept as is. For the hardware renderer, graphic patches
// are 'unpacked', and are kept into the cache in that unpacked format, and
// the heap memory cache then acts as a 'level 2' cache just after the
// graphics card memory.
//
// Cache a patch into heap memory, convert the patch format as necessary
//
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
lumpcache_t *lumpcache = NULL;
if (!TestValidLump(wad, lump))
return NULL;
lumpcache = wadfiles[wad]->patchcache;
if (!lumpcache[lump])
{
size_t len = W_LumpLengthPwad(wad, lump);
void *ptr, *lumpdata;
#ifndef NO_PNG_LUMPS
void *srcdata = NULL;
#endif
ptr = Z_Malloc(len, tag, &lumpcache[lump]);
lumpdata = Z_Malloc(len, tag, NULL);
// read the lump in full
W_ReadLumpHeaderPwad(wad, lump, lumpdata, 0, 0);
#ifndef NO_PNG_LUMPS
// lump is a png so convert it
if (R_IsLumpPNG((UINT8 *)lumpdata, len))
{
size_t newlen;
srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen);
ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]);
M_Memcpy(ptr, srcdata, newlen);
Z_Free(srcdata);
}
else // just copy it into the patch cache
#endif
M_Memcpy(ptr, lumpdata, len);
}
else
Z_ChangeTag(lumpcache[lump], tag);
return lumpcache[lump];
return Patch_CacheSoftware(wad, lump, tag, false);
}
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag)
@ -1714,46 +1629,15 @@ void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag)
void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
#ifdef HWRENDER
GLPatch_t *grPatch;
#endif
if (!TestValidLump(wad, lump))
return NULL;
#ifdef HWRENDER
// Software-only compile cache the data without conversion
if (rendermode == render_soft || rendermode == render_none)
#endif
{
return W_CacheSoftwarePatchNumPwad(wad, lump, tag);
}
#ifdef HWRENDER
grPatch = HWR_GetCachedGLPatchPwad(wad, lump);
if (grPatch->mipmap->data)
{
if (tag == PU_CACHE)
tag = PU_HWRCACHE;
Z_ChangeTag(grPatch->mipmap->data, tag);
}
if (rendermode == render_opengl)
return (void *)Patch_CacheGL(wad, lump, tag, false);
else
{
patch_t *ptr = NULL;
// Only load the patch if we haven't initialised the grPatch yet
if (grPatch->mipmap->width == 0)
ptr = W_CacheLumpNumPwad(grPatch->wadnum, grPatch->lumpnum, PU_STATIC);
// Run HWR_MakePatch in all cases, to recalculate some things
HWR_MakePatch(ptr, grPatch, grPatch->mipmap, false);
Z_Free(ptr);
}
// return GLPatch_t, which can be casted to (patch_t) with valid patch header info
return (void *)grPatch;
#endif
return Patch_CacheSoftware(wad, lump, tag, false);
}
void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
@ -1761,6 +1645,111 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag)
return W_CachePatchNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
void *W_CachePatchName(const char *name, INT32 tag)
{
lumpnum_t num = W_CheckNumForName(name);
if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForName("MISSING"), tag);
return W_CachePatchNum(num, tag);
}
void *W_CachePatchLongName(const char *name, INT32 tag)
{
lumpnum_t num = W_CheckNumForLongName(name);
if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag);
return W_CachePatchNum(num, tag);
}
void **W_GetPatchPointerPwad(UINT16 wad, UINT16 lump, INT32 tag)
{
void **pp;
if (!TestValidLump(wad, lump))
return NULL;
pp = (void **)(&(wadfiles[wad]->patchinfo.current[lump]));
if (*pp) // Already cached
return pp;
#ifdef HWRENDER
if (rendermode == render_opengl)
Patch_CacheGL(wad, lump, tag, true);
else
#endif
Patch_CacheSoftware(wad, lump, tag, true);
return pp;
}
void **W_GetPatchPointer(lumpnum_t lumpnum, INT32 tag)
{
return W_GetPatchPointerPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag);
}
void **W_GetPatchPointerFromName(const char *name, INT32 tag)
{
lumpnum_t num = W_CheckNumForName(name);
if (num == LUMPERROR)
return W_GetPatchPointer(W_GetNumForName("MISSING"), tag);
return W_GetPatchPointer(num, tag);
}
void **W_GetPatchPointerFromLongName(const char *name, INT32 tag)
{
lumpnum_t num = W_CheckNumForLongName(name);
if (num == LUMPERROR)
return W_GetPatchPointer(W_CheckNumForLongName("MISSING"), tag);
return W_GetPatchPointer(num, tag);
}
#ifdef ROTSPRITE
void **W_GetRotatedPatchPointerPwad(UINT16 wad, UINT16 lump, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip)
{
static rotsprite_vars_t rsvars;
patchinfo_t *patchinfo = NULL;
if (!TestValidLump(wad, lump))
return NULL;
patchinfo = &wadfiles[wad]->patchinfo;
if (!patchinfo->rotated[lump])
RotSprite_AllocCurrentPatchInfo(patchinfo, lump);
rsvars.rollangle = rollangle;
rsvars.sprite = sprite;
rsvars.pivot = pivot;
rsvars.flip = flip;
if (sprite)
Patch_CacheRotatedForSpritePwad(wad, lump, tag, rsvars, true);
else
Patch_CacheRotatedPwad(wad, lump, tag, rsvars, true);
return (void **)(&(patchinfo->rotated[lump][RotSprite_GetCurrentPatchInfoIdx(rollangle, flip)]));
}
void **W_GetRotatedPatchPointer(lumpnum_t lumpnum, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip)
{
return W_GetRotatedPatchPointerPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag,rollangle,sprite,pivot,flip);
}
void **W_GetRotatedPatchPointerFromName(const char *name, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip)
{
lumpnum_t num = W_CheckNumForName(name);
if (num == LUMPERROR)
return W_GetRotatedPatchPointer(W_GetNumForName("MISSING"), tag, rollangle, sprite, pivot, flip);
return W_GetRotatedPatchPointer(num, tag, rollangle, sprite, pivot, flip);
}
void **W_GetRotatedPatchPointerFromLongName(const char *name, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip)
{
lumpnum_t num = W_CheckNumForLongName(name);
if (num == LUMPERROR)
return W_GetRotatedPatchPointer(W_CheckNumForLongName("MISSING"), tag, rollangle, sprite, pivot, flip);
return W_GetRotatedPatchPointer(num, tag, rollangle, sprite, pivot, flip);
}
#endif
void W_UnlockCachedPatch(void *patch)
{
// The hardware code does its own memory management, as its patches
@ -1768,32 +1757,9 @@ void W_UnlockCachedPatch(void *patch)
#ifdef HWRENDER
if (rendermode == render_opengl)
HWR_UnlockCachedPatch((GLPatch_t*)patch);
else
#endif
Z_Unlock(patch);
}
void *W_CachePatchName(const char *name, INT32 tag)
{
lumpnum_t num;
num = W_CheckNumForName(name);
if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForName("MISSING"), tag);
return W_CachePatchNum(num, tag);
}
void *W_CachePatchLongName(const char *name, INT32 tag)
{
lumpnum_t num;
num = W_CheckNumForLongName(name);
if (num == LUMPERROR)
return W_CachePatchNum(W_GetNumForLongName("MISSING"), tag);
return W_CachePatchNum(num, tag);
}
#ifndef NOMD5
#define MD5_LEN 16

View file

@ -22,6 +22,8 @@
#pragma interface
#endif
#define lumpcache_t void *
// a raw entry of the wad directory
// NOTE: This sits here and not in w_wad.c because p_setup.c makes use of it to load map WADs inside PK3s.
#if defined(_MSC_VER)
@ -37,7 +39,6 @@ typedef struct
#pragma pack()
#endif
// ==============================================================
// WAD FILE STRUCTURE DEFINITIONS
// ==============================================================
@ -92,6 +93,22 @@ virtres_t* vres_GetMap(lumpnum_t);
void vres_Free(virtres_t*);
virtlump_t* vres_Find(const virtres_t*, const char*);
// =========================================================================
// PATCH INFO
// =========================================================================
#include "r_patchtrees.h"
typedef struct patchinfo_s
{
patchtree_t renderer[num_patchtrees];
lumpcache_t *current;
#ifdef ROTSPRITE
lumpcache_t **rotated;
#endif
} patchinfo_t;
// =========================================================================
// DYNAMIC WAD LOADING
// =========================================================================
@ -100,12 +117,6 @@ virtlump_t* vres_Find(const virtres_t*, const char*);
#define MAX_WADFILES 48 // maximum of wad files used at the same time
// (there is a max of simultaneous open files anyway, and this should be plenty)
#define lumpcache_t void *
#ifdef HWRENDER
#include "m_aatree.h"
#endif
// Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further.
typedef enum restype
{
@ -122,10 +133,7 @@ typedef struct wadfile_s
restype_t type;
lumpinfo_t *lumpinfo;
lumpcache_t *lumpcache;
lumpcache_t *patchcache;
#ifdef HWRENDER
aatree_t *hwrcache; // patches are cached in renderer's native format
#endif
patchinfo_t patchinfo;
UINT16 numlumps; // this wad's number of resources
FILE *handle;
UINT32 filesize; // for network
@ -134,8 +142,9 @@ typedef struct wadfile_s
boolean important; // also network - !W_VerifyNMUSlumps
} wadfile_t;
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad flumpnum>>16) // wad file number in upper word
#define WADFILENUM(lumpnum) (UINT16)((lumpnum)>>16) // wad file number in upper word
#define LUMPNUM(lumpnum) (UINT16)((lumpnum)&0xFFFF) // lump number for this pwad
#define WADANDLUMP(wad, lump) (UINT32)(((wad)<<16)|((lump)&0xFFFF)) // wad and lump number
extern UINT16 numwadfiles;
extern wadfile_t *wadfiles[MAX_WADFILES];
@ -193,7 +202,6 @@ void *W_CacheLumpNum(lumpnum_t lump, INT32 tag);
void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag);
boolean W_IsLumpCached(lumpnum_t lump, void *ptr);
boolean W_IsPatchCached(lumpnum_t lump, void *ptr);
void *W_CacheLumpName(const char *name, INT32 tag);
void *W_CachePatchName(const char *name, INT32 tag);
@ -209,6 +217,20 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag);
void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag);
void *W_CacheSoftwarePatchNum(lumpnum_t lumpnum, INT32 tag);
// Returns patch pointers.
void **W_GetPatchPointerPwad(UINT16 wad, UINT16 lump, INT32 tag);
void **W_GetPatchPointer(lumpnum_t lumpnum, INT32 tag);
void **W_GetPatchPointerFromName(const char *name, INT32 tag);
void **W_GetPatchPointerFromLongName(const char *name, INT32 tag);
#ifdef ROTSPRITE
// Returns rotated patch pointers.
void **W_GetRotatedPatchPointerPwad(UINT16 wad, UINT16 lump, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip);
void **W_GetRotatedPatchPointer(lumpnum_t lumpnum, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip);
void **W_GetRotatedPatchPointerFromName(const char *name, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip);
void **W_GetRotatedPatchPointerFromLongName(const char *name, INT32 tag, INT32 rollangle, boolean sprite, void *pivot, boolean flip);
#endif
void W_UnlockCachedPatch(void *patch);
void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);

View file

@ -300,6 +300,7 @@
<ClCompile Include="..\r_main.c" />
<ClCompile Include="..\r_plane.c" />
<ClCompile Include="..\r_patch.c" />
<ClCompile Include="..\r_rotsprite.c" />
<ClCompile Include="..\r_portal.c" />
<ClCompile Include="..\r_segs.c" />
<ClCompile Include="..\r_sky.c" />
@ -454,7 +455,9 @@
<ClInclude Include="..\r_local.h" />
<ClInclude Include="..\r_main.h" />
<ClInclude Include="..\r_plane.h" />
<ClInclude Include="..\r_patch.h" />
<ClInclude Include="..\r_patch.h" />
<ClInclude Include="..\r_rotsprite.h" />
<ClInclude Include="..\r_patchtrees.h" />
<ClInclude Include="..\r_portal.h" />
<ClInclude Include="..\r_segs.h" />
<ClInclude Include="..\r_sky.h" />

View file

@ -472,6 +472,9 @@
<ClCompile Include="..\r_patch.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\r_rotsprite.c">
<Filter>R_Rend</Filter>
</ClCompile>
<ClCompile Include="..\r_portal.c">
<Filter>R_Rend</Filter>
</ClCompile>
@ -889,6 +892,12 @@
<ClInclude Include="..\r_patch.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\r_rotsprite.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\r_patchtrees.h">
<Filter>R_Rend</Filter>
</ClInclude>
<ClInclude Include="..\r_portal.h">
<Filter>R_Rend</Filter>
</ClInclude>

View file

@ -48,6 +48,7 @@
// this is the CURRENT rendermode!! very important: used by w_wad, and much other code
rendermode_t rendermode = render_soft;
rendermode_t chosenrendermode = render_none; // set by command line arguments
static void OnTop_OnChange(void);
// synchronize page flipping with screen refresh
static CV_PossibleValue_t CV_NeverOnOff[] = {{-1, "Never"}, {0, "Off"}, {1, "On"}, {0, NULL}};
@ -56,7 +57,6 @@ static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff,
static consvar_t cv_ontop = {"ontop", "Never", 0, CV_NeverOnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
boolean highcolor;
int vid_opengl_state = 0;
static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces
static LPBITMAPINFO bmiMain = NULL;
@ -778,7 +778,7 @@ static INT32 WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *currentm
I_OutputMsg("VID_SetWindowedDisplayMode()\n");
lvid->u.numpages = 1; // not used
lvid->numpages = 1; // not used
lvid->direct = NULL; // DOS remains
lvid->buffer = NULL;
@ -903,9 +903,9 @@ INT32 VID_SetMode(INT32 modenum)
if (cv_scr_depth.value < 16)
CV_SetValue(&cv_scr_depth, 16);
vid.bpp = cv_scr_depth.value/8;
vid.u.windowed = (bWinParm || !cv_fullscreen.value);
vid.windowed = (bWinParm || !cv_fullscreen.value);
pcurrentmode->bytesperpixel = vid.bpp;
pcurrentmode->windowed = vid.u.windowed;
pcurrentmode->windowed = vid.windowed;
}
}
@ -952,7 +952,11 @@ INT32 VID_SetMode(INT32 modenum)
return 1;
}
void VID_CheckRenderer(void) {}
boolean VID_CheckRenderer(void)
{
return false;
}
void VID_CheckGLLoaded(rendermode_t oldrender)
{
(void)oldrender;
@ -995,7 +999,7 @@ static INT32 WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *currentmode)
// DD modes do double-buffer page flipping, but the game engine doesn't need this..
lvid->u.numpages = 2;
lvid->numpages = 2;
// release ddraw surfaces etc..
ReleaseChtuff();

View file

@ -66,7 +66,7 @@ typedef union
INT32 passedx2;
y_bonus_t bonuses[4];
patch_t *bonuspatches[4];
patch_t **bonuspatches[4];
SINT8 gotperfbonus; // Used for visitation flags.
@ -74,7 +74,7 @@ typedef union
UINT32 tics; // time
UINT8 actnum; // act number being displayed
patch_t *ptotal; // TOTAL
patch_t **ptotal; // TOTAL
UINT8 gotlife; // Number of extra lives obtained
} coop;
@ -90,14 +90,14 @@ typedef union
INT32 passedx4;
y_bonus_t bonuses[2];
patch_t *bonuspatches[2];
patch_t **bonuspatches[2];
patch_t *pscore; // SCORE
patch_t **pscore; // SCORE
UINT32 score; // fake score
// Continues
UINT8 continues;
patch_t *pcontinues;
patch_t **pcontinues;
INT32 *playerchar; // Continue HUD
UINT16 *playercolor;
@ -112,9 +112,9 @@ typedef union
INT32 *character[MAXPLAYERS]; // Winner's character #
INT32 num[MAXPLAYERS]; // Winner's player #
char *name[MAXPLAYERS]; // Winner's name
patch_t *result; // RESULT
patch_t *blueflag;
patch_t *redflag; // int_ctf uses this struct too.
patch_t **result; // RESULT
patch_t **blueflag;
patch_t **redflag; // int_ctf uses this struct too.
INT32 numplayers; // Number of players being displayed
char levelstring[40]; // holds levelnames up to 32 characters
} match;
@ -140,10 +140,10 @@ typedef union
static y_data data;
// graphics
static patch_t *bgpatch = NULL; // INTERSCR
static patch_t *widebgpatch = NULL; // INTERSCW
static patch_t *bgtile = NULL; // SPECTILE/SRB2BACK
static patch_t *interpic = NULL; // custom picture defined in map header
static patch_t **bgpatch = NULL; // INTERSCR
static patch_t **widebgpatch = NULL; // INTERSCW
static patch_t **bgtile = NULL; // SPECTILE/SRB2BACK
static patch_t **interpic = NULL; // custom picture defined in map header
static boolean usetile;
static INT32 timer;
@ -176,7 +176,6 @@ 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)
@ -323,13 +322,6 @@ void Y_IntermissionDrawer(void)
if (intertype == int_none || rendermode == render_none)
return;
// Lactozilla: Renderer switching
if (needpatchrecache)
{
Y_CleanupData();
safetorender = false;
}
if (!usebuffer || !safetorender)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
@ -337,7 +329,7 @@ void Y_IntermissionDrawer(void)
goto dontdrawbg;
if (useinterpic)
V_DrawScaledPatch(0, 0, 0, interpic);
V_DrawScaledPatch(0, 0, 0, *interpic);
else if (!usetile)
{
if (rendermode == render_soft && usebuffer)
@ -362,13 +354,13 @@ void Y_IntermissionDrawer(void)
else
{
if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400)
V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch);
V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, *widebgpatch);
else if (bgpatch)
V_DrawScaledPatch(0, 0, 0, bgpatch);
V_DrawScaledPatch(0, 0, 0, *bgpatch);
}
}
else if (bgtile)
V_DrawPatchFill(bgtile);
V_DrawPatchFill(*bgtile);
LUAh_IntermissionHUD();
if (!LUA_HudEnabled(hud_intermissiontally))
@ -426,7 +418,7 @@ dontdrawbg:
// Total
if (safetorender)
{
V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal);
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;
@ -436,7 +428,7 @@ dontdrawbg:
{
if (data.coop.bonuses[i].display && safetorender)
{
V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]);
V_DrawScaledPatch(152, bonusy, 0, *data.coop.bonuspatches[i]);
V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points);
}
bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1;
@ -539,18 +531,18 @@ dontdrawbg:
V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2);
}
V_DrawScaledPatch(152 + xoffset3, 108, 0, data.spec.bonuspatches[0]);
V_DrawScaledPatch(152 + xoffset3, 108, 0, *data.spec.bonuspatches[0]);
V_DrawTallNum(BASEVIDWIDTH + xoffset3 - 68, 109, 0, data.spec.bonuses[0].points);
if (data.spec.bonuses[1].display)
{
V_DrawScaledPatch(152 + xoffset4, 124, 0, data.spec.bonuspatches[1]);
V_DrawScaledPatch(152 + xoffset4, 124, 0, *data.spec.bonuspatches[1]);
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125, 0, data.spec.bonuses[1].points);
yoffset = 16;
// hack; pass the buck along...
xoffset4 = xoffset5;
xoffset5 = xoffset6;
}
V_DrawScaledPatch(152 + xoffset4, 124+yoffset, 0, data.spec.pscore);
V_DrawScaledPatch(152 + xoffset4, 124+yoffset, 0, *data.spec.pscore);
V_DrawTallNum(BASEVIDWIDTH + xoffset4 - 68, 125+yoffset, 0, data.spec.score);
// Draw continues!
@ -558,7 +550,7 @@ dontdrawbg:
{
UINT8 continues = data.spec.continues & 0x7F;
V_DrawScaledPatch(152 + xoffset5, 150+yoffset, 0, data.spec.pcontinues);
V_DrawScaledPatch(152 + xoffset5, 150+yoffset, 0, *data.spec.pcontinues);
if (continues > 5)
{
INT32 leftx = (continues >= 10) ? 216 : 224;
@ -664,7 +656,7 @@ dontdrawbg:
// draw the header
if (safetorender)
V_DrawScaledPatch(112, 2, 0, data.match.result);
V_DrawScaledPatch(112, 2, 0, *data.match.result);
// draw the level name
V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring);
@ -777,10 +769,10 @@ dontdrawbg:
char name[MAXPLAYERNAME+1];
// Show the team flags and the team score at the top instead of "RESULTS"
V_DrawSmallScaledPatch(128 - SHORT(data.match.blueflag->width)/4, 2, 0, data.match.blueflag);
V_DrawSmallScaledPatch(128 - SHORT((*data.match.blueflag)->width)/4, 2, 0, *data.match.blueflag);
V_DrawCenteredString(128, 16, 0, va("%u", bluescore));
V_DrawSmallScaledPatch(192 - SHORT(data.match.redflag->width)/4, 2, 0, data.match.redflag);
V_DrawSmallScaledPatch(192 - SHORT((*data.match.redflag)->width)/4, 2, 0, *data.match.redflag);
V_DrawCenteredString(192, 16, 0, va("%u", redscore));
// draw the level name
@ -1259,20 +1251,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_PATCH);
data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH);
data.coop.bonuspatches[i] = (patch_t **)W_GetPatchPointerFromName(data.coop.bonuses[i].patch, PU_PATCH);
data.coop.ptotal = (patch_t **)W_GetPatchPointerFromName("YB_TOTAL", PU_PATCH);
// get act number
data.coop.actnum = mapheaderinfo[gamemap-1]->actnum;
// get background patches
widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH);
bgpatch = W_CachePatchName("INTERSCR", PU_PATCH);
widebgpatch = (patch_t **)W_GetPatchPointerFromName("INTERSCW", PU_PATCH);
bgpatch = (patch_t **)W_GetPatchPointerFromName("INTERSCR", PU_PATCH);
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
{
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
interpic = (patch_t **)W_GetPatchPointerFromName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
useinterpic = true;
usebuffer = false;
}
@ -1330,18 +1322,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_PATCH);
data.spec.bonuspatches[i] = (patch_t **)W_GetPatchPointerFromName(data.spec.bonuses[i].patch, PU_PATCH);
data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH);
data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH);
data.spec.pscore = (patch_t **)W_GetPatchPointerFromName("YB_SCORE", PU_PATCH);
data.spec.pcontinues = (patch_t **)W_GetPatchPointerFromName("YB_CONTI", PU_PATCH);
// get background tile
bgtile = W_CachePatchName("SPECTILE", PU_PATCH);
bgtile = (patch_t **)W_GetPatchPointerFromName("SPECTILE", PU_PATCH);
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
{
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
interpic = (patch_t **)W_GetPatchPointerFromName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
useinterpic = true;
}
else
@ -1353,14 +1345,14 @@ void Y_StartIntermission(void)
// get special stage specific patches
/* if (!stagefailed && ALL7EMERALDS(emeralds))
{
data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH);
data.spec.cemerald = (patch_t **)W_GetPatchPointerFromName("GOTEMALL", PU_PATCH);
data.spec.headx = 70;
data.spec.nowsuper = players[consoleplayer].skin
? NULL : W_CachePatchName("NOWSUPER", PU_PATCH);
? NULL : W_GetPatchPointerFromName("NOWSUPER", PU_PATCH);
}
else
{
data.spec.cemerald = W_CachePatchName("CEMERALD", PU_PATCH);
data.spec.cemerald = (patch_t **)W_GetPatchPointerFromName("CEMERALD", PU_PATCH);
data.spec.headx = 48;
data.spec.nowsuper = NULL;
} */
@ -1437,10 +1429,9 @@ void Y_StartIntermission(void)
data.match.levelstring[sizeof data.match.levelstring - 1] = '\0';
// get RESULT header
data.match.result =
W_CachePatchName("RESULT", PU_PATCH);
data.match.result = (patch_t **)W_GetPatchPointerFromName("RESULT", PU_PATCH);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
bgtile = (patch_t **)W_GetPatchPointerFromName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -1466,9 +1457,9 @@ void Y_StartIntermission(void)
data.match.levelstring[sizeof data.match.levelstring - 1] = '\0';
// get RESULT header
data.match.result = W_CachePatchName("RESULT", PU_PATCH);
data.match.result = (patch_t **)W_GetPatchPointerFromName("RESULT", PU_PATCH);
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
bgtile = (patch_t **)W_GetPatchPointerFromName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -1505,7 +1496,7 @@ void Y_StartIntermission(void)
data.match.blueflag = bmatcico;
}
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
bgtile = (patch_t **)W_GetPatchPointerFromName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -1531,7 +1522,7 @@ void Y_StartIntermission(void)
data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0';
// get background tile
bgtile = W_CachePatchName("SRB2BACK", PU_PATCH);
bgtile = (patch_t **)W_GetPatchPointerFromName("SRB2BACK", PU_PATCH);
usetile = true;
useinterpic = false;
break;
@ -2069,15 +2060,14 @@ void Y_EndIntermission(void)
usebuffer = false;
}
#define UNLOAD(x) if (x) {Z_ChangeTag(x, PU_CACHE);} x = NULL;
#define CLEANUP(x) x = NULL;
#define UNLOAD(x) if (x) {Z_ChangeTag(*x, PU_CACHE);} x = NULL;
//
// Y_UnloadData
//
static void Y_UnloadData(void)
{
// In hardware mode, don't Z_ChangeTag a pointer returned by W_CachePatchName().
// In hardware mode, don't Z_ChangeTag a pointer returned by W_GetPatchPointerFromName().
// It doesn't work and is unnecessary.
if (rendermode != render_soft)
return;
@ -2122,46 +2112,3 @@ static void Y_UnloadData(void)
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,7 +27,6 @@
#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"
@ -499,33 +498,6 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
// Utility functions
// -----------------
// for renderer switching
boolean needpatchflush = false;
boolean needpatchrecache = false;
// flush all patches from memory
void Z_FlushCachedPatches(void)
{
CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n");
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);
Z_FreeTag(PU_HWRMODELTEXTURE_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

@ -142,12 +142,5 @@ size_t Z_TagsUsage(INT32 lowtag, INT32 hightag);
// Miscellaneous functions
//
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