Compare commits

...
58 Commits
Author SHA1 Message Date
Alug 0ac0f2bae2 forgor to remove this 2024-10-26 00:51:24 +02:00
Alug cee28c6166 refactor a bunch of crap and fix skyportals 2024-10-25 22:58:10 +02:00
Alug a6be267325 Add visplane portal creation functionality and use it to replace the skybox rendering.
https://git.do.srb2.org/STJr/SRB2/-/commit/264386f84257a47fe5480bb6300df02d039a2491
2024-10-25 22:58:05 +02:00
Alug 426740e0ac port srb2 software portal refactor 2024-10-25 22:57:43 +02:00
Alug 78c0f64135 dont pass skybox to r_setupframe
why was this even done?
neither srb2 nor v2/rr ever did this?
2024-10-25 22:57:38 +02:00
indev b6e766ee44 Fix A_Lua not removing error handler from lua stack 2024-10-25 23:15:52 +03:00
Alug 5437040b78 move the return ealier in V_DoPostProcessor 2024-10-25 20:21:10 +02:00
Alug c786569981 Merge branch 'refactorpostimg' into Saturn-Next 2024-10-25 20:12:56 +02:00
Alug 7064b14539 Merge branch 'autoloadagain' into Saturn-Next 2024-10-25 20:12:53 +02:00
Alug f275ae98f5 this is needed for postimg stuff in first person
lol
also adds break in splitscreen lööp
2024-10-25 20:12:14 +02:00
Alug ef07d89e29 Revert "update lzf compression to 1.6"
This reverts commit 48e71afec1.
2024-10-25 19:50:16 +02:00
Alug b9bbd45e15 Revert "shut up mingw"
This reverts commit 75637e361c.
2024-10-25 19:50:10 +02:00
Alug 2bda27b80d Revert "those should be size_t"
This reverts commit b357c09171.
2024-10-25 19:49:26 +02:00
Alug 6ebf90cc50 Merge branch 'Saturn-Next' into autoloadagain 2024-10-25 03:28:43 +02:00
Alug ea00bebb04 Merge branch 'Saturn-Next' into refactorpostimg 2024-10-25 03:28:20 +02:00
Alug b862d835a5 save one calc lol 2024-10-25 03:27:51 +02:00
Alug d6602747ae oops forgor lol 2024-10-25 03:26:22 +02:00
Alug 9f79429d03 slight cleanup + make static + smol optimize ogl sprite drawers 2024-10-25 03:26:19 +02:00
Alug 5ff0c09868 just check for noencore bool in hwr_processseg instead of checked line flags everytime 2024-10-23 21:33:31 +02:00
Alug ad1c3e63a4 why not reuse those? 2024-10-23 21:33:28 +02:00
Alug 24dd6ba675 cleanup HWR_ProcessSeg
stuff was quite the mess
2024-10-23 21:33:21 +02:00
Alug 85f036a45b dont always calc this twice 2024-10-23 21:33:14 +02:00
Alug 6f8342b9a8 remove cv_splitwallfix
tbh i dont think anyone even knows about this, never heard any complains, never had any issues, neither visually or performancewise.
its just clutter at this point
2024-10-23 21:33:04 +02:00
Alug c5c6f6b820 this does nothing 2024-10-23 21:30:21 +02:00
Alug 3d472c34a1 no need to check stuff in already postload marked addons 2024-10-23 15:48:44 +02:00
Alug 63ca366bd8 dont play rain sounds when weather is disabled 2024-10-23 13:00:36 +02:00
Alug e9e888ab7f remove debug print 2024-10-23 02:41:28 +02:00
indev 5ea55b3e3a Add W_CheckFileContains for W_CheckPostLoadList 2024-10-23 02:41:25 +02:00
Alug 8b1797927a attempt to check for things in file for postload detection 2024-10-23 02:41:23 +02:00
Alug 05a98964fb split auto and postload, let autoload run on gamestart again
prep for smth
2024-10-23 02:41:20 +02:00
Alug 8cbf798de8 redo rain sound overflow fix
https://git.do.srb2.org/KartKrew/RingRacers/-/commit/3eac1fed0f44a8285a9f6b82a12e86997bbb0d34
2024-10-23 02:37:32 +02:00
Alug 9314a24cb2 use highly optmized (but slightly inaccurate) version of R_PointOnSide for rendering 2024-10-23 02:37:08 +02:00
Alug 19b1683e61 make those not look terrible thx 2024-10-22 01:18:13 +02:00
Alug d029107e75 refactor postimg stuff so it can be combined with each other better
thx much indev! <3
everything now works with encore!
software now also supports screen effects in splitscreen!
2024-10-22 01:17:57 +02:00
Alug bc97e0b703 actually remove "renderflags" lol 2024-10-21 22:53:44 +02:00
Alug f47c663f79 remove renderflags
those literally did nothing
2024-10-21 22:47:32 +02:00
Alug 6f9d41eadb fix R_ThingVisible
those are "eflags" in kart smh
2024-10-21 22:46:59 +02:00
Alug 1b512edc56 add proper null check here too 2024-10-21 21:28:08 +02:00
Alug 884a6da2bd dont use cv_sloperolldist in splitscreen + save some assignments and one fixedhypot call
also use tabs lul
2024-10-21 21:07:32 +02:00
Alug 7a3d958fc1 tab pls 2024-10-21 18:43:08 +02:00
Alug 7223581539 Clarify we're calculating a cross product 2024-10-21 18:10:29 +02:00
Alug 664bd2de3f dont draw fadescreen when minimap iss active 2024-10-21 17:47:44 +02:00
indev 63568e3861 Fix off-by-one error for using '?' as map name 2024-10-21 18:43:37 +03:00
indev f149d058a1 Fix off-by-one error in lib_setSfxInfo 2024-10-21 18:06:35 +03:00
Alug 970251ced3 also check here ig? 2024-10-21 17:01:27 +02:00
Alug dba7a7dc3c prevent map command crash from maps with invalid or non existing mapinfo 2024-10-21 15:37:44 +02:00
Alug 393c0be407 Revert "attempt to optimize some p_maputl stuff"
This reverts commit 81d415c5ba.
2024-10-21 14:19:35 +02:00
Alug 5e9ea2429b replace those two P_MobjWasRemoved with simple null check insteead
since those may actually segfault if null anyways
2024-10-21 06:23:14 +02:00
Alug 81a14995da trailing space hell 2024-10-21 06:14:24 +02:00
Alug 4267ac9a8d remove more P_MobjWasRemoved checks
same as before, those may be not synchsafe
2024-10-21 06:04:47 +02:00
Alug bcf72cc0e8 revert some P_MobjWasRemoved checks i forgor about
those may NOT be vanilla netsafe
2024-10-21 06:04:17 +02:00
Alug 54d9a98090 rotsprite stuff also should be SHORT 2024-10-20 19:11:54 +02:00
Alug 81d415c5ba attempt to optimize some p_maputl stuff 2024-10-20 16:25:12 +02:00
Alug de1b801bda try to take some registers for span drawers too 2024-10-20 16:24:02 +02:00
Alug 2c665fef6f remove this again 2024-10-20 15:21:42 +02:00
Alug c6fbf405bf optimize R_PointOnSegSide
its only used for 2 rendering functions, so being potentially inaccurate is not that dangerous and the speedup in some instances might be worth the tradeoff
2024-10-20 15:16:37 +02:00
Alug 7076c35521 HWR_RenderPlane can be static 2024-10-20 14:57:28 +02:00
Alug 86ed1b709e fix some rendering issues and crashes in software renderer
- Increase MINZ from 4 fracunits to 16
- R_StoreWallRange: do not render textures with holes
- fix off-by-one error in R_ProjectSprite
- Avoid rendering unused left/right edges of screen while rolling
- Clamp patch column post drawing bounds
- Vissprites: set dc.texheight
- Add null check for column in R_DrawMaskedColumn
2024-10-20 14:57:22 +02:00
45 changed files with 1832 additions and 1441 deletions

No files matched your search

+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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];
+8
View File
@@ -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),
+2
View File
@@ -413,6 +413,8 @@ typedef struct player_s
// See pflags_t, above.
pflags_t pflags;
UINT16 postimgflags;
// playing animation.
panim_t panim;
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-1
View File
@@ -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
View File
@@ -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;
+1 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+189 -341
View File
@@ -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;
}
+2 -2
View File
@@ -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
-5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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:
-8
View File
@@ -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
+1
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+63
View File
@@ -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
View File
@@ -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)
-6
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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__