mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-24 21:02:26 +00:00
added qccgui icon (courtesy of shpuld)
isolated transfers a little. added preliminary support for r1q2 and q2pro protocols (no zlib). fixed some missing q2 hud configstrings. fixed models attached to particles not appearing the first time around. fixed halos appearing on {foo fullbright textures. fix particle crash bug from missing particlecubes. implement r_converteffectinfo (instead of r_importeffectinfo with r_exportalleffects) for convenience. also now more complete and more accurate. loadfont no longer auto-allocates slot 0. fix issues with r_dynamic -1 don't restart audio on vid_reload (only reload it). this fixes audio issues with capturedemo with gamedir changes. fix possible crash from loading sounds during an audio reload/restart. now listens on both ports 27500 and 26000 when running quake, by default. sv_port or -port args will override. work around surfedge corruption in some instance of the slide4 map that dimman found. attempt to nudge players to travel at at least 200qu when travelling vertically through portals. this should help alieviate gravity-induced stuttering issues. fix nested function types used in conjunction with op_state. now assumes static within the parent. optimise array indexes slightly. fix issue with ptr[float].foo fix some qcc bugs to do with implicit type conversions fix a portal / angle protocol extension issue, so legacy clients can use portals, they just can't see the other side (nor predict them). fix q2 victory.pcx issue at the end of the game. use abort/sigabort instead of sigsegv on linux sys_errors. this should help get people to report stuff better. reformat the nq server advertising to be more helpful. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4996 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b1d2179394
commit
e996609c73
54 changed files with 1615 additions and 537 deletions
|
@ -1368,7 +1368,8 @@ endif
|
|||
# This is for linking the FTE icon to the MinGW target
|
||||
$(OUT_DIR)/resources.o : winquake.rc
|
||||
@$(WINDRES) $(BRANDFLAGS) -I$(CLIENT_DIR) -O coff $< $@
|
||||
|
||||
$(OUT_DIR)/fteqcc.o : fteqcc.rc
|
||||
@$(WINDRES) $(BRANDFLAGS) -I$(PROGS_DIR) -O coff $< $@
|
||||
#npAPI stuff requires some extra resources
|
||||
$(OUT_DIR)/npplug.o : ftequake/npplug.rc
|
||||
@$(WINDRES) $(BRANDFLAGS) -I$(CLIENT_DIR) -O coff $< $@
|
||||
|
@ -1553,11 +1554,11 @@ _qcc-tmp: $(REQDIR)
|
|||
qcc-rel:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqcc" OUT_DIR="$(RELEASE_DIR)/qcc" SOBJS="qcctui.o"
|
||||
qccgui-rel:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqccgui" OUT_DIR="$(RELEASE_DIR)/qcc" SOBJS="qccgui.o qccguistuff.o" LDFLAGS="$(LDFLAGS) -lole32 -lcomdlg32 -lcomctl32 -lshlwapi -mwindows"
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqccgui" OUT_DIR="$(RELEASE_DIR)/qcc" SOBJS="qccgui.o qccguistuff.o fteqcc.o" LDFLAGS="$(LDFLAGS) -lole32 -lcomdlg32 -lcomctl32 -lshlwapi -mwindows"
|
||||
qcc-dbg:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-dbg REQDIR=debugdir EXE_NAME="../fteqcc" OUT_DIR="$(DEBUG_DIR)/qcc" SOBJS="qcctui.o"
|
||||
qccgui-dbg:
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-dbg REQDIR=debugdir EXE_NAME="../fteqccgui" OUT_DIR="$(DEBUG_DIR)/qcc" SOBJS="qccgui.o qccguistuff.o" LDFLAGS="$(LDFLAGS) -lole32 -lcomdlg32 -lcomctl32 -lshlwapi -mwindows"
|
||||
@$(MAKE) _qcc-tmp TYPE=_out-dbg REQDIR=debugdir EXE_NAME="../fteqccgui" OUT_DIR="$(DEBUG_DIR)/qcc" SOBJS="qccgui.o qccguistuff.o fteqcc.o" LDFLAGS="$(LDFLAGS) -lole32 -lcomdlg32 -lcomctl32 -lshlwapi -mwindows"
|
||||
|
||||
|
||||
#scintilla is messy as fuck when building statically. but at least we can strip out the lexers we don't use this way.
|
||||
|
|
|
@ -1456,8 +1456,13 @@ qboolean CLQ2_SendCmd (sizebuf_t *buf)
|
|||
MSG_WriteByte (buf, clcq2_move);
|
||||
|
||||
// save the position for a checksum qbyte
|
||||
checksumIndex = buf->cursize;
|
||||
MSG_WriteByte (buf, 0);
|
||||
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2 || cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
||||
checksumIndex = -1;
|
||||
else
|
||||
{
|
||||
checksumIndex = buf->cursize;
|
||||
MSG_WriteByte (buf, 0);
|
||||
}
|
||||
|
||||
if (!cl.q2frame.valid || cl_nodelta.ival)
|
||||
MSG_WriteLong (buf, -1); // no compression
|
||||
|
@ -1484,11 +1489,14 @@ qboolean CLQ2_SendCmd (sizebuf_t *buf)
|
|||
// calculate a checksum over the move commands
|
||||
dontdrop = CL_WriteDeltas(0, buf);
|
||||
|
||||
buf->data[checksumIndex] = Q2COM_BlockSequenceCRCByte(
|
||||
buf->data + checksumIndex + 1, buf->cursize - checksumIndex - 1,
|
||||
seq_hash);
|
||||
if (checksumIndex >= 0)
|
||||
{
|
||||
buf->data[checksumIndex] = Q2COM_BlockSequenceCRCByte(
|
||||
buf->data + checksumIndex + 1, buf->cursize - checksumIndex - 1,
|
||||
seq_hash);
|
||||
}
|
||||
|
||||
if (cl.sendprespawn)
|
||||
if (cl.sendprespawn || !cls.protocol_q2)
|
||||
buf->cursize = 0; //tastyspleen.net is alergic.
|
||||
|
||||
return dontdrop;
|
||||
|
|
|
@ -242,7 +242,11 @@ static struct
|
|||
netadr_t adr; //address that we're trying to transfer to.
|
||||
int mtu;
|
||||
unsigned int compresscrc;
|
||||
int protocol; //tracked as part of guesswork based upon what replies we get.
|
||||
int protocol; //nq/qw/q2/q3. guessed based upon server replies
|
||||
int subprotocol; //the monkeys are trying to eat me.
|
||||
unsigned int fteext1;
|
||||
unsigned int fteext2;
|
||||
int qport;
|
||||
int challenge; //tracked as part of guesswork based upon what replies we get.
|
||||
double time; //for connection retransmits
|
||||
int defaultport;
|
||||
|
@ -541,8 +545,8 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
|
|||
fteprotextsupported = 0;
|
||||
#endif
|
||||
|
||||
cls.fteprotocolextensions = fteprotextsupported;
|
||||
cls.fteprotocolextensions2 = fteprotextsupported2;
|
||||
connectinfo.fteext1 = fteprotextsupported;
|
||||
connectinfo.fteext2 = fteprotextsupported2;
|
||||
#endif
|
||||
|
||||
t1 = Sys_DoubleTime ();
|
||||
|
@ -574,8 +578,12 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
|
|||
|
||||
connectinfo.time = realtime+t2-t1; // for retransmit requests
|
||||
|
||||
cls.qport = qport.value;
|
||||
Cvar_SetValue(&qport, (cls.qport+1)&0xffff);
|
||||
//fixme: we shouldn't cycle these so much
|
||||
connectinfo.qport = qport.value;
|
||||
Cvar_SetValue(&qport, (connectinfo.qport+1)&0xffff);
|
||||
|
||||
if (connectinfo.protocol == CP_QUAKE2 && (connectinfo.subprotocol == PROTOCOL_VERSION_R1Q2 || connectinfo.subprotocol == PROTOCOL_VERSION_Q2PRO))
|
||||
connectinfo.qport &= 0xff;
|
||||
|
||||
// Info_SetValueForStarKey (cls.userinfo, "*ip", NET_AdrToString(adr), MAX_INFO_STRING);
|
||||
|
||||
|
@ -601,8 +609,7 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
|
|||
#ifdef Q3CLIENT
|
||||
if (connectinfo.protocol == CP_QUAKE3)
|
||||
{ //q3 requires some very strange things.
|
||||
cls.challenge = connectinfo.challenge;
|
||||
CLQ3_SendConnectPacket(to);
|
||||
CLQ3_SendConnectPacket(to, connectinfo.challenge, connectinfo.qport);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -612,15 +619,7 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
|
|||
if (clients>1) //splitscreen 'connect' command specifies the number of userinfos sent.
|
||||
Q_strncatz(data, va("%i", clients), sizeof(data));
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
if (connectinfo.protocol == CP_QUAKE2)
|
||||
Q_strncatz(data, va(" %i", PROTOCOL_VERSION_Q2), sizeof(data));
|
||||
else
|
||||
#endif
|
||||
Q_strncatz(data, va(" %i", PROTOCOL_VERSION_QW), sizeof(data));
|
||||
|
||||
|
||||
Q_strncatz(data, va(" %i %i", cls.qport, connectinfo.challenge), sizeof(data));
|
||||
Q_strncatz(data, va(" %i %i %i", connectinfo.subprotocol, connectinfo.qport, connectinfo.challenge), sizeof(data));
|
||||
|
||||
//userinfo0 has some twiddles for extensions from other qw engines.
|
||||
Q_strncatz(data, " \"", sizeof(data));
|
||||
|
@ -638,9 +637,12 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
|
|||
|
||||
Q_strncatz(data, "\"", sizeof(data));
|
||||
for (c = 1; c < clients; c++)
|
||||
{
|
||||
Q_strncatz(data, va(" \"%s\"", cls.userinfo[c]), sizeof(data));
|
||||
}
|
||||
|
||||
if (connectinfo.protocol == CP_QUAKE2 && connectinfo.subprotocol == PROTOCOL_VERSION_R1Q2)
|
||||
Q_strncatz(data, va(" %d %d", mtu, 1905), sizeof(data)); //mti, sub-sub-version
|
||||
else if (connectinfo.protocol == CP_QUAKE2 && connectinfo.subprotocol == PROTOCOL_VERSION_Q2PRO)
|
||||
Q_strncatz(data, va(" %d 0 0 %d", mtu, 1021), sizeof(data)); //mtu, netchan-fragmentation, zlib, sub-sub-version
|
||||
|
||||
Q_strncatz(data, "\n", sizeof(data));
|
||||
|
||||
|
@ -681,8 +683,6 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
|
|||
Q_strncatz(data, va("0x%x \"%s\"\n", PROTOCOL_INFO_GUID, info), sizeof(data));
|
||||
|
||||
NET_SendPacket (NS_CLIENT, strlen(data), data, to);
|
||||
|
||||
cl.splitclients = 0;
|
||||
}
|
||||
|
||||
char *CL_TryingToConnect(void)
|
||||
|
@ -718,9 +718,7 @@ void CL_CheckForResend (void)
|
|||
if (!cls.state && (!connectinfo.trying || sv.state != ss_clustermode) && sv.state)
|
||||
{
|
||||
extern cvar_t dpcompat_nopreparse;
|
||||
unsigned int pext1, pext2;
|
||||
pext1 = 0;
|
||||
pext2 = 0;
|
||||
memset(&connectinfo, 0, sizeof(connectinfo));
|
||||
connectinfo.trying = true;
|
||||
connectinfo.istransfer = false;
|
||||
|
||||
|
@ -735,28 +733,29 @@ void CL_CheckForResend (void)
|
|||
{
|
||||
#ifdef Q3CLIENT
|
||||
case GT_QUAKE3:
|
||||
pext1 = 0;
|
||||
pext2 = 0;
|
||||
cls.protocol = CP_QUAKE3;
|
||||
connectinfo.protocol = CP_QUAKE3;
|
||||
break;
|
||||
#endif
|
||||
#ifdef Q2CLIENT
|
||||
case GT_QUAKE2:
|
||||
pext1 = 0;
|
||||
pext2 = 0;
|
||||
cls.protocol = CP_QUAKE2;
|
||||
connectinfo.protocol = CP_QUAKE2;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_Q2;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cl.movesequence = 0;
|
||||
if (!strcmp(cl_loopbackprotocol.string, "qw"))
|
||||
{ //qw with all supported extensions -default
|
||||
pext1 = Net_PextMask(1, false);
|
||||
pext2 = Net_PextMask(2, false);
|
||||
cls.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.fteext1 = Net_PextMask(1, false);
|
||||
connectinfo.fteext2 = Net_PextMask(2, false);
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "qwid") || !strcmp(cl_loopbackprotocol.string, "idqw"))
|
||||
cls.protocol = CP_QUAKEWORLD;
|
||||
{
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
}
|
||||
#ifdef Q3CLIENT
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "q3"))
|
||||
cls.protocol = CP_QUAKE3;
|
||||
|
@ -766,53 +765,55 @@ void CL_CheckForResend (void)
|
|||
{ //for debugging.
|
||||
if (rand() & 1)
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_FITZ666;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_FITZ666;
|
||||
}
|
||||
else
|
||||
{
|
||||
cls.protocol = CP_QUAKEWORLD;
|
||||
pext1 = Net_PextMask(1, false);
|
||||
pext2 = Net_PextMask(2, false);
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
connectinfo.fteext1 = Net_PextMask(1, false);
|
||||
connectinfo.fteext2 = Net_PextMask(2, false);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "fitz") || !strcmp(cl_loopbackprotocol.string, "666") || !strcmp(cl_loopbackprotocol.string, "999"))
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_FITZ666;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_FITZ666;
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "nq")) //actually proquake, because we might as well use the extra angles
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_PROQUAKE3_4;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_PROQUAKE3_4;
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "nqid") || !strcmp(cl_loopbackprotocol.string, "idnq"))
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_ID;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_ID;
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "dp6") || !strcmp(cl_loopbackprotocol.string, "dpp6"))
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_DP6;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_DP6;
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "dp7") || !strcmp(cl_loopbackprotocol.string, "dpp7"))
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_DP7;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_DP7;
|
||||
}
|
||||
else if (progstype != PROG_QW && progstype != PROG_H2) //h2 depends on various extensions and doesn't really match either protocol, but we go for qw because that gives us all sorts of extensions.
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_FITZ666;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_FITZ666;
|
||||
//FIXME: pext
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{ //protocol wasn't recognised, and we didn't take the nq fallback, so that must mean we're going for qw.
|
||||
cls.protocol = CP_QUAKEWORLD;
|
||||
pext1 = Net_PextMask(1, false);
|
||||
pext2 = Net_PextMask(2, false);
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
connectinfo.fteext1 = Net_PextMask(1, false);
|
||||
connectinfo.fteext2 = Net_PextMask(2, false);
|
||||
}
|
||||
|
||||
#ifdef NETPREPARSE
|
||||
|
@ -824,28 +825,30 @@ void CL_CheckForResend (void)
|
|||
Con_Printf("dpcompat_nopreparse is unsupported with hexen2\n");
|
||||
else if (progstype == PROG_QW && cls.protocol != CP_QUAKEWORLD)
|
||||
{
|
||||
cls.protocol = CP_QUAKEWORLD;
|
||||
pext1 = Net_PextMask(1, false);
|
||||
pext2 = Net_PextMask(2, false);
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
connectinfo.fteext1 = Net_PextMask(1, false);
|
||||
connectinfo.fteext2 = Net_PextMask(2, false);
|
||||
}
|
||||
else if (progstype != PROG_QW && cls.protocol == CP_QUAKEWORLD)
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_DP7; //dpcompat_nopreparse is only really needed for DP mods that send unknowable svc_tempentity messages to the client.
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_DP7; //dpcompat_nopreparse is only really needed for DP mods that send unknowable svc_tempentity messages to the client.
|
||||
}
|
||||
}
|
||||
|
||||
//make sure the protocol within demos is actually correct/sane
|
||||
if (cls.demorecording == 1 && cls.protocol != CP_QUAKEWORLD)
|
||||
{
|
||||
cls.protocol = CP_QUAKEWORLD;
|
||||
pext1 = Net_PextMask(1, false);
|
||||
pext2 = Net_PextMask(2, false);
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
connectinfo.fteext1 = Net_PextMask(1, false);
|
||||
connectinfo.fteext2 = Net_PextMask(2, false);
|
||||
}
|
||||
else if (cls.demorecording == 2 && cls.protocol != CP_NETQUAKE)
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_FITZ666;
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_FITZ666;
|
||||
//FIXME: use pext.
|
||||
}
|
||||
break;
|
||||
|
@ -853,7 +856,6 @@ void CL_CheckForResend (void)
|
|||
|
||||
CL_FlushClientCommands(); //clear away all client->server clientcommands.
|
||||
|
||||
connectinfo.protocol = cls.protocol;
|
||||
#ifdef NQPROT
|
||||
if (connectinfo.protocol == CP_NETQUAKE)
|
||||
{
|
||||
|
@ -873,21 +875,21 @@ void CL_CheckForResend (void)
|
|||
net_message.packing = SZ_RAWBYTES;
|
||||
net_message.cursize = 0;
|
||||
|
||||
if (cls.protocol_nq == CPNQ_ID)
|
||||
if (connectinfo.subprotocol == CPNQ_ID)
|
||||
{
|
||||
net_from = connectinfo.adr;
|
||||
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
|
||||
|
||||
SVC_DirectConnect();
|
||||
}
|
||||
else if (cls.protocol_nq == CPNQ_FITZ666)
|
||||
else if (connectinfo.subprotocol == CPNQ_FITZ666)
|
||||
{
|
||||
net_from = connectinfo.adr;
|
||||
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\666\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
|
||||
|
||||
SVC_DirectConnect();
|
||||
}
|
||||
else if (cls.protocol_nq == CPNQ_PROQUAKE3_4)
|
||||
else if (connectinfo.subprotocol == CPNQ_PROQUAKE3_4)
|
||||
{
|
||||
net_from = connectinfo.adr;
|
||||
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\1\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
|
||||
|
@ -903,8 +905,7 @@ void CL_CheckForResend (void)
|
|||
{
|
||||
if (!connectinfo.challenge)
|
||||
connectinfo.challenge = rand();
|
||||
cls.challenge = connectinfo.challenge;
|
||||
CL_SendConnectPacket (NULL, 8192-16, pext1, pext2, false);
|
||||
CL_SendConnectPacket (NULL, 8192-16, connectinfo.fteext1, connectinfo.fteext2, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2797,7 +2798,10 @@ void CL_ConnectionlessPacket (void)
|
|||
|
||||
#ifdef Q2CLIENT
|
||||
if (connectinfo.protocol == CP_QUAKE2 || connectinfo.protocol == CP_UNKNOWN)
|
||||
{
|
||||
connectinfo.protocol = CP_QUAKE2;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_Q2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("\nChallenge from another protocol, ignoring Q2 challenge\n");
|
||||
|
@ -2812,7 +2816,10 @@ void CL_ConnectionlessPacket (void)
|
|||
/*no idea, assume a QuakeWorld challenge response ('c' packet)*/
|
||||
|
||||
else if (connectinfo.protocol == CP_QUAKEWORLD || connectinfo.protocol == CP_UNKNOWN)
|
||||
{
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("\nChallenge from another protocol, ignoring QW challenge\n");
|
||||
|
@ -2825,7 +2832,30 @@ void CL_ConnectionlessPacket (void)
|
|||
lasttime = curtime;
|
||||
lastadr = net_from;
|
||||
|
||||
connectinfo.challenge = atoi(s);
|
||||
s = COM_Parse(s);
|
||||
connectinfo.challenge = atoi(com_token);
|
||||
|
||||
while((s = COM_Parse(s)))
|
||||
{
|
||||
if (connectinfo.protocol == CP_QUAKE2 && !strncmp(com_token, "p=", 2))
|
||||
{
|
||||
char *p = com_token+2;
|
||||
do
|
||||
{
|
||||
switch(strtoul(p, &p, 0))
|
||||
{
|
||||
case PROTOCOL_VERSION_R1Q2:
|
||||
if (connectinfo.subprotocol < PROTOCOL_VERSION_R1Q2)
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_R1Q2;
|
||||
break;
|
||||
case PROTOCOL_VERSION_Q2PRO:
|
||||
if (connectinfo.subprotocol < PROTOCOL_VERSION_Q2PRO)
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_Q2PRO;
|
||||
break;
|
||||
}
|
||||
} while (*p++ == ',');
|
||||
}
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
@ -2917,7 +2947,7 @@ void CL_ConnectionlessPacket (void)
|
|||
{
|
||||
Con_Printf ("accept\n");
|
||||
Validation_Apply_Ruleset();
|
||||
Netchan_Setup(NS_CLIENT, &cls.netchan, &net_from, cls.qport);
|
||||
Netchan_Setup(NS_CLIENT, &cls.netchan, &net_from, connectinfo.qport);
|
||||
CL_ParseEstablished();
|
||||
Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername);
|
||||
|
||||
|
@ -2986,6 +3016,7 @@ void CL_ConnectionlessPacket (void)
|
|||
if (c == S2C_CONNECTION)
|
||||
{
|
||||
connectinfo.protocol = CP_QUAKEWORLD;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_QW;
|
||||
#if defined(Q2CLIENT) || defined(Q3CLIENT)
|
||||
client_connect: //fixme: make function
|
||||
#endif
|
||||
|
@ -3018,9 +3049,18 @@ client_connect: //fixme: make function
|
|||
}
|
||||
}
|
||||
connectinfo.trying = false;
|
||||
cl.splitclients = 0;
|
||||
cls.protocol = connectinfo.protocol;
|
||||
cls.fteprotocolextensions = connectinfo.fteext1;
|
||||
cls.fteprotocolextensions2 = connectinfo.fteext2;
|
||||
cls.challenge = connectinfo.challenge;
|
||||
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, cls.qport);
|
||||
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, connectinfo.qport);
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
cls.protocol_q2 = connectinfo.subprotocol;
|
||||
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2 || cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
||||
cls.netchan.qportsize = 1;
|
||||
}
|
||||
cls.netchan.fragmentsize = connectinfo.mtu;
|
||||
if (connectinfo.mtu >= 64)
|
||||
cls.netchan.message.maxsize = sizeof(cls.netchan.message_buf);
|
||||
|
@ -3184,7 +3224,9 @@ void CLNQ_ConnectionlessPacket(void)
|
|||
|
||||
Validation_Apply_Ruleset();
|
||||
|
||||
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, cls.qport);
|
||||
cls.fteprotocolextensions = connectinfo.fteext1;
|
||||
cls.fteprotocolextensions2 = connectinfo.fteext2;
|
||||
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, connectinfo.qport);
|
||||
CL_ParseEstablished();
|
||||
cls.netchan.isnqprotocol = true;
|
||||
cls.netchan.compresstable = NULL;
|
||||
|
|
|
@ -3102,9 +3102,9 @@ void CLQ2_ParseServerData (void)
|
|||
int svcnt;
|
||||
// int cflag;
|
||||
|
||||
memset(&cls.netchan.netprim, 0, sizeof(cls.netchan.netprim));
|
||||
cls.netchan.netprim.coordsize = 2;
|
||||
cls.netchan.netprim.anglesize = 1;
|
||||
MSG_ChangePrimitives(cls.netchan.netprim);
|
||||
|
||||
Con_DPrintf ("Serverdata packet received.\n");
|
||||
//
|
||||
|
@ -3119,8 +3119,12 @@ void CLQ2_ParseServerData (void)
|
|||
i = MSG_ReadLong ();
|
||||
cls.protocol_q2 = i;
|
||||
|
||||
if (i > PROTOCOL_VERSION_Q2 || i < (cls.demoplayback?PROTOCOL_VERSION_Q2_DEMO_MIN:PROTOCOL_VERSION_Q2_MIN))
|
||||
Host_EndGame ("Server returned version %i, not %i", i, PROTOCOL_VERSION_Q2);
|
||||
if (i == PROTOCOL_VERSION_R1Q2)
|
||||
Con_DPrintf("Using R1Q2 protocol\n");
|
||||
else if (i == PROTOCOL_VERSION_Q2PRO)
|
||||
Con_DPrintf("Using Q2PRO protocol\n");
|
||||
else if (i > PROTOCOL_VERSION_Q2 || i < (cls.demoplayback?PROTOCOL_VERSION_Q2_DEMO_MIN:PROTOCOL_VERSION_Q2_MIN))
|
||||
Host_EndGame ("Q2 Server returned version %i, not %i", i, PROTOCOL_VERSION_Q2);
|
||||
|
||||
svcnt = MSG_ReadLong ();
|
||||
/*cl.attractloop =*/ MSG_ReadByte ();
|
||||
|
@ -3160,6 +3164,40 @@ void CLQ2_ParseServerData (void)
|
|||
str = MSG_ReadString ();
|
||||
Q_strncpyz (cl.levelname, str, sizeof(cl.levelname));
|
||||
|
||||
|
||||
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2)
|
||||
{
|
||||
unsigned short r1q2ver;
|
||||
qboolean isenhanced = MSG_ReadByte();
|
||||
if (isenhanced)
|
||||
Host_EndGame ("R1Q2 server is running an unsupported mod");
|
||||
r1q2ver = MSG_ReadShort(); //protocol version... limit... yeah, buggy.
|
||||
if (r1q2ver < 1903 || r1q2ver > 1905)
|
||||
Host_EndGame ("R1Q2 server version %i not supported", r1q2ver);
|
||||
MSG_ReadByte(); //'used to be advanced deltas'
|
||||
MSG_ReadByte(); //strafejump hack
|
||||
|
||||
if (r1q2ver >= 1905)
|
||||
cls.netchan.netprim.q2flags |= NPQ2_SIZE32;
|
||||
}
|
||||
else if (cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
||||
{
|
||||
unsigned short q2prover = MSG_ReadShort(); //q2pro protocol version
|
||||
if (q2prover < 1011 || q2prover > 1021)
|
||||
Host_EndGame ("Q2PRO server version %i not supported", q2prover);
|
||||
MSG_ReadByte(); //server state (ie: demo playback vs actual game)
|
||||
MSG_ReadByte(); //strafejump hack
|
||||
MSG_ReadByte(); //q2pro qw-mode. kinda silly for us tbh.
|
||||
if (q2prover >= 1014)
|
||||
cls.netchan.netprim.q2flags |= NPQ2_SIZE32;
|
||||
if (q2prover >= 1018)
|
||||
cls.netchan.netprim.q2flags |= NPQ2_ANG16;
|
||||
if (q2prover >= 1015)
|
||||
MSG_ReadByte(); //some kind of waterjump hack enable
|
||||
}
|
||||
|
||||
MSG_ChangePrimitives(cls.netchan.netprim);
|
||||
|
||||
if (cl.playerview[0].playernum == -1)
|
||||
{ // playing a cinematic or showing a pic, not a level
|
||||
SCR_EndLoadingPlaque();
|
||||
|
@ -3801,6 +3839,9 @@ void CLQ2_ParseClientinfo(int i, char *s)
|
|||
player_info_t *player;
|
||||
//s contains "name\model/skin"
|
||||
|
||||
if (i >= MAX_CLIENTS)
|
||||
return;
|
||||
|
||||
player = &cl.players[i];
|
||||
|
||||
*player->userinfo = '\0';
|
||||
|
@ -3857,7 +3898,11 @@ void CLQ2_ParseConfigString (void)
|
|||
|
||||
// do something apropriate
|
||||
|
||||
if (i == Q2CS_SKY)
|
||||
if (i == Q2CS_NAME)
|
||||
{
|
||||
Q_strncpyz (cl.levelname, s, sizeof(cl.levelname));
|
||||
}
|
||||
else if (i == Q2CS_SKY)
|
||||
{
|
||||
Q_strncpyz (cl.skyname, s, sizeof(cl.skyname));
|
||||
}
|
||||
|
@ -3921,9 +3966,16 @@ void CLQ2_ParseConfigString (void)
|
|||
Z_Free(cl.item_name[i-Q2CS_ITEMS]);
|
||||
cl.item_name[i-Q2CS_ITEMS] = Z_StrDup(s);
|
||||
}
|
||||
else if (i >= Q2CS_GENERAL && i < Q2CS_GENERAL+Q2MAX_GENERAL)
|
||||
{
|
||||
Z_Free(cl.configstring_general[i-Q2CS_PLAYERSKINS]);
|
||||
cl.configstring_general[i-Q2CS_PLAYERSKINS] = Z_StrDup(s);
|
||||
}
|
||||
else if (i >= Q2CS_PLAYERSKINS && i < Q2CS_PLAYERSKINS+Q2MAX_CLIENTS)
|
||||
{
|
||||
CLQ2_ParseClientinfo (i-Q2CS_PLAYERSKINS, s);
|
||||
Z_Free(cl.configstring_general[i-Q2CS_PLAYERSKINS]);
|
||||
cl.configstring_general[i-Q2CS_PLAYERSKINS] = Z_StrDup(s);
|
||||
}
|
||||
else if (i == Q2CS_MAPCHECKSUM)
|
||||
{
|
||||
|
@ -6715,6 +6767,19 @@ void CLQ2_ParseServerMessage (void)
|
|||
switch (cmd)
|
||||
{
|
||||
default:
|
||||
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2 || cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
||||
{
|
||||
switch(cmd & 0x1f)
|
||||
{
|
||||
case svcq2_frame: //20 (the bastard to implement.)
|
||||
CLQ2_ParseFrame(cmd>>5);
|
||||
break;
|
||||
default:
|
||||
Host_EndGame ("CLQ2_ParseServerMessage: Illegible server message (%i)", cmd);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Host_EndGame ("CLQ2_ParseServerMessage: Illegible server message (%i)", cmd);
|
||||
return;
|
||||
|
||||
|
@ -6750,10 +6815,16 @@ void CLQ2_ParseServerMessage (void)
|
|||
else
|
||||
Host_EndGame ("Server disconnected");
|
||||
return;
|
||||
case svcq2_reconnect: //8
|
||||
case svcq2_reconnect: //8. this is actually kinda weird to have
|
||||
Con_TPrintf ("reconnecting...\n");
|
||||
#if 1
|
||||
CL_Disconnect();
|
||||
CL_BeginServerReconnect();
|
||||
return;
|
||||
#else
|
||||
CL_SendClientCommand(true, "new");
|
||||
break;
|
||||
#endif
|
||||
case svcq2_sound: //9 // <see code>
|
||||
CLQ2_ParseStartSoundPacket();
|
||||
break;
|
||||
|
@ -6804,7 +6875,7 @@ void CLQ2_ParseServerMessage (void)
|
|||
Host_EndGame ("CL_ParseServerMessage: svcq2_deltapacketentities not as part of svcq2_frame");
|
||||
return;
|
||||
case svcq2_frame: //20 (the bastard to implement.)
|
||||
CLQ2_ParseFrame();
|
||||
CLQ2_ParseFrame(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,9 +130,18 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
|
|||
}
|
||||
else
|
||||
{ // encoded bbox
|
||||
x = 8*(ent->solid & 31);
|
||||
zd = 8*((ent->solid>>5) & 31);
|
||||
zu = 8*((ent->solid>>10) & 63) - 32;
|
||||
if (cls.netchan.netprim.q2flags & NPQ2_SIZE32)
|
||||
{
|
||||
x = ent->solid & 255;
|
||||
zd = (ent->solid >> 8) & 255;
|
||||
zu = ((ent->solid >> 16) & 65535) - 32768;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 8*(ent->solid & 31);
|
||||
zd = 8*((ent->solid>>5) & 31);
|
||||
zu = 8*((ent->solid>>10) & 63) - 32;
|
||||
}
|
||||
|
||||
bmins[0] = bmins[1] = -x;
|
||||
bmaxs[0] = bmaxs[1] = x;
|
||||
|
|
|
@ -2562,8 +2562,7 @@ void CLQ2_ParseTEnt (void)
|
|||
MSG_ReadPos (pos);
|
||||
MSG_ReadDir (dir);
|
||||
color = MSG_ReadByte ();
|
||||
//FIXME: should use q2's vertical puff thing
|
||||
P_RunParticleEffect (pos, dir, color, cnt);
|
||||
P_RunParticleEffectPalette("q2part.TEQ2_LASER_SPARKS", pos, dir, color, cnt);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -3660,15 +3659,29 @@ void CL_UpdateExplosions (void)
|
|||
|
||||
for (i=0, ex=cl_explosions; i < explosions_running; i++, ex++)
|
||||
{
|
||||
if (!ex->model && !ex->flags)
|
||||
if (!ex->model && !(ex->flags&Q2RF_BEAM))
|
||||
continue;
|
||||
|
||||
lastrunningexplosion = i;
|
||||
if (ex->model->loadstate == MLS_LOADING)
|
||||
continue;
|
||||
if (ex->model->loadstate != MLS_LOADED)
|
||||
{
|
||||
ex->model = NULL;
|
||||
ex->flags = 0;
|
||||
P_DelinkTrailstate(&(ex->trailstate));
|
||||
continue;
|
||||
}
|
||||
|
||||
f = ex->framerate*(cl.time - ex->start);
|
||||
|
||||
if (ex->firstframe >= 0)
|
||||
{
|
||||
firstframe = ex->firstframe;
|
||||
numframes = ex->numframes;
|
||||
|
||||
if (!numframes)
|
||||
numframes = ex->model->numframes - firstframe;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -470,8 +470,6 @@ typedef struct
|
|||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect
|
||||
|
||||
int qport;
|
||||
|
||||
struct ftenet_connections_s *sockets;
|
||||
|
||||
qdownload_t *download;
|
||||
|
@ -797,6 +795,7 @@ typedef struct
|
|||
char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH];
|
||||
char *particle_ssname[MAX_SSPARTICLESPRE];
|
||||
#ifdef Q2CLIENT
|
||||
char *configstring_general[Q2MAX_CLIENTS|Q2MAX_GENERAL];
|
||||
char *image_name[Q2MAX_IMAGES];
|
||||
char *item_name[Q2MAX_ITEMS];
|
||||
short inventory[Q2MAX_ITEMS];
|
||||
|
@ -1288,7 +1287,7 @@ qboolean CL_MayLerp(void);
|
|||
#ifdef Q3CLIENT
|
||||
void VARGS CLQ3_SendClientCommand(const char *fmt, ...) LIKEPRINTF(1);
|
||||
void CLQ3_SendAuthPacket(netadr_t *gameserver);
|
||||
void CLQ3_SendConnectPacket(netadr_t *to);
|
||||
void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport);
|
||||
void CLQ3_SendCmd(usercmd_t *cmd);
|
||||
qboolean CLQ3_Netchan_Process(void);
|
||||
void CLQ3_ParseServerMessage (void);
|
||||
|
@ -1475,7 +1474,7 @@ void CLQ2_ParseTEnt (void);
|
|||
void CLQ2_AddEntities (void);
|
||||
void CLQ2_ParseBaseline (void);
|
||||
void CLQ2_ClearParticleState(void);
|
||||
void CLQ2_ParseFrame (void);
|
||||
void CLQ2_ParseFrame (int extrabits);
|
||||
void CLQ2_RunMuzzleFlash2 (int ent, int flash_number);
|
||||
int CLQ2_RegisterTEntModels (void);
|
||||
#endif
|
||||
|
|
|
@ -708,13 +708,25 @@ void CLQ2_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int
|
|||
to->origin[1] = MSG_ReadCoord ();
|
||||
if (bits & Q2U_ORIGIN3)
|
||||
to->origin[2] = MSG_ReadCoord ();
|
||||
|
||||
if (bits & Q2U_ANGLE1)
|
||||
to->angles[0] = MSG_ReadAngle();
|
||||
if (bits & Q2U_ANGLE2)
|
||||
to->angles[1] = MSG_ReadAngle();
|
||||
if (bits & Q2U_ANGLE3)
|
||||
to->angles[2] = MSG_ReadAngle();
|
||||
|
||||
if ((bits & Q2UX_ANGLE16) && (net_message.prim.q2flags & NPQ2_ANG16))
|
||||
{
|
||||
if (bits & Q2U_ANGLE1)
|
||||
to->angles[0] = MSG_ReadAngle16();
|
||||
if (bits & Q2U_ANGLE2)
|
||||
to->angles[1] = MSG_ReadAngle16();
|
||||
if (bits & Q2U_ANGLE3)
|
||||
to->angles[2] = MSG_ReadAngle16();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bits & Q2U_ANGLE1)
|
||||
to->angles[0] = MSG_ReadAngle();
|
||||
if (bits & Q2U_ANGLE2)
|
||||
to->angles[1] = MSG_ReadAngle();
|
||||
if (bits & Q2U_ANGLE3)
|
||||
to->angles[2] = MSG_ReadAngle();
|
||||
}
|
||||
|
||||
if (bits & Q2U_OLDORIGIN)
|
||||
MSG_ReadPos (to->u.q2.old_origin);
|
||||
|
@ -728,7 +740,12 @@ void CLQ2_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int
|
|||
to->u.q2.event = 0;
|
||||
|
||||
if (bits & Q2U_SOLID)
|
||||
to->solid = MSG_ReadShort ();
|
||||
{
|
||||
if (net_message.prim.q2flags & NPQ2_SIZE32)
|
||||
to->solid = MSG_ReadLong();
|
||||
else
|
||||
to->solid = MSG_ReadShort ();
|
||||
}
|
||||
}
|
||||
|
||||
void CLQ2_ClearParticleState(void)
|
||||
|
@ -956,7 +973,7 @@ void CLQ2_ParseBaseline (void)
|
|||
CL_ParsePlayerstate
|
||||
===================
|
||||
*/
|
||||
void CLQ2_ParsePlayerstate (q2frame_t *oldframe, q2frame_t *newframe)
|
||||
void CLQ2_ParsePlayerstate (q2frame_t *oldframe, q2frame_t *newframe, int extflags)
|
||||
{
|
||||
int flags;
|
||||
q2player_state_t *state;
|
||||
|
@ -983,15 +1000,21 @@ void CLQ2_ParsePlayerstate (q2frame_t *oldframe, q2frame_t *newframe)
|
|||
{
|
||||
state->pmove.origin[0] = MSG_ReadShort ();
|
||||
state->pmove.origin[1] = MSG_ReadShort ();
|
||||
state->pmove.origin[2] = MSG_ReadShort ();
|
||||
if (extflags & Q2PSX_OLD)
|
||||
state->pmove.origin[2] = MSG_ReadShort ();
|
||||
}
|
||||
if (extflags & Q2PSX_M_ORIGIN2)
|
||||
state->pmove.origin[2] = MSG_ReadShort ();
|
||||
|
||||
if (flags & Q2PS_M_VELOCITY)
|
||||
{
|
||||
state->pmove.velocity[0] = MSG_ReadShort ();
|
||||
state->pmove.velocity[1] = MSG_ReadShort ();
|
||||
state->pmove.velocity[2] = MSG_ReadShort ();
|
||||
if (extflags & Q2PSX_OLD)
|
||||
state->pmove.velocity[2] = MSG_ReadShort ();
|
||||
}
|
||||
if (extflags & Q2PSX_M_VELOCITY2)
|
||||
state->pmove.velocity[2] = MSG_ReadShort ();
|
||||
|
||||
if (flags & Q2PS_M_TIME)
|
||||
state->pmove.pm_time = MSG_ReadByte ();
|
||||
|
@ -1026,8 +1049,11 @@ void CLQ2_ParsePlayerstate (q2frame_t *oldframe, q2frame_t *newframe)
|
|||
{
|
||||
state->viewangles[0] = MSG_ReadAngle16 ();
|
||||
state->viewangles[1] = MSG_ReadAngle16 ();
|
||||
state->viewangles[2] = MSG_ReadAngle16 ();
|
||||
if (extflags & Q2PSX_OLD)
|
||||
state->viewangles[2] = MSG_ReadAngle16 ();
|
||||
}
|
||||
if (extflags & Q2PSX_VIEWANGLE2)
|
||||
state->viewangles[2] = MSG_ReadAngle16 ();
|
||||
|
||||
if (flags & Q2PS_KICKANGLES)
|
||||
{
|
||||
|
@ -1044,9 +1070,24 @@ void CLQ2_ParsePlayerstate (q2frame_t *oldframe, q2frame_t *newframe)
|
|||
if (flags & Q2PS_WEAPONFRAME)
|
||||
{
|
||||
state->gunframe = MSG_ReadByte ();
|
||||
if (extflags & Q2PSX_OLD)
|
||||
{
|
||||
state->gunoffset[0] = MSG_ReadChar ()*0.25;
|
||||
state->gunoffset[1] = MSG_ReadChar ()*0.25;
|
||||
state->gunoffset[2] = MSG_ReadChar ()*0.25;
|
||||
state->gunangles[0] = MSG_ReadChar ()*0.25;
|
||||
state->gunangles[1] = MSG_ReadChar ()*0.25;
|
||||
state->gunangles[2] = MSG_ReadChar ()*0.25;
|
||||
}
|
||||
}
|
||||
if (extflags & Q2PSX_GUNOFFSET)
|
||||
{
|
||||
state->gunoffset[0] = MSG_ReadChar ()*0.25;
|
||||
state->gunoffset[1] = MSG_ReadChar ()*0.25;
|
||||
state->gunoffset[2] = MSG_ReadChar ()*0.25;
|
||||
}
|
||||
if (extflags & Q2PSX_GUNANGLES)
|
||||
{
|
||||
state->gunangles[0] = MSG_ReadChar ()*0.25;
|
||||
state->gunangles[1] = MSG_ReadChar ()*0.25;
|
||||
state->gunangles[2] = MSG_ReadChar ()*0.25;
|
||||
|
@ -1067,10 +1108,19 @@ void CLQ2_ParsePlayerstate (q2frame_t *oldframe, q2frame_t *newframe)
|
|||
state->rdflags = MSG_ReadByte ();
|
||||
|
||||
// parse stats
|
||||
statbits = MSG_ReadLong ();
|
||||
for (i=0 ; i<Q2MAX_STATS ; i++)
|
||||
if (statbits & (1<<i) )
|
||||
state->stats[i] = MSG_ReadShort();
|
||||
if (extflags & (Q2PSX_OLD|Q2PSX_STATS))
|
||||
statbits = MSG_ReadLong ();
|
||||
else
|
||||
statbits = 0;
|
||||
if (statbits)
|
||||
{
|
||||
for (i=0 ; i<Q2MAX_STATS ; i++)
|
||||
if (statbits & (1<<i) )
|
||||
state->stats[i] = MSG_ReadShort();
|
||||
}
|
||||
|
||||
if (extflags & Q2PSX_CLIENTNUM)
|
||||
/*state->viewent =*/ MSG_ReadByte();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1104,12 +1154,12 @@ void CLQ2_FireEntityEvents (q2frame_t *frame)
|
|||
CL_ParseFrame
|
||||
================
|
||||
*/
|
||||
void CLQ2_ParseFrame (void)
|
||||
void CLQ2_ParseFrame (int extrabits)
|
||||
{
|
||||
int cmd;
|
||||
int len;
|
||||
q2frame_t *old;
|
||||
int i,j;
|
||||
int i,j, chokecount;
|
||||
|
||||
memset (&cl.q2frame, 0, sizeof(cl.q2frame));
|
||||
|
||||
|
@ -1117,8 +1167,31 @@ void CLQ2_ParseFrame (void)
|
|||
CLQ2_ClearProjectiles(); // clear projectiles for new frame
|
||||
#endif
|
||||
|
||||
cl.q2frame.serverframe = MSG_ReadLong ();
|
||||
cl.q2frame.deltaframe = MSG_ReadLong ();
|
||||
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2 || cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
||||
{
|
||||
unsigned int bits = MSG_ReadLong();
|
||||
cl.q2frame.serverframe = bits & 0x07ffffff;
|
||||
i = bits >> 27;
|
||||
if (i == 31)
|
||||
cl.q2frame.deltaframe = -1;
|
||||
else
|
||||
cl.q2frame.deltaframe = cl.q2frame.serverframe - i;
|
||||
bits = MSG_ReadByte();
|
||||
chokecount = bits & 0xf;
|
||||
extrabits = (extrabits<<4) | (bits>>4);
|
||||
}
|
||||
else
|
||||
{
|
||||
cl.q2frame.serverframe = MSG_ReadLong ();
|
||||
cl.q2frame.deltaframe = MSG_ReadLong ();
|
||||
if (cls.protocol_q2 > 26)
|
||||
chokecount = MSG_ReadByte ();
|
||||
else
|
||||
chokecount = 0;
|
||||
|
||||
extrabits = Q2PSX_OLD;
|
||||
}
|
||||
|
||||
cl.q2frame.servertime = cl.q2frame.serverframe*100;
|
||||
|
||||
cl.oldgametime = cl.gametime;
|
||||
|
@ -1126,12 +1199,8 @@ void CLQ2_ParseFrame (void)
|
|||
cl.gametime = cl.q2frame.servertime/1000.f;
|
||||
cl.gametimemark = realtime;
|
||||
|
||||
if (cls.protocol_q2 > 26)
|
||||
{
|
||||
i = MSG_ReadByte ();
|
||||
for (j=0 ; j<i ; j++)
|
||||
cl.outframes[ (cls.netchan.incoming_acknowledged-1-j)&UPDATE_MASK ].latency = -2;
|
||||
}
|
||||
for (j=0 ; j<chokecount ; j++)
|
||||
cl.outframes[ (cls.netchan.incoming_acknowledged-1-j)&UPDATE_MASK ].latency = -2;
|
||||
|
||||
if (cl_shownet.value == 3)
|
||||
Con_Printf (" frame:%i delta:%i\n", cl.q2frame.serverframe, cl.q2frame.deltaframe);
|
||||
|
@ -1179,17 +1248,23 @@ void CLQ2_ParseFrame (void)
|
|||
MSG_ReadData (&cl.q2frame.areabits, len);
|
||||
|
||||
// read playerinfo
|
||||
cmd = MSG_ReadByte ();
|
||||
// SHOWNET(svc_strings[cmd]);
|
||||
if (cmd != svcq2_playerinfo)
|
||||
Host_EndGame ("CL_ParseFrame: not playerinfo");
|
||||
CLQ2_ParsePlayerstate (old, &cl.q2frame);
|
||||
if (cls.protocol_q2 != PROTOCOL_VERSION_R1Q2 && cls.protocol_q2 != PROTOCOL_VERSION_Q2PRO)
|
||||
{
|
||||
cmd = MSG_ReadByte ();
|
||||
// SHOWNET(svc_strings[cmd]);
|
||||
if (cmd != svcq2_playerinfo)
|
||||
Host_EndGame ("CL_ParseFrame: not playerinfo");
|
||||
}
|
||||
CLQ2_ParsePlayerstate (old, &cl.q2frame, extrabits);
|
||||
|
||||
// read packet entities
|
||||
cmd = MSG_ReadByte ();
|
||||
if (cls.protocol_q2 != PROTOCOL_VERSION_R1Q2 && cls.protocol_q2 != PROTOCOL_VERSION_Q2PRO)
|
||||
{
|
||||
cmd = MSG_ReadByte ();
|
||||
// SHOWNET(svc_strings[cmd]);
|
||||
if (cmd != svcq2_packetentities)
|
||||
Host_EndGame ("CL_ParseFrame: not packetentities");
|
||||
if (cmd != svcq2_packetentities)
|
||||
Host_EndGame ("CL_ParseFrame: not packetentities");
|
||||
}
|
||||
CLQ2_ParsePacketEntities (old, &cl.q2frame);
|
||||
|
||||
// save the frame off in the backup array for later delta comparisons
|
||||
|
@ -1742,8 +1817,10 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
if (effects & Q2EF_TRACKER) // lame... problematic?
|
||||
{
|
||||
if (P_ParticleTrail(cent->lerp_origin, ent.origin, pt_q2[Q2RT_BLASTERTRAIL2], ent.keynum, NULL, ¢->trailstate))
|
||||
{
|
||||
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xd0, 1, ¢->trailstate);
|
||||
V_AddLight (ent.keynum, ent.origin, 200, 0, 0.2, 0);
|
||||
V_AddLight (ent.keynum, ent.origin, 200, 0, 0.2, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1042,7 +1042,7 @@ void CLQ3_SendAuthPacket(netadr_t *gameserver)
|
|||
}
|
||||
}
|
||||
|
||||
void CLQ3_SendConnectPacket(netadr_t *to)
|
||||
void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport)
|
||||
{
|
||||
char data[2048];
|
||||
char adrbuf[MAX_ADR_SIZE];
|
||||
|
@ -1056,7 +1056,7 @@ void CLQ3_SendConnectPacket(netadr_t *to)
|
|||
msg.overflowed = msg.allowoverflow = 0;
|
||||
msg.maxsize = sizeof(data);
|
||||
MSG_WriteLong(&msg, -1);
|
||||
MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", cls.challenge, cls.qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), &net_local_cl_ipadr), cls.userinfo[0]));
|
||||
MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i\\ip\\%s%s\"", challenge, qport, PROTOCOL_VERSION_Q3, NET_AdrToString (adrbuf, sizeof(adrbuf), &net_local_cl_ipadr), cls.userinfo[0]));
|
||||
#ifdef HUFFNETWORK
|
||||
Huff_EncryptPacket(&msg, 12);
|
||||
if (!Huff_CompressionCRC(HUFFCRC_QUAKE3))
|
||||
|
|
|
@ -3616,7 +3616,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
|
|||
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
|
||||
for (i = 0, valid = false; i < imgwidth * imgheight; i++)
|
||||
{
|
||||
if (((qbyte*)rawdata)[i] < 256-vid.fullbright)
|
||||
if (((qbyte*)rawdata)[i] == 255 || ((qbyte*)rawdata)[i] < 256-vid.fullbright)
|
||||
rgbadata[i] = 0;
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1110,7 +1110,10 @@ static void PClassic_RunParticleEffect (vec3_t org, vec3_t dir, int color, int c
|
|||
{
|
||||
Classic_RunParticleEffect(org, dir, color, count);
|
||||
}
|
||||
|
||||
static void PClassic_RunParticleEffectPalette (const char *nameprefix, vec3_t org, vec3_t dir, int color, int count)
|
||||
{
|
||||
Classic_RunParticleEffect(org, dir, color, count);
|
||||
}
|
||||
|
||||
particleengine_t pe_classic =
|
||||
{
|
||||
|
@ -1129,6 +1132,7 @@ particleengine_t pe_classic =
|
|||
PClassic_RunParticleEffect2,
|
||||
PClassic_RunParticleEffect3,
|
||||
PClassic_RunParticleEffect4,
|
||||
PClassic_RunParticleEffectPalette,
|
||||
|
||||
PClassic_ParticleTrailIndex,
|
||||
PClassic_EmitSkyEffectTris,
|
||||
|
|
|
@ -20,6 +20,7 @@ static void PNULL_RunParticleEffect (vec3_t org, vec3_t dir, int color, int coun
|
|||
static void PNULL_RunParticleEffect2 (vec3_t org, vec3_t dmin, vec3_t dmax, int color, int effect, int count){}
|
||||
static void PNULL_RunParticleEffect3 (vec3_t org, vec3_t box, int color, int effect, int count){}
|
||||
static void PNULL_RunParticleEffect4 (vec3_t org, float radius, int color, int effect, int count){}
|
||||
static void PNULL_RunParticleEffectPalette (const char *nameprefix, vec3_t org, vec3_t dir, int color, int count){}
|
||||
|
||||
static void PNULL_ParticleTrailIndex (vec3_t start, vec3_t end, int color, int crnd, trailstate_t **tsk){}
|
||||
static void PNULL_EmitSkyEffectTris(model_t *mod, msurface_t *fa, int ptype){}
|
||||
|
@ -65,6 +66,7 @@ particleengine_t pe_null =
|
|||
PNULL_RunParticleEffect2,
|
||||
PNULL_RunParticleEffect3,
|
||||
PNULL_RunParticleEffect4,
|
||||
PNULL_RunParticleEffectPalette,
|
||||
|
||||
PNULL_ParticleTrailIndex,
|
||||
PNULL_EmitSkyEffectTris,
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4593,24 +4593,24 @@ static void QCBUILTIN PF_getentity(pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
G_FLOAT(OFS_RETURN) = es->skinnum;
|
||||
break;
|
||||
case GE_MINS:
|
||||
G_FLOAT(OFS_RETURN+0) = -(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = -(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+2) = -((es->solid>>5) & 31);
|
||||
G_FLOAT(OFS_RETURN+0) = -(int)(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = -(int)(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+2) = -(int)((es->solid>>5) & 31);
|
||||
break;
|
||||
case GE_MAXS:
|
||||
G_FLOAT(OFS_RETURN+0) = (es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = (es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = ((es->solid>>10) & 63) - 32;
|
||||
G_FLOAT(OFS_RETURN+2) = ((es->solid>>10) & 63) - 32;
|
||||
break;
|
||||
case GE_ABSMIN:
|
||||
G_FLOAT(OFS_RETURN+0) = le->origin[0] + -(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = le->origin[1] + -(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+2) = le->origin[2] + -((es->solid>>5) & 31);
|
||||
G_FLOAT(OFS_RETURN+0) = le->origin[0] + -(int)(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = le->origin[1] + -(int)(es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+2) = le->origin[2] + -(int)((es->solid>>5) & 31);
|
||||
break;
|
||||
case GE_ABSMAX:
|
||||
G_FLOAT(OFS_RETURN+0) = le->origin[0] + (es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = le->origin[1] + (es->solid & 31);
|
||||
G_FLOAT(OFS_RETURN+1) = le->origin[2] + ((es->solid>>10) & 63) - 32;
|
||||
G_FLOAT(OFS_RETURN+2) = le->origin[2] + ((es->solid>>10) & 63) - 32;
|
||||
break;
|
||||
case GE_ORIGINANDVECTORS:
|
||||
VectorCopy(le->origin, G_VECTOR(OFS_RETURN));
|
||||
|
@ -5408,7 +5408,7 @@ static struct {
|
|||
{"setmodelindex", PF_cs_SetModelIndex, 333}, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
|
||||
{"modelnameforindex", PF_cs_ModelnameForIndex, 334}, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC)
|
||||
|
||||
{"particleeffectnum", PF_cs_particleeffectnum, 335}, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
|
||||
{"particleeffectnum", PF_cs_particleeffectnum, 335}, // #335 float(string effectname) particleeffectnum (EXT_CSQC)
|
||||
{"trailparticles", PF_cs_trailparticles, 336}, // #336 void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC),
|
||||
{"trailparticles_dp", PF_cs_trailparticles, 336}, // #336 DP sucks
|
||||
{"pointparticles", PF_cs_pointparticles, 337}, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC)
|
||||
|
|
|
@ -83,7 +83,7 @@ void QCBUILTIN PF_CL_drawresetcliparea (pubprogfuncs_t *prinst, struct globalvar
|
|||
G_FLOAT(OFS_RETURN) = 1;
|
||||
}
|
||||
|
||||
#define FONT_SLOTS 16
|
||||
#define FONT_SLOTS 32
|
||||
#define FONT_SIZES 16
|
||||
struct {
|
||||
unsigned int owner; //kdm_foo. whoever has an interest in this font. font is purged when this becomes 0.
|
||||
|
@ -153,6 +153,17 @@ int PR_findnamedfont(const char *name, qboolean isslotname)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
int PR_findunusedfont(void)
|
||||
{
|
||||
int i;
|
||||
//don't find slot 0.
|
||||
for (i = FONT_SLOTS; i-- > 1; )
|
||||
{
|
||||
if (!*fontslot[i].slotname && !*fontslot[i].facename)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//purgeowner is the bitmask of owners that are getting freed.
|
||||
//if purgeowner is 0, fonts will get purged
|
||||
void PR_ReleaseFonts(unsigned int purgeowner)
|
||||
|
@ -232,7 +243,7 @@ void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
else if (slotnum < 0)
|
||||
slotnum = PR_findnamedfont(facename, false);
|
||||
if (slotnum < 0)
|
||||
slotnum = PR_findnamedfont("", true);
|
||||
slotnum = PR_findunusedfont();
|
||||
if (slotnum < 0)
|
||||
return; //eep.
|
||||
|
||||
|
|
|
@ -3442,6 +3442,21 @@ char *particle_set_q2part =
|
|||
"scalefactor 0.8\n"
|
||||
"}\n"
|
||||
|
||||
"r_part TEQ2_LASER_SPARKS\n"
|
||||
"{\n"
|
||||
"texture \"classicparticle\"\n"
|
||||
"tcoords 0 0 16 16 32\n"
|
||||
"count 1\n"
|
||||
"scale 1\n"
|
||||
"alpha 1\n"
|
||||
"die 0.3 0.8\n"
|
||||
"randomvel 20\n"
|
||||
"orgadd 0 7\n"
|
||||
"spawnorg 4\n"
|
||||
"gravity 40\n"
|
||||
"scalefactor 0.8\n"
|
||||
"}\n"
|
||||
|
||||
"r_part te_splashsparks\n"
|
||||
"{\n"
|
||||
"texture \"classicparticle\"\n"
|
||||
|
@ -3692,7 +3707,7 @@ char *particle_set_q2part =
|
|||
"lightradius 150\n"
|
||||
"lightradiusfade 400\n"
|
||||
"lightrgb 1 1 0\n"
|
||||
"lightshadows 0\n"
|
||||
"lightshadows 1\n"
|
||||
"sound \"weapons/lashit.wav\" 1 1 0 0\n"
|
||||
"}\n"
|
||||
"r_part teq2_blaster2\n"
|
||||
|
@ -3714,7 +3729,7 @@ char *particle_set_q2part =
|
|||
"lightradius 150\n"
|
||||
"lightradiusfade 400\n"
|
||||
"lightrgb 0.05 1.0 0.05\n"
|
||||
"lightshadows 0\n"
|
||||
"lightshadows 1\n"
|
||||
"sound \"weapons/lashit.wav\" 1 1 0 0\n"
|
||||
"}\n"
|
||||
"r_part TR_BLASTERTRAIL\n"
|
||||
|
@ -3729,6 +3744,10 @@ char *particle_set_q2part =
|
|||
"randomvel 5\n"
|
||||
"die 0.3 0.5\n"
|
||||
"colorindex 0xe0\n"
|
||||
"lightradius 200\n"
|
||||
"lightradiusfade 400\n"
|
||||
"lightrgb 1.0 1.0 0.0\n"
|
||||
"lightshadows 1\n"
|
||||
"}\n"
|
||||
|
||||
//green version
|
||||
|
@ -3744,6 +3763,10 @@ char *particle_set_q2part =
|
|||
"randomvel 5\n"
|
||||
"die 0.3 0.5\n"
|
||||
"colorindex 0xd0\n"
|
||||
"lightradius 200\n"
|
||||
"lightradiusfade 400\n"
|
||||
"lightrgb 0.0 1.0 0.0\n"
|
||||
"lightshadows 1\n"
|
||||
"}\n"
|
||||
|
||||
|
||||
|
@ -3914,12 +3937,25 @@ char *particle_set_q2part =
|
|||
"}\n"
|
||||
"r_part trq2_gib\n"
|
||||
"{\n"
|
||||
"assoc tr_gib\n"
|
||||
"texture \"particles/quake\"\n"
|
||||
"step 3\n"
|
||||
"scale 4\n"
|
||||
"die 1.0 1.4\n"
|
||||
"colorindex 0xe8 7\n"
|
||||
"spawnorg 1\n"
|
||||
"spawnvel 5\n"
|
||||
"gravity -20\n"
|
||||
"}\n"
|
||||
//FIXME: implement
|
||||
"r_part trq2_greengib\n"
|
||||
"{\n"
|
||||
"assoc tr_gib\n"
|
||||
"texture \"particles/quake\"\n"
|
||||
"step 3\n"
|
||||
"scale 4\n"
|
||||
"die 1.0 1.4\n"
|
||||
"colorindex 0xdb 7\n"
|
||||
"spawnorg 1\n"
|
||||
"spawnvel 5\n"
|
||||
"gravity -20\n"
|
||||
"}\n"
|
||||
|
||||
"r_part TR_PLASMA\n"
|
||||
|
@ -3951,6 +3987,14 @@ char *particle_set_q2part =
|
|||
"lightrgb 1.0 1.0 0.0\n"
|
||||
"}\n"
|
||||
|
||||
//FIXME: add particles
|
||||
"r_part tr_trap\n"
|
||||
"{\n"
|
||||
"lighttime 0\n"
|
||||
"lightradius 100 200\n"
|
||||
"lightrgb 1.0 0.8 0.25\n"
|
||||
"}\n"
|
||||
|
||||
//flags do NOT use coronas, because it obscures the holding player's skin colour
|
||||
"r_part tr_flag1\n"
|
||||
"{\n"
|
||||
|
@ -3989,15 +4033,6 @@ char *particle_set_q2part =
|
|||
"lightrgb 0.25 0.25 1.0\n"
|
||||
"}\n"
|
||||
|
||||
|
||||
//FIXME: add particles
|
||||
"r_part tr_trap\n"
|
||||
"{\n"
|
||||
"lighttime 0\n"
|
||||
"lightradius 100 200\n"
|
||||
"lightrgb 1.0 0.8 0.25\n"
|
||||
"}\n"
|
||||
|
||||
"r_part EF_FLIES\n"
|
||||
"{\n"
|
||||
"texture \"classicparticle\"\n"
|
||||
|
@ -4095,6 +4130,28 @@ char *particle_set_q2part =
|
|||
"sound \"weapons/xpld_wat.wav\" 1 1 0 0\n"
|
||||
"model \"sprites/s_bfg2.sp2\" framestart=0 frameend=4 alpha=0.3 transparent fullbright noshadow\n"
|
||||
"}\n"
|
||||
|
||||
|
||||
//31qu cylinder, 8-98 high
|
||||
//should look like its sucked up into some thingie above
|
||||
"r_part TEQ2_BOSSTPORT\n"
|
||||
"{\n"
|
||||
"texture \"classicparticle\"\n"
|
||||
"tcoords 0 0 16 16 32\n"
|
||||
"count 800\n"
|
||||
"scale 1\n"
|
||||
"alpha 1\n"
|
||||
"die 0.5 0.8\n"
|
||||
"orgadd 8 -98\n"
|
||||
"veladd 100 200\n"
|
||||
"spawnmode circle\n"
|
||||
"spawnorg 48 0\n"
|
||||
"spawnvel -50 30\n"
|
||||
"randomvel 32 31\n"
|
||||
"gravity -800\n"
|
||||
"rgbf 1 1 1\n"
|
||||
"scalefactor 0.8\n"
|
||||
"}\n"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2683,10 +2683,12 @@ void R_GeneratedWorldEBO(void *ctx, void *data, size_t a_, size_t b_)
|
|||
webogeneratingstate = 0;
|
||||
mod = webostate->wmodel;
|
||||
|
||||
GL_DeselectVAO();
|
||||
|
||||
qglGenBuffersARB(1, &webostate->ebo);
|
||||
for (i = 0, idxcount = 0; i < webostate->numbatches; i++)
|
||||
idxcount += webostate->batches[i].numidx;
|
||||
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, webostate->ebo);
|
||||
GL_SelectEBO(webostate->ebo);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, idxcount*sizeof(index_t), NULL, GL_STATIC_DRAW_ARB);
|
||||
for (i = 0, idxcount = 0; i < webostate->numbatches; i++)
|
||||
{
|
||||
|
@ -2755,7 +2757,7 @@ static void Surf_SimpleWorld(struct webostate_s *es, qbyte *pvs)
|
|||
{
|
||||
//FIXME: pre-allocate
|
||||
// continue;
|
||||
eb->maxidx = eb->numidx + surf->mesh->numindexes;
|
||||
eb->maxidx = eb->numidx + surf->mesh->numindexes + 512;
|
||||
eb->idxbuffer = BZ_Realloc(eb->idxbuffer, eb->maxidx * sizeof(index_t));
|
||||
}
|
||||
for (i = 0; i < mesh->numindexes; i++)
|
||||
|
|
|
@ -1025,7 +1025,7 @@ void D3DSucks(void)
|
|||
Sys_Error("Failed to reload content after mode switch\n");
|
||||
}
|
||||
|
||||
void R_ShutdownRenderer(qboolean videotoo)
|
||||
void R_ShutdownRenderer(qboolean devicetoo)
|
||||
{
|
||||
//make sure the worker isn't still loading stuff
|
||||
COM_WorkerFullSync();
|
||||
|
@ -1048,7 +1048,7 @@ void R_ShutdownRenderer(qboolean videotoo)
|
|||
if (Draw_Shutdown)
|
||||
Draw_Shutdown();
|
||||
|
||||
if (VID_DeInit && videotoo)
|
||||
if (VID_DeInit && devicetoo)
|
||||
{
|
||||
TRACE(("dbg: R_ApplyRenderer: VID_DeInit\n"));
|
||||
VID_DeInit();
|
||||
|
@ -1070,7 +1070,10 @@ void R_ShutdownRenderer(qboolean videotoo)
|
|||
|
||||
RQ_Shutdown();
|
||||
|
||||
S_Shutdown(false);
|
||||
if (devicetoo)
|
||||
S_Shutdown(false);
|
||||
else
|
||||
S_StopAllSounds (true);
|
||||
}
|
||||
|
||||
void R_GenPaletteLookup(void)
|
||||
|
@ -1363,7 +1366,7 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
|
|||
|
||||
TRACE(("dbg: R_ApplyRenderer: S_Restart_f\n"));
|
||||
if (!isDedicated)
|
||||
S_DoRestart();
|
||||
S_DoRestart(true);
|
||||
|
||||
#ifdef Q3SERVER
|
||||
if (svs.gametype == GT_QUAKE3)
|
||||
|
|
|
@ -335,6 +335,8 @@ char *Get_Q2ConfigString(int i)
|
|||
return cl.item_name[i-Q2CS_ITEMS]?cl.item_name[i-Q2CS_ITEMS]:"";
|
||||
if (i == Q2CS_STATUSBAR)
|
||||
return cl.q2statusbar;
|
||||
if (i == Q2CS_NAME)
|
||||
return cl.levelname;
|
||||
|
||||
if (i >= Q2CS_MODELS && i < Q2CS_MODELS + Q2MAX_MODELS)
|
||||
return cl.model_name [i-Q2CS_MODELS];
|
||||
|
@ -342,6 +344,8 @@ char *Get_Q2ConfigString(int i)
|
|||
return cl.model_name [i-Q2CS_SOUNDS];
|
||||
if (i == Q2CS_AIRACCEL)
|
||||
return "4";
|
||||
if (i >= Q2CS_PLAYERSKINS && i < Q2CS_GENERAL+Q2MAX_GENERAL)
|
||||
return cl.configstring_general[i-Q2CS_PLAYERSKINS]?cl.configstring_general[i-Q2CS_PLAYERSKINS]:"";
|
||||
//#define Q2CS_LIGHTS (Q2CS_IMAGES +Q2MAX_IMAGES)
|
||||
//#define Q2CS_ITEMS (Q2CS_LIGHTS +Q2MAX_LIGHTSTYLES)
|
||||
//#define Q2CS_PLAYERSKINS (Q2CS_ITEMS +Q2MAX_ITEMS)
|
||||
|
@ -763,6 +767,10 @@ void Sbar_ShowScores (void)
|
|||
|
||||
void Sbar_Hexen2InvLeft_f(void)
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invprev");
|
||||
|
@ -786,6 +794,10 @@ void Sbar_Hexen2InvLeft_f(void)
|
|||
}
|
||||
void Sbar_Hexen2InvRight_f(void)
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invnext");
|
||||
|
@ -809,6 +821,11 @@ void Sbar_Hexen2InvRight_f(void)
|
|||
}
|
||||
void Sbar_Hexen2InvUse_f(void)
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invuse");
|
||||
|
@ -823,21 +840,37 @@ void Sbar_Hexen2InvUse_f(void)
|
|||
void Sbar_Hexen2ShowInfo_f(void)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[CL_TargettedSplit(false)];
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
pv->sb_hexen2_extra_info = true;
|
||||
}
|
||||
void Sbar_Hexen2DontShowInfo_f(void)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[CL_TargettedSplit(false)];
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
pv->sb_hexen2_extra_info = false;
|
||||
}
|
||||
void Sbar_Hexen2PInfoPlaque_f(void)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[CL_TargettedSplit(false)];
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
pv->sb_hexen2_infoplaque = true;
|
||||
}
|
||||
void Sbar_Hexen2MInfoPlaque_f(void)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[CL_TargettedSplit(false)];
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand(Cmd_Argv(0)))
|
||||
return;
|
||||
#endif
|
||||
pv->sb_hexen2_infoplaque = false;
|
||||
}
|
||||
|
||||
|
@ -2326,7 +2359,7 @@ static void Sbar_Hexen2DrawExtra (playerview_t *pv)
|
|||
|
||||
pclass = cl.players[pv->playernum].h2playerclass;
|
||||
if (pclass >= sizeof(pclassname)/sizeof(pclassname[0]))
|
||||
pclass = sizeof(pclassname)/sizeof(pclassname[0]) - 1;
|
||||
pclass = 0;
|
||||
|
||||
|
||||
//adjust it so there's space
|
||||
|
|
|
@ -1785,9 +1785,11 @@ void S_Startup (void)
|
|||
|
||||
//why isn't this part of S_Restart_f anymore?
|
||||
//so that the video code can call it directly without flushing the models it's just loaded.
|
||||
void S_DoRestart (void)
|
||||
void S_DoRestart (qboolean onlyifneeded)
|
||||
{
|
||||
int i;
|
||||
if (onlyifneeded && sound_started)
|
||||
return; //don't need to if its already running.
|
||||
|
||||
S_StopAllSounds (true);
|
||||
S_Shutdown(false);
|
||||
|
@ -1810,7 +1812,7 @@ void S_DoRestart (void)
|
|||
|
||||
void S_Restart_f (void)
|
||||
{
|
||||
S_DoRestart();
|
||||
S_DoRestart(false);
|
||||
}
|
||||
|
||||
void S_Control_f (void)
|
||||
|
@ -2114,7 +2116,14 @@ void S_Purge(qboolean retaintouched)
|
|||
sfx = &known_sfx[i];
|
||||
/*don't hurt sounds if they're being processed by a worker thread*/
|
||||
if (sfx->loadstate == SLS_LOADING)
|
||||
continue;
|
||||
{
|
||||
if (retaintouched)
|
||||
continue; //don't bother waiting
|
||||
|
||||
//trying to shut down or something.
|
||||
//make sure there's no worker about to write to sfx after the memory is freed
|
||||
COM_WorkerPartialSync(sfx, &sfx->loadstate, SLS_LOADING);
|
||||
}
|
||||
|
||||
/*don't purge the file if its still relevent*/
|
||||
if (retaintouched && sfx->touched)
|
||||
|
|
|
@ -890,7 +890,6 @@ void S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b)
|
|||
{
|
||||
if (AudioInputPlugins[i](s, data, filesize, snd_speed))
|
||||
{
|
||||
s->loadstate = SLS_LOADED;
|
||||
//wake up the main thread in case it decided to wait for us.
|
||||
COM_AddWork(0, S_LoadedOrFailed, s, NULL, SLS_LOADED, 0);
|
||||
BZ_Free(data);
|
||||
|
|
|
@ -194,7 +194,7 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch);
|
|||
void SND_ResampleStream (void *in, int inrate, int inwidth, int inchannels, int insamps, void *out, int outrate, int outwidth, int outchannels, int resampstyle);
|
||||
|
||||
// restart entire sound subsystem (doesn't flush old sounds, so make sure that happens)
|
||||
void S_DoRestart (void);
|
||||
void S_DoRestart (qboolean onlyifneeded);
|
||||
|
||||
void S_Restart_f (void);
|
||||
|
||||
|
|
|
@ -786,7 +786,7 @@ STAT_H2_CNT_INVINCIBILITY, // changes stat bar
|
|||
STAT_H2_ARTIFACT_ACTIVE,
|
||||
STAT_H2_ARTIFACT_LOW,
|
||||
STAT_H2_MOVETYPE,
|
||||
STAT_H2_CAMERAMODE,
|
||||
STAT_H2_CAMERAMODE, //entity
|
||||
STAT_H2_HASTED,
|
||||
STAT_H2_INVENTORY,
|
||||
STAT_H2_RINGS_ACTIVE,
|
||||
|
@ -800,21 +800,21 @@ STAT_H2_FLIGHT_T,
|
|||
STAT_H2_WATER_T,
|
||||
STAT_H2_TURNING_T,
|
||||
STAT_H2_REGEN_T,
|
||||
STAT_H2_PUZZLE1,
|
||||
STAT_H2_PUZZLE2,
|
||||
STAT_H2_PUZZLE3,
|
||||
STAT_H2_PUZZLE4,
|
||||
STAT_H2_PUZZLE5,
|
||||
STAT_H2_PUZZLE6,
|
||||
STAT_H2_PUZZLE7,
|
||||
STAT_H2_PUZZLE8,
|
||||
STAT_H2_PUZZLE1, //string
|
||||
STAT_H2_PUZZLE2, //string
|
||||
STAT_H2_PUZZLE3, //string
|
||||
STAT_H2_PUZZLE4, //string
|
||||
STAT_H2_PUZZLE5, //string
|
||||
STAT_H2_PUZZLE6, //string
|
||||
STAT_H2_PUZZLE7, //string
|
||||
STAT_H2_PUZZLE8, //string
|
||||
STAT_H2_MAXHEALTH,
|
||||
STAT_H2_MAXMANA,
|
||||
STAT_H2_FLAGS,
|
||||
STAT_H2_PLAYERCLASS,
|
||||
|
||||
STAT_H2_OBJECTIVE1,
|
||||
STAT_H2_OBJECTIVE2,
|
||||
STAT_H2_OBJECTIVE1, //integer
|
||||
STAT_H2_OBJECTIVE2, //integer
|
||||
|
||||
|
||||
STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR = 220, // DP
|
||||
|
|
|
@ -1778,6 +1778,36 @@ void Cmd_RestrictCommand_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
void Cmd_EnumerateLevel(int level, char *buf, size_t bufsize)
|
||||
{
|
||||
cmdalias_t *a;
|
||||
cmd_function_t *cmds;
|
||||
int cmdlevel;
|
||||
*buf = 0;
|
||||
for (cmds = cmd_functions; cmds; cmds=cmds->next)
|
||||
{
|
||||
cmdlevel = cmds->restriction?cmds->restriction:rcon_level.ival;
|
||||
|
||||
if (level == cmdlevel)
|
||||
{
|
||||
if (*buf)
|
||||
Q_strncatz(buf, "\t", bufsize);
|
||||
Q_strncatz(buf, cmds->name, bufsize);
|
||||
}
|
||||
}
|
||||
for (a=cmd_alias ; a ; a=a->next)
|
||||
{
|
||||
cmdlevel = a->restriction?a->restriction:rcon_level.ival;
|
||||
|
||||
if (level == cmdlevel)
|
||||
{
|
||||
if (*buf)
|
||||
Q_strncatz(buf, "\t", bufsize);
|
||||
Q_strncatz(buf, cmds->name, bufsize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Cmd_Level(char *name)
|
||||
{
|
||||
cmdalias_t *a;
|
||||
|
@ -1793,7 +1823,7 @@ int Cmd_Level(char *name)
|
|||
{
|
||||
if (!strcmp(a->name, name))
|
||||
{
|
||||
return a->restriction?a->restriction:Cmd_ExecLevel;
|
||||
return a->restriction?a->restriction:rcon_level.ival;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -73,6 +73,7 @@ then searches for a command or variable that matches the first token.
|
|||
typedef void (*xcommand_t) (void);
|
||||
|
||||
int Cmd_Level(char *name);
|
||||
void Cmd_EnumerateLevel(int level, char *buf, size_t bufsize);
|
||||
|
||||
void Cmd_Init (void);
|
||||
void Cmd_Shutdown(void);
|
||||
|
|
|
@ -108,8 +108,12 @@ typedef enum {false, true} qboolean;
|
|||
|
||||
struct netprim_s
|
||||
{
|
||||
int coordsize;
|
||||
int anglesize;
|
||||
qbyte coordsize;
|
||||
qbyte anglesize;
|
||||
#define NPQ2_ANG16 (1<<0)
|
||||
#define NPQ2_SIZE32 (1<<0)
|
||||
qbyte q2flags;
|
||||
qbyte pad;
|
||||
};
|
||||
//============================================================================
|
||||
|
||||
|
|
|
@ -2631,7 +2631,7 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
|
|||
FS_ChangeGame(man, cfg_reload_on_gamedir.ival, false);
|
||||
}
|
||||
|
||||
#define QCFG "set com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n"
|
||||
#define QCFG "set com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\nsv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n"
|
||||
/*stuff that makes dp-only mods work a bit better*/
|
||||
#define DPCOMPAT QCFG "set _cl_playermodel \"\"\n set dpcompat_set 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n"
|
||||
/*nexuiz/xonotic has a few quirks/annoyances...*/
|
||||
|
|
|
@ -83,6 +83,7 @@ void CalcSurfaceExtents (model_t *mod, msurface_t *s)
|
|||
mvertex_t *v;
|
||||
mtexinfo_t *tex;
|
||||
int bmins[2], bmaxs[2];
|
||||
int idx;
|
||||
|
||||
mins[0] = mins[1] = 999999;
|
||||
maxs[0] = maxs[1] = -99999;
|
||||
|
@ -92,10 +93,13 @@ void CalcSurfaceExtents (model_t *mod, msurface_t *s)
|
|||
for (i=0 ; i<s->numedges ; i++)
|
||||
{
|
||||
e = mod->surfedges[s->firstedge+i];
|
||||
if (e >= 0)
|
||||
v = &mod->vertexes[mod->edges[e].v[0]];
|
||||
idx = e < 0;
|
||||
if (idx)
|
||||
e = -e;
|
||||
if (e < 0 || e >= mod->numedges)
|
||||
v = &mod->vertexes[0];
|
||||
else
|
||||
v = &mod->vertexes[mod->edges[-e].v[1]];
|
||||
v = &mod->vertexes[mod->edges[e].v[idx]];
|
||||
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
|
|
|
@ -167,6 +167,7 @@ typedef struct
|
|||
netadr_t remote_address;
|
||||
netsrc_t sock;
|
||||
int qport;
|
||||
int qportsize;
|
||||
|
||||
// bandwidth estimator
|
||||
double cleartime; // if realtime > nc->cleartime, free to go
|
||||
|
|
|
@ -342,6 +342,8 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t *adr, int qport)
|
|||
chan->message.maxsize = MAX_QWMSGLEN;
|
||||
|
||||
chan->qport = qport;
|
||||
|
||||
chan->qportsize = 2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -701,7 +703,12 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
// send the qport if we are a client
|
||||
#ifndef SERVERONLY
|
||||
if (chan->sock == NS_CLIENT)
|
||||
MSG_WriteShort (&send, cls.qport);
|
||||
{
|
||||
if (chan->qportsize == 2)
|
||||
MSG_WriteShort (&send, chan->qport);
|
||||
else if (chan->qportsize == 1)
|
||||
MSG_WriteByte (&send, chan->qport&0xff);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (chan->fragmentsize)
|
||||
|
@ -742,7 +749,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
if (!cls.demoplayback)
|
||||
#endif
|
||||
{
|
||||
int hsz = 10 + ((chan->sock == NS_CLIENT)?2:0); /*header size, if fragmentation is in use*/
|
||||
int hsz = 10 + ((chan->sock == NS_CLIENT)?chan->qportsize:0); /*header size, if fragmentation is in use*/
|
||||
|
||||
if ((!chan->fragmentsize) || send.cursize-hsz < ((chan->fragmentsize - hsz)&~7))
|
||||
{
|
||||
|
@ -778,7 +785,12 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
|||
*(int*)&send.data[(offset) + 4] = LittleLong(w2);
|
||||
#ifndef SERVERONLY
|
||||
if (chan->sock == NS_CLIENT)
|
||||
*(short*)&send.data[offset + hsz-4] = LittleShort(cls.qport);
|
||||
{
|
||||
if (chan->qportsize == 2)
|
||||
*(short*)&send.data[offset + hsz-4] = LittleShort(chan->qport);
|
||||
else if (chan->qportsize == 1)
|
||||
*(qbyte*)&send.data[offset + hsz-3] = chan->qport&0xff;
|
||||
}
|
||||
#endif
|
||||
*(short*)&send.data[offset + hsz-2] = LittleShort((offset>>2) | (more?1:0));
|
||||
|
||||
|
|
|
@ -2089,60 +2089,86 @@ static qboolean FTENET_AddToCollection_Ptr(ftenet_connections_t *col, const char
|
|||
}
|
||||
return count > 0;
|
||||
}
|
||||
qboolean FTENET_AddToCollection(ftenet_connections_t *col, const char *name, const char *address, netadrtype_t addrtype, qboolean islisten)
|
||||
qboolean FTENET_AddToCollection(ftenet_connections_t *col, const char *name, const char *addresslist, netadrtype_t addrtype, qboolean islisten)
|
||||
{
|
||||
ftenet_generic_connection_t *(*establish)(qboolean isserver, const char *address, netadr_t adr) = NULL;
|
||||
netadr_t adr;
|
||||
netadr_t adr[8];
|
||||
ftenet_generic_connection_t *(*establish[countof(adr)])(qboolean isserver, const char *address, netadr_t adr);
|
||||
char address[countof(adr)][256];
|
||||
unsigned int i, j;
|
||||
qboolean success;
|
||||
|
||||
//resolve the address to something sane so we can determine the address type and thus the connection type to use
|
||||
if (!address || !*address)
|
||||
adr.type = NA_INVALID;
|
||||
else if (islisten)
|
||||
NET_PortToAdr(addrtype, address, &adr);
|
||||
else
|
||||
NET_StringToAdr(address, 0, &adr);
|
||||
if (strchr(name, ':'))
|
||||
return false;
|
||||
|
||||
switch(adr.type)
|
||||
for (i = 0; addresslist && *addresslist && i < countof(adr); i++)
|
||||
{
|
||||
default: establish = NULL; break;
|
||||
addresslist = COM_ParseStringSet(addresslist, address[i], sizeof(address[i]));
|
||||
//resolve the address to something sane so we can determine the address type and thus the connection type to use
|
||||
if (!*address[i])
|
||||
adr[i].type = NA_INVALID;
|
||||
else if (islisten)
|
||||
NET_PortToAdr(addrtype, address[i], &adr[i]);
|
||||
else
|
||||
NET_StringToAdr(address[i], 0, &adr[i]);
|
||||
|
||||
switch(adr[i].type)
|
||||
{
|
||||
default: establish[i] = NULL; break;
|
||||
#ifdef HAVE_NATPMP
|
||||
case NA_NATPMP: establish = FTENET_NATPMP_EstablishConnection; break;
|
||||
case NA_NATPMP: establish[i] = FTENET_NATPMP_EstablishConnection; break;
|
||||
#endif
|
||||
#if !defined(CLIENTONLY) && !defined(SERVERONLY)
|
||||
case NA_LOOPBACK: establish = FTENET_Loop_EstablishConnection; break;
|
||||
case NA_LOOPBACK: establish[i] = FTENET_Loop_EstablishConnection; break;
|
||||
#endif
|
||||
#ifdef HAVE_IPV4
|
||||
case NA_IP: establish = FTENET_UDP4_EstablishConnection; break;
|
||||
case NA_IP: establish[i] = FTENET_UDP4_EstablishConnection; break;
|
||||
#endif
|
||||
#ifdef IPPROTO_IPV6
|
||||
case NA_IPV6: establish = FTENET_UDP6_EstablishConnection; break;
|
||||
case NA_IPV6: establish[i] = FTENET_UDP6_EstablishConnection; break;
|
||||
#endif
|
||||
#ifdef USEIPX
|
||||
case NA_IPX: establish = FTENET_IPX_EstablishConnection; break;
|
||||
case NA_IPX: establish[i] = FTENET_IPX_EstablishConnection; break;
|
||||
#endif
|
||||
case NA_WEBSOCKET:
|
||||
case NA_WEBSOCKET:
|
||||
#ifdef HAVE_WEBSOCKCL
|
||||
if (!islisten)
|
||||
establish = FTENET_WebSocket_EstablishConnection;
|
||||
if (!islisten)
|
||||
establish[i] = FTENET_WebSocket_EstablishConnection;
|
||||
#endif
|
||||
#ifdef TCPCONNECT
|
||||
establish = FTENET_TCP4Connect_EstablishConnection;
|
||||
establish[i] = FTENET_TCP4Connect_EstablishConnection;
|
||||
#endif
|
||||
break;
|
||||
break;
|
||||
#ifdef IRCCONNECT
|
||||
case NA_IRC: establish = FTENET_IRCConnect_EstablishConnection; break;
|
||||
case NA_IRC: establish[i] = FTENET_IRCConnect_EstablishConnection; break;
|
||||
#endif
|
||||
#ifdef TCPCONNECT
|
||||
case NA_TCP: establish = FTENET_TCP4Connect_EstablishConnection; break;
|
||||
case NA_TLSV4: establish = FTENET_TLS4Connect_EstablishConnection; break;
|
||||
case NA_TCP: establish[i] = FTENET_TCP4Connect_EstablishConnection; break;
|
||||
case NA_TLSV4: establish[i] = FTENET_TLS4Connect_EstablishConnection; break;
|
||||
#endif
|
||||
#if defined(TCPCONNECT) && defined(IPPROTO_IPV6)
|
||||
case NA_TCPV6: establish = FTENET_TCP6Connect_EstablishConnection; break;
|
||||
case NA_TLSV6: establish = FTENET_TLS6Connect_EstablishConnection; break;
|
||||
case NA_TCPV6: establish[i] = FTENET_TCP6Connect_EstablishConnection; break;
|
||||
case NA_TLSV6: establish[i] = FTENET_TLS6Connect_EstablishConnection; break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return FTENET_AddToCollection_Ptr(col, name, establish, islisten, address, &adr);
|
||||
if (i == 1)
|
||||
{
|
||||
success |= FTENET_AddToCollection_Ptr(col, name, establish[0], islisten, address[0], &adr[0]);
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
success |= FTENET_AddToCollection_Ptr(col, name, NULL, islisten, NULL, NULL);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
success |= FTENET_AddToCollection_Ptr(col, va("%s:%i", name, j), establish[j], islisten, address[j], &adr[j]);
|
||||
}
|
||||
for (; j < countof(adr); j++)
|
||||
{
|
||||
success |= FTENET_AddToCollection_Ptr(col, va("%s:%i", name, j), NULL, islisten, NULL, NULL);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void FTENET_CloseCollection(ftenet_connections_t *col)
|
||||
|
@ -2589,7 +2615,11 @@ qboolean NET_PortToAdr (int adrfamily, const char *s, netadr_t *a)
|
|||
char *e;
|
||||
if (net_enabled.ival || adrfamily == NA_LOOPBACK)
|
||||
{
|
||||
int port = strtoul(s, &e, 10);
|
||||
int port;
|
||||
if (!strncmp(s, "natpmp:", 7))
|
||||
return NET_StringToAdr2(s, 0, a, 1);
|
||||
|
||||
port = strtoul(s, &e, 10);
|
||||
if (*e) //if *e then its not just a single number in there, so treat it as a proper address.
|
||||
return NET_StringToAdr(s, 0, a);
|
||||
else if (e != s) //if we actually read something (even a 0)
|
||||
|
|
|
@ -217,6 +217,7 @@ int P_FindParticleType(const char *efname);
|
|||
#define P_RunParticleEffect2 pe->RunParticleEffect2
|
||||
#define P_RunParticleEffect3 pe->RunParticleEffect3
|
||||
#define P_RunParticleEffect4 pe->RunParticleEffect4
|
||||
#define P_RunParticleEffectPalette pe->RunParticleEffectPalette
|
||||
|
||||
#define P_ParticleTrailIndex pe->ParticleTrailIndex
|
||||
#define P_EmitSkyEffectTris pe->EmitSkyEffectTris
|
||||
|
@ -241,6 +242,7 @@ typedef struct {
|
|||
void (*RunParticleEffect2) (vec3_t org, vec3_t dmin, vec3_t dmax, int color, int effect, int count);
|
||||
void (*RunParticleEffect3) (vec3_t org, vec3_t box, int color, int effect, int count);
|
||||
void (*RunParticleEffect4) (vec3_t org, float radius, int color, int effect, int count);
|
||||
void (*RunParticleEffectPalette) (const char *nameprefix, vec3_t org, vec3_t dir, int color, int count);
|
||||
|
||||
void (*ParticleTrailIndex) (vec3_t start, vec3_t end, int color, int crnd, trailstate_t **tsk);
|
||||
void (*EmitSkyEffectTris) (struct model_s *mod, struct msurface_s *fa, int ptype);
|
||||
|
|
|
@ -93,6 +93,7 @@ static qboolean PM_PortalTransform(world_t *w, int portalnum, vec3_t org, vec3_t
|
|||
void *pr_globals = PR_globals(w->progs, PR_CURRENT);
|
||||
int i;
|
||||
int tmp;
|
||||
float f;
|
||||
|
||||
*w->g.self = EDICT_TO_PROG(w->progs, portal);
|
||||
//transform origin+velocity etc
|
||||
|
@ -121,6 +122,16 @@ static qboolean PM_PortalTransform(world_t *w, int portalnum, vec3_t org, vec3_t
|
|||
VectorCopy(w->g.v_right, move);
|
||||
// VectorCopy(w->g.v_up, pmove.gravitydir);
|
||||
|
||||
//floor+floor, ish
|
||||
if (DotProduct(w->g.v_up, pmove.gravitydir) < 0.7)
|
||||
{
|
||||
f = DotProduct(newvel, newvel);
|
||||
if (f < 200*200)
|
||||
{
|
||||
VectorScale(newvel, 200 / sqrt(f), newvel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//transform the angles too
|
||||
VectorCopy(org, G_VECTOR(OFS_PARM0));
|
||||
|
|
|
@ -220,7 +220,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
|
|||
VectorSubtract (end, origin, end_l);
|
||||
|
||||
// sweep the box through the model
|
||||
if (model)
|
||||
if (model && model->funcs.NativeTrace)
|
||||
{
|
||||
if (angles[0] || angles[1] || angles[2])
|
||||
{
|
||||
|
|
|
@ -807,6 +807,8 @@ void QCBUILTIN PF_getsurfacenearpoint(pubprogfuncs_t *prinst, struct globalvars_
|
|||
if (!model || model->type != mod_brush)
|
||||
return;
|
||||
|
||||
bestdist = 256;
|
||||
|
||||
if (model->fromgame == fg_quake || model->fromgame == fg_quake2)
|
||||
{
|
||||
//all polies, we can skip parts. special case.
|
||||
|
@ -5823,6 +5825,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
// {"DP_ENT_COLORMOD"},
|
||||
{"DP_ENT_CUSTOMCOLORMAP"},
|
||||
{"DP_ENT_EXTERIORMODELTOCLIENT"},
|
||||
{"DP_ENT_TRAILEFFECTNUM", 1, NULL, {"particleeffectnum"}, "self.traileffectnum=particleeffectnum(\"myeffectname\n\"); can be used to attach a particle trail to the given server entity. This is equivelent to calling trailparticles each frame."},
|
||||
//only in dp6 currently {"DP_ENT_GLOW"},
|
||||
{"DP_ENT_VIEWMODEL"},
|
||||
{"DP_GECKO_SUPPORT", 7, NULL, {"gecko_create", "gecko_destroy", "gecko_navigate", "gecko_keyevent", "gecko_mousemove", "gecko_resize", "gecko_get_texture_extent"}},
|
||||
|
@ -5832,6 +5835,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"DP_HALFLIFE_MAP_CVAR"},
|
||||
//to an extend {"DP_HALFLIFE_SPRITE"},
|
||||
{"DP_INPUTBUTTONS"},
|
||||
{"DP_LIGHTSTYLE_STATICVALUE"},
|
||||
{"DP_LITSUPPORT"},
|
||||
{"DP_MD3_TAGSINFO", 2, NULL, {"gettagindex", "gettaginfo"}},
|
||||
{"DP_MONSTERWALK", 0, NULL, {NULL}, "MOVETYPE_WALK is valid on non-player entities. Note that only players receive acceleration etc in line with none/bounce/fly/noclip movetypes on the player, thus you will have to provide your own accelerations (incluing gravity) yourself."},
|
||||
|
@ -5858,7 +5862,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"DP_QC_MINMAXBOUND", 3, NULL, {"min", "max", "bound"}},
|
||||
{"DP_QC_MULTIPLETEMPSTRINGS", 0, NULL, {NULL}, "Superseded by DP_QC_UNLIMITEDTEMPSTRINGS. Functions that return a temporary string will not overwrite/destroy previous temporary strings until at least 16 strings are returned (or control returns to the engine)."},
|
||||
{"DP_QC_RANDOMVEC", 1, NULL, {"randomvec"}},
|
||||
{"DP_QC_RENDER_SCENE"}, //clear+addentity+setviewprop+renderscene+setmodel are available to menuqc.
|
||||
{"DP_QC_RENDER_SCENE", 0, NULL, {NULL}, "clearscene+addentity+setviewprop+renderscene+setmodel are available to menuqc. WARNING: DP advertises this extension without actually supporting it, FTE does actually support it."},
|
||||
{"DP_QC_SINCOSSQRTPOW", 4, NULL, {"sin", "cos", "sqrt", "pow"}},
|
||||
{"DP_QC_STRFTIME", 1, NULL, {"strftime"}},
|
||||
{"DP_QC_STRING_CASE_FUNCTIONS", 2, NULL, {"strtolower", "strtoupper"}},
|
||||
|
@ -5871,7 +5875,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"DP_QC_TRACE_MOVETYPE_HITMODEL"},
|
||||
{"DP_QC_TRACE_MOVETYPE_WORLDONLY"},
|
||||
{"DP_QC_TRACE_MOVETYPES"}, //this one is just a lame excuse to add annother extension...
|
||||
{"DP_QC_UNLIMITEDTEMPSTRINGS", 0, NULL, {NULL}, "Supersedes DP_QC_MULTIPLETEMPSTRINGS, superseded by FTE_QC_PERSISTENTTEMPSTRINGS. All temp strings will be valid at least until the QCVM returns."},
|
||||
{"DP_QC_UNLIMITEDTEMPSTRINGS", 0, NULL, {NULL}, "Supersedes DP_QC_MULTIPLETEMPSTRINGS, superseded by FTE_QC_PERSISTENTTEMPSTRINGS. Specifies that all temp strings will be valid at least until the QCVM returns."},
|
||||
{"DP_QC_URI_ESCAPE", 2, NULL, {"uri_escape", "uri_unescape"}},
|
||||
#ifdef WEBCLIENT
|
||||
{"DP_QC_URI_GET", 1, NULL, {"uri_get"}},
|
||||
|
@ -5889,23 +5893,23 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"DP_SOLIDCORPSE"},
|
||||
{"DP_SPRITE32"}, //hmm... is it legal to advertise this one?
|
||||
{"DP_SV_BOTCLIENT", 2, NULL, {"spawnclient", "clienttype"}},
|
||||
{"DP_SV_CLIENTCOLORS"},
|
||||
{"DP_SV_CLIENTNAME"},
|
||||
{"DP_SV_CLIENTCOLORS", 0, NULL, {NULL}, "Provided only for compatibility with DP."},
|
||||
{"DP_SV_CLIENTNAME", 0, NULL, {NULL}, "Provided only for compatibility with DP."},
|
||||
{"DP_SV_DRAWONLYTOCLIENT"},
|
||||
{"DP_SV_DROPCLIENT", 1, NULL, {"dropclient"}},
|
||||
{"DP_SV_DROPCLIENT", 1, NULL, {"dropclient"}, "Equivelent to quakeworld's stuffcmd(self,\"disconnect\\n\"); hack"},
|
||||
{"DP_SV_EFFECT", 1, NULL, {"effect"}},
|
||||
{"DP_SV_EXTERIORMODELFORCLIENT"},
|
||||
{"DP_SV_NODRAWTOCLIENT"}, //I prefer my older system. Guess I might as well remove that older system at some point.
|
||||
{"DP_SV_PLAYERPHYSICS"},
|
||||
//FTE cannot implement this one, because dp's arguments are the wrong way around. its otherwise implemented. {"DP_SV_POINTPARTICLES"},
|
||||
{"DP_SV_PLAYERPHYSICS", 0, NULL, {NULL}, "Allows reworking parts of NQ player physics. USE AT OWN RISK - this necessitates NQ physics and is thus guarenteed to break prediction."},
|
||||
{"DP_SV_POINTPARTICLES", 3, NULL, {"particleeffectnum", "pointparticles", "trailparticles"}, "Specifies that pointparticles (and trailparticles) exists in ssqc as well as csqc (and that dp's trailparticles argument fuckup will normally work). ssqc values can be passed to csqc for use, the reverse is not true. Does NOT mean that DP's effectinfo.txt is supported, only that ssqc has functionality equivelent to csqc."},
|
||||
{"DP_SV_POINTSOUND", 1, NULL, {"pointsound"}},
|
||||
{"DP_SV_PRECACHEANYTIME"},
|
||||
{"DP_SV_PRECACHEANYTIME", 0, NULL, {NULL}, "Specifies that the various precache builtins can be called at any time. WARNING: precaches are sent reliably while sound events, modelindexes, and particle events are not. This can mean sounds and particles might not work the first time around, or models may take a while to appear (after the reliables are received and the model is loaded from disk). Always attempt to precache a little in advance in order to reduce these issues (preferably at the start of the map...)"},
|
||||
{"DP_SV_SETCOLOR"},
|
||||
{"DP_SV_SPAWNFUNC_PREFIX"},
|
||||
{"DP_SV_WRITEPICTURE", 1, NULL, {"WritePicture"}},
|
||||
{"DP_SV_WRITEUNTERMINATEDSTRING", 1, NULL, {"WriteUnterminatedString"}},
|
||||
{"DP_TE_BLOOD", 1, NULL, {"te_blood"}},
|
||||
{"DP_TE_BLOODSHOWER", 1, NULL, {"te_bloodshower"}},
|
||||
{"_DP_TE_BLOODSHOWER", 1, NULL, {"te_bloodshower"}},
|
||||
{"DP_TE_CUSTOMFLASH", 1, NULL, {"te_customflash"}},
|
||||
{"DP_TE_EXPLOSIONRGB", 1, NULL, {"te_explosionrgb"}},
|
||||
{"_DP_TE_FLAMEJET", 1, NULL, {"te_flamejet"}},
|
||||
|
@ -5937,7 +5941,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
"skel_get_bonerel", "skel_get_boneabs", "skel_set_bone", "skel_mul_bone", "skel_mul_bones", "skel_copybones",
|
||||
"skel_delete", "frameforname", "frameduration"}},
|
||||
{"FTE_CSQC_RENDERTARGETS_WIP", 0, NULL, {NULL}, "VF_DESTCOLOUR etc exist and are supported"},
|
||||
{"FTE_ENT_SKIN_CONTENTS"}, //self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder.
|
||||
{"FTE_ENT_SKIN_CONTENTS", 0, NULL, {NULL}, "self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder."},
|
||||
{"FTE_ENT_UNIQUESPAWNID"},
|
||||
{"FTE_EXTENDEDTEXTCODES"},
|
||||
{"FTE_FORCESHADER", 1, NULL, {"shaderforname"}}, //I'd rename this to _CSQC_ but it does technically provide this builtin to menuqc too, not that the forceshader entity field exists there... but whatever.
|
||||
|
@ -5946,9 +5950,11 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}, "Allows you to check if a client has too many reliable messages pending."},
|
||||
{"FTE_MEMALLOC", 4, NULL, {"memalloc", "memfree", "memcpy", "memfill8"}, "Allows dynamically allocating memory. Use pointers to access this memory. Memory will not be saved into saved games."},
|
||||
#ifndef NOMEDIA
|
||||
{"FTE_MEDIA_AVI"}, //playfilm supports avi files.
|
||||
{"FTE_MEDIA_CIN"}, //playfilm command supports q2 cin files.
|
||||
{"FTE_MEDIA_ROQ"}, //playfilm command supports q3 roq files
|
||||
#if defined(_WIN32) && !defined(WINRT)
|
||||
{"FTE_MEDIA_AVI", 0, NULL, {NULL}, "playfilm command supports avi files."},
|
||||
#endif
|
||||
{"FTE_MEDIA_CIN", 0, NULL, {NULL}, "playfilm command supports q2 cin files."},
|
||||
{"FTE_MEDIA_ROQ", 0, NULL, {NULL}, "playfilm command supports q3 roq files."},
|
||||
#endif
|
||||
{"FTE_MULTIPROGS", 5, NULL, {"externcall", "addprogs", "externvalue", "externset", "instr"}, "Multiple progs.dat files can be loaded inside the same qcvm."}, //multiprogs functions are available.
|
||||
{"FTE_MULTITHREADED", 3, NULL, {"sleep", "fork", "abort"}},
|
||||
|
@ -5958,7 +5964,7 @@ lh_extension_t QSG_Extensions[] = {
|
|||
#ifdef SVCHAT
|
||||
{"FTE_NPCCHAT", 1, NULL, {"chat"}}, //server looks at chat files. It automagically branches through calling qc functions as requested.
|
||||
#endif
|
||||
{"FTE_QC_CHECKCOMMAND", 1, NULL, {"checkcommand"}},
|
||||
{"FTE_QC_CHECKCOMMAND", 1, NULL, {"checkcommand"}, "Provides a way to test if a console command exists, and whether its a command/alias/cvar. Does not say anything about the expected meanings of any arguments or values."},
|
||||
{"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}},
|
||||
{"FTE_QC_HARDWARECURSORS", 0, NULL, {NULL}, "setcursormode exists in both csqc+menuqc, and accepts additional arguments to specify a cursor image to use when this module has focus. If the image exceeds hardware limits, it will be emulated using regular draws - this at least still avoids conflicting cursors."},
|
||||
{"FTE_QC_HASHTABLES", 6, NULL, {"hash_createtab", "hash_destroytab", "hash_add", "hash_get", "hash_delete", "hash_getkey"}},
|
||||
|
@ -5971,6 +5977,18 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"FTE_QC_RAGDOLL_WIP", 1, NULL, {"ragupdate", "skel_set_bone_world", "skel_mmap"}},
|
||||
{"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}}, //includes the SV_ParseConnectionlessPacket event.
|
||||
{"FTE_QC_TRACETRIGGER"},
|
||||
#ifdef Q2CLIENT
|
||||
{"FTE_QUAKE2_CLIENT", 0, NULL, {NULL}, "This engine is able to act as a quake2 client"},
|
||||
#endif
|
||||
#ifdef Q2SERVER
|
||||
{"FTE_QUAKE2_SERVER", 0, NULL, {NULL}, "This engine is able to act as a quake2 server"},
|
||||
#endif
|
||||
#ifdef Q3CLIENT
|
||||
{"FTE_QUAKE3_CLIENT", 0, NULL, {NULL}, "This engine is able to act as a quake3 client"},
|
||||
#endif
|
||||
#ifdef Q3SERVER
|
||||
{"FTE_QUAKE3_SERVER", 0, NULL, {NULL}, "This engine is able to act as a quake3 server"},
|
||||
#endif
|
||||
{"FTE_SOLID_LADDER"}, //Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS
|
||||
|
||||
#ifdef SQL
|
||||
|
@ -5986,6 +6004,10 @@ lh_extension_t QSG_Extensions[] = {
|
|||
{"FTE_SV_REENTER"},
|
||||
{"FTE_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash",
|
||||
"te_teleport", "te_lightning1", "te_lightning2", "te_lightning3", "te_lightningblood", "te_bloodqw"}},
|
||||
#ifdef TERRAIN
|
||||
{"FTE_TERRAIN_MAP", 0, NULL, {NULL}, "This engine supports .hmp files, as well as terrain embedded within bsp files."},
|
||||
{"FTE_RAW_MAP", 0, NULL, {NULL}, "This engine supports directly loading .map files, as well as realtime editing of the various brushes."},
|
||||
#endif
|
||||
|
||||
{"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system.
|
||||
{"NEH_CMD_PLAY2"},
|
||||
|
|
|
@ -105,10 +105,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define PROTOCOL_INFO_GUID (('G'<<0) + ('U'<<8) + ('I'<<16) + ('D' << 24)) //globally 'unique' client id info.
|
||||
|
||||
#define PROTOCOL_VERSION_QW 28
|
||||
#define PROTOCOL_VERSION_Q2_DEMO_MIN 26
|
||||
#define PROTOCOL_VERSION_Q2_MIN 31
|
||||
#define PROTOCOL_VERSION_Q2 34
|
||||
#define PROTOCOL_VERSION_QW 28
|
||||
|
||||
#define PROTOCOL_VERSION_Q2_DEMO_MIN 26
|
||||
#define PROTOCOL_VERSION_Q2_MIN 31
|
||||
#define PROTOCOL_VERSION_Q2 34
|
||||
#define PROTOCOL_VERSION_R1Q2 35
|
||||
#define PROTOCOL_VERSION_Q2PRO 36
|
||||
|
||||
//=========================================
|
||||
|
||||
|
@ -392,7 +395,13 @@ enum svcq2_ops_e
|
|||
svcq2_playerinfo, //17 // variable
|
||||
svcq2_packetentities,//18 // [...]
|
||||
svcq2_deltapacketentities,//19 // [...]
|
||||
svcq2_frame //20 (the bastard to implement.)
|
||||
svcq2_frame, //20 (the bastard to implement.)
|
||||
|
||||
|
||||
svcr1q2_zpacket = 21,
|
||||
svcr1q2_zdownload = 22,
|
||||
svcq2pro_gamestate = 23, // q2pro specific, means svc_playerupdate in r1q2
|
||||
svcq2pro_setting = 24,
|
||||
};
|
||||
|
||||
enum clcq2_ops_e
|
||||
|
@ -766,6 +775,7 @@ enum clcq2_ops_e
|
|||
#define Q2U_ANGLE1 (1<<10)
|
||||
#define Q2U_MODEL (1<<11)
|
||||
#define Q2U_RENDERFX8 (1<<12) // fullbright, etc
|
||||
#define Q2UX_ANGLE16 (1<<13)
|
||||
#define Q2U_EFFECTS8 (1<<14) // autorotate, trails, etc
|
||||
#define Q2U_MOREBITS2 (1<<15) // read one additional qbyte
|
||||
|
||||
|
@ -784,6 +794,12 @@ enum clcq2_ops_e
|
|||
#define Q2U_SKIN16 (1<<25)
|
||||
#define Q2U_SOUND (1<<26)
|
||||
#define Q2U_SOLID (1<<27)
|
||||
#define Q2UX_UNUSED4 (1<<28)
|
||||
#define Q2UX_UNUSED3 (1<<29)
|
||||
#define Q2UX_UNUSED2 (1<<30)
|
||||
#define Q2UX_UNUSED1 (1<<31)
|
||||
|
||||
#define Q2UX_UNUSED (Q2UX_UNUSED1|Q2UX_UNUSED2|Q2UX_UNUSED3|Q2UX_UNUSED4)
|
||||
|
||||
|
||||
//==============================================
|
||||
|
@ -1009,6 +1025,7 @@ typedef struct entity_state_s
|
|||
vec3_t predorg;
|
||||
} q1;
|
||||
} u;
|
||||
|
||||
unsigned short modelindex2; //q2/vweps
|
||||
unsigned short frame;
|
||||
|
||||
|
@ -1031,13 +1048,13 @@ typedef struct entity_state_s
|
|||
|
||||
qbyte lightstyle;
|
||||
qbyte lightpflags;
|
||||
unsigned short solid;
|
||||
unsigned short tagindex;
|
||||
unsigned int tagentity;
|
||||
|
||||
unsigned int solid;
|
||||
#define ES_SOLID_BSP 31
|
||||
|
||||
unsigned short light[4];
|
||||
|
||||
unsigned short tagentity;
|
||||
unsigned short tagindex;
|
||||
} entity_state_t;
|
||||
extern entity_state_t nullentitystate;
|
||||
|
||||
|
@ -1178,6 +1195,14 @@ typedef struct q1usercmd_s
|
|||
#define Q2PS_WEAPONFRAME (1<<13)
|
||||
#define Q2PS_RDFLAGS (1<<14)
|
||||
|
||||
#define Q2PSX_GUNOFFSET (1<<0)
|
||||
#define Q2PSX_GUNANGLES (1<<1)
|
||||
#define Q2PSX_M_VELOCITY2 (1<<2)
|
||||
#define Q2PSX_M_ORIGIN2 (1<<3)
|
||||
#define Q2PSX_VIEWANGLE2 (1<<4)
|
||||
#define Q2PSX_STATS (1<<5)
|
||||
#define Q2PSX_CLIENTNUM (1<<6)
|
||||
#define Q2PSX_OLD (1<<8) //not part of the protocol, just lazy handling.
|
||||
|
||||
|
||||
// entity_state_t->renderfx flags
|
||||
|
|
|
@ -734,7 +734,7 @@ void Netchan_TransmitNextFragment( netchan_t *chan )
|
|||
// Send the qport if we are a client
|
||||
if( chan->sock == NS_CLIENT )
|
||||
{
|
||||
MSG_WriteShort( &send, cls.qport);
|
||||
MSG_WriteShort( &send, chan->qport);
|
||||
}
|
||||
#endif
|
||||
fragmentLength = chan->reliable_length - chan->reliable_start;
|
||||
|
@ -833,7 +833,7 @@ void Netchan_TransmitQ3( netchan_t *chan, int length, const qbyte *data )
|
|||
// Send the qport if we are a client
|
||||
if( chan->sock == NS_CLIENT )
|
||||
{
|
||||
MSG_WriteShort( &send, cls.qport);
|
||||
MSG_WriteShort( &send, chan->qport);
|
||||
}
|
||||
#endif
|
||||
// Copy the message to the packet
|
||||
|
|
|
@ -2657,9 +2657,8 @@ qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, lump_t *
|
|||
void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *cookie)
|
||||
{
|
||||
unsigned int vertidx;
|
||||
int i, lindex;
|
||||
int i, lindex, edgevert;
|
||||
mesh_t *mesh = surf->mesh;
|
||||
medge_t *pedge;
|
||||
float *vec;
|
||||
float s, t, d;
|
||||
int sty;
|
||||
|
@ -2692,17 +2691,13 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
|
|||
for (i=0 ; i<mesh->numvertexes ; i++)
|
||||
{
|
||||
lindex = mod->surfedges[surf->firstedge + i];
|
||||
|
||||
if (lindex > 0)
|
||||
{
|
||||
pedge = &mod->edges[lindex];
|
||||
vertidx = pedge->v[0];
|
||||
}
|
||||
edgevert = lindex <= 0;
|
||||
if (edgevert)
|
||||
lindex = -lindex;
|
||||
if (lindex < 0 || lindex >= mod->numedges)
|
||||
vertidx = 0;
|
||||
else
|
||||
{
|
||||
pedge = &mod->edges[-lindex];
|
||||
vertidx = pedge->v[1];
|
||||
}
|
||||
vertidx = mod->edges[lindex].v[edgevert];
|
||||
vec = mod->vertexes[vertidx].position;
|
||||
|
||||
s = DotProduct (vec, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
|
||||
|
@ -2973,6 +2968,7 @@ static int Mod_Batches_Generate(model_t *mod)
|
|||
mod->lightmaps.count /= merge;
|
||||
mod->lightmaps.height *= merge;
|
||||
|
||||
mod->numbatches = 0;
|
||||
|
||||
//for each surface, find a suitable batch to insert it into.
|
||||
//we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit)
|
||||
|
|
|
@ -2878,18 +2878,12 @@ void DumpGLState(void)
|
|||
// qglGetPointerv(GL_FOG_COORD_ARRAY_POINTER, &ptr);
|
||||
// Sys_Printf("GL_FOG_COORDINATE_ARRAY_EXT: %i (%lx)\n", (int) qglIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT), (int) ptr);
|
||||
// }
|
||||
// if (qglIsEnabled(GL_INDEX_ARRAY))
|
||||
{
|
||||
if (qglBindBufferARB)
|
||||
qglGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &rval);
|
||||
else
|
||||
rval = 0;
|
||||
#ifndef GL_INDEX_ARRAY_POINTER
|
||||
Sys_Printf("GL_ELEMENT_ARRAY_BUFFER_BINDING: %i:%p\n", rval, (void*)0);
|
||||
#else
|
||||
qglGetPointerv(GL_INDEX_ARRAY_POINTER, &ptr);
|
||||
Sys_Printf("GL_INDEX_ARRAY: %s %i:%p\n", qglIsEnabled(GL_INDEX_ARRAY)?"en":"dis", rval, ptr);
|
||||
#endif
|
||||
}
|
||||
if (qglIsEnabled(GL_NORMAL_ARRAY))
|
||||
{
|
||||
|
|
|
@ -18,6 +18,21 @@ r_part pe_default
|
|||
scalefactor 0.8
|
||||
}
|
||||
|
||||
r_part TEQ2_LASER_SPARKS
|
||||
{
|
||||
texture "classicparticle"
|
||||
tcoords 0 0 16 16 32
|
||||
count 1
|
||||
scale 1
|
||||
alpha 1
|
||||
die 0.3 0.8
|
||||
randomvel 20
|
||||
orgadd 0 7
|
||||
spawnorg 4
|
||||
gravity 40
|
||||
scalefactor 0.8
|
||||
}
|
||||
|
||||
r_part te_splashsparks
|
||||
{
|
||||
texture "classicparticle"
|
||||
|
@ -268,7 +283,7 @@ r_part teq2_blaster
|
|||
lightradius 150
|
||||
lightradiusfade 400
|
||||
lightrgb 1 1 0
|
||||
lightshadows 0
|
||||
lightshadows 1
|
||||
sound "weapons/lashit.wav" 1 1 0 0
|
||||
}
|
||||
r_part teq2_blaster2
|
||||
|
@ -290,7 +305,7 @@ r_part teq2_blaster2
|
|||
lightradius 150
|
||||
lightradiusfade 400
|
||||
lightrgb 0.05 1.0 0.05
|
||||
lightshadows 0
|
||||
lightshadows 1
|
||||
sound "weapons/lashit.wav" 1 1 0 0
|
||||
}
|
||||
r_part TR_BLASTERTRAIL
|
||||
|
@ -305,6 +320,10 @@ r_part TR_BLASTERTRAIL
|
|||
randomvel 5
|
||||
die 0.3 0.5
|
||||
colorindex 0xe0
|
||||
lightradius 200
|
||||
lightradiusfade 400
|
||||
lightrgb 1.0 1.0 0.0
|
||||
lightshadows 1
|
||||
}
|
||||
|
||||
//green version
|
||||
|
@ -320,6 +339,10 @@ r_part TR_BLASTERTRAIL2
|
|||
randomvel 5
|
||||
die 0.3 0.5
|
||||
colorindex 0xd0
|
||||
lightradius 200
|
||||
lightradiusfade 400
|
||||
lightrgb 0.0 1.0 0.0
|
||||
lightshadows 1
|
||||
}
|
||||
|
||||
|
||||
|
@ -490,12 +513,25 @@ r_part trq2_grenade
|
|||
}
|
||||
r_part trq2_gib
|
||||
{
|
||||
assoc tr_gib
|
||||
texture "particles/quake"
|
||||
step 3
|
||||
scale 4
|
||||
die 1.0 1.4
|
||||
colorindex 0xe8 7
|
||||
spawnorg 1
|
||||
spawnvel 5
|
||||
gravity -20
|
||||
}
|
||||
//FIXME: implement
|
||||
r_part trq2_greengib
|
||||
{
|
||||
assoc tr_gib
|
||||
texture "particles/quake"
|
||||
step 3
|
||||
scale 4
|
||||
die 1.0 1.4
|
||||
colorindex 0xdb 7
|
||||
spawnorg 1
|
||||
spawnvel 5
|
||||
gravity -20
|
||||
}
|
||||
|
||||
r_part TR_PLASMA
|
||||
|
@ -527,6 +563,14 @@ r_part tr_tagtrail
|
|||
lightrgb 1.0 1.0 0.0
|
||||
}
|
||||
|
||||
//FIXME: add particles
|
||||
r_part tr_trap
|
||||
{
|
||||
lighttime 0
|
||||
lightradius 100 200
|
||||
lightrgb 1.0 0.8 0.25
|
||||
}
|
||||
|
||||
//flags do NOT use coronas, because it obscures the holding player's skin colour
|
||||
r_part tr_flag1
|
||||
{
|
||||
|
@ -565,15 +609,6 @@ r_part tr_flag2
|
|||
lightrgb 0.25 0.25 1.0
|
||||
}
|
||||
|
||||
|
||||
//FIXME: add particles
|
||||
r_part tr_trap
|
||||
{
|
||||
lighttime 0
|
||||
lightradius 100 200
|
||||
lightrgb 1.0 0.8 0.25
|
||||
}
|
||||
|
||||
r_part EF_FLIES
|
||||
{
|
||||
texture "classicparticle"
|
||||
|
@ -670,4 +705,26 @@ r_part teq2_bfg_explosion
|
|||
lightrgbfade 0.0 0.0 0.0
|
||||
sound "weapons/xpld_wat.wav" 1 1 0 0
|
||||
model "sprites/s_bfg2.sp2" framestart=0 frameend=4 alpha=0.3 transparent fullbright noshadow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//31qu cylinder, 8-98 high
|
||||
//should look like its sucked up into some thingie above
|
||||
r_part TEQ2_BOSSTPORT
|
||||
{
|
||||
texture "classicparticle"
|
||||
tcoords 0 0 16 16 32
|
||||
count 800
|
||||
scale 1
|
||||
alpha 1
|
||||
die 0.5 0.8
|
||||
orgadd 8 -98
|
||||
veladd 100 200
|
||||
spawnmode circle
|
||||
spawnorg 48 0
|
||||
spawnvel -50 30
|
||||
randomvel 32 31
|
||||
gravity -800
|
||||
rgbf 1 1 1
|
||||
scalefactor 0.8
|
||||
}
|
||||
|
|
BIN
engine/qclib/byshpuld.ico
Normal file
BIN
engine/qclib/byshpuld.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
|
@ -1232,17 +1232,17 @@ reeval:
|
|||
return s;
|
||||
*/ }
|
||||
break;
|
||||
/* case OP_PUSH:
|
||||
OPC->_int = ENGINEPOINTER(&localstack[localstack_used+pr_spushed]);
|
||||
pr_spushed += OPA->_int;
|
||||
if (pr_spushed + localstack_used >= LOCALSTACK_SIZE)
|
||||
case OP_PUSH:
|
||||
OPC->_int = ENGINEPOINTER(&prinst.localstack[prinst.localstack_used+prinst.spushed]);
|
||||
prinst.spushed += OPA->_int;
|
||||
if (prinst.spushed + prinst.localstack_used >= LOCALSTACK_SIZE)
|
||||
{
|
||||
pr_spushed = 0;
|
||||
prinst.spushed = 0;
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError(progfuncs, "Progs pushed too much");
|
||||
PR_RunError(&progfuncs->funcs, "Progs pushed too much");
|
||||
}
|
||||
break;
|
||||
case OP_POP:
|
||||
/* case OP_POP:
|
||||
pr_spushed -= OPA->_int;
|
||||
if (pr_spushed < 0)
|
||||
{
|
||||
|
|
1
engine/qclib/fteqcc.rc
Normal file
1
engine/qclib/fteqcc.rc
Normal file
|
@ -0,0 +1 @@
|
|||
101 ICON "byshpuld.ico"
|
|
@ -464,6 +464,7 @@ struct QCC_function_s
|
|||
const char *file;
|
||||
int line;
|
||||
char *name; //internal name of function
|
||||
struct QCC_function_s *parentscope; //for nested functions
|
||||
struct QCC_type_s *type; //same as the def's type
|
||||
struct QCC_def_s *def;
|
||||
struct QCC_def_s *firstlocal;
|
||||
|
|
|
@ -220,6 +220,8 @@ const QCC_sref_t nullsref = {0};
|
|||
struct QCC_function_s *pr_scope; // the function being parsed, or NULL
|
||||
QCC_type_t *pr_classtype; // the class that the current function is part of.
|
||||
QCC_type_t *pr_assumetermtype; //undefined things get this time, with no warning about being undeclared (used for the state function, so prototypes are not needed)
|
||||
QCC_function_t *pr_assumetermscope;
|
||||
unsigned int pr_assumetermflags; //GDF_
|
||||
pbool pr_dumpasm;
|
||||
QCC_string_t s_file, s_file2; // filename for function definition
|
||||
|
||||
|
@ -1626,6 +1628,7 @@ static QCC_sref_t QCC_GetTemp(QCC_type_t *type);
|
|||
void QCC_FreeTemp(QCC_sref_t t);
|
||||
void QCC_FreeDef(QCC_def_t *def);
|
||||
QCC_sref_t QCC_MakeSRefForce(QCC_def_t *def, unsigned int ofs, QCC_type_t *type);
|
||||
QCC_sref_t QCC_MakeSRef(QCC_def_t *def, unsigned int ofs, QCC_type_t *type);
|
||||
|
||||
//we're about to overwrite the given def, so if there's any aliases to it, we need to clear them out.
|
||||
static void QCC_ClobberDef(QCC_def_t *def)
|
||||
|
@ -2916,11 +2919,39 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
QCC_FreeTemp(var_a);
|
||||
optres_assignments++;
|
||||
|
||||
if (flags&STFL_DISCARDRESULT)
|
||||
{
|
||||
QCC_FreeTemp(var_b);
|
||||
var_b = nullsref;
|
||||
}
|
||||
return var_b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (op - pr_opcodes == OP_ADD_I && statements[numstatements-1].op == OP_MUL_I && opt_assignments)
|
||||
{
|
||||
//mul_i idx 4i tmp
|
||||
//add_i tmp 2i out
|
||||
//becomes add_piw 2i idx out
|
||||
|
||||
// const QCC_eval_t *eval_a = QCC_SRef_EvalConst(var_a);
|
||||
const QCC_eval_t *eval_b = QCC_SRef_EvalConst(statements[numstatements-1].b);
|
||||
|
||||
if (eval_b && eval_b->_int == 4)
|
||||
{
|
||||
if (opt_assignments && var_a.cast && var_a.sym == statements[numstatements-1].c.sym && var_a.ofs == statements[numstatements-1].c.ofs)
|
||||
if (var_a.sym && var_b.sym && var_a.sym->temp && var_a.sym->refcount==1)
|
||||
{
|
||||
op = &pr_opcodes[OP_ADD_PIW];
|
||||
QCC_FreeDef(var_a.sym);
|
||||
var_a = var_b;
|
||||
var_b = statements[numstatements-1].a;
|
||||
numstatements--;
|
||||
QCC_ForceUnFreeDef(var_b.sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!QCC_OPCodeValid(op))
|
||||
|
@ -3156,10 +3187,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
var_a.cast = type_float;
|
||||
}
|
||||
if (var_b.cast)
|
||||
{
|
||||
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_F], var_a, var_b, NULL, 0));
|
||||
return var_b;
|
||||
}
|
||||
return QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_F], var_a, var_b, NULL, flags&STFL_DISCARDRESULT);
|
||||
}
|
||||
return var_a;
|
||||
case OP_CONV_FTOI:
|
||||
|
@ -3185,10 +3213,7 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
var_a.cast = type_integer;
|
||||
}
|
||||
if (var_b.cast)
|
||||
{
|
||||
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_I], var_a, var_b, NULL, 0));
|
||||
return var_b;
|
||||
}
|
||||
return QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_I], var_a, var_b, NULL, flags&STFL_DISCARDRESULT);
|
||||
}
|
||||
return var_a;
|
||||
case OP_STORE_P:
|
||||
|
@ -5008,13 +5033,24 @@ QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou
|
|||
}
|
||||
}
|
||||
if (!strcmp(funcname, "alloca"))
|
||||
{ //FIXME: half of these functions with regular expression arguments should be handled later or something
|
||||
QCC_sref_t sz;
|
||||
{ //FIXME: half of these functions with known arguments should be handled later or something
|
||||
QCC_sref_t sz, ret;
|
||||
|
||||
if (!func.sym->initialized)
|
||||
func.sym->initialized = 3;
|
||||
func.sym->referenced = true;
|
||||
QCC_FreeTemp(func);
|
||||
|
||||
sz = QCC_PR_Expression(TOP_PRIORITY, 0);
|
||||
QCC_PR_Expect(")");
|
||||
sz = QCC_SupplyConversion(sz, ev_integer, true);
|
||||
sz = QCC_PR_Statement(&pr_opcodes[OP_PUSH], sz, nullsref, NULL);
|
||||
return sz;
|
||||
//result = push_words((sz+3)/4);
|
||||
sz = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], sz, QCC_MakeIntConst(3), NULL);
|
||||
sz = QCC_PR_Statement(&pr_opcodes[OP_DIV_I], sz, QCC_MakeIntConst(4), NULL);
|
||||
QCC_FreeTemp(sz);
|
||||
ret = QCC_GetTemp(QCC_PointerTypeTo(type_variant));
|
||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_PUSH], sz, nullsref, ret, false); //push *(int*)&a elements
|
||||
return ret;
|
||||
}
|
||||
if (!strcmp(funcname, "_"))
|
||||
{
|
||||
|
@ -6386,12 +6422,20 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
}
|
||||
arraysize = 0;
|
||||
|
||||
//convert it to ints if that makes sense
|
||||
if (QCC_OPCodeValid(&pr_opcodes[OP_ADD_I]))
|
||||
{
|
||||
if (idx.cast)
|
||||
idx = QCC_SupplyConversion(idx, ev_integer, true);
|
||||
tmp = QCC_SupplyConversion(tmp, ev_integer, true);
|
||||
}
|
||||
|
||||
if (t->size != 1) /*don't multiply by type size if the instruction/emulation will do that instead*/
|
||||
{
|
||||
if (tmp.cast->type == ev_float)
|
||||
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], tmp, QCC_MakeFloatConst(t->size), NULL);
|
||||
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], QCC_SupplyConversion(tmp, ev_float, true), QCC_MakeFloatConst(t->size), NULL);
|
||||
else
|
||||
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], tmp, QCC_MakeIntConst(t->size), NULL);
|
||||
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_I], QCC_SupplyConversion(tmp, ev_integer, true), QCC_MakeIntConst(t->size), NULL);
|
||||
}
|
||||
|
||||
//legacy opcodes needs to stay using floats even if an int was specified
|
||||
|
@ -6404,9 +6448,9 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
|
||||
/*calc the new index*/
|
||||
if (idx.cast && idx.cast->type == ev_float && tmp.cast->type == ev_float)
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], idx, QCC_SupplyConversion(tmp, ev_float, true), NULL);
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], QCC_SupplyConversion(idx, ev_float, true), QCC_SupplyConversion(tmp, ev_float, true), NULL);
|
||||
else if (idx.cast)
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL);
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], QCC_SupplyConversion(idx, ev_integer, true), QCC_SupplyConversion(tmp, ev_integer, true), NULL);
|
||||
else
|
||||
idx = tmp;
|
||||
}
|
||||
|
@ -6453,7 +6497,7 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
{
|
||||
tmp = QCC_MakeIntConst(t->params[i].ofs);
|
||||
if (idx.cast)
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, tmp, NULL);
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], QCC_SupplyConversion(idx, ev_integer, true), QCC_SupplyConversion(tmp, ev_integer, true), NULL);
|
||||
else
|
||||
idx = tmp;
|
||||
}
|
||||
|
@ -6461,7 +6505,7 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
{
|
||||
tmp = QCC_MakeFloatConst(t->params[i].ofs);
|
||||
if (idx.cast)
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], idx, tmp, NULL);
|
||||
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], QCC_SupplyConversion(idx, ev_float, true), QCC_SupplyConversion(tmp, ev_float, true), NULL);
|
||||
else
|
||||
idx = tmp;
|
||||
}
|
||||
|
@ -6617,22 +6661,19 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
|
|||
d = QCC_GetTemp(type_vector);
|
||||
d.cast = type_float;
|
||||
if (x.cast->type == ev_float)
|
||||
x=QCC_PR_StatementFlags(pr_opcodes + OP_STORE_F, x, d, NULL, STFL_PRESERVEB);
|
||||
QCC_PR_StatementFlags(pr_opcodes + OP_STORE_F, x, d, NULL, STFL_PRESERVEB|STFL_DISCARDRESULT);
|
||||
else
|
||||
x=QCC_PR_StatementFlags(pr_opcodes+OP_STORE_IF, x, d, NULL, STFL_PRESERVEB);
|
||||
QCC_FreeTemp(x);
|
||||
QCC_PR_StatementFlags(pr_opcodes+OP_STORE_IF, x, d, NULL, STFL_PRESERVEB|STFL_DISCARDRESULT);
|
||||
d.ofs++;
|
||||
if (y.cast->type == ev_float)
|
||||
y=QCC_PR_StatementFlags(pr_opcodes + OP_STORE_F, y, d, NULL, STFL_PRESERVEB);
|
||||
QCC_PR_StatementFlags(pr_opcodes + OP_STORE_F, y, d, NULL, STFL_PRESERVEB|STFL_DISCARDRESULT);
|
||||
else
|
||||
y=QCC_PR_StatementFlags(pr_opcodes+OP_STORE_IF, y, d, NULL, STFL_PRESERVEB);
|
||||
QCC_FreeTemp(y);
|
||||
QCC_PR_StatementFlags(pr_opcodes+OP_STORE_IF, y, d, NULL, STFL_PRESERVEB|STFL_DISCARDRESULT);
|
||||
d.ofs++;
|
||||
if (z.cast->type == ev_float)
|
||||
z=QCC_PR_StatementFlags(pr_opcodes + OP_STORE_F, z, d, NULL, STFL_PRESERVEB);
|
||||
QCC_PR_StatementFlags(pr_opcodes + OP_STORE_F, z, d, NULL, STFL_PRESERVEB|STFL_DISCARDRESULT);
|
||||
else
|
||||
z=QCC_PR_StatementFlags(pr_opcodes+OP_STORE_IF, z, d, NULL, STFL_PRESERVEB);
|
||||
QCC_FreeTemp(z);
|
||||
QCC_PR_StatementFlags(pr_opcodes+OP_STORE_IF, z, d, NULL, STFL_PRESERVEB|STFL_DISCARDRESULT);
|
||||
d.ofs++;
|
||||
d.ofs -= 3;
|
||||
d.cast = type_vector;
|
||||
|
@ -6719,6 +6760,7 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
|
|||
d = QCC_MakeIntConst(0);
|
||||
else if ( (!strcmp(name, "randomv")) ||
|
||||
(!strcmp(name, "sizeof")) ||
|
||||
(!strcmp(name, "alloca")) ||
|
||||
(!strcmp(name, "entnum")) ||
|
||||
(!strcmp(name, "autocvar")) ||
|
||||
(!strcmp(name, "used_model")) ||
|
||||
|
@ -6753,7 +6795,7 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
|
|||
}
|
||||
else if (pr_assumetermtype)
|
||||
{
|
||||
d = QCC_PR_GetSRef (pr_assumetermtype, name, NULL, true, 0, false);
|
||||
d = QCC_PR_GetSRef (pr_assumetermtype, name, pr_assumetermscope, true, 0, pr_assumetermflags);
|
||||
if (!d.cast)
|
||||
QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
|
||||
}
|
||||
|
@ -6942,7 +6984,7 @@ QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit)
|
|||
char typeb[256];
|
||||
TypeName(src.cast, typea, sizeof(typea));
|
||||
TypeName(cast, typeb, sizeof(typeb));
|
||||
QCC_PR_ParseWarning(0, "Implicit cast from %s to %s\n", typea, typeb);
|
||||
QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb);
|
||||
}
|
||||
}
|
||||
src.cast = cast;
|
||||
|
@ -6968,7 +7010,7 @@ QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit)
|
|||
char typeb[256];
|
||||
TypeName(src.cast, typea, sizeof(typea));
|
||||
TypeName(cast, typeb, sizeof(typeb));
|
||||
QCC_PR_ParseWarning(0, "Implicit cast from %s to %s\n", typea, typeb);
|
||||
QCC_PR_ParseWarning(0, "Implicit cast from %s to %s", typea, typeb);
|
||||
}
|
||||
src.cast = cast;
|
||||
}
|
||||
|
@ -8008,7 +8050,9 @@ QCC_sref_t QCC_StoreToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable, pb
|
|||
{
|
||||
addr = dest->base;
|
||||
}
|
||||
QCC_PR_Statement(&pr_opcodes[OP_STOREP_C], addr, source, NULL);
|
||||
// if (readable) //if we're returning source, make sure it can't get freed
|
||||
// QCC_UnFreeTemp(source);
|
||||
QCC_PR_StatementFlags(&pr_opcodes[OP_STOREP_C], source, addr, NULL, STFL_DISCARDRESULT|(preservedest?STFL_PRESERVEB:0)|(readable?STFL_PRESERVEA:0));
|
||||
}
|
||||
break;
|
||||
case REF_ACCESSOR:
|
||||
|
@ -9839,6 +9883,7 @@ void QCC_PR_ParseState (void)
|
|||
{
|
||||
QCC_sref_t s1, def;
|
||||
|
||||
//FIXME: this is ambiguous with pre-inc and post-inc logic.
|
||||
if (QCC_PR_CheckToken("++") || QCC_PR_CheckToken("--"))
|
||||
{
|
||||
s1 = QCC_PR_ParseImmediate ();
|
||||
|
@ -9920,6 +9965,8 @@ void QCC_PR_ParseState (void)
|
|||
QCC_PR_ParseWarning(WARN_UNEXPECTEDPUNCT, "missing comma in state definition");
|
||||
|
||||
pr_assumetermtype = type_function;
|
||||
pr_assumetermscope = pr_scope->parentscope;
|
||||
pr_assumetermflags = GDF_CONST | (pr_assumetermscope?GDF_STATIC:0);
|
||||
def = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||
if (typecmp(def.cast, type_function))
|
||||
{
|
||||
|
@ -10863,6 +10910,7 @@ QCC_function_t *QCC_PR_GenerateQCFunction (QCC_def_t *def, QCC_type_t *type)
|
|||
func->firstlocal = NULL;
|
||||
func->def = def;
|
||||
func->type = type;
|
||||
func->parentscope = pr_scope;
|
||||
return func;
|
||||
}
|
||||
|
||||
|
@ -11816,6 +11864,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *s
|
|||
{
|
||||
if (scope)
|
||||
{
|
||||
//FIXME: should we be scanning the locals list instead, and remove the localstable?
|
||||
def = pHash_Get(&localstable, name);
|
||||
|
||||
while(def)
|
||||
|
@ -11829,23 +11878,38 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *s
|
|||
|
||||
if ( def->scope && def->scope != scope)
|
||||
{
|
||||
def = pHash_GetNext(&localstable, name, def);
|
||||
continue; // in a different function
|
||||
struct QCC_function_s *pscope = NULL;
|
||||
if (def->isstatic)
|
||||
{
|
||||
for (pscope = scope->parentscope; pscope; pscope = pscope->parentscope)
|
||||
if (def->scope == pscope)
|
||||
break;
|
||||
}
|
||||
if (!pscope)
|
||||
{
|
||||
def = pHash_GetNext(&localstable, name, def);
|
||||
continue; // in a different function
|
||||
}
|
||||
}
|
||||
|
||||
if (type && typecmp(def->type, type))
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type, typebuf1, sizeof(typebuf1)), TypeName(def->type, typebuf2, sizeof(typebuf2)));
|
||||
if (def->arraysize != arraysize && arraysize>=0)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
|
||||
if (allocate && scope)
|
||||
if (allocate && scope && !(flags & GDF_STATIC))
|
||||
{
|
||||
if (allocate == 2)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Duplicate definition of %s.", name);
|
||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
||||
if (def->isstatic)
|
||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "nonstatic redeclaration of %s ignored", name);
|
||||
else
|
||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
||||
QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
|
||||
// if (!scope)
|
||||
// QCC_PR_ParsePrintDef(def);
|
||||
}
|
||||
else if (allocate && (flags & GDF_STATIC) && !def->isstatic)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "static redefinition of %s follows non-static definition.", name);
|
||||
|
||||
QCC_ForceUnFreeDef(def);
|
||||
return def;
|
||||
|
@ -11919,7 +11983,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *s
|
|||
}
|
||||
if (def->arraysize != arraysize && arraysize>=0)
|
||||
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
|
||||
if (allocate && scope)
|
||||
if (allocate && scope && !(flags & GDF_STATIC))
|
||||
{
|
||||
if (allocate == 2)
|
||||
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Duplicate definition of %s.", name);
|
||||
|
@ -11929,7 +11993,10 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *s
|
|||
continue; // in a different function
|
||||
}
|
||||
|
||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
||||
if (def->isstatic)
|
||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "nonstatic redeclaration of %s ignored", name);
|
||||
else
|
||||
QCC_PR_ParseWarning (WARN_DUPLICATEDEFINITION, "%s duplicate definition ignored", name);
|
||||
QCC_PR_ParsePrintDef(WARN_DUPLICATEDEFINITION, def);
|
||||
// if (!scope)
|
||||
// QCC_PR_ParsePrintDef(def);
|
||||
|
@ -13060,17 +13127,21 @@ void QCC_PR_ParseDefs (char *classname)
|
|||
else if (forceused) //FIXME: make proper pragma(used) thingie
|
||||
gd_flags |= GDF_USED;
|
||||
|
||||
#if IAMNOTLAZY
|
||||
if (dynlength.cast)
|
||||
{
|
||||
#if 1//IAMNOTLAZY
|
||||
def = QCC_PR_GetDef (QCC_PR_PointerType(type), name, pr_scope, allocatenew, 0, gd_flags);
|
||||
dynlength = QCC_SupplyConversion(dynlength, ev_integer, true);
|
||||
if (type->size != 1)
|
||||
dynlength = QCC_PR_Statement(pr_opcodes+OP_MUL_I, dynlength, QCC_MakeIntConst(type->size), NULL);
|
||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_PUSH], dynlength, nullsref, def, false); //push *(int*)&a elements
|
||||
QCC_PR_SimpleStatement(&pr_opcodes[OP_PUSH], dynlength, nullsref, QCC_MakeSRef(def, 0, def->type), false); //push *(int*)&a elements
|
||||
QCC_FreeTemp(dynlength);
|
||||
QCC_FreeDef(def);
|
||||
#else
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "%s is dynamically sized", name);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
#endif
|
||||
def = QCC_PR_GetDef (type, name, pr_scope, allocatenew, arraysize, gd_flags);
|
||||
|
||||
if (!def)
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#define EMBEDDEBUG
|
||||
|
||||
#define IDI_ICON_FTEQCC MAKEINTRESOURCE(101)
|
||||
|
||||
void AddSourceFile(const char *parentsrc, const char *filename);
|
||||
void GUI_ParseCommandLine(char *args);
|
||||
void GUI_RevealOptions(void);
|
||||
|
@ -2145,7 +2147,7 @@ void EditFile(char *name, int line, pbool setcontrol)
|
|||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.hIcon = 0;
|
||||
wndclass.hIcon = LoadIcon(ghInstance, IDI_ICON_FTEQCC);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wndclass.lpszMenuName = 0;
|
||||
|
@ -3429,7 +3431,7 @@ void OptionsDialog(void)
|
|||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.hIcon = 0;
|
||||
wndclass.hIcon = LoadIcon(ghInstance, IDI_ICON_FTEQCC);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wndclass.lpszMenuName = 0;
|
||||
|
@ -4719,7 +4721,7 @@ void CreateOutputWindow(pbool doannoates)
|
|||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.hIcon = 0;
|
||||
wndclass.hIcon = LoadIcon(ghInstance, IDI_ICON_FTEQCC);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wndclass.lpszMenuName = 0;
|
||||
|
@ -5076,7 +5078,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.hIcon = 0;
|
||||
wndclass.hIcon = LoadIcon(ghInstance, IDI_ICON_FTEQCC);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wndclass.lpszMenuName = 0;
|
||||
|
|
|
@ -34,6 +34,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define PF_sqlescape PF_Fixme
|
||||
#define PF_sqlversion PF_Fixme
|
||||
#define PF_sqlreadfloat PF_Fixme
|
||||
#define PF_sqlreadblob PF_Fixme
|
||||
#define PF_sqlescapeblob PF_Fixme
|
||||
#endif
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
|
@ -3752,14 +3754,18 @@ void QCBUILTIN PF_sv_particleeffectnum(pubprogfuncs_t *prinst, struct globalvars
|
|||
*/
|
||||
int i;
|
||||
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
|
||||
if (s[0] <= ' ')
|
||||
{
|
||||
PR_BIError (prinst, "PF_precache_particles: Bad string");
|
||||
/*if (!ssqc_deprecated_warned)
|
||||
{
|
||||
PR_RunWarning(prinst, "PF_precache_particles: Bad string");
|
||||
ssqc_deprecated_warned = true;
|
||||
}*/
|
||||
return;
|
||||
}
|
||||
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
|
||||
for (i=1 ; i<MAX_SSPARTICLESPRE ; i++)
|
||||
{
|
||||
if (!*sv.strings.particle_precache[i])
|
||||
|
@ -3769,14 +3775,16 @@ void QCBUILTIN PF_sv_particleeffectnum(pubprogfuncs_t *prinst, struct globalvars
|
|||
if (sv.state != ss_loading)
|
||||
{
|
||||
Con_DPrintf("Delayed particle precache: %s\n", s);
|
||||
MSG_WriteByte(&sv.reliable_datagram, svcfte_precache);
|
||||
MSG_WriteShort(&sv.reliable_datagram, i|PC_PARTICLE);
|
||||
MSG_WriteString(&sv.reliable_datagram, s);
|
||||
MSG_WriteByte(&sv.multicast, svcfte_precache);
|
||||
MSG_WriteShort(&sv.multicast, i|PC_PARTICLE);
|
||||
MSG_WriteString(&sv.multicast, s);
|
||||
#ifdef NQPROT
|
||||
MSG_WriteByte(&sv.nqreliable_datagram, svcdp_precache);
|
||||
MSG_WriteShort(&sv.nqreliable_datagram, i|PC_PARTICLE);
|
||||
MSG_WriteString(&sv.nqreliable_datagram, s);
|
||||
MSG_WriteByte(&sv.nqmulticast, svcdp_precache);
|
||||
MSG_WriteShort(&sv.nqmulticast, i|PC_PARTICLE);
|
||||
MSG_WriteString(&sv.nqmulticast, s);
|
||||
#endif
|
||||
|
||||
SV_MulticastProtExt(vec3_origin, MULTICAST_ALL_R, pr_global_struct->dimension_send, PEXT_CSQC, 0);
|
||||
}
|
||||
}
|
||||
if (!strcmp(sv.strings.particle_precache[i], s))
|
||||
|
@ -5869,6 +5877,83 @@ void QCBUILTIN PF_sqlreadfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
G_FLOAT(OFS_RETURN) = 0;
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_sqlreadblob (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
sqlserver_t *server;
|
||||
queryresult_t *qres;
|
||||
char *data;
|
||||
|
||||
int serveridx = G_FLOAT(OFS_PARM0);
|
||||
int queryidx = G_FLOAT(OFS_PARM1);
|
||||
int row = G_FLOAT(OFS_PARM2);
|
||||
int column = G_FLOAT(OFS_PARM3);
|
||||
int dst = G_INT(OFS_PARM4);
|
||||
int dstsize = G_INT(OFS_PARM5);
|
||||
|
||||
if (dst <= 0 || dst+dstsize >= prinst->stringtablesize)
|
||||
{ //FIXME: this check should be some utility function.
|
||||
PR_BIError(prinst, "PF_sqlreadblob: invalid dest\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SQL_Available())
|
||||
{
|
||||
server = SQL_GetServer(serveridx, false);
|
||||
if (server)
|
||||
{
|
||||
qres = SQL_GetQueryResult(server, queryidx, row);
|
||||
if (qres)
|
||||
{
|
||||
size_t blobsize;
|
||||
data = SQL_ReadField(server, qres, row, column, true, &blobsize);
|
||||
if (data)
|
||||
{ //unsure how to handle overflows. we truncate for now.
|
||||
blobsize = min(blobsize, dstsize);
|
||||
G_INT(OFS_RETURN) = blobsize;
|
||||
memcpy(prinst->stringtable + dst, data, blobsize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("Invalid sql request/row\n");
|
||||
PR_StackTrace(prinst, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// else we failed to get anything
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
}
|
||||
void QCBUILTIN PF_sqlescapeblob (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
char hex[16] = "0123456789abcdef";
|
||||
// int serveridx = G_FLOAT(OFS_PARM0); //fixme
|
||||
int qcptr = G_INT(OFS_PARM1);
|
||||
int size = G_INT(OFS_PARM2);
|
||||
char *out;
|
||||
|
||||
qbyte *blob = prinst->stringtable + qcptr;
|
||||
|
||||
if (qcptr <= 0 || qcptr+size >= prinst->stringtablesize)
|
||||
{ //FIXME: this check should be some utility function.
|
||||
PR_BIError(prinst, "PF_sqlescapeblob: invalid blob\n");
|
||||
return;
|
||||
}
|
||||
|
||||
G_INT(OFS_RETURN) = prinst->AllocTempString(prinst, &out, size*2+4);
|
||||
|
||||
//"x'DEADBEEF'"
|
||||
*out++ = 'x';
|
||||
*out++ = '\'';
|
||||
for (; size > 0; size--, blob++)
|
||||
{
|
||||
*out++ = hex[*blob>>4];
|
||||
*out++ = hex[*blob&15];
|
||||
}
|
||||
*out++ = '\'';
|
||||
*out++ = 0;
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_sqlerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
sqlserver_t *server;
|
||||
|
@ -7806,6 +7891,16 @@ void QCBUILTIN PF_sv_trailparticles(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
ednum = G_EDICTNUM(prinst, OFS_PARM1);
|
||||
}
|
||||
|
||||
if (efnum <= 0)
|
||||
{
|
||||
// if (!ssqc_deprecated_warned)
|
||||
// {
|
||||
// PR_RunWarning(prinst, "PF_sv_trailparticles: invalid effect");
|
||||
// ssqc_deprecated_warned = true;
|
||||
// }
|
||||
return;
|
||||
}
|
||||
|
||||
MSG_WriteByte(&sv.multicast, svcfte_trailparticles);
|
||||
MSG_WriteEntity(&sv.multicast, ednum);
|
||||
MSG_WriteShort(&sv.multicast, efnum);
|
||||
|
@ -7840,6 +7935,16 @@ void QCBUILTIN PF_sv_pointparticles(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
float *vel = (prinst->callargc < 3)?vec3_origin:G_VECTOR(OFS_PARM2);
|
||||
int count = (prinst->callargc < 4)?1:G_FLOAT(OFS_PARM3);
|
||||
|
||||
if (efnum <= 0)
|
||||
{
|
||||
// if (!ssqc_deprecated_warned)
|
||||
// {
|
||||
// PR_RunWarning(prinst, "PF_sv_pointparticles: invalid effect");
|
||||
// ssqc_deprecated_warned = true;
|
||||
// }
|
||||
return;
|
||||
}
|
||||
|
||||
if (count > 65535)
|
||||
count = 65535;
|
||||
|
||||
|
@ -8648,10 +8753,10 @@ static void ParamNegateFix ( float * xx, float * yy, int Zone )
|
|||
static void QCBUILTIN PF_ShowPic(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
const char *slot = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
const char *picname = PR_GetStringOfs(prinst, OFS_PARM1);
|
||||
float x = G_FLOAT(OFS_PARM2);
|
||||
float y = G_FLOAT(OFS_PARM3);
|
||||
float zone = G_FLOAT(OFS_PARM4);
|
||||
const char *picname = PR_GetStringOfs(prinst, OFS_PARM1);
|
||||
float x = G_FLOAT(OFS_PARM2);
|
||||
float y = G_FLOAT(OFS_PARM3);
|
||||
unsigned int zone = G_FLOAT(OFS_PARM4);
|
||||
int entnum;
|
||||
|
||||
client_t *cl;
|
||||
|
@ -9090,9 +9195,18 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
|
|||
if (delta[0] || delta[1] || delta[2])
|
||||
{
|
||||
//eular angle changes suck
|
||||
client_t *cl = ClientReliableWrite_BeginSplit(client, svcfte_setangledelta, 7);
|
||||
for (i=0 ; i < 3 ; i++)
|
||||
ClientReliableWrite_Angle16 (cl, delta[i]);
|
||||
if (client->fteprotocolextensions2 & PEXT2_SETANGLEDELTA)
|
||||
{
|
||||
client_t *cl = ClientReliableWrite_BeginSplit(client, svcfte_setangledelta, 7);
|
||||
for (i=0 ; i < 3 ; i++)
|
||||
ClientReliableWrite_Angle16 (cl, delta[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
client_t *cl = ClientReliableWrite_BeginSplit(client, svc_setangle, 7);
|
||||
for (i=0 ; i < 3 ; i++)
|
||||
ClientReliableWrite_Angle (cl, sv_player->v->v_angle[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9729,6 +9843,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"sqlescape", PF_sqlescape, 0, 0, 0, 256, "string(float serveridx, string data)"}, // sqlescape (FTE_SQL)
|
||||
{"sqlversion", PF_sqlversion, 0, 0, 0, 257, "string(float serveridx)"}, // sqlversion (FTE_SQL)
|
||||
{"sqlreadfloat", PF_sqlreadfloat, 0, 0, 0, 258, "float(float serveridx, float queryidx, float row, float column)"}, // sqlreadfloat (FTE_SQL)
|
||||
{"sqlreadblob", PF_sqlreadblob, 0, 0, 0, 0, "int(float serveridx, float queryidx, float row, float column, _variant *ptr, int maxsize)"},
|
||||
{"sqlescapeblob", PF_sqlescapeblob, 0, 0, 0, 0, "string(float serveridx, _variant *ptr, int maxsize)"},
|
||||
|
||||
{"stoi", PF_stoi, 0, 0, 0, 259, D("int(string)", "Converts the given string into a true integer. Base 8, 10, or 16 is determined based upon the format of the string.")},
|
||||
{"itos", PF_itos, 0, 0, 0, 260, D("string(int)", "Converts the passed true integer into a base10 string.")},
|
||||
|
@ -11017,10 +11133,10 @@ void PR_DumpPlatform_f(void)
|
|||
{"CHAN_BODY", "const float", QW|NQ|CS, NULL, CHAN_BODY},
|
||||
{"CHANF_RELIABLE", "const float", QW, NULL, 8},
|
||||
|
||||
{"SOUNDFLAG_RELIABLE", "const float", QW|NQ, NULL, CF_RELIABLE},
|
||||
{"SOUNDFLAG_ABSVOLUME", "const float", /*QW|NQ|*/CS,NULL, CF_ABSVOLUME},
|
||||
{"SOUNDFLAG_FORCELOOP", "const float", /*QW|NQ|*/CS,NULL, CF_FORCELOOP},
|
||||
{"SOUNDFLAG_NOSPACIALISE", "const float", /*QW|NQ|*/CS,NULL, CF_NOSPACIALISE},
|
||||
{"SOUNDFLAG_RELIABLE", "const float", QW|NQ, "The sound will be sent reliably, and without regard to phs.", CF_RELIABLE},
|
||||
{"SOUNDFLAG_ABSVOLUME", "const float", /*QW|NQ|*/CS,"The sample's volume is not scaled by the volume cvar. Use with caution", CF_ABSVOLUME},
|
||||
{"SOUNDFLAG_FORCELOOP", "const float", /*QW|NQ|*/CS,"The sound will restart once it reaches the end of the sample.", CF_FORCELOOP},
|
||||
{"SOUNDFLAG_NOSPACIALISE", "const float", /*QW|NQ|*/CS,"The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation.", CF_NOSPACIALISE},
|
||||
|
||||
{"ATTN_NONE", "const float", QW|NQ|CS, "Sounds with this attenuation can be heard throughout the map", ATTN_NONE},
|
||||
{"ATTN_NORM", "const float", QW|NQ|CS, "Standard attenuation", ATTN_NORM},
|
||||
|
@ -11103,11 +11219,11 @@ void PR_DumpPlatform_f(void)
|
|||
{"STUFFCMD_IGNOREINDEMO","const float", QW|NQ, "The protocol we are connected to the server with.", STUFFCMD_IGNOREINDEMO},
|
||||
{"STUFFCMD_DEMOONLY", "const float", QW|NQ, "The protocol we are connected to the server with.", STUFFCMD_DEMOONLY},
|
||||
|
||||
{"SOUND_RELIABLE", "const float", QW|NQ, "The sound will be sent reliably, and without regard to phs.", CF_RELIABLE},
|
||||
/* {"SOUND_RELIABLE", "const float", QW|NQ, "The sound will be sent reliably, and without regard to phs.", CF_RELIABLE},
|
||||
{"SOUND_FORCELOOP", "const float", QW|NQ|CS,"The sound will restart once it reaches the end of the sample.", CF_FORCELOOP},
|
||||
{"SOUND_NOSPACIALISE", "const float", QW|NQ|CS,"The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation.", CF_NOSPACIALISE},
|
||||
{"SOUND_ABSVOLUME", "const float", QW|NQ|CS,"The sample's volume is not scaled by the volume cvar. Use with caution", CF_ABSVOLUME},
|
||||
|
||||
*/
|
||||
// edict.flags
|
||||
{"FL_FLY", "const float", QW|NQ|CS, NULL, FL_FLY},
|
||||
{"FL_SWIM", "const float", QW|NQ|CS, NULL, FL_SWIM},
|
||||
|
@ -11171,6 +11287,17 @@ void PR_DumpPlatform_f(void)
|
|||
{"MF_TRACER2", "const float", QW|NQ|CS, NULL, EF_MF_TRACER2>>24},
|
||||
{"MF_TRACER3", "const float", QW|NQ|CS, NULL, EF_MF_TRACER3>>24},
|
||||
|
||||
|
||||
{"SL_ORG_TL", "const float", QW|NQ, NULL, SL_ORG_TL},
|
||||
{"SL_ORG_TR", "const float", QW|NQ, NULL, SL_ORG_TR},
|
||||
{"SL_ORG_BL", "const float", QW|NQ, NULL, SL_ORG_BL},
|
||||
{"SL_ORG_BR", "const float", QW|NQ, NULL, SL_ORG_BR},
|
||||
{"SL_ORG_MM", "const float", QW|NQ, NULL, SL_ORG_MM},
|
||||
{"SL_ORG_TM", "const float", QW|NQ, NULL, SL_ORG_TM},
|
||||
{"SL_ORG_BM", "const float", QW|NQ, NULL, SL_ORG_BM},
|
||||
{"SL_ORG_ML", "const float", QW|NQ, NULL, SL_ORG_ML},
|
||||
{"SL_ORG_MR", "const float", QW|NQ, NULL, SL_ORG_MR},
|
||||
|
||||
{"PFLAGS_NOSHADOW", "const float", QW|NQ|CS, "Associated RT lights attached will not cast shadows, making them significantly faster to draw.", PFLAGS_NOSHADOW},
|
||||
{"PFLAGS_CORONA", "const float", QW|NQ|CS, "Enables support of coronas on the associated rtlights.", PFLAGS_CORONA},
|
||||
{"PFLAGS_FULLDYNAMIC", "const float", QW|NQ, "When set in self.pflags, enables fully-customised dynamic lights. Custom rtlight information is not otherwise used.", PFLAGS_FULLDYNAMIC},
|
||||
|
|
|
@ -540,6 +540,7 @@ void SV_Map_f (void)
|
|||
if (strlen(level) > 4 &&
|
||||
(!strcmp(level + strlen(level)-4, ".cin") ||
|
||||
!strcmp(level + strlen(level)-4, ".roq") ||
|
||||
!strcmp(level + strlen(level)-4, ".pcx") ||
|
||||
!strcmp(level + strlen(level)-4, ".avi")))
|
||||
{
|
||||
cinematic = true;
|
||||
|
@ -2590,7 +2591,7 @@ static void SV_SendGameCommand_f(void)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
Con_Printf("This command requires a Q2 sever\n");
|
||||
Con_Printf("Mod-specific command not known\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2705,10 +2705,10 @@ int glowsize=0, glowcolor=0, colourmod=0;
|
|||
else
|
||||
MSG_WriteByte (msg,ent->number);
|
||||
|
||||
if (bits & NQU_MODEL) MSG_WriteByte (msg, ent->modelindex);
|
||||
if (bits & NQU_FRAME) MSG_WriteByte (msg, ent->frame);
|
||||
if (bits & NQU_COLORMAP) MSG_WriteByte (msg, ent->colormap);
|
||||
if (bits & NQU_SKIN) MSG_WriteByte (msg, ent->skinnum);
|
||||
if (bits & NQU_MODEL) MSG_WriteByte (msg, ent->modelindex & 0xff);
|
||||
if (bits & NQU_FRAME) MSG_WriteByte (msg, ent->frame & 0xff);
|
||||
if (bits & NQU_COLORMAP) MSG_WriteByte (msg, ent->colormap & 0xff);
|
||||
if (bits & NQU_SKIN) MSG_WriteByte (msg, ent->skinnum & 0xff);
|
||||
if (bits & NQU_EFFECTS) MSG_WriteByte (msg, eff & 0x00ff);
|
||||
if (bits & NQU_ORIGIN1) MSG_WriteCoord (msg, ent->origin[0]);
|
||||
if (bits & NQU_ANGLE1) MSG_WriteAngle(msg, ent->angles[0]);
|
||||
|
@ -2723,18 +2723,18 @@ int glowsize=0, glowcolor=0, colourmod=0;
|
|||
if (bits & RMQU_SCALE) MSG_WriteByte(msg, ent->scale);
|
||||
if (bits & FITZU_FRAME2) MSG_WriteByte(msg, ent->frame>>8);
|
||||
if (bits & FITZU_MODEL2) MSG_WriteByte(msg, ent->modelindex>>8);
|
||||
if (bits & FITZU_LERPFINISH)MSG_WriteByte(msg, (ed->v->nextthink - sv.world.physicstime) * 255);
|
||||
if (bits & FITZU_LERPFINISH)MSG_WriteByte(msg, bound(0, (int)((ed->v->nextthink - sv.world.physicstime) * 255), 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bits & DPU_ALPHA) MSG_WriteByte(msg, ent->trans*255);
|
||||
if (bits & DPU_SCALE) MSG_WriteByte(msg, ent->scale*16);
|
||||
if (bits & DPU_ALPHA) MSG_WriteByte(msg, ent->trans);
|
||||
if (bits & DPU_SCALE) MSG_WriteByte(msg, ent->scale);
|
||||
if (bits & DPU_EFFECTS2) MSG_WriteByte(msg, eff >> 8);
|
||||
if (bits & DPU_GLOWSIZE) MSG_WriteByte(msg, glowsize);
|
||||
if (bits & DPU_GLOWCOLOR) MSG_WriteByte(msg, glowcolor);
|
||||
if (bits & DPU_COLORMOD) MSG_WriteByte(msg, colourmod);
|
||||
if (bits & DPU_FRAME2) MSG_WriteByte(msg, (int)ent->frame >> 8);
|
||||
if (bits & DPU_MODEL2) MSG_WriteByte(msg, (int)ent->modelindex >> 8);
|
||||
if (bits & DPU_FRAME2) MSG_WriteByte(msg, ent->frame >> 8);
|
||||
if (bits & DPU_MODEL2) MSG_WriteByte(msg, ent->modelindex >> 8);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5290,7 +5290,10 @@ void SV_Init (quakeparms_t *parms)
|
|||
#endif
|
||||
|
||||
if (sv.state == ss_dead)
|
||||
SV_Error ("Couldn't load a map");
|
||||
{
|
||||
Cmd_ExecuteString("path", RESTRICT_LOCAL);
|
||||
SV_Error ("Couldn't load a map. You may need to use the -basedir argument.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,10 @@ void Sys_Error (const char *error, ...)
|
|||
|
||||
tcsetattr(STDIN_FILENO, TCSADRAIN, &orig);
|
||||
|
||||
*(int*)-3 = 0;
|
||||
//we used to fire sigsegv. this resulted in people reporting segfaults and not the error message that appeared above. resulting in wasted debugging.
|
||||
//abort should trigger a SIGABRT and still give us the same stack trace. should be more useful that way.
|
||||
abort();
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
@ -616,6 +619,7 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
|
|||
case SIGILL: strcpy(signame, "SIGILL"); break;
|
||||
case SIGFPE: strcpy(signame, "SIGFPE"); break;
|
||||
case SIGBUS: strcpy(signame, "SIGBUS"); break;
|
||||
case SIGABRT: strcpy(signame, "SIGABRT"); break;
|
||||
case SIGSEGV: Q_snprintfz(signame, sizeof(signame), "SIGSEGV (%p)", info->si_addr); break;
|
||||
default: Q_snprintfz(signame, sizeof(signame), "%i", sig); break;
|
||||
}
|
||||
|
@ -707,6 +711,7 @@ int main(int argc, char *argv[])
|
|||
sigaction(SIGILL, &act, NULL);
|
||||
sigaction(SIGFPE, &act, NULL);
|
||||
sigaction(SIGSEGV, &act, NULL);
|
||||
sigaction(SIGABRT, &act, NULL);
|
||||
sigaction(SIGBUS, &act, NULL);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -81,10 +81,10 @@ cvar_t sv_floodprotect_suicide = CVAR("sv_floodprotect_suicide", "1");
|
|||
cvar_t sv_floodprotect_sendmessage = CVARAF("sv_floodprotect_sendmessage", "",
|
||||
"floodprotmsg", 0);
|
||||
|
||||
cvar_t votelevel = SCVAR("votelevel", "0");
|
||||
cvar_t voteminimum = SCVAR("voteminimum", "4");
|
||||
cvar_t votepercent = SCVAR("votepercent", "-1");
|
||||
cvar_t votetime = SCVAR("votetime", "10");
|
||||
cvar_t votelevel = CVARD("votelevel", "0", "This is the restriction level of commands that players may vote for. You can reconfigure commands, cvars, or aliases individually. Additionally, aliases can be configured via aliaslevel to be executed at a different level from their restriction level. This can be used to indirectly allow voting for 'map dm4' for instance, without allowing people to vote for every map.");
|
||||
cvar_t voteminimum = CVARD("voteminimum", "4", "At least this many players must vote the same way for the vote to pass.");
|
||||
cvar_t votepercent = CVARD("votepercent", "-1", "At least this percentage of players must vote the same way for the vote to pass.");
|
||||
cvar_t votetime = CVARD("votetime", "10", "Votes will be discarded after this many minutes");
|
||||
|
||||
cvar_t pr_allowbutton1 = CVARFD("pr_allowbutton1", "1", CVAR_LATCH, "The button1 field is believed to have been intended to work with the +use command, but it was never hooked up. In NetQuake, this field was often repurposed for other things as it was not otherwise used (and cannot be removed without breaking the crc), while third-party QuakeWorld engines did decide to implement it as believed was intended. As a result, this cvar only applies to QuakeWorld mods and a value of 1 is only likely to cause issues with NQ mods that were ported to QW.");
|
||||
extern cvar_t sv_minping;
|
||||
|
@ -445,13 +445,15 @@ void SV_New_f (void)
|
|||
void SVNQ_New_f (void)
|
||||
{
|
||||
extern cvar_t coop;
|
||||
char message[2048];
|
||||
int i;
|
||||
int maxplayers = 0;
|
||||
int op;
|
||||
char message[2048];
|
||||
char build[256], mapname[128];
|
||||
int i;
|
||||
int maxplayers = 0;
|
||||
int op;
|
||||
unsigned int protext1 = 0, protext2 = 0, protmain = 0, protfl = 0;
|
||||
char *protoname;
|
||||
extern cvar_t sv_listen_nq;
|
||||
const char *gamedir;
|
||||
|
||||
host_client->prespawn_stage = PRESPAWN_INVALID;
|
||||
host_client->prespawn_idx = 0;
|
||||
|
@ -554,8 +556,28 @@ void SVNQ_New_f (void)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef OFFICIAL_RELEASE
|
||||
Q_snprintfz(build, sizeof(build), "v%i.%02i", FTE_VER_MAJOR, FTE_VER_MINOR);
|
||||
#else
|
||||
#if defined(SVNREVISION)
|
||||
if (strcmp(STRINGIFY(SVNREVISION), "-"))
|
||||
Q_snprintfz(build, sizeof(build), "SVN %s", STRINGIFY(SVNREVISION));
|
||||
else
|
||||
#endif
|
||||
Q_snprintfz(build, sizeof(build), "%s", __DATE__);
|
||||
#endif
|
||||
|
||||
gamedir = Info_ValueForKey (svs.info, "*gamedir");
|
||||
if (!gamedir[0])
|
||||
{
|
||||
gamedir = FS_GetGamedir(true);
|
||||
}
|
||||
COM_FileBase(sv.modelname, mapname, sizeof(mapname));
|
||||
|
||||
Q_snprintfz (message, sizeof(message), "%c\n%s - "DISTRIBUTION" (%s%s%s%s %s) - %s", 2, gamedir,
|
||||
protoname,(protext1||(protext2&~(PEXT2_REPLACEMENTDELTAS|PEXT2_VOICECHAT)))?"+":"",(protext2&PEXT2_REPLACEMENTDELTAS)?"F":"",(protext2&PEXT2_VOICECHAT)?"V":"",
|
||||
build, mapname);
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_print);
|
||||
Q_snprintfz (message, sizeof(message), "%c\n%s %s%s%s%s server\n", 2, version_string(), (protext2&PEXT2_REPLACEMENTDELTAS)?"FTE":"", protoname, (protext1||(protext2&~(PEXT2_REPLACEMENTDELTAS|PEXT2_VOICECHAT)))?"+":"", (protext2&PEXT2_VOICECHAT)?"V":"");
|
||||
MSG_WriteString (&host_client->netchan.message,message);
|
||||
|
||||
if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7)
|
||||
|
@ -4145,12 +4167,23 @@ void SV_Vote_f (void)
|
|||
|
||||
if (!votelevel.value || ((host_client->penalties & (BAN_MUTE|BAN_DEAF)) == (BAN_MUTE|BAN_DEAF)))
|
||||
{
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "Voting was dissallowed\n");
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "Voting is dissallowed on this server\n");
|
||||
return;
|
||||
}
|
||||
if (!*command)
|
||||
{
|
||||
char cmds[900];
|
||||
Cmd_EnumerateLevel(votelevel.value, cmds, sizeof(cmds));
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "Allowed commands:\n%s\n", cmds);
|
||||
return;
|
||||
}
|
||||
if (host_client->penalties & BAN_MUTE)
|
||||
{
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "Sorry, you cannot vote when muted as it may allow you to send a message.\n");
|
||||
//pretend to vote for it
|
||||
if (host_client->penalties & BAN_STEALTH)
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "%s casts a vote for '%s'\n", host_client->name, command);
|
||||
else
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "Sorry, you cannot vote when muted as it may allow you to send a message.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5591,7 +5624,7 @@ ucmd_t ucmdsq2[] = {
|
|||
|
||||
{"nextserver", SVQ2_NextServer_f, true},
|
||||
|
||||
{"vote", SV_Vote_f, true},
|
||||
{"ftevote", SV_Vote_f, true},
|
||||
|
||||
//#ifdef SVRANKING
|
||||
// {"topten", Rank_ListTop10_f, true},
|
||||
|
@ -6930,10 +6963,18 @@ done:
|
|||
args[i] = 0;
|
||||
rname = MSG_ReadString();
|
||||
if (i)
|
||||
rname = va("Cmd_%s_%s", rname, args);
|
||||
rname = va("CSEv_%s_%s", rname, args);
|
||||
else
|
||||
rname = va("Cmd_%s", rname);
|
||||
rname = va("CSEv_%s", rname);
|
||||
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
||||
if (!f)
|
||||
{
|
||||
if (i)
|
||||
rname = va("Cmd_%s_%s", rname, args);
|
||||
else
|
||||
rname = va("Cmd_%s", rname);
|
||||
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
||||
}
|
||||
if (f)
|
||||
{
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
|
||||
|
|
|
@ -75,7 +75,6 @@ void HUD_Plus_f(void)
|
|||
{
|
||||
char *t;
|
||||
hud_t *hud;
|
||||
char buf[64];
|
||||
|
||||
if (Cmd_Argc() < 1)
|
||||
return;
|
||||
|
|
|
@ -436,7 +436,9 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(GetPlayerInfo);
|
||||
CHECKBUILTIN(LocalPlayerNumber);
|
||||
CHECKBUILTIN(GetLocalPlayerNumbers);
|
||||
#ifdef FTEPLUGIN
|
||||
CHECKBUILTIN(GetLastInputFrame);
|
||||
#endif
|
||||
CHECKBUILTIN(GetTrackerOwnFrags);
|
||||
CHECKBUILTIN(GetServerInfo);
|
||||
CHECKBUILTIN(SetUserInfo);
|
||||
|
|
Loading…
Reference in a new issue