Compare commits
58
Commits
v7.1
...
refactorportals
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ac0f2bae2 | ||
|
|
cee28c6166 | ||
|
|
a6be267325 | ||
|
|
426740e0ac | ||
|
|
78c0f64135 | ||
|
|
b6e766ee44 | ||
|
|
5437040b78 | ||
|
|
c786569981 | ||
|
|
7064b14539 | ||
|
|
f275ae98f5 | ||
|
|
ef07d89e29 | ||
|
|
b9bbd45e15 | ||
|
|
2bda27b80d | ||
|
|
6ebf90cc50 | ||
|
|
ea00bebb04 | ||
|
|
b862d835a5 | ||
|
|
d6602747ae | ||
|
|
9f79429d03 | ||
|
|
5ff0c09868 | ||
|
|
ad1c3e63a4 | ||
|
|
24dd6ba675 | ||
|
|
85f036a45b | ||
|
|
6f8342b9a8 | ||
|
|
c5c6f6b820 | ||
|
|
3d472c34a1 | ||
|
|
63ca366bd8 | ||
|
|
e9e888ab7f | ||
|
|
5ea55b3e3a | ||
|
|
8b1797927a | ||
|
|
05a98964fb | ||
|
|
8cbf798de8 | ||
|
|
9314a24cb2 | ||
|
|
19b1683e61 | ||
|
|
d029107e75 | ||
|
|
bc97e0b703 | ||
|
|
f47c663f79 | ||
|
|
6f9d41eadb | ||
|
|
1b512edc56 | ||
|
|
884a6da2bd | ||
|
|
7a3d958fc1 | ||
|
|
7223581539 | ||
|
|
664bd2de3f | ||
|
|
63568e3861 | ||
|
|
f149d058a1 | ||
|
|
970251ced3 | ||
|
|
dba7a7dc3c | ||
|
|
393c0be407 | ||
|
|
5e9ea2429b | ||
|
|
81a14995da | ||
|
|
4267ac9a8d | ||
|
|
bcf72cc0e8 | ||
|
|
54d9a98090 | ||
|
|
81d415c5ba | ||
|
|
de1b801bda | ||
|
|
2c665fef6f | ||
|
|
c6fbf405bf | ||
|
|
7076c35521 | ||
|
|
86ed1b709e |
No files matched your search
@@ -563,6 +563,7 @@ OBJS:=$(i_main_o) \
|
||||
$(OBJDIR)/r_splats.o \
|
||||
$(OBJDIR)/r_patch.o \
|
||||
$(OBJDIR)/r_things.o \
|
||||
$(OBJDIR)/r_portal.o \
|
||||
$(OBJDIR)/screen.o \
|
||||
$(OBJDIR)/v_video.o \
|
||||
$(OBJDIR)/s_sound.o \
|
||||
|
||||
+1
-1
@@ -4464,7 +4464,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||
if (server && multiplayer && motd[0] != '\0')
|
||||
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
|
||||
|
||||
D_AddAutoloadFiles();
|
||||
D_AddPostloadFiles();
|
||||
|
||||
LUAh_PlayerJoin(newplayernum);
|
||||
|
||||
|
||||
+29
-57
@@ -99,7 +99,6 @@ UINT8 window_notinfocus = false;
|
||||
// DEMO LOOP
|
||||
//
|
||||
//static INT32 demosequence;
|
||||
static const char *pagename = "MAP1PIC";
|
||||
static char *startupwadfiles[MAX_WADFILES];
|
||||
static char *startuppwads[MAX_WADFILES];
|
||||
|
||||
@@ -116,7 +115,6 @@ boolean devparm = false; // started game with -devparm
|
||||
boolean singletics = false; // timedemo
|
||||
boolean lastdraw = false;
|
||||
|
||||
postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
|
||||
INT32 postimgparam[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
// These variables are only true if
|
||||
@@ -513,15 +511,12 @@ static boolean D_Display(void)
|
||||
|
||||
if (rendermode == render_soft)
|
||||
{
|
||||
if (!splitscreen)
|
||||
R_ApplyViewMorph();
|
||||
if (!splitscreen)
|
||||
R_ApplyViewMorph();
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (!postimgtype[i])
|
||||
continue;
|
||||
|
||||
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
|
||||
V_DoPostProcessor(i, &players[displayplayers[i]], postimgparam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1072,8 +1067,7 @@ static void D_FindAddonsToAutoload(void)
|
||||
const char *autoloadpath;
|
||||
boolean postload;
|
||||
|
||||
INT32 i, len;
|
||||
boolean hasprefix = false;
|
||||
INT32 i;
|
||||
char wadsToAutoload[256] = "";
|
||||
|
||||
// does it exist tho
|
||||
@@ -1095,7 +1089,8 @@ static void D_FindAddonsToAutoload(void)
|
||||
|| (wadsToAutoload[0] == '#'))
|
||||
continue;
|
||||
// this marks it so that it loads after loading server addons
|
||||
else if (fastncmp(wadsToAutoload, "postload ", 9)) {
|
||||
else if (fastncmp(wadsToAutoload, "postload ", 9))
|
||||
{
|
||||
strremove(wadsToAutoload, "postload ");
|
||||
postload = true;
|
||||
}
|
||||
@@ -1107,34 +1102,10 @@ static void D_FindAddonsToAutoload(void)
|
||||
wadsToAutoload[i] = '\0';
|
||||
}
|
||||
|
||||
len = strlen(wadsToAutoload);
|
||||
hasprefix = false;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
if (!postload && W_CheckPostLoadList(wadsToAutoload))
|
||||
{
|
||||
if (wadsToAutoload[i] == '_')
|
||||
{
|
||||
hasprefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Lets just hope no one adds bonuschars in autoload
|
||||
if (hasprefix)
|
||||
{
|
||||
// We searching for c in prefix, which stands for "character" and doesn't work well with
|
||||
// autoload atm, only fine for postload
|
||||
for (i = 0; i < len; ++i)
|
||||
{
|
||||
if (wadsToAutoload[i] == '_') break; // Prefix end
|
||||
|
||||
if (wadsToAutoload[i] == 'c' || wadsToAutoload[i] == 'C')
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "forcing postload for %s as local skin\n", wadsToAutoload);
|
||||
postload = true;
|
||||
break; // Found it
|
||||
}
|
||||
}
|
||||
CONS_Printf("forcing postload for file %s\n", wadsToAutoload);
|
||||
postload = true;
|
||||
}
|
||||
|
||||
// LOAD IT
|
||||
@@ -1152,30 +1123,30 @@ static void D_FindAddonsToAutoload(void)
|
||||
fclose(autoloadconfigfile);
|
||||
}
|
||||
|
||||
void D_AddAutoloadFiles(void)
|
||||
static void D_AddAutoloadFiles(void)
|
||||
{
|
||||
if (wasautoloaded && postautoloaded)
|
||||
if (wasautoloaded)
|
||||
return;
|
||||
|
||||
if (!wasautoloaded && !modeattacking)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfiles);
|
||||
CONS_Printf("D_AutoloadFile(): Loading autoloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfiles) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfiles);
|
||||
|
||||
wasautoloaded = true;
|
||||
}
|
||||
wasautoloaded = true;
|
||||
}
|
||||
|
||||
if ((!postautoloaded) && netgame)
|
||||
{
|
||||
CONS_Printf("D_AutoloadFile(): Loading postloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
|
||||
CONS_Printf("D_AutoloadFile(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfilespost);
|
||||
void D_AddPostloadFiles(void)
|
||||
{
|
||||
if (postautoloaded || !netgame)
|
||||
return;
|
||||
|
||||
postautoloaded = true;
|
||||
}
|
||||
CONS_Printf("D_AddPostloadFiles(): Loading postloaded addons...\n");
|
||||
if (W_AddAutoloadedLocalFiles(autoloadwadfilespost) == 0)
|
||||
CONS_Printf("D_AddPostloadFiles(): Are you sure you put in valid files or what?\n");
|
||||
D_CleanFile(autoloadwadfilespost);
|
||||
|
||||
postautoloaded = true;
|
||||
}
|
||||
|
||||
void D_CleanFile(char **filearray)
|
||||
@@ -1870,6 +1841,8 @@ void D_SRB2Main(void)
|
||||
CONS_Printf("ST_Init(): Init status bar.\n");
|
||||
ST_Init();
|
||||
|
||||
D_AddAutoloadFiles();
|
||||
|
||||
// Set up splitscreen players before joining!
|
||||
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
|
||||
{
|
||||
@@ -2071,7 +2044,6 @@ void D_SRB2Main(void)
|
||||
|
||||
if (dedicated && server)
|
||||
{
|
||||
pagename = "TITLESKY";
|
||||
levelstarttic = gametic;
|
||||
G_SetGamestate(GS_LEVEL);
|
||||
if (!P_SetupLevel(false, false))
|
||||
|
||||
+3
-3
@@ -45,12 +45,12 @@ extern boolean statdp; // stat display for extended player setup
|
||||
extern boolean nametaggfx; // Nametag stuffs
|
||||
extern boolean driftgaugegfx;
|
||||
|
||||
void D_AddAutoloadFiles(void);
|
||||
|
||||
// autoload stuff
|
||||
extern boolean autoloading;
|
||||
extern boolean autoloaded;
|
||||
extern boolean postautoloaded;
|
||||
extern boolean wasautoloaded;
|
||||
|
||||
void D_AddPostloadFiles(void);
|
||||
|
||||
extern char *autoloadwadfilespost[MAX_WADFILES];
|
||||
extern char *autoloadwadfiles[MAX_WADFILES];
|
||||
|
||||
@@ -2983,6 +2983,14 @@ static void Command_Map_f(void)
|
||||
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
|
||||
else
|
||||
{
|
||||
if (!mapheaderinfo[newmapnum-1] || mapheaderinfo[newmapnum-1] == NULL)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Invalid mapheaderinfo for Course %s (%s)\n"), realmapname, G_BuildMapName(newmapnum));
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype)))
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Course %s (%s) doesn't support %s mode!\n(Use -force to override)\n"), realmapname, G_BuildMapName(newmapnum),
|
||||
|
||||
@@ -413,6 +413,8 @@ typedef struct player_s
|
||||
// See pflags_t, above.
|
||||
pflags_t pflags;
|
||||
|
||||
UINT16 postimgflags;
|
||||
|
||||
// playing animation.
|
||||
panim_t panim;
|
||||
|
||||
|
||||
@@ -112,7 +112,6 @@ extern UINT8 window_notinfocus; // are we in focus? (backend independant -- hand
|
||||
extern boolean nodrawers;
|
||||
extern boolean noblit;
|
||||
extern boolean lastdraw;
|
||||
extern postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 postimgparam[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern INT32 viewwindowx, viewwindowy;
|
||||
|
||||
+6
-8
@@ -344,14 +344,12 @@ typedef union FColorRGBA RGBA_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
postimg_none,
|
||||
postimg_water,
|
||||
postimg_motion,
|
||||
postimg_flip,
|
||||
postimg_heat,
|
||||
postimg_mirror,
|
||||
postimg_mirrorflip
|
||||
} postimg_t;
|
||||
POSTIMG_WATER = 1, // Underwater screen effect.
|
||||
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
|
||||
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
|
||||
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
|
||||
POSTIMG_MIRROR = 1<<4, // encore screen effect.
|
||||
} postimgflag_t;
|
||||
|
||||
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
|
||||
#define LUMPERROR UINT32_MAX
|
||||
|
||||
+3
-4
@@ -4542,8 +4542,7 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (apromapnum == 0 || wanttable)
|
||||
else if (apromapnum == 0 || wanttable)
|
||||
{
|
||||
/* LEVEL 1--match keywords verbatim */
|
||||
if (( aprop = strcasestr(realmapname, mapname) ))
|
||||
@@ -4634,8 +4633,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep)
|
||||
{
|
||||
if (mapname[0] == '*') // current map
|
||||
return gamemap;
|
||||
else if (mapname[0] == '?')
|
||||
return G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL);
|
||||
else if (mapname[0] == '?' && mapheaderinfo[gamemap-1])
|
||||
return G_RandMap(G_TOLFlag(gametype), gamemap-1, false, 0, false, NULL)+1;
|
||||
else if (mapname[0] == '+' && mapheaderinfo[gamemap-1]) // next map
|
||||
{
|
||||
newmapnum = mapheaderinfo[gamemap-1]->nextlevel;
|
||||
|
||||
@@ -32,7 +32,6 @@ typedef struct gr_vissprite_s
|
||||
float scale;
|
||||
float spritexscale, spriteyscale;
|
||||
float spritexoffset, spriteyoffset;
|
||||
UINT32 renderflags;
|
||||
GLPatch_t *gpatch;
|
||||
boolean flip;
|
||||
UINT8 translucency; //alpha level 0-255
|
||||
|
||||
+182
-232
@@ -106,8 +106,6 @@ consvar_t cv_grbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL
|
||||
consvar_t cv_grframebuffer = {"gr_framebuffer", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, CV_grframebuffer_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
#endif
|
||||
|
||||
consvar_t cv_splitwallfix = {"splitwallfix", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
static CV_PossibleValue_t grrenderdistance_cons_t[] = {
|
||||
{0, "Max"}, {1, "1024"}, {2, "2048"}, {3, "4096"}, {4, "6144"}, {5, "8192"},
|
||||
{6, "12288"}, {7, "16384"}, {0, NULL}};
|
||||
@@ -297,6 +295,8 @@ ps_metric_t ps_hw_numcolors = {0};
|
||||
ps_metric_t ps_hw_batchsorttime = {0};
|
||||
ps_metric_t ps_hw_batchdrawtime = {0};
|
||||
|
||||
static void HWR_AddSprites(sector_t *sec);
|
||||
static void HWR_ProjectSprite(mobj_t *thing);
|
||||
static void HWR_AddPrecipitationSprites(void);
|
||||
static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
|
||||
@@ -652,7 +652,7 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope)
|
||||
|
||||
// HWR_RenderPlane
|
||||
// Render a floor or ceiling convex polygon
|
||||
void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap)
|
||||
static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap)
|
||||
{
|
||||
FSurfaceInfo Surf;
|
||||
FOutVector *v3d;
|
||||
@@ -679,7 +679,7 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc
|
||||
// no convex poly were generated for this subsector
|
||||
if (!xsub->planepoly)
|
||||
return;
|
||||
|
||||
|
||||
pv = xsub->planepoly->pts;
|
||||
nrPlaneVerts = xsub->planepoly->numpts;
|
||||
|
||||
@@ -838,14 +838,14 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc
|
||||
PolyFlags |= PF_Masked|PF_Modulated;
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
{
|
||||
if (PolyFlags & PF_Fog)
|
||||
shader = SHADER_FOG;
|
||||
else if (cv_ripplewater.value && (PolyFlags & PF_Ripple))
|
||||
shader = SHADER_WATER;
|
||||
else
|
||||
shader = SHADER_FLOOR;
|
||||
|
||||
|
||||
PolyFlags |= PF_ColorMapped;
|
||||
}
|
||||
|
||||
@@ -950,7 +950,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
|
||||
fixed_t i;
|
||||
// seg bbox
|
||||
fixed_t segbbox[4];
|
||||
|
||||
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
M_ClearBox(segbbox);
|
||||
@@ -1005,7 +1005,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
|
||||
|
||||
if (HWR_UseShader())
|
||||
shader = SHADER_WALL;
|
||||
|
||||
|
||||
HWR_ProcessPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal, shader, false);
|
||||
}
|
||||
}
|
||||
@@ -1038,7 +1038,7 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
|
||||
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap)
|
||||
{
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
|
||||
if (HWR_UseShader())
|
||||
@@ -1077,6 +1077,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
float endpegt, endpegb, endpegmul;
|
||||
float endheight = 0.0f, endbheight = 0.0f;
|
||||
|
||||
float diff;
|
||||
|
||||
fixed_t v1x = FloatToFixed(wallVerts[0].x);
|
||||
fixed_t v1y = FloatToFixed(wallVerts[0].z);
|
||||
fixed_t v2x = FloatToFixed(wallVerts[1].x);
|
||||
@@ -1088,32 +1090,36 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
realbot = bot = wallVerts[0].y;
|
||||
diff = top - bot;
|
||||
|
||||
pegt = wallVerts[3].t;
|
||||
pegb = wallVerts[0].t;
|
||||
|
||||
// Lactozilla: If both heights of a side lay on the same position, then this wall is a triangle.
|
||||
// To avoid division by zero, which would result in a NaN, we check if the vertical difference
|
||||
// between the two vertices is not zero.
|
||||
if (fpclassify(top - bot) == FP_ZERO && cv_splitwallfix.value)
|
||||
if (fpclassify(diff) == FP_ZERO)
|
||||
pegmul = 0.0;
|
||||
else
|
||||
pegmul = (pegb - pegt) / (top - bot);
|
||||
pegmul = (pegb - pegt) / diff;
|
||||
|
||||
endrealtop = endtop = wallVerts[2].y;
|
||||
endrealbot = endbot = wallVerts[1].y;
|
||||
diff = endtop - endbot;
|
||||
|
||||
endpegt = wallVerts[2].t;
|
||||
endpegb = wallVerts[1].t;
|
||||
|
||||
if (fpclassify(endtop - endbot) == FP_ZERO && cv_splitwallfix.value)
|
||||
if (fpclassify(diff) == FP_ZERO)
|
||||
endpegmul = 0.0;
|
||||
else
|
||||
endpegmul = (endpegb - endpegt) / (endtop - endbot);
|
||||
endpegmul = (endpegb - endpegt) / diff;
|
||||
|
||||
for (INT32 i = 0; i < sector->numlights; i++)
|
||||
{
|
||||
if (endtop < endrealbot && top < realbot)
|
||||
return;
|
||||
|
||||
|
||||
lightlist_t *list = sector->lightlist;
|
||||
|
||||
if (!(list[i].flags & FF_NOSHADE))
|
||||
@@ -1176,14 +1182,11 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
bheight = realbot;
|
||||
endbheight = endrealbot;
|
||||
}
|
||||
|
||||
if (cv_splitwallfix.value)
|
||||
{
|
||||
if (endbheight > endtop)
|
||||
endbot = endtop;
|
||||
}
|
||||
|
||||
if ((endbheight >= endtop && bheight >= top && !cv_splitwallfix.value) || (bheight >= top && cv_splitwallfix.value))
|
||||
if (endbheight > endtop)
|
||||
endbot = endtop;
|
||||
|
||||
if (bheight >= top)
|
||||
continue;
|
||||
|
||||
// Found a break
|
||||
@@ -1193,15 +1196,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
||||
if (bot < realbot)
|
||||
bot = realbot;
|
||||
|
||||
if (cv_splitwallfix.value)
|
||||
endbot = min(max(endbheight, endrealbot), endtop);
|
||||
else
|
||||
{
|
||||
endbot = endbheight;
|
||||
|
||||
if (endbot < endrealbot)
|
||||
endbot = endrealbot;
|
||||
}
|
||||
endbot = min(max(endbheight, endrealbot), endtop);
|
||||
|
||||
Surf->PolyColor.s.alpha = alpha;
|
||||
|
||||
@@ -1429,19 +1424,14 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
fixed_t worldhighslope = 0, worldlowslope = 0;
|
||||
fixed_t v1x, v1y, v2x, v2y;
|
||||
|
||||
float cliplow = 0.0f, cliphigh = 0.0f;
|
||||
fixed_t h, l; // 3D sides and 2s middle textures
|
||||
fixed_t hS, lS;
|
||||
|
||||
FUINT lightnum = 0; // shut up compiler
|
||||
extracolormap_t *colormap;
|
||||
FSurfaceInfo Surf;
|
||||
|
||||
boolean noencore = false;
|
||||
|
||||
gr_sidedef = gr_curline->sidedef;
|
||||
gr_linedef = gr_curline->linedef;
|
||||
|
||||
const boolean noencore = (gr_linedef->flags & ML_TFERLINE);
|
||||
|
||||
if (gr_curline->pv1)
|
||||
{
|
||||
vs.x = ((polyvertex_t *)gr_curline->pv1)->x;
|
||||
@@ -1492,18 +1482,16 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
|
||||
// x offset the texture
|
||||
fixed_t texturehpeg = gr_sidedef->textureoffset + gr_curline->offset;
|
||||
cliplow = (float)texturehpeg;
|
||||
cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
|
||||
float cliplow = (float)texturehpeg;
|
||||
float cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT));
|
||||
|
||||
lightnum = gr_frontsector->lightlevel;
|
||||
colormap = gr_frontsector->extra_colormap;
|
||||
FUINT lightnum = gr_frontsector->lightlevel;
|
||||
extracolormap_t *colormap = gr_frontsector->extra_colormap;
|
||||
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline);
|
||||
|
||||
if (gr_linedef->flags & ML_TFERLINE)
|
||||
noencore = true;
|
||||
|
||||
FSurfaceInfo Surf;
|
||||
Surf.PolyColor.s.alpha = 255;
|
||||
|
||||
|
||||
INT32 gr_midtexture = R_GetTextureNum(gr_sidedef->midtexture);
|
||||
GLMapTexture_t *grTex = NULL;
|
||||
|
||||
@@ -1512,6 +1500,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
{
|
||||
INT32 gr_toptexture = 0, gr_bottomtexture = 0;
|
||||
|
||||
fixed_t texturevpeg;
|
||||
|
||||
SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight)
|
||||
SLOPEPARAMS(gr_backsector->f_slope, worldlow, worldlowslope, gr_backsector->floorheight)
|
||||
|
||||
@@ -1527,8 +1517,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
{
|
||||
// Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the
|
||||
// backsector is lower
|
||||
if ((worldhigh <= worldtop && worldhighslope <= worldtopslope)// Assuming ESLOPE is always on with my changes
|
||||
&& (worldhigh != worldtop || worldhighslope != worldtopslope))
|
||||
if ((worldhigh <= worldtop && worldhighslope <= worldtopslope) // Assuming ESLOPE is always on with my changes
|
||||
&& (worldhigh != worldtop || worldhighslope != worldtopslope))
|
||||
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
|
||||
{
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
|
||||
@@ -1604,51 +1594,47 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
// check TOP TEXTURE
|
||||
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gr_toptexture)
|
||||
{
|
||||
// PEGGING
|
||||
if (gr_linedef->flags & ML_DONTPEGTOP)
|
||||
texturevpeg = 0;
|
||||
else if (gr_linedef->flags & ML_EFFECT1)
|
||||
texturevpeg = worldhigh + textureheight[gr_toptexture] - worldtop;
|
||||
else
|
||||
texturevpeg = gr_backsector->ceilingheight + textureheight[gr_toptexture] - gr_frontsector->ceilingheight;
|
||||
|
||||
texturevpeg += gr_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= textureheight[gr_toptexture];
|
||||
|
||||
grTex = HWR_GetTexture(gr_toptexture, noencore);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gr_linedef->flags & ML_EFFECT1))
|
||||
{
|
||||
fixed_t texturevpegtop; // top
|
||||
|
||||
grTex = HWR_GetTexture(gr_toptexture, gr_linedef->flags & ML_TFERLINE);
|
||||
|
||||
// PEGGING
|
||||
if (gr_linedef->flags & ML_DONTPEGTOP)
|
||||
texturevpegtop = 0;
|
||||
else if (gr_linedef->flags & ML_EFFECT1)
|
||||
texturevpegtop = worldhigh + textureheight[gr_sidedef->toptexture] - worldtop;
|
||||
else
|
||||
texturevpegtop = gr_backsector->ceilingheight + textureheight[gr_sidedef->toptexture] - gr_frontsector->ceilingheight;
|
||||
|
||||
texturevpegtop += gr_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpegtop %= SHORT(textures[gr_toptexture]->height)<<FRACBITS;
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpegtop * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gr_frontsector->ceilingheight - gr_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gr_linedef->flags & ML_EFFECT1))
|
||||
{
|
||||
// Unskewed
|
||||
wallVerts[3].t -= (worldtop - gr_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[2].t -= (worldtopslope - gr_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].t -= (worldhigh - gr_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[1].t -= (worldhighslope - gr_backsector->ceilingheight) * grTex->scaleY;
|
||||
}
|
||||
else if (gr_linedef->flags & ML_DONTPEGTOP)
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpegtop + worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
// Unskewed
|
||||
wallVerts[3].t -= (worldtop - gr_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[2].t -= (worldtopslope - gr_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].t -= (worldhigh - gr_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[1].t -= (worldhighslope - gr_backsector->ceilingheight) * grTex->scaleY;
|
||||
}
|
||||
else if (gr_linedef->flags & ML_DONTPEGTOP)
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
|
||||
// set top/bottom coords
|
||||
@@ -1658,35 +1644,33 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
|
||||
|
||||
if (!gl_drawing_stencil && gr_frontsector->numlights)
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, gr_linedef->flags & ML_TFERLINE, &Surf, FF_CUTLEVEL, NULL, 0);
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_toptexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0);
|
||||
else if (!gl_drawing_stencil && grTex->mipmap.flags & TF_TRANSPARENT)
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, gr_linedef->flags & ML_TFERLINE, PF_Environment, false, lightnum, colormap);
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_toptexture, noencore, PF_Environment, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
|
||||
// check BOTTOM TEXTURE
|
||||
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gr_bottomtexture) //only if VISIBLE!!!
|
||||
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gr_bottomtexture)
|
||||
{
|
||||
fixed_t texturevpegbottom = 0; // bottom
|
||||
|
||||
grTex = HWR_GetTexture(gr_bottomtexture, gr_linedef->flags & ML_TFERLINE);
|
||||
|
||||
// PEGGING
|
||||
if (!(gr_linedef->flags & ML_DONTPEGBOTTOM))
|
||||
texturevpegbottom = 0;
|
||||
texturevpeg = 0;
|
||||
else if (gr_linedef->flags & ML_EFFECT1)
|
||||
texturevpegbottom = worldbottom - worldlow;
|
||||
texturevpeg = worldbottom - worldlow;
|
||||
else
|
||||
texturevpegbottom = gr_frontsector->floorheight - gr_backsector->floorheight;
|
||||
texturevpeg = gr_frontsector->floorheight - gr_backsector->floorheight;
|
||||
|
||||
texturevpegbottom += gr_sidedef->rowoffset;
|
||||
texturevpeg += gr_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpegbottom %= SHORT(textures[gr_bottomtexture]->height)<<FRACBITS;
|
||||
texturevpeg %= textureheight[gr_bottomtexture];
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpegbottom * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY;
|
||||
grTex = HWR_GetTexture(gr_bottomtexture, noencore);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gr_backsector->floorheight - gr_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
@@ -1702,15 +1686,14 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
else if (gr_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
|
||||
//wallVerts[3].t = wallVerts[0].t - (worldlow - worldbottom) * grTex->scaleY; // no need, [3] is already this
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpegbottom + worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
}
|
||||
|
||||
// set top/bottom coords
|
||||
@@ -1720,9 +1703,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||
|
||||
if (!gl_drawing_stencil && gr_frontsector->numlights)
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, gr_linedef->flags & ML_TFERLINE, &Surf, FF_CUTLEVEL, NULL, 0);
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_bottomtexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0);
|
||||
else if (!gl_drawing_stencil && grTex->mipmap.flags & TF_TRANSPARENT)
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, gr_linedef->flags & ML_TFERLINE, PF_Environment, false, lightnum, colormap);
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_bottomtexture, noencore, PF_Environment, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
@@ -1758,23 +1741,21 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
else
|
||||
low = back->floorheight;
|
||||
|
||||
repeats = (high - low)/textureheight[gr_sidedef->midtexture];
|
||||
if ((high-low)%textureheight[gr_sidedef->midtexture])
|
||||
repeats = (high - low) / textureheight[gr_midtexture];
|
||||
if ((high - low) % textureheight[gr_midtexture])
|
||||
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
|
||||
}
|
||||
else
|
||||
repeats = 1;
|
||||
|
||||
fixed_t midtexheight = textureheight[gr_midtexture] * repeats;
|
||||
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
|
||||
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
|
||||
|
||||
// SoM: a little note: This code re-arranging will
|
||||
// fix the bug in Nimrod map02. popentop and popenbottom
|
||||
// record the limits the texture can be displayed in.
|
||||
// polytop and polybottom, are the ideal (i.e. unclipped)
|
||||
// heights of the polygon, and h & l, are the final (clipped)
|
||||
// poly coords.
|
||||
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
|
||||
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
|
||||
|
||||
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
|
||||
// you must use the linedef's backsector to be correct
|
||||
@@ -1788,39 +1769,40 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
{
|
||||
popentop = min(worldtop, worldhigh);
|
||||
popenbottom = max(worldbottom, worldlow);
|
||||
|
||||
popentopslope = min(worldtopslope, worldhighslope);
|
||||
popenbottomslope = max(worldbottomslope, worldlowslope);
|
||||
}
|
||||
|
||||
// Find the wall's coordinates
|
||||
fixed_t midtexheight = textureheight[gr_midtexture] * repeats;
|
||||
|
||||
if (gr_linedef->flags & ML_EFFECT2)
|
||||
{
|
||||
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
|
||||
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) // Peg it to the floor
|
||||
{
|
||||
polybottom = max(front->floorheight, back->floorheight) + gr_sidedef->rowoffset;
|
||||
polybottomslope = polybottom;
|
||||
polytop = polybottom + midtexheight;
|
||||
polytopslope = polytop;
|
||||
}
|
||||
else
|
||||
else // Peg it to the ceiling
|
||||
{
|
||||
polytop = min(front->ceilingheight, back->ceilingheight) + gr_sidedef->rowoffset;
|
||||
polytopslope = polytop;
|
||||
polybottom = polytop - midtexheight;
|
||||
polybottomslope = polybottom;
|
||||
}
|
||||
|
||||
// The right side's coordinates are the the same as the left side
|
||||
polytopslope = polytop;
|
||||
polybottomslope = polybottom;
|
||||
}
|
||||
else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
|
||||
else if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3)) // Skew the texture, but peg it to the floor
|
||||
{
|
||||
polybottom = popenbottom + gr_sidedef->rowoffset;
|
||||
polytop = polybottom + midtexheight;
|
||||
polybottomslope = popenbottomslope + gr_sidedef->rowoffset;
|
||||
polytopslope = polybottomslope + midtexheight;
|
||||
}
|
||||
else
|
||||
else // Skew it according to the ceiling's slope
|
||||
{
|
||||
polytop = popentop + gr_sidedef->rowoffset;
|
||||
polybottom = polytop - textureheight[gr_midtexture]*repeats;
|
||||
polybottom = polytop - midtexheight;
|
||||
polytopslope = popentopslope + gr_sidedef->rowoffset;
|
||||
polybottomslope = polytopslope - midtexheight;
|
||||
@@ -1851,9 +1833,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
lS = max(polybottomslope, lowcutslope);
|
||||
|
||||
// PEGGING
|
||||
fixed_t texturevpeg, texturevpegslope;
|
||||
|
||||
grTex = HWR_GetTexture(gr_midtexture, gr_linedef->flags & ML_TFERLINE);
|
||||
fixed_t texturevpegslope;
|
||||
|
||||
if (!!(gr_linedef->flags & ML_DONTPEGBOTTOM) ^ !!(gr_linedef->flags & ML_EFFECT3))
|
||||
{
|
||||
@@ -1866,11 +1846,16 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
texturevpegslope = polytopslope - hS;
|
||||
}
|
||||
|
||||
grTex = HWR_GetTexture(gr_midtexture, noencore);
|
||||
|
||||
// Left side
|
||||
wallVerts[3].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
|
||||
// Right side
|
||||
wallVerts[2].t = texturevpegslope * grTex->scaleY;
|
||||
wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// set top/bottom coords
|
||||
@@ -1889,9 +1874,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
blendmode |= PF_Decal;
|
||||
|
||||
if (!gl_drawing_stencil && gr_frontsector->numlights)
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, gr_linedef->flags & ML_TFERLINE, &Surf, (!(blendmode & PF_Masked)) ? FF_TRANSLUCENT : FF_CUTLEVEL, NULL, PF_Decal);
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, noencore, &Surf, (!(blendmode & PF_Masked)) ? FF_TRANSLUCENT : FF_CUTLEVEL, NULL, PF_Decal);
|
||||
else if (!gl_drawing_stencil && !(blendmode & PF_Masked))
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, gr_linedef->flags & ML_TFERLINE, blendmode, false, lightnum, colormap);
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, noencore, blendmode, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
|
||||
}
|
||||
@@ -1911,7 +1896,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
else
|
||||
texturevpeg = gr_sidedef->rowoffset; // top of texture at top
|
||||
|
||||
grTex = HWR_GetTexture(gr_midtexture, gr_linedef->flags & ML_TFERLINE);
|
||||
grTex = HWR_GetTexture(gr_midtexture, noencore);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gr_frontsector->ceilingheight - gr_frontsector->floorheight) * grTex->scaleY;
|
||||
@@ -1944,11 +1929,11 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||
|
||||
if (gr_frontsector->numlights)
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, gr_linedef->flags & ML_TFERLINE, &Surf, FF_CUTLEVEL, NULL, 0);
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, gr_midtexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0);
|
||||
else // I don't think that solid walls can use translucent linedef types...
|
||||
{
|
||||
if (grTex->mipmap.flags & TF_TRANSPARENT)
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, gr_linedef->flags & ML_TFERLINE, PF_Environment, false, lightnum, colormap);
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, gr_midtexture, noencore, PF_Environment, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
@@ -1965,22 +1950,21 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
|
||||
// Single sided lines are simple for skywalls, just need to draw from the top or bottom of the sector if there's
|
||||
// a sky flat
|
||||
if (!gr_curline->polyseg)
|
||||
{
|
||||
if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector
|
||||
{
|
||||
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
|
||||
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
|
||||
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
if (gr_frontsector->floorpic == skyflatnum)
|
||||
{
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
|
||||
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space
|
||||
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
@@ -1988,7 +1972,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
}
|
||||
|
||||
//Hurdler: 3d-floors test
|
||||
if (!gl_drawing_stencil && gr_frontsector && gr_backsector && gr_frontsector->tag != gr_backsector->tag && (gr_backsector->ffloors || gr_frontsector->ffloors))
|
||||
if (!gl_drawing_stencil && gr_backsector && gr_frontsector->tag != gr_backsector->tag && (gr_backsector->ffloors || gr_frontsector->ffloors))
|
||||
{
|
||||
ffloor_t * rover;
|
||||
fixed_t highcut = 0, lowcut = 0;
|
||||
@@ -2120,9 +2104,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(lightnum, colormap);
|
||||
|
||||
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline);
|
||||
|
||||
if (gr_frontsector->numlights)
|
||||
HWR_SplitWall(gr_frontsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0);
|
||||
@@ -2144,7 +2129,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
else
|
||||
{
|
||||
if (blendmode != PF_Masked)
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, texnum, gr_linedef->flags & ML_TFERLINE, blendmode, false, lightnum, colormap);
|
||||
HWR_AddTransparentWall(wallVerts, &Surf, texnum, noencore, blendmode, false, lightnum, colormap);
|
||||
else
|
||||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
@@ -2190,7 +2175,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
l = lowcut;
|
||||
lS = lowcutslope;
|
||||
}
|
||||
|
||||
|
||||
//Hurdler: HW code starts here
|
||||
//FIXME: check if peging is correct
|
||||
// set top/bottom coords
|
||||
@@ -2234,9 +2219,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||
|
||||
lightnum = rover->master->frontsector->lightlevel;
|
||||
colormap = rover->master->frontsector->extra_colormap;
|
||||
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline);
|
||||
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
|
||||
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(lightnum, colormap);
|
||||
|
||||
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gr_curline);
|
||||
|
||||
if (gr_backsector->numlights)
|
||||
HWR_SplitWall(gr_backsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0);
|
||||
@@ -2288,7 +2274,7 @@ static boolean CheckClip(sector_t * afrontsector, sector_t * abacksector)
|
||||
if (afrontsector->f_slope || afrontsector->c_slope || abacksector->f_slope || abacksector->c_slope)
|
||||
{
|
||||
fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t
|
||||
|
||||
|
||||
if (gr_curline->pv1)
|
||||
{
|
||||
v1x = FLOAT_TO_FIXED(((polyvertex_t *)gr_curline->pv1)->x);
|
||||
@@ -2309,7 +2295,7 @@ static boolean CheckClip(sector_t * afrontsector, sector_t * abacksector)
|
||||
v2x = gr_curline->v2->x;
|
||||
v2y = gr_curline->v2->y;
|
||||
}
|
||||
|
||||
|
||||
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
|
||||
if (slope) { \
|
||||
end1 = P_GetZAt(slope, v1x, v1y); \
|
||||
@@ -2680,7 +2666,7 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t
|
||||
|
||||
static FOutVector *planeVerts = NULL;
|
||||
static UINT16 numAllocedPlaneVerts = 0;
|
||||
|
||||
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
nrPlaneVerts = polysector->numVertices;
|
||||
@@ -2826,11 +2812,11 @@ void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t
|
||||
blendmode |= PF_Masked|PF_Modulated;
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
{
|
||||
shader = SHADER_FLOOR;
|
||||
blendmode |= PF_ColorMapped;
|
||||
}
|
||||
|
||||
|
||||
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, shader, false);
|
||||
}
|
||||
|
||||
@@ -3092,7 +3078,7 @@ static void HWR_Subsector(size_t num)
|
||||
continue;
|
||||
if (sub->validcount == validcount)
|
||||
continue;
|
||||
|
||||
|
||||
// rendering heights for bottom and top planes
|
||||
// yes there were functions for this stuff, no idea why it wasnt used but bleh
|
||||
bottomCullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy);
|
||||
@@ -3325,7 +3311,7 @@ static void HWR_RenderBSPNode(INT32 bspnum)
|
||||
bsp = &nodes[bspnum];
|
||||
|
||||
// Decide which side the view point is on.
|
||||
side = R_PointOnSide(viewx, viewy, bsp);
|
||||
side = R_PointOnSideRender(viewx, viewy, bsp);
|
||||
|
||||
// Recursively divide front space.
|
||||
if (HWR_PortalCheckBBox(bsp->bbox[side]))
|
||||
@@ -3811,7 +3797,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr)
|
||||
}
|
||||
|
||||
alpha = Surf.PolyColor.s.alpha;
|
||||
|
||||
|
||||
// Start with the lightlevel and colormap from the top of the sprite
|
||||
lightlevel = *list[sector->numlights - 1].lightlevel;
|
||||
|
||||
@@ -3951,7 +3937,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr)
|
||||
GLPatch_t *gpatch; // sprite patch converted to hardware
|
||||
FSurfaceInfo Surf;
|
||||
FBITFIELD blend = 0;
|
||||
|
||||
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
if (!spr->mobj)
|
||||
@@ -4484,7 +4470,7 @@ static void HWR_RenderDrawNodes(void)
|
||||
wall->lightlevel, wall->wallcolormap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PS_STOP_TIMING(ps_hw_nodedrawtime);
|
||||
|
||||
numdrawnodes = 0;
|
||||
@@ -4496,9 +4482,10 @@ static void HWR_RenderDrawNodes(void)
|
||||
// --------------------------------------------------------------------------
|
||||
// Draw all vissprites
|
||||
// --------------------------------------------------------------------------
|
||||
void HWR_DrawSprites(void)
|
||||
static void HWR_DrawSprites(void)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < gr_visspritecount; i++)
|
||||
{
|
||||
gr_vissprite_t *spr = gr_vsprorder[i];
|
||||
@@ -4542,7 +4529,7 @@ void HWR_DrawSprites(void)
|
||||
// HWR_AddSprites
|
||||
// During BSP traversal, this adds sprites by sector.
|
||||
// --------------------------------------------------------------------------
|
||||
void HWR_AddSprites(sector_t *sec)
|
||||
static void HWR_AddSprites(sector_t *sec)
|
||||
{
|
||||
mobj_t *thing;
|
||||
fixed_t limit_dist;
|
||||
@@ -4595,7 +4582,7 @@ static void HWR_AddPrecipitationSprites(void)
|
||||
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
precipmobj_t *th;
|
||||
|
||||
|
||||
if (current_bsp_culling_distance)
|
||||
drawdist = min((fixed_t)current_bsp_culling_distance, (fixed_t)(cv_drawdist_precip.value) * precipscale);
|
||||
else
|
||||
@@ -4629,7 +4616,7 @@ static void HWR_AddPrecipitationSprites(void)
|
||||
// Generates a vissprite for a thing if it might be visible.
|
||||
// --------------------------------------------------------------------------
|
||||
// BP why not use xtoviexangle/viewangletox like in bsp ?....
|
||||
void HWR_ProjectSprite(mobj_t *thing)
|
||||
static void HWR_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
gr_vissprite_t *vis;
|
||||
float tr_x, tr_y;
|
||||
@@ -4666,12 +4653,12 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
angle_t sliptiderollangle = 0;
|
||||
#endif
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
if (!thing)
|
||||
return;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
vflip = (thing->eflags & MFE_VERTICALFLIP);
|
||||
mirrored = thing->mirrored;
|
||||
hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
|
||||
@@ -4776,9 +4763,9 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
else
|
||||
{
|
||||
// choose a different rotation based on player view
|
||||
if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
rot = 2; // F3 slot
|
||||
else // Normal behaviour
|
||||
rot = (ang+ANGLE_202h)>>29;
|
||||
@@ -4802,9 +4789,9 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
#ifdef ROTSPRITE
|
||||
if (cv_spriteroll.value)
|
||||
{
|
||||
rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), interp.roll)
|
||||
rollangle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), interp.roll)
|
||||
+ FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), interp.pitch)
|
||||
+ FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), interp.sloperoll)
|
||||
+ FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), interp.sloperoll)
|
||||
+ FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), interp.slopepitch)
|
||||
+ thing->rollangle;
|
||||
|
||||
@@ -4823,12 +4810,12 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
|
||||
if (rotsprite != NULL)
|
||||
{
|
||||
spr_width = rotsprite->width << FRACBITS;
|
||||
spr_height = rotsprite->height << FRACBITS;
|
||||
spr_offset = rotsprite->leftoffset << FRACBITS;
|
||||
spr_topoffset = rotsprite->topoffset << FRACBITS;
|
||||
spr_width = SHORT(rotsprite->width) << FRACBITS;
|
||||
spr_height = SHORT(rotsprite->height) << FRACBITS;
|
||||
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
|
||||
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
|
||||
spr_topoffset += FEETADJUST;
|
||||
|
||||
|
||||
// flip -> rotate, not rotate -> flip
|
||||
flip = 0;
|
||||
}
|
||||
@@ -4836,21 +4823,8 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
{
|
||||
spr_offset = interp.spritexoffset;
|
||||
spr_topoffset = interp.spriteyoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
SINT8 flipoffset = 1;
|
||||
|
||||
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
|
||||
flipoffset = -1;
|
||||
|
||||
spr_offset += interp.spritexoffset * flipoffset;
|
||||
spr_topoffset += interp.spriteyoffset * flipoffset;
|
||||
}
|
||||
spr_offset += interp.spritexoffset;
|
||||
spr_topoffset += interp.spriteyoffset;
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
@@ -4865,7 +4839,7 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
|
||||
spritexscale *= this_scale;
|
||||
spriteyscale *= this_scale;
|
||||
|
||||
|
||||
flip = !flip != !hflip;
|
||||
|
||||
if (flip)
|
||||
@@ -4910,13 +4884,12 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
if (heightsec != -1 && phs != -1) // only clip things which are in special sectors
|
||||
{
|
||||
if (gr_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ?
|
||||
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) :
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight))
|
||||
return;
|
||||
|
||||
if (gr_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ?
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gr_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gr_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) :
|
||||
FIXED_TO_FLOAT(interp.z) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4926,7 +4899,9 @@ void HWR_ProjectSprite(mobj_t *thing)
|
||||
vis->x2 = x2;
|
||||
vis->z1 = z1;
|
||||
vis->z2 = z2;
|
||||
|
||||
vis->tz = tz; // Keep tz for the simple sprite sorting that happens
|
||||
|
||||
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
|
||||
vis->flip = flip;
|
||||
|
||||
@@ -5218,9 +5193,6 @@ static void HWR_SetTransformAiming(FTransform *trans)
|
||||
|
||||
void HWR_SetTransform(float fpov, player_t *player)
|
||||
{
|
||||
postimg_t *postprocessor = &postimgtype[0];
|
||||
INT32 i;
|
||||
|
||||
gr_viewx = FIXED_TO_FLOAT(viewx);
|
||||
gr_viewy = FIXED_TO_FLOAT(viewy);
|
||||
gr_viewz = FIXED_TO_FLOAT(viewz);
|
||||
@@ -5249,24 +5221,16 @@ void HWR_SetTransform(float fpov, player_t *player)
|
||||
HWR_RollTransform(&atransform, viewroll);
|
||||
atransform.splitscreen = splitscreen;
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
postprocessor = &postimgtype[i];
|
||||
}
|
||||
|
||||
atransform.flip = false;
|
||||
if (*postprocessor == postimg_flip)
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR))
|
||||
atransform.flip = true;
|
||||
|
||||
atransform.mirror = false;
|
||||
if (*postprocessor == postimg_mirror)
|
||||
if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP))
|
||||
atransform.mirror = true;
|
||||
|
||||
atransform.mirrorflip = false;
|
||||
if (*postprocessor == postimg_mirrorflip)
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && (player->postimgflags & POSTIMG_MIRROR))
|
||||
atransform.mirrorflip = true;
|
||||
|
||||
// Set transform.
|
||||
@@ -5352,7 +5316,7 @@ static void HWR_RenderPortal(gl_portal_t* portal, gl_portal_t* rootportal, const
|
||||
HWR_PortalFrame(rootportal);
|
||||
else // current frame is not a portal frame but the main view!
|
||||
{
|
||||
R_SetupFrame(player, false);
|
||||
R_SetupFrame(player);
|
||||
portalclipline = NULL;
|
||||
}
|
||||
|
||||
@@ -5428,7 +5392,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe
|
||||
}
|
||||
else
|
||||
portalclipline = NULL;
|
||||
|
||||
|
||||
// Set transform.
|
||||
HWD.pfnSetTransform(&atransform);
|
||||
|
||||
@@ -5478,7 +5442,7 @@ static void HWR_RenderViewpoint(gl_portal_t *rootportal, const float fpov, playe
|
||||
HWR_SetTransform(fpov, player);// restore transform
|
||||
}
|
||||
gr_collect_skywalls = false;
|
||||
|
||||
|
||||
ps_numsprites.value.i = gr_visspritecount;
|
||||
PS_START_TIMING(ps_hw_spritesorttime);
|
||||
HWR_SortVisSprites();
|
||||
@@ -5626,7 +5590,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||
}
|
||||
PS_STOP_TIMING(ps_skyboxtime);
|
||||
|
||||
R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here
|
||||
R_SetupFrame(player); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here
|
||||
framecount++; // for timedemo
|
||||
HWR_RenderFrame(viewnumber, player, false);
|
||||
}
|
||||
@@ -5702,8 +5666,6 @@ void HWR_AddCommands(void)
|
||||
|
||||
CV_RegisterVar(&cv_grbatching);
|
||||
|
||||
CV_RegisterVar(&cv_splitwallfix);
|
||||
|
||||
CV_RegisterVar(&cv_grrenderdistance);
|
||||
|
||||
CV_RegisterVar(&cv_grfakecontrast);
|
||||
@@ -5750,7 +5712,7 @@ void HWR_Startup(void)
|
||||
{
|
||||
CONS_Printf("HWR_Startup()...\n");
|
||||
textureformat = patchformat = GL_TEXFMT_RGBA;
|
||||
|
||||
|
||||
HWR_InitTextureCache();
|
||||
HWR_InitMD2();
|
||||
|
||||
@@ -5789,7 +5751,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
|
||||
{
|
||||
FBITFIELD blendmode = blend;
|
||||
UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha
|
||||
|
||||
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting
|
||||
@@ -5809,10 +5771,10 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
|
||||
|
||||
blendmode |= PF_ColorMapped;
|
||||
}
|
||||
|
||||
|
||||
if (fogwall)
|
||||
blendmode |= PF_Fog;
|
||||
|
||||
|
||||
blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency
|
||||
HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode, shader, false);
|
||||
|
||||
@@ -5829,20 +5791,8 @@ INT32 HWR_GetTextureUsed(void)
|
||||
|
||||
void HWR_DoPostProcessor(player_t *player)
|
||||
{
|
||||
postimg_t *type = &postimgtype[0];
|
||||
UINT8 i;
|
||||
|
||||
HWD.pfnUnSetShader();
|
||||
|
||||
for (i = splitscreen; i > 0; i--)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
type = &postimgtype[i];
|
||||
break;
|
||||
}
|
||||
|
||||
// Armageddon Blast Flash!
|
||||
// Could this even be considered postprocessor?
|
||||
if (!HWR_PalRenderFlashpal() && player->flashcount)
|
||||
@@ -5879,7 +5829,7 @@ void HWR_DoPostProcessor(player_t *player)
|
||||
return;
|
||||
|
||||
// Drunken vision! WooOOooo~
|
||||
if (*type == postimg_water || *type == postimg_heat)
|
||||
if (player->postimgflags & POSTIMG_WATER || player->postimgflags & POSTIMG_HEAT)
|
||||
{
|
||||
// 10 by 10 grid. 2 coordinates (xy)
|
||||
float v[SCREENVERTS][SCREENVERTS][2];
|
||||
@@ -5891,7 +5841,7 @@ void HWR_DoPostProcessor(player_t *player)
|
||||
INT32 FREQUENCY;
|
||||
|
||||
// Modifies the wave.
|
||||
if (*type == postimg_water)
|
||||
if (player->postimgflags & POSTIMG_WATER)
|
||||
{
|
||||
WAVELENGTH = 5;
|
||||
AMPLITUDE = 20;
|
||||
|
||||
@@ -116,7 +116,7 @@ void HWR_MakeScreenFinalTexture(void);
|
||||
void HWR_DrawScreenFinalTexture(INT32 width, INT32 height);
|
||||
|
||||
// hw_main.c: Planes
|
||||
void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
//void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
|
||||
|
||||
void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
|
||||
@@ -131,12 +131,6 @@ void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 t
|
||||
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
|
||||
void HWR_DrawSkyBackground(float fpov);
|
||||
|
||||
// hw_main.c: Sprites
|
||||
void HWR_AddSprites(sector_t *sec);
|
||||
void HWR_ProjectSprite(mobj_t *thing);
|
||||
//void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
|
||||
void HWR_DrawSprites(void);
|
||||
|
||||
// hw_bsp.c
|
||||
void HWR_CreatePlanePolygons(INT32 bspnum);
|
||||
extern boolean gr_maphasportals;
|
||||
@@ -152,7 +146,6 @@ extern consvar_t cv_grshaders;
|
||||
#ifdef USE_FBO_OGL
|
||||
extern consvar_t cv_grframebuffer;
|
||||
#endif
|
||||
extern consvar_t cv_splitwallfix;
|
||||
extern consvar_t cv_grshearing;
|
||||
extern consvar_t cv_grfov;
|
||||
extern consvar_t cv_grmdls;
|
||||
|
||||
+2
-1
@@ -2617,7 +2617,8 @@ static void HU_DrawRankings(void)
|
||||
boolean completed[MAXPLAYERS];
|
||||
UINT32 whiteplayer = MAXPLAYERS;
|
||||
|
||||
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
|
||||
if (!automapactive)
|
||||
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
|
||||
|
||||
if (cons_menuhighlight.value)
|
||||
hilicol = cons_menuhighlight.value;
|
||||
|
||||
+88
-94
@@ -725,34 +725,34 @@ void K_RegisterKartStuff(void)
|
||||
CV_RegisterVar(&cv_showinput);
|
||||
CV_RegisterVar(&cv_showlaptimes);
|
||||
CV_RegisterVar(&cv_newspeedometer);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_battlespeedo);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_saltyhop);
|
||||
CV_RegisterVar(&cv_saltyhopsfx);
|
||||
CV_RegisterVar(&cv_saltysquish);
|
||||
|
||||
|
||||
//Colourized HUD
|
||||
CV_RegisterVar(&cv_colorizedhud);
|
||||
CV_RegisterVar(&cv_colorizedhudcolor);
|
||||
CV_RegisterVar(&cv_colorizeditembox);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_darkitembox);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_biglaps);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_highresportrait);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_slamsound);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_minihead);
|
||||
CV_RegisterVar(&cv_showminimapnames);
|
||||
CV_RegisterVar(&cv_showlapemblem);
|
||||
|
||||
CV_RegisterVar(&cv_stagetitle);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_stagetitle);
|
||||
|
||||
CV_RegisterVar(&cv_lessflicker);
|
||||
|
||||
|
||||
CV_RegisterVar(&cv_mouseturn);
|
||||
|
||||
}
|
||||
@@ -3197,7 +3197,7 @@ static void K_StretchPlayerGravity(player_t *p)
|
||||
I_Assert(p != NULL);
|
||||
I_Assert(p->mo != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(p->mo));
|
||||
|
||||
|
||||
if (p->mo->slamsoundtimer)
|
||||
p->mo->slamsoundtimer--;
|
||||
|
||||
@@ -3233,7 +3233,7 @@ static void K_StretchPlayerGravity(player_t *p)
|
||||
slamDiv = 0;
|
||||
else
|
||||
slamDiv = FixedDiv(p->mo->stretchslam, stretchScaleFactor);
|
||||
|
||||
|
||||
p->mo->spritexscale = (dxs+(((slamDiv*2)/3)*2));
|
||||
p->mo->spriteyscale = (dys-(slamDiv));
|
||||
if (p->mo->stretchslam > 0)
|
||||
@@ -3243,7 +3243,7 @@ static void K_StretchPlayerGravity(player_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
static void K_QuiteSaltyHop(player_t *p)
|
||||
static void K_QuiteSaltyHop(player_t *p)
|
||||
{
|
||||
// what the fuck is this haya
|
||||
fixed_t mos = FRACUNIT; // doesnt work correctly if it isnt :/
|
||||
@@ -3265,7 +3265,7 @@ static void K_QuiteSaltyHop(player_t *p)
|
||||
p->mo->salty_zoffset = 0;
|
||||
p->mo->salty_momz = 0;
|
||||
p->mo->init_salty = true;
|
||||
}
|
||||
}
|
||||
else if ((p->mo->salty_jump)) {
|
||||
if (p->mo->eflags & MFE_JUSTHITFLOOR) {
|
||||
p->mo->salty_zoffset = 0;
|
||||
@@ -3299,7 +3299,7 @@ static void K_QuiteSaltyHop(player_t *p)
|
||||
p->mo->salty_jump = true;
|
||||
p->mo->salty_zoffset = 0;
|
||||
p->mo->salty_momz = 6*mos;
|
||||
if (cv_saltyhopsfx.value)
|
||||
if (cv_saltyhopsfx.value)
|
||||
S_StartSound(p->mo, sfx_s25a);
|
||||
}
|
||||
}
|
||||
@@ -3308,56 +3308,55 @@ static void K_QuiteSaltyHop(player_t *p)
|
||||
|
||||
void K_RollMobjBySlopes(mobj_t* mo, boolean usedistance)
|
||||
{
|
||||
I_Assert(mo->subsector != NULL);
|
||||
I_Assert(mo->subsector->sector != NULL);
|
||||
I_Assert(mo->subsector != NULL);
|
||||
I_Assert(mo->subsector->sector != NULL);
|
||||
|
||||
angle_t an;
|
||||
boolean flip = mo->eflags & MFE_VERTICALFLIP;
|
||||
fixed_t m_dist = R_PointToDist(mo->x, mo->y);
|
||||
fixed_t rolldist = cv_sloperolldist.value * mapobjectscale;
|
||||
angle_t an;
|
||||
const boolean flip = mo->eflags & MFE_VERTICALFLIP;
|
||||
const fixed_t m_dist = usedistance ? R_PointToDist(mo->x, mo->y) : 0;
|
||||
const fixed_t rolldist = cv_sloperolldist.value * mapobjectscale;
|
||||
|
||||
// lifted from hw_md2
|
||||
if (mo->standingslope)
|
||||
{
|
||||
fixed_t tempz = mo->standingslope->normal.z;
|
||||
fixed_t tempy = mo->standingslope->normal.y;
|
||||
fixed_t tempx = mo->standingslope->normal.x;
|
||||
fixed_t tempangle = -(R_PointToAngle2(
|
||||
0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
||||
// lifted from hw_md2
|
||||
if (mo->standingslope)
|
||||
{
|
||||
fixed_t tempz = mo->standingslope->normal.z;
|
||||
fixed_t tempy = mo->standingslope->normal.y;
|
||||
fixed_t tempx = mo->standingslope->normal.x;
|
||||
fixed_t tempangle = -(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
||||
|
||||
// admittedly this is a very hacky way to do the pitch and roll easing
|
||||
// admittedly this is a very hacky way to do the pitch and roll easing
|
||||
|
||||
// pitch
|
||||
if ((!usedistance) || (m_dist <= (rolldist)))
|
||||
{
|
||||
an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV;
|
||||
// pitch
|
||||
if ((!usedistance) || (m_dist <= (rolldist)))
|
||||
{
|
||||
an = (INT32)((angle_t)tempangle - mo->pitch_sprite) / SLOPEROLL_DIV;
|
||||
|
||||
mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle;
|
||||
}
|
||||
else
|
||||
mo->pitch_sprite = FixedAngle(0);
|
||||
mo->pitch_sprite = an ? mo->pitch_sprite + an : (angle_t)tempangle;
|
||||
}
|
||||
else
|
||||
mo->pitch_sprite = FixedAngle(0);
|
||||
|
||||
mo->slopepitch = flip ? InvAngle(mo->pitch_sprite) : mo->pitch_sprite;
|
||||
mo->slopepitch = flip ? InvAngle(mo->pitch_sprite) : mo->pitch_sprite;
|
||||
|
||||
// roll
|
||||
tempangle = (R_PointToAngle2(0, 0, tempz, tempy));
|
||||
// roll
|
||||
tempangle = (R_PointToAngle2(0, 0, tempz, tempy));
|
||||
|
||||
if ((!usedistance) || (m_dist <= (rolldist)))
|
||||
{
|
||||
an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV;
|
||||
if (!usedistance || (m_dist <= (rolldist)))
|
||||
{
|
||||
an = (INT32)((angle_t)tempangle - mo->roll_sprite) / SLOPEROLL_DIV;
|
||||
|
||||
mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle;
|
||||
}
|
||||
else
|
||||
mo->roll_sprite = FixedAngle(0);
|
||||
mo->roll_sprite = an ? mo->roll_sprite + an : (angle_t)tempangle;
|
||||
}
|
||||
else
|
||||
mo->roll_sprite = FixedAngle(0);
|
||||
|
||||
mo->sloperoll = flip ? InvAngle(mo->roll_sprite) : mo->roll_sprite;
|
||||
}
|
||||
else if (P_IsObjectOnGround(mo))
|
||||
{
|
||||
mo->sloperoll = FixedAngle(0);
|
||||
mo->slopepitch = FixedAngle(0);
|
||||
}
|
||||
mo->sloperoll = flip ? InvAngle(mo->roll_sprite) : mo->roll_sprite;
|
||||
}
|
||||
else if (P_IsObjectOnGround(mo))
|
||||
{
|
||||
mo->sloperoll = FixedAngle(0);
|
||||
mo->slopepitch = FixedAngle(0);
|
||||
}
|
||||
}
|
||||
|
||||
void K_SpawnBoostTrail(player_t *player)
|
||||
@@ -4460,7 +4459,6 @@ void K_RepairOrbitChain(mobj_t *orbit)
|
||||
if (orbit->target && orbit->target->player)
|
||||
{
|
||||
player_t *player = orbit->target->player;
|
||||
|
||||
INT32 num = 0;
|
||||
|
||||
mobj_t *cur = orbit->target->hnext;
|
||||
@@ -6504,14 +6502,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||
player->mo->spriteyscale = player->mo->realyscale;
|
||||
}
|
||||
|
||||
boolean usedist = false;
|
||||
|
||||
if (cv_sloperolldist.value > 0)
|
||||
usedist = true;
|
||||
if ((cv_spriteroll.value) && (cv_sloperoll.value))
|
||||
if (cv_spriteroll.value && cv_sloperoll.value)
|
||||
{
|
||||
if ((!player->mo->salty_jump)) // seeing a character rotate mid-hop looks really janky
|
||||
K_RollMobjBySlopes(player->mo, usedist);
|
||||
K_RollMobjBySlopes(player->mo, (cv_sloperolldist.value && !splitscreen));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7111,7 +7105,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX);
|
||||
kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX);
|
||||
kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX);
|
||||
|
||||
|
||||
if (xtra_speedo) // snowy speedometer
|
||||
{
|
||||
skp_smallsticker = W_CachePatchName("SP_SMSTC", PU_HUDGFX);
|
||||
@@ -7126,8 +7120,8 @@ void K_LoadKartHUDGraphics(void)
|
||||
{
|
||||
skp_smallsticker3 = W_CachePatchName("SP_SM3TC", PU_HUDGFX);
|
||||
}
|
||||
|
||||
if (achi_speedo)
|
||||
|
||||
if (achi_speedo)
|
||||
{
|
||||
skp_smallstickerachi = W_CachePatchName("SP_AMSTC", PU_HUDGFX);
|
||||
skp_speedpatchesachi[0] = W_CachePatchName("K_TRNULL", PU_HUDGFX); // lolxd
|
||||
@@ -7137,7 +7131,7 @@ void K_LoadKartHUDGraphics(void)
|
||||
skp_speedpatchesachi[4] = W_CachePatchName("SP_APERC", PU_HUDGFX);
|
||||
}
|
||||
|
||||
if (big_lap){
|
||||
if (big_lap){
|
||||
kp_lapstickerbig = W_CachePatchName("K_STLAPB", PU_HUDGFX);
|
||||
kp_lapstickerbig2 = W_CachePatchName("K_STLA2B", PU_HUDGFX);
|
||||
}
|
||||
@@ -7159,8 +7153,8 @@ void K_LoadKartHUDGraphics(void)
|
||||
kp_itembgclr[3] = W_CachePatchName("K_ISBCD", PU_HUDGFX);
|
||||
kp_itemmulstickerclr[1] = W_CachePatchName("K_ISMULC", PU_HUDGFX);
|
||||
kp_itemmulstickerclr[0] = W_CachePatchName("K_ITMULC", PU_HUDGFX);
|
||||
|
||||
if (big_lap_color){
|
||||
|
||||
if (big_lap_color){
|
||||
kp_lapstickerbigclr = W_CachePatchName("K_SCLAPB", PU_HUDGFX);
|
||||
kp_lapstickerbig2clr = W_CachePatchName("K_SCLA2B", PU_HUDGFX);
|
||||
}
|
||||
@@ -7170,8 +7164,8 @@ void K_LoadKartHUDGraphics(void)
|
||||
|
||||
if (xtra_speedo3 && xtra_speedo_clr3) // 80x11 patch scaled to size
|
||||
skp_smallstickerclr3 = W_CachePatchName("SC_SM3TC", PU_HUDGFX);
|
||||
|
||||
if (achi_speedo && achi_speedo_clr)
|
||||
|
||||
if (achi_speedo && achi_speedo_clr)
|
||||
{
|
||||
skp_smallstickerachiclr = W_CachePatchName("SC_AMSTC", PU_HUDGFX);
|
||||
skp_speedpatchesachiclr[0] = W_CachePatchName("K_TRNULL", PU_HUDGFX); // lolxd
|
||||
@@ -7202,13 +7196,13 @@ void K_LoadKartHUDGraphics(void)
|
||||
// Nametags
|
||||
if (nametaggfx)
|
||||
{
|
||||
|
||||
|
||||
nametagpic = W_CachePatchName("NTLINE", PU_HUDGFX);
|
||||
nametagline = W_CachePatchName("NTLINEV", PU_HUDGFX);
|
||||
nametagspeed = W_CachePatchName("NTSP", PU_HUDGFX);
|
||||
nametagweight = W_CachePatchName("NTWH", PU_HUDGFX);
|
||||
}
|
||||
|
||||
|
||||
if (driftgaugegfx){
|
||||
driftgauge = W_CachePatchName("K_DGAU", PU_HUDGFX);
|
||||
driftgaugecolor = W_CachePatchName("K_DCAU", PU_HUDGFX);
|
||||
@@ -7775,7 +7769,7 @@ static void K_drawKartStats(void)
|
||||
flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT;
|
||||
|
||||
UINT8 splitnum = 0;
|
||||
|
||||
|
||||
for (; splitnum < MAXSPLITSCREENPLAYERS; ++splitnum)
|
||||
{
|
||||
if (stplyr == &players[displayplayers[splitnum]])
|
||||
@@ -7784,7 +7778,7 @@ static void K_drawKartStats(void)
|
||||
|
||||
if (!LUA_HudEnabled(hud_statdisplay))
|
||||
return;
|
||||
|
||||
|
||||
//Internal offset for speedometer
|
||||
if (cv_kartspeedometer.value)
|
||||
{
|
||||
@@ -8348,7 +8342,7 @@ static void K_DrawKartPositionNum(INT32 num)
|
||||
scale *= 2;
|
||||
overtake = true; // this is used for splitscreen stuff in conjunction with flipdraw.
|
||||
}
|
||||
|
||||
|
||||
if (splitscreen || (cv_showinput.value && !splitscreen))
|
||||
scale /= 2;
|
||||
|
||||
@@ -8640,7 +8634,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||
p = &players[tab[i].num];
|
||||
if (cv_highresportrait.value)
|
||||
V_DrawSmallMappedPatch(x, y-4, 0, R_GetSkinFaceWant(p), colormap);
|
||||
else
|
||||
else
|
||||
V_DrawMappedPatch(x, y-4, 0, R_GetSkinFaceRank(p), colormap);
|
||||
}
|
||||
/*if (G_BattleGametype() && players[tab[i].num].kartstuff[k_bumper] > 0) -- not enough space for this
|
||||
@@ -8782,7 +8776,7 @@ static void K_drawKartSpeedometer(void)
|
||||
//KartZ speedo
|
||||
fixed_t fuspeed = 0;
|
||||
INT32 spdpatch = 0;
|
||||
|
||||
|
||||
INT32 speedtype = 0;
|
||||
INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT);
|
||||
|
||||
@@ -8810,7 +8804,7 @@ static void K_drawKartSpeedometer(void)
|
||||
}
|
||||
|
||||
// man.
|
||||
if ((cv_newspeedometer.value == 1) || (cv_newspeedometer.value == 2 && !xtra_speedo) || (cv_newspeedometer.value == 3 && !achi_speedo) || (cv_newspeedometer.value == 4 && !kartzspeedo) || (cv_newspeedometer.value == 5 && !xtra_speedo3))
|
||||
if ((cv_newspeedometer.value == 1) || (cv_newspeedometer.value == 2 && !xtra_speedo) || (cv_newspeedometer.value == 3 && !achi_speedo) || (cv_newspeedometer.value == 4 && !kartzspeedo) || (cv_newspeedometer.value == 5 && !xtra_speedo3))
|
||||
{
|
||||
switch (speedtype) {
|
||||
case 1:
|
||||
@@ -8859,8 +8853,8 @@ static void K_drawKartSpeedometer(void)
|
||||
V_DrawScaledPatch(SPDM_X + 1, SPDM_Y + 4, (V_HUDTRANS|splitflags), (skp_smallstickerachi));
|
||||
V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL);
|
||||
V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatchesachi[cv_kartspeedometer.value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cv_newspeedometer.value == 5 && xtra_speedo3) // why bother if we dont?
|
||||
{
|
||||
if (K_UseColorHud() && xtra_speedo_clr3) //Colourized hud
|
||||
@@ -8874,19 +8868,19 @@ static void K_drawKartSpeedometer(void)
|
||||
V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL);
|
||||
V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatches[cv_kartspeedometer.value]);
|
||||
}
|
||||
|
||||
|
||||
// Kart Z speedo bullshit...
|
||||
// Draw the Speed counter.
|
||||
else if (cv_newspeedometer.value == 4 && kartzspeedo)
|
||||
{
|
||||
fuspeed = FixedDiv(stplyr->speed, mapobjectscale)/FRACUNIT;
|
||||
|
||||
|
||||
#define NUM_INTERVALS 22
|
||||
const int speedIntervals[NUM_INTERVALS] = {2, 5, 7, 10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35, 37, 40, 42, 45, 47, 50, 52, 55};
|
||||
|
||||
for (int i = 0; i < NUM_INTERVALS; ++i)
|
||||
for (int i = 0; i < NUM_INTERVALS; ++i)
|
||||
{
|
||||
if (fuspeed < speedIntervals[i])
|
||||
if (fuspeed < speedIntervals[i])
|
||||
{
|
||||
spdpatch = i;
|
||||
break;
|
||||
@@ -9076,9 +9070,9 @@ static boolean K_GetScreenCoords(vector2_t *vec, player_t *player, mobj_t *targe
|
||||
// project the angle to get our final X coordinate
|
||||
x = FixedMul(FINETANGENT(((x+ANGLE_90)>>ANGLETOFINESHIFT) & 4095), fov);
|
||||
if (splitscreen == 1) // divide by 320/200 (1.6) on 2P splitscreen
|
||||
x = (x/2) + (x/8);
|
||||
x = (x/2) + (x/8);
|
||||
x = x + xres;
|
||||
|
||||
|
||||
// now clip in screen-space
|
||||
if (!dontclip && (x < 0 || x > xres*2 || y < 0 || y > yres*2))
|
||||
return false;
|
||||
@@ -9141,7 +9135,7 @@ static void K_drawNameTags(void)
|
||||
fixed_t maxdistance = (10*cv_nametagdist.value)* mapobjectscale;
|
||||
flipped = 0;
|
||||
fixed_t z;
|
||||
|
||||
|
||||
if (i > PLAYERSMASK)
|
||||
continue;
|
||||
if (!players[i].mo || P_MobjWasRemoved(players[i].mo) || players[i].spectator || !playeringame[i])
|
||||
@@ -9180,7 +9174,7 @@ static void K_drawNameTags(void)
|
||||
trans = V_40TRANS;
|
||||
else if (distance > (maxdistance*3/5))
|
||||
trans = V_20TRANS;
|
||||
else
|
||||
else
|
||||
trans = 0;
|
||||
break;
|
||||
case 3:
|
||||
@@ -9380,7 +9374,7 @@ skipcrap:
|
||||
if (!K_GetScreenCoords(&pos, stplyr, stplyr->mo, FixedMul(cv_driftgaugeofs.value, cv_driftgaugeofs.value > 0 ? stplyr->mo->scale : mapobjectscale), false))
|
||||
return;
|
||||
|
||||
basex = pos.x>>FRACBITS;
|
||||
basex = pos.x>>FRACBITS;
|
||||
basey = pos.y>>FRACBITS;
|
||||
|
||||
fixed_t barx;
|
||||
@@ -9654,12 +9648,12 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags)
|
||||
colormap = R_GetTranslationColormap(TC_RAINBOW, mo->color, GTC_CACHE);
|
||||
else
|
||||
colormap = R_GetLocalTranslationColormap(mo->skin, mo->localskin, mo->color, GTC_CACHE, skinlocal);
|
||||
|
||||
|
||||
if (cv_minihead.value)
|
||||
V_DrawFixedPatch(amxpos + (2*FRACUNIT), amypos + (2*FRACUNIT), FRACUNIT/2, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap);
|
||||
else
|
||||
V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, ((skinlocal) ? localfacemmapprefix : facemmapprefix)[skin], colormap);
|
||||
|
||||
|
||||
if (cv_showminimapnames.value && !(modeattacking || gamestate == GS_TIMEATTACK))
|
||||
{
|
||||
const char *player_name = va("%c%s", V_GetSkincolorChar(mo->color), player_names[mo->player - players]);
|
||||
@@ -10505,7 +10499,7 @@ void K_drawKartHUD(void)
|
||||
|
||||
// Draw the item window
|
||||
if (LUA_HudEnabled(hud_item) && !freecam)
|
||||
K_drawKartItem();
|
||||
K_drawKartItem();
|
||||
|
||||
if (cv_driftgauge.value && !modeattacking)
|
||||
{
|
||||
|
||||
+3
-1
@@ -111,6 +111,8 @@ static void A_Lua(mobj_t *actor)
|
||||
lua_pushinteger(gL, var2);
|
||||
LUA_Call(gL, 3, 0, 1);
|
||||
|
||||
lua_pop(gL, 1); // pop error handler
|
||||
|
||||
if (found)
|
||||
{
|
||||
--superstack;
|
||||
@@ -940,7 +942,7 @@ static int lib_setSfxInfo(lua_State *L)
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
{
|
||||
int j = lua_tointeger(L, 2) - 1;
|
||||
int j = lua_tointeger(L, 2);
|
||||
|
||||
// Read and Write enums were combined, need to do this switch now
|
||||
switch (j)
|
||||
|
||||
+1
-1
@@ -281,7 +281,7 @@ static int lib_iterateSectorThinglist(lua_State *L)
|
||||
if (!lua_isnil(L, 1))
|
||||
{
|
||||
thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
if (P_MobjWasRemoved(thing))
|
||||
if (!thing)
|
||||
return luaL_error(L, "current entry in thinglist was removed; avoid calling P_RemoveMobj on entries!");
|
||||
thing = thing->snext;
|
||||
}
|
||||
|
||||
@@ -37,8 +37,9 @@
|
||||
/*
|
||||
* Sacrifice very little compression quality in favour of compression speed.
|
||||
* This gives almost the same compression as the default code, and is
|
||||
* (very roughly) 15% faster. This is the preferred mode of operation.
|
||||
* (very roughly) 15% faster. This is the preferable mode of operation.
|
||||
*/
|
||||
|
||||
#ifndef VERY_FAST
|
||||
# define VERY_FAST 1
|
||||
#endif
|
||||
@@ -47,7 +48,7 @@
|
||||
* Sacrifice some more compression quality in favour of compression speed.
|
||||
* (roughly 1-2% worse compression for large blocks and
|
||||
* 9-10% for small, redundant, blocks and >>20% better speed in both cases)
|
||||
* In short: when in need for speed, enable this for binary data,
|
||||
* In INT16: when in need for speed, enable this for binary data,
|
||||
* possibly disable this for text data.
|
||||
*/
|
||||
#ifndef ULTRA_FAST
|
||||
@@ -65,10 +66,21 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use string functions to copy memory.
|
||||
* this is usually a loss, even with glibc's optimized memcpy
|
||||
*/
|
||||
#ifndef USE_MEMCPY
|
||||
#ifdef _MSC_VER
|
||||
# define USE_MEMCPY 0
|
||||
#else
|
||||
# define USE_MEMCPY 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* You may choose to pre-set the hash table (might be faster on some
|
||||
* modern cpus and large (>>64k) blocks, and also makes compression
|
||||
* deterministic/repeatable when the configuration otherwise is the same).
|
||||
* modern cpus and large (>>64k) blocks)
|
||||
*/
|
||||
#ifndef INIT_HTAB
|
||||
# define INIT_HTAB 1
|
||||
@@ -76,15 +88,15 @@
|
||||
|
||||
/*
|
||||
* Avoid assigning values to errno variable? for some embedding purposes
|
||||
* (linux kernel for example), this is necessary. NOTE: this breaks
|
||||
* the documentation in lzf.h. Avoiding errno has no speed impact.
|
||||
* (linux kernel for example), this is neccessary. NOTE: this breaks
|
||||
* the documentation in lzf.h.
|
||||
*/
|
||||
#ifndef AVOID_ERRNO
|
||||
# define AVOID_ERRNO 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whether to pass the LZF_STATE variable as argument, or allocate it
|
||||
* Wether to pass the LZF_STATE variable as argument, or allocate it
|
||||
* on the stack. For small-stack environments, define this to 1.
|
||||
* NOTE: this breaks the prototype in lzf.h.
|
||||
*/
|
||||
@@ -93,108 +105,50 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whether to add extra checks for input validity in lzf_decompress
|
||||
* Wether to add extra checks for input validity in lzf_decompress
|
||||
* and return EINVAL if the input stream has been corrupted. This
|
||||
* only shields against overflowing the input buffer and will not
|
||||
* detect most corrupted streams.
|
||||
* This check is not normally noticeable on modern hardware
|
||||
* This check is not normally noticable on modern hardware
|
||||
* (<1% slowdown), but might slow down older cpus considerably.
|
||||
*/
|
||||
#ifndef CHECK_INPUT
|
||||
# define CHECK_INPUT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whether the target CPU has a slow multiplication. This affects
|
||||
* the default hash function for the compressor, and enables a slightly
|
||||
* worse hash function that needs only shifts.
|
||||
*/
|
||||
#ifndef MULTIPLICATION_IS_SLOW
|
||||
# define MULTIPLICATION_IS_SLOW 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If defined, then this data type will be used for storing offsets.
|
||||
* This can be useful if you want to use a huge hashtable, want to
|
||||
* conserve memory, or both, and your data fits into e.g. 64kb.
|
||||
* If instead you want to compress data > 4GB, then it's better to
|
||||
* to "#define LZF_USE_OFFSETS 0" instead.
|
||||
*/
|
||||
/*#define LZF_HSLOT unsigned short*/
|
||||
|
||||
/*
|
||||
* Whether to store pointers or offsets inside the hash table. On
|
||||
* 64 bit architetcures, pointers take up twice as much space,
|
||||
* and might also be slower. Default is to autodetect.
|
||||
*/
|
||||
/*#define LZF_USE_OFFSETS autodetect */
|
||||
|
||||
/*
|
||||
* Whether to optimise code for size, at the expense of speed. Use
|
||||
* this when you are extremely tight on memory, perhaps in combination
|
||||
* with AVOID_ERRNO 1 and CHECK_INPUT 0.
|
||||
*/
|
||||
#ifndef OPTIMISE_SIZE
|
||||
# ifdef __OPTIMIZE_SIZE__
|
||||
# define OPTIMISE_SIZE 1
|
||||
# else
|
||||
# define OPTIMISE_SIZE 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* nothing should be changed below */
|
||||
|
||||
# include <string.h>
|
||||
# include <limits.h>
|
||||
|
||||
#if ULTRA_FAST
|
||||
# undef VERY_FAST
|
||||
#endif
|
||||
|
||||
#ifndef LZF_USE_OFFSETS
|
||||
# ifdef _WIN32
|
||||
# define LZF_USE_OFFSETS defined(_M_X64)
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef unsigned char u8;
|
||||
|
||||
#ifdef LZF_HSLOT
|
||||
# define LZF_HSLOT_BIAS ((const u8 *)in_data)
|
||||
#else
|
||||
# ifdef LZF_USE_OFFSETS
|
||||
# define LZF_HSLOT_BIAS ((const u8 *)in_data)
|
||||
typedef unsigned int LZF_HSLOT;
|
||||
typedef const u8 *LZF_STATE[1 << (HLOG)];
|
||||
|
||||
#if !STRICT_ALIGN
|
||||
/* for unaligned accesses we need a 16 bit datatype. */
|
||||
# include <limits.h>
|
||||
# if USHRT_MAX == 65535
|
||||
typedef unsigned short u16;
|
||||
# elif UINT_MAX == 65535
|
||||
typedef unsigned int u16;
|
||||
# else
|
||||
# define LZF_HSLOT_BIAS 0
|
||||
typedef const u8 *LZF_HSLOT;
|
||||
# undef STRICT_ALIGN
|
||||
# define STRICT_ALIGN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX == 65535
|
||||
typedef unsigned short u16;
|
||||
#elif UINT_MAX == 65535
|
||||
typedef unsigned int u16;
|
||||
#else
|
||||
# undef STRICT_ALIGN
|
||||
# define STRICT_ALIGN 1
|
||||
#if ULTRA_FAST
|
||||
# if defined(VERY_FAST)
|
||||
# undef VERY_FAST
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define LZF_MAX_LIT (1 << 5)
|
||||
#define LZF_MAX_OFF (1 << 13)
|
||||
#define LZF_MAX_REF ((1 << 8) + (1 << 3))
|
||||
|
||||
typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const u8 *first [1 << (6+8)]; /* most recent occurance of a match */
|
||||
u16 prev [LZF_MAX_OFF]; /* how many bytes to go backwards for the next match */
|
||||
} LZF_STATE_BEST[1];
|
||||
#if USE_MEMCPY || INIT_HTAB
|
||||
# ifdef __cplusplus
|
||||
# include <cstring>
|
||||
# else
|
||||
# include <string.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -210,31 +164,14 @@ typedef struct
|
||||
# define SET_ERRNO(n) errno = (n)
|
||||
#endif
|
||||
|
||||
#ifndef USE_REP_MOVSB
|
||||
#if (defined (__i386) || defined (__amd64)) && __GNUC__ >= 3
|
||||
#define USE_REP_MOVSB 1
|
||||
#else
|
||||
#define USE_REP_MOVSB 0 // Default to 0 if not defined elsewhere
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_REP_MOVSB /* small win on amd, big loss on intel */
|
||||
#if (defined (__i386) || defined (__amd64)) && __GNUC__ >= 3
|
||||
# define lzf_movsb(dst, src, len) \
|
||||
asm ("rep movsb" \
|
||||
: "=D" (dst), "=S" (src), "=c" (len) \
|
||||
: "0" (dst), "1" (src), "2" (len));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
size_t
|
||||
lzf_decompress (const void *const in_data, size_t in_len,
|
||||
void *out_data, size_t out_len)
|
||||
void *out_data, size_t out_len)
|
||||
{
|
||||
u8 const *ip = (const u8 *)in_data;
|
||||
u8 *op = (u8 *)out_data;
|
||||
u8 *op = (u8 *)out_data;
|
||||
u8 const *const in_end = ip + in_len;
|
||||
u8 *const out_end = op + out_len;
|
||||
u8 *const out_end = op + out_len;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -258,23 +195,14 @@ lzf_decompress (const void *const in_data, size_t in_len,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef lzf_movsb
|
||||
lzf_movsb (op, ip, ctrl);
|
||||
#elif OPTIMISE_SIZE
|
||||
while (ctrl--)
|
||||
*op++ = *ip++;
|
||||
#if USE_MEMCPY
|
||||
M_Memcpy (op, ip, ctrl);
|
||||
op += ctrl;
|
||||
ip += ctrl;
|
||||
#else
|
||||
switch (ctrl)
|
||||
{
|
||||
case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++;
|
||||
case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++;
|
||||
case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++;
|
||||
case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++;
|
||||
case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++;
|
||||
case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case 9: *op++ = *ip++;
|
||||
case 8: *op++ = *ip++; case 7: *op++ = *ip++; case 6: *op++ = *ip++; case 5: *op++ = *ip++;
|
||||
case 4: *op++ = *ip++; case 3: *op++ = *ip++; case 2: *op++ = *ip++; case 1: *op++ = *ip++;
|
||||
}
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--ctrl);
|
||||
#endif
|
||||
}
|
||||
else /* back reference */
|
||||
@@ -316,49 +244,12 @@ lzf_decompress (const void *const in_data, size_t in_len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef lzf_movsb
|
||||
len += 2;
|
||||
lzf_movsb (op, ref, len);
|
||||
#elif OPTIMISE_SIZE
|
||||
len += 2;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
|
||||
do
|
||||
*op++ = *ref++;
|
||||
while (--len);
|
||||
#else
|
||||
switch (len)
|
||||
{
|
||||
default:
|
||||
len += 2;
|
||||
|
||||
if (op >= ref + len)
|
||||
{
|
||||
/* disjunct areas */
|
||||
memcpy (op, ref, len);
|
||||
op += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* overlapping, use octet by octet copying */
|
||||
do
|
||||
*op++ = *ref++;
|
||||
while (--len);
|
||||
}
|
||||
break;
|
||||
|
||||
case 9: *op++ = *ref++;
|
||||
case 8: *op++ = *ref++;
|
||||
case 7: *op++ = *ref++;
|
||||
case 6: *op++ = *ref++;
|
||||
case 5: *op++ = *ref++;
|
||||
case 4: *op++ = *ref++;
|
||||
case 3: *op++ = *ref++;
|
||||
case 2: *op++ = *ref++;
|
||||
case 1: *op++ = *ref++;
|
||||
case 0: *op++ = *ref++; /* two octets more */
|
||||
*op++ = *ref++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
while (ip < in_end);
|
||||
@@ -375,29 +266,23 @@ lzf_decompress (const void *const in_data, size_t in_len,
|
||||
|
||||
/*
|
||||
* don't play with this unless you benchmark!
|
||||
* the data format is not dependent on the hash function.
|
||||
* the hash function might seem strange, just believe me,
|
||||
* decompression is not dependent on the hash function
|
||||
* the hashing function might seem strange, just believe me
|
||||
* it works ;)
|
||||
*/
|
||||
#ifndef FRST
|
||||
# define FRST(p) (((p[0]) << 8) | p[1])
|
||||
# define NEXT(v,p) (((v) << 8) | p[2])
|
||||
# if MULTIPLICATION_IS_SLOW
|
||||
# if ULTRA_FAST
|
||||
# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
|
||||
# elif VERY_FAST
|
||||
# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
# else
|
||||
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
# endif
|
||||
# else
|
||||
/* this one was developed with sesse,
|
||||
* and is very similar to the one in snappy.
|
||||
* it does need a modern enough cpu with a fast multiplication.
|
||||
*/
|
||||
# define IDX(h) (((h * 0x1e35a7bdU) >> (32 - HLOG - 8)) & (HSIZE - 1))
|
||||
# endif
|
||||
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
#endif
|
||||
/*
|
||||
* IDX works because it is very similar to a multiplicative hash, e.g.
|
||||
* ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
|
||||
* the latter is also quite fast on newer CPUs, and sligthly better
|
||||
*
|
||||
* the next one is also quite good, albeit slow ;)
|
||||
* (int)(cos(h & 0xffffff) * 1e6)
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* original lzv-like hash function, much worse and thus slower */
|
||||
@@ -406,214 +291,177 @@ lzf_decompress (const void *const in_data, size_t in_len,
|
||||
# define IDX(h) ((h) & (HSIZE - 1))
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
# define expect(expr,value) __builtin_expect ((expr),(value))
|
||||
# define inline inline
|
||||
#else
|
||||
# define expect(expr,value) (expr)
|
||||
# define inline static
|
||||
#endif
|
||||
|
||||
#define expect_false(expr) expect ((expr) != 0, 0)
|
||||
#define expect_true(expr) expect ((expr) != 0, 1)
|
||||
#define MAX_LIT (1 << 5)
|
||||
#define MAX_OFF (1 << 13)
|
||||
#define MAX_REF ((1 << 8) + (1 << 3))
|
||||
|
||||
/*
|
||||
* compressed format
|
||||
*
|
||||
* 000LLLLL <L+1> ; literal, L+1=1..33 octets
|
||||
* LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
|
||||
* 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
|
||||
* 000LLLLL <L+1> ; literal
|
||||
* LLLooooo oooooooo ; backref L
|
||||
* 111ooooo LLLLLLLL oooooooo ; backref L+7
|
||||
*
|
||||
*/
|
||||
|
||||
size_t
|
||||
lzf_compress (const void *const in_data, size_t in_len,
|
||||
void *out_data, size_t out_len
|
||||
lzf_compress (const void *const in_data,size_t in_len,
|
||||
void *out_data, size_t out_len
|
||||
#if LZF_STATE_ARG
|
||||
, LZF_STATE htab
|
||||
, LZF_STATE *htab
|
||||
#endif
|
||||
)
|
||||
)
|
||||
{
|
||||
#if !LZF_STATE_ARG
|
||||
LZF_STATE htab;
|
||||
#endif
|
||||
const u8 **hslot;
|
||||
const u8 *ip = (const u8 *)in_data;
|
||||
u8 *op = (u8 *)out_data;
|
||||
u8 *op = (u8 *)out_data;
|
||||
const u8 *in_end = ip + in_len;
|
||||
u8 *out_end = op + out_len;
|
||||
const u8 *ref;
|
||||
|
||||
/*
|
||||
* off requires a type wide enough to hold a general pointer difference.
|
||||
* ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
|
||||
* works for differences within a single object). We also assume that
|
||||
* no bit pattern traps. Since the only platform that is both non-POSIX
|
||||
* and fails to support both assumptions is windows 64 bit, we make a
|
||||
* special workaround for it.
|
||||
*/
|
||||
u8 *out_end = op + out_len;
|
||||
const u8 *ref = NULL;
|
||||
|
||||
unsigned int hval = FRST (ip);
|
||||
size_t off;
|
||||
unsigned int hval;
|
||||
int lit;
|
||||
|
||||
if (!in_len || !out_len)
|
||||
return 0;
|
||||
int lit = 0;
|
||||
|
||||
#if INIT_HTAB
|
||||
# if USE_MEMCPY
|
||||
memset (htab, 0, sizeof (htab));
|
||||
# else
|
||||
for (hslot = htab; hslot < htab + HSIZE; hslot++)
|
||||
*hslot++ = ip;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
lit = 0; op++; /* start run */
|
||||
|
||||
hval = FRST (ip);
|
||||
while (ip < in_end - 2)
|
||||
for (;;)
|
||||
{
|
||||
LZF_HSLOT *hslot;
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
hslot = htab + IDX (hval);
|
||||
ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS;
|
||||
|
||||
if (1
|
||||
#if INIT_HTAB
|
||||
&& ref < ip /* the next test will actually take care of this, but this is faster */
|
||||
#endif
|
||||
&& (off = ip - ref - 1) < LZF_MAX_OFF
|
||||
&& ref > (const u8 *)in_data
|
||||
&& ref[2] == ip[2]
|
||||
#if STRICT_ALIGN
|
||||
&& ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
|
||||
#else
|
||||
&& *(const u16 *)ref == *(const u16 *)ip
|
||||
#endif
|
||||
)
|
||||
if (ip < in_end - 2)
|
||||
{
|
||||
/* match found at *ref++ */
|
||||
unsigned int len = 2;
|
||||
size_t maxlen = in_end - ip - len;
|
||||
maxlen = maxlen > LZF_MAX_REF ? LZF_MAX_REF : maxlen;
|
||||
hval = NEXT (hval, ip);
|
||||
hslot = htab + IDX (hval);
|
||||
ref = *hslot; *hslot = ip;
|
||||
|
||||
if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */
|
||||
if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */
|
||||
return 0;
|
||||
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
op -= !lit; /* undo run if length is zero */
|
||||
|
||||
for (;;)
|
||||
if (
|
||||
#if INIT_HTAB && !USE_MEMCPY
|
||||
ref < ip /* the next test will actually take care of this, but this is faster */
|
||||
&&
|
||||
#endif
|
||||
(off = ip - ref - 1) < MAX_OFF
|
||||
&& ip + 4 < in_end
|
||||
&& ref > (const u8 *)in_data
|
||||
#if STRICT_ALIGN
|
||||
&& ref[0] == ip[0]
|
||||
&& ref[1] == ip[1]
|
||||
&& ref[2] == ip[2]
|
||||
#else
|
||||
&& *(const u16 *)ref == *(const u16 *)ip
|
||||
&& ref[2] == ip[2]
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (expect_true (maxlen > 16))
|
||||
{
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
/* match found at *ref++ */
|
||||
unsigned int len = 2;
|
||||
size_t maxlen = in_end - ip - len;
|
||||
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
|
||||
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
}
|
||||
if (op + lit + 1 + 3 >= out_end)
|
||||
return 0;
|
||||
|
||||
do
|
||||
len++;
|
||||
while (len < maxlen && ref[len] == ip[len]);
|
||||
|
||||
break;
|
||||
}
|
||||
if (lit)
|
||||
{
|
||||
*op++ = (u8)(lit - 1);
|
||||
lit = -lit;
|
||||
do
|
||||
*op++ = ip[lit];
|
||||
while (++lit);
|
||||
}
|
||||
|
||||
len -= 2; /* len is now #octets - 1 */
|
||||
ip++;
|
||||
len -= 2;
|
||||
ip++;
|
||||
|
||||
if (len < 7)
|
||||
{
|
||||
*op++ = (off >> 8) + (len << 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (off >> 8) + ( 7 << 5);
|
||||
*op++ = len - 7;
|
||||
}
|
||||
if (len < 7)
|
||||
{
|
||||
*op++ = (u8)((off >> 8) + (len << 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (u8)((off >> 8) + ( 7 << 5));
|
||||
*op++ = (u8)(len - 7);
|
||||
}
|
||||
|
||||
*op++ = off;
|
||||
|
||||
lit = 0; op++; /* start run */
|
||||
|
||||
ip += len + 1;
|
||||
|
||||
if (expect_false (ip >= in_end - 2))
|
||||
break;
|
||||
*op++ = (u8)off;
|
||||
|
||||
#if ULTRA_FAST || VERY_FAST
|
||||
--ip;
|
||||
# if VERY_FAST && !ULTRA_FAST
|
||||
--ip;
|
||||
# endif
|
||||
hval = FRST (ip);
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
|
||||
# if VERY_FAST && !ULTRA_FAST
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
# endif
|
||||
#else
|
||||
ip -= len + 1;
|
||||
|
||||
do
|
||||
{
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
}
|
||||
while (len--);
|
||||
ip += len;
|
||||
#if VERY_FAST && !ULTRA_FAST
|
||||
--ip;
|
||||
#endif
|
||||
hval = FRST (ip);
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip;
|
||||
ip++;
|
||||
|
||||
#if VERY_FAST && !ULTRA_FAST
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip;
|
||||
ip++;
|
||||
#endif
|
||||
#else
|
||||
do
|
||||
{
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip;
|
||||
ip++;
|
||||
}
|
||||
while (len--);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (ip == in_end)
|
||||
break;
|
||||
|
||||
/* one more literal byte we must copy */
|
||||
lit++;
|
||||
ip++;
|
||||
|
||||
if (lit == MAX_LIT)
|
||||
{
|
||||
/* one more literal byte we must copy */
|
||||
if (expect_false (op >= out_end))
|
||||
if (op + 1 + MAX_LIT >= out_end)
|
||||
return 0;
|
||||
|
||||
lit++; *op++ = *ip++;
|
||||
|
||||
if (expect_false (lit == LZF_MAX_LIT))
|
||||
{
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
lit = 0; op++; /* start run */
|
||||
}
|
||||
*op++ = MAX_LIT - 1;
|
||||
#if USE_MEMCPY
|
||||
M_Memcpy (op, ip - MAX_LIT, MAX_LIT);
|
||||
op += MAX_LIT;
|
||||
lit = 0;
|
||||
#else
|
||||
lit = -lit;
|
||||
do
|
||||
*op++ = ip[lit];
|
||||
while (++lit);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (op + 3 > out_end) /* at most 3 bytes can be missing here */
|
||||
return 0;
|
||||
|
||||
while (ip < in_end)
|
||||
if (lit)
|
||||
{
|
||||
lit++; *op++ = *ip++;
|
||||
if (op + lit + 1 >= out_end)
|
||||
return 0;
|
||||
|
||||
if (expect_false (lit == LZF_MAX_LIT))
|
||||
{
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
lit = 0; op++; /* start run */
|
||||
}
|
||||
*op++ = (u8)(lit - 1);
|
||||
lit = -lit;
|
||||
do
|
||||
*op++ = ip[lit];
|
||||
while (++lit);
|
||||
}
|
||||
|
||||
op [- lit - 1] = lit - 1; /* end run */
|
||||
op -= !lit; /* undo run if length is zero */
|
||||
|
||||
return op - (u8 *)out_data;
|
||||
return op - (u8 *) out_data;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
// Copyright (C) 2000-2005 by Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
@@ -22,7 +22,7 @@
|
||||
**
|
||||
***********************************************************************/
|
||||
|
||||
#define LZF_VERSION 0x0106 /* 1.6 */
|
||||
#define LZF_VERSION 0x0105 /* 1.5 */
|
||||
|
||||
/*
|
||||
* Compress in_len bytes stored at the memory block starting at
|
||||
|
||||
@@ -1498,8 +1498,6 @@ static menuitem_t OP_ExpOptionsMenu[] =
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_grframebuffer, 110},
|
||||
#endif
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_grpalettedepth, 130},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Splitwall/Slope texture fix", &cv_splitwallfix, 150},
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1517,7 +1515,6 @@ static const char* OP_ExpTooltips[] =
|
||||
"Allows the game to downsample from a higher resolution than your display\nin OpenGL renderer mode. Requires a GPU with atleast OpenGL 3.0 support.",
|
||||
#endif
|
||||
"Change the depth of the Palette in Palette rendering mode\n 16 bits is like software looks ingame\nwhile 24 bits is how software looks in screenshots.",
|
||||
"Fixes issues that resulted in Textures sticking from the ground sometimes.\n This may be CPU heavy and result in worse performance in some cases.",
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1535,7 +1532,6 @@ enum
|
||||
op_exp_fbo,
|
||||
#endif
|
||||
op_exp_paldepth,
|
||||
op_exp_spltwal,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -4724,7 +4720,6 @@ void M_Init(void)
|
||||
#ifdef USE_FBO_OGL
|
||||
OP_ExpOptionsMenu[op_exp_fbo].status = IT_DISABLED;
|
||||
#endif
|
||||
OP_ExpOptionsMenu[op_exp_spltwal].status = IT_DISABLED;
|
||||
}
|
||||
|
||||
if (rendermode == render_opengl)
|
||||
|
||||
+2
-5
@@ -2400,8 +2400,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage);
|
||||
if (P_MobjWasRemoved(target))
|
||||
return (shouldForce == 1); // mobj was removed
|
||||
if (P_MobjWasRemoved(source))
|
||||
source = NULL;
|
||||
if (shouldForce == 1)
|
||||
force = true;
|
||||
else if (shouldForce == 2)
|
||||
@@ -2638,6 +2636,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
P_ResetPlayer(target->player);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (target->type)
|
||||
{
|
||||
case MT_EGGMOBILE2: // egg slimer
|
||||
@@ -2651,9 +2650,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
||||
P_SetMobjState(target, target->info->painstate);
|
||||
break;
|
||||
}
|
||||
|
||||
if (P_MobjWasRemoved(target))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!P_MobjWasRemoved(target))
|
||||
{
|
||||
|
||||
+105
-84
@@ -408,7 +408,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
||||
P_RadiusAttack(mo, mo, 96*FRACUNIT);
|
||||
|
||||
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
|
||||
if (!P_MobjWasRemoved(explodemo))
|
||||
if (explodemo)
|
||||
{
|
||||
P_SetScale(explodemo, mo->scale);
|
||||
explodemo->destscale = mo->destscale;
|
||||
@@ -417,7 +417,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
||||
S_StartSound(explodemo, sfx_pop);
|
||||
}
|
||||
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
|
||||
if (!P_MobjWasRemoved(explodemo))
|
||||
if (explodemo)
|
||||
{
|
||||
P_SetScale(explodemo, mo->scale);
|
||||
explodemo->destscale = mo->destscale;
|
||||
@@ -426,7 +426,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
||||
S_StartSound(explodemo, sfx_dmpain);
|
||||
}
|
||||
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
|
||||
if (!P_MobjWasRemoved(explodemo))
|
||||
if (explodemo)
|
||||
{
|
||||
P_SetScale(explodemo, mo->scale);
|
||||
explodemo->destscale = mo->destscale;
|
||||
@@ -435,7 +435,7 @@ void P_ExplodeMissile(mobj_t *mo)
|
||||
S_StartSound(explodemo, sfx_pop);
|
||||
}
|
||||
explodemo = P_SpawnMobj(mo->x, mo->y, mo->z, MT_EXPLODE);
|
||||
if (!P_MobjWasRemoved(explodemo))
|
||||
if (explodemo)
|
||||
{
|
||||
P_SetScale(explodemo, mo->scale);
|
||||
explodemo->destscale = mo->destscale;
|
||||
@@ -3249,7 +3249,7 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
||||
{
|
||||
boolean itsatwodlevel = false;
|
||||
boolean flipcam = (player->pflags & PF_FLIPCAM && !(player->pflags & PF_NIGHTSMODE) && player->mo->eflags & MFE_VERTICALFLIP);
|
||||
postimg_t postimg = postimg_none;
|
||||
UINT16 postimgflags = 0;
|
||||
UINT8 i;
|
||||
|
||||
// This can happen when joining
|
||||
@@ -3271,64 +3271,67 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
||||
}
|
||||
}
|
||||
|
||||
if (encoremode && !flipcam)
|
||||
postimg = postimg_mirror;
|
||||
else if (!encoremode && flipcam)
|
||||
postimg = postimg_flip;
|
||||
else if (encoremode && flipcam)
|
||||
postimg = postimg_mirrorflip;
|
||||
else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||
if (encoremode)
|
||||
postimgflags |= POSTIMG_MIRROR;
|
||||
if (flipcam)
|
||||
postimgflags |= POSTIMG_FLIP;
|
||||
|
||||
if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||
{
|
||||
camera_t dummycam;
|
||||
|
||||
dummycam.subsector = player->awayviewmobj->subsector;
|
||||
dummycam.x = player->awayviewmobj->x;
|
||||
dummycam.y = player->awayviewmobj->y;
|
||||
dummycam.z = player->awayviewmobj->z;
|
||||
//dummycam.height = 40*FRACUNIT; // alt view height is 20*FRACUNIT
|
||||
dummycam.height = 0; // Why? Remote viewpoint cameras have no height.
|
||||
|
||||
// Are we in water?
|
||||
if (P_CameraCheckWater(&dummycam))
|
||||
postimg = postimg_water;
|
||||
else if (P_CameraCheckHeat(&dummycam))
|
||||
postimg = postimg_heat;
|
||||
postimgflags |= POSTIMG_WATER;
|
||||
if (P_CameraCheckHeat(&dummycam))
|
||||
postimgflags |= POSTIMG_HEAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Are we in water?
|
||||
if (P_CameraCheckWater(thiscam))
|
||||
postimg = postimg_water;
|
||||
else if (P_CameraCheckHeat(thiscam))
|
||||
postimg = postimg_heat;
|
||||
postimgflags |= POSTIMG_WATER;
|
||||
if (P_CameraCheckHeat(thiscam))
|
||||
postimgflags |= POSTIMG_HEAT;
|
||||
}
|
||||
|
||||
if (postimg != postimg_none)
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
postimgtype[i] = postimg;
|
||||
}
|
||||
players[displayplayers[i]].postimgflags = postimgflags;
|
||||
break;
|
||||
}
|
||||
|
||||
if (thiscam->momx || thiscam->momy)
|
||||
{
|
||||
if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam))
|
||||
{ // Never fails for 2D mode.
|
||||
if (!P_TryCameraMove(thiscam->x + thiscam->momx, thiscam->y + thiscam->momy, thiscam)) // Never fails for 2D mode.
|
||||
{
|
||||
mobj_t dummy;
|
||||
|
||||
dummy.thinker.function.acp1 = (actionf_p1)P_MobjThinker;
|
||||
dummy.subsector = thiscam->subsector;
|
||||
dummy.x = thiscam->x;
|
||||
dummy.y = thiscam->y;
|
||||
dummy.z = thiscam->z;
|
||||
dummy.height = thiscam->height;
|
||||
|
||||
if (player->pflags & PF_TIMEOVER)
|
||||
player->kartstuff[k_timeovercam] = (2*TICRATE)+1;
|
||||
|
||||
if (!resetcalled && !(player->pflags & PF_NOCLIP || leveltime < introtime) && !P_CheckSight(&dummy, player->mo)) // TODO: "P_CheckCameraSight" instead.
|
||||
P_ResetCamera(player, thiscam);
|
||||
else
|
||||
P_SlideCameraMove(thiscam);
|
||||
|
||||
if (resetcalled) // Okay this means the camera is fully reset.
|
||||
return true;
|
||||
}
|
||||
@@ -3410,8 +3413,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
|
||||
I_Assert(mobj != NULL);
|
||||
I_Assert(mobj->player != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
|
||||
if (!mobj)
|
||||
return;
|
||||
|
||||
P_MobjCheckWater(mobj);
|
||||
@@ -6030,41 +6033,36 @@ static void P_KoopaThinker(mobj_t *koopa)
|
||||
//
|
||||
void P_RollPitchMobj(mobj_t* mobj)
|
||||
{
|
||||
boolean usedist = false;
|
||||
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
if (!mobj || P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
if (cv_sloperolldist.value > 0)
|
||||
usedist = true;
|
||||
|
||||
if (cv_spriteroll.value && cv_sloperoll.value == 2)
|
||||
{
|
||||
K_RollMobjBySlopes(mobj, usedist);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->sloperoll = FixedAngle(0);
|
||||
mobj->slopepitch = FixedAngle(0);
|
||||
}
|
||||
if (cv_spriteroll.value && cv_sloperoll.value == 2)
|
||||
{
|
||||
K_RollMobjBySlopes(mobj, cv_sloperolldist.value && !splitscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
mobj->sloperoll = FixedAngle(0);
|
||||
mobj->slopepitch = FixedAngle(0);
|
||||
}
|
||||
}
|
||||
|
||||
angle_t P_MobjPitchAndRoll(mobj_t *mobj)
|
||||
{
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
angle_t ang = 0;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
angle_t ang = 0;
|
||||
angle_t camang = 0;
|
||||
angle_t return_angle = 0;
|
||||
|
||||
|
||||
if (!cv_spriteroll.value)
|
||||
return 0;
|
||||
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return 0;
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return 0;
|
||||
|
||||
size_t rot = mobj->frame & FF_FRAMEMASK;
|
||||
boolean papersprite = (mobj->frame & FF_PAPERSPRITE);
|
||||
size_t rot = mobj->frame & FF_FRAMEMASK;
|
||||
boolean papersprite = (mobj->frame & FF_PAPERSPRITE);
|
||||
|
||||
if (mobj->skin && mobj->sprite == SPR_PLAY)
|
||||
{
|
||||
@@ -6095,12 +6093,12 @@ angle_t P_MobjPitchAndRoll(mobj_t *mobj)
|
||||
camang = R_PointToAngle(mobj->x, mobj->y);
|
||||
}
|
||||
|
||||
return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll)
|
||||
return_angle = FixedMul(FINECOSINE((ang) >> ANGLETOFINESHIFT), mobj->roll)
|
||||
+ FixedMul(FINESINE((ang) >> ANGLETOFINESHIFT), mobj->pitch);
|
||||
|
||||
if (cv_sloperoll.value)
|
||||
{
|
||||
return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll)
|
||||
return_angle += FixedMul(FINECOSINE((camang) >> ANGLETOFINESHIFT), mobj->sloperoll)
|
||||
+ FixedMul(FINESINE((camang) >> ANGLETOFINESHIFT), mobj->slopepitch);
|
||||
}
|
||||
|
||||
@@ -6263,7 +6261,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (cv_sloperoll.value == 2 && mobj->state == &states[S_SHADOW])
|
||||
{
|
||||
mobj->slopepitch = mobj->target->slopepitch;
|
||||
@@ -6286,6 +6284,7 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
P_RemoveMobj(mobj);
|
||||
return;
|
||||
}
|
||||
|
||||
P_RollPitchMobj(mobj);
|
||||
break;
|
||||
case MT_SMOLDERING:
|
||||
@@ -6916,9 +6915,6 @@ void P_MobjThinker(mobj_t *mobj)
|
||||
// separate thinker
|
||||
if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse))
|
||||
{
|
||||
if (P_MobjWasRemoved(mobj))
|
||||
return;
|
||||
|
||||
P_MobjCheckWater(mobj);
|
||||
P_PushableThinker(mobj);
|
||||
|
||||
@@ -9434,11 +9430,11 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
||||
mobj->destscale = mapobjectscale;
|
||||
mobj->scalespeed = mapobjectscale/12;
|
||||
}
|
||||
|
||||
|
||||
// Sprite rendering
|
||||
mobj->realxscale = mobj->realyscale = mobj->scale;
|
||||
mobj->realxscale = mobj->realyscale = mobj->scale;
|
||||
mobj->spritexscale = mobj->realxscale;
|
||||
mobj->spriteyscale = mobj->realyscale;
|
||||
mobj->spriteyscale = mobj->realyscale;
|
||||
mobj->spritexoffset = mobj->spriteyoffset = 0;
|
||||
|
||||
// Funni slam sound when landing
|
||||
@@ -9892,11 +9888,11 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
|
||||
mobj->destscale = mapobjectscale;
|
||||
mobj->scalespeed = mapobjectscale/12;
|
||||
}
|
||||
|
||||
|
||||
// Sprite rendering
|
||||
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
|
||||
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
|
||||
mobj->spritexoffset = mobj->spriteyoffset = 0;
|
||||
|
||||
|
||||
// set subsector and/or block links
|
||||
P_SetThingPosition(mobj);
|
||||
I_Assert(mobj->subsector != NULL);
|
||||
@@ -9994,10 +9990,13 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
||||
|
||||
if (mobj->floorz != starting_floorz)
|
||||
mobj->precipflags |= PCF_FOF;
|
||||
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|
||||
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
|
||||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
else
|
||||
{
|
||||
INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
|
||||
|
||||
if (special == 7 || special == 6 || mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
}
|
||||
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
@@ -10100,7 +10099,7 @@ void P_RemoveMobj(mobj_t *mobj)
|
||||
P_SetTarget(&mobj->hprev->hnext, cachenext);
|
||||
P_SetTarget(&mobj->hprev, NULL);
|
||||
}
|
||||
|
||||
|
||||
// clear the reference from the mapthing
|
||||
if (mobj->spawnpoint)
|
||||
mobj->spawnpoint->mobj = NULL;
|
||||
@@ -10291,7 +10290,7 @@ void P_PrecipitationEffects(void)
|
||||
INT32 volume;
|
||||
size_t i;
|
||||
|
||||
boolean sounds_rain = true;
|
||||
boolean rainsfx = true;
|
||||
boolean sounds_thunder = true;
|
||||
boolean effects_lightning = true;
|
||||
boolean lightningStrike = false;
|
||||
@@ -10324,7 +10323,7 @@ void P_PrecipitationEffects(void)
|
||||
effects_lightning = false;
|
||||
break;
|
||||
case PRECIP_STORM_NORAIN: // no rain, lightning and thunder allowed
|
||||
sounds_rain = false;
|
||||
rainsfx = false;
|
||||
case PRECIP_STORM: // everything.
|
||||
break;
|
||||
default:
|
||||
@@ -10332,6 +10331,8 @@ void P_PrecipitationEffects(void)
|
||||
return;
|
||||
}
|
||||
|
||||
boolean sounds_rain = ((cv_drawdist_precip.value != 0) && rainsfx && (!leveltime || leveltime % 80 == 1));
|
||||
|
||||
// Currently thunderstorming with lightning, and we're sounding the thunder...
|
||||
// and where there's thunder, there's gotta be lightning!
|
||||
if (effects_lightning && lightningStrike)
|
||||
@@ -10351,38 +10352,57 @@ void P_PrecipitationEffects(void)
|
||||
if (sound_disabled)
|
||||
return; // Sound off? D'aw, no fun.
|
||||
|
||||
if (!sounds_rain && !sounds_thunder)
|
||||
return; // no need to calculate volume at ALL
|
||||
|
||||
if (players[displayplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
|
||||
volume = 255; // Sky above? We get it full blast.
|
||||
else
|
||||
{
|
||||
/* GCC is optimizing away y >= yl, FUCK YOU */
|
||||
volatile fixed_t x, y, yl, yh, xl, xh;
|
||||
INT64 x, y, yl, yh, xl, xh;
|
||||
fixed_t closedist, newdist;
|
||||
|
||||
// Essentially check in a 1024 unit radius of the player for an outdoor area.
|
||||
yl = players[displayplayers[0]].mo->y - 1024*FRACUNIT;
|
||||
yh = players[displayplayers[0]].mo->y + 1024*FRACUNIT;
|
||||
xl = players[displayplayers[0]].mo->x - 1024*FRACUNIT;
|
||||
xh = players[displayplayers[0]].mo->x + 1024*FRACUNIT;
|
||||
closedist = 2048*FRACUNIT;
|
||||
#define RADIUSSTEP (64*FRACUNIT)
|
||||
#define SEARCHRADIUS (16*RADIUSSTEP)
|
||||
yl = yh = players[displayplayers[0]].mo->y;
|
||||
yl -= SEARCHRADIUS;
|
||||
while (yl < INT32_MIN)
|
||||
yl += RADIUSSTEP;
|
||||
yh += SEARCHRADIUS;
|
||||
while (yh > INT32_MAX)
|
||||
yh -= RADIUSSTEP;
|
||||
|
||||
for (y = yl; y >= yl && y <= yh; y += FRACUNIT*64)
|
||||
for (x = xl; x >= xl && x <= xh; x += FRACUNIT*64)
|
||||
xl = xh = players[displayplayers[0]].mo->x;
|
||||
xl -= SEARCHRADIUS;
|
||||
while (xl < INT32_MIN)
|
||||
xl += RADIUSSTEP;
|
||||
xh += SEARCHRADIUS;
|
||||
while (xh > INT32_MAX)
|
||||
xh -= RADIUSSTEP;
|
||||
|
||||
closedist = SEARCHRADIUS*2;
|
||||
#undef SEARCHRADIUS
|
||||
for (y = yl; y <= yh; y += RADIUSSTEP)
|
||||
for (x = xl; x <= xh; x += RADIUSSTEP)
|
||||
{
|
||||
if (R_PointInSubsector(x, y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
|
||||
if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic != skyflatnum) // Found the outdoors!
|
||||
continue;
|
||||
|
||||
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, x, y, 0);
|
||||
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0);
|
||||
|
||||
if (newdist < closedist)
|
||||
closedist = newdist;
|
||||
}
|
||||
|
||||
volume = 255 - (closedist>>(FRACBITS+2));
|
||||
}
|
||||
#undef RADIUSSTEP
|
||||
|
||||
volume = CLAMP(volume, 0, 255);
|
||||
|
||||
if (sounds_rain && (!leveltime || leveltime % 80 == 1))
|
||||
if (sounds_rain)
|
||||
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume);
|
||||
|
||||
if (!sounds_thunder)
|
||||
@@ -11250,7 +11270,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
|
||||
|
||||
mobj = P_SpawnMobj(x, y, z, i);
|
||||
|
||||
if (!mobj || P_MobjWasRemoved(mobj)) {
|
||||
if (!mobj || P_MobjWasRemoved(mobj))
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Failed to spawn map thing #%d at %d, %d. This will crash vanilla clients!\n", mthing->type, x>>FRACBITS, y>>FRACBITS);
|
||||
return;
|
||||
}
|
||||
|
||||
+4
-5
@@ -261,6 +261,7 @@ typedef enum {
|
||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
||||
} precipflag_t;
|
||||
|
||||
// Map Object definition.
|
||||
typedef struct mobj_s
|
||||
{
|
||||
@@ -287,8 +288,7 @@ typedef struct mobj_s
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
UINT32 renderflags; // render flags
|
||||
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
@@ -440,8 +440,7 @@ typedef struct precipmobj_s
|
||||
spritenum_t sprite; // used to find patch_t and flip value
|
||||
UINT32 frame; // frame number, plus bits see p_pspr.h
|
||||
UINT16 anim_duration; // for FF_ANIMATE states
|
||||
|
||||
UINT32 renderflags; // render flags
|
||||
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
@@ -450,7 +449,7 @@ typedef struct precipmobj_s
|
||||
fixed_t realxscale, realyscale; // funn-E streeetch
|
||||
|
||||
fixed_t stretchslam; // "squish" effect when you land
|
||||
|
||||
|
||||
//sloperollangle
|
||||
angle_t sloperoll, slopepitch;
|
||||
angle_t old_sloperoll, old_slopepitch;
|
||||
|
||||
+2
-9
@@ -2587,9 +2587,6 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
|
||||
|
||||
P_LevelInitStuff(reloadinggamestate);
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
postimgtype[i] = postimg_none;
|
||||
|
||||
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
|
||||
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
|
||||
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
|
||||
@@ -2992,13 +2989,9 @@ boolean P_SetupLevel(boolean skipprecip, boolean reloadinggamestate)
|
||||
savedata.lives = 0;
|
||||
}
|
||||
|
||||
// assume the skybox is visible on level load.
|
||||
skyVisible = true;
|
||||
memset(skyVisiblePerPlayer, true, sizeof(skyVisiblePerPlayer));
|
||||
|
||||
if (loadprecip) // uglier hack
|
||||
{ // to make a newly loaded level start on the second frame.
|
||||
INT32 buf = gametic % TICQUEUE;
|
||||
{
|
||||
INT32 buf = gametic % TICQUEUE; // to make a newly loaded level start on the second frame.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
|
||||
+4
-9
@@ -469,9 +469,6 @@ void P_Ticker(boolean run)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
postimgtype[i] = postimg_none;
|
||||
|
||||
P_MapStart();
|
||||
|
||||
if (run)
|
||||
@@ -682,16 +679,17 @@ void P_Ticker(boolean run)
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
player_t *player = &players[displayplayers[i]];
|
||||
boolean isSkyVisibleForPlayer = skyVisiblePerPlayer[i];
|
||||
|
||||
if (!player->mo)
|
||||
continue;
|
||||
|
||||
if (isSkyVisibleForPlayer && skyboxmo[0] && cv_skybox.value)
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
|
||||
|
||||
if (skybox)
|
||||
{
|
||||
R_SkyboxFrame(player);
|
||||
}
|
||||
R_SetupFrame(player, (skyboxmo[0] && cv_skybox.value));
|
||||
R_SetupFrame(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -708,9 +706,6 @@ void P_PreTicker(INT32 frames)
|
||||
INT32 i;
|
||||
ticcmd_t temptic;
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
postimgtype[i] = postimg_none;
|
||||
|
||||
hook_defrosting = frames;
|
||||
|
||||
while (hook_defrosting)
|
||||
|
||||
+24
-26
@@ -4106,8 +4106,8 @@ boolean P_SpectatorJoinGame(player_t *player)
|
||||
static void P_CalcPostImg(player_t *player)
|
||||
{
|
||||
sector_t *sector = player->mo->subsector->sector;
|
||||
postimg_t *type = NULL;
|
||||
INT32 *param;
|
||||
INT16 typeflag = 0;
|
||||
//INT32 *param;
|
||||
fixed_t pviewheight;
|
||||
UINT8 i;
|
||||
|
||||
@@ -4122,20 +4122,19 @@ static void P_CalcPostImg(player_t *player)
|
||||
pviewheight = player->awayviewmobj->z + 20*FRACUNIT;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
/*for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
type = &postimgtype[i];
|
||||
param = &postimgparam[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// see if we are in heat (no, not THAT kind of heat...)
|
||||
|
||||
if (P_FindSpecialLineFromTag(13, sector->tag, -1) != -1)
|
||||
*type = postimg_heat;
|
||||
typeflag |= POSTIMG_HEAT;
|
||||
else if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
@@ -4154,7 +4153,7 @@ static void P_CalcPostImg(player_t *player)
|
||||
continue;
|
||||
|
||||
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
|
||||
*type = postimg_heat;
|
||||
typeflag |= POSTIMG_HEAT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4176,36 +4175,35 @@ static void P_CalcPostImg(player_t *player)
|
||||
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||
continue;
|
||||
|
||||
*type = postimg_water;
|
||||
typeflag |= POSTIMG_WATER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!encoremode) // srb2kart
|
||||
{
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
*type = postimg_flip;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
*type = postimg_mirrorflip;
|
||||
else
|
||||
*type = postimg_mirror;
|
||||
}
|
||||
if (encoremode) // srb2kart
|
||||
typeflag |= POSTIMG_MIRROR;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
typeflag |= POSTIMG_FLIP;
|
||||
|
||||
#if 1
|
||||
(void)param;
|
||||
#else
|
||||
// Motion blur
|
||||
if (player->speed > (35<<FRACBITS))
|
||||
// unused
|
||||
/*if (player->speed > (35<<FRACBITS))
|
||||
{
|
||||
*type = postimg_motion;
|
||||
typeflag |= POSTIMG_MOTION;
|
||||
*param = (player->speed - 32)/4;
|
||||
|
||||
if (*param > 5)
|
||||
*param = 5;
|
||||
}*/
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
players[displayplayers[i]].postimgflags = typeflag;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void P_DoTimeOver(player_t *player)
|
||||
|
||||
+5
-3
@@ -15,6 +15,7 @@
|
||||
#include "g_game.h"
|
||||
#include "r_local.h"
|
||||
#include "r_state.h"
|
||||
#include "r_portal.h" // Add seg portals
|
||||
|
||||
#include "r_splats.h"
|
||||
#include "p_local.h" // camera
|
||||
@@ -28,11 +29,11 @@ side_t *sidedef;
|
||||
line_t *linedef;
|
||||
sector_t *frontsector;
|
||||
sector_t *backsector;
|
||||
portal_pair *g_portal; // is curline a portal seg?
|
||||
|
||||
// very ugly realloc() of drawsegs at run-time, I upped it to 512
|
||||
// instead of 256.. and someone managed to send me a level with
|
||||
// 896 drawsegs! So too bad here's a limit removal a-la-Boom
|
||||
drawseg_t *curdrawsegs = NULL; /**< This is used to handle multiple lists for masked drawsegs. */
|
||||
drawseg_t *drawsegs = NULL;
|
||||
drawseg_t *ds_p = NULL;
|
||||
|
||||
@@ -486,7 +487,7 @@ static void R_AddLine(seg_t *line)
|
||||
line2 = P_FindSpecialLineFromTag(40, line->linedef->tag, line2);
|
||||
if (line2 >= 0) // found it!
|
||||
{
|
||||
R_AddPortal(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
|
||||
Portal_Add2Lines(line->linedef-lines, line2, x1, x2); // Remember the lines for later rendering
|
||||
//return; // Don't fill in that space now!
|
||||
goto clipsolid;
|
||||
}
|
||||
@@ -1319,7 +1320,8 @@ void R_RenderBSPNode(INT32 bspnum)
|
||||
bsp = &nodes[bspnum];
|
||||
|
||||
// Decide which side the view point is on.
|
||||
side = R_PointOnSide(viewx, viewy, bsp);
|
||||
side = R_PointOnSideRender(viewx, viewy, bsp);
|
||||
|
||||
// Recursively divide front space.
|
||||
R_RenderBSPNode(bsp->children[side]);
|
||||
|
||||
|
||||
+3
-2
@@ -25,12 +25,14 @@ extern side_t *sidedef;
|
||||
extern line_t *linedef;
|
||||
extern sector_t *frontsector;
|
||||
extern sector_t *backsector;
|
||||
extern portal_pair *g_portal; // is curline a portal seg?
|
||||
typedef struct portal_s portal_t;
|
||||
extern portal_t *g_portal; // is curline a portal seg?
|
||||
|
||||
// drawsegs are allocated on the fly... see r_segs.c
|
||||
|
||||
extern INT32 checkcoord[12][4];
|
||||
|
||||
extern drawseg_t *curdrawsegs;
|
||||
extern drawseg_t *drawsegs;
|
||||
extern drawseg_t *ds_p;
|
||||
extern INT32 doorclosed;
|
||||
@@ -41,7 +43,6 @@ void R_ClearClipSegs(void);
|
||||
void R_PortalClearClipSegs(INT32 start, INT32 end);
|
||||
void R_ClearDrawSegs(void);
|
||||
void R_RenderBSPNode(INT32 bspnum);
|
||||
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2);
|
||||
|
||||
// determines when a given sector shouldn't abide by the encoremap's palette.
|
||||
// no longer a static since this is used for encore in hw_main.c as well now:
|
||||
|
||||
@@ -687,14 +687,6 @@ typedef struct
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
typedef enum // trimmed since its only real use here is for xscale/yscale
|
||||
{
|
||||
RF_HORIZONTALFLIP = 0x0001, // Flip sprite horizontally
|
||||
RF_VERTICALFLIP = 0x0002, // Flip sprite vertically
|
||||
RF_ABSOLUTEOFFSETS = 0x0004, // Sprite uses the object's offsets absolutely, instead of relatively
|
||||
RF_FLIPOFFSETS = 0x0008, // Relative object offsets are flipped with the sprite
|
||||
} renderflags_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SRF_SINGLE = 0, // 0-angle for all rotations
|
||||
|
||||
@@ -78,6 +78,7 @@ fixed_t dc_iscale, dc_texturemid;
|
||||
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;
|
||||
INT32 dc_sourcelength;
|
||||
|
||||
// -----------------------
|
||||
// translucency stuff here
|
||||
|
||||
@@ -62,6 +62,7 @@ extern lighttable_t *ds_colormap;
|
||||
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
|
||||
extern INT32 ds_waterofs, ds_bgofs;
|
||||
extern UINT8 *ds_source; // start of a 64*64 tile image
|
||||
extern INT32 dc_sourcelength;
|
||||
extern UINT8 *ds_transmap;
|
||||
|
||||
extern INT32 ds_bgofs;
|
||||
|
||||
+130
-34
@@ -28,6 +28,8 @@ void R_DrawColumn_8(void)
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
INT32 npow2min;
|
||||
INT32 npow2max;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
@@ -51,13 +53,26 @@ void R_DrawColumn_8(void)
|
||||
fracstep = dc_iscale;
|
||||
frac = (dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep))*(!dc_hires);
|
||||
|
||||
|
||||
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
|
||||
// This is as fast as it gets.
|
||||
{
|
||||
register const UINT8 *source = dc_source;
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
|
||||
if (dc_sourcelength <= 0)
|
||||
{
|
||||
// Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch
|
||||
// This is to just render it effectively the identity function.
|
||||
npow2min = INT32_MIN;
|
||||
npow2max = INT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
npow2min = -1;
|
||||
npow2max = dc_sourcelength;
|
||||
}
|
||||
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
@@ -74,7 +89,10 @@ void R_DrawColumn_8(void)
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
*dest = colormap[source[frac>>FRACBITS]];
|
||||
|
||||
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
|
||||
// and a few bytes after as well
|
||||
*dest = colormap[source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]];
|
||||
dest += vid.width;
|
||||
|
||||
// Avoid overflow.
|
||||
@@ -115,6 +133,8 @@ void R_Draw2sMultiPatchColumn_8(void)
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
INT32 npow2min;
|
||||
INT32 npow2max;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
@@ -147,6 +167,20 @@ void R_Draw2sMultiPatchColumn_8(void)
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
register UINT8 val;
|
||||
|
||||
if (dc_sourcelength <= 0)
|
||||
{
|
||||
// Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch
|
||||
// This is to just render it effectively the identity function.
|
||||
npow2min = INT32_MIN;
|
||||
npow2max = INT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
npow2min = -1;
|
||||
npow2max = dc_sourcelength;
|
||||
}
|
||||
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
@@ -163,7 +197,10 @@ void R_Draw2sMultiPatchColumn_8(void)
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
val = source[frac>>FRACBITS];
|
||||
|
||||
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
|
||||
// and a few bytes after as well
|
||||
val = source[CLAMP(frac>>FRACBITS, npow2min, npow2max)];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
{
|
||||
@@ -223,6 +260,8 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac;
|
||||
fixed_t fracstep;
|
||||
INT32 npow2min;
|
||||
INT32 npow2max;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
@@ -256,6 +295,20 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight-1;
|
||||
register UINT8 val;
|
||||
|
||||
if (dc_sourcelength <= 0)
|
||||
{
|
||||
// Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch
|
||||
// This is to just render it effectively the identity function.
|
||||
npow2min = INT32_MIN;
|
||||
npow2max = INT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
npow2min = -1;
|
||||
npow2max = dc_sourcelength;
|
||||
}
|
||||
|
||||
if (dc_texheight & heightmask) // not a power of 2 -- killough
|
||||
{
|
||||
heightmask++;
|
||||
@@ -272,7 +325,10 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void)
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
val = source[frac>>FRACBITS];
|
||||
|
||||
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
|
||||
// and a few bytes after as well
|
||||
val = source[CLAMP(frac>>FRACBITS, npow2min, npow2max)];
|
||||
|
||||
if (val != TRANSPARENTPIXEL)
|
||||
{
|
||||
@@ -376,6 +432,8 @@ void R_DrawTranslucentColumn_8(void)
|
||||
register INT32 count;
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac, fracstep;
|
||||
INT32 npow2min;
|
||||
INT32 npow2max;
|
||||
|
||||
count = dc_yh - dc_yl + 1;
|
||||
|
||||
@@ -403,6 +461,20 @@ void R_DrawTranslucentColumn_8(void)
|
||||
register const UINT8 *transmap = dc_transmap;
|
||||
register const lighttable_t *colormap = dc_colormap;
|
||||
register INT32 heightmask = dc_texheight - 1;
|
||||
|
||||
if (dc_sourcelength <= 0)
|
||||
{
|
||||
// Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch
|
||||
// This is to just render it effectively the identity function.
|
||||
npow2min = INT32_MIN;
|
||||
npow2max = INT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
npow2min = -1;
|
||||
npow2max = dc_sourcelength;
|
||||
}
|
||||
|
||||
if (dc_texheight & heightmask)
|
||||
{
|
||||
heightmask++;
|
||||
@@ -420,7 +492,11 @@ void R_DrawTranslucentColumn_8(void)
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
*dest = *(transmap + (colormap[source[frac>>FRACBITS]]<<8) + (*dest));
|
||||
|
||||
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
|
||||
// and a few bytes after as well
|
||||
*dest = *(transmap + (colormap[source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]]<<8) + (*dest));
|
||||
|
||||
dest += vid.width;
|
||||
|
||||
if ((frac += fracstep) >= heightmask)
|
||||
@@ -458,6 +534,8 @@ void R_DrawTranslatedTranslucentColumn_8(void)
|
||||
register INT32 count;
|
||||
register UINT8 *dest;
|
||||
register fixed_t frac, fracstep;
|
||||
INT32 npow2min;
|
||||
INT32 npow2max;
|
||||
|
||||
count = dc_yh - dc_yl + 1;
|
||||
|
||||
@@ -477,6 +555,20 @@ void R_DrawTranslatedTranslucentColumn_8(void)
|
||||
// This is as fast as it gets.
|
||||
{
|
||||
register INT32 heightmask = dc_texheight - 1;
|
||||
|
||||
if (dc_sourcelength <= 0)
|
||||
{
|
||||
// Note: we need to unconditionally clamp in npow2 draw loop to avoid a CPU branch
|
||||
// This is to just render it effectively the identity function.
|
||||
npow2min = INT32_MIN;
|
||||
npow2max = INT32_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
npow2min = -1;
|
||||
npow2max = dc_sourcelength;
|
||||
}
|
||||
|
||||
if (dc_texheight & heightmask)
|
||||
{
|
||||
heightmask++;
|
||||
@@ -494,7 +586,10 @@ void R_DrawTranslatedTranslucentColumn_8(void)
|
||||
// Re-map color indices from wall texture column
|
||||
// using a lighting/special effects LUT.
|
||||
// heightmask is the Tutti-Frutti fix
|
||||
*dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest));
|
||||
|
||||
// -1 is the lower clamp bound because column posts have a "safe" byte before the real data
|
||||
// and a few bytes after as well
|
||||
*dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[CLAMP(frac>>FRACBITS, npow2min, npow2max)]]]<<8) + (*dest));
|
||||
dest += vid.width;
|
||||
|
||||
if ((frac += fracstep) >= heightmask)
|
||||
@@ -586,14 +681,14 @@ void R_DrawSpan_8 (void)
|
||||
fixed_t xposition;
|
||||
fixed_t yposition;
|
||||
fixed_t xstep, ystep;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
|
||||
size_t count = (ds_x2 - ds_x1 + 1);
|
||||
register size_t count = (ds_x2 - ds_x1 + 1);
|
||||
size_t i;
|
||||
|
||||
xposition = ds_xfrac; yposition = ds_yfrac;
|
||||
@@ -681,13 +776,13 @@ void R_DrawTiltedSpan_8(void)
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
|
||||
double startz, startu, startv;
|
||||
double izstep, uzstep, vzstep;
|
||||
double endz, endu, endv;
|
||||
UINT32 stepu, stepv;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
|
||||
|
||||
@@ -822,13 +917,13 @@ void R_DrawTiltedTranslucentSpan_8(void)
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
|
||||
double startz, startu, startv;
|
||||
double izstep, uzstep, vzstep;
|
||||
double endz, endu, endv;
|
||||
UINT32 stepu, stepv;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
|
||||
|
||||
@@ -964,14 +1059,14 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
UINT8 *dsrc;
|
||||
|
||||
double startz, startu, startv;
|
||||
double izstep, uzstep, vzstep;
|
||||
double endz, endu, endv;
|
||||
UINT32 stepu, stepv;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
|
||||
|
||||
@@ -1105,7 +1200,7 @@ void R_DrawTiltedSplat_8(void)
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
|
||||
UINT8 val;
|
||||
|
||||
@@ -1113,7 +1208,7 @@ void R_DrawTiltedSplat_8(void)
|
||||
double izstep, uzstep, vzstep;
|
||||
double endz, endu, endv;
|
||||
UINT32 stepu, stepv;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
|
||||
|
||||
@@ -1257,13 +1352,13 @@ void R_DrawSplat_8 (void)
|
||||
UINT32 xposition;
|
||||
UINT32 yposition;
|
||||
UINT32 xstep, ystep;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
|
||||
size_t count;
|
||||
register size_t count;
|
||||
size_t i;
|
||||
UINT32 val;
|
||||
|
||||
@@ -1327,13 +1422,13 @@ void R_DrawTranslucentSplat_8 (void)
|
||||
UINT32 xposition;
|
||||
UINT32 yposition;
|
||||
UINT32 xstep, ystep;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
|
||||
size_t count;
|
||||
register size_t count;
|
||||
size_t i;
|
||||
UINT8 val;
|
||||
|
||||
@@ -1392,14 +1487,14 @@ void R_DrawTranslucentSpan_8 (void)
|
||||
fixed_t xposition;
|
||||
fixed_t yposition;
|
||||
fixed_t xstep, ystep;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
|
||||
|
||||
size_t count = (ds_x2 - ds_x1 + 1);
|
||||
register size_t count = (ds_x2 - ds_x1 + 1);
|
||||
size_t i;
|
||||
|
||||
xposition = ds_xfrac; yposition = ds_yfrac;
|
||||
@@ -1451,14 +1546,14 @@ void R_DrawTranslucentWaterSpan_8(void)
|
||||
UINT32 xposition;
|
||||
UINT32 yposition;
|
||||
UINT32 xstep, ystep;
|
||||
UINT32 bit;
|
||||
register UINT32 bit;
|
||||
|
||||
UINT8 *source;
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
UINT8 *dsrc;
|
||||
|
||||
size_t count;
|
||||
register size_t count;
|
||||
size_t i;
|
||||
|
||||
// SoM: we only need 6 bits for the integer part (0 thru 63) so the rest
|
||||
@@ -1510,9 +1605,9 @@ void R_DrawTranslucentWaterSpan_8(void)
|
||||
void R_DrawFogSpan_8(void)
|
||||
{
|
||||
UINT8 *colormap;
|
||||
UINT8 *dest;
|
||||
register UINT8 *dest;
|
||||
|
||||
size_t count;
|
||||
register size_t count;
|
||||
|
||||
colormap = ds_colormap;
|
||||
//dest = ylookup[ds_y] + columnofs[ds_x1];
|
||||
@@ -1543,8 +1638,8 @@ void R_DrawFogSpan_8(void)
|
||||
*/
|
||||
void R_DrawFogColumn_8(void)
|
||||
{
|
||||
INT32 count;
|
||||
UINT8 *dest;
|
||||
register INT32 count;
|
||||
register UINT8 *dest;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
|
||||
@@ -1579,7 +1674,8 @@ void R_DrawFogColumn_8(void)
|
||||
*/
|
||||
void R_DrawColumnShadowed_8(void)
|
||||
{
|
||||
INT32 count, realyh, i, height, bheight = 0, solid = 0;
|
||||
register INT32 count;
|
||||
INT32 realyh, i, height, bheight = 0, solid = 0;
|
||||
|
||||
realyh = dc_yh;
|
||||
|
||||
|
||||
+83
-203
@@ -31,6 +31,7 @@
|
||||
#include "p_spec.h" // skyboxmo
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h" // quake camera shake
|
||||
#include "r_portal.h"
|
||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "r_fps.h" // Frame interpolation/uncapped
|
||||
#include "tables.h"
|
||||
@@ -61,19 +62,9 @@ fixed_t viewx, viewy, viewz;
|
||||
angle_t viewangle, aimingangle, viewroll;
|
||||
UINT8 viewssnum;
|
||||
fixed_t viewcos, viewsin;
|
||||
boolean skyVisible;
|
||||
boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible for each splitscreen player
|
||||
sector_t *viewsector;
|
||||
player_t *viewplayer;
|
||||
|
||||
// PORTALS!
|
||||
// You can thank and/or curse JTE for these.
|
||||
UINT8 portalrender;
|
||||
sector_t *portalcullsector;
|
||||
portal_pair *portal_base, *portal_cap;
|
||||
line_t *portalclipline;
|
||||
INT32 portalclipstart, portalclipend;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
fixed_t rendertimefrac_unpaused;
|
||||
fixed_t renderdeltatics;
|
||||
@@ -325,29 +316,6 @@ PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *restrict node)
|
||||
(~mask & (FixedMul(y, node->dx>>FRACBITS) >= FixedMul(node->dy>>FRACBITS, x)));
|
||||
}
|
||||
|
||||
// killough 5/2/98: reformatted
|
||||
PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
|
||||
{
|
||||
fixed_t lx = line->v1->x;
|
||||
fixed_t ly = line->v1->y;
|
||||
fixed_t ldx = line->v2->x - lx;
|
||||
fixed_t ldy = line->v2->y - ly;
|
||||
|
||||
if (!ldx)
|
||||
return x <= lx ? ldy > 0 : ldy < 0;
|
||||
|
||||
if (!ldy)
|
||||
return y <= ly ? ldx < 0 : ldx > 0;
|
||||
|
||||
x -= lx;
|
||||
y -= ly;
|
||||
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ((ldy ^ ldx ^ x ^ y) < 0)
|
||||
return (ldy ^ x) < 0; // (left is negative)
|
||||
return FixedMul(y, ldx>>FRACBITS) >= FixedMul(ldy>>FRACBITS, x);
|
||||
}
|
||||
|
||||
//
|
||||
// R_PointToAngle
|
||||
// To get a global angle from cartesian coordinates,
|
||||
@@ -1359,7 +1327,7 @@ void R_SkyboxFrame(player_t *player)
|
||||
R_InterpolateView(R_UsingFrameInterpolation() ? (demo.playback && demo.freecam) ? rendertimefrac_unpaused : rendertimefrac : FRACUNIT, false);
|
||||
}
|
||||
|
||||
void R_SetupFrame(player_t *player, boolean skybox)
|
||||
void R_SetupFrame(player_t *player)
|
||||
{
|
||||
camera_t *thiscam;
|
||||
boolean chasecam = false;
|
||||
@@ -1422,7 +1390,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
||||
else if (thiscam && !chasecam)
|
||||
thiscam->chase = false;
|
||||
|
||||
newview->sky = !skybox;
|
||||
newview->sky = false;
|
||||
|
||||
if (player->awayviewtics) // cut-away view stuff
|
||||
{
|
||||
@@ -1504,115 +1472,49 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
||||
R_InterpolateView(R_UsingFrameInterpolation() ? (demo.playback && demo.freecam) ? rendertimefrac_unpaused : rendertimefrac : FRACUNIT, false);
|
||||
}
|
||||
|
||||
#define ANGLED_PORTALS
|
||||
|
||||
static void R_PortalFrame(line_t *start, line_t *dest, portal_pair *portal)
|
||||
static void R_PortalFrame(portal_t *portal)
|
||||
{
|
||||
vertex_t dest_c, start_c;
|
||||
#ifdef ANGLED_PORTALS
|
||||
// delta angle
|
||||
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
||||
#endif
|
||||
|
||||
//R_SetupFrame(player, false);
|
||||
viewx = portal->viewx;
|
||||
viewy = portal->viewy;
|
||||
viewz = portal->viewz;
|
||||
|
||||
viewangle = portal->viewangle;
|
||||
// newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
portalcullsector = dest->frontsector;
|
||||
viewsector = dest->frontsector;
|
||||
portalclipline = dest;
|
||||
portalclipstart = portal->start;
|
||||
portalclipend = portal->end;
|
||||
|
||||
// Offset the portal view by the linedef centers
|
||||
|
||||
// looking glass center
|
||||
start_c.x = (start->v1->x + start->v2->x) / 2;
|
||||
start_c.y = (start->v1->y + start->v2->y) / 2;
|
||||
|
||||
// other side center
|
||||
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
|
||||
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
||||
|
||||
// Heights!
|
||||
viewz += dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
|
||||
// calculate the difference in position and rotation!
|
||||
#ifdef ANGLED_PORTALS
|
||||
if (dangle == 0)
|
||||
#endif
|
||||
{ // the entrance goes straight opposite the exit, so we just need to mess with the offset.
|
||||
viewx += dest_c.x - start_c.x;
|
||||
viewy += dest_c.y - start_c.y;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ANGLED_PORTALS
|
||||
viewangle += dangle;
|
||||
// newview->sin = FINESINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
// newview->cos = FINECOSINE(newview->angle>>ANGLETOFINESHIFT);
|
||||
//CONS_Printf("dangle == %u\n", AngleFixed(dangle)>>FRACBITS);
|
||||
|
||||
// ????
|
||||
if (portal->clipline != -1)
|
||||
{
|
||||
fixed_t disttopoint;
|
||||
angle_t angtopoint;
|
||||
|
||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, newview->x, newview->y);
|
||||
angtopoint = R_PointToAngle2(start_c.x, start_c.y, newview->x, newview->y);
|
||||
angtopoint += dangle;
|
||||
|
||||
viewx = dest_c.x+FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
viewy = dest_c.y+FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
|
||||
{
|
||||
portal_pair *portal = Z_Malloc(sizeof(portal_pair), PU_LEVEL, NULL);
|
||||
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
|
||||
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
|
||||
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL);
|
||||
|
||||
portal->line1 = line1;
|
||||
portal->line2 = line2;
|
||||
portal->pass = portalrender+1;
|
||||
portal->next = NULL;
|
||||
|
||||
R_PortalStoreClipValues(x1, x2, ceilingclipsave, floorclipsave, frontscalesave);
|
||||
|
||||
portal->ceilingclip = ceilingclipsave;
|
||||
portal->floorclip = floorclipsave;
|
||||
portal->frontscale = frontscalesave;
|
||||
|
||||
portal->start = x1;
|
||||
portal->end = x2;
|
||||
|
||||
g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg
|
||||
|
||||
portal->viewx = viewx;
|
||||
portal->viewy = viewy;
|
||||
portal->viewz = viewz;
|
||||
portal->viewangle = viewangle;
|
||||
|
||||
if (!portal_base)
|
||||
{
|
||||
portal_base = portal;
|
||||
portal_cap = portal;
|
||||
portalclipline = &lines[portal->clipline];
|
||||
portalcullsector = portalclipline->frontsector;
|
||||
viewsector = portalclipline->frontsector;
|
||||
}
|
||||
else
|
||||
{
|
||||
portal_cap->next = portal;
|
||||
portal_cap = portal;
|
||||
portalclipline = NULL;
|
||||
portalcullsector = NULL;
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
}
|
||||
}
|
||||
|
||||
static void Mask_Pre (maskcount_t* m)
|
||||
{
|
||||
m->drawsegs[0] = ds_p - drawsegs;
|
||||
m->vissprites[0] = visspritecount;
|
||||
m->viewx = viewx;
|
||||
m->viewy = viewy;
|
||||
m->viewz = viewz;
|
||||
m->viewsector = viewsector;
|
||||
}
|
||||
|
||||
static void Mask_Post (maskcount_t* m)
|
||||
{
|
||||
m->drawsegs[1] = ds_p - drawsegs;
|
||||
m->vissprites[1] = visspritecount;
|
||||
}
|
||||
|
||||
// ================
|
||||
// R_RenderView
|
||||
// ================
|
||||
@@ -1625,9 +1527,8 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
|
||||
|
||||
void R_RenderPlayerView(player_t *player)
|
||||
{
|
||||
portal_pair *portal;
|
||||
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
|
||||
UINT8 i;
|
||||
INT32 nummasks = 1;
|
||||
maskcount_t* masks = malloc(sizeof(maskcount_t));
|
||||
|
||||
// if this is display player 1
|
||||
if (cv_homremoval.value && player == &players[displayplayers[0]])
|
||||
@@ -1652,44 +1553,7 @@ void R_RenderPlayerView(player_t *player)
|
||||
}
|
||||
}
|
||||
|
||||
// load previous saved value of skyVisible for the player
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
skyVisible = skyVisiblePerPlayer[i];
|
||||
break;
|
||||
}
|
||||
|
||||
portalrender = 0;
|
||||
portal_base = portal_cap = NULL;
|
||||
|
||||
PS_START_TIMING(ps_skyboxtime);
|
||||
if (skybox && skyVisible)
|
||||
{
|
||||
R_SkyboxFrame(player);
|
||||
|
||||
R_ClearClipSegs();
|
||||
R_ClearDrawSegs();
|
||||
R_ClearPlanes();
|
||||
R_ClearSprites();
|
||||
#ifdef FLOORSPLATS
|
||||
R_ClearVisibleFloorSplats();
|
||||
#endif
|
||||
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
R_ClipSprites();
|
||||
R_DrawPlanes();
|
||||
#ifdef FLOORSPLATS
|
||||
R_DrawVisibleFloorSplats();
|
||||
#endif
|
||||
R_DrawMasked();
|
||||
}
|
||||
PS_STOP_TIMING(ps_skyboxtime);
|
||||
|
||||
R_SetupFrame(player, skybox);
|
||||
skyVisible = false;
|
||||
R_SetupFrame(player);
|
||||
framecount++;
|
||||
validcount++;
|
||||
|
||||
@@ -1706,7 +1570,7 @@ void R_RenderPlayerView(player_t *player)
|
||||
else
|
||||
{
|
||||
portalclipstart = 0;
|
||||
portalclipend = viewwidth-1;
|
||||
portalclipend = viewwidth;
|
||||
R_ClearClipSegs();
|
||||
}
|
||||
R_ClearDrawSegs();
|
||||
@@ -1715,50 +1579,75 @@ void R_RenderPlayerView(player_t *player)
|
||||
R_ClearVisibleFloorSplats();
|
||||
#endif
|
||||
|
||||
// The head node is the last node output.
|
||||
Portal_InitList();
|
||||
|
||||
// The head node is the last node output.
|
||||
Mask_Pre(&masks[nummasks - 1]);
|
||||
curdrawsegs = ds_p;
|
||||
ps_numbspcalls.value.i = ps_numpolyobjects.value.i = ps_numdrawnodes.value.i = 0;
|
||||
PS_START_TIMING(ps_bsptime);
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
PS_STOP_TIMING(ps_bsptime);
|
||||
Mask_Post(&masks[nummasks - 1]);
|
||||
|
||||
R_AddPrecipitationSprites();
|
||||
|
||||
PS_START_TIMING(ps_sw_spritecliptime);
|
||||
R_ClipSprites();
|
||||
R_ClipSprites(drawsegs, NULL);
|
||||
PS_STOP_TIMING(ps_sw_spritecliptime);
|
||||
|
||||
ps_numsprites.value.i = numvisiblesprites;
|
||||
|
||||
// PORTAL RENDERING
|
||||
// Add skybox portals caused by sky visplanes.
|
||||
if (skyboxmo[0] && cv_skybox.value)
|
||||
Portal_AddSkyboxPortals();
|
||||
|
||||
PS_START_TIMING(ps_sw_portaltime);
|
||||
for(portal = portal_base; portal; portal = portal_base)
|
||||
// Portal rendering. Hijacks the BSP traversal.
|
||||
if (portal_base)
|
||||
{
|
||||
// render the portal
|
||||
CONS_Debug(DBG_RENDER, "Rendering portal from line %d to %d\n", portal->line1, portal->line2);
|
||||
portalrender = portal->pass;
|
||||
portal_t *portal;
|
||||
|
||||
R_PortalFrame(&lines[portal->line1], &lines[portal->line2], portal);
|
||||
for (portal = portal_base; portal; portal = portal_base)
|
||||
{
|
||||
portalrender = portal->pass; // Recursiveness depth.
|
||||
|
||||
R_PortalClearClipSegs(portal->start, portal->end);
|
||||
R_ClearFFloorClips();
|
||||
|
||||
R_PortalRestoreClipValues(portal->start, portal->end, portal->ceilingclip, portal->floorclip, portal->frontscale);
|
||||
// Apply the viewpoint stored for the portal.
|
||||
R_PortalFrame(portal);
|
||||
|
||||
validcount++;
|
||||
// Hack in the clipsegs to delimit the starting
|
||||
// clipping for sprites and possibly other similar
|
||||
// future items.
|
||||
R_PortalClearClipSegs(portal->start, portal->end);
|
||||
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
R_ClipSprites();
|
||||
//R_DrawPlanes();
|
||||
//R_DrawMasked();
|
||||
// Hack in the top/bottom clip values for the window
|
||||
// that were previously stored.
|
||||
Portal_ClipApply(portal);
|
||||
|
||||
// okay done. free it.
|
||||
portalcullsector = NULL; // Just in case...
|
||||
portal_base = portal->next;
|
||||
Z_Free(portal->ceilingclip);
|
||||
Z_Free(portal->floorclip);
|
||||
Z_Free(portal->frontscale);
|
||||
Z_Free(portal);
|
||||
validcount++;
|
||||
|
||||
masks = realloc(masks, (++nummasks)*sizeof(maskcount_t));
|
||||
|
||||
Mask_Pre(&masks[nummasks - 1]);
|
||||
curdrawsegs = ds_p;
|
||||
|
||||
portalskipprecipmobjs = portal->isskybox;
|
||||
|
||||
// Render the BSP from the new viewpoint, and clip
|
||||
// any sprites with the new clipsegs and window.
|
||||
R_RenderBSPNode((INT32)numnodes - 1);
|
||||
Mask_Post(&masks[nummasks - 1]);
|
||||
|
||||
portalskipprecipmobjs = false;
|
||||
|
||||
R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
|
||||
|
||||
Portal_Remove(portal);
|
||||
}
|
||||
}
|
||||
PS_STOP_TIMING(ps_sw_portaltime);
|
||||
// END PORTAL RENDERING
|
||||
|
||||
PS_START_TIMING(ps_sw_planetime);
|
||||
R_DrawPlanes();
|
||||
@@ -1769,19 +1658,10 @@ void R_RenderPlayerView(player_t *player)
|
||||
// draw mid texture and sprite
|
||||
// And now 3D floors/sides!
|
||||
PS_START_TIMING(ps_sw_maskedtime);
|
||||
R_DrawMasked();
|
||||
R_DrawMasked(masks, nummasks);
|
||||
PS_STOP_TIMING(ps_sw_maskedtime);
|
||||
|
||||
// save value to skyVisiblePerPlayer
|
||||
// this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
skyVisiblePerPlayer[i] = skyVisible;
|
||||
break;
|
||||
}
|
||||
free(masks);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
||||
+19
-23
@@ -73,7 +73,24 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
// Utility functions.
|
||||
INT32 R_PointOnSide(fixed_t x, fixed_t y, const node_t *node);
|
||||
INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line);
|
||||
|
||||
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideRender(fixed_t x, fixed_t y, const node_t *node)
|
||||
{
|
||||
// use cross product to determine side quickly
|
||||
return (INT64)(y - node->y) * node->dx - (INT64)(x - node->x) * node->dy > 0;
|
||||
}
|
||||
|
||||
FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSegSide(fixed_t x, fixed_t y, const seg_t *line)
|
||||
{
|
||||
fixed_t lx = line->v1->x;
|
||||
fixed_t ly = line->v1->y;
|
||||
fixed_t ldx = line->v2->x - lx;
|
||||
fixed_t ldy = line->v2->y - ly;
|
||||
|
||||
// use cross product to determine side quickly
|
||||
return (INT64)(y - ly) * ldx - (INT64)(x - lx) * ldy > 0;
|
||||
}
|
||||
|
||||
angle_t R_PointToAngle(fixed_t x, fixed_t y);
|
||||
angle_t R_PointToAngle64(INT64 x, INT64 y);
|
||||
angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1);
|
||||
@@ -90,27 +107,6 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y);
|
||||
boolean R_DoCulling(line_t *cullheight, line_t *viewcullheight, fixed_t vz, fixed_t bottomh, fixed_t toph);
|
||||
void R_GetRenderBlockMapDimensions(fixed_t drawdist, INT32 *xl, INT32 *xh, INT32 *yl, INT32 *yh);
|
||||
|
||||
|
||||
typedef struct portal_pair
|
||||
{
|
||||
INT32 line1;
|
||||
INT32 line2;
|
||||
UINT8 pass;
|
||||
struct portal_pair *next;
|
||||
|
||||
fixed_t viewx;
|
||||
fixed_t viewy;
|
||||
fixed_t viewz;
|
||||
angle_t viewangle;
|
||||
|
||||
INT32 start;
|
||||
INT32 end;
|
||||
INT16 *ceilingclip;
|
||||
INT16 *floorclip;
|
||||
fixed_t *frontscale;
|
||||
} portal_pair;
|
||||
|
||||
|
||||
// Performance stats
|
||||
extern precise_t ps_prevframetime;// time when previous frame was rendered
|
||||
extern ps_metric_t ps_rendercalltime;
|
||||
@@ -164,8 +160,8 @@ void R_SetViewSize(void);
|
||||
void R_ExecuteSetViewSize(void);
|
||||
|
||||
void R_SkyboxFrame(player_t *player);
|
||||
void R_SetupFrame(player_t *player);
|
||||
|
||||
void R_SetupFrame(player_t *player, boolean skybox);
|
||||
// Called by G_Drawer.
|
||||
void R_RenderPlayerView(player_t *player);
|
||||
|
||||
|
||||
+21
-59
@@ -23,6 +23,8 @@
|
||||
#include "r_state.h"
|
||||
#include "r_splats.h" // faB(21jan):testing
|
||||
#include "r_sky.h"
|
||||
#include "r_portal.h"
|
||||
|
||||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
@@ -39,13 +41,7 @@
|
||||
// good night sweet prince
|
||||
//#define SHITPLANESPARENCY
|
||||
|
||||
//SoM: 3/23/2000: Use Boom visplane hashing.
|
||||
#define VISPLANEHASHBITS 9
|
||||
#define VISPLANEHASHMASK ((1<<VISPLANEHASHBITS)-1)
|
||||
// the last visplane list is outside of the hash table and is used for fof planes
|
||||
#define MAXVISPLANES ((1<<VISPLANEHASHBITS)+1)
|
||||
|
||||
static visplane_t *visplanes[MAXVISPLANES];
|
||||
visplane_t *visplanes[MAXVISPLANES];
|
||||
static visplane_t *freetail;
|
||||
static visplane_t **freehead = &freetail;
|
||||
|
||||
@@ -112,50 +108,6 @@ void R_InitPlanes(void)
|
||||
// FIXME: unused
|
||||
}
|
||||
|
||||
// R_PortalStoreClipValues
|
||||
// Saves clipping values for later. -Red
|
||||
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < end-start; i++)
|
||||
{
|
||||
*ceil = ceilingclip[start+i];
|
||||
ceil++;
|
||||
*floor = floorclip[start+i];
|
||||
floor++;
|
||||
*scale = frontscale[start+i];
|
||||
scale++;
|
||||
}
|
||||
}
|
||||
|
||||
// R_PortalRestoreClipValues
|
||||
// Inverse of the above. Restores the old value!
|
||||
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < end-start; i++)
|
||||
{
|
||||
ceilingclip[start+i] = *ceil;
|
||||
ceil++;
|
||||
floorclip[start+i] = *floor;
|
||||
floor++;
|
||||
frontscale[start+i] = *scale;
|
||||
scale++;
|
||||
}
|
||||
|
||||
// HACKS FOLLOW
|
||||
for (i = 0; i < start; i++)
|
||||
{
|
||||
floorclip[i] = -1;
|
||||
ceilingclip[i] = (INT16)viewheight;
|
||||
}
|
||||
for (i = end; i < vid.width; i++)
|
||||
{
|
||||
floorclip[i] = -1;
|
||||
ceilingclip[i] = (INT16)viewheight;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Water ripple effect!!
|
||||
// Needs the height of the plane, and the vertical position of the span.
|
||||
@@ -307,6 +259,24 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
|
||||
spanfunc();
|
||||
}
|
||||
|
||||
void R_ClearFFloorClips (void)
|
||||
{
|
||||
INT32 i, p;
|
||||
|
||||
// opening / clipping determination
|
||||
for (i = 0; i < viewwidth; i++)
|
||||
{
|
||||
for (p = 0; p < MAXFFLOORS; p++)
|
||||
{
|
||||
ffloor[p].f_clip[i] = (INT16)viewheight;
|
||||
ffloor[p].c_clip[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
numffloors = 0;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// R_ClearPlanes
|
||||
// At begining of frame.
|
||||
@@ -329,8 +299,6 @@ void R_ClearPlanes(void)
|
||||
}
|
||||
}
|
||||
|
||||
numffloors = 0;
|
||||
|
||||
for (i = 0; i < MAXVISPLANES; i++)
|
||||
{
|
||||
for (*freehead = visplanes[i], visplanes[i] = NULL;
|
||||
@@ -665,12 +633,6 @@ static void R_DrawSkyPlane(visplane_t *pl)
|
||||
INT32 x;
|
||||
INT32 angle;
|
||||
|
||||
if (!newview->sky)
|
||||
{
|
||||
skyVisible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
wallcolfunc = walldrawerfunc;
|
||||
|
||||
// use correct aspect ratio scale
|
||||
|
||||
+3
-2
@@ -18,6 +18,7 @@
|
||||
#include "r_data.h"
|
||||
#include "p_polyobj.h"
|
||||
|
||||
//SoM: 3/23/2000: Use Boom visplane hashing.
|
||||
#define VISPLANEHASHBITS 9
|
||||
#define VISPLANEHASHMASK ((1<<VISPLANEHASHBITS)-1)
|
||||
// the last visplane list is outside of the hash table and is used for fof planes
|
||||
@@ -56,6 +57,7 @@ typedef struct visplane_s
|
||||
boolean noencore;
|
||||
} visplane_t;
|
||||
|
||||
extern visplane_t *visplanes[MAXVISPLANES];
|
||||
extern visplane_t *floorplane;
|
||||
extern visplane_t *ceilingplane;
|
||||
|
||||
@@ -75,9 +77,8 @@ extern fixed_t *yslope;
|
||||
extern lighttable_t **planezlight;
|
||||
|
||||
void R_InitPlanes(void);
|
||||
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
|
||||
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
|
||||
void R_ClearPlanes(void);
|
||||
void R_ClearFFloorClips (void);
|
||||
|
||||
void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
|
||||
void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
|
||||
|
||||
+317
@@ -0,0 +1,317 @@
|
||||
// SONIC ROBO BLAST 2 KART
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Kart Krew.
|
||||
// Copyright (C) 2020 by Sonic Team Junior.
|
||||
// Copyright (C) 2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1996 by id Software, Inc.
|
||||
//
|
||||
// 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_portal.c
|
||||
/// \brief Software renderer portals.
|
||||
|
||||
#include "r_portal.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_main.h"
|
||||
#include "doomstat.h"
|
||||
#include "p_spec.h" // Skybox viewpoints
|
||||
#include "z_zone.h"
|
||||
#include "r_things.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
|
||||
boolean portalskipprecipmobjs = false;
|
||||
|
||||
// Linked list for portals.
|
||||
portal_t *portal_base, *portal_cap;
|
||||
|
||||
line_t *portalclipline;
|
||||
sector_t *portalcullsector;
|
||||
INT32 portalclipstart, portalclipend;
|
||||
|
||||
portal_t *g_portal; // is curline a portal seg?
|
||||
|
||||
void Portal_InitList (void)
|
||||
{
|
||||
portalrender = 0;
|
||||
portal_base = portal_cap = NULL;
|
||||
}
|
||||
|
||||
/** Apply the clipping window from a portal.
|
||||
*/
|
||||
void Portal_ClipApply (const portal_t* portal)
|
||||
{
|
||||
INT32 i;
|
||||
INT32 start = portal->start;
|
||||
INT32 end = portal->end;
|
||||
INT16 *ceil = portal->ceilingclip;
|
||||
INT16 *floor = portal->floorclip;
|
||||
fixed_t *scale = portal->frontscale;
|
||||
|
||||
for (i = 0; i < end-start; i++)
|
||||
{
|
||||
ceilingclip[start+i] = *ceil;
|
||||
ceil++;
|
||||
floorclip[start+i] = *floor;
|
||||
floor++;
|
||||
frontscale[start+i] = *scale;
|
||||
scale++;
|
||||
}
|
||||
|
||||
// HACKS FOLLOW
|
||||
for (i = 0; i < start; i++)
|
||||
{
|
||||
floorclip[i] = -1;
|
||||
ceilingclip[i] = (INT16)viewheight;
|
||||
}
|
||||
for (i = end; i < vid.width; i++)
|
||||
{
|
||||
floorclip[i] = -1;
|
||||
ceilingclip[i] = (INT16)viewheight;
|
||||
}
|
||||
}
|
||||
|
||||
static portal_t* Portal_Add (const INT16 x1, const INT16 x2)
|
||||
{
|
||||
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
|
||||
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
|
||||
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
|
||||
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
|
||||
|
||||
// Linked list.
|
||||
if (!portal_base)
|
||||
{
|
||||
portal_base = portal;
|
||||
portal_cap = portal;
|
||||
}
|
||||
else
|
||||
{
|
||||
portal_cap->next = portal;
|
||||
portal_cap = portal;
|
||||
}
|
||||
portal->next = NULL;
|
||||
|
||||
// Store clipping values so they can be restored once the portal is rendered.
|
||||
portal->ceilingclip = ceilingclipsave;
|
||||
portal->floorclip = floorclipsave;
|
||||
portal->frontscale = frontscalesave;
|
||||
portal->start = x1;
|
||||
portal->end = x2;
|
||||
|
||||
// Increase recursion level.
|
||||
portal->pass = portalrender+1;
|
||||
|
||||
portal->isskybox = false;
|
||||
|
||||
return portal;
|
||||
}
|
||||
|
||||
void Portal_Remove (portal_t* portal)
|
||||
{
|
||||
portalcullsector = NULL;
|
||||
portal_base = portal->next;
|
||||
Z_Free(portal->ceilingclip);
|
||||
Z_Free(portal->floorclip);
|
||||
Z_Free(portal->frontscale);
|
||||
Z_Free(portal);
|
||||
}
|
||||
|
||||
/** Creates a portal out of two lines and a determined screen range.
|
||||
*
|
||||
* line1 determines the entrance, and line2 the exit.
|
||||
* x1 and x2 determine the screen's column bounds.
|
||||
|
||||
* The view's offset from the entry line center is obtained,
|
||||
* and then rotated&translated to the exit line's center.
|
||||
* When the portal renders, it will create the illusion of
|
||||
* the two lines being seamed together.
|
||||
*/
|
||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2)
|
||||
{
|
||||
portal_t* portal = Portal_Add(x1, x2);
|
||||
|
||||
// Offset the portal view by the linedef centers
|
||||
line_t* start = &lines[line1];
|
||||
line_t* dest = &lines[line2];
|
||||
|
||||
angle_t dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
|
||||
|
||||
fixed_t disttopoint;
|
||||
angle_t angtopoint;
|
||||
|
||||
vertex_t dest_c, start_c;
|
||||
|
||||
// looking glass center
|
||||
start_c.x = (start->v1->x + start->v2->x) / 2;
|
||||
start_c.y = (start->v1->y + start->v2->y) / 2;
|
||||
|
||||
// other side center
|
||||
dest_c.x = (dest->v1->x + dest->v2->x) / 2;
|
||||
dest_c.y = (dest->v1->y + dest->v2->y) / 2;
|
||||
|
||||
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
|
||||
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
|
||||
angtopoint += dangle;
|
||||
|
||||
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
|
||||
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
|
||||
portal->viewangle = viewangle + dangle;
|
||||
|
||||
portal->clipline = line2;
|
||||
|
||||
g_portal = portal; // this tells R_StoreWallRange that curline is a portal seg
|
||||
}
|
||||
|
||||
/** Store the clipping window for a portal using a visplane.
|
||||
*
|
||||
* Since visplanes top/bottom windows work in an identical way,
|
||||
* it can just be copied almost directly.
|
||||
*/
|
||||
static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal)
|
||||
{
|
||||
INT16 start = portal->start;
|
||||
INT16 end = portal->end;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < end - start; i++)
|
||||
{
|
||||
// Invalid column.
|
||||
if (plane->top[i + start] == 65535)
|
||||
{
|
||||
portal->ceilingclip[i] = -1;
|
||||
portal->floorclip[i] = -1;
|
||||
continue;
|
||||
}
|
||||
portal->ceilingclip[i] = plane->top[i + start] - 1;
|
||||
portal->floorclip[i] = plane->bottom[i + start] + 1;
|
||||
portal->frontscale[i] = INT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
extern INT32 viewwidth;
|
||||
|
||||
static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16* end)
|
||||
{
|
||||
*start = plane->minx;
|
||||
*end = plane->maxx + 1;
|
||||
|
||||
// Visplanes have 1-px pads on their sides (extra columns).
|
||||
// Trim them, else it may render out of bounds.
|
||||
if (*end > viewwidth)
|
||||
*end = viewwidth;
|
||||
|
||||
if (!(*start < *end))
|
||||
return true;
|
||||
|
||||
|
||||
/** Trims a visplane's horizontal gap to match its render area.
|
||||
*
|
||||
* Visplanes' minx/maxx may sometimes exceed the area they're
|
||||
* covering. This merely adjusts the boundaries to the next
|
||||
* valid area.
|
||||
*/
|
||||
|
||||
while (plane->bottom[*start] == 0 && plane->top[*start] == 65535 && *start < *end)
|
||||
{
|
||||
(*start)++;
|
||||
}
|
||||
|
||||
|
||||
while (plane->bottom[*end - 1] == 0 && plane->top[*start] == 65535 && *end > *start)
|
||||
{
|
||||
(*end)--;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Creates a skybox portal out of a visplane.
|
||||
*
|
||||
* Applies the necessary offsets and rotation to give
|
||||
* a depth illusion to the skybox.
|
||||
*/
|
||||
static void Portal_AddSkybox (const visplane_t* plane)
|
||||
{
|
||||
INT16 start, end;
|
||||
mapheader_t *mh;
|
||||
portal_t* portal;
|
||||
|
||||
if (TrimVisplaneBounds(plane, &start, &end))
|
||||
return;
|
||||
|
||||
portal = Portal_Add(start, end);
|
||||
|
||||
Portal_ClipVisplane(plane, portal);
|
||||
|
||||
portal->viewx = skyboxmo[0]->x;
|
||||
portal->viewy = skyboxmo[0]->y;
|
||||
portal->viewz = 0;
|
||||
if (skyboxmo[0]->spawnpoint)
|
||||
portal->viewz = ((fixed_t)skyboxmo[0]->spawnpoint->angle)<<FRACBITS;
|
||||
portal->viewangle = viewangle + skyboxmo[0]->angle;
|
||||
|
||||
mh = mapheaderinfo[gamemap-1];
|
||||
|
||||
// If a relative viewpoint exists, offset the viewpoint.
|
||||
if (skyboxmo[1])
|
||||
{
|
||||
fixed_t x = 0, y = 0;
|
||||
angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT;
|
||||
|
||||
if (mh->skybox_scalex > 0)
|
||||
x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex;
|
||||
else if (mh->skybox_scalex < 0)
|
||||
x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex;
|
||||
|
||||
if (mh->skybox_scaley > 0)
|
||||
y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley;
|
||||
else if (mh->skybox_scaley < 0)
|
||||
y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley;
|
||||
|
||||
// Apply transform to account for the skybox viewport angle.
|
||||
portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang));
|
||||
portal->viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang));
|
||||
}
|
||||
|
||||
if (mh->skybox_scalez > 0)
|
||||
portal->viewz += viewz / mh->skybox_scalez;
|
||||
else if (mh->skybox_scalez < 0)
|
||||
portal->viewz += viewz * -mh->skybox_scalez;
|
||||
|
||||
portal->clipline = -1;
|
||||
portal->isskybox = true;
|
||||
}
|
||||
|
||||
/** Creates portals for the currently existing sky visplanes.
|
||||
* The visplanes are also removed and cleared from the list.
|
||||
*/
|
||||
void Portal_AddSkyboxPortals (void)
|
||||
{
|
||||
visplane_t *pl;
|
||||
INT32 i;
|
||||
UINT16 count = 0;
|
||||
|
||||
for (i = 0; i < MAXVISPLANES; i++, pl++)
|
||||
{
|
||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||
{
|
||||
//if (pl->minx >= pl->maxx)
|
||||
//continue;
|
||||
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
Portal_AddSkybox(pl);
|
||||
|
||||
pl->minx = 0;
|
||||
pl->maxx = -1;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//CONS_Debug(DBG_RENDER, "Skybox portals: %d\n", count);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2018 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_portal.h
|
||||
/// \brief Software renderer portal struct, functions, linked list extern.
|
||||
|
||||
#ifndef __R_PORTAL__
|
||||
#define __R_PORTAL__
|
||||
|
||||
#include "r_data.h"
|
||||
#include "r_plane.h" // visplanes
|
||||
|
||||
/*
|
||||
* Portal structure for the software renderer.
|
||||
*/
|
||||
typedef struct portal_s
|
||||
{
|
||||
struct portal_s *next;
|
||||
|
||||
// Viewport.
|
||||
fixed_t viewx;
|
||||
fixed_t viewy;
|
||||
fixed_t viewz;
|
||||
angle_t viewangle;
|
||||
|
||||
UINT8 pass; /**< Keeps track of the portal's recursion depth. */
|
||||
boolean isskybox;
|
||||
INT32 clipline; /**< Optional clipline for line-based portals. */
|
||||
|
||||
// Clipping information.
|
||||
INT32 start; /**< First horizontal pixel coordinate to draw at. */
|
||||
INT32 end; /**< Last horizontal pixel coordinate to draw at. */
|
||||
INT16 *ceilingclip; /**< Temporary screen top clipping array. */
|
||||
INT16 *floorclip; /**< Temporary screen bottom clipping array. */
|
||||
fixed_t *frontscale;/**< Temporary screen bottom clipping array. */
|
||||
} portal_t;
|
||||
|
||||
extern portal_t* portal_base;
|
||||
extern portal_t* portal_cap;
|
||||
extern UINT8 portalrender;
|
||||
extern boolean portalskipprecipmobjs;
|
||||
|
||||
extern line_t *portalclipline;
|
||||
extern sector_t *portalcullsector;
|
||||
extern INT32 portalclipstart, portalclipend;
|
||||
|
||||
void Portal_InitList (void);
|
||||
void Portal_Remove (portal_t* portal);
|
||||
void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2);
|
||||
|
||||
void Portal_ClipRange (portal_t* portal);
|
||||
void Portal_ClipApply (const portal_t* portal);
|
||||
|
||||
void Portal_AddSkyboxPortals (void);
|
||||
|
||||
#endif
|
||||
+19
-5
@@ -15,6 +15,7 @@
|
||||
#include "r_local.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
#include "r_portal.h"
|
||||
#include "r_splats.h"
|
||||
|
||||
#include "w_wad.h"
|
||||
@@ -275,6 +276,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
|
||||
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
dc_sourcelength = 0;
|
||||
|
||||
if (colfunc == wallcolfunc)
|
||||
twosmultipatchfunc();
|
||||
@@ -1446,6 +1448,7 @@ static void R_RenderSegLoop (void)
|
||||
dc_texturemid = rw_midtexturemid;
|
||||
dc_source = R_GetColumn(midtexture,texturecolumn);
|
||||
dc_texheight = textureheight[midtexture]>>FRACBITS;
|
||||
dc_sourcelength = 0;
|
||||
colfunc();
|
||||
|
||||
// dont draw anything more for this column, since
|
||||
@@ -1493,6 +1496,7 @@ static void R_RenderSegLoop (void)
|
||||
dc_texturemid = rw_toptexturemid;
|
||||
dc_source = R_GetColumn(toptexture,texturecolumn);
|
||||
dc_texheight = textureheight[toptexture]>>FRACBITS;
|
||||
dc_sourcelength = 0;
|
||||
colfunc();
|
||||
ceilingclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
@@ -1530,6 +1534,7 @@ static void R_RenderSegLoop (void)
|
||||
dc_source = R_GetColumn(bottomtexture,
|
||||
texturecolumn);
|
||||
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
|
||||
dc_sourcelength = 0;
|
||||
colfunc();
|
||||
floorclip[rw_x] = (INT16)mid;
|
||||
}
|
||||
@@ -1605,6 +1610,12 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
|
||||
}
|
||||
}
|
||||
|
||||
static inline INT32 get_flat_tex (INT32 texnum)
|
||||
{
|
||||
texnum = R_GetTextureNum(texnum);
|
||||
return textures[texnum]->holes ? 0 : texnum; // R_DrawWallColumn cannot render holey textures
|
||||
}
|
||||
|
||||
//
|
||||
// R_StoreWallRange
|
||||
// A wall segment will be drawn
|
||||
@@ -1632,6 +1643,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
|
||||
if (ds_p == drawsegs+maxdrawsegs)
|
||||
{
|
||||
size_t curpos = curdrawsegs - drawsegs;
|
||||
size_t pos = ds_p - drawsegs;
|
||||
size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128;
|
||||
if (firstseg)
|
||||
@@ -1639,6 +1651,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL);
|
||||
ds_p = drawsegs + pos;
|
||||
maxdrawsegs = newmax;
|
||||
curdrawsegs = drawsegs + curpos;
|
||||
if (firstseg)
|
||||
firstseg = drawsegs + (size_t)firstseg;
|
||||
}
|
||||
@@ -1691,6 +1704,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
// borrowed fix from *cough* zdoom *cough*
|
||||
// [RH] We also need to adjust the openings pointers that
|
||||
// were already stored in drawsegs.
|
||||
//for (ds = curdrawsegs; ds < ds_p; ds++)
|
||||
for (ds = drawsegs; ds < ds_p; ds++)
|
||||
{
|
||||
#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings;
|
||||
@@ -1862,7 +1876,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
{
|
||||
fixed_t texheight;
|
||||
// single sided line
|
||||
midtexture = R_GetTextureNum(sidedef->midtexture);
|
||||
midtexture = get_flat_tex(sidedef->midtexture);
|
||||
texheight = textureheight[midtexture];
|
||||
// a single sided line is terminal, so it must mark ends
|
||||
markfloor = markceiling = true;
|
||||
@@ -2045,15 +2059,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
{
|
||||
// Special case... use offsets from 2nd side but only if it has a texture.
|
||||
side_t *def = &sides[linedef->sidenum[1]];
|
||||
toptexture = R_GetTextureNum(def->toptexture);
|
||||
toptexture = get_flat_tex(def->toptexture);
|
||||
|
||||
if (!toptexture) //Second side has no texture, use the first side's instead.
|
||||
toptexture = R_GetTextureNum(sidedef->toptexture);
|
||||
toptexture = get_flat_tex(sidedef->toptexture);
|
||||
texheight = textureheight[toptexture];
|
||||
}
|
||||
else
|
||||
{
|
||||
toptexture = R_GetTextureNum(sidedef->toptexture);
|
||||
toptexture = get_flat_tex(sidedef->toptexture);
|
||||
texheight = textureheight[toptexture];
|
||||
}
|
||||
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
|
||||
@@ -2078,7 +2092,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
if (worldlow > worldbottom || worldlowslope > worldbottomslope) // Only if VISIBLE!!!
|
||||
{
|
||||
// bottom texture
|
||||
bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
|
||||
bottomtexture = get_flat_tex(sidedef->bottomtexture);
|
||||
|
||||
if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
|
||||
@@ -90,14 +90,8 @@ extern side_t *sides;
|
||||
extern fixed_t viewx, viewy, viewz;
|
||||
extern angle_t viewangle, aimingangle, viewroll;
|
||||
extern UINT8 viewssnum; // splitscreen view number
|
||||
extern boolean viewsky, skyVisible;
|
||||
extern boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible of each splitscreen player
|
||||
extern sector_t *viewsector;
|
||||
extern player_t *viewplayer;
|
||||
extern UINT8 portalrender;
|
||||
extern sector_t *portalcullsector;
|
||||
extern line_t *portalclipline;
|
||||
extern INT32 portalclipstart, portalclipend;
|
||||
|
||||
extern consvar_t cv_allowmlook;
|
||||
extern consvar_t cv_maxportals;
|
||||
|
||||
+205
-135
@@ -25,6 +25,7 @@
|
||||
#include "r_things.h"
|
||||
#include "r_patch.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_portal.h"
|
||||
#include "p_tick.h"
|
||||
#include "p_local.h"
|
||||
#include "p_slopes.h"
|
||||
@@ -43,7 +44,7 @@ CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2];
|
||||
|
||||
static void R_InitSkins(void);
|
||||
|
||||
#define MINZ (FRACUNIT*4)
|
||||
#define MINZ (FRACUNIT*16)
|
||||
#define BASEYCENTER (BASEVIDHEIGHT/2)
|
||||
|
||||
typedef struct
|
||||
@@ -522,7 +523,7 @@ void R_InitSprites(void)
|
||||
|
||||
// it can be is do before loading config for skin cvar possible value
|
||||
R_InitSkins();
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
for (i = 0; i < numwadfiles; i++)
|
||||
{
|
||||
R_AddSkins((UINT16)i, false);
|
||||
R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps);
|
||||
@@ -583,6 +584,9 @@ void R_DrawMaskedColumn(column_t *column)
|
||||
|
||||
basetexturemid = dc_texturemid;
|
||||
|
||||
if (!column || column == 0)
|
||||
return;
|
||||
|
||||
for (; column->topdelta != 0xff ;)
|
||||
{
|
||||
// calculate unclipped screen coordinates
|
||||
@@ -618,6 +622,7 @@ void R_DrawMaskedColumn(column_t *column)
|
||||
if (dc_yl <= dc_yh && dc_yh > 0 && column->length != 0)
|
||||
{
|
||||
dc_source = (UINT8 *)column + 3;
|
||||
dc_sourcelength = column->length;
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
|
||||
// Drawn by R_DrawColumn.
|
||||
@@ -682,6 +687,7 @@ static void R_DrawFlippedMaskedColumn(column_t *column)
|
||||
if (dc_yl <= dc_yh && dc_yh > 0 && column->length != 0)
|
||||
{
|
||||
dc_source = ZZ_Alloc(column->length);
|
||||
dc_sourcelength = column->length;
|
||||
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
|
||||
*d++ = *s;
|
||||
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
|
||||
@@ -727,7 +733,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto
|
||||
}
|
||||
|
||||
|
||||
// TODO This check should not be necessary. But Papersprites near to the camera will sometimes create invalid values
|
||||
// for the vissprite's startfrac. This happens because they are not depth culled like other sprites.
|
||||
// Someone who is more familiar with papersprites pls check and try to fix <3
|
||||
@@ -799,7 +805,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||
dc_colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
dc_texturemid = vis->texturemid;
|
||||
dc_texheight = 0;
|
||||
dc_texheight = SHORT(patch->height);
|
||||
|
||||
frac = vis->startfrac;
|
||||
windowtop = windowbottom = sprbotscreen = INT32_MAX;
|
||||
@@ -808,8 +814,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->localskin)->highresscale);
|
||||
else if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES)
|
||||
this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale);
|
||||
|
||||
if (this_scale <= 0)
|
||||
this_scale = 1;
|
||||
|
||||
if (this_scale != FRACUNIT)
|
||||
{
|
||||
if (!vis->isScaled)
|
||||
@@ -875,12 +883,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||
}
|
||||
else
|
||||
{
|
||||
pwidth = SHORT(patch->width);
|
||||
|
||||
// Non-paper drawing loop
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
{
|
||||
texturecolumn = CLAMP(frac >> FRACBITS, 0, pwidth - 1);
|
||||
{
|
||||
texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1);
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
|
||||
localcolfunc (column);
|
||||
@@ -926,7 +932,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
||||
|
||||
dc_iscale = FixedDiv(FRACUNIT, vis->scale);
|
||||
dc_texturemid = FixedDiv(vis->texturemid, this_scale);
|
||||
dc_texheight = 0;
|
||||
dc_texheight = SHORT(patch->height);
|
||||
|
||||
frac = vis->startfrac;
|
||||
spryscale = vis->scale;
|
||||
@@ -941,7 +947,14 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
||||
|
||||
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
|
||||
{
|
||||
texturecolumn = CLAMP(frac >> FRACBITS, 0, SHORT(patch->width) - 1);
|
||||
texturecolumn = frac>>FRACBITS;
|
||||
|
||||
if (texturecolumn < 0 || texturecolumn >= patch->width)
|
||||
{
|
||||
CONS_Debug(DBG_RENDER, "R_DrawPrecipitationSpriteRange: bad texturecolumn\n");
|
||||
break;
|
||||
}
|
||||
|
||||
column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn]));
|
||||
|
||||
R_DrawMaskedColumn(column);
|
||||
@@ -1154,7 +1167,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
angle_t pitchnroll = 0;
|
||||
angle_t sliptiderollangle = 0;
|
||||
#endif
|
||||
|
||||
|
||||
INT32 dist = -1;
|
||||
|
||||
if (cv_grmaxinterpdist.value)
|
||||
@@ -1256,7 +1269,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
{
|
||||
ang = R_PointToAngle (interp.x, interp.y) - interp.angle;
|
||||
camang = R_PointToAngle (interp.x, interp.y);
|
||||
|
||||
|
||||
if (mirrored)
|
||||
ang = InvAngle(ang);
|
||||
}
|
||||
@@ -1273,9 +1286,9 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
// choose a different rotation based on player view
|
||||
//ang = R_PointToAngle (interp.x, interp.y) - interpangle;
|
||||
|
||||
if ((ang < ANGLE_180) && (sprframe->rotate & SRF_RIGHT)) // See from right
|
||||
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
|
||||
rot = 6; // F7 slot
|
||||
else if ((ang >= ANGLE_180) && (sprframe->rotate & SRF_LEFT)) // See from left
|
||||
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
|
||||
rot = 2; // F3 slot
|
||||
else // Normal behaviour
|
||||
rot = (ang+ANGLE_202h)>>29;
|
||||
@@ -1286,7 +1299,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
}
|
||||
|
||||
I_Assert(lump < max_spritelumps);
|
||||
|
||||
|
||||
if (thing->localskin && ((skin_t *)thing->localskin)->flags & SF_HIRES)
|
||||
this_scale = FixedMul(this_scale, ((skin_t *)thing->localskin)->highresscale);
|
||||
else if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
|
||||
@@ -1299,7 +1312,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
|
||||
#ifdef ROTSPRITE
|
||||
pitchnroll = 0; // set this to 0, non-paper sprites will affect this value
|
||||
|
||||
|
||||
if (cv_spriteroll.value)
|
||||
{
|
||||
if (papersprite)
|
||||
@@ -1345,10 +1358,10 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
|
||||
if (rotsprite != NULL)
|
||||
{
|
||||
spr_width = rotsprite->width << FRACBITS;
|
||||
spr_height = rotsprite->height << FRACBITS;
|
||||
spr_offset = rotsprite->leftoffset << FRACBITS;
|
||||
spr_topoffset = rotsprite->topoffset << FRACBITS;
|
||||
spr_width = SHORT(rotsprite->width) << FRACBITS;
|
||||
spr_height = SHORT(rotsprite->height) << FRACBITS;
|
||||
spr_offset = SHORT(rotsprite->leftoffset) << FRACBITS;
|
||||
spr_topoffset = SHORT(rotsprite->topoffset) << FRACBITS;
|
||||
spr_topoffset += FEETADJUST;
|
||||
|
||||
// flip -> rotate, not rotate -> flip
|
||||
@@ -1366,21 +1379,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
if (spritexscale < 1 || spriteyscale < 1)
|
||||
return;
|
||||
|
||||
if (thing->renderflags & RF_ABSOLUTEOFFSETS)
|
||||
{
|
||||
spr_offset = interp.spritexoffset;
|
||||
spr_topoffset = interp.spriteyoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
SINT8 flipoffset = 1;
|
||||
|
||||
if ((thing->renderflags & RF_FLIPOFFSETS) && flip)
|
||||
flipoffset = -1;
|
||||
|
||||
spr_offset += interp.spritexoffset * flipoffset;
|
||||
spr_topoffset += interp.spriteyoffset * flipoffset;
|
||||
}
|
||||
spr_offset += interp.spritexoffset;
|
||||
spr_topoffset += interp.spriteyoffset;
|
||||
|
||||
if (flip)
|
||||
offset = spr_offset - spr_width;
|
||||
@@ -1457,7 +1457,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
tx2 += FixedDiv(tx-tx2, div);
|
||||
tz2 = FixedMul(MINZ, this_scale);
|
||||
}
|
||||
|
||||
|
||||
if ((tx2 / 4) < -(FixedMul(tz2, fovtan)) || (tx / 4) > FixedMul(tz, fovtan)) // too far off the side?
|
||||
return;
|
||||
|
||||
@@ -1485,7 +1485,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
return;
|
||||
|
||||
range++; // fencepost problem
|
||||
|
||||
|
||||
if (range > 32767)
|
||||
{
|
||||
// If the range happens to be too large for fixed_t,
|
||||
@@ -1528,7 +1528,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
// PORTAL SPRITE CLIPPING
|
||||
if (portalrender && portalclipline)
|
||||
{
|
||||
if (x2 < portalclipstart || x1 > portalclipend)
|
||||
if (x2 < portalclipstart || x1 >= portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
|
||||
@@ -1600,7 +1600,6 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
|
||||
// store information in a vissprite
|
||||
vis = R_NewVisSprite();
|
||||
vis->renderflags = thing->renderflags;
|
||||
vis->heightsec = heightsec; //SoM: 3/17/2000
|
||||
vis->mobjflags = thing->flags;
|
||||
vis->scale = yscale; //<<detailshift;
|
||||
@@ -1621,17 +1620,8 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
|
||||
vis->mobj = thing; // Easy access! Tails 06-07-2002
|
||||
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
||||
|
||||
// PORTAL SEMI-CLIPPING
|
||||
if (portalrender && portalclipline)
|
||||
{
|
||||
if (vis->x1 < portalclipstart)
|
||||
vis->x1 = portalclipstart;
|
||||
if (vis->x2 > portalclipend)
|
||||
vis->x2 = portalclipend;
|
||||
}
|
||||
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
|
||||
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
||||
|
||||
vis->sector = thing->subsector->sector;
|
||||
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS);
|
||||
@@ -1841,7 +1831,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||
// PORTAL SPRITE CLIPPING
|
||||
if (portalrender && portalclipline)
|
||||
{
|
||||
if (x2 < portalclipstart || x1 > portalclipend)
|
||||
if (x2 < portalclipstart || x1 >= portalclipend)
|
||||
return;
|
||||
|
||||
if (P_PointOnLineSide(interp.x, interp.y, portalclipline) != 0)
|
||||
@@ -1875,17 +1865,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||
vis->scalestep = 0;
|
||||
vis->paperdistance = 0;
|
||||
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
||||
|
||||
// PORTAL SEMI-CLIPPING
|
||||
if (portalrender && portalclipline)
|
||||
{
|
||||
if (vis->x1 < portalclipstart)
|
||||
vis->x1 = portalclipstart;
|
||||
if (vis->x2 > portalclipend)
|
||||
vis->x2 = portalclipend;
|
||||
}
|
||||
vis->x1 = x1 < portalclipstart ? portalclipstart : x1;
|
||||
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
||||
|
||||
vis->xscale = xscale; //SoM: 4/17/2000
|
||||
vis->sector = thing->subsector->sector;
|
||||
@@ -1990,6 +1971,12 @@ void R_AddPrecipitationSprites(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// do not render in skybox
|
||||
if (portalskipprecipmobjs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
R_GetRenderBlockMapDimensions(drawdist, &xl, &xh, &yl, &yh);
|
||||
|
||||
for (bx = xl; bx <= xh; bx++)
|
||||
@@ -2013,46 +2000,47 @@ void R_AddPrecipitationSprites(void)
|
||||
//
|
||||
// R_SortVisSprites
|
||||
//
|
||||
static vissprite_t vsprsortedhead;
|
||||
|
||||
void R_SortVisSprites(void)
|
||||
static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 end)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT32 i, count = 0;
|
||||
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
||||
vissprite_t *best = NULL;
|
||||
vissprite_t unsorted;
|
||||
fixed_t bestscale;
|
||||
INT32 bestdispoffset;
|
||||
|
||||
if (!visspritecount)
|
||||
return;
|
||||
dsfirst = &unsorted;
|
||||
dsprev = dsfirst;
|
||||
dsnext = dsfirst;
|
||||
|
||||
unsorted.next = unsorted.prev = &unsorted;
|
||||
I_Assert(start <= end);
|
||||
|
||||
dsfirst = R_GetVisSprite(0);
|
||||
|
||||
// The first's prev and last's next will be set to
|
||||
// nonsense, but are fixed in a moment
|
||||
for (i = 0, dsnext = dsfirst, ds = NULL; i < visspritecount; i++)
|
||||
for (i = start; i < end; ++i)
|
||||
{
|
||||
dsprev = ds;
|
||||
ds = dsnext;
|
||||
if (i < visspritecount - 1) dsnext = R_GetVisSprite(i + 1);
|
||||
ds = R_GetVisSprite(i);
|
||||
|
||||
ds->next = dsnext;
|
||||
ds->prev = dsprev;
|
||||
// Do not include this sprite, since it is completely obscured
|
||||
if (ds->cut & SC_NOTVISIBLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dsnext = ds;
|
||||
|
||||
dsprev->next = dsnext;
|
||||
dsnext->prev = dsprev;
|
||||
dsprev = dsnext;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// Fix first and last. ds still points to the last one after the loop
|
||||
dsfirst->prev = &unsorted;
|
||||
unsorted.next = dsfirst;
|
||||
if (ds)
|
||||
ds->next = &unsorted;
|
||||
unsorted.prev = ds;
|
||||
dsnext->next = dsfirst;
|
||||
dsfirst->prev = dsnext;
|
||||
|
||||
// pull the vissprites out by scale
|
||||
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
|
||||
for (i = 0; i < visspritecount; i++)
|
||||
vsprsortedhead->next = vsprsortedhead->prev = vsprsortedhead;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
bestscale = bestdispoffset = INT32_MAX;
|
||||
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
|
||||
@@ -2078,15 +2066,12 @@ void R_SortVisSprites(void)
|
||||
best = ds;
|
||||
}
|
||||
}
|
||||
if (best)
|
||||
{
|
||||
best->next->prev = best->prev;
|
||||
best->prev->next = best->next;
|
||||
best->next = &vsprsortedhead;
|
||||
best->prev = vsprsortedhead.prev;
|
||||
vsprsortedhead.prev->next = best;
|
||||
vsprsortedhead.prev = best;
|
||||
}
|
||||
best->next->prev = best->prev;
|
||||
best->prev->next = best->next;
|
||||
best->next = vsprsortedhead;
|
||||
best->prev = vsprsortedhead->prev;
|
||||
vsprsortedhead->prev->next = best;
|
||||
vsprsortedhead->prev = best;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2096,28 +2081,28 @@ void R_SortVisSprites(void)
|
||||
static drawnode_t *R_CreateDrawNode(drawnode_t *link);
|
||||
|
||||
static drawnode_t nodebankhead;
|
||||
static drawnode_t nodehead;
|
||||
|
||||
static void R_CreateDrawNodes(void)
|
||||
static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean tempskip)
|
||||
{
|
||||
drawnode_t *entry;
|
||||
drawseg_t *ds;
|
||||
INT32 i, p, best, x1, x2;
|
||||
fixed_t bestdelta, delta;
|
||||
vissprite_t *rover;
|
||||
static vissprite_t vsprsortedhead;
|
||||
drawnode_t *r2;
|
||||
visplane_t *plane;
|
||||
INT32 sintersect;
|
||||
fixed_t scale = 0;
|
||||
|
||||
// Add the 3D floors, thicksides, and masked textures...
|
||||
for (ds = ds_p; ds-- > drawsegs ;)
|
||||
for (ds = drawsegs + mask->drawsegs[1]; ds-- > drawsegs + mask->drawsegs[0];)
|
||||
{
|
||||
if (ds->numthicksides)
|
||||
{
|
||||
for (i = 0; i < ds->numthicksides; i++)
|
||||
{
|
||||
entry = R_CreateDrawNode(&nodehead);
|
||||
entry = R_CreateDrawNode(head);
|
||||
entry->thickseg = ds;
|
||||
entry->ffloor = ds->thicksides[i];
|
||||
}
|
||||
@@ -2133,7 +2118,7 @@ static void R_CreateDrawNodes(void)
|
||||
else
|
||||
{
|
||||
// Put it in!
|
||||
entry = R_CreateDrawNode(&nodehead);
|
||||
entry = R_CreateDrawNode(head);
|
||||
entry->plane = plane;
|
||||
entry->seg = ds;
|
||||
}
|
||||
@@ -2141,7 +2126,7 @@ static void R_CreateDrawNodes(void)
|
||||
}
|
||||
if (ds->maskedtexturecol)
|
||||
{
|
||||
entry = R_CreateDrawNode(&nodehead);
|
||||
entry = R_CreateDrawNode(head);
|
||||
entry->seg = ds;
|
||||
}
|
||||
if (ds->numffloorplanes)
|
||||
@@ -2173,7 +2158,7 @@ static void R_CreateDrawNodes(void)
|
||||
}
|
||||
if (best != -1)
|
||||
{
|
||||
entry = R_CreateDrawNode(&nodehead);
|
||||
entry = R_CreateDrawNode(head);
|
||||
entry->plane = ds->ffloorplanes[best];
|
||||
entry->seg = ds;
|
||||
ds->ffloorplanes[best] = NULL;
|
||||
@@ -2184,6 +2169,9 @@ static void R_CreateDrawNodes(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (tempskip)
|
||||
return;
|
||||
|
||||
// find all the remaining polyobject planes and add them on the end of the list
|
||||
// probably this is a terrible idea if we wanted them to be sorted properly
|
||||
// but it works getting them in for now
|
||||
@@ -2199,16 +2187,18 @@ static void R_CreateDrawNodes(void)
|
||||
PolyObjects[i].visplane = NULL;
|
||||
continue;
|
||||
}
|
||||
entry = R_CreateDrawNode(&nodehead);
|
||||
entry = R_CreateDrawNode(head);
|
||||
entry->plane = plane;
|
||||
// note: no seg is set, for what should be obvious reasons
|
||||
PolyObjects[i].visplane = NULL;
|
||||
}
|
||||
|
||||
if (visspritecount == 0)
|
||||
// No vissprites in this mask?
|
||||
if (mask->vissprites[1] - mask->vissprites[0] == 0)
|
||||
return;
|
||||
|
||||
R_SortVisSprites();
|
||||
R_SortVisSprites(&vsprsortedhead, mask->vissprites[0], mask->vissprites[1]);
|
||||
|
||||
for (rover = vsprsortedhead.prev; rover != &vsprsortedhead; rover = rover->prev)
|
||||
{
|
||||
if (rover->szt > vid.height || rover->sz < 0)
|
||||
@@ -2216,7 +2206,7 @@ static void R_CreateDrawNodes(void)
|
||||
|
||||
sintersect = (rover->x1 + rover->x2) / 2;
|
||||
|
||||
for (r2 = nodehead.next; r2 != &nodehead; r2 = r2->next)
|
||||
for (r2 = head->next; r2 != head; r2 = r2->next)
|
||||
{
|
||||
if (r2->plane)
|
||||
{
|
||||
@@ -2355,9 +2345,9 @@ static void R_CreateDrawNodes(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r2 == &nodehead)
|
||||
if (r2 == head)
|
||||
{
|
||||
entry = R_CreateDrawNode(&nodehead);
|
||||
entry = R_CreateDrawNode(head);
|
||||
entry->sprite = rover;
|
||||
}
|
||||
}
|
||||
@@ -2389,7 +2379,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link)
|
||||
node->thickseg = NULL;
|
||||
node->ffloor = NULL;
|
||||
node->sprite = NULL;
|
||||
|
||||
|
||||
ps_numdrawnodes.value.i++;
|
||||
return node;
|
||||
}
|
||||
@@ -2401,25 +2391,24 @@ static void R_DoneWithNode(drawnode_t *node)
|
||||
(node->prev = &nodebankhead)->next = node;
|
||||
}
|
||||
|
||||
static void R_ClearDrawNodes(void)
|
||||
static void R_ClearDrawNodes(drawnode_t* head)
|
||||
{
|
||||
drawnode_t *rover;
|
||||
drawnode_t *next;
|
||||
|
||||
for (rover = nodehead.next; rover != &nodehead ;)
|
||||
for (rover = head->next; rover != head;)
|
||||
{
|
||||
next = rover->next;
|
||||
R_DoneWithNode(rover);
|
||||
rover = next;
|
||||
}
|
||||
|
||||
nodehead.next = nodehead.prev = &nodehead;
|
||||
head->next = head->prev = head;
|
||||
}
|
||||
|
||||
void R_InitDrawNodes(void)
|
||||
{
|
||||
nodebankhead.next = nodebankhead.prev = &nodebankhead;
|
||||
nodehead.next = nodehead.prev = &nodehead;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2483,7 +2472,7 @@ static boolean R_CheckSpriteVisible(vissprite_t *spr, INT32 x1, INT32 x2)
|
||||
|
||||
// R_ClipVisSprite
|
||||
// Clips vissprites without drawing, so that portals can work. -Red
|
||||
static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2)
|
||||
static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal)
|
||||
{
|
||||
drawseg_t *ds;
|
||||
INT32 x;
|
||||
@@ -2522,8 +2511,36 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2)
|
||||
|
||||
ds = curr->user;
|
||||
|
||||
if (ds->portalpass > 0 && ds->portalpass <= portalrender)
|
||||
continue; // is a portal
|
||||
if (ds->portalpass != 66) // unused?
|
||||
{
|
||||
if (ds->portalpass > 0 && ds->portalpass <= portalrender)
|
||||
continue; // is a portal
|
||||
|
||||
if (ds->scale1 > ds->scale2)
|
||||
{
|
||||
lowscale = ds->scale2;
|
||||
scale = ds->scale1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lowscale = ds->scale1;
|
||||
scale = ds->scale2;
|
||||
}
|
||||
|
||||
if (scale < spr->sortscale ||
|
||||
(lowscale < spr->sortscale &&
|
||||
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
|
||||
{
|
||||
// masked mid texture?
|
||||
/*
|
||||
if (ds->maskedtexturecol)
|
||||
R_RenderMaskedSegRange (ds, r1, r2);
|
||||
*/
|
||||
|
||||
// seg is behind sprite
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
|
||||
r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
|
||||
@@ -2666,7 +2683,7 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2)
|
||||
if (spr->cliptop[x] == -2)
|
||||
spr->cliptop[x] = -1;
|
||||
}
|
||||
|
||||
|
||||
// Check if it'll be visible
|
||||
// Not done for floorsprites.
|
||||
if (cv_spriteclip.value)
|
||||
@@ -2674,11 +2691,34 @@ static void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2)
|
||||
if (!R_CheckSpriteVisible(spr, x1, x2))
|
||||
spr->cut |= SC_NOTVISIBLE;
|
||||
}
|
||||
|
||||
if (portal)
|
||||
{
|
||||
INT32 start_index = max(portal->start, x1);
|
||||
INT32 end_index = min(portal->start + portal->end - portal->start, x2);
|
||||
for (x = x1; x < start_index; x++)
|
||||
{
|
||||
spr->clipbot[x] = -1;
|
||||
spr->cliptop[x] = -1;
|
||||
}
|
||||
for (x = start_index; x <= end_index; x++)
|
||||
{
|
||||
if (spr->clipbot[x] > portal->floorclip[x - portal->start])
|
||||
spr->clipbot[x] = portal->floorclip[x - portal->start];
|
||||
if (spr->cliptop[x] < portal->ceilingclip[x - portal->start])
|
||||
spr->cliptop[x] = portal->ceilingclip[x - portal->start];
|
||||
}
|
||||
for (x = end_index + 1; x <= x2; x++)
|
||||
{
|
||||
spr->clipbot[x] = -1;
|
||||
spr->cliptop[x] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_ClipSprites(void)
|
||||
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
|
||||
{
|
||||
const size_t maxdrawsegs = ds_p - drawsegs;
|
||||
const size_t maxdrawsegs = ds_p - dsstart;
|
||||
const INT32 cx = viewwidth / 2;
|
||||
drawseg_t* ds;
|
||||
INT32 i;
|
||||
@@ -2711,7 +2751,7 @@ void R_ClipSprites(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (ds = ds_p; ds-- > drawsegs;)
|
||||
for (ds = ds_p; ds-- > dsstart;)
|
||||
{
|
||||
if (ds->silhouette || ds->maskedtexturecol)
|
||||
{
|
||||
@@ -2741,7 +2781,7 @@ void R_ClipSprites(void)
|
||||
for (; clippedvissprites < visspritecount; clippedvissprites++)
|
||||
{
|
||||
vissprite_t *spr = R_GetVisSprite(clippedvissprites);
|
||||
|
||||
|
||||
if (cv_spriteclip.value
|
||||
&& (spr->szt > vid.height || spr->sz < 0))
|
||||
{
|
||||
@@ -2765,8 +2805,8 @@ void R_ClipSprites(void)
|
||||
drawsegs_xrange_count = drawsegs_xranges[0].count;
|
||||
}
|
||||
|
||||
R_ClipVisSprite(spr, spr->x1, spr->x2);
|
||||
|
||||
R_ClipVisSprite(spr, spr->x1, spr->x2, portal);
|
||||
|
||||
if ((spr->cut & SC_NOTVISIBLE) == 0)
|
||||
numvisiblesprites++;
|
||||
}
|
||||
@@ -2783,10 +2823,10 @@ boolean R_ThingVisible (mobj_t *thing)
|
||||
|
||||
if (splitscreen)
|
||||
{
|
||||
if ((viewssnum == 0 && (thing->renderflags & MFE_DRAWONLYFORP1))
|
||||
|| (viewssnum == 1 && (thing->renderflags & MFE_DRAWONLYFORP2))
|
||||
|| (viewssnum == 2 && (thing->renderflags & MFE_DRAWONLYFORP2))
|
||||
|| (viewssnum == 3 && (thing->renderflags & MFE_DRAWONLYFORP4)))
|
||||
if ((viewssnum == 0 && (thing->eflags & MFE_DRAWONLYFORP1))
|
||||
|| (viewssnum == 1 && (thing->eflags & MFE_DRAWONLYFORP2))
|
||||
|| (viewssnum == 2 && (thing->eflags & MFE_DRAWONLYFORP2))
|
||||
|| (viewssnum == 3 && (thing->eflags & MFE_DRAWONLYFORP4)))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2810,14 +2850,12 @@ boolean R_ThingWithinDist (mobj_t *thing, fixed_t limit_dist)
|
||||
//
|
||||
// R_DrawMasked
|
||||
//
|
||||
void R_DrawMasked(void)
|
||||
static void R_DrawMaskedList (drawnode_t* head)
|
||||
{
|
||||
drawnode_t *r2;
|
||||
drawnode_t *next;
|
||||
|
||||
R_CreateDrawNodes();
|
||||
|
||||
for (r2 = nodehead.next; r2 != &nodehead; r2 = r2->next)
|
||||
for (r2 = head->next; r2 != head; r2 = r2->next)
|
||||
{
|
||||
if (r2->plane)
|
||||
{
|
||||
@@ -2855,7 +2893,39 @@ void R_DrawMasked(void)
|
||||
r2 = next;
|
||||
}
|
||||
}
|
||||
R_ClearDrawNodes();
|
||||
}
|
||||
|
||||
void R_DrawMasked(maskcount_t* masks, INT32 nummasks)
|
||||
{
|
||||
drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */
|
||||
INT32 i;
|
||||
|
||||
heads = calloc(nummasks, sizeof(drawnode_t));
|
||||
|
||||
for (i = 0; i < nummasks; i++)
|
||||
{
|
||||
heads[i].next = heads[i].prev = &heads[i];
|
||||
|
||||
viewx = masks[i].viewx;
|
||||
viewy = masks[i].viewy;
|
||||
viewz = masks[i].viewz;
|
||||
viewsector = masks[i].viewsector;
|
||||
|
||||
R_CreateDrawNodes(&masks[i], &heads[i], false);
|
||||
}
|
||||
|
||||
for (; nummasks > 0; nummasks--)
|
||||
{
|
||||
viewx = masks[nummasks - 1].viewx;
|
||||
viewy = masks[nummasks - 1].viewy;
|
||||
viewz = masks[nummasks - 1].viewz;
|
||||
viewsector = masks[nummasks - 1].viewsector;
|
||||
|
||||
R_DrawMaskedList(&heads[nummasks - 1]);
|
||||
R_ClearDrawNodes(&heads[nummasks - 1]);
|
||||
}
|
||||
|
||||
free(heads);
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
@@ -3293,7 +3363,7 @@ static int skinSortFunc(const void *a, const void *b) //tbh i have no clue what
|
||||
void sortSkinGrid(void)
|
||||
{
|
||||
//CONS_Printf("Sorting skin list (%d)...\n", cv_skinselectgridsort.value);
|
||||
qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc);
|
||||
qs22j(skinsorted, numskins, sizeof(UINT8), skinSortFunc);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -3577,7 +3647,7 @@ next_token:
|
||||
Forceskin_cons_t[numskins+1].value = numskins;
|
||||
Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name;
|
||||
}
|
||||
|
||||
|
||||
skin->localskin = local;
|
||||
|
||||
// so we dont have to guess
|
||||
@@ -3604,7 +3674,7 @@ next_token:
|
||||
CONS_Debug(DBG_SETUP, M_GetText("Incremented %d, %d to %d\n"), skin->kartspeed, skin->kartweight, skinstatscount[skin->kartspeed - 1][skin->kartweight - 1]);
|
||||
skinsorted[numskins] = numskins;
|
||||
}
|
||||
|
||||
|
||||
allskins[numallskins] = ( (local) ? localskins : skins )[( (local) ? numlocalskins : numskins )];
|
||||
|
||||
local ? numlocalskins++ : numskins++;
|
||||
|
||||
+16
-3
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "sounds.h"
|
||||
#include "r_plane.h"
|
||||
#include "r_portal.h"
|
||||
#include "r_patch.h"
|
||||
|
||||
// "Left" and "Right" character symbols for additional rotation functionality
|
||||
@@ -55,11 +56,11 @@ extern fixed_t sprtopscreen;
|
||||
extern fixed_t sprbotscreen;
|
||||
extern fixed_t windowtop;
|
||||
extern fixed_t windowbottom;
|
||||
extern INT32 lengthcol;
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column);
|
||||
void R_SortVisSprites(void);
|
||||
|
||||
//faB: find sprites in wadfile, replace existing, add new ones
|
||||
// (only sprites from namelist are added or replaced)
|
||||
@@ -70,7 +71,19 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||
void R_AddPrecipitationSprites(void);
|
||||
void R_InitSprites(void);
|
||||
void R_ClearSprites(void);
|
||||
void R_DrawMasked(void);
|
||||
|
||||
/** Used to count the amount of masked elements
|
||||
* per portal to later group them in separate
|
||||
* drawnode lists.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
size_t drawsegs[2];
|
||||
size_t vissprites[2];
|
||||
fixed_t viewx, viewy, viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
|
||||
sector_t* viewsector;
|
||||
} maskcount_t;
|
||||
void R_DrawMasked(maskcount_t* masks, INT32 nummasks);
|
||||
|
||||
boolean R_ThingVisible (mobj_t *thing);
|
||||
boolean R_ThingWithinDist (mobj_t *thing, fixed_t limit_dist);
|
||||
@@ -192,7 +205,7 @@ typedef struct vissprite_s
|
||||
|
||||
extern UINT32 visspritecount, numvisiblesprites;
|
||||
|
||||
void R_ClipSprites(void);
|
||||
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
|
||||
|
||||
UINT8 *R_GetSpriteTranslation(vissprite_t *vis);
|
||||
|
||||
|
||||
+60
-59
@@ -1112,7 +1112,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
||||
|
||||
if (x >= vid.width || y >= vid.height)
|
||||
return; // off the screen
|
||||
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
w += x;
|
||||
@@ -1126,7 +1126,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
||||
|
||||
if (w <= 0 || h <= 0)
|
||||
return; // zero width/height wouldn't draw anything
|
||||
|
||||
|
||||
if (x + w > vid.width)
|
||||
w = vid.width-x;
|
||||
if (y + h > vid.height)
|
||||
@@ -1149,7 +1149,7 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
|
||||
}
|
||||
|
||||
c &= 255;
|
||||
|
||||
|
||||
if (alphalevel)
|
||||
{
|
||||
const UINT8 *fadetable = ((UINT8 *)transtables + ((alphalevel-1)<<FF_TRANSSHIFT) + (c*256));
|
||||
@@ -2495,7 +2495,7 @@ void V_DrawThinStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *str
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
charflags = (option & V_CHARCOLORMASK);
|
||||
colormap = V_GetStringColormap(charflags);
|
||||
|
||||
@@ -3189,7 +3189,7 @@ INT32 heatindex[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
|
||||
// Perform a particular image postprocessing function.
|
||||
//
|
||||
|
||||
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
||||
{
|
||||
#if NUMSCREENS < 5
|
||||
// do not enable image post processing for ARM, SH and MIPS CPUs
|
||||
@@ -3197,6 +3197,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
(void)type;
|
||||
(void)param;
|
||||
#else
|
||||
(void)param; // unused motion blur stuff
|
||||
INT32 yoffset, xoffset;
|
||||
|
||||
#ifdef HWRENDER
|
||||
@@ -3207,6 +3208,9 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
if (view < 0 || view > 3 || view > splitscreen)
|
||||
return;
|
||||
|
||||
if (!player->postimgflags)
|
||||
return;
|
||||
|
||||
if ((view == 1 && splitscreen == 1) || view >= 2)
|
||||
yoffset = viewheight;
|
||||
else
|
||||
@@ -3217,10 +3221,11 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
else
|
||||
xoffset = 0;
|
||||
|
||||
if (type == postimg_water)
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
|
||||
if (player->postimgflags & POSTIMG_WATER)
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y;
|
||||
// Set disStart to a range from 0 to FINEANGLE, incrementing by 128 per tic
|
||||
angle_t disStart = (((leveltime-1)*128) + (rendertimefrac / (FRACUNIT/128))) & FINEMASK;
|
||||
@@ -3257,29 +3262,30 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
}
|
||||
|
||||
/*
|
||||
Unoptimized version
|
||||
for (x = 0; x < vid.width*vid.bpp; x++)
|
||||
{
|
||||
newpix = (x + sine);
|
||||
Unoptimized version
|
||||
for (x = 0; x < vid.width*vid.bpp; x++)
|
||||
{
|
||||
newpix = (x + sine);
|
||||
|
||||
if (newpix < 0)
|
||||
newpix = 0;
|
||||
else if (newpix >= vid.width)
|
||||
newpix = vid.width-1;
|
||||
if (newpix < 0)
|
||||
newpix = 0;
|
||||
else if (newpix >= vid.width)
|
||||
newpix = vid.width-1;
|
||||
|
||||
tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]);
|
||||
}*/
|
||||
|
||||
tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]);
|
||||
}*/
|
||||
disStart += 22;//the offset into the displacement map, increment each game loop
|
||||
disStart &= FINEMASK; //clip it to FINEMASK
|
||||
}
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
UINT8 *tmp = tmpscr;
|
||||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
else if (type == postimg_motion) // Motion Blur!
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
|
||||
/*if (player->postimgflags & POSTIMG_MOTION) // Motion Blur!
|
||||
{
|
||||
INT32 x, y;
|
||||
|
||||
// TODO: Add a postimg_param so that we can pick the translucency level...
|
||||
@@ -3288,30 +3294,12 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
for (x = xoffset; x < xoffset+viewwidth; x++)
|
||||
{
|
||||
tmpscr[y*vid.width + x]
|
||||
= colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))];
|
||||
}
|
||||
tmpscr[y*vid.width + x] = colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))];
|
||||
}
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
else if (type == postimg_flip) // Flip the screen upside-down
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y, y2;
|
||||
}*/
|
||||
|
||||
for (y = yoffset, y2 = yoffset+viewheight - 1; y < yoffset+viewheight; y++, y2--)
|
||||
M_Memcpy(&tmpscr[(y2*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth);
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
}
|
||||
else if (type == postimg_heat) // Heat wave
|
||||
if (player->postimgflags & POSTIMG_HEAT) // Heat wave
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y;
|
||||
|
||||
// Make sure table is built
|
||||
@@ -3352,40 +3340,53 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
|
||||
heatindex[view] %= vid.height;
|
||||
}
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
UINT8 *tmp = tmpscr;
|
||||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
else if (type == postimg_mirror) // Flip the screen on the x axis
|
||||
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR)) // Flip the screen upside-down
|
||||
{
|
||||
INT32 y, y2;
|
||||
|
||||
for (y = yoffset, y2 = yoffset+viewheight - 1; y < yoffset+viewheight; y++, y2--)
|
||||
M_Memcpy(&tmpscr[(y2*vid.width)+xoffset], &srcscr[(y*vid.width)+xoffset], viewwidth);
|
||||
|
||||
UINT8 *tmp = tmpscr;
|
||||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
else if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP)) // Flip the screen on the x axis
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y, x, x2;
|
||||
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
for (x = xoffset, x2 = xoffset+((viewwidth*vid.bpp)-1); x < xoffset+(viewwidth*vid.bpp); x++, x2--)
|
||||
tmpscr[y*vid.width + x2] = srcscr[y*vid.width + x];
|
||||
}
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
UINT8 *tmp = tmpscr;
|
||||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
else if (type == postimg_mirrorflip) // Flip the screen upside-down and on the x axis
|
||||
else if ((player->postimgflags & POSTIMG_MIRROR) && (player->postimgflags & POSTIMG_FLIP)) // Flip the screen upside-down and on the x axis
|
||||
{
|
||||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
INT32 y, x;
|
||||
|
||||
for (y = yoffset; y < yoffset + viewheight; y++)
|
||||
for (x = xoffset; x < xoffset + viewwidth; x++)
|
||||
tmpscr[((yoffset + viewheight - 1 - y) * vid.width) + xoffset + viewwidth - (x - xoffset) - 1] = srcscr[(y * vid.width) + x];
|
||||
|
||||
VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
UINT8 *tmp = tmpscr;
|
||||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
|
||||
VID_BlitLinearScreen(srcscr+vid.width*vid.bpp*yoffset+xoffset, tmpscr+vid.width*vid.bpp*yoffset+xoffset,
|
||||
viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Taken from my videos-in-SRB2 project
|
||||
// Generates a color look-up table
|
||||
// which has up to 64 colors at each channel
|
||||
|
||||
+3
-1
@@ -251,7 +251,9 @@ INT32 V_SubStringLengthToFit(const char *string, INT32 width, INT32 option);
|
||||
|
||||
char V_GetSkincolorChar(INT32 color);
|
||||
|
||||
void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param);
|
||||
typedef struct player_s player_t;
|
||||
|
||||
void V_DoPostProcessor(INT32 view, player_t *player, INT32 param);
|
||||
|
||||
void V_DrawPatchFill(patch_t *pat);
|
||||
|
||||
|
||||
+219
@@ -2120,6 +2120,225 @@ int W_VerifyNMUSlumps(const char *filename)
|
||||
return W_VerifyFile(filename, NMUSlist, false);
|
||||
}
|
||||
|
||||
static int W_NameStartsWith(const char *name, lumpchecklist_t *checklist)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; checklist[j].len && checklist[j].name; ++j)
|
||||
{
|
||||
if (strncasecmp(name, checklist[j].name, checklist[j].len) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if file contains at least one lump which name starts with one of strings in checklist
|
||||
static int W_CheckWADContains(FILE *fp, lumpchecklist_t *checklist)
|
||||
{
|
||||
size_t i, j;
|
||||
// if we're here it's a WAD file
|
||||
wadinfo_t header;
|
||||
filelump_t lumpinfo;
|
||||
|
||||
// read the header
|
||||
if (fread(&header, 1, sizeof header, fp) == sizeof header
|
||||
&& header.numlumps < INT16_MAX
|
||||
&& strncmp(header.identification, "ZWAD", 4)
|
||||
&& strncmp(header.identification, "IWAD", 4)
|
||||
&& strncmp(header.identification, "PWAD", 4)
|
||||
&& strncmp(header.identification, "SDLL", 4))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
header.numlumps = LONG(header.numlumps);
|
||||
header.infotableofs = LONG(header.infotableofs);
|
||||
|
||||
// let seek to the lumpinfo list
|
||||
if (fseek(fp, header.infotableofs, SEEK_SET) == -1)
|
||||
return true;
|
||||
|
||||
for (i = 0; i < header.numlumps; i++)
|
||||
{
|
||||
// fill in lumpinfo for this wad file directory
|
||||
if (fread(&lumpinfo, sizeof (lumpinfo), 1 , fp) != 1)
|
||||
return -1;
|
||||
|
||||
lumpinfo.filepos = LONG(lumpinfo.filepos);
|
||||
lumpinfo.size = LONG(lumpinfo.size);
|
||||
|
||||
if (lumpinfo.size == 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < NUMSPRITES; j++)
|
||||
if (!strncmp(lumpinfo.name, sprnames[j], 4)) // Sprites
|
||||
continue;
|
||||
|
||||
if (W_NameStartsWith(lumpinfo.name, checklist))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int W_CheckPK3Contains(FILE *fp, lumpchecklist_t *checklist)
|
||||
{
|
||||
zend_t zend;
|
||||
zlentry_t zlentry;
|
||||
|
||||
long file_size;/* size of zip file */
|
||||
long data_size;/* size of data inside zip file */
|
||||
|
||||
UINT16 numlumps;
|
||||
size_t i;
|
||||
|
||||
char pat_central[] = {0x50, 0x4b, 0x01, 0x02, 0x00};
|
||||
char pat_end[] = {0x50, 0x4b, 0x05, 0x06, 0x00};
|
||||
|
||||
char lumpname[9];
|
||||
|
||||
// Haha the ResGetLumpsZip function doesn't
|
||||
// check for file errors, so neither will I.
|
||||
|
||||
// Central directory bullshit
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
file_size = ftell(fp);
|
||||
|
||||
if (!ResFindSignature(fp, pat_end, max(0, ftell(fp) - (22 + 65536))))
|
||||
return true;
|
||||
|
||||
fseek(fp, -4, SEEK_CUR);
|
||||
if (fread(&zend, 1, sizeof zend, fp) < sizeof zend)
|
||||
return true;
|
||||
|
||||
data_size = sizeof zend;
|
||||
|
||||
numlumps = SHORT(zend.entries);
|
||||
|
||||
fseek(fp, LONG(zend.cdiroffset), SEEK_SET);
|
||||
|
||||
char *cdir = (char*)(malloc(LONG(zend.cdirsize)));
|
||||
|
||||
if (fread(cdir, 1, LONG(zend.cdirsize), fp) < (UINT32)(LONG(zend.cdirsize)))
|
||||
return true;
|
||||
|
||||
size_t offset = 0;
|
||||
|
||||
for (i = 0; i < numlumps; i++)
|
||||
{
|
||||
zentry_t *zentry = (zentry_t*)(cdir + offset);
|
||||
char* fullname;
|
||||
char* trimname;
|
||||
char* dotpos;
|
||||
|
||||
if (memcmp(zentry->signature, pat_central, 4) != 0)
|
||||
return false;
|
||||
|
||||
fullname = (char*)(malloc(SHORT(zentry->namelen) + 1));
|
||||
strlcpy(fullname, (char*)(zentry + 1), SHORT(zentry->namelen) + 1);
|
||||
|
||||
// Strip away file address and extension for the 8char name.
|
||||
if ((trimname = strrchr(fullname, '/')) != 0)
|
||||
trimname++;
|
||||
else
|
||||
trimname = fullname; // Care taken for root files.
|
||||
|
||||
if (*trimname) // Ignore directories, well kinda
|
||||
{
|
||||
if ((dotpos = strrchr(trimname, '.')) == 0)
|
||||
dotpos = fullname + strlen(fullname); // Watch for files without extension.
|
||||
|
||||
memset(lumpname, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
|
||||
strncpy(lumpname, trimname, min(8, dotpos - trimname));
|
||||
|
||||
if (W_NameStartsWith(lumpname, checklist))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (W_NameStartsWith(fullname, checklist))
|
||||
return true;
|
||||
|
||||
free(fullname);
|
||||
|
||||
offset += sizeof *zentry + SHORT(zentry->namelen) + SHORT(zentry->xtralen) + SHORT(zentry->commlen);
|
||||
|
||||
data_size +=
|
||||
sizeof *zentry + SHORT(zentry->namelen) + SHORT(zentry->xtralen) + SHORT(zentry->commlen);
|
||||
|
||||
if (fseek(fp, LONG(zentry->offset), SEEK_SET) != 0)
|
||||
return false;
|
||||
|
||||
if (fread(&zlentry, 1, sizeof(zlentry_t), fp) < sizeof (zlentry_t))
|
||||
return false;
|
||||
|
||||
data_size +=
|
||||
sizeof zlentry + SHORT(zlentry.namelen) + SHORT(zlentry.xtralen) + LONG(zlentry.compsize);
|
||||
}
|
||||
|
||||
free(cdir);
|
||||
|
||||
if (data_size < file_size)
|
||||
{
|
||||
const char * error = "ZIP file has holes (%ld extra bytes)\n";
|
||||
CONS_Alert(CONS_ERROR, error, (file_size - data_size));
|
||||
return -1;
|
||||
}
|
||||
else if (data_size > file_size)
|
||||
{
|
||||
const char * error = "Reported size of ZIP file contents exceeds file size (%ld extra bytes)\n";
|
||||
CONS_Alert(CONS_ERROR, error, (data_size - file_size));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int W_CheckFileContains(const char *filename, lumpchecklist_t *checklist)
|
||||
{
|
||||
FILE *handle;
|
||||
int contains = false;
|
||||
|
||||
if (!checklist)
|
||||
I_Error("No checklist for %s\n", filename);
|
||||
// open wad file
|
||||
if ((handle = W_OpenWadFile(&filename, false)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (stricmp(&filename[strlen(filename) - 4], ".pk3") == 0)
|
||||
contains = W_CheckPK3Contains(handle, checklist);
|
||||
else
|
||||
{
|
||||
// detect wad file by the absence of the other supported extensions
|
||||
if (stricmp(&filename[strlen(filename) - 4], ".soc")
|
||||
&& stricmp(&filename[strlen(filename) - 4], ".lua"))
|
||||
{
|
||||
contains = W_CheckWADContains(handle, checklist);
|
||||
}
|
||||
}
|
||||
fclose(handle);
|
||||
return contains;
|
||||
}
|
||||
|
||||
int W_CheckPostLoadList(const char *filename)
|
||||
{
|
||||
static lumpchecklist_t postloadlist[] =
|
||||
{
|
||||
{"Lua/", 4},
|
||||
{"SOC/", 4},
|
||||
{"Skins/", 6},
|
||||
{"S_SKIN", 6},
|
||||
{"LUA_", 4},
|
||||
{"SOC_", 4},
|
||||
{"MAINCFG", 7},
|
||||
{"OBJCTCFG", 8},
|
||||
{"MAP", 3},
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
return W_CheckFileContains(filename, postloadlist);
|
||||
}
|
||||
|
||||
/** \brief Generates a virtual resource used for level data loading.
|
||||
*
|
||||
* \param lumpnum_t reference
|
||||
|
||||
@@ -226,4 +226,6 @@ void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5);
|
||||
|
||||
int W_VerifyNMUSlumps(const char *filename);
|
||||
|
||||
int W_CheckPostLoadList(const char *filename);
|
||||
|
||||
#endif // __W_WAD__
|
||||
Reference in new issue
Block a user