mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-05 07:51:42 +00:00
Merge branch SRB2:next into disable-powerup-hud
This commit is contained in:
commit
5bbc1e323a
13 changed files with 275 additions and 253 deletions
|
@ -55,7 +55,7 @@ static UINT8 *demobuffer = NULL;
|
|||
static UINT8 *demo_p, *demotime_p;
|
||||
static UINT8 *demoend;
|
||||
static UINT8 demoflags;
|
||||
static UINT16 demoversion;
|
||||
UINT16 demoversion;
|
||||
boolean singledemo; // quit after playing a demo from cmdline
|
||||
boolean demo_start; // don't start playing demo right away
|
||||
boolean demo_forwardmove_rng; // old demo backwards compatibility
|
||||
|
@ -98,7 +98,7 @@ demoghost *ghosts = NULL;
|
|||
// DEMO RECORDING
|
||||
//
|
||||
|
||||
#define DEMOVERSION 0x0010
|
||||
#define DEMOVERSION 0x0011
|
||||
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
|
||||
|
||||
#define DF_GHOST 0x01 // This demo contains ghost data too!
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
// demoplaying back and demo recording
|
||||
extern boolean demoplayback, titledemo, demorecording, timingdemo;
|
||||
extern tic_t demostarttime;
|
||||
extern UINT16 demoversion;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
@ -116,8 +116,36 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
polygonArray[polygonArraySize].texture = current_texture;
|
||||
polygonArray[polygonArraySize].shader = shader;
|
||||
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
|
||||
// default to polygonArraySize so we don't lose order on horizon lines
|
||||
// (yes, it's supposed to be negative, since we're sorting in that direction)
|
||||
polygonArray[polygonArraySize].hash = -polygonArraySize;
|
||||
polygonArraySize++;
|
||||
|
||||
if (!(PolyFlags & PF_NoTexture) && !horizonSpecial)
|
||||
{
|
||||
// use FNV-1a to hash polygons for later sorting.
|
||||
INT32 hash = 0x811c9dc5;
|
||||
#define DIGEST(h, x) h ^= (x); h *= 0x01000193
|
||||
if (current_texture)
|
||||
{
|
||||
DIGEST(hash, current_texture->downloaded);
|
||||
}
|
||||
DIGEST(hash, PolyFlags);
|
||||
DIGEST(hash, pSurf->PolyColor.rgba);
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
DIGEST(hash, shader);
|
||||
DIGEST(hash, pSurf->TintColor.rgba);
|
||||
DIGEST(hash, pSurf->FadeColor.rgba);
|
||||
DIGEST(hash, pSurf->LightInfo.light_level);
|
||||
DIGEST(hash, pSurf->LightInfo.fade_start);
|
||||
DIGEST(hash, pSurf->LightInfo.fade_end);
|
||||
}
|
||||
#undef DIGEST
|
||||
// remove the sign bit to ensure that skybox and horizon line comes first.
|
||||
polygonArray[polygonArraySize-1].hash = (hash & INT32_MAX);
|
||||
}
|
||||
|
||||
memcpy(&unsortedVertexArray[unsortedVertexArraySize], pOutVerts, iNumPts * sizeof(FOutVector));
|
||||
unsortedVertexArraySize += iNumPts;
|
||||
}
|
||||
|
@ -135,84 +163,7 @@ static int comparePolygons(const void *p1, const void *p2)
|
|||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
UINT32 downloaded1 = 0;
|
||||
UINT32 downloaded2 = 0;
|
||||
|
||||
int shader1 = poly1->shader;
|
||||
int shader2 = poly2->shader;
|
||||
// make skywalls and horizon lines first in order
|
||||
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
|
||||
shader1 = -1;
|
||||
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
|
||||
shader2 = -1;
|
||||
diff = shader1 - shader2;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (shader1 == -1 && shader2 == -1)
|
||||
return index1 - index2;
|
||||
|
||||
if (poly1->texture)
|
||||
downloaded1 = poly1->texture->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
if (poly2->texture)
|
||||
downloaded2 = poly2->texture->downloaded;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
diff = poly1->polyFlags - poly2->polyFlags;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
|
||||
diff = poly1->surf.LightInfo.light_level - poly2->surf.LightInfo.light_level;
|
||||
if (diff != 0) return diff;
|
||||
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
|
||||
if (diff != 0) return diff;
|
||||
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned int index1 = *(const unsigned int*)p1;
|
||||
unsigned int index2 = *(const unsigned int*)p2;
|
||||
PolygonArrayEntry* poly1 = &polygonArray[index1];
|
||||
PolygonArrayEntry* poly2 = &polygonArray[index2];
|
||||
int diff;
|
||||
INT64 diff64;
|
||||
|
||||
GLMipmap_t *texture1 = poly1->texture;
|
||||
GLMipmap_t *texture2 = poly2->texture;
|
||||
UINT32 downloaded1 = 0;
|
||||
UINT32 downloaded2 = 0;
|
||||
if (poly1->polyFlags & PF_NoTexture || poly1->horizonSpecial)
|
||||
texture1 = NULL;
|
||||
if (poly2->polyFlags & PF_NoTexture || poly2->horizonSpecial)
|
||||
texture2 = NULL;
|
||||
if (texture1)
|
||||
downloaded1 = texture1->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
if (texture2)
|
||||
downloaded2 = texture2->downloaded;
|
||||
// skywalls and horizon lines must retain their order for horizon lines to work
|
||||
if (!texture1 && !texture2)
|
||||
return index1 - index2;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
diff = poly1->polyFlags - poly2->polyFlags;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||
|
||||
return 0;
|
||||
return poly1->hash - poly2->hash;
|
||||
}
|
||||
|
||||
// This function organizes the geometry collected by HWR_ProcessPolygon calls into batches and uses
|
||||
|
@ -263,10 +214,7 @@ void HWR_RenderBatches(void)
|
|||
|
||||
// sort polygons
|
||||
PS_START_TIMING(ps_hw_batchsorttime);
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||
else
|
||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygonsNoShaders);
|
||||
qsort(polygonIndexArray, polygonArraySize, sizeof(unsigned int), comparePolygons);
|
||||
PS_STOP_TIMING(ps_hw_batchsorttime);
|
||||
// sort order
|
||||
// 1. shader
|
||||
|
@ -362,46 +310,45 @@ void HWR_RenderBatches(void)
|
|||
{
|
||||
// check if a state change is required, set the change bools and next vars
|
||||
int nextIndex = polygonIndexArray[polygonReadPos];
|
||||
nextShader = polygonArray[nextIndex].shader;
|
||||
nextTexture = polygonArray[nextIndex].texture;
|
||||
nextPolyFlags = polygonArray[nextIndex].polyFlags;
|
||||
nextSurfaceInfo = polygonArray[nextIndex].surf;
|
||||
if (nextPolyFlags & PF_NoTexture)
|
||||
nextTexture = 0;
|
||||
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
|
||||
if (polygonArray[index].hash != polygonArray[nextIndex].hash)
|
||||
{
|
||||
changeState = true;
|
||||
changeShader = true;
|
||||
}
|
||||
if (currentTexture != nextTexture)
|
||||
{
|
||||
changeState = true;
|
||||
changeTexture = true;
|
||||
}
|
||||
if (currentPolyFlags != nextPolyFlags)
|
||||
{
|
||||
changeState = true;
|
||||
changePolyFlags = true;
|
||||
}
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
||||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
|
||||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
||||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
|
||||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
|
||||
nextShader = polygonArray[nextIndex].shader;
|
||||
nextTexture = polygonArray[nextIndex].texture;
|
||||
nextPolyFlags = polygonArray[nextIndex].polyFlags;
|
||||
nextSurfaceInfo = polygonArray[nextIndex].surf;
|
||||
if (nextPolyFlags & PF_NoTexture)
|
||||
nextTexture = 0;
|
||||
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
changeState = true;
|
||||
changeSurfaceInfo = true;
|
||||
changeShader = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba)
|
||||
if (currentTexture != nextTexture)
|
||||
{
|
||||
changeState = true;
|
||||
changeSurfaceInfo = true;
|
||||
changeTexture = true;
|
||||
}
|
||||
if (currentPolyFlags != nextPolyFlags)
|
||||
{
|
||||
changePolyFlags = true;
|
||||
}
|
||||
if (cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
||||
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
|
||||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
||||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
|
||||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
|
||||
{
|
||||
changeSurfaceInfo = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba)
|
||||
{
|
||||
changeSurfaceInfo = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,36 +370,39 @@ void HWR_RenderBatches(void)
|
|||
if (stopFlag) break;
|
||||
|
||||
// change state according to change bools and next vars, update current vars and reset bools
|
||||
if (changeShader)
|
||||
if (changeState)
|
||||
{
|
||||
HWD.pfnSetShader(nextShader);
|
||||
currentShader = nextShader;
|
||||
changeShader = false;
|
||||
if (changeShader)
|
||||
{
|
||||
HWD.pfnSetShader(nextShader);
|
||||
currentShader = nextShader;
|
||||
changeShader = false;
|
||||
|
||||
ps_hw_numshaders.value.i++;
|
||||
}
|
||||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
ps_hw_numshaders.value.i++;
|
||||
}
|
||||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
|
||||
ps_hw_numtextures.value.i++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
{
|
||||
currentPolyFlags = nextPolyFlags;
|
||||
changePolyFlags = false;
|
||||
ps_hw_numtextures.value.i++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
{
|
||||
currentPolyFlags = nextPolyFlags;
|
||||
changePolyFlags = false;
|
||||
|
||||
ps_hw_numpolyflags.value.i++;
|
||||
}
|
||||
if (changeSurfaceInfo)
|
||||
{
|
||||
currentSurfaceInfo = nextSurfaceInfo;
|
||||
changeSurfaceInfo = false;
|
||||
ps_hw_numpolyflags.value.i++;
|
||||
}
|
||||
if (changeSurfaceInfo)
|
||||
{
|
||||
currentSurfaceInfo = nextSurfaceInfo;
|
||||
changeSurfaceInfo = false;
|
||||
|
||||
ps_hw_numcolors.value.i++;
|
||||
ps_hw_numcolors.value.i++;
|
||||
}
|
||||
}
|
||||
// and that should be it?
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ typedef struct
|
|||
int shader;
|
||||
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
|
||||
boolean horizonSpecial;
|
||||
INT32 hash;
|
||||
} PolygonArrayEntry;
|
||||
|
||||
void HWR_StartBatching(void);
|
||||
|
|
|
@ -1626,17 +1626,22 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
|
||||
side_t *side = &sides[rover->master->sidenum[0]];
|
||||
|
||||
INT16 lineflags;
|
||||
boolean do_texture_skew;
|
||||
boolean dont_peg_bottom;
|
||||
|
||||
if (rover->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = gl_curline->linedef-gl_backsector->lines[0];
|
||||
newline = rover->master->frontsector->lines[0] + linenum;
|
||||
side = &sides[newline->sidenum[0]];
|
||||
lineflags = newline->flags;
|
||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
else
|
||||
lineflags = gl_curline->linedef->flags;
|
||||
{
|
||||
do_texture_skew = rover->master->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = gl_curline->linedef->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
|
||||
texnum = R_GetTextureNum(side->midtexture);
|
||||
|
||||
|
@ -1675,15 +1680,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// ...Oh well, anyway, Lower Unpegged now changes pegging of FOFs like in software
|
||||
// -- Monster Iestyn 26/06/18
|
||||
fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
|
||||
boolean attachtobottom = !!(lineflags & ML_DONTPEGBOTTOM);
|
||||
|
||||
grTex = HWR_GetTexture(texnum);
|
||||
xscale = FixedToFloat(side->scalex_mid);
|
||||
yscale = FixedToFloat(side->scaley_mid);
|
||||
|
||||
if (!(lineflags & ML_SKEWTD)) // no skewing
|
||||
if (!do_texture_skew) // no skewing
|
||||
{
|
||||
if (attachtobottom)
|
||||
if (dont_peg_bottom)
|
||||
texturevpeg -= (*rover->topheight - *rover->bottomheight) * yscale;
|
||||
|
||||
wallVerts[3].t = (((*rover->topheight - h) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
|
@ -1693,7 +1697,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!attachtobottom) // skew by top
|
||||
if (!dont_peg_bottom) // skew by top
|
||||
{
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = (((h - l) * yscale) + texturevpeg) * grTex->scaleY;
|
||||
|
|
|
@ -415,16 +415,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
|
||||
//CONS_Printf("\x82%s ", player_names[pnum]);
|
||||
|
||||
// If a verified admin banned someone, the server needs to know about it.
|
||||
// If the playernum isn't zero (the server) then the server needs to record the ban.
|
||||
if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN))
|
||||
{
|
||||
if (I_Ban && !I_Ban(playernode[(INT32)pnum]))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||
else
|
||||
Ban_Add(reason);
|
||||
}
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case KICK_MSG_GO_AWAY:
|
||||
|
@ -500,6 +490,16 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
|||
break;
|
||||
}
|
||||
|
||||
// If a verified admin banned someone, the server needs to know about it.
|
||||
// If the playernum isn't zero (the server) then the server needs to record the ban.
|
||||
if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN))
|
||||
{
|
||||
if (I_Ban && !I_Ban(playernode[(INT32)pnum]))
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
|
||||
else
|
||||
Ban_Add(msg == KICK_MSG_CUSTOM_BAN ? reason : NULL);
|
||||
}
|
||||
|
||||
if (pnum == consoleplayer)
|
||||
{
|
||||
LUA_HookBool(false, HOOK(GameQuit));
|
||||
|
|
|
@ -134,6 +134,7 @@ typedef union
|
|||
#include "d_netfil.h"
|
||||
#include "i_tcp.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../i_threads.h"
|
||||
|
||||
#include "../doomstat.h"
|
||||
|
||||
|
@ -263,12 +264,33 @@ static const char* inet_ntopA(short af, const void *cp, char *buf, socklen_t len
|
|||
|
||||
#ifdef HAVE_MINIUPNPC // based on old XChat patch
|
||||
static void I_ShutdownUPnP(void);
|
||||
static void I_InitUPnP(void);
|
||||
I_mutex upnp_mutex;
|
||||
static struct UPNPUrls urls;
|
||||
static struct IGDdatas data;
|
||||
static char lanaddr[64];
|
||||
|
||||
static inline void I_InitUPnP(void)
|
||||
struct upnpdata
|
||||
{
|
||||
int upnpc_started;
|
||||
};
|
||||
static struct upnpdata *upnpuser;
|
||||
static void init_upnpc_once(struct upnpdata *upnpdata);
|
||||
|
||||
static void I_InitUPnP(void)
|
||||
{
|
||||
upnpuser = malloc(sizeof *upnpuser);
|
||||
upnpuser->upnpc_started = 0;
|
||||
I_spawn_thread("init_upnpc_once", (I_thread_fn)init_upnpc_once, upnpuser);
|
||||
}
|
||||
|
||||
static void
|
||||
init_upnpc_once(struct upnpdata *upnpuserdata)
|
||||
{
|
||||
|
||||
if (upnpuserdata->upnpc_started != 0)
|
||||
return;
|
||||
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
const char * const deviceTypes[] = {
|
||||
"urn:schemas-upnp-org:device:InternetGatewayDevice:2",
|
||||
"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
|
||||
|
@ -311,35 +333,43 @@ static inline void I_InitUPnP(void)
|
|||
I_AddExitFunc(I_ShutdownUPnP);
|
||||
}
|
||||
freeUPNPDevlist(devlist);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
}
|
||||
else if (upnp_error == UPNPDISCOVER_SOCKET_ERROR)
|
||||
{
|
||||
CONS_Printf(M_GetText("No UPnP devices discovered\n"));
|
||||
}
|
||||
upnpuserdata->upnpc_started =1;
|
||||
}
|
||||
|
||||
static inline void I_UPnP_add(const char * addr, const char *port, const char * servicetype)
|
||||
{
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
if (addr == NULL)
|
||||
addr = lanaddr;
|
||||
if (!urls.controlURL || urls.controlURL[0] == '\0')
|
||||
return;
|
||||
UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
|
||||
port, port, addr, "SRB2", servicetype, NULL, NULL);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
}
|
||||
|
||||
static inline void I_UPnP_rem(const char *port, const char * servicetype)
|
||||
{
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
if (!urls.controlURL || urls.controlURL[0] == '\0')
|
||||
return;
|
||||
UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype,
|
||||
port, servicetype, NULL);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
}
|
||||
|
||||
static void I_ShutdownUPnP(void)
|
||||
{
|
||||
I_UPnP_rem(serverport_name, "UDP");
|
||||
I_lock_mutex(&upnp_mutex);
|
||||
FreeUPNPUrls(&urls);
|
||||
I_unlock_mutex(upnp_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7975,6 +7975,18 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
{
|
||||
clientGamedata->mapvisited[gamemap-1] |= MV_VISITED;
|
||||
serverGamedata->mapvisited[gamemap-1] |= MV_VISITED;
|
||||
|
||||
M_SilentUpdateUnlockablesAndEmblems(serverGamedata);
|
||||
|
||||
if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k68);
|
||||
G_SaveGameData(clientGamedata);
|
||||
}
|
||||
else if (!reloadinggamestate)
|
||||
{
|
||||
G_SaveGameData(clientGamedata);
|
||||
}
|
||||
}
|
||||
|
||||
levelloading = false;
|
||||
|
|
59
src/p_user.c
59
src/p_user.c
|
@ -19,6 +19,7 @@
|
|||
#include "d_event.h"
|
||||
#include "netcode/d_net.h"
|
||||
#include "netcode/net_command.h"
|
||||
#include "g_demo.h" // demoplayback, demoversion
|
||||
#include "g_game.h"
|
||||
#include "p_local.h"
|
||||
#include "r_fps.h"
|
||||
|
@ -7521,49 +7522,46 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
newangle = 270;
|
||||
}
|
||||
else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axises.
|
||||
{
|
||||
newangle = (INT16)FixedInt(AngleFixed(R_PointToAngle2(0,0, cmd->sidemove*FRACUNIT, cmd->forwardmove*FRACUNIT)));
|
||||
|
||||
if (cmd->forwardmove == -36 && cmd->sidemove == 35 && !(demoplayback && demoversion < 0x0011))
|
||||
newangle = 315; // Hack to compensate for directly down-right returning 314, not 315
|
||||
}
|
||||
|
||||
newangle -= player->viewrollangle / ANG1;
|
||||
|
||||
if (newangle < 0 && moved)
|
||||
newangle = (INT16)(360+newangle);
|
||||
}
|
||||
|
||||
if (player->pflags & PF_DRILLING)
|
||||
thrustfactor = 2;
|
||||
else
|
||||
{
|
||||
thrustfactor = 8;
|
||||
|
||||
// Decelerate while turning normally.
|
||||
if (moved && player->flyangle != newangle && player->speed > 12000)
|
||||
player->speed -= 60;
|
||||
}
|
||||
|
||||
for (i = 0; i < thrustfactor; i++)
|
||||
{
|
||||
if (moved && player->flyangle != newangle)
|
||||
{
|
||||
INT32 anglediff = (((newangle-player->flyangle)+360)%360);
|
||||
INT32 angledif2 = (((player->flyangle-newangle)+360)%360);
|
||||
// "player->flyangle" is our current angle, "newangle" is where we want to go
|
||||
INT32 anglediff = ((newangle - player->flyangle) + 360) % 360; // "+360" and then "%360" wraps it to 0-359
|
||||
|
||||
// player->flyangle is the one to move
|
||||
// newangle is the "move to"
|
||||
if (anglediff == 0 && angledif2 == 0)
|
||||
break;
|
||||
// How sharply can we turn?
|
||||
if (player->pflags & PF_DRILLING)
|
||||
thrustfactor = 2;
|
||||
else
|
||||
{
|
||||
thrustfactor = 8;
|
||||
if (player->speed > 12000) // Decelerate while turning normally
|
||||
player->speed -= 60;
|
||||
}
|
||||
|
||||
if (anglediff>angledif2)
|
||||
player->flyangle--;
|
||||
else // if (anglediff<angledif2)
|
||||
player->flyangle++;
|
||||
// Now, turn!
|
||||
if (anglediff <= thrustfactor || anglediff >= (360-thrustfactor))
|
||||
player->flyangle = newangle;
|
||||
else if (anglediff <= 180)
|
||||
player->flyangle += thrustfactor;
|
||||
else
|
||||
player->flyangle -= thrustfactor;
|
||||
|
||||
player->flyangle = (player->flyangle + 360) % 360; // Buff out negatives, >360 angles...
|
||||
}
|
||||
|
||||
// Buff out negatives, >360 angles...
|
||||
player->flyangle = ((player->flyangle + 360) % 360);
|
||||
}
|
||||
|
||||
if (!(player->speed)
|
||||
&& cmd->forwardmove == 0)
|
||||
if (player->speed == 0 && cmd->forwardmove == 0 && (cmd->sidemove == 0 || (demoplayback && demoversion < 0x0011)))
|
||||
still = true;
|
||||
|
||||
// No more bumper braking
|
||||
|
@ -7724,6 +7722,9 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
visangle += 180;
|
||||
}
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP) // Flip the roll angle in reverse gravity
|
||||
visangle *= -1;
|
||||
|
||||
rollangle = FixedAngle(visangle<<FRACBITS);
|
||||
}
|
||||
}
|
||||
|
|
43
src/r_main.c
43
src/r_main.c
|
@ -1023,26 +1023,43 @@ void R_Init(void)
|
|||
boolean R_IsPointInSector(sector_t *sector, fixed_t x, fixed_t y)
|
||||
{
|
||||
size_t i;
|
||||
line_t *closest = NULL;
|
||||
fixed_t closestdist = INT32_MAX;
|
||||
size_t passes = 0;
|
||||
|
||||
for (i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
vertex_t v;
|
||||
fixed_t dist;
|
||||
line_t *line = sector->lines[i];
|
||||
vertex_t *v1, *v2;
|
||||
|
||||
// find the line closest to the point we're looking for.
|
||||
P_ClosestPointOnLine(x, y, sector->lines[i], &v);
|
||||
dist = R_PointToDist2(0, 0, v.x - x, v.y - y);
|
||||
if (dist < closestdist)
|
||||
if (line->frontsector == line->backsector)
|
||||
continue;
|
||||
|
||||
v1 = line->v1;
|
||||
v2 = line->v2;
|
||||
|
||||
// make sure v1 is below v2
|
||||
if (v1->y > v2->y)
|
||||
{
|
||||
closest = sector->lines[i];
|
||||
closestdist = dist;
|
||||
vertex_t *tmp = v1;
|
||||
v1 = v2;
|
||||
v2 = tmp;
|
||||
}
|
||||
else if (v1->y == v2->y)
|
||||
// horizontal line, we can't match this
|
||||
continue;
|
||||
|
||||
if (v1->y < y && y <= v2->y)
|
||||
{
|
||||
// if the y axis in inside the line, find the point where we intersect on the x axis...
|
||||
fixed_t vx = v1->x + (INT64)(v2->x - v1->x) * (y - v1->y) / (v2->y - v1->y);
|
||||
|
||||
// ...and if that point is to the left of the point, count it as inside.
|
||||
if (vx < x)
|
||||
passes++;
|
||||
}
|
||||
}
|
||||
|
||||
// if the side of the closest line is in this sector, we're inside of it.
|
||||
return P_PointOnLineSide(x, y, closest) == 0 ? closest->frontsector == sector : closest->backsector == sector;
|
||||
// and odd number of passes means we're inside the polygon.
|
||||
return passes % 2;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1201,7 +1218,7 @@ void R_SetupFrame(player_t *player)
|
|||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
|
||||
if (r_viewmobj->subsector)
|
||||
if (!P_MobjWasRemoved(r_viewmobj) && r_viewmobj->subsector)
|
||||
newview->sector = r_viewmobj->subsector->sector;
|
||||
else
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
|
17
src/r_segs.c
17
src/r_segs.c
|
@ -543,7 +543,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
lightlist_t *light;
|
||||
r_lightlist_t *rlight;
|
||||
INT32 range;
|
||||
line_t *newline = NULL;
|
||||
// Render FOF sides kinda like normal sides, with the frac and step and everything
|
||||
// NOTE: INT64 instead of fixed_t because overflow concerns
|
||||
INT64 top_frac, top_step, bottom_frac, bottom_step;
|
||||
|
@ -553,7 +552,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
fixed_t left_top, left_bottom; // needed here for slope skewing
|
||||
pslope_t *skewslope = NULL;
|
||||
boolean do_texture_skew;
|
||||
INT16 lineflags;
|
||||
boolean dont_peg_bottom;
|
||||
fixed_t wall_scalex, wall_scaley;
|
||||
|
||||
void (*colfunc_2s) (column_t *);
|
||||
|
@ -573,12 +572,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
if (pfloor->master->flags & ML_TFERLINE)
|
||||
{
|
||||
size_t linenum = curline->linedef-backsector->lines[0];
|
||||
newline = pfloor->master->frontsector->lines[0] + linenum;
|
||||
line_t *newline = pfloor->master->frontsector->lines[0] + linenum;
|
||||
sidedef = &sides[newline->sidenum[0]];
|
||||
lineflags = newline->flags;
|
||||
do_texture_skew = newline->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = newline->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
else
|
||||
lineflags = curline->linedef->flags;
|
||||
{
|
||||
do_texture_skew = pfloor->master->flags & ML_SKEWTD;
|
||||
dont_peg_bottom = curline->linedef->flags & ML_DONTPEGBOTTOM;
|
||||
}
|
||||
|
||||
texnum = R_GetTextureNum(sidedef->midtexture);
|
||||
|
||||
|
@ -756,8 +759,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
|
||||
left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
|
||||
|
||||
do_texture_skew = lineflags & ML_SKEWTD;
|
||||
|
||||
if (do_texture_skew)
|
||||
{
|
||||
skewslope = *pfloor->t_slope; // skew using top slope by default
|
||||
|
@ -768,7 +769,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
|||
|
||||
offsetvalue = sidedef->rowoffset + sidedef->offsety_mid;
|
||||
|
||||
if (lineflags & ML_DONTPEGBOTTOM)
|
||||
if (dont_peg_bottom)
|
||||
{
|
||||
if (do_texture_skew)
|
||||
{
|
||||
|
|
|
@ -3496,7 +3496,7 @@ boolean R_ThingVisible (mobj_t *thing)
|
|||
(thing->sprite == SPR_NULL) || // Don't draw null-sprites
|
||||
(thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects
|
||||
(thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects
|
||||
(r_viewmobj && (
|
||||
(!P_MobjWasRemoved(r_viewmobj) && (
|
||||
(r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects
|
||||
(r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj
|
||||
(r_viewmobj == thing->dontdrawforviewmobj) // Don't draw objects that are hidden for the current view
|
||||
|
|
|
@ -1785,46 +1785,49 @@ static void ST_drawNightsRecords(void)
|
|||
|
||||
static void ST_drawNiGHTSLink(void)
|
||||
{
|
||||
static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0};
|
||||
const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0);
|
||||
INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? (stplyr->linkcount-1 >= 600) ? 2 : 1 : 0);
|
||||
skincolornum_t colornum;
|
||||
fixed_t x, y, scale;
|
||||
|
||||
if (sel != prevsel[q])
|
||||
if (stplyr->linkcount != 0) // Don't show a faint 4294967295 link, even when debugging
|
||||
{
|
||||
prevsel[q] = sel;
|
||||
prevtime[q] = 2 + mag;
|
||||
static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0};
|
||||
const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0);
|
||||
INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? (stplyr->linkcount-1 >= 600) ? 2 : 1 : 0);
|
||||
skincolornum_t colornum;
|
||||
fixed_t x, y, scale;
|
||||
|
||||
if (sel != prevsel[q])
|
||||
{
|
||||
prevsel[q] = sel;
|
||||
prevtime[q] = 2 + mag;
|
||||
}
|
||||
|
||||
if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics)))
|
||||
colornum = SKINCOLOR_ICY;
|
||||
else
|
||||
colornum = linkColor[mag][sel];
|
||||
|
||||
aflag |= ((stplyr->linktimer < (UINT32)nightslinktics/3)
|
||||
? (9 - 9*stplyr->linktimer/(nightslinktics/3)) << V_ALPHASHIFT
|
||||
: 0);
|
||||
|
||||
y = (160+11)<<FRACBITS;
|
||||
aflag |= V_SNAPTOBOTTOM;
|
||||
|
||||
x = (160+4)<<FRACBITS;
|
||||
|
||||
if (prevtime[q])
|
||||
{
|
||||
scale = ((32 + prevtime[q])<<FRACBITS)/32;
|
||||
prevtime[q]--;
|
||||
}
|
||||
else
|
||||
scale = FRACUNIT;
|
||||
|
||||
y -= (11*scale);
|
||||
|
||||
ST_DrawNightsOverlayNum(x-(4*scale), y, scale, aflag, (stplyr->linkcount-1), nightsnum, colornum);
|
||||
V_DrawFixedPatch(x+(4*scale), y, scale, aflag, nightslink,
|
||||
colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE));
|
||||
}
|
||||
|
||||
if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics)))
|
||||
colornum = SKINCOLOR_ICY;
|
||||
else
|
||||
colornum = linkColor[mag][sel];
|
||||
|
||||
aflag |= ((stplyr->linktimer < (UINT32)nightslinktics/3)
|
||||
? (9 - 9*stplyr->linktimer/(nightslinktics/3)) << V_ALPHASHIFT
|
||||
: 0);
|
||||
|
||||
y = (160+11)<<FRACBITS;
|
||||
aflag |= V_SNAPTOBOTTOM;
|
||||
|
||||
x = (160+4)<<FRACBITS;
|
||||
|
||||
if (prevtime[q])
|
||||
{
|
||||
scale = ((32 + prevtime[q])<<FRACBITS)/32;
|
||||
prevtime[q]--;
|
||||
}
|
||||
else
|
||||
scale = FRACUNIT;
|
||||
|
||||
y -= (11*scale);
|
||||
|
||||
ST_DrawNightsOverlayNum(x-(4*scale), y, scale, aflag, (stplyr->linkcount-1), nightsnum, colornum);
|
||||
V_DrawFixedPatch(x+(4*scale), y, scale, aflag, nightslink,
|
||||
colornum == 0 ? colormaps : R_GetTranslationColormap(TC_DEFAULT, colornum, GTC_CACHE));
|
||||
|
||||
// Show remaining link time left in debug
|
||||
if (cv_debug & DBG_NIGHTSBASIC)
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, 180, V_SNAPTOBOTTOM, va("End in %d.%02d", stplyr->linktimer/TICRATE, G_TicsToCentiseconds(stplyr->linktimer)));
|
||||
|
@ -1854,13 +1857,15 @@ static void ST_drawNiGHTSHUD(void)
|
|||
for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill)
|
||||
V_DrawScaledPatch(locx + 2 + dfill, locy + 3, V_PERPLAYER|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]);
|
||||
|
||||
// Display actual drill amount and bumper time
|
||||
// Display actual flyangle, drill amount, and bumper time
|
||||
if (!splitscreen && (cv_debug & DBG_NIGHTSBASIC))
|
||||
{
|
||||
V_DrawString(locx, locy - 16, V_MONOSPACE, va("ANGLE: %3d", stplyr->flyangle));
|
||||
|
||||
if (stplyr->bumpertime)
|
||||
V_DrawString(locx, locy - 8, V_REDMAP|V_MONOSPACE, va("BUMPER: 0.%02d", G_TicsToCentiseconds(stplyr->bumpertime)));
|
||||
else
|
||||
V_DrawString(locx, locy - 8, V_MONOSPACE, va("Drill: %3d%%", (stplyr->drillmeter*100)/(96*20)));
|
||||
V_DrawString(locx, locy - 8, V_MONOSPACE, va("DRILL: %3d%%", (stplyr->drillmeter*100)/(96*20)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue