Compare commits

..
2 Commits
Author SHA1 Message Date
alufolie91 9936f9c740 have Z_IsMobjValid2 print an error in console
if mobj pointer is invalid
the callee should handle the behavior
2026-10-02 18:23:29 +02:00
alufolie91 bee5c8e5ed add code to check for mobj pointer validity
as we use the pool allocator we may check if a mobj points into the address range of the level pool specific to mobj allocations (g_level_large_pool)
this may help in debugging stuff without the need to run things like ASAN or valgrind
2026-10-02 18:23:26 +02:00
31 changed files with 452 additions and 673 deletions

No files matched your search

-2
View File
@@ -246,8 +246,6 @@ set(SRB2_CONFIG_ASAN OFF CACHE BOOL
"Compile with AddressSanitizer (libasan).")
set(SRB2_CONFIG_UBSAN OFF CACHE BOOL
"Compile with UndefinedBehaviorSanitizer (libubsan).")
set(SRB2_CONFIG_TSAN OFF CACHE BOOL
"Compile with ThreadSanitizer (libtsan).")
set(SRB2_CONFIG_MUMBLE ON CACHE BOOL
"Enable Mumble support")
+5 -18
View File
@@ -75,7 +75,6 @@
# PROFILEMODE=1 - Enable performance profiling (gprof).
# USEASAN=1 - Enable building with Address Sanitizer.
# USEUBSAN=1 - Enable building with Undefined Behavior Sanitizer.
# USETSAN=1 - Enable building with Thread Sanitizer.
# NOLIBBACKTRACE=1 - Disable using Libbacktrace for crashlog traces.
#
# General flags for building:
@@ -262,35 +261,23 @@ debug_opts=-D_DEBUG
else # build a normal optimized version
debug_opts=-DNDEBUG
opts+=-O3
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
endif
endif
ifdef USEASAN
# compile with asan
opts+=-O1 -fsanitize=address -fno-omit-frame-pointer -fno-common
libs+=-fsanitize=address
NOLTO=1
endif
ifdef USEUBSAN
# compile with ubsan
opts+=-O1 -fsanitize=undefined -fno-omit-frame-pointer
libs+=-fsanitize=undefined
NOLTO=1
endif
ifdef USETSAN
# compile with tsan
opts+=-O1 -fsanitize=thread -fno-omit-frame-pointer
libs+=-fsanitize=thread
NOLTO=1
endif
ifndef DEBUGMODE
ifndef NOLTO
# compile with LTO
opts+=-flto=auto
libs+=-flto=auto
endif
endif
ifdef USEJEMALLOC
-1
View File
@@ -1739,7 +1739,6 @@ static void CV_SetCVar(consvar_t *var, const char *value, boolean stealth)
// send the value of the variable
UINT8 buf[128];
UINT8 *p = buf;
if (!(server || (IsPlayerAdmin(consoleplayer))))
{
CONS_Alert(CONS_NOTICE, "Only the server or admin can change: %s %s\n", var->name, var->string);
+24
View File
@@ -149,6 +149,30 @@ void PoolAllocator::release()
allocated_blocks_ = 0;
}
bool PoolAllocator::ptrcheck(const void* p) const
{
const uintptr_t paddr = reinterpret_cast<uintptr_t>(p);
ChunkFooter* next = nullptr;
for (ChunkFooter* chunk = first_chunk_; chunk != nullptr; chunk = next)
{
const uintptr_t blockstart = reinterpret_cast<uintptr_t>(chunk->start);
const uintptr_t blockend = blockstart + blocks_ * block_size_;
//CONS_Printf("mobj ptr %lu, block start %lu end %lu\n", paddr, blockstart, blockend);
if (paddr >= blockstart && paddr < blockend)
{
return true;
}
next = chunk->next;
}
return false;
}
static LinearMemory g_frame_memory {4 * 1024 * 1024};
void* Z_Frame_Alloc(size_t size)
+1
View File
@@ -65,6 +65,7 @@ public:
constexpr size_t allocated_bytes() const noexcept { return allocated_blocks_ * block_size_; };
void release();
bool ptrcheck(const void* p) const;
};
} // namespace srb2
+2 -8
View File
@@ -1149,19 +1149,13 @@ static void D_FindAddonsToAutoload(void)
// ok so theres still issues with players adding stuff to autoload by accident
// sometimes this stuff contains maps
// you can probably imagine how that goes in a netgame....
int retmap = W_CheckAutoLoadContainsMap(wadsToAutoload);
if (retmap == -1)
{
CONS_Alert(CONS_WARNING, "Autoload: file %s was not found or not valid.\n", wadsToAutoload);
continue;
}
if (retmap > 0)
if (W_CheckAutoLoadContainsMap(wadsToAutoload))
{
CONS_Alert(CONS_WARNING, "Autoload: file %s contains map data, this WILL cause crashes and desynchs! skipping...\n", wadsToAutoload);
continue;
}
if (!postload && W_CheckPostLoadList(wadsToAutoload) > 0)
if (!postload && W_CheckPostLoadList(wadsToAutoload))
{
CONS_Printf("Autoload: forcing postload for file %s\n", wadsToAutoload);
postload = true;
+3 -12
View File
@@ -361,17 +361,11 @@ typedef struct squishdance_s
{
tic_t countdown; // hold "custom 3" for 2 seconds to engange le dance
tic_t time;
fixed_t work;
fixed_t ang;
fixed_t bounce; // hehe squishy
} squishdance_t;
typedef struct salty_s
{
bool ready;
bool tapping;
fixed_t zoffset;
fixed_t momz;
bool jump;
} salty_t;
// ========================================================================
// PLAYER STRUCTURE
// ========================================================================
@@ -567,9 +561,6 @@ typedef struct player_s
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
// saltyhop! hardcode edition
salty_t salty;
squishdance_t squishdance;
fixed_t fovadd; // adjust FOV for hw rendering
+3 -8
View File
@@ -119,25 +119,20 @@ target_compile_definitions(SRB2SDL2 PRIVATE
-DHAVE_THREADS
)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(SRB2_CONFIG_ASAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
endif()
if(SRB2_CONFIG_UBSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
endif()
if(SRB2_CONFIG_TSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
endif()
## strip debug symbols into separate file when using gcc
# if(CMAKE_COMPILER_IS_GNUCC)
# if(${CMAKE_BUILD_TYPE} MATCHES Debug)
+1 -4
View File
@@ -474,7 +474,6 @@ void DRPC_UpdatePresence(void)
char charname[11+SKINNAMESIZE+1];
boolean joinSecretSet = false;
char *clientJoinSecret = NULL;
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
@@ -531,8 +530,7 @@ void DRPC_UpdatePresence(void)
// Grab the host's IP for joining.
if ((join = DRPC_GetServerIP()) != NULL)
{
clientJoinSecret = DRPC_XORIPString(join);
discordPresence.joinSecret = clientJoinSecret;
discordPresence.joinSecret = DRPC_XORIPString(join);
joinSecretSet = true;
}
}
@@ -714,7 +712,6 @@ void DRPC_UpdatePresence(void)
}
Discord_UpdatePresence(&discordPresence);
free(clientJoinSecret);
}
#endif // HAVE_DISCORDRPC
+16 -100
View File
@@ -96,7 +96,7 @@ static void HWR_FreePoly(poly_t *poly)
// divfrac = how far along partline vector is crossing pt
static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t *v2)
{
double frac;
double frac1, frac2;
double num; // numerator
double den; // denominator
double v1x, v1y, v1dx, v1dy; // polygon side vector, v1->v2
@@ -122,23 +122,24 @@ static boolean fracdivline(fdivline_t *partline, polyvertex_t *v1, polyvertex_t
// first check the frac along the polygon segment,
// (do not accept hit with the extensions)
num = (v3x - v1x)*v3dy + (v1y - v3y)*v3dx;
frac = num / den;
frac1 = num / den;
// 0= cross at v1, 1.0= cross at v2
if (frac < 0.0 || frac > 1.0) // double
if (frac1 < 0.0 || frac1 > 1.0) // double
return false; // not within the polygon side
// now get the frac along the BSP line
// which is useful to determine what is left, what is right
num = (v3x - v1x)*v1dy + (v1y - v3y)*v1dx;
frac2 = num / den;
partline->divfrac = num / den; // how far along partline vector
partline->divfrac = frac2; // how far along partline vector
// [WDJ] find the interception point along the segment.
// It should be slightly more accurate because it is always closer to the
// crossing point than arbitrary positions on the partition line.
partline->divpt.x = v1x + v1dx*frac;
partline->divpt.y = v1y + v1dy*frac;
partline->divpt.x = v1x + v1dx*frac1;
partline->divpt.y = v1y + v1dy*frac1;
return true;
}
@@ -160,71 +161,6 @@ static boolean SameVertex(polyvertex_t *p1, polyvertex_t *p2)
return true;
}
// Adapted from function in prboom.
// Point is to rightside of divline when result > 0,
// but result is multiplied by length of divline.
// Returns near 0, when point is on, or nearly on, the divline.
static inline double point_rightside(fdivline_t *dl, polyvertex_t *v4)
{
// Cross product of dl and vector dl->(x,y) to v4,
// is > 0 when v4 is to right side of divline.
// Viewed along divline from vertex, looking towards positive dx,dy.
// If divline is rotated until dy>0 and dx = 0, then true when rotated
// vertex position is to the right of the divline (v4->x > dl->x).
return ((((double)(v4->x) - (double)(dl->x)) * (double)(dl->dy))
- (((double)(v4->y) - (double)(dl->y)) * (double)(dl->dx)));
}
// [WDJ] The front and back MUST match the BSP determination, else it will assign
// this poly to the wrong sector.
// May have 1 point on the line, and other points might be very close to the line.
// Can only trust a test of a point that is NOT on the line.
// Using a tstdist = 0.5f worked, but it might break on very small poly.
// Avactor.wad had polys with d = 9.09, 5552, 1.64, 1011, 14252, 0.0136, 0.00634, 14655, 3,
// -0.3044, 7, 1.53, etc..,
// and one poly with d = -0.023 with the rest of the points d > 0.
// One 14 point poly with divline len=8, had to test 9 points to find d = 36.
// Typical: divline len=70 d=6828, divline len=1.0 d=35, divline len=1.414 d=5.
// The result of point_rightside is proportional to the length of divline.
// The divline length can be from 1.414 to 14000.
static void UnsplitPoly(fdivline_t *dlnp, poly_t *poly,
poly_t **frontpoly, poly_t **backpoly)
{
int32_t i;
double d;
const double tstd = hypot((double)dlnp->dx, (double)dlnp->dy) / 2.0;
double sumd = 0; // accumulated left or rightness.
for (i = 0; i < poly->numpts; i++)
{
// Look for a point that is obviously to the left or right.
d = point_rightside(dlnp, &poly->pts[i]); // d > 0 is right
sumd += d;
if (d > tstd)
goto poly_rightside;
if (d < -tstd)
goto poly_leftside;
}
// Did not find an obvious left or right point, then
if (sumd < 0)
goto poly_leftside;
poly_rightside:
// poly is to rightside of divline.
*frontpoly = poly;
*backpoly = NULL;
return;
poly_leftside:
// poly is to leftside of divline.
*frontpoly = NULL;
*backpoly = poly;
return;
}
// split a _CONVEX_ polygon in two convex polygons
// outputs:
// frontpoly : polygon on right side of bsp line
@@ -327,7 +263,10 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
// linedefs where each side point the same sector, that is:
// the deep water effect with the original Doom
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
//TODO: make sure front poly is to front of partition line?
*frontpoly = poly;
*backpoly = NULL;
return;
}
@@ -335,14 +274,16 @@ static void SplitPoly (fdivline_t *dlnp, // splitting parametric line
if (pe < 0)
{
//I_Error("SplitPoly: only one point for split line (%d %d)", ps, pe);
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
*frontpoly = poly;
*backpoly = NULL;
return;
}
if (pe <= ps)
{
//I_Error("SplitPoly: invalid splitting line (%d %d)", ps, pe);
UnsplitPoly(dlnp, poly, frontpoly, backpoly);
*frontpoly = poly;
*backpoly = NULL;
return;
}
@@ -447,10 +388,6 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
vertex_t *v1, *v2;
fdivline_t cutseg; // x, y, dx, dy as start of node_t struct
// empty poly? just save us some time then
if (poly->numpts <= 0)
return frontpoly;
// for each seg of the subsector
for (; segcount--; lseg++)
{
@@ -552,23 +489,6 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 segcount, poly_t *poly)
// need 2 points
if (pe >= 0)
{
// Cuts that miss the polygon.
if (ps_frac < 0.0 && cutseg.divfrac < 0.0)
continue;
if (ps_frac > 1.0 && cutseg.divfrac > 1.0)
continue;
#define FRAC_EP 0.01f
// Reject cuts that could make the polygon non-convex.
// Cannot make normal cut, ps_frac end is loose.
if ((ps_frac < (0.0 - FRAC_EP)) || (ps_frac > (1.0f + FRAC_EP)))
continue;
// Cannot make normal cut, cutseg.divfrac end is loose.
if ((cutseg.divfrac < (0.0 - FRAC_EP)) || (cutseg.divfrac > (1.0f + FRAC_EP)))
continue;
#undef FRAC_EP
// generate FRONT poly
frontpoly = HWR_AllocPoly(poly_num_pts);
@@ -760,11 +680,7 @@ static void WalkBSPNode(INT32 bspnum, poly_t *poly, UINT16 *leafnode, fixed_t *b
memcpy(bbox, bsp->bbox[0], 4*sizeof (fixed_t));
}
else
{
// [WDJ] Having no front poly is as likely as no back poly, since
// logic in Split Poly was changed to check poly direction.
// I_Error("HWR_WalkBSPNode: no front poly, bspnum= %d\n", bspnum);
}
I_Error("WalkBSPNode: no front poly?");
// Recursively divide back space.
if (backpoly)
+40 -19
View File
@@ -614,12 +614,24 @@ void HWR_FreeMapTextures(void)
gl_numtextures = 0;
}
#define NAME flatcheck
#define KEY_TY UINT32
#define HASH_FN vt_hash_integer
#define CMPR_FN vt_cmpr_integer
#include "../verstable.h"
static void HWR_PrecacheLevelFlats(void)
{
// lookup for flats that may´ve been already loaded
flatcheck flatpresent;
size_t i;
#if 0
size_t j;
#endif
INT32 k;
// FIXME: this needs to account for FOFs to properly work
// this kinda messes up encore remapping behavior at times
// so just disable it for now ig
#ifdef GLENCORE
if (encoremap)
{
@@ -627,6 +639,9 @@ static void HWR_PrecacheLevelFlats(void)
}
#endif
flatcheck_init(&flatpresent);
flatcheck_reserve(&flatpresent, numlevelflats);
// special case for encore
#if 0
#ifdef GLENCORE
@@ -635,7 +650,6 @@ static void HWR_PrecacheLevelFlats(void)
// go through all sectors to determine if it should be remapped for encore
for (i = 0; i < numsectors; i++)
{
size_t j;
sector_t *sec = &sectors[i];
// gotta check sector floor and ceiling
@@ -678,7 +692,11 @@ static void HWR_PrecacheLevelFlats(void)
{
const levelflat_t *levelflat = &levelflats[i];
HWR_GetFlat(levelflat->lumpnum, false);
if (flatcheck_is_end(flatcheck_get(&flatpresent, levelflat->lumpnum)))
{
HWR_GetFlat(levelflat->lumpnum, false);
flatcheck_insert(&flatpresent, levelflat->lumpnum);
}
if (levelflat->speed) // is it an animated flat ?
{
@@ -686,11 +704,17 @@ static void HWR_PrecacheLevelFlats(void)
for (k = 0; k < levelflat->numpics; k++)
{
lumpnum_t lump = levelflat->baselumpnum + k;
HWR_GetFlat(lump, false);
if (flatcheck_is_end(flatcheck_get(&flatpresent, lump)))
{
HWR_GetFlat(lump, false);
flatcheck_insert(&flatpresent, lump);
}
}
}
}
}
flatcheck_cleanup(&flatpresent);
}
static void HWR_PrecacheLevelTextures(void)
@@ -714,7 +738,7 @@ static void HWR_PrecacheLevelTextures(void)
{
const line_t *line = &lines[i];
#ifdef GLENCORE
const boolean noencoremap = (encoremap && (line->flags & ML_TFERLINE));
const int noencoremap = ((encoremap && (line->flags & ML_TFERLINE)) ? 2 : 1);
#endif
// two sides
for (j = 0; j < 2; j++)
@@ -731,27 +755,25 @@ static void HWR_PrecacheLevelTextures(void)
{
const INT32 texnum = sidetex[f];
if (texnum <= 0 || (unsigned)texnum >= gl_numtextures)
if (texnum < 0 || texnum >= (signed)gl_numtextures)
continue;
if (!(texturepresent[texnum] & 1))
{
texturepresent[texnum] |= 1;
HWR_GetTexture(texnum, false);
}
if (texturepresent[texnum])
continue;
#ifdef GLENCORE
if (noencoremap
&& !(texturepresent[texnum] & 2))
{
texturepresent[texnum] |= 2;
texturepresent[texnum] = 1|noencoremap;
#else
texturepresent[texnum] = 1;
#endif
HWR_GetTexture(texnum, false);
#ifdef GLENCORE
if (noencoremap & 2)
HWR_GetTexture(texnum, true);
}
#endif
}
}
}
// check for animated textures
for (anim = anims; anim < lastanim; anim++)
{
if (!anim->istexture)
@@ -770,7 +792,6 @@ static void HWR_PrecacheLevelTextures(void)
{
HWR_GetTexture(animtexnum, false);
}
#ifdef GLENCORE
if (texpresent & 2)
{
@@ -892,7 +913,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean noencore)
GLMapTexture_t *gltex;
GLMipmap_t *glMipmap;
if (tex < 0 || (unsigned)tex >= gl_numtextures)
if (tex < 0 || tex >= (signed)gl_numtextures)
{
#ifdef PARANOIA
I_Error("HWR_GetTexture: Invalid texture ID %d", tex);
+52 -82
View File
@@ -610,7 +610,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
fflatsize = 1024.0f;
flatflag = 1023;
break;
case 262144: // 512x512 lump
case 262144:// 512x512 lump
fflatsize = 512.0f;
flatflag = 511;
break;
@@ -721,7 +721,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false);
if (gl_maphashorizonlines && subsector && !FOFsector && cv_glhorizonlines.value)
if (gl_maphashorizonlines && subsector && cv_glhorizonlines.value)
{
// Horizon lines
FOutVector horizonpts[6];
@@ -742,6 +742,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
line_t* ld = line->linedef;
// this check sucks and is a hotspot lel
if (LIKELY(ld->special != HORIZONSPECIAL))
continue;
@@ -1239,44 +1240,46 @@ static inline boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
pSurf->PolyColor.s.alpha = 0xFF;
// check if linedef alpha is within range
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
// set alpha for transparent walls
switch (gl_linedef->special)
if (LIKELY(!gl_curline->polyseg))
{
// Translucent linedef types
case 102:
case 121 ... 125:
case 141 ... 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode)
{
if (linealpha)
// check if linedef alpha is within range
const boolean linealpha = (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT);
// set alpha for transparent walls
switch (gl_linedef->special)
{
// Translucent linedef types
case 102:
case 121 ... 125:
case 141 ... 145:
case 174:
case 175:
case 192:
case 195:
case 221:
case 253:
case 256:
if (gl_linedef->blendmode && linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (linealpha)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->blendmode)
{
if (linealpha)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (linealpha)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
}
}
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
else if (gl_curline->polyseg->translucency > 0)
{
// Polyobject translucency is shared between all of its lines
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
@@ -1383,8 +1386,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// two sided line
if (gl_backsector)
{
const INT32 gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
const INT32 gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
fixed_t texturevpeg;
@@ -1395,7 +1397,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (!gl_curline->polyseg) // Don't do it for polyobjects
{
// Sky Ceilings
wallVerts[2].y = wallVerts[3].y = FLOATMAX; // draw to top of map space
wallVerts[3].y = wallVerts[2].y = FLOATMAX;
auto draw_sky_walls = []
(int vert1, int vert2, fixed_t world, fixed_t worldslope, auto& wwallVerts, auto& sSurf) FUNCINLINE
@@ -1405,9 +1407,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_DrawSkyWall(wwallVerts, &sSurf);
};
// worldtop = front ceiling
// worldhigh = back ceiling
if (gl_frontsector->ceilingpic == skyflatnum)
{
if (gl_backsector->ceilingpic == skyflatnum)
@@ -1426,17 +1425,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
worldtop = worldhigh;
worldtopslope = worldhighslope;
}
else if (!gl_toptexture &&
(worldhigh <= worldtop && worldhighslope <= worldtopslope) && // Assuming ESLOPE is always on with my changes
(worldhigh != worldtop || worldhighslope != worldtopslope))
{
// Only the frontsector is sky.
// If there's no upper texture, extend the sky wall
// down to the lower of the two ceilings.
fixed_t top = std::min(worldtop, worldhigh);
fixed_t topslope = std::min(worldtopslope, worldhighslope);
draw_sky_walls(0, 1, top, topslope, wallVerts, Surf);
}
else
{
// Only the frontsector is sky, just draw a skywall from the front ceiling
@@ -1449,11 +1437,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
draw_sky_walls(0, 1, worldtop, worldtopslope, wallVerts, Surf);
}
// worldbottom = front floor
// worldlow = back floor
// Sky Floors
wallVerts[0].y = wallVerts[1].y = FLOATMIN; // draw to bottom of map space
wallVerts[0].y = wallVerts[1].y = FLOATMIN;
if (gl_frontsector->floorpic == skyflatnum)
{
@@ -1465,7 +1450,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gl_bottomtexture))
&& !(gl_sidedef->bottomtexture))
{
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
@@ -1476,25 +1461,15 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
draw_sky_walls(3, 2, worldbottom, worldbottomslope, wallVerts, Surf);
}
}
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_bottomtexture))
else if ((gl_backsector->floorpic == skyflatnum) && !(gl_sidedef->bottomtexture))
{
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
else if (gl_frontsector->ceilingpic == skyflatnum &&
gl_backsector->ceilingpic == skyflatnum &&
(worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gl_bottomtexture))
{
// Both ceilings are sky, but neither floor is sky.
// If there's a lower wall gap without a bottom texture,
// draw a skywall from the backsector's higher floor.
draw_sky_walls(3, 2, worldlow, worldlowslope, wallVerts, Surf);
}
}
gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture);
// check TOP TEXTURE
if (gl_toptexture && (worldhighslope < worldtopslope || worldhigh < worldtop))
{
@@ -1558,6 +1533,8 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
}
gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
// check BOTTOM TEXTURE
if (gl_bottomtexture && (worldlowslope > worldbottomslope || worldlow > worldbottom))
{
@@ -2985,7 +2962,7 @@ static void HWR_Subsector(size_t num)
}
else
{
HWR_GetFlat(flatlump, R_NoEncore(rover->master->frontsector, bottom));
HWR_GetFlat(flatlump, R_NoEncore(gl_frontsector, !bottom));
light = R_GetPlaneLight(gl_frontsector, centerHeight, underside);
HWR_RenderPlane(sub, &extrasubsectors[num], !bottom, roverheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, flatlump,
@@ -3483,12 +3460,8 @@ static inline void HWR_ApplyDispoffset(gl_vissprite_t *spr, FOutVector *wallVert
{
HWR_RotateSpritePolyToAim(spr, wallVerts, false, papersprite);
const float f_xdiff = (spr->x1 - gl_viewx);
const float f_ydiff = (spr->z1 - gl_viewy);
const float f_zdiff = (spr->gzt - gl_viewz);
const float sprdist = sqrtf((f_xdiff*f_xdiff) + (f_ydiff*f_ydiff) + (f_zdiff*f_zdiff));
const float distfact = ((2.0f * spr->dispoffset) + 20.0f) / sprdist;
const float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
const float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
for (size_t i = 0; i < 4; i++)
{
@@ -4314,10 +4287,7 @@ static void HWR_RenderDrawNodes(void)
gl_frontsector = NULL;
if (!(plane->blend & PF_NoTexture))
{
const boolean ceiling = plane->FOFSector ? !plane->isceiling : plane->isceiling; // match software!
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, ceiling));
}
HWR_GetFlat(plane->lumpnum, R_NoEncore(plane->FOFSector, plane->isceiling));
HWR_RenderPlane(NULL, plane->xsub, plane->isceiling, plane->fixedheight, plane->blend, plane->lightlevel,
plane->lumpnum, plane->FOFSector, plane->alpha, plane->planecolormap);
+3 -3
View File
@@ -1146,8 +1146,8 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Look at HWR_ProjectSprite for more
{
md2_t *md2s = NULL;
int skinnum = 0;
md2_t *md2s;
int skinnum;
patch_t *gpatch, *blendgpatch;
GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL;
INT32 durs = spr->mobj->state->tics;
@@ -1221,7 +1221,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
skinnum = (skin_t *)spr->mobj->localskin - skins;
}
}
else if (spr->mobj->skin)
else
{
md2s = md2_playermodels;
skinnum = (skin_t *)spr->mobj->skin - skins;
+3 -1
View File
@@ -3829,8 +3829,10 @@ static void K_drawKartMinimap(void)
}
else
{
const INT32 skinnum = K_GetMobjLocalSkinNum(mobj->skin, mobj->localskin, mobj->skinlocal);
// special case if startcolor is not the default (160 / Green)
if (K_GetMobjSkin(mobj)->starttranscolor != skins[0].starttranscolor)
if (skinnum && skins[skinnum].starttranscolor != skins[0].starttranscolor)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
}
+100 -163
View File
@@ -71,11 +71,12 @@ consvar_t cv_stairjank = {"stairjank", "Off", CV_SAVE|CV_CALL, CV_OnOff, PDistor
consvar_t cv_stairjanksfx = {"stairjanksfx", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
//hardcode saltyhop mhhm
consvar_t cv_saltyhop = {"hardcodehop", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void saltyhop_onchange(void);
consvar_t cv_saltyhop = {"hardcodehop", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, saltyhop_onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyhopsfx = {"hardcodehopsfx", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltysquish = {"hardcodehopsquish", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t saltyheight_t[] = {{FRACUNIT/4, "MIN"}, {2*FRACUNIT, "MAX"}, {0, NULL}};
consvar_t cv_saltyheight = {"hardcodehopheight", "1", CV_FLOAT|CV_SAVE, saltyheight_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyheight = {"hardcodehopheight", "1", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, saltyheight_t, saltyhop_onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_saltyroll = {"hardcodehoproll", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_squishdance = {"squishdance", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@@ -83,6 +84,23 @@ consvar_t cv_squishdance = {"squishdance", "On", CV_SAVE, CV_OnOff, NULL, 0, NUL
static CV_PossibleValue_t squishdancespeed_cons_t[] = {{20, "MIN"}, {280, "MAX"}, {0, NULL}};
consvar_t cv_squishdancespeed = {"squishdance_speed", "140", CV_SAVE, squishdancespeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void saltyhop_onchange(void)
{
// reset everything when toggling saltyhop
if (gamestate != GS_LEVEL)
return;
for (INT32 i = 0; i < MAXPLAYERS; i++)
{
player_t *player = &players[i];
if (!player || P_MobjWasRemoved(player->mo))
continue;
memset(&player->mo->salty, 0, sizeof(player->mo->salty));
}
}
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
// franticitems is Frantic Mode items, bool
@@ -1809,56 +1827,25 @@ void K_RespawnChecker(player_t *player)
mobj_t *mo;
angle_t newangle;
fixed_t newx, newy, newz;
#ifdef PHOBOS_BUILD
const fixed_t fscale = player->mo->scale;
#else
static const fixed_t fscale = FRACUNIT; // does NOT use scale, since this effect doesn't scale properly
#endif
newangle = FixedAngle(((360/8)*i)*FRACUNIT);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * fscale);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * fscale);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31<<FRACBITS); // does NOT use scale, since this effect doesn't scale properly
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31<<FRACBITS);
if (player->mo->eflags & MFE_VERTICALFLIP)
newz = player->mo->z + player->mo->height;
else
newz = player->mo->z;
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
if (!P_MobjWasRemovedCompat(mo))
if (mo)
{
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
P_SetTarget(&mo->target, player->mo);
mo->angle = newangle+ANGLE_90;
mo->momz = (8 * fscale) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = fscale));
mo->momz = (8<<FRACBITS) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = FRACUNIT));
}
#ifndef PHOBOS_BUILD
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// and we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the normal lazers!
mo->flags2 |= MF2_DONTDRAW;
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31 * player->mo->scale);
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31 * player->mo->scale);
// now spawn our local lazers
mo = P_SpawnMobj(newx, newy, newz, MT_DEZLASER);
if (!P_MobjWasRemovedCompat(mo))
{
if (player->mo->eflags & MFE_VERTICALFLIP)
mo->eflags |= MFE_VERTICALFLIP;
P_SetTarget(&mo->target, player->mo);
mo->angle = newangle+ANGLE_90;
mo->momz = (8 * player->mo->scale) * P_MobjFlip(player->mo);
P_SetScale(mo, (mo->destscale = player->mo->scale));
mo->islocal = true; // Keep this local!
}
}
#endif
}
}
}
@@ -2207,7 +2194,7 @@ static void K_GetKartBoostPower(player_t *player)
// Technically, all mobjs that think can cause desynchs if they are spawned conditionally, so best we can do
// is to hide them if you are in saltyhop jump
if (dust && player->salty.jump)
if (dust && player->mo->salty.jump)
dust->flags2 |= MF2_DONTDRAW;
if (leveltime % 6 == 0)
@@ -3236,8 +3223,10 @@ static void K_SpawnDriftSparks(player_t *player)
for (i = 0; i < 2; i++)
{
const angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
const fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
fixed_t driftExtraScale = 0;
angle_t thrustangle = (travelangle + ((i&1) ? -1 : 1)*ANGLE_135);
fixed_t smolscale = FixedMul(32*FRACUNIT, player->mo->scale);
newx = player->mo->x + P_ReturnThrustX(player->mo, thrustangle, smolscale);
newy = player->mo->y + P_ReturnThrustY(player->mo, thrustangle, smolscale);
@@ -3249,9 +3238,9 @@ static void K_SpawnDriftSparks(player_t *player)
spark->angle = travelangle-(ANGLE_45/5)*player->kartstuff[k_drift];
// scale increase while driftspark level gained timer is running
const fixed_t driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
driftExtraScale = FixedDiv(player->driftsparkGrowTimer, DRIFTSPARKGROWTICS);
spark->destscale = FixedMul(player->mo->scale, FRACUNIT + FixedMul(driftExtraScale, cv_driftsparkpulse.value));
P_SetScale(spark, spark->destscale);
P_SetScale(spark, spark->destscale); // why not use what we calculated above?
spark->momx = player->mo->momx/2;
spark->momy = player->mo->momy/2;
@@ -3343,10 +3332,10 @@ static void K_StretchPlayerGravity(player_t *player)
mobj_t *pmo = player->mo;
const fixed_t tempxscale = pmo->realxscale;
const fixed_t tempyscale = pmo->realyscale;
fixed_t tempxscale = pmo->realxscale;
fixed_t tempyscale = pmo->realyscale;
stretchScaleFactor = FixedDiv(mapobjectscale*60, cv_gravstretch.value);
stretchScaleFactor = FixedDiv(FRACUNIT*60, cv_gravstretch.value);
stretchScaleFactor = min(stretchScaleFactor, MAXSTRETCHDIV);
if (pmo->slamsoundtimer)
@@ -3354,26 +3343,26 @@ static void K_StretchPlayerGravity(player_t *player)
if (!P_IsObjectOnGround(pmo))
{
const fixed_t pzmom = abs(pmo->momz);
fixed_t pzmom = abs(pmo->momz);
const fixed_t stretchDiv = FixedDiv(pzmom, stretchScaleFactor);
if (abs(pzmom/mapobjectscale) != 0)
if (abs(pzmom/FRACUNIT) != 0)
{
if ((tempxscale - stretchDiv) > (tempxscale / 5))
if (((tempxscale-(stretchDiv))) > (tempxscale/5))
{
pmo->spritexscale = (tempxscale - stretchDiv);
pmo->stretchslam = pzmom;
}
else
pmo->spritexscale = (tempxscale / 5);
pmo->spritexscale = (tempxscale/5);
pmo->spriteyscale = (tempyscale + ((stretchDiv * 2) / 3));
pmo->spriteyscale = (tempyscale + ((stretchDiv*2)/3));
}
}
else if (pmo->stretchslam > 0)
{
// Funni slam sound when landing
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*mapobjectscale))
if (cv_slamsound.value && (pmo->eflags & MFE_JUSTHITFLOOR) && !pmo->slamsoundtimer && (pmo->stretchslam > 4*FRACUNIT))
{
S_StartSound(pmo, sfx_s3k4c);
pmo->slamsoundtimer = TICRATE;
@@ -3381,9 +3370,9 @@ static void K_StretchPlayerGravity(player_t *player)
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, stretchScaleFactor);
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3 ) * 2));
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
pmo->spriteyscale = (tempyscale - slamDiv);
pmo->stretchslam -= (4*mapobjectscale);
pmo->stretchslam -= (4*FRACUNIT);
}
else
pmo->stretchslam = 0;
@@ -3398,16 +3387,16 @@ static void K_SaltySquish(player_t *player)
mobj_t *pmo = player->mo;
const fixed_t tempxscale = pmo->realxscale;
const fixed_t tempyscale = pmo->realyscale;
fixed_t tempxscale = pmo->realxscale;
fixed_t tempyscale = pmo->realyscale;
if (pmo->stretchslam > 0)
{
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, mapobjectscale*60); // stretchScaleFactor = FixedDiv(mapobjectscale*60, FRACUNIT)
const fixed_t slamDiv = FixedDiv(pmo->stretchslam, FRACUNIT*60); // stretchScaleFactor = FixedDiv(FRACUNIT*60, FRACUNIT)
pmo->spritexscale = (tempxscale + (((slamDiv * 2) / 3) * 2));
pmo->spritexscale = (tempxscale + (((slamDiv*2)/3)*2));
pmo->spriteyscale = (tempyscale - slamDiv);
pmo->stretchslam -= (4*mapobjectscale);
pmo->stretchslam -= (4*FRACUNIT);
}
else
pmo->stretchslam = 0;
@@ -3415,92 +3404,88 @@ static void K_SaltySquish(player_t *player)
static void K_QuiteSaltyHop(player_t *player)
{
I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo));
if (!cv_saltyhop.value)
return;
// what the fuck is this haya
mobj_t *pmo = player->mo;
salty_t *psalty = &player->salty;
if (!cv_saltyhop.value)
{
// reset before we leave
psalty->jump = psalty->ready = psalty->tapping = false;
psalty->momz = psalty->zoffset = 0;
return;
}
salty_t *psalt = &pmo->salty;
const boolean onground = P_IsObjectOnGround(pmo);
// ready?
if (!player->kartstuff[k_jmp])
{
psalty->ready = true;
psalty->tapping = false;
psalt->ready = true;
psalt->tapping = false;
}
else if (psalty->ready)
else if (psalt->ready)
{
psalty->ready = false;
psalty->tapping = true;
psalt->ready = false;
psalt->tapping = true;
}
else
{
psalty->tapping = false;
psalt->tapping = false;
}
// GO!
if (psalty->jump)
if (!psalt->init)
{
psalt->jump = false;
psalt->zoffset = 0;
psalt->momz = 0;
psalt->init = true;
}
else if (psalt->jump)
{
if (pmo->eflags & MFE_JUSTHITFLOOR)
{
psalty->zoffset = 0;
psalt->zoffset = 0;
}
else if (onground)
{
psalty->zoffset += psalty->momz;
psalty->momz -= (FRACUNIT*3/2);
psalt->zoffset += psalt->momz;
psalt->momz -= (FRACUNIT*3/2);
}
else
{
//psalty->zoffset *= (49/50)*FRACUNIT; // this just rounds down to 0 lol
psalty->zoffset = 0;
psalty->momz = 0;
psalt->zoffset *= (49/50)*FRACUNIT;
psalt->momz = 0;
}
if (psalty->zoffset <= 0)
if (psalt->zoffset <= 0)
{
if (cv_saltyhopsfx.value && !(pmo->eflags & MFE_JUSTHITFLOOR) && onground)
S_StartSound(pmo, sfx_s268);
psalty->jump = false;
psalty->zoffset = 0;
psalty->momz = 0;
psalt->jump = false;
psalt->zoffset = 0;
psalt->momz = 0;
// shlamma damma
if (cv_saltysquish.value)
pmo->stretchslam += 8*mapobjectscale;
pmo->stretchslam += 8*FRACUNIT;
}
else if (psalty->zoffset > 0)
else if (cv_saltysquish.value && psalt->zoffset >= 0)
{
if (cv_saltysquish.value)
{
// goofy ahh hack
pmo->spriteyscale += (FRACUNIT/8);
pmo->spritexscale -= (FRACUNIT/8);
}
// goofy ahh hack
pmo->spriteyscale += (FRACUNIT/8);
pmo->spritexscale -= (FRACUNIT/8);
}
pmo->spriteyoffset += FixedMul(psalty->zoffset, cv_saltyheight.value);
pmo->spriteyoffset += FixedMul(psalt->zoffset, cv_saltyheight.value);
// Stop any and all drift sounds when hopping.
if (S_SoundPlaying(pmo, sfx_screec))
S_StopSoundByID(pmo, sfx_screec);
if (S_SoundPlaying(pmo, sfx_drift))
S_StopSoundByID(pmo, sfx_drift);
if (cv_saltyhopsfx.value)
{
if (S_SoundPlaying(pmo, sfx_screec))
S_StopSoundByID(pmo, sfx_screec);
if (S_SoundPlaying(pmo, sfx_drift))
S_StopSoundByID(pmo, sfx_drift);
}
}
else if (psalty->tapping && onground && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer])
else if (psalt->tapping && onground && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer])
{
psalty->jump = true;
psalty->zoffset = 0;
psalty->momz = 6*FRACUNIT;
psalt->jump = true;
psalt->zoffset = 0;
psalt->momz = 6*FRACUNIT;
if (cv_saltyhopsfx.value)
S_StartSound(pmo, sfx_s25a);
}
@@ -3527,7 +3512,7 @@ boolean K_ShouldSlopeRoll(mobj_t *mobj)
return false;
// seeing a character rotate mid-hop looks really janky
if (!cv_saltyroll.value && mobj->player && mobj->player->salty.jump)
if (!cv_saltyroll.value && mobj->player && mobj->player->mo->salty.jump)
return false;
return K_CheckSlopeRollDist(mobj);
@@ -3739,7 +3724,7 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
dust = P_SpawnMobj(rand_x, rand_y, mo->z, MT_WIPEOUTTRAIL);
P_SetTarget(&dust->target, mo);
dust->angle = R_PointToAngle2(0, 0, mo->momx, mo->momy);
dust->angle = R_PointToAngle2(0,0,mo->momx,mo->momy);
dust->destscale = mo->scale;
P_SetScale(dust, mo->scale);
K_FlipFromObject(dust, mo);
@@ -3765,11 +3750,6 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent)
void K_DriftDustHandling(mobj_t *spawner)
{
angle_t anglediff;
#ifdef PHOBOS_BUILD
const fixed_t fscale = spawner->scale;
#else
static const fixed_t fscale = FRACUNIT; // should be spawner->scale but the below calls P_Random!
#endif
if (leveltime % 2 != 0 || !P_IsObjectOnGround(spawner))
return;
@@ -3786,7 +3766,7 @@ void K_DriftDustHandling(mobj_t *spawner)
{
angle_t playerangle = spawner->angle;
if (spawner->player->speed < (5 * fscale))
if (spawner->player->speed < 5<<FRACBITS)
return;
if (spawner->player->cmd.forwardmove < 0)
@@ -3797,7 +3777,7 @@ void K_DriftDustHandling(mobj_t *spawner)
}
else
{
if (P_AproxDistance(spawner->momx, spawner->momy) < (5 * fscale))
if (P_AproxDistance(spawner->momx, spawner->momy) < 5<<FRACBITS)
return;
anglediff = abs((signed)(spawner->angle - R_PointToAngle2(0, 0, spawner->momx, spawner->momy)));
@@ -3810,29 +3790,13 @@ void K_DriftDustHandling(mobj_t *spawner)
if (anglediff > ANG10*4) // Trying to turn further than 40 degrees
{
mobj_t *dust = NULL;
fixed_t spawnx = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
fixed_t spawny = P_RandomRange(-spawnrange, spawnrange)<<FRACBITS;
INT32 speedrange = 2;
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
const INT32 momxrand = P_RandomRange(-speedrange, speedrange);
const INT32 momyrand = P_RandomRange(-speedrange, speedrange);
const INT32 momzrand = P_RandomRange(1, 4);
if (P_MobjWasRemovedCompat(dust))
return;
#ifdef PHOBOS_BUILD
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
#else
dust->momx = FixedMul(spawner->momx + (momxrand<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (momyrand<<FRACBITS), 3*(spawner->scale)/4);
#endif
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
mobj_t *dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
dust->momx = FixedMul(spawner->momx + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momy = FixedMul(spawner->momy + (P_RandomRange(-speedrange, speedrange)<<FRACBITS), 3*(spawner->scale)/4);
dust->momz = P_MobjFlip(spawner) * (P_RandomRange(1, 4) * (spawner->scale));
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
dust->scalespeed = spawner->scale/12;
@@ -3841,33 +3805,6 @@ void K_DriftDustHandling(mobj_t *spawner)
S_StartSound(spawner, sfx_screec);
K_MatchGenericExtraFlags(dust, spawner);
#ifndef PHOBOS_BUILD
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// and we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the normal dust!
dust->flags2 |= MF2_DONTDRAW;
// now spawn our dust locally
dust = P_SpawnMobj(spawner->x + spawnx, spawner->y + spawny, spawner->z, MT_DRIFTDUST);
if (P_MobjWasRemovedCompat(dust))
return;
dust->momx = FixedMul(spawner->momx + (momxrand * spawner->scale), 3*FRACUNIT/4);
dust->momy = FixedMul(spawner->momy + (momyrand * spawner->scale), 3*FRACUNIT/4);
dust->momz = P_MobjFlip(spawner) * (momzrand * (spawner->scale));
P_SetScale(dust, spawner->scale/2);
dust->destscale = spawner->scale * 3;
dust->scalespeed = spawner->scale/12;
dust->islocal = true; // Keep this local!
K_MatchGenericExtraFlags(dust, spawner);
}
#endif
}
}
+1 -6
View File
@@ -182,19 +182,14 @@ void COM_Lua_f(void)
len = (argc+1)*256;
buf = malloc(len);
if (buf == NULL)
I_Error("Failed to allocate buffer for COM_Lua_f");
p = buf;
WRITEUINT8(p, argc);
for (i = 0; i < argc; i++)
WRITESTRINGN(p, COM_Argv(i), 255);
if (flags & COM_SPLITSCREEN)
if (flags & 2)
SendNetXCmdForPlayer(1, XD_LUACMD, buf, p-buf);
else
SendNetXCmd(XD_LUACMD, buf, p-buf);
free(buf);
return;
}
+2 -12
View File
@@ -13,13 +13,6 @@
#include <string.h>
#ifdef HAVE_THREADS
#include <threads.h>
#define local_for_thread thread_local
#else
#define local_for_thread
#endif
#include "doomdef.h"
#include "command.h"
#include "m_argv.h"
@@ -38,11 +31,8 @@ char **myargv = NULL;
boolean myargmalloc = false;
/** \brief founded the parm
*
* thread_local because it can potentially be used from multiple threads (global variables aaaaaa)
* (myargc and myargv don't have to be thread_local because they are never modified after being set up)
*/
static local_for_thread INT32 found;
static INT32 found;
/** \brief The M_CheckParm function
@@ -101,7 +91,7 @@ INT32 M_CheckProtoParam(const char *check)
const char *M_GetProtoParam(void)
{
INT32 i;
char *string;
static char *string;
for (i = 1; i < myargc; i++)
{
+13 -24
View File
@@ -3984,10 +3984,6 @@ menudemo_t *demolist = NULL; // Replays that that have been checked to match wit
menudemo_t *demolist_all = NULL; // All replays
size_t demolist_all_size = 0;
boolean replaynamesloaded = false;
// Whenever we start a replay load thread, we increment this number and then thread will remember current value,
// and by the end it will compare it with current value, and if it is equal it means thread can store data it has loaded.
// If it's not equal, that means we started more than one thread (left and re-entered menu for example)
size_t replaythreadnum = 0;
#ifdef HAVE_THREADS
I_mutex replayquerymutex;
@@ -4017,14 +4013,12 @@ static SINT8 replayScrollDelay = TICRATE, replayScrollDir = 1;
static void ReplayNamesLoadThread(void* userdata)
{
(void)userdata;
Lock_search_state();
size_t demolist_all_size_local = demolist_all_size;
menudemo_t *demolist_all_local = (menudemo_t*)malloc(sizeof(menudemo_t)*demolist_all_size_local);
memcpy(demolist_all_local, demolist_all, sizeof(menudemo_t)*demolist_all_size_local);
size_t localreplaythreadnum = replaythreadnum;
char *replaydirpath = (char*)userdata;
Unlock_search_state();
@@ -4044,7 +4038,7 @@ static void ReplayNamesLoadThread(void* userdata)
Lock_search_state();
if (replaythreadnum == localreplaythreadnum && demolist_all)
if (fastcmp(menupath, replaydirpath) && demolist_all)
{
memcpy(demolist_all, demolist_all_local, sizeof(menudemo_t)*demolist_all_size);
replaynamesloaded = true;
@@ -4053,20 +4047,22 @@ static void ReplayNamesLoadThread(void* userdata)
Unlock_search_state();
// Was allocated before thread start, we need to free it
free(replaydirpath);
free(demolist_all_local);
}
static void LoadReplayNames(void)
{
char *replaydirpath = strdup(menupath);
Lock_search_state();
replaythreadnum++;
replaynamesloaded = false;
Unlock_search_state();
#ifdef HAVE_THREADS
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, NULL);
I_spawn_thread("replay-names-load", ReplayNamesLoadThread, replaydirpath);
#else
ReplayNamesLoadThread(NULL);
ReplayNamesLoadThread(replaydirpath);
#endif
}
@@ -4105,12 +4101,8 @@ static void M_HutCheckReplays(size_t maxnum)
// Mark as done
replayqueryfound = replayquerycheck = sizedirmenu;
Lock_search_state();
memcpy(demolist, demolist_all, sizeof(menudemo_t) * sizedirmenu);
Unlock_search_state();
return;
}
@@ -4259,15 +4251,13 @@ static boolean M_HandleReplayHutQuery(INT32 choice)
char tmp[MAXREPLAYQUERY+1];
memcpy(tmp, replayqueryinput_buffer, MAXREPLAYQUERY+1);
// Honestly not sure if locks for replaynamesloaded are necessary...
// Thread sanitizer does report race condition whenever replaynamesloaded is accessed without lock
// but really it is only ever set to false in main thread and only set to true in replay load thread,
// and both are done via locks. If replaynamesloaded is true, it is never gonna suddenly switch from true to false
// while we're in main thread, and if it would switch from false to true it is not really a big deal, we will just skip
// 1 frame where replay names were loaded
Lock_search_state();
if (!replaynamesloaded)
{
Unlock_search_state();
return false;
}
Unlock_search_state();
if (M_TextInputHandle(&replayqueryinput, choice))
{
@@ -9939,7 +9929,6 @@ static void M_DrawLocalSkinMenu(void)
V_DrawFill(mx + 220 - (charw/2), my+54, charw, 84, 239);
#undef charw
// FIXME: is skins[displayskin.localnum] even correct?
UINT8 *colormap = R_GetLocalTranslationColormap(&skins[displayskin.localnum], (displayskin.localskin ? &localskins[displayskin.localnum] : NULL), cv_playercolor.value, GTC_MENUCACHE, displayskin.localskin);
V_DrawMappedPatch(mx, my+50, 0, (patch_t *)W_CachePatchName(displayskin.facewant, PU_PATCH), colormap);
@@ -9957,7 +9946,7 @@ static void M_DrawLocalSkinMenu(void)
my += 120;
#ifdef HWRENDER
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[displayskin.localnum] : &md2_playermodels[skintodisplay]);
md2_t *md2 = (displayskin.localskin ? &md2_localplayermodels[skintodisplay] : &md2_playermodels[skintodisplay]);
// if we have 3d models enabled and a model exists
// try to show it instead of the sprite
+60 -102
View File
@@ -6280,39 +6280,16 @@ static void P_MobjSceneryThink(mobj_t *mobj)
case MT_SMOLDERING:
if (leveltime % 2 == 0)
{
mobj_t *smoke;
fixed_t x = P_RandomRange(-35, 35)*mobj->scale;
fixed_t y = P_RandomRange(-35, 35)*mobj->scale;
fixed_t z = P_RandomRange(0, 70)*mobj->scale;
smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
mobj_t *smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
P_SetMobjState(smoke, S_OPAQUESMOKE1);
K_MatchGenericExtraFlags(smoke, mobj);
smoke->scale = mobj->scale * 2;
smoke->destscale = mobj->scale * 6;
const INT32 momrand = P_RandomRange(4, 9);
#ifdef PHOBOS_BUILD
smoke->momz = momrand*mobj->scale*P_MobjFlip(smoke);
#else
smoke->momz = momrand*FRACUNIT*P_MobjFlip(smoke);
// vanilla compat really is annoying.......
// but this stuff is messed up on mobjscaled maps
// so we gotta respawn it locally to avoid desynchs...
if (mapobjectscale != FRACUNIT)
{
// hide the smoke!
smoke->flags2 |= MF2_DONTDRAW;
smoke = P_SpawnMobj(mobj->x + x, mobj->y + y, mobj->z + z, MT_SMOKE);
P_SetMobjState(smoke, S_OPAQUESMOKE1);
K_MatchGenericExtraFlags(smoke, mobj);
smoke->scale = mobj->scale * 2;
smoke->destscale = mobj->scale * 6;
smoke->momz = momrand*mobj->scale*P_MobjFlip(smoke);
smoke->islocal = true; // Keep this local!
}
#endif
smoke->momz = P_RandomRange(4, 9)*FRACUNIT*P_MobjFlip(smoke);
}
break;
case MT_BOOMPARTICLE:
@@ -9187,12 +9164,6 @@ static boolean P_MobjPushableThink(mobj_t *mobj)
static void P_FiringThink(mobj_t *mobj)
{
if (!mobj->target)
return;
if (mobj->health <= 0)
return;
if (mobj->state->action == (actionf_p1)A_Boss1Laser)
{
var1 = mobj->state->var1;
@@ -9255,12 +9226,7 @@ void P_MobjThinker(mobj_t *mobj)
mobj->flags2 &= ~MF2_PUSHED;
mobj->eflags &= ~(MFE_SPRUNG|MFE_JUSTBOUNCEDWALL);
#ifdef PHOBOS_BUILD
P_SetTarget(&tmfloorthing, NULL);
P_SetTarget(&tmhitthing, NULL);
#else
tmfloorthing = tmhitthing = NULL;
#endif
// do NOT trigger linedef executors for "local" mobjs
if (!mobj->islocal)
@@ -9276,13 +9242,8 @@ void P_MobjThinker(mobj_t *mobj)
}
if (mobj->scale != mobj->destscale)
{
P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale.
if (P_MobjWasRemovedCompat(mobj))
return;
}
if (!mobj->player)
{
if (mobj->type == MT_GHOST && mobj->fuse > 0 // Not guaranteed to be MF_SCENERY or not MF_SCENERY!
@@ -9327,21 +9288,6 @@ void P_MobjThinker(mobj_t *mobj)
{
if (!P_MobjDeadThink(mobj))
return;
// Fading tile
if (mobj->type >= MT_BOUNCEPICKUP && mobj->type <= MT_GRENADEPICKUP)
{
INT32 value = mobj->info->damage/10;
value = mobj->fuse/value;
value = 10-value;
value--;
if (value <= 0)
value = 1;
mobj->frame &= ~FF_TRANSMASK;
mobj->frame |= value << FF_TRANSSHIFT;
}
}
else
{
@@ -9352,7 +9298,7 @@ void P_MobjThinker(mobj_t *mobj)
if (P_MobjWasRemoved(mobj))
return;
if (mobj->flags2 & MF2_FIRING)
if (mobj->flags2 & MF2_FIRING && mobj->target && mobj->health > 0)
P_FiringThink(mobj);
if (mobj->flags & MF_AMBIENT)
@@ -9419,27 +9365,23 @@ void P_MobjThinker(mobj_t *mobj)
P_ButteredSlope(mobj);
}
if (mobj->health)
if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health &&
P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz
{
// extra pit check in case these didn't have momz
if ((mobj->flags & (MF_ENEMY|MF_BOSS)) &&
P_CheckDeathPitCollide(mobj))
P_KillMobj(mobj, NULL, NULL);
return;
}
// Crush enemies!
if (mobj->ceilingz - mobj->floorz < mobj->height)
{
if (((mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->flags & MF_SHOOTABLE) || mobj->type == MT_EGGSHIELD) &&
!(mobj->flags & MF_NOCLIPHEIGHT) &&
mobj->health > 0)
{
P_KillMobj(mobj, NULL, NULL);
return;
}
// Crush enemies!
if ((mobj->ceilingz - mobj->floorz) < mobj->height)
{
if ((((mobj->flags & (MF_ENEMY|MF_BOSS)) && (mobj->flags & MF_SHOOTABLE)) || mobj->type == MT_EGGSHIELD) &&
!(mobj->flags & MF_NOCLIPHEIGHT) &&
mobj->health > 0)
{
P_KillMobj(mobj, NULL, NULL);
return;
}
}
}
if (P_MobjWasRemovedCompat(mobj))
@@ -9447,6 +9389,24 @@ void P_MobjThinker(mobj_t *mobj)
// Can end up here if a player dies.
P_CycleMobjState(mobj);
if (P_MobjWasRemoved(mobj))
return;
if ((mobj->health == 0) && // Fading tile
(mobj->type >= MT_BOUNCEPICKUP && mobj->type <= MT_GRENADEPICKUP))
{
INT32 value = mobj->info->damage/10;
value = mobj->fuse/value;
value = 10-value;
value--;
if (value <= 0)
value = 1;
mobj->frame &= ~FF_TRANSMASK;
mobj->frame |= value << FF_TRANSSHIFT;
}
}
// Quick, optimized function for the Rail Rings
@@ -9700,13 +9660,20 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mapobjectscale;
mobj->scalespeed = mapobjectscale/12;
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
if (mapobjectscale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
{
mobj->destscale = mapobjectscale;
mobj->scalespeed = mapobjectscale/12;
}
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->realxscale = mobj->realyscale =
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
// set subsector and/or block links
P_SetThingPosition(mobj);
@@ -10148,13 +10115,20 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
// All mobjs are created at 100% scale.
mobj->scale = FRACUNIT;
mobj->destscale = mapobjectscale;
mobj->scalespeed = mapobjectscale/12;
mobj->destscale = mobj->scale;
mobj->scalespeed = FRACUNIT/12;
if (mapobjectscale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN)
{
mobj->destscale = mapobjectscale;
mobj->scalespeed = mapobjectscale/12;
}
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->realxscale = mobj->realyscale =
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
// set subsector and/or block links
P_SetThingPosition(mobj);
@@ -10254,9 +10228,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
P_CalculatePrecipFloor(mobj);
if (mobj->floorz != starting_floorz)
{
; //mobj->precipflags |= PCF_FOF;
}
mobj->precipflags |= PCF_FOF;
else
{
const INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
@@ -10390,13 +10362,7 @@ void P_RemoveMobj(mobj_t *mobj)
// clear the reference from the mapthing
if (mobj->spawnpoint)
{
#ifdef PHOBOS_BUILD
P_SetTarget(&mobj->spawnpoint->mobj, NULL);
#else
mobj->spawnpoint->mobj = NULL;
#endif
}
R_RemoveMobjInterpolator(mobj);
@@ -10607,9 +10573,6 @@ void P_PrecipitationEffects(void)
P_SpawnLightningFlash(ss); // Spawn a quick flash thinker
}
if (sound_disabled)
return; // Sound off? D'aw, no fun.
const mobj_t *pmo = players[displayplayers[0]].mo;
// Local effects from here on out!
@@ -10617,6 +10580,9 @@ void P_PrecipitationEffects(void)
if (!playeringame[displayplayers[0]] || !pmo)
return;
if (sound_disabled)
return; // Sound off? D'aw, no fun.
const boolean sounds_rain = ((cv_drawdist_precip.value != 0) && rainsfx && (!leveltime || leveltime % 80 == 1));
if (!sounds_rain && !sounds_thunder)
@@ -10864,9 +10830,7 @@ void P_SpawnPlayer(INT32 playernum)
mobj_t *mobj;
if (p->playerstate == PST_REBORN)
{
G_PlayerReborn(playernum);
}
for (i = 0; i < MAXPLAYERS; i++)
{
@@ -10940,15 +10904,9 @@ void P_SpawnPlayer(INT32 playernum)
}
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
I_Assert(mobj != NULL);
#ifdef PHOBOS_BUILD
mobj->player = p;
P_SetTarget(&p->mo, mobj);
#else
(mobj->player = p)->mo = mobj;
#endif
//P_SetTarget(&p->mo, mobj);
mobj->angle = mobj->old_angle = 0;
+17 -3
View File
@@ -258,12 +258,23 @@ typedef enum
// PRECIPITATION flags ?! ?! ?!
//
typedef enum {
PCF_INVISIBLE = 1, // Don't draw.
PCF_INVISIBLE = 1, // Don't draw.
PCF_PIT = 1<<1, // Above pit.
PCF_SPLASH = 1<<2, // Splashed on the ground, return to the ceiling after the animation's over
PCF_THUNK = 1<<3, // Ran the thinker this tic.
PCF_FOF = 1<<2, // Above FOF.
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
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;
typedef struct salty_s
{
bool init;
bool ready;
bool tapping;
fixed_t zoffset;
fixed_t momz;
bool jump;
} salty_t;
// Map Object definition.
typedef struct mobj_s
@@ -401,6 +412,9 @@ typedef struct mobj_s
tic_t slamsoundtimer; // Funni slam sound when landing
// saltyhop! hardcode edition
salty_t salty;
// WARNING: New fields must be added separately to savegame and Lua.
boolean islocal; // BEWARE: islocal does not exist in vanilla, strictly to be used for locally loaded addons to not cause desynchs with the mobj linedef trigger check. DO NOT USE THIS IN ACTUAL ADDONS YOU INTEND TO USE ON YOUR SERVER
} mobj_t;
-36
View File
@@ -1109,10 +1109,6 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242)
return;
// do not send over locally spawned mobjs
if (mobj->islocal)
return;
if (mobj->spawnpoint && mobj->info->doomednum != -1)
{
// spawnpoint is not modified but we must save it since it is an identifier
@@ -1138,17 +1134,9 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
if (mobj->momx != 0 || mobj->momy != 0 || mobj->momz != 0)
#endif
diff |= MD_MOM;
#ifdef PHOBOS_BUILD
if (mobj->radius != FixedMul(mapobjectscale, mobj->info->radius))
#else
if (mobj->radius != mobj->info->radius)
#endif
diff |= MD_RADIUS;
#ifdef PHOBOS_BUILD
if (mobj->height != FixedMul(mapobjectscale, mobj->info->height))
#else
if (mobj->height != mobj->info->height)
#endif
diff |= MD_HEIGHT;
if (mobj->flags != mobj->info->flags)
diff |= MD_FLAGS;
@@ -1191,19 +1179,11 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
diff |= MD_MOVEFACTOR;
if (mobj->fuse)
diff |= MD_FUSE;
#ifdef PHOBOS_BUILD
if (mobj->watertop != INT32_MAX)
#else
if (mobj->watertop)
#endif
diff |= MD_WATERTOP;
if (mobj->waterbottom)
diff |= MD_WATERBOTTOM;
#ifdef PHOBOS_BUILD
if (mobj->scale != mapobjectscale)
#else
if (mobj->scale != FRACUNIT)
#endif
diff |= MD_SCALE;
if (mobj->destscale != mobj->scale)
diff |= MD_DSCALE;
@@ -2110,19 +2090,11 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
if (diff & MD_RADIUS)
mobj->radius = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->radius = FixedMul(mobj->info->radius, mapobjectscale);
#else
mobj->radius = mobj->info->radius;
#endif
if (diff & MD_HEIGHT)
mobj->height = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->height = FixedMul(mobj->info->height, mapobjectscale);
#else
mobj->height = mobj->info->height;
#endif
if (diff & MD_FLAGS)
mobj->flags = READUINT32(save->p);
else
@@ -2194,20 +2166,12 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
mobj->fuse = READINT32(save->p);
if (diff & MD_WATERTOP)
mobj->watertop = READFIXED(save->p);
#ifdef PHOBOS_BUILD
else
mobj->watertop = INT32_MAX;
#endif
if (diff & MD_WATERBOTTOM)
mobj->waterbottom = READFIXED(save->p);
if (diff & MD_SCALE)
mobj->scale = READFIXED(save->p);
else
#ifdef PHOBOS_BUILD
mobj->scale = mapobjectscale;
#else
mobj->scale = FRACUNIT;
#endif
if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save->p);
else
+7 -18
View File
@@ -570,13 +570,13 @@ static void P_LoadSegs(UINT8 *data)
if (seg->sidedef == &sides[seg->linedef->sidenum[0]])
{
seg->v1 = lines[rawlinedef].v1;
seg->v2 = lines[rawlinedef].v2;
seg->v1 = lines[ms->linedef].v1;
seg->v2 = lines[ms->linedef].v2;
}
else
{
seg->v1 = lines[rawlinedef].v2;
seg->v2 = lines[rawlinedef].v1;
seg->v1 = lines[ms->linedef].v2;
seg->v2 = lines[ms->linedef].v1;
}
}
else
@@ -584,6 +584,7 @@ static void P_LoadSegs(UINT8 *data)
seg->v1 = &vertexes[v1];
seg->v2 = &vertexes[v2];
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
@@ -596,6 +597,7 @@ static void P_LoadSegs(UINT8 *data)
//seg->fv2.z = FixedToFloat(seg->v2->z);
}
#endif
seg->length = P_SegLength(seg);
P_UpdateSegLightOffset(seg);
@@ -2094,13 +2096,6 @@ static void P_LoadMapBSP(const virtres_t* virt)
virtlump_t* virtsegs = vres_Find(virt, "SEGS");
virtlump_t* virtnodes = vres_Find(virt, "NODES");
if (!virtssectors)
I_Error("SSECTORS lump not found");
if (!virtsegs)
I_Error("SEGS lump not found");
if (!virtnodes)
I_Error("NODES lump not found");
numsubsectors = virtssectors->size / sizeof(mapsubsector_t);
numnodes = virtnodes->size / sizeof(mapnode_t);
numsegs = virtsegs->size / sizeof(mapseg_t);
@@ -3429,13 +3424,7 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local)
{
// check if someone tries to load maps locally lol
// do this here so we can skip loading the file anyways
int retmap = W_CheckAutoLoadContainsMap(wadfilename);
if (retmap == -1)
{
CONS_Alert(CONS_WARNING, "addilelocal: file %s was not found or not valid.\n", wadfilename);
return UINT16_MAX;
}
if (retmap > 0)
if (W_CheckAutoLoadContainsMap(wadfilename))
{
CONS_Alert(CONS_WARNING, "addilelocal: locally added file %s contains map data, this WILL cause crashes and desynchs! not added.\n", wadfilename);
return UINT16_MAX;
+3 -9
View File
@@ -1962,19 +1962,13 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (!dest)
return;
const angle_t ang = (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle;
const boolean dontstopmove = (line->flags & ML_EFFECT4) == ML_EFFECT4;
if (bot)
P_Teleport(bot, dest->x, dest->y, dest->z, ang, (line->flags & ML_BLOCKMONSTERS) == 0, dontstopmove);
P_Teleport(bot, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, (line->flags & ML_BLOCKMONSTERS) == 0, (line->flags & ML_EFFECT4) == ML_EFFECT4);
if (line->flags & ML_BLOCKMONSTERS)
{
P_Teleport(mo, dest->x, dest->y, dest->z, ang, false, dontstopmove);
}
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, false, (line->flags & ML_EFFECT4) == ML_EFFECT4);
else
{
P_Teleport(mo, dest->x, dest->y, dest->z, ang, true, dontstopmove);
P_Teleport(mo, dest->x, dest->y, dest->z, (line->flags & ML_NOCLIMB) ? mo->angle : dest->angle, true, (line->flags & ML_EFFECT4) == ML_EFFECT4);
// Play the 'bowrwoosh!' sound
S_StartSound(dest, sfx_mixup);
}
+11 -17
View File
@@ -91,7 +91,7 @@ void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move)
mo->momx = FixedMul(move, FINECOSINE(angle));
if (!twodmo(mo))
mo->momy = FixedMul(move, FINESINE(angle));
mo->momy = FixedMul(move,FINESINE(angle));
}
void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move)
@@ -4517,33 +4517,27 @@ static void DoABarrelRoll(player_t *player)
static void P_DoFunnyDance(player_t *player)
{
fixed_t bpm; // 140bpm ish
fixed_t work, ang, bounce; // hehe squishy
I_Assert(player != NULL);
I_Assert(!P_MobjWasRemoved(player->mo));
if (player->spectator)
if (player->spectator || !player->mo || player->kartstuff[k_respawn] || player->mo->salty.jump) // this looks jank as hell during hop
return;
// this looks jank as hell during hop or respawn
if (player->kartstuff[k_respawn] || player->salty.jump)
return;
player->squishdance.bounce = 0;
// bpm = FixedDiv((60*TICRATE)<<FRACBITS, FLOAT_TO_FIXED(mapmusic.bpm)); << maybe can get the tempo and beat detection lib to work for bpm autodetection
bpm = ((60*TICRATE) / (cv_squishdancespeed.value)) << FRACBITS;
bpm = FixedDiv((60*TICRATE)<<FRACBITS, FLOAT_TO_FIXED((float)cv_squishdancespeed.value));
work = (player->squishdance.time << FRACBITS) % bpm;
player->squishdance.work = (player->squishdance.time << FRACBITS) % bpm;
if (player->squishdance.time >= (FRACUNIT >> 1)) // prevent overflow jump - takes about 15 minutes
player->squishdance.time = (work >> FRACBITS);
player->squishdance.time = (player->squishdance.work >> FRACBITS);
work = FixedDiv(work*180, bpm);
player->squishdance.work = FixedDiv(player->squishdance.work*180, bpm);
ang = ((FixedAngle(work) >> ANGLETOFINESHIFT) & FINEMASK);
bounce = ((FINESINE(ang) - FRACUNIT/2) / 2);
player->squishdance.ang = ((FixedAngle(player->squishdance.work) >> ANGLETOFINESHIFT) & FINEMASK);
player->squishdance.bounce = ((FINESINE(player->squishdance.ang) - FRACUNIT/2) / 2);
player->mo->spritexscale -= bounce;
player->mo->spriteyscale += bounce;
player->mo->spritexscale -= player->squishdance.bounce;
player->mo->spriteyscale += player->squishdance.bounce;
player->squishdance.time++;
}
+1 -1
View File
@@ -6,7 +6,7 @@
// Copyright (C) 1996 by id Software, Inc.
// Copyright (C) 1999 by Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
// Copyright (C) 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) Copyright 2005, 2006 by Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
// Copyright (C) 2013 by James Haley, Stephen McGranahan, et al.
//
// This program is free software distributed under the
+38 -6
View File
@@ -61,6 +61,7 @@ fixed_t rw_distance = 0;
static INT32 rw_x, rw_stopx;
static angle_t rw_centerangle;
static fixed_t rw_offset;
static fixed_t rw_offset2; // for splats
static fixed_t rw_scale, rw_scalestep;
static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid;
static INT32 worldtop, worldbottom, worldhigh, worldlow;
@@ -263,7 +264,12 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
else if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
walllights = R_GetWallLight(lightnum);
if (lightnum < 0)
walllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
walllights = scalelight[LIGHTLEVELS - 1];
else
walllights = scalelight[lightnum];
}
if (frontsector->heightsec != -1)
@@ -365,7 +371,12 @@ static void R_RenderMaskedSegLoop(drawcolumndata_t* dc, drawseg_t *drawseg, INT3
lightnum = rlight->lightnum;
xwalllights = R_GetWallLight(lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
@@ -813,7 +824,12 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
else if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
walllights = R_GetWallLight(lightnum);
if (lightnum < 0)
walllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
walllights = scalelight[LIGHTLEVELS-1];
else
walllights = scalelight[lightnum];
}
maskedtexturecol = drawseg->thicksidecol;
@@ -955,7 +971,12 @@ void R_RenderThickSideRange(drawseg_t *drawseg, INT32 x1, INT32 x2, ffloor_t *pf
lightnum = rlight->lightnum;
xwalllights = R_GetWallLight(lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
@@ -1446,7 +1467,12 @@ static void R_RenderSegLoop(drawcolumndata_t* dc)
else if (P_ApplyLightOffset(lightnum, curline->frontsector))
lightnum += curline->lightOffset;
xwalllights = R_GetWallLight(lightnum);
if (lightnum < 0)
xwalllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
xwalllights = scalelight[LIGHTLEVELS-1];
else
xwalllights = scalelight[lightnum];
pindex = FixedMul(rw_scale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
@@ -2525,6 +2551,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_offset = -rw_offset;
/// don't use texture offset for splats
rw_offset2 = rw_offset + curline->offset;
rw_offset += sidedef->textureoffset + curline->offset;
rw_centerangle = ANGLE_90 + viewangle - rw_normalangle;
@@ -2537,7 +2564,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (P_ApplyLightOffset(lightnum, frontsector))
lightnum += curline->lightOffset;
walllights = R_GetWallLight(lightnum);
if (lightnum < 0)
walllights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
walllights = scalelight[LIGHTLEVELS - 1];
else
walllights = scalelight[lightnum];
}
// if a floor / ceiling plane is on the wrong side
-5
View File
@@ -22,11 +22,6 @@ extern "C" {
#pragma interface
#endif
FUNCINLINE static ATTRINLINE lighttable_t** R_GetWallLight(INT32 llevel)
{
return scalelight[CLAMP(llevel, 0, LIGHTLEVELS-1)];
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop);
+20 -5
View File
@@ -1062,7 +1062,12 @@ static void R_SplitSprite(vissprite_t *sprite)
{
INT32 lightnum = R_GetSoftLightlevel(*sector->lightlist[i].lightlevel);
spritelights = R_GetWallLight(lightnum);
if (lightnum < 0)
spritelights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
spritelights = scalelight[LIGHTLEVELS-1];
else
spritelights = scalelight[lightnum];
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
@@ -1740,7 +1745,12 @@ static void R_ProjectSprite(mobj_t *thing)
}
}
lights_array = R_GetWallLight(lightnum);
if (lightnum < 0)
lights_array = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
lights_array = scalelight[LIGHTLEVELS-1];
else
lights_array = scalelight[lightnum];
}
// store information in a vissprite
@@ -2077,11 +2087,16 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
if (!sec->numlights)
{
if (sec->heightsec == -1)
lightlevel = sec->lightlevel;
if (sec->heightsec == -1) lightlevel = sec->lightlevel;
lightnum = R_GetSoftLightlevel(lightlevel);
spritelights = R_GetWallLight(lightnum);
if (lightnum < 0)
spritelights = scalelight[0];
else if (lightnum >= LIGHTLEVELS)
spritelights = scalelight[LIGHTLEVELS-1];
else
spritelights = scalelight[lightnum];
}
// Handle all things in sector.
+3 -8
View File
@@ -233,25 +233,20 @@ if(${SDL2_FOUND})
-DHAVE_THREADS
)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE AND NOT SRB2_CONFIG_ASAN AND NOT SRB2_CONFIG_UBSAN AND NOT SRB2_CONFIG_TSAN)
if(SRB2_CONFIG_LTO AND NOT SRB2_CONFIG_DEBUGMODE)
set_property(TARGET SRB2SDL2 PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(SRB2_CONFIG_ASAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=address -fno-omit-frame-pointer -fno-common)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=address)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=address)
endif()
if(SRB2_CONFIG_UBSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=undefined -fno-omit-frame-pointer)
target_compile_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=undefined)
endif()
if(SRB2_CONFIG_TSAN)
target_compile_options(SRB2SDL2 PRIVATE -O1 -fsanitize=thread -fno-omit-frame-pointer)
target_link_options(SRB2SDL2 PRIVATE -fsanitize=thread)
endif()
if(NOT SRB2_CONFIG_MUMBLE)
target_compile_options(SRB2SDL2 PRIVATE -DNOMUMBLE)
endif()
+21
View File
@@ -804,6 +804,27 @@ void* Z_LevelPoolMalloc(size_t size)
return p;
}
boolean Z_IsMobjValid2(void *p, const char *file, INT32 line)
{
//(void)file;
//(void)line;
// mobj was removed
// no need to worry here
if (p == NULL)
return false;
// mobjs reside in the large pool
if (!g_level_large_pool.ptrcheck(p))
{
//I_Error("invalid mobj! at %s:%d", file, line);
CONS_Alert(CONS_ERROR, "invalid mobj! at %s:%d", file, line);
return false;
}
return true;
}
void* Z_LevelPoolCalloc(size_t size)
{
void* p = Z_LevelPoolMalloc(size);
+2
View File
@@ -173,6 +173,8 @@ char *Z_StrDup(const char *in);
size_t Z_LevelPoolUsage(void);
void *Z_LevelPoolMalloc(size_t size);
void *Z_LevelPoolCalloc(size_t size);
#define Z_IsMobjValid(p) Z_IsMobjValid2(p, __FILE__, __LINE__)
boolean Z_IsMobjValid2(void *p, const char *file, INT32 line);
void Z_LevelPoolFree(void *p, size_t size);
// for use with CLEANUP macro