------------------------------------------------------------------------

r4175 | acceptthis | 2013-01-26 18:23:37 +0000 (Sat, 26 Jan 2013) | 8 lines

improved replacementdeltas+nq a little, still needs work.
embrace the menuqc! pr_dumpplatform now includes MENU defs+builtins.
swapped search ordering of paks+dirs, so progs.dat will be used instead of pak0.pak/progs.dat.
fteqcc slightly more sensible with if statements and void+vector types.
fteqcc shows the first line where models are precached/used instead of showing no line at all.
fix missing explosions when running qw gamecode.
accept channels between 8 and 255. 
support for sending fitzquake's increased stat limits.
------------------------------------------------------------------------


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4173 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-03-12 22:35:33 +00:00
parent 9e2969390d
commit a339c727d0
55 changed files with 2152 additions and 1541 deletions

View file

@ -419,6 +419,7 @@ CLIENT_OBJS = \
cl_tent.o \
cl_cam.o \
cl_screen.o \
pr_clcmd.o \
cl_ui.o \
cl_ignore.o \
cl_cg.o \
@ -810,7 +811,7 @@ ifeq ($(FTE_TARGET),vc)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(SPEEX_OBJS) snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_win_threads.o $(D3DGL_OBJS) fs_win32.o $(LTO_END) resources.o $(LTO_START)
D3D_EXE_NAME=../fted3dqw$(BITS).exe
D3DCL_EXE_NAME=../fted3dclqw$(BITS).exe
D3D_LDFLAGS=$(JPEGLIB) libs/libpng$(BITS).lib uuid.lib gdi32.lib ole32.lib
D3D_LDFLAGS=$(JPEGLIB) libs/libpng$(BITS).lib uuid.lib gdi32.lib ole32.lib /subsystem:windows
D3D_CFLAGS=$(D3DCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD $(SPEEXCFLAGS) -DMSVCLIBSPATH="libs/"
D3DB_DIR=d3d_vc$(BITS)
D3DCL_DIR=d3dcl_vc$(BITS)
@ -1062,6 +1063,8 @@ endif
SV_DIR?=sv_sdl
-include Makefile_private
.default: help
all: rel
rel: sv-rel gl-rel mingl-rel

View file

@ -496,7 +496,7 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
bits |= MSG_ReadByte()<<24;
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Update %4i 0x%x\n", msg_readcount, entnum, bits);
Con_Printf("%3i: Update %4i 0x%x\n", msg_readcount, entnum, bits);
if (bits & UF_RESET)
{
@ -506,7 +506,7 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
else if (!olds)
{
/*reset got lost, probably the data will be filled in later - FIXME: we should probably ignore this entity*/
Con_DPrintf("New entity without reset\n");
Con_DPrintf("New entity %i without reset\n", entnum);
*news = nullentitystate;
// *news = *baseline;
}
@ -639,10 +639,18 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->trans = MSG_ReadByte();
if (bits & UF_SCALE)
news->scale = MSG_ReadByte();
if (bits & UF_ABSLIGHT)
news->abslight = MSG_ReadByte();
if (bits & UF_UNUSED3)
{
// news->abslight = MSG_ReadByte();
}
if (bits & UF_DRAWFLAGS)
{
news->hexen2flags = MSG_ReadByte();
if ((news->hexen2flags & MLS_MASKIN) == MLS_ABSLIGHT)
news->abslight = MSG_ReadByte();
else
news->abslight = 0;
}
if (bits & UF_TAGINFO)
{
news->tagentity = MSGCL_ReadEntity();
@ -718,6 +726,29 @@ void CLFTE_ParseEntities(void)
// Con_Printf("CL: Dropped %i\n", i);
// }
#ifdef NQPROT
if (cls.protocol == CP_NETQUAKE)
{
int i;
for (i = 0; i < MAX_SPLITS; i++)
cl.playerview[i].fixangle = false;
cls.netchan.outgoing_sequence = cls.netchan.incoming_unreliable;
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence;
cls.netchan.outgoing_sequence++;
cl.last_servermessage = realtime;
cl.ackedinputsequence = MSG_ReadLong();
if (cl.numackframes == sizeof(cl.ackframes)/sizeof(cl.ackframes[0]))
cl.numackframes--;
cl.ackframes[cl.numackframes++] = cls.netchan.incoming_sequence;
cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].receivedtime = realtime;
if (cl.validsequence != cls.netchan.incoming_sequence-1)
Con_Printf("CLIENT: Dropped a frame\n");
}
#endif
newpacket = cls.netchan.incoming_sequence&UPDATE_MASK;
oldpacket = cl.validsequence&UPDATE_MASK;
newp = &cl.frames[newpacket].packet_entities;
@ -725,8 +756,10 @@ void CLFTE_ParseEntities(void)
cl.frames[newpacket].invalid = true;
if (!cl.validsequence || cls.netchan.incoming_sequence-cl.validsequence >= UPDATE_BACKUP-1)
if (!cl.validsequence || cls.netchan.incoming_sequence-cl.validsequence >= UPDATE_BACKUP-1 || oldp == newp)
{
//yes, this results in a load of invalid packets for a while.
//server is meant to notice and send a reset packet, which causes it to become valid again
oldp = &nullp;
oldp->num_entities = 0;
oldp->max_entities = 0;
@ -787,14 +820,17 @@ void CLFTE_ParseEntities(void)
if (removeflag)
{
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Remove %i @ %i\n", msg_readcount, newnum, cls.netchan.incoming_sequence);
Con_Printf("%3i: Remove %i @ %i\n", msg_readcount, newnum, cls.netchan.incoming_sequence);
if (!newnum)
{
/*removal of world - means forget all entities*/
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Reset all\n", msg_readcount);
Con_Printf("%3i: Reset all\n", msg_readcount);
newp->num_entities = 0;
oldp = &nullp;
oldp->num_entities = 0;
oldp->max_entities = 0;
isvalid = true;
continue;
}
@ -1233,7 +1269,6 @@ void DP5_ParseDelta(entity_state_t *s)
}
}
int cl_latestframenum;
void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o(
{
//the incoming entities do not come in in any order. :(
@ -1252,7 +1287,9 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o(
int oldi, newi, lowesti, lowestv, newremaining;
qboolean remove;
cl_latestframenum = MSG_ReadLong(); /*server sequence to be acked*/
if (cl.numackframes == sizeof(cl.ackframes)/sizeof(cl.ackframes[0]))
cl.numackframes--;
cl.ackframes[cl.numackframes++] = MSG_ReadLong(); /*server sequence to be acked*/
if (cls.protocol_nq >= CPNQ_DP7)
cl.ackedinputsequence = MSG_ReadLong(); /*client input sequence which has been acked*/
@ -2941,6 +2978,9 @@ void CL_TransitionEntities (void)
packnew = &cl.frames[newf].packet_entities;
packold = &cl.frames[oldf].packet_entities;
// Con_Printf("%f %f %f\n", packold->servertime, servertime, packnew->servertime);
// Con_Printf("%f %f %f\n", cl.oldgametime, servertime, cl.gametime);
CL_TransitionPacketEntities(newff, packnew, packold, servertime);
cl.currentpacktime = servertime;
cl.currentpackentities = packnew;
@ -3194,8 +3234,9 @@ void CL_LinkPacketEntities (void)
}
else if (state->colormap > 0 && state->colormap <= MAX_CLIENTS)
{
ent->topcolour = cl.players[state->colormap-1].ttopcolor;
ent->bottomcolour = cl.players[state->colormap-1].tbottomcolor;
ent->playerindex = state->colormap-1;
ent->topcolour = cl.players[ent->playerindex].ttopcolor;
ent->bottomcolour = cl.players[ent->playerindex].tbottomcolor;
}
// set skin

View file

@ -997,7 +997,7 @@ void Name_Callback(struct cvar_s *var, char *oldvalue)
void CLNQ_SendCmd(sizebuf_t *buf)
{
extern int cl_latestframenum;
int i;
// if (cls.signon == 4)
{
@ -1008,11 +1008,12 @@ void CLNQ_SendCmd(sizebuf_t *buf)
CLNQ_SendMove (&independantphysics[0], 0, buf);
}
if (CPNQ_IS_DP && cls.signon == 4)
for (i = 0; i < cl.numackframes; i++)
{
MSG_WriteByte(buf, clcdp_ackframe);
MSG_WriteLong(buf, cl_latestframenum);
MSG_WriteLong(buf, cl.ackframes[i]);
}
cl.numackframes = 0;
memset(&independantphysics[0], 0, sizeof(independantphysics[0]));
}

View file

@ -59,7 +59,7 @@ cvar_t hud_tracking_show = CVAR("hud_tracking_show", "1");
cvar_t cl_defaultport = CVARAFD("cl_defaultport", STRINGIFY(PORT_QWSERVER), "port", 0, "The default port to connect to servers.\nQW: "STRINGIFY(PORT_QWSERVER)", NQ: "STRINGIFY(PORT_NQSERVER)", Q2: "STRINGIFY(PORT_Q2SERVER)".");
cvar_t cfg_save_name = CVARF("cfg_save_name", "fte", CVAR_ARCHIVE);
cvar_t cfg_save_name = CVARF("cfg_save_name", "fte", CVAR_ARCHIVE|CVAR_NOTFROMSERVER);
cvar_t cl_splitscreen = CVARD("cl_splitscreen", "0", "Enables splitscreen support. See also: allow_splitscreen, in_rawinput*, the \"p\" command.");
@ -685,6 +685,7 @@ void CL_CheckForResend (void)
{
Con_TPrintf (TLC_BADSERVERADDRESS);
connect_time = -1;
SCR_EndLoadingPlaque();
return;
}
NET_AdrToString(data, sizeof(data), adr);
@ -754,11 +755,13 @@ void CL_CheckForResend (void)
{
Con_TPrintf (TLC_BADSERVERADDRESS);
connect_time = -1;
SCR_EndLoadingPlaque();
return;
}
if (!NET_IsClientLegal(&adr))
{
Con_TPrintf (TLC_ILLEGALSERVERADDRESS);
SCR_EndLoadingPlaque();
connect_time = -1;
return;
}

View file

@ -68,7 +68,9 @@ typedef enum {
SLIST_TEST_EQUAL,
SLIST_TEST_GREATER,
SLIST_TEST_GREATEREQUAL,
SLIST_TEST_NOTEQUAL
SLIST_TEST_NOTEQUAL,
SLIST_TEST_STARTSWITH,
SLIST_TEST_NOTSTARTSWITH
} slist_test_t;

View file

@ -194,7 +194,7 @@ char *svc_nqstrings[] =
"nqsvc_damage", // [qbyte] impact [qbyte] blood [vec3] from
"nqsvc_spawnstatic",
"nqOBSOLETE svc_spawnbinary",
"nqsvcfte_spawnstatic2(21)",
"nqsvc_spawnbaseline",
"nqsvc_temp_entity", // <variable>
@ -237,7 +237,34 @@ char *svc_nqstrings[] =
"dpsvc_spawnstaticsound2", //59
"dpsvc_trailparticles", //60
"dpsvc_pointparticles", //61
"dpsvc_pointparticles1" //62
"dpsvc_pointparticles1", //62
"NEW PROTOCOL(63)",
"NEW PROTOCOL(64)",
"NEW PROTOCOL(65)",
"nqsvcfte_spawnbaseline2(66)", //66
"NEW PROTOCOL(67)",
"NEW PROTOCOL(68)",
"NEW PROTOCOL(69)",
"NEW PROTOCOL(70)",
"NEW PROTOCOL(71)",
"NEW PROTOCOL(72)",
"NEW PROTOCOL(73)",
"NEW PROTOCOL(74)",
"NEW PROTOCOL(75)",
"NEW PROTOCOL(76)",
"NEW PROTOCOL(77)",
"NEW PROTOCOL(78)",
"NEW PROTOCOL(79)",
"NEW PROTOCOL(80)",
"NEW PROTOCOL(81)",
"NEW PROTOCOL(82)",
"NEW PROTOCOL(83)",
"NEW PROTOCOL(84)",
"NEW PROTOCOL(85)",
"nqsvcfte_updateentities(86)",
"NEW PROTOCOL(87)",
"NEW PROTOCOL(88)",
};
extern cvar_t requiredownloads, cl_standardchat, msg_filter, cl_countpendingpl, cl_download_mapsrc;
@ -1865,7 +1892,8 @@ void CL_ParseDownload (void)
cls.downloadqw = NULL;
}
CL_DownloadFailed(cls.downloadremotename, true);
CL_CheckOrEnqueDownloadFile(name, localname, DLLF_IGNOREFAILED);
//FIXME: find some safe way to do this and actually test it. we should already know the local name, but we might have gained a .gz or something (this is quakeforge after all).
// CL_CheckOrEnqueDownloadFile(name, localname, DLLF_IGNOREFAILED);
return;
}
@ -2300,6 +2328,13 @@ void CLQW_ParseServerData (void)
float maxspeed, entgrav;
if (cls.downloadmethod == DL_QWPENDING)
{
//if we didn't actually start downloading it yet, cancel the current download.
//this is to avoid qizmo not responding to the download command, resulting in hanging downloads that cause the client to then be unable to connect anywhere simply because someone's skin was set.
CL_DownloadFailed(cls.downloadremotename, true);
}
Con_DPrintf ("Serverdata packet received.\n");
//
// wipe the client_state_t struct
@ -2702,7 +2737,24 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
Stats_NewMap();
Cvar_ForceCallback(Cvar_FindVar("r_particlesdesc"));
protover = MSG_ReadLong ();
cls.fteprotocolextensions = 0;
cls.fteprotocolextensions2 = 0;
for(;;)
{
protover = MSG_ReadLong ();
switch(protover)
{
case PROTOCOL_VERSION_FTE:
cls.fteprotocolextensions = MSG_ReadLong();
continue;
case PROTOCOL_VERSION_FTE2:
cls.fteprotocolextensions2 = MSG_ReadLong();
continue;
default:
break;
}
break;
}
netprim.coordsize = 2;
netprim.anglesize = 1;
@ -2779,6 +2831,13 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
{
Con_DPrintf("Standard NQ protocols\n");
}
if (cls.fteprotocolextensions & PEXT_FLOATCOORDS)
{
if (netprim.anglesize < 2)
netprim.anglesize = 2;
if (netprim.coordsize < 4)
netprim.coordsize = 4;
}
cls.netchan.message.prim = cls.netchan.netprim = netprim;
MSG_ChangePrimitives(netprim);
@ -3726,7 +3785,7 @@ void CLQW_ParseStartSoundPacket(void)
Host_EndGame ("CL_ParseStartSoundPacket: ent = %i", ent);
#ifdef PEXT_CSQC
if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation))
if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation, 100))
#endif
{
if (!sound_num)
@ -3874,7 +3933,7 @@ void CLNQ_ParseStartSoundPacket(void)
pos[i] = MSG_ReadCoord ();
#ifdef PEXT_CSQC
if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation))
if (!CSQC_StartSound(ent, channel, cl.sound_name[sound_num], pos, volume/255.0, attenuation, pitchadj))
#endif
{
if (!sound_num)
@ -4831,10 +4890,12 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
if (memessage)
{
if (!cl_standardchat.value && (plrflags & TPM_SPECTATOR))
Q_strncatz(fullchatmessage, "^m^0*^7 ", sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, "^0*^7 ", sizeof(fullchatmessage));
else
Q_strncatz(fullchatmessage, "^m* ", sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, "* ", sizeof(fullchatmessage));
}
else
Q_strncatz(fullchatmessage, "\1", sizeof(fullchatmessage));
#if defined(_WIN32) && !defined(NOMEDIA)
TTS_SayChatString(&msg);
@ -4842,15 +4903,15 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
if (plrflags & (TPM_TEAM|TPM_OBSERVEDTEAM)) // for team chat don't highlight the name, just the brackets
{
Q_strncatz(fullchatmessage, va("\1(^[%s%s^d\\player\\%i^])", name_coloured?"^m":"", name, plr-cl.players), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("(^[^7%s%s^d\\player\\%i^])", name_coloured?"^m":"", name, plr-cl.players), sizeof(fullchatmessage));
}
else if (cl_standardchat.ival)
{
Q_strncatz(fullchatmessage, va("\1^[%s%s^d\\player\\%i^]", name_coloured?"^m":"", name, plr-cl.players), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("^[^7%s%s^d\\player\\%i^]", name_coloured?"^m":"", name, plr-cl.players), sizeof(fullchatmessage));
}
else
{
Q_strncatz(fullchatmessage, va("\1^[%s^%c%s^d\\player\\%i^]", name_coloured?"^m":"", c, name, plr-cl.players), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("^[^7%s^%c%s^d\\player\\%i^]", name_coloured?"^m":"", c, name, plr-cl.players), sizeof(fullchatmessage));
}
if (!memessage)
@ -5182,7 +5243,7 @@ void CL_DumpPacket(void)
{
if (pos >= net_message.cursize)
Con_Printf("X");
else if (packet[pos] == 0 || packet[pos] == '\n')
else if (packet[pos] == 0 || packet[pos] == '\t' || packet[pos] == '\r' || packet[pos] == '\n')
Con_Printf(".");
else
Con_Printf("%c", (unsigned char)packet[pos]);
@ -5265,7 +5326,7 @@ void CLQW_ParseServerMessage (void)
{
default:
CL_DumpPacket();
Host_EndGame ("CL_ParseServerMessage: Illegible server message (%i)", cmd);
Host_EndGame ("CL_ParseServerMessage: Illegible server message (%i@%i)", cmd, msg_readcount-1);
return;
case svc_time:
@ -5475,7 +5536,7 @@ void CLQW_ParseServerMessage (void)
case svc_spawnstatic:
CL_ParseStatic (1);
break;
case svc_spawnstatic2:
case svcfte_spawnstatic2:
CL_ParseStatic (2);
break;
case svc_temp_entity:
@ -5992,7 +6053,7 @@ qboolean CLNQ_ParseNQPrints(char *s)
{
while(*s >= '0' && *s <= '9')
s++;
if (*s == ' ' && s-start >= 4)
if (*s == ' ' && s-start >= 3)
{
s++;
start = s;
@ -6041,8 +6102,6 @@ void CLNQ_ParseServerMessage (void)
// cl.last_servermessage = realtime;
CL_ClearProjectiles ();
cls.netchan.nqreliable_allowed = true;
//
// if recording demos, copy the message out
//
@ -6233,6 +6292,22 @@ void CLNQ_ParseServerMessage (void)
CL_ParseBaseline (cl_baselines + i);
break;
//PEXT_REPLACEMENTDELTAS
case svcfte_updateentities:
if (cls.signon == 4 - 1)
{ // first update is the final signon stage
cls.signon = 4;
CLNQ_SignonReply ();
}
CLFTE_ParseEntities();
break;
case svcfte_spawnstatic2:
CL_ParseStatic (2);
break;
case svcfte_spawnbaseline2:
CL_ParseBaseline2 ();
break;
case svc_time:
cl.playerview[0].oldfixangle = cl.playerview[0].fixangle;
VectorCopy(cl.playerview[0].fixangles, cl.playerview[0].oldfixangles);
@ -6240,7 +6315,7 @@ void CLNQ_ParseServerMessage (void)
cls.netchan.outgoing_sequence++;
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence-1;
cl.validsequence = cls.netchan.incoming_sequence-1;
cl.validsequence = cls.netchan.incoming_sequence;
received_framecount = host_framecount;
cl.last_servermessage = realtime;
@ -6267,8 +6342,8 @@ void CLNQ_ParseServerMessage (void)
else
{
// cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.num_entities=0;
cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.servertime = cl.gametime;
cl.frames[cl.validsequence&UPDATE_MASK].packet_entities.num_entities=0;
cl.frames[cl.validsequence&UPDATE_MASK].packet_entities.servertime = cl.gametime;
}
break;

View file

@ -1478,12 +1478,12 @@ void SCR_SetLoadingStage(int stage)
loadingfile = NULL;
break;
case LS_CONNECTION:
SCR_SetLoadingFile("connection...");
SCR_SetLoadingFile("waiting for connection...");
break;
case LS_SERVER:
if (scr_con_current > vid.height*scr_consize.value)
scr_con_current = vid.height*scr_consize.value;
SCR_SetLoadingFile("server...");
SCR_SetLoadingFile("starting server...");
break;
case LS_CLIENT:
SCR_SetLoadingFile("initial state");
@ -1571,7 +1571,10 @@ void SCR_DrawLoading (void)
y += 16;
if (loadingfile)
{
Draw_FunString(x+8, y+4, loadingfile);
y+=8;
}
}
else
{ //hexen2 files
@ -1697,8 +1700,8 @@ void SCR_EndLoadingPlaque (void)
scr_disabled_for_loading = false;
*levelshotname = '\0';
SCR_SetLoadingStage(0);
scr_drawloading = false;
loading_stage = 0;
}
void SCR_ImageName (char *mapname)

View file

@ -52,7 +52,7 @@ typedef struct
vec3_t velocity;
int weaponframe;
int modelindex;
unsigned int modelindex;
int frame;
int skinnum;
int effects;
@ -524,6 +524,10 @@ typedef struct
double last_ping_request; // while showing scoreboard
double last_servermessage;
//list of ent frames that still need to be acked.
int numackframes;
int ackframes[64];
#ifdef Q2CLIENT
q2frame_t q2frame;
q2frame_t q2frames[Q2UPDATE_BACKUP];
@ -1105,7 +1109,7 @@ qboolean CSQC_KeyPress(int key, int unicode, qboolean down, int devid);
qboolean CSQC_MouseMove(float xdelta, float ydelta, int devid);
qboolean CSQC_MousePosition(float xabs, float yabs, int devid);
qboolean CSQC_Accelerometer(float x, float y, float z);
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation);
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation, float pitchmod);
void CSQC_ParseEntities(void);
qboolean CSQC_SettingListener(void);

View file

@ -609,10 +609,10 @@ void Key_DefaultLinkClicked(char *text, char *info)
}
return;
}
c = Info_ValueForKey(info, "desc");
if (*c)
c = Info_ValueForKey(info, "menu");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Con_Footerf(false, "%s", c);
Cbuf_AddText(va("\nmenu_cmd conlink %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "connect");
@ -651,6 +651,12 @@ void Key_DefaultLinkClicked(char *text, char *info)
Cbuf_AddText(va("\nimpulse %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "desc");
if (*c)
{
Con_Footerf(false, "%s", c);
return;
}
if (!*info && *text == '/')
{
Q_strncpyz(key_lines[edit_line]+1, text, sizeof(key_lines[edit_line])-1);

View file

@ -1846,7 +1846,6 @@ dllfunction_t gecko_functions[] =
{(void**)&posgk_browser_lock_data, "osgk_browser_lock_data"},
{(void**)&posgk_browser_unlock_data, "osgk_browser_unlock_data"},
{(void**)&posgk_browser_event_mouse_move, "osgk_browser_event_mouse_move"},
{(void**)&posgk_browser_event_mouse_move, "osgk_browser_event_mouse_move"},
{(void**)&posgk_browser_event_mouse_button, "osgk_browser_event_mouse_button"},
{(void**)&posgk_browser_event_key, "osgk_browser_event_key"},
@ -4030,3 +4029,4 @@ qboolean Media_PausedDemo(void) {return false;}
int filmtexture;
#endif

View file

@ -325,15 +325,6 @@ void M_Menu_Setup_f (void)
menu_t *menu;
menucustom_t *ci;
menubutton_t *b;
static const char *classnames[] =
{
"Paladin",
"Crusader",
"Necromancer",
"Assasin",
"Demoness",
NULL
};
mgt = M_GameType();
if (mgt == MGT_QUAKE2) //quake2 main menu.
@ -414,6 +405,15 @@ void M_Menu_Setup_f (void)
(info->teamedit = MC_AddEdit(menu, 64, 56, "Your team", team.string));
if (mgt == MGT_HEXEN2)
{
static const char *classnames[] =
{
"Paladin",
"Crusader",
"Necromancer",
"Assasin",
"Demoness",
NULL
};
cvar_t *pc = Cvar_Get("cl_playerclass", "1", CVAR_USERINFO|CVAR_ARCHIVE, "Hexen2");
(info->classedit = MC_AddCombo(menu, 64, 72, "Your class", (const char **)classnames, pc->ival-1));
}

View file

@ -437,6 +437,7 @@ const char *presetexec[] =
"gl_specular 0;"
"r_loadlit 0;"
"r_fastsky 1;"
"r_drawflame 0;"
"r_waterstyle 0;"
"r_lavastyle 0;"
"r_shadow_realtime_dlight 0;"
@ -462,7 +463,7 @@ const char *presetexec[] =
"r_lavastyle 1;"
"r_nolightdir 0;"
, // normal (faithful) options
, // normal (faithful) options, with content replacement thrown in
#ifdef MINIMAL
"r_particlesystem classic;"
#else
@ -476,6 +477,7 @@ const char *presetexec[] =
"gl_load24bit 1;"
"r_replacemodels \"md3 md2\";"
"r_waterwarp 1;"
"r_drawflame 1;"
, // nice options
"r_stains 0.75;"

View file

@ -507,18 +507,24 @@ void M_Menu_Help_f (void)
m_state = m_help;
help_page = 0;
if (COM_FDepthFile("gfx/help1.lmp", true) < COM_FDepthFile("gfx/menu/help1.lmp", true))
if (COM_FDepthFile("gfx/help0.lmp", true) <= COM_FDepthFile("gfx/menu/help1.lmp", true))
{
helpstyle = "gfx/help%i.lmp";
num_help_pages = 6;
helppagemin=0;
}
else
{
helpstyle = "gfx/menu/help%02i.lmp";
num_help_pages = 5;
helppagemin = 1;
}
num_help_pages = 1;
while(num_help_pages < 100)
{
if (!COM_FDepthFile(va(helpstyle, num_help_pages+helppagemin), true))
break;
num_help_pages++;
}
}
@ -1071,7 +1077,7 @@ void M_Draw (int uimenu)
return;
}
if (m_state == m_none)
if (m_state == m_none || m_state == m_menu_dat)
return;
if ((!menu_script || scr_con_current) && !m_recursiveDraw)

View file

@ -443,6 +443,7 @@ void MP_Draw(void);
void MP_RegisterCvarsAndCmds(void);
void MP_Keydown(int key, int unicode);
void MP_Keyup(int key, int unicode);
int MP_BuiltinValid(char *name, int num);
#define MGT_BAD ~0
#define MGT_QUAKE1 0

View file

@ -537,7 +537,7 @@ int Master_KeyForName(char *keyname)
return SLKEY_MAP;
else if (!strcmp(keyname, "ping"))
return SLKEY_PING;
else if (!strcmp(keyname, "name"))
else if (!strcmp(keyname, "name") || !strcmp(keyname, "hostname"))
return SLKEY_NAME;
else if (!strcmp(keyname, "address") || !strcmp(keyname, "cname"))
return SLKEY_ADDRESS;

View file

@ -1554,7 +1554,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
if (ptype->dl_radius)
{
Q_strncatz(outstr, va("lightradius %g %g\n", ptype->dl_radius), outstrlen);
Q_strncatz(outstr, va("lightradius %g\n", ptype->dl_radius), outstrlen);
Q_strncatz(outstr, va("lightradiusfade %g \n", ptype->dl_decay[3]), outstrlen);
Q_strncatz(outstr, va("lightrgb %g %g %g\n", ptype->dl_rgb[0], ptype->dl_rgb[1], ptype->dl_rgb[2]), outstrlen);
Q_strncatz(outstr, va("lightrgbfade %g %g %g\n", ptype->dl_decay[0], ptype->dl_decay[1], ptype->dl_decay[2]), outstrlen);
@ -4480,40 +4480,45 @@ static void GL_DrawTrifanParticle(int count, particle_t **plist, plooks_t *type)
}
}
static void R_AddLineSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type)
static void R_AddLineSparkParticle(int count, particle_t **plist, plooks_t *type)
{
vec3_t v, cr, o2;
float scale;
if (cl_numstrisvert+2 > cl_maxstrisvert)
/*
particle_t *p;
while (count--)
{
cl_maxstrisvert+=64*2;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
p = *plist++;
if (cl_numstrisvert+2 > cl_maxstrisvert)
{
cl_maxstrisvert+=64*2;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+0]);
VectorCopy(p->rgba, cl_strisvertc[cl_numstrisvert+1]);
cl_strisvertc[cl_numstrisvert+1][3] = 0;
Vector2Set(cl_strisvertt[cl_numstrisvert+0], p->s1, p->t1);
Vector2Set(cl_strisvertt[cl_numstrisvert+1], p->s2, p->t2);
VectorCopy(p->org, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(p->org, -1/10, p->vel, cl_strisvertv[cl_numstrisvert+1]);
if (cl_numstrisidx+2 > cl_maxstrisidx)
{
cl_maxstrisidx += 64*2;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 1;
cl_numstrisvert += 2;
t->numvert += 2;
t->numidx += 2;
}
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+0]);
VectorCopy(p->rgba, cl_strisvertc[cl_numstrisvert+1]);
cl_strisvertc[cl_numstrisvert+1][3] = 0;
Vector2Set(cl_strisvertt[cl_numstrisvert+0], p->s1, p->t1);
Vector2Set(cl_strisvertt[cl_numstrisvert+1], p->s2, p->t2);
VectorCopy(p->org, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(p->org, -1/10, p->vel, cl_strisvertv[cl_numstrisvert+1]);
if (cl_numstrisidx+2 > cl_maxstrisidx)
{
cl_maxstrisidx += 64*2;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 1;
cl_numstrisvert += 2;
t->numvert += 2;
t->numidx += 2;
*/
}
static void R_AddTSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type)
@ -4919,9 +4924,9 @@ static void R_AddTexturedParticle(scenetris_t *t, particle_t *p, plooks_t *type)
static void PScript_DrawParticleTypes (void)
{
void (*sparklineparticles)(scenetris_t *t, particle_t *p, plooks_t *type)=R_AddLineSparkParticle;
void (*sparkfanparticles)(scenetris_t *t, particle_t *p, plooks_t *type)=GL_DrawTrifanParticle;
void (*sparktexturedparticles)(scenetris_t *t, particle_t *p, plooks_t *type)=GL_DrawTexturedSparkParticle;
void (*sparklineparticles)(int count, particle_t **plist, plooks_t *type)=R_AddLineSparkParticle;
void (*sparkfanparticles)(int count, particle_t **plist, plooks_t *type)=GL_DrawTrifanParticle;
void (*sparktexturedparticles)(int count, particle_t **plist, plooks_t *type)=GL_DrawTexturedSparkParticle;
qboolean (*tr) (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
void *pdraw, *bdraw;
@ -5590,3 +5595,4 @@ particleengine_t pe_script =
#endif
#endif

View file

@ -3153,98 +3153,6 @@ static void QCBUILTIN PF_cs_OpenPortal (pubprogfuncs_t *prinst, struct globalvar
#endif
}
#ifndef NOMEDIA
// #487 float(string name) gecko_create( string name )
static void QCBUILTIN PF_cs_gecko_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = 1;
}
// #488 void(string name) gecko_destroy( string name )
static void QCBUILTIN PF_cs_gecko_destroy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
// #489 void(string name) gecko_navigate( string name, string URI )
static void QCBUILTIN PF_cs_gecko_navigate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
char *command = PR_GetStringOfs(prinst, OFS_PARM1);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_Command(cin, command);
}
// #490 float(string name) gecko_keyevent( string name, float key, float eventtype )
static void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
int key = G_FLOAT(OFS_PARM1);
int eventtype = G_FLOAT(OFS_PARM2);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_KeyEvent(cin, MP_TranslateDPtoFTECodes(key), (key>127)?0:key, eventtype);
}
// #491 void gecko_mousemove( string name, float x, float y )
static void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
float posx = G_FLOAT(OFS_PARM1);
float posy = G_FLOAT(OFS_PARM2);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_MouseMove(cin, posx, posy);
}
// #492 void gecko_resize( string name, float w, float h )
static void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
float sizex = G_FLOAT(OFS_PARM1);
float sizey = G_FLOAT(OFS_PARM2);
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (!cin)
return;
Media_Send_Resize(cin, sizex, sizey);
}
// #493 vector gecko_get_texture_extent( string name )
static void QCBUILTIN PF_cs_gecko_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *shader = PR_GetStringOfs(prinst, OFS_PARM0);
float *ret = G_VECTOR(OFS_RETURN);
int sx, sy;
cin_t *cin;
cin = R_ShaderFindCinematic(shader);
if (cin)
{
Media_Send_GetSize(cin, &sx, &sy);
}
else
{
sx = 0;
sy = 0;
}
ret[0] = sx;
ret[1] = sy;
ret[2] = 0;
}
#endif
static void QCBUILTIN PF_cs_droptofloor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent;
@ -3284,20 +3192,6 @@ static void QCBUILTIN PF_cs_copyentity (pubprogfuncs_t *prinst, struct globalvar
World_LinkEdict (&csqc_world, (wedict_t*)out, false);
}
static void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = !!cls.demoplayback;
}
static void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
#ifdef CLIENTONLY
G_FLOAT(OFS_RETURN) = false;
#else
G_FLOAT(OFS_RETURN) = sv.state != ss_dead;
#endif
}
static void QCBUILTIN PF_cl_getlight (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
vec3_t ambient, diffuse, dir;
@ -3370,24 +3264,6 @@ static void QCBUILTIN PF_rotatevectorsbytag (pubprogfuncs_t *prinst, struct glob
VectorCopy(srcorg, retorg);
}
static void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
char *defaultbody = PF_VarString(prinst, 1, pr_globals);
shader_t *shad;
if (*defaultbody)
shad = R_RegisterShader(str, defaultbody);
else
shad = R_RegisterSkin(str, NULL);
if (shad)
G_FLOAT(OFS_RETURN) = shad-r_shaders + 1;
else
G_FLOAT(OFS_RETURN) = 0;
}
@ -3671,7 +3547,7 @@ qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state)
{
func_t func;
if (!state || !state->modelindex)
if (!state || state->modelindex <= 0 || state->modelindex >= MAX_MODELS)
{
if (csqcdelta_playerents[playernum])
{
@ -4658,8 +4534,10 @@ static struct {
{"writetofile", PF_writetofile, 606},
{"isfunction", PF_isfunction, 607},
{"parseentitydata", PF_parseentitydata, 608},
{"keynumtostring", PF_cl_keynumtostring, 609},
{"findkeysforcommand", PF_cl_findkeysforcommand, 610},
{"stringtokeynum", PF_cl_stringtokeynum, 614},
{"sprintf", PF_sprintf, 627},
@ -5661,7 +5539,7 @@ qboolean CSQC_LoadResource(char *resname, char *restype)
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, resname));
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, restype));
(((string_t *)pr_globals)[OFS_PARM1] = PR_TempString(csqcprogs, restype));
PR_ExecuteProgram (csqcprogs, csqcg.loadresource);
@ -5797,7 +5675,7 @@ static void CSQC_EntityCheck(int entnum)
}
}
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation)
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation, float pitchmod)
{
void *pr_globals;
csqcedict_t *ent;
@ -5814,6 +5692,7 @@ int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float
G_FLOAT(OFS_PARM3) = vol;
G_FLOAT(OFS_PARM4) = attenuation;
VectorCopy(pos, G_VECTOR(OFS_PARM5));
G_FLOAT(OFS_PARM6) = attenuation;
PR_ExecuteProgram(csqcprogs, csqcg.event_sound);

File diff suppressed because it is too large Load diff

View file

@ -244,7 +244,7 @@ void R2D_Init(void)
"}\n"
"}\n"
);
shader_menutint = R_RegisterShader("menutint_glsl",
shader_menutint = R_RegisterShader("menutint",
"{\n"
"if $glsl && gl_menutint_shader != 0\n"
"[\n"
@ -610,6 +610,13 @@ void R2D_Font_Callback(struct cvar_s *var, char *oldvalue)
#ifdef _WIN32
if (!strcmp(var->string, "?"))
{
BOOL (APIENTRY *pChooseFontA)(LPCHOOSEFONTA) = NULL;
dllfunction_t funcs[] =
{
{(void*)&pChooseFontA, "ChooseFontA"},
{NULL}
};
qboolean MyRegGetStringValue(HKEY base, char *keyname, char *valuename, void *data, int datalen);
LOGFONT lf = {0};
CHOOSEFONT cf = {sizeof(cf)};
extern HWND mainwindow;
@ -620,20 +627,21 @@ void R2D_Font_Callback(struct cvar_s *var, char *oldvalue)
cf.iPointSize = (8 * vid.rotpixelheight)/vid.height;
cf.Flags = CF_FORCEFONTEXIST | CF_TTONLY;
cf.lpLogFont = &lf;
Sys_LoadLibrary("Comdlg32.dll", funcs);
if (ChooseFont(&cf))
if (pChooseFontA && pChooseFontA(&cf))
{
char fname[MAX_OSPATH];
DWORD bufsz = sizeof(fname);
char *keyname;
keyname = va("%s%s%s (TrueType)", lf.lfFaceName, lf.lfWeight>=FW_BOLD?" Bold":"", lf.lfItalic?" Italic":"");
if (ERROR_SUCCESS == RegGetValue(HKEY_LOCAL_MACHINE, WinNT?"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts":"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts", keyname, RRF_RT_REG_SZ, NULL, fname, &bufsz))
if (MyRegGetStringValue(HKEY_LOCAL_MACHINE, WinNT?"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts":"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts", keyname, fname, sizeof(fname)))
{
Cvar_Set(var, fname);
return;
}
keyname = va("%s (OpenType)", lf.lfFaceName);
if (ERROR_SUCCESS == RegGetValue(HKEY_LOCAL_MACHINE, WinNT?"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts":"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts", keyname, RRF_RT_REG_SZ, NULL, fname, &bufsz))
if (MyRegGetStringValue(HKEY_LOCAL_MACHINE, WinNT?"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts":"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts", keyname, fname, sizeof(fname)))
{
Cvar_Set(var, fname);
return;
@ -1165,3 +1173,4 @@ void R2D_DrawCrosshair(void)
#endif

View file

@ -276,7 +276,7 @@ cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1",
cvar_t r_clear = CVARAF("r_clear","0",
"gl_clear", 0);
cvar_t gl_max_size = SCVARF ("gl_max_size", "1024", CVAR_RENDERERLATCH);
cvar_t gl_max_size = SCVARF ("gl_max_size", "2048", CVAR_RENDERERLATCH);
cvar_t gl_maxshadowlights = SCVARF ("gl_maxshadowlights", "2",
CVAR_ARCHIVE);
cvar_t gl_menutint_shader = SCVAR ("gl_menutint_shader", "1");

View file

@ -1978,7 +1978,8 @@ void Win7_TaskListInit(void)
}
#endif
#if defined(SVNREVISION)
#if defined(SVNREVISION) && !defined(MINIMAL)
#define SVNREVISIONSTR STRINGIFY(SVNREVISION)
#if defined(OFFICIAL_RELEASE)
#define BUILDTYPE "rel"
#else
@ -2003,7 +2004,7 @@ void Win7_TaskListInit(void)
#else
#define EXETYPE "glqw"
#endif
#elif defiend(D3DQUAKE)
#elif defined(D3DQUAKE)
#define EXETYPE "d3dqw"
#elif defiend(SWQUAKE)
#define EXETYPE "swqw"
@ -2012,41 +2013,50 @@ void Win7_TaskListInit(void)
#define EXETYPE "qw"
#endif
#ifdef UPDATE_URL
void MyRegSetValue(HKEY base, char *keyname, char *valuename, int type, void *data, int datalen)
{
HKEY subkey;
RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey);
RegSetValueEx(subkey, valuename, 0, type, data, datalen);
RegCloseKey (subkey);
}
void MyRegDeleteKeyValue(HKEY base, char *keyname, char *valuename)
{
HKEY subkey;
RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey);
RegDeleteValue(subkey, valuename);
RegCloseKey (subkey);
}
void MyRegGetStringValue(HKEY base, char *keyname, char *valuename, void *data, int datalen)
qboolean MyRegGetStringValue(HKEY base, char *keyname, char *valuename, void *data, int datalen)
{
qboolean result = false;
DWORD resultlen = datalen - 1;
HKEY subkey;
DWORD type = REG_NONE;
RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey);
RegQueryValueEx(subkey, valuename, NULL, &type, data, &datalen);
RegCloseKey (subkey);
if (RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey) == ERROR_SUCCESS)
{
result = ERROR_SUCCESS == RegQueryValueEx(subkey, valuename, NULL, &type, data, &datalen);
RegCloseKey (subkey);
}
if (type == REG_SZ || type == REG_EXPAND_SZ)
((char*)data)[datalen] = 0;
else
((char*)data)[0] = 0;
return result;
}
#ifdef UPDATE_URL
void MyRegSetValue(HKEY base, char *keyname, char *valuename, int type, void *data, int datalen)
{
HKEY subkey;
if (RegCreateKeyEx(base, keyname, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS)
{
RegSetValueEx(subkey, valuename, 0, type, data, datalen);
RegCloseKey (subkey);
}
}
void MyRegDeleteKeyValue(HKEY base, char *keyname, char *valuename)
{
HKEY subkey;
if (RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey) == ERROR_SUCCESS)
{
RegDeleteValue(subkey, valuename);
RegCloseKey (subkey);
}
}
qboolean Update_GetHomeDirectory(char *homedir, int homedirsize)
{
HMODULE shfolder = LoadLibrary("shfolder.dll");
DWORD winver = (DWORD)LOBYTE(LOWORD(GetVersion()));
if (shfolder)
{
@ -2111,7 +2121,7 @@ void Update_Versioninfo_Available(struct dl_download *dl)
{
if (!strnicmp(linebuf, "Revision: ", 10))
{
if (atoi(linebuf+10) > atoi(SVNREVISION))
if (atoi(linebuf+10) > atoi(SVNREVISIONSTR))
{
struct dl_download *dl;
Con_Printf("Downloading update: revision %i\n", atoi(linebuf+10));
@ -2143,24 +2153,22 @@ void Update_Check(void)
qboolean Sys_CheckUpdated(void)
{
if (!strcmp(SVNREVISION, "-"))
int ffe = COM_CheckParm("--fromfrontend");
PROCESS_INFORMATION childinfo;
STARTUPINFO startinfo = {sizeof(startinfo)};
if (!strcmp(SVNREVISIONSTR, "-"))
return false; //no revision info in this build, meaning its custom built and thus cannot check against the available updated versions.
else if (COM_CheckParm("-noupdate") || COM_CheckParm("--noupdate"))
return false;
else if (!COM_CheckParm("-autoupdate") && !COM_CheckParm("--autoupdate"))
return false;
else if (!COM_CheckParm("--fromfrontend"))
else if (!ffe)
{
char frontendpath[MAX_OSPATH];
char pendingpath[MAX_OSPATH];
char updatedpath[MAX_QPATH];
PROCESS_INFORMATION childinfo;
STARTUPINFO startinfo;
char *cmdline = GetCommandLineA();
memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(startinfo);
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, pendingpath, sizeof(pendingpath));
if (*pendingpath)
{
@ -2175,7 +2183,21 @@ qboolean Sys_CheckUpdated(void)
if (*updatedpath)
{
if (CreateProcess(updatedpath, va("%s --fromfrontend", COM_Parse(cmdline)), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo))
GetModuleFileName(NULL, frontendpath, sizeof(frontendpath)-1);
if (CreateProcess(updatedpath, va("--fromfrontend \"%s\" \"%s\" %s", SVNREVISIONSTR, frontendpath, COM_Parse(GetCommandLineA())), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo))
return true;
}
}
else
{
char frontendpath[MAX_OSPATH];
//com_argv[ffe+1] is frontend revision
//com_argv[ffe+2] is frontend location
if (atoi(com_argv[ffe+1]) > atoi(SVNREVISIONSTR))
{
//ping-pong it back, to make sure we're running the most recent version.
GetModuleFileName(NULL, frontendpath, sizeof(frontendpath)-1);
if (CreateProcess(com_argv[ffe+2], va("--fromfrontend \"%s\" \"%s\" %s", "", "", COM_Parse(GetCommandLineA())), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo))
return true;
}
}

View file

@ -1861,6 +1861,13 @@ void Cmd_ForwardToServer_f (void)
if (SCR_RSShot())
return;
}
if (Q_strcasecmp(Cmd_Argv(1), "pext") == 0 && (cls.protocol != CP_NETQUAKE || cls.protocol_nq != CPNQ_ID || cls.netchan.remote_address.type != NA_LOOPBACK))
{ //don't send any extension flags this if we're using cl_loopbackprotocol nqid, purely for a compat test.
//if you want to record compat-demos, disable extensions instead.
unsigned int fp1 = Net_PextMask(1, cls.protocol == CP_NETQUAKE), fp2 = Net_PextMask(2, cls.protocol == CP_NETQUAKE);
CL_SendClientCommand(true, "pext %#x %#x %#x %#x", PROTOCOL_VERSION_FTE, fp1, PROTOCOL_VERSION_FTE2, fp2);
return;
}
if (Q_strcasecmp(Cmd_Argv(1), "ptrack") == 0)
{
if (!*Cmd_Argv(2))
@ -2774,6 +2781,12 @@ void Cmd_WriteConfig_f(void)
char fname[MAX_OSPATH];
char sysname[MAX_OSPATH];
if (Cmd_IsInsecure())
{
Con_Printf ("%s not allowed\n", Cmd_Argv(0));
return;
}
filename = Cmd_Argv(1);
if (!*filename)
{

View file

@ -133,8 +133,8 @@ void Cmd_Args_Set(char *newargs);
#define RESTRICT_RCON rcon_level.ival
#define RESTRICT_PROGS RESTRICT_MAX-2
#define Cmd_FromGamecode() (Cmd_ExecLevel>=RESTRICT_SERVER) //cheat provention
#define Cmd_IsInsecure() (Cmd_ExecLevel>=RESTRICT_INSECURE) //prevention from the server from breaking/crashing/wiping us.
#define Cmd_FromGamecode() (Cmd_ExecLevel>=RESTRICT_SERVER) //cheat provention. block cheats if its not fromgamecode
#define Cmd_IsInsecure() (Cmd_ExecLevel>=RESTRICT_INSECURE) //prevention from the server from breaking/crashing/wiping us. if this returns true, block file access etc.
// Parses a single line of text into arguments and tries to execute it
// as if it was typed at the console

View file

@ -1921,7 +1921,7 @@ void COM_DefaultExtension (char *path, char *extension, int maxlen)
//3 invalid unicode char
//4 invalid utf-16 lead/high surrogate
//5 invalid utf-16 tail/low surrogate
unsigned int utf8_decode(int *error, const void *in, void **out)
unsigned int utf8_decode(int *error, const void *in, char **out)
{
//uc is the output unicode char
unsigned int uc = 0xfffdu; //replacement character
@ -2406,7 +2406,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
if (*str & 0x80 && utf8 > 0)
{ //check for utf-8
int decodeerror;
void *end;
char *end;
uc = utf8_decode(&decodeerror, str, &end);
if (decodeerror)
{
@ -2600,8 +2600,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
//we don't support the full 12bit colour depth (only 4-bit CGA)
//so find the closest that we do support
int best = 1;
float bd = 255*255*255, d;
int c;
float bd = 255*255*255;
int r, g, b;
if (str[2] >= '0' && str[2] <= '9')
r = (str[2]-'0');

View file

@ -293,7 +293,7 @@ void COM_ParsePlusSets (void);
typedef unsigned int conchar_t;
char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, qboolean ignoreflags);
conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, qboolean keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator
unsigned int utf8_decode(int *error, const void *in, void **out);
unsigned int utf8_decode(int *error, const void *in, char **out);
unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen);
char *COM_SkipPath (const char *pathname);

View file

@ -1447,6 +1447,20 @@ static searchpath_t *FS_AddPathHandle(const char *purepath, const char *probable
else
Q_strncpyz(search->purepath, purepath, sizeof(search->purepath));
//temp packages also do not nest
if (!istemporary)
{
for (i = 0; i < sizeof(searchpathformats)/sizeof(searchpathformats[0]); i++)
{
if (!searchpathformats[i].extension || !searchpathformats[i].funcs || !searchpathformats[i].funcs->OpenNew || !searchpathformats[i].loadscan)
continue;
if (loadstuff & (1<<i))
{
FS_AddDataFiles(purepath, probablepath, search, searchpathformats[i].extension, searchpathformats[i].funcs);
}
}
}
if (istemporary)
{
//add at end. pureness will reorder if needed.
@ -1462,23 +1476,8 @@ static searchpath_t *FS_AddPathHandle(const char *purepath, const char *probable
search->next = com_searchpaths;
com_searchpaths = search;
}
com_fschanged = true;
//temp packages also do not nest
if (!istemporary)
{
for (i = 0; i < sizeof(searchpathformats)/sizeof(searchpathformats[0]); i++)
{
if (!searchpathformats[i].extension || !searchpathformats[i].funcs || !searchpathformats[i].funcs->OpenNew || !searchpathformats[i].loadscan)
continue;
if (loadstuff & (1<<i))
{
FS_AddDataFiles(purepath, probablepath, search, searchpathformats[i].extension, searchpathformats[i].funcs);
}
}
}
return search;
}

View file

@ -124,7 +124,9 @@ typedef struct
#ifdef NQPROT
int isnqprotocol;
qboolean nqreliable_allowed;
qboolean nqreliable_allowed; //says the peer has acked the last reliable (or timed out and needs resending).
float nqreliable_resendtime;//force nqreliable_allowed, thereby forcing a resend of anything n
qboolean nqunreliableonly; //prohibits new reliables, but allows resends.
#endif
struct netprim_s netprim;
int fragmentsize;

View file

@ -317,6 +317,9 @@ void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport)
chan->sock = sock;
chan->remote_address = adr;
chan->last_received = realtime;
#ifdef NQPROT
chan->nqreliable_allowed = true;
#endif
chan->message.data = chan->message_buf;
chan->message.allowoverflow = true;
@ -406,6 +409,7 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
}
chan->incoming_reliable_acknowledged = chan->reliable_sequence;
chan->reliable_sequence++;
chan->nqreliable_allowed = true;
chan->last_received = realtime;
}
@ -415,10 +419,9 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
Con_Printf("Future ack recieved\n");
if (showpackets.value)
Con_Printf ("<-- a s=%i a=%i(%i) %i\n"
, chan->outgoing_sequence
, chan->incoming_sequence
, chan->incoming_reliable_sequence
Con_Printf ("in %s a=%i %i\n"
, chan->sock != NS_SERVER?"s2c":"c2s"
, sequence
, 0);
return NQP_ERROR; //don't try execing the 'payload'. I hate ack packets.
@ -426,7 +429,7 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
if (header & NETFLAG_UNRELIABLE)
{
if (sequence < chan->incoming_unreliable)
if (sequence <= chan->incoming_unreliable)
{
Con_DPrintf("Stale datagram recieved\n");
return NQP_ERROR;
@ -452,10 +455,9 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
chan->good_count++;
if (showpackets.value)
Con_Printf ("<-- u s=%i a=%i(%i) %i\n"
, chan->outgoing_sequence
, chan->incoming_sequence
, chan->incoming_reliable_sequence
Con_Printf ("in %s u=%i %i\n"
, chan->sock != NS_SERVER?"s2c":"c2s"
, chan->incoming_unreliable
, net_message.cursize);
return NQP_DATAGRAM;
}
@ -466,6 +468,11 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
runt[0] = BigLong(NETFLAG_ACK | 8);
runt[1] = BigLong(sequence);
NET_SendPacket (chan->sock, 8, runt, net_from);
if (showpackets.value)
Con_Printf ("out %s a=%i %i\n"
, chan->sock == NS_SERVER?"s2c":"c2s"
, sequence
, 0);
chan->last_received = realtime;
if (sequence == chan->incoming_reliable_sequence)
@ -489,10 +496,9 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
MSG_BeginReading(chan->netprim);
if (showpackets.value)
Con_Printf ("<-- r s=%i a=%i(%i) %i\n"
, chan->outgoing_sequence
, chan->incoming_sequence
, chan->incoming_reliable_sequence
Con_Printf ("in %s r=%i %i\n"
, chan->sock != NS_SERVER?"s2c":"c2s"
, sequence
, net_message.cursize);
return NQP_RELIABLE; //we can read it now
}
@ -536,9 +542,12 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
send.cursize = 0;
/*unreliables flood out, but reliables are tied to server sequences*/
if (chan->nqreliable_resendtime < realtime)
chan->nqreliable_allowed = true;
if (chan->nqreliable_allowed)
{
if (!chan->reliable_length && chan->message.cursize)
//consume the new reliable when we can.
if (!chan->reliable_length && chan->message.cursize && !chan->nqunreliableonly)
{
memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize);
chan->reliable_length = chan->message.cursize;
@ -560,8 +569,8 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
{
if (send.cursize + length < send.maxsize)
{ //throw the unreliable packet into the same one as the reliable (but not sent reliably)
SZ_Write (&send, data, length);
length = 0;
// SZ_Write (&send, data, length);
// length = 0;
}
*(int*)send_buf = BigLong(NETFLAG_DATA | NETFLAG_EOM | send.cursize);
@ -574,14 +583,15 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
sentsize += send.cursize;
if (showpackets.value)
Con_Printf ("--> r s=%i a=%i(%i) %i\n"
, chan->outgoing_sequence
, chan->incoming_sequence
, chan->incoming_reliable_sequence
Con_Printf ("out %s r s=%i %i\n"
, chan->sock == NS_SERVER?"s2c":"c2s"
, chan->reliable_sequence
, send.cursize);
send.cursize = 0;
chan->nqreliable_allowed = false;
chan->nqreliable_resendtime = realtime + 0.3; //resend reliables after 0.3 seconds. nq transports suck.
}
chan->nqreliable_allowed = false;
}
//send out the unreliable (if still unsent)
@ -598,8 +608,9 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
sentsize += send.cursize;
if (showpackets.value)
Con_Printf ("--> u s=%i %i\n"
, chan->outgoing_unreliable
Con_Printf ("out %s u=%i %i\n"
, chan->sock == NS_SERVER?"s2c":"c2s"
, chan->outgoing_unreliable-1
, send.cursize);
send.cursize = 0;
}

View file

@ -1,3 +1,5 @@
//file for builtin implementations relevent to all VMs.
#include "quakedef.h"
#if !defined(CLIENTONLY) || defined(CSQC_DAT) || defined(MENU_DAT)
@ -2844,6 +2846,16 @@ static struct {
} qctoken[MAXQCTOKENS];
unsigned int qctoken_count;
void tokenize_flush(void)
{
while(qctoken_count > 0)
{
qctoken_count--;
free(qctoken[qctoken_count].token);
}
qctoken_count = 0;
}
void QCBUILTIN PF_ArgC (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //85 //float() argc;
{
G_FLOAT(OFS_RETURN) = qctoken_count;
@ -2908,13 +2920,7 @@ void QCBUILTIN PF_tokenizebyseparator (pubprogfuncs_t *prinst, struct globalvar
seps++;
}
/*flush the old lot*/
while(qctoken_count > 0)
{
qctoken_count--;
free(qctoken[qctoken_count].token);
}
qctoken_count = 0;
tokenize_flush();
qctoken[qctoken_count].start = 0;
if (*str)
@ -3928,6 +3934,7 @@ void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored)
#ifdef TEXTEDITOR
Editor_ProgsKilled(progs);
#endif
tokenize_flush();
}
@ -3943,7 +3950,8 @@ static void PR_AutoCvarApply(pubprogfuncs_t *prinst, eval_t *val, etype_t type,
val->_int = var->ival;
break;
case ev_string:
prinst->RemoveProgsString(prinst, val->_int);
if (val->_int)
prinst->RemoveProgsString(prinst, val->_int);
if (*var->string)
val->_int = PR_SetString(prinst, var->string);
else
@ -4011,6 +4019,7 @@ void PDECL PR_FoundPrefixedGlobals(pubprogfuncs_t *progfuncs, char *name, eval_t
break;
case ev_string:
vals = PR_GetString(progfuncs, val->string);
val->_int = 0;
break;
default:
return;
@ -4196,6 +4205,7 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_ENT_SKIN_CONTENTS"}, //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"}},
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
{"FTE_GFX_QUAKE3SHADERS"},
{"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}},

View file

@ -331,6 +331,26 @@ void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_destroy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_navigate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_cs_gecko_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
typedef enum{
SLIST_HOSTCACHEVIEWCOUNT,
SLIST_HOSTCACHETOTALCOUNT,
SLIST_MASTERQUERYCOUNT,
SLIST_MASTERREPLYCOUNT,
SLIST_SERVERQUERYCOUNT,
SLIST_SERVERREPLYCOUNT,
SLIST_SORTFIELD,
SLIST_SORTDESCENDING
} hostcacheglobal_t;
void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void search_close_progs(pubprogfuncs_t *prinst, qboolean complain);

View file

@ -171,7 +171,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svc_damage 19
#define svc_spawnstatic 20
#define svc_spawnstatic2 21
#define svcfte_spawnstatic2 21
#define svc_spawnbaseline 22
#define svc_temp_entity 23 // variable
@ -541,7 +541,7 @@ enum clcq2_ops_e
/*the rest is optional extensions*/
#define UF_ALPHA (1u<<16)
#define UF_SCALE (1u<<17)
#define UF_ABSLIGHT (1u<<18)
#define UF_UNUSED3 (1u<<18)
#define UF_DRAWFLAGS (1u<<19)
#define UF_TAGINFO (1u<<20)
#define UF_LIGHT (1u<<21)

View file

@ -258,4 +258,5 @@ int D3D9Shader_FindUniform(union programhandle_u *h, int type, char *name)
return -1;
}
#endif
#endif

View file

@ -237,6 +237,7 @@ Global
{2866F783-6B44-4655-A38D-D53874037454}.Debug|Win32.Build.0 = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.Debug|x64.ActiveCfg = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.ActiveCfg = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.Build.0 = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLDebug|x64.ActiveCfg = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLRelease|Win32.ActiveCfg = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLRelease|x64.ActiveCfg = Release|Win32

View file

@ -12007,6 +12007,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\pr_clcmd.c"
>
</File>
<File
RelativePath="..\client\pr_csqc.c"
>

View file

@ -71,7 +71,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"n -= 1.0 - 4.0/256.0;\n"
"#ifdef RIPPLEMAP\n"
"n += texture2D(s_t3, stc)*3;\n"
"n += texture2D(s_t3, stc).rgb*3.0;\n"
"#endif\n"
//the fresnel term decides how transparent the water should be
@ -414,23 +414,50 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!permu FRAMEBLEND\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvarf gl_specular\n"
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
"#ifdef UPPERLOWER\n"
"#define UPPER\n"
"#define LOWER\n"
"#endif\n"
"varying vec2 tc;\n"
"varying vec3 light;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"attribute vec2 v_texcoord;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"#endif\n"
"void main ()\n"
"{\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
"vec3 n, s, t, w;\n"
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = -dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = dot(eyeminusvertex, t.xyz);\n"
"eyevector.z = dot(eyeminusvertex, n.xyz);\n"
"#else\n"
"vec3 n;\n"
"gl_Position = skeletaltransform_n(n);\n"
"#endif\n"
"light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);\n"
"tc = v_texcoord;\n"
"}\n"
@ -449,24 +476,54 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t3;\n"
"#endif\n"
"#if defined(SPECULAR)\n"
"uniform sampler2D s_t4;\n"
"uniform sampler2D s_t5;\n"
"uniform float cvar_gl_specular;\n"
"#endif\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
"vec4 col, sp;\n"
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
"col = texture2D(s_t0, tc);\n"
"#ifdef UPPER\n"
"vec4 uc = texture2D(s_t2, tc);\n"
"col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);\n"
"col.rgb += uc.rgb*e_uppercolour*uc.a;\n"
"#endif\n"
"#ifdef LOWER\n"
"vec4 lc = texture2D(s_t1, tc);\n"
"col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);\n"
"col.rgb += lc.rgb*e_lowercolour*lc.a;\n"
"#endif\n"
"col.rgb *= light;\n"
"#if defined(SPECULAR)\n"
"vec3 bumps = normalize(vec3(texture2D(s_t4, tc)) - 0.5);\n"
"vec4 specs = texture2D(s_t5, tc);\n"
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0));\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);\n"
"col.rgb += cvar_gl_specular * spec * specs.rgb;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"vec4 fb = texture2D(s_t3, tc);\n"
"col.rgb = mix(col.rgb, fb.rgb, fb.a);\n"
"#endif\n"
"gl_FragColor = fog4(col * e_colourident);\n"
"}\n"
"#endif\n"
@ -1366,6 +1423,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
{QR_OPENGL, 110, "rtlight",
"!!permu BUMP\n"
"!!permu SKELETAL\n"
"!!permu UPPERLOWER\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
@ -1383,6 +1441,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#extension GL_ARB_texture_gather : enable\n"
"#endif\n"
"#ifdef UPPERLOWER\n"
"#define UPPER\n"
"#define LOWER\n"
"#endif\n"
"varying vec2 tcbase;\n"
"varying vec3 lightvector;\n"
@ -1431,20 +1494,20 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t0; //diffuse\n"
"#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform sampler2D s_t1;\n"
"uniform sampler2D s_t1; //normalmap\n"
"#endif\n"
"#ifdef SPECULAR\n"
"uniform sampler2D s_t2;\n"
"uniform sampler2D s_t2; //specular\n"
"#endif\n"
"#ifdef CUBEPROJ\n"
"uniform samplerCube s_t3;\n"
"uniform samplerCube s_t3; //projected cubemap\n"
"#endif\n"
"#ifdef PCF\n"
"#ifdef CUBESHADOW\n"
"uniform samplerCubeShadow s_t4;\n"
"uniform samplerCubeShadow s_t4; //shadowmap\n"
"#else\n"
"#if 0//def GL_ARB_texture_gather\n"
"uniform sampler2D s_t4;\n"
@ -1453,6 +1516,14 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"#endif\n"
"#endif\n"
"#ifdef LOWER\n"
"uniform sampler2D s_t5; //pants colours\n"
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t6; //shirt colours\n"
"uniform vec3 e_uppercolour;\n"
"#endif\n"
"uniform float l_lightradius;\n"
@ -1494,7 +1565,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//assume z is the major axis (ie: forward from the light)
"vec3 t = shadowcoord;\n"
"float ma = dir.z;\n"
"vec4 axis = vec4(1.0, 1.0, 1.0, 0.0);\n"
"vec3 axis = vec3(1.0, 1.0, 1.0);\n"
"if (dir.x > ma)\n"
"{\n"
"ma = dir.x;\n"
@ -1566,6 +1637,14 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#define tcbase tcoffsetmap\n"
"#endif\n"
"vec3 bases = vec3(texture2D(s_t0, tcbase));\n"
"#ifdef UPPER\n"
"vec4 uc = texture2D(s_t6, tcbase);\n"
"bases.rgb += uc.rgb*e_uppercolour*uc.a;\n"
"#endif\n"
"#ifdef LOWER\n"
"vec4 lc = texture2D(s_t5, tcbase);\n"
"bases.rgb += lc.rgb*e_lowercolour*lc.a;\n"
"#endif\n"
"#if defined(BUMP) || defined(SPECULAR)\n"
"vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5);\n"
"#endif\n"
@ -1716,7 +1795,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform sampler2D s_t0;/*$currentrender*/\n"
"uniform sampler2D s_t1;/*warp image*/\n"
"uniform sampler2D s_t2;/*edge image*/\n"
"uniform vec3 e_rendertexturescale;\n"
"uniform vec4 e_rendertexturescale;\n"
"uniform float cvar_r_waterwarp;\n"
"void main ()\n"
"{\n"

View file

@ -634,6 +634,7 @@ enum {
WARN_UNSAFEFUNCTIONRETURNTYPE,
WARN_MISSINGOPTIONAL,
WARN_SYSTEMCRC,
WARN_CONDITIONALTYPEMISMATCH,
ERR_PARSEERRORS, //caused by qcc_pr_parseerror being called.
@ -875,22 +876,21 @@ extern int numtemps;
typedef char PATHSTRING[MAX_DATA_PATH];
extern PATHSTRING *precache_sounds;
extern int *precache_sounds_block;
extern int *precache_sounds_used;
typedef struct
{
PATHSTRING name;
int block;
int used;
int fileline;
char *filename;
} precache_t;
extern precache_t *precache_sound;
extern int numsounds;
extern PATHSTRING *precache_textures;
extern int *precache_textures_block;
extern precache_t *precache_texture;
extern int numtextures;
extern PATHSTRING *precache_models;
extern int *precache_models_block;
extern int *precache_models_used;
extern precache_t *precache_model;
extern int nummodels;
extern PATHSTRING *precache_files;
extern int *precache_files_block;
extern precache_t *precache_file;
extern int numfiles;
typedef struct qcc_includechunk_s {

View file

@ -1973,7 +1973,7 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
if (statements[numstatements-1].c == var_a->ofs)
{
static QCC_def_t nvara;
if (statements[numstatements-1].op == OP_NOT_F)
if (statements[numstatements-1].op == OP_NOT_F && QCC_OPCodeValid(&pr_opcodes[OP_IF_F]))
op = &pr_opcodes[OP_IF_F];
else
op = &pr_opcodes[OP_IF_I];
@ -2812,16 +2812,16 @@ void QCC_PrecacheSound (QCC_def_t *e, int ch)
if (!*n)
return;
for (i=0 ; i<numsounds ; i++)
if (!STRCMP(n, precache_sounds[i]))
if (!STRCMP(n, precache_sound[i].name))
return;
if (numsounds == QCC_MAX_SOUNDS)
return;
// QCC_Error ("PrecacheSound: numsounds == MAX_SOUNDS");
strcpy (precache_sounds[i], n);
strcpy (precache_sound[i].name, n);
if (ch >= '1' && ch <= '9')
precache_sounds_block[i] = ch - '0';
precache_sound[i].block = ch - '0';
else
precache_sounds_block[i] = 1;
precache_sound[i].block = 1;
numsounds++;
}
@ -2839,25 +2839,27 @@ void QCC_PrecacheModel (QCC_def_t *e, int ch)
if (!*n)
return;
for (i=0 ; i<nummodels ; i++)
if (!STRCMP(n, precache_models[i]))
if (!STRCMP(n, precache_model[i].name))
{
if (!precache_models_block[i])
if (!precache_model[i].block)
{
if (ch >= '1' && ch <= '9')
precache_models_block[i] = ch - '0';
precache_model[i].block = ch - '0';
else
precache_models_block[i] = 1;
precache_model[i].block = 1;
}
return;
}
if (nummodels == QCC_MAX_MODELS)
return;
// QCC_Error ("PrecacheModels: nummodels == MAX_MODELS");
strcpy (precache_models[i], n);
strcpy (precache_model[i].name, n);
if (ch >= '1' && ch <= '9')
precache_models_block[i] = ch - '0';
precache_model[i].block = ch - '0';
else
precache_models_block[i] = 1;
precache_model[i].block = 1;
precache_model[i].filename = strings+s_file;
precache_model[i].fileline = pr_source_line;
nummodels++;
}
@ -2875,16 +2877,19 @@ void QCC_SetModel (QCC_def_t *e)
if (!*n)
return;
for (i=0 ; i<nummodels ; i++)
if (!STRCMP(n, precache_models[i]))
if (!STRCMP(n, precache_model[i].name))
{
precache_models_used[i]++;
precache_model[i].used++;
return;
}
if (nummodels == QCC_MAX_MODELS)
return;
strcpy (precache_models[i], n);
precache_models_block[i] = 0;
precache_models_used[i]=1;
strcpy (precache_model[i].name, n);
precache_model[i].block = 0;
precache_model[i].used=1;
precache_model[i].filename = strings+s_file;
precache_model[i].fileline = pr_source_line;
nummodels++;
}
@ -2902,16 +2907,16 @@ void QCC_PrecacheTexture (QCC_def_t *e, int ch)
if (!*n)
return;
for (i=0 ; i<numtextures ; i++)
if (!STRCMP(n, precache_textures[i]))
if (!STRCMP(n, precache_texture[i].name))
return;
if (nummodels == QCC_MAX_MODELS)
return;
// QCC_Error ("PrecacheTextures: numtextures == MAX_TEXTURES");
strcpy (precache_textures[i], n);
strcpy (precache_texture[i].name, n);
if (ch >= '1' && ch <= '9')
precache_textures_block[i] = ch - '0';
precache_texture[i].block = ch - '0';
else
precache_textures_block[i] = 1;
precache_texture[i].block = 1;
numtextures++;
}
@ -2929,16 +2934,16 @@ void QCC_PrecacheFile (QCC_def_t *e, int ch)
if (!*n)
return;
for (i=0 ; i<numfiles ; i++)
if (!STRCMP(n, precache_files[i]))
if (!STRCMP(n, precache_file[i].name))
return;
if (numfiles == QCC_MAX_FILES)
return;
// QCC_Error ("PrecacheFile: numfiles == MAX_FILES");
strcpy (precache_files[i], n);
strcpy (precache_file[i].name, n);
if (ch >= '1' && ch <= '9')
precache_files_block[i] = ch - '0';
precache_file[i].block = ch - '0';
else
precache_files_block[i] = 1;
precache_file[i].block = 1;
numfiles++;
}
@ -2947,16 +2952,16 @@ void QCC_PrecacheFileOptimised (char *n, int ch)
int i;
for (i=0 ; i<numfiles ; i++)
if (!STRCMP(n, precache_files[i]))
if (!STRCMP(n, precache_file[i].name))
return;
if (numfiles == QCC_MAX_FILES)
return;
// QCC_Error ("PrecacheFile: numfiles == MAX_FILES");
strcpy (precache_files[i], n);
strcpy (precache_file[i].name, n);
if (ch >= '1' && ch <= '9')
precache_files_block[i] = ch - '0';
precache_file[i].block = ch - '0';
else
precache_files_block[i] = 1;
precache_file[i].block = 1;
numfiles++;
}
@ -5853,6 +5858,97 @@ pbool QCC_PR_StatementBlocksMatch(QCC_dstatement_t *p1, int p1count, QCC_dstatem
return true;
}
//vanilla qc only has an OP_IFNOT_I, others will be emulated as required, so we tend to need to emulate other opcodes.
QCC_dstatement_t *QCC_Generate_OP_IF(QCC_def_t *e)
{
QCC_dstatement_t *st;
switch(e->type->type)
{
//int/pointer types
case ev_entity:
case ev_field:
case ev_function:
case ev_pointer:
case ev_integer:
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &st));
break;
//emulated types
case ev_string:
QCC_PR_ParseWarning(WARN_IFSTRING_USED, "if (string) tests for null, not empty.");
if (flag_ifstring)
{
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_S], e, NULL, &st));
break;
}
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &st));
break;
case ev_float:
if (flag_iffloat || QCC_OPCodeValid(&pr_opcodes[OP_IF_F]))
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, NULL, &st));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &st));
break;
case ev_vector:
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], QCC_PR_Statement (&pr_opcodes[OP_NOT_V], e, NULL, NULL), NULL, &st));
break;
case ev_variant:
case ev_struct:
case ev_union:
case ev_void:
default:
QCC_PR_ParseWarning(WARN_CONDITIONALTYPEMISMATCH, "conditional type mismatch: %s", basictypenames[e->type->type]);
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &st));
break;
}
return st;
}
QCC_dstatement_t *QCC_Generate_OP_IFNOT(QCC_def_t *e)
{
QCC_dstatement_t *st;
switch(e->type->type)
{
//int/pointer types
case ev_entity:
case ev_field:
case ev_function:
case ev_pointer:
case ev_integer:
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, NULL, &st));
break;
//emulated types
case ev_string:
QCC_PR_ParseWarning(WARN_IFSTRING_USED, "if (string) tests for null, not empty");
if (flag_ifstring)
{
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, NULL, &st));
break;
}
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, NULL, &st));
break;
case ev_float:
if (flag_iffloat || QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F]))
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, NULL, &st));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, NULL, &st));
break;
case ev_vector:
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], QCC_PR_Statement (&pr_opcodes[OP_NOT_V], e, NULL, NULL), NULL, &st));
break;
case ev_variant:
case ev_struct:
case ev_union:
case ev_void:
default:
QCC_PR_ParseWarning(WARN_CONDITIONALTYPEMISMATCH, "conditional type mismatch: %s", basictypenames[e->type->type]);
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, NULL, &st));
break;
}
return st;
}
/*
============
PR_ParseStatement
@ -5960,15 +6056,8 @@ void QCC_PR_ParseStatement (void)
else
patch1 = NULL;
}
else if (!typecmp( e->type, type_string) && flag_ifstring) //special case, as strings are now pointers, not offsets from string table
{
QCC_PR_ParseWarning(WARN_IFSTRING_USED, "while(string) can result in bizzare behaviour");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, 0, &patch1));
}
else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F]))) //special case, as negative 0 is also zero
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch1));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch1));
patch1 = QCC_Generate_OP_IFNOT(e);
}
QCC_PR_Expect (")"); //after the line number is noted..
QCC_PR_ParseStatement ();
@ -6111,16 +6200,7 @@ void QCC_PR_ParseStatement (void)
}
else
{
if (!typecmp( e->type, type_string) && flag_ifstring)
{
QCC_PR_ParseWarning(WARN_IFSTRING_USED, "do {} while(string) can result in bizzare behaviour");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_S], e, NULL, &patch2));
}
else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, NULL, &patch2));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, NULL, &patch2));
patch2 = QCC_Generate_OP_IF(e);
patch2->b = patch1 - patch2;
}
@ -6205,27 +6285,11 @@ void QCC_PR_ParseStatement (void)
if (negate)
{
if (!typecmp( e->type, type_string) && flag_ifstring)
{
QCC_PR_ParseWarning(WARN_IFSTRING_USED, "if not(string) can result in bizzare behaviour");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_S], e, 0, &patch1));
}
else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_F], e, 0, &patch1));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IF_I], e, 0, &patch1));
patch1 = QCC_Generate_OP_IF(e);
}
else
{
if (!typecmp( e->type, type_string) && flag_ifstring)
{
QCC_PR_ParseWarning(WARN_IFSTRING_USED, "if (string) can result in bizzare behaviour");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, 0, &patch1));
}
else if (!typecmp( e->type, type_float) && (flag_iffloat||QCC_OPCodeValid(&pr_opcodes[OP_IFNOT_F])))
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch1));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch1));
patch1 = QCC_Generate_OP_IFNOT(e);
}
QCC_PR_Expect (")"); //close bracket is after we save the statement to mem (so debugger does not show the if statement as being on the line after
@ -6487,12 +6551,7 @@ void QCC_PR_ParseStatement (void)
}
else
{
if (e->type->type == ev_string)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_S], e, 0, &patch3));
else if (e->type->type == ev_float)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_F], e, 0, &patch3));
else
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_IFNOT_I], e, 0, &patch3));
patch3 = QCC_Generate_OP_IFNOT(e);
}
patch3->b = &statements[pr_cases[i]] - patch3;
}
@ -9017,7 +9076,8 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
}
}
if (!pr_scope || def->constant)
tmp->references++;
if (!pr_scope || def->constant || def->isstatic)
{
if (!tmp->constant)
QCC_PR_ParseErrorPrintDef (ERR_BADIMMEDIATETYPE, def, "initializer is not constant");

View file

@ -1446,7 +1446,7 @@ void QCC_PR_LexString (void)
}
}
if (len)
QCC_PR_ParseWarning(WARN_NOTUTF8, "String constant is not valid utf-8\n");
QCC_PR_ParseWarning(WARN_NOTUTF8, "String constant is not valid utf-8");
}
return;
}

View file

@ -887,6 +887,8 @@ void EditorReload(editor_t *editor)
QCC_ReadFile(editor->filename, file, flen);
file[flen] = 0;
}
else
file = NULL;
SendMessage(editor->editpane, EM_SETEVENTMASK, 0, 0);
@ -894,15 +896,18 @@ void EditorReload(editor_t *editor)
Edit_SetSel(editor->editpane,0,Edit_GetTextLength(editor->editpane));
Edit_ReplaceSel(editor->editpane,"");
if (!fl_autohighlight)
if (file)
{
GUIPrint(editor->editpane, file);
if (!fl_autohighlight)
{
GUIPrint(editor->editpane, file);
}
else
{
GUIFormattingPrint(editor->editpane, file);
}
free(file);
}
else
{
GUIFormattingPrint(editor->editpane, file);
}
free(file);
editor->modified = false;
stat(editor->filename, &sbuf);
@ -1888,16 +1893,7 @@ int GUIprintf(const char *msg, ...)
return 0;
}
if (strstr(buf, "warning: "))
{
if (outstatus < 1)
{
TreeView_SetBkColor(projecttree, RGB(255, 255, 0));
outstatus = 1;
}
col = RGB(128, 128, 0);
}
else if (strstr(buf, "error: "))
if (strstr(buf, ": error"))
{
if (outstatus < 2)
{
@ -1906,6 +1902,15 @@ int GUIprintf(const char *msg, ...)
}
col = RGB(255, 0, 0);
}
else if (strstr(buf, ": warning"))
{
if (outstatus < 1)
{
TreeView_SetBkColor(projecttree, RGB(255, 255, 0));
outstatus = 1;
}
col = RGB(128, 128, 0);
}
else
col = RGB(0, 0, 0);

View file

@ -77,23 +77,16 @@ int numfielddefs;
//typedef char PATHSTRING[MAX_DATA_PATH];
PATHSTRING *precache_sounds;
int *precache_sounds_block;
int *precache_sounds_used;
precache_t *precache_sound;
int numsounds;
PATHSTRING *precache_textures;
int *precache_textures_block;
int *precache_textures_block;
precache_t *precache_texture;
int numtextures;
PATHSTRING *precache_models;
int *precache_models_block;
int *precache_models_used;
precache_t *precache_model;
int nummodels;
PATHSTRING *precache_files;
int *precache_files_block;
precache_t *precache_file;
int numfiles;
extern int numCompilerConstants;
@ -988,10 +981,10 @@ pbool QCC_WriteData (int crc)
for (i = 0; i < nummodels; i++)
{
if (!precache_models_used[i])
QCC_PR_Warning(WARN_EXTRAPRECACHE, NULL, 0, "Model %s was precached but not directly used", precache_models[i]);
else if (!precache_models_block[i])
QCC_PR_Warning(WARN_NOTPRECACHED, NULL, 0, "Model %s was used but not precached", precache_models[i]);
if (!precache_model[i].used)
QCC_PR_Warning(WARN_EXTRAPRECACHE, precache_model[i].filename, precache_model[i].fileline, "Model %s was precached but not directly used", precache_model[i].name);
else if (!precache_model[i].block)
QCC_PR_Warning(WARN_NOTPRECACHED, precache_model[i].filename, precache_model[i].fileline, "Model %s was used but not precached", precache_model[i].name);
}
//PrintStrings ();
//PrintFunctions ();
@ -2438,33 +2431,33 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir)
for (i=0 ; i<numsounds ; i++)
{
if (precache_sounds_block[i] != blocknum)
if (precache_sound[i].block != blocknum)
continue;
sprintf (srcfile,"%s%s",srcdir, precache_sounds[i]);
sprintf (destfile,"%s%s",destdir, precache_sounds[i]);
sprintf (srcfile,"%s%s",srcdir, precache_sound[i].name);
sprintf (destfile,"%s%s",destdir, precache_sound[i].name);
if (copytype == 1)
QCC_CopyFile (srcfile, destfile);
else
QCC_PackFile (srcfile, precache_sounds[i]);
QCC_PackFile (srcfile, precache_sound[i].name);
}
for (i=0 ; i<nummodels ; i++)
{
if (precache_models_block[i] != blocknum)
if (precache_model[i].block != blocknum)
continue;
sprintf (srcfile,"%s%s",srcdir, precache_models[i]);
sprintf (destfile,"%s%s",destdir, precache_models[i]);
sprintf (srcfile,"%s%s",srcdir, precache_model[i].name);
sprintf (destfile,"%s%s",destdir, precache_model[i].name);
if (copytype == 1)
QCC_CopyFile (srcfile, destfile);
else
QCC_PackFile (srcfile, precache_models[i]);
QCC_PackFile (srcfile, precache_model[i].name);
}
for (i=0 ; i<numtextures ; i++)
{
if (precache_textures_block[i] != blocknum)
if (precache_texture[i].block != blocknum)
continue;
{
sprintf (name, "%s", precache_textures[i]);
sprintf (name, "%s", precache_texture[i].name);
sprintf (srcfile,"%s%s",srcdir, name);
sprintf (destfile,"%s%s",destdir, name);
if (copytype == 1)
@ -2473,7 +2466,7 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir)
QCC_PackFile (srcfile, name);
}
{
sprintf (name, "%s.bmp", precache_textures[i]);
sprintf (name, "%s.bmp", precache_texture[i].name);
sprintf (srcfile,"%s%s",srcdir, name);
sprintf (destfile,"%s%s",destdir, name);
if (copytype == 1)
@ -2482,7 +2475,7 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir)
QCC_PackFile (srcfile, name);
}
{
sprintf (name, "%s.tga", precache_textures[i]);
sprintf (name, "%s.tga", precache_texture[i].name);
sprintf (srcfile,"%s%s",srcdir, name);
sprintf (destfile,"%s%s",destdir, name);
if (copytype == 1)
@ -2493,14 +2486,14 @@ void _QCC_CopyFiles (int blocknum, int copytype, char *srcdir, char *destdir)
}
for (i=0 ; i<numfiles ; i++)
{
if (precache_files_block[i] != blocknum)
if (precache_file[i].block != blocknum)
continue;
sprintf (srcfile,"%s%s",srcdir, precache_files[i]);
sprintf (destfile,"%s%s",destdir, precache_files[i]);
sprintf (srcfile,"%s%s",srcdir, precache_file[i].name);
sprintf (destfile,"%s%s",destdir, precache_file[i].name);
if (copytype == 1)
QCC_CopyFile (srcfile, destfile);
else
QCC_PackFile (srcfile, precache_files[i]);
QCC_PackFile (srcfile, precache_file[i].name);
}
if (copytype == 2)
@ -3155,22 +3148,13 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
precache_sounds = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_SOUNDS);
precache_sounds_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_SOUNDS);
precache_sounds_used = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_SOUNDS);
precache_sound = (void *)qccHunkAlloc(sizeof(*precache_sound)*QCC_MAX_SOUNDS);
numsounds=0;
precache_textures = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_TEXTURES);
precache_textures_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_TEXTURES);
precache_texture = (void *)qccHunkAlloc(sizeof(*precache_texture)*QCC_MAX_TEXTURES);
numtextures=0;
precache_models = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_MODELS);
precache_models_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_MODELS);
precache_models_used = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_MODELS);
precache_model = (void *)qccHunkAlloc(sizeof(*precache_model)*QCC_MAX_MODELS);
nummodels=0;
precache_files = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_FILES);
precache_files_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_FILES);
precache_file = (void *)qccHunkAlloc(sizeof(*precache_file)*QCC_MAX_FILES);
numfiles = 0;
qcc_typeinfo = (void *)qccHunkAlloc(sizeof(QCC_type_t)*maxtypeinfos);

View file

@ -1877,7 +1877,7 @@ void NPP_QWWriteShort(int dest, short data) //replacement write func (nq to qw)
qbyte b[2];
short s;
} u;
if (bufferlen == 2 && majortype == svc_temp_entity)
if (bufferlen == 2 && majortype == svc_temp_entity && (minortype == TE_LIGHTNING1 || minortype == TE_LIGHTNING2 || minortype == TE_LIGHTNING3))
NPP_QWWriteEntity(dest, data);
else
{

View file

@ -2894,6 +2894,7 @@ void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuat
{
int i, soundnum, j;
sizebuf_t *buf[3] = {&sv.signon, &sv.nqmulticast, &sv.multicast};
sizebuf_t *msg;
// check to see if samp was properly precached
for (soundnum=1 ; *sv.strings.sound_precache[soundnum] ; soundnum++)
@ -2913,13 +2914,16 @@ void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuat
for (j = 0; j < 3; j++)
{
msg = buf[j];
if (sv.state == ss_loading && j)
break;
// add an svc_spawnambient command to the level signon packet
MSG_WriteByte (buf[j],svc_spawnstaticsound);
MSG_WriteByte (msg,svc_spawnstaticsound);
for (i=0 ; i<3 ; i++)
MSG_WriteCoord(buf[j], pos[i]);
MSG_WriteByte (buf[j], soundnum);
MSG_WriteByte (buf[j], vol*255);
MSG_WriteByte (buf[j], attenuation*64);
MSG_WriteCoord(msg, pos[i]);
MSG_WriteByte (msg, soundnum);
MSG_WriteByte (msg, vol*255);
MSG_WriteByte (msg, attenuation*64);
}
SV_Multicast(pos, MULTICAST_ALL_R);
}
@ -2978,10 +2982,14 @@ static void QCBUILTIN PF_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_
flags = G_FLOAT(OFS_PARM5);
if (channel < 0)
channel = 0;
channel &= 7;
}
else
{
//QW uses channel&8 to mean reliable.
flags = (channel & 8)?1:0;
//demangle it so the upper bits are still useful.
channel = (channel & 7) | ((channel & 0x1f0) >> 1);
}
if (volume < 0) //erm...
return;
@ -2990,8 +2998,9 @@ static void QCBUILTIN PF_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_
volume = 255;
if (flags & 1)
channel |= 8;
channel |= 256;
//shift the reliable flag to 256 instead.
SVQ1_StartSound ((wedict_t*)entity, channel, sample, volume, attenuation, pitchadj);
}
@ -8721,6 +8730,100 @@ static void QCBUILTIN PF_SendPacket(pubprogfuncs_t *prinst, struct globalvars_s
#endif
BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"fixme", PF_Fixme, 0, 0, 0, 0, "void()"},
#ifndef SERVERONLY
//begin menu-only 'standard'
{"checkextension", PF_Fixme, 0, 0, 0, 1, "float(string ext)"},
{"error", PF_Fixme, 0, 0, 0, 2, "void(string err,...)"},
{"objerror", PF_Fixme, 0, 0, 0, 3, "void(string err,...)"},
{"print", PF_Fixme, 0, 0, 0, 4, "void(string text,...)"},
{"bprint", PF_Fixme, 0, 0, 0, 5, "void(string text,...)"},
{"msprint", PF_Fixme, 0, 0, 0, 6, "void(float clientnum, string text,...)"},
{"cprint", PF_Fixme, 0, 0, 0, 7, "void(string text,...)"},
{"normalize", PF_Fixme, 0, 0, 0, 8, "vector(vector)"},
{"vlen", PF_Fixme, 0, 0, 0, 9, "float(vector)"},
{"vectoyaw", PF_Fixme, 0, 0, 0, 10, "float(vector)"},
{"vectoangles", PF_Fixme, 0, 0, 0, 11, "vector(vector)"},
{"random", PF_Fixme, 0, 0, 0, 12, "float()"},
{"localcmd", PF_Fixme, 0, 0, 0, 13, "void(string)"},
{"cvar", PF_Fixme, 0, 0, 0, 14, "float(string name)"},
{"cvar_set", PF_Fixme, 0, 0, 0, 15, "void(string name, string value)"},
{"dprint", PF_Fixme, 0, 0, 0, 16, "void(string text)"},
{"ftos", PF_Fixme, 0, 0, 0, 17, "string(float)"},
{"fabs", PF_Fixme, 0, 0, 0, 18, "float(float)"},
{"vtos", PF_Fixme, 0, 0, 0, 19, "string(vector)"},
{"etos", PF_Fixme, 0, 0, 0, 20, "string(entity)"},
{"stof", PF_Fixme, 0, 0, 0, 21, "float(string)"},
{"spawn", PF_Fixme, 0, 0, 0, 22, "entity()"},
{"remove", PF_Fixme, 0, 0, 0, 23, "void(entity)"},
{"find", PF_Fixme, 0, 0, 0, 24, "entity(entity start, .string field, string match)"},
{"findfloat", PF_Fixme, 0, 0, 0, 25, "entity(entity start, .__variant field, __variant match)"},
{"findchain", PF_Fixme, 0, 0, 0, 26, "entity(.string field, string match)"},
{"findchainfloat", PF_Fixme, 0, 0, 0, 27, "entity(.__variant field, __variant match)"},
{"precache_file", PF_Fixme, 0, 0, 0, 28, "string(string file)"},
{"precache_sound", PF_Fixme, 0, 0, 0, 29, "string(string sample)"},
{"coredump", PF_Fixme, 0, 0, 0, 30, "void()"},
{"traceon", PF_Fixme, 0, 0, 0, 31, "void()"},
{"traceoff", PF_Fixme, 0, 0, 0, 32, "void()"},
{"eprint", PF_Fixme, 0, 0, 0, 33, "void(entity)"},
{"rint", PF_Fixme, 0, 0, 0, 34, "float(float)"},
{"floor", PF_Fixme, 0, 0, 0, 35, "float(float)"},
{"ceil", PF_Fixme, 0, 0, 0, 36, "float(float)"},
{"nextent", PF_Fixme, 0, 0, 0, 37, "entity(entity)"},
{"sin", PF_Fixme, 0, 0, 0, 38, "float(float)"},
{"cos", PF_Fixme, 0, 0, 0, 39, "float(float)"},
{"sqrt", PF_Fixme, 0, 0, 0, 40, "float(float)"},
{"randomvector", PF_Fixme, 0, 0, 0, 41, "vector()"},
{"registercvar", PF_Fixme, 0, 0, 0, 42, "float(string name, string value, float flags)"},
{"min", PF_Fixme, 0, 0, 0, 43, "float(float,...)"},
{"max", PF_Fixme, 0, 0, 0, 44, "float(float,...)"},
{"bound", PF_Fixme, 0, 0, 0, 45, "float(float min,float value,float max)"},
{"pow", PF_Fixme, 0, 0, 0, 46, "float(float,float)"},
{"copyentity", PF_Fixme, 0, 0, 0, 47, "void(entity src, entity dst)"},
{"fopen", PF_Fixme, 0, 0, 0, 48, "float(string filename, float mode)"},
{"fclose", PF_Fixme, 0, 0, 0, 49, "void(float fhandle)"},
{"fgets", PF_Fixme, 0, 0, 0, 50, "string(float fhandle)"},
{"fputs", PF_Fixme, 0, 0, 0, 51, "void(float fhandle, string s)"},
{"strlen", PF_Fixme, 0, 0, 0, 52, "float(string)"},
{"strcat", PF_Fixme, 0, 0, 0, 53, "string(string, optional string, optional string, optional string, optional string, optional string, optional string, optional string)"},
{"substring", PF_Fixme, 0, 0, 0, 54, "string(string s, float start, float length)"},
{"stov", PF_Fixme, 0, 0, 0, 55, "vector(string)"},
{"strzone", PF_Fixme, 0, 0, 0, 56, "string(string)"},
{"strunzone", PF_Fixme, 0, 0, 0, 57, "void(string)"},
{"tokenize", PF_Fixme, 0, 0, 0, 58, "float(string)"},
{"argv", PF_Fixme, 0, 0, 0, 59, "string(float)"},
{"isserver", PF_Fixme, 0, 0, 0, 60, "float()"},
{"clientcount", PF_Fixme, 0, 0, 0, 61, "float()"},
{"clientstate", PF_Fixme, 0, 0, 0, 62, "float()"},
{"clientcommand", PF_Fixme, 0, 0, 0, 63, "void(float client, string s)"},
{"changelevel", PF_Fixme, 0, 0, 0, 64, "void(string map)"},
{"localsound", PF_Fixme, 0, 0, 0, 65, "void(string sample)"},
{"getmousepos", PF_Fixme, 0, 0, 0, 66, "vector()"},
{"gettime", PF_Fixme, 0, 0, 0, 67, "float()"},
{"loadfromdata", PF_Fixme, 0, 0, 0, 68, "void(string data)"},
{"loadfromfile", PF_Fixme, 0, 0, 0, 69, "void(string data)"},
{"mod", PF_Fixme, 0, 0, 0, 70, "float(float val, float m)"},
{"cvar_string", PF_Fixme, 0, 0, 0, 71, "string(string name)"},
{"crash", PF_Fixme, 0, 0, 0, 72, "void()"},
{"stackdump", PF_Fixme, 0, 0, 0, 73, "void()"},
{"search_begin", PF_Fixme, 0, 0, 0, 74, "float(string pattern, float caseinsensitive, float quiet)"},
{"search_end", PF_Fixme, 0, 0, 0, 75, "void(float handle)"},
{"search_getsize", PF_Fixme, 0, 0, 0, 76, "float(float handle)"},
{"search_getfilename",PF_Fixme, 0, 0, 0, 77, "string(float handle, float num)"},
{"etof", PF_Fixme, 0, 0, 0, 79, "float(entity)"},
{"ftoe", PF_Fixme, 0, 0, 0, 80, "entity(float)"},
{"validstring", PF_Fixme, 0, 0, 0, 81, "float(string)"},
{"altstr_count", PF_Fixme, 0, 0, 0, 82, "float(string str)"},
{"altstr_prepare", PF_Fixme, 0, 0, 0, 83, "string(string str)"},
{"altstr_get", PF_Fixme, 0, 0, 0, 84, "string(string str, float num)"},
{"altstr_set", PF_Fixme, 0, 0, 0, 85, "string(string str, float num, string set) "},
{"altstr_ins", PF_Fixme, 0, 0, 0, 86, "string(string str, float num, string set)"},
{"findflags", PF_Fixme, 0, 0, 0, 87, "entity(entity start, .float field, float match)"},
{"findchainflags", PF_Fixme, 0, 0, 0, 88, "entity(.float field, float match)"},
{"mcvar_defstring", PF_Fixme, 0, 0, 0, 89, "string(string name) " STUB},
//end menu-only 'standard'
#endif
//nq qw h2 ebfs
{"ignore", PF_Ignore, 0, 0, 0, 0, "void()"},
{"makevectors", PF_makevectors, 1, 1, 1, 0, "void(vector vang)"},
{"setorigin", PF_setorigin, 2, 2, 2, 0, "void(entity e, vector o)"},
@ -9117,7 +9220,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
//2d (immediate) operations
{"drawline", PF_Fixme, 0, 0, 0, 315, "void(float width, vector pos1, vector pos2)"},// (EXT_CSQC)
{"iscachedpic", PF_Fixme, 0, 0, 0, 316, "float(string name)"},// (EXT_CSQC)
{"precache_pic", PF_Fixme, 0, 0, 0, 317, "string(string name, float trywad)"},// (EXT_CSQC)
{"precache_pic", PF_Fixme, 0, 0, 0, 317, "string(string name, optional float trywad)"},// (EXT_CSQC)
{"draw_getimagesize",PF_Fixme, 0, 0, 0, 318, "vector(string picname)"},// (EXT_CSQC)
{"freepic", PF_Fixme, 0, 0, 0, 319, "void(string name)"},// (EXT_CSQC)
//320
@ -9208,7 +9311,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
//DP_QC_COPYENTITY
{"copyentity", PF_copyentity, 0, 0, 0, 400, "void(entity from, entity to)"},// (DP_QC_COPYENTITY)
//DP_SV_SETCOLOR
{"setcolors", PF_setcolors, 0, 0, 0, 401, "void(entity from, entity to)"},//
{"setcolors", PF_setcolors, 0, 0, 0, 401, "void(entity from, entity to)"},//DP_SV_SETCOLOR
//DP_QC_FINDCHAIN
{"findchain", PF_sv_findchain, 0, 0, 0, 402, "entity(.string field, string match)"},// (DP_QC_FINDCHAIN)
//DP_QC_FINDCHAINFLOAT
@ -9262,6 +9365,41 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437, "string(entity e, float s)"},// (DP_QC_GETSURFACE)
{"getsurfacenearpoint",PF_getsurfacenearpoint,0,0, 0, 438, "float(entity e, vector p)"},// (DP_QC_GETSURFACE)
{"getsurfaceclippedpoint",PF_getsurfaceclippedpoint,0,0,0, 439, "vector(entity e, float s, vector p)" STUB},// (DP_QC_GETSURFACE)
#ifndef SERVERONLY
//begin menu-only
{"buf_create", PF_Fixme, 0, 0, 0, 440, "float()"},//DP_QC_STRINGBUFFERS
{"buf_del", PF_Fixme, 0, 0, 0, 441, "void(float bufhandle)"},//DP_QC_STRINGBUFFERS
{"buf_getsize", PF_Fixme, 0, 0, 0, 442, "float(float bufhandle)"},//DP_QC_STRINGBUFFERS
{"buf_copy", PF_Fixme, 0, 0, 0, 443, "void(float bufhandle_from, float bufhandle_to)"},//DP_QC_STRINGBUFFERS
{"buf_sort", PF_Fixme, 0, 0, 0, 444, "void(float bufhandle, float sortpower, float backward)"},//DP_QC_STRINGBUFFERS
{"buf_implode", PF_Fixme, 0, 0, 0, 445, "string(float bufhandle, string glue)"},//DP_QC_STRINGBUFFERS
{"bufstr_get", PF_Fixme, 0, 0, 0, 446, "string(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
{"bufstr_set", PF_Fixme, 0, 0, 0, 447, "void(float bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS
{"bufstr_add", PF_Fixme, 0, 0, 0, 448, "float(float bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS
{"bufstr_free", PF_Fixme, 0, 0, 0, 449, "void(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
{"iscachedpic", PF_Fixme, 0, 0, 0, 451, "float(string name)"},// (EXT_CSQC)
{"precache_pic", PF_Fixme, 0, 0, 0, 452, "string(string name, optional float trywad)"},// (EXT_CSQC)
{"freepic", PF_Fixme, 0, 0, 0, 453, "void(string name)"},// (EXT_CSQC)
{"drawcharacter", PF_Fixme, 0, 0, 0, 454, "float(vector position, float character, vector scale, vector rgb, float alpha, optional float flag)"},// (EXT_CSQC, [EXT_CSQC_???])
{"drawrawstring", PF_Fixme, 0, 0, 0, 455, "float(vector position, string text, vector scale, vector rgb, float alpha, optional float flag)"},// (EXT_CSQC, [EXT_CSQC_???])
{"drawpic", PF_Fixme, 0, 0, 0, 456, "float(vector position, string pic, vector size, vector rgb, float alpha, optional float flag)"},// (EXT_CSQC, [EXT_CSQC_???])
{"drawfill", PF_Fixme, 0, 0, 0, 457, "float(vector position, vector size, vector rgb, float alpha, optional float flag)"},// (EXT_CSQC, [EXT_CSQC_???])
{"drawsetcliparea", PF_Fixme, 0, 0, 0, 458, "void(float x, float y, float width, float height)"},// (EXT_CSQC_???)
{"drawresetcliparea",PF_Fixme, 0, 0, 0, 459, "void(void)"},// (EXT_CSQC_???)
{"drawgetimagesize",PF_Fixme, 0, 0, 0, 460, "vector(string picname)"},// (EXT_CSQC)
{"cin_open", PF_Fixme, 0, 0, 0, 461, "float(string file, string id)" STUB},
{"cin_close", PF_Fixme, 0, 0, 0, 462, "void(string id)" STUB},
{"cin_setstate", PF_Fixme, 0, 0, 0, 463, "void(string id, float newstate)" STUB},
{"cin_getstate", PF_Fixme, 0, 0, 0, 464, "float(string id)" STUB},
{"cin_restart", PF_Fixme, 0, 0, 0, 465, "void(string file)" STUB},
{"drawline", PF_Fixme, 0, 0, 0, 466, "void(float width, vector pos1, vector pos2)"},// (EXT_CSQC)
{"drawstring", PF_Fixme, 0, 0, 0, 467, "float(vector position, string text, vector scale, vector rgb, float alpha, float flag)"},// #326
{"stringwidth", PF_Fixme, 0, 0, 0, 468, "float(string text, float usecolours, optional vector fontsize)"},// EXT_CSQC_'DARKPLACES'
{"drawsubpic", PF_Fixme, 0, 0, 0, 469, "void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, float flag)"},// #328 EXT_CSQC_'DARKPLACES'
//end menu-only
#endif
//begin non-menu
{"clientcommand", PF_clientcommand, 0, 0, 0, 440, "void(entity e, string s)"},// (KRIMZON_SV_PARSECLIENTCOMMAND)
{"tokenize", PF_Tokenize, 0, 0, 0, 441, "float(string s)"},// (KRIMZON_SV_PARSECLIENTCOMMAND)
{"argv", PF_ArgV, 0, 0, 0, 442, "string(float n)"},// (KRIMZON_SV_PARSECLIENTCOMMAND
@ -9292,6 +9430,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"bufstr_set", PF_bufstr_set, 0, 0, 0, 467, "void(float bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS
{"bufstr_add", PF_bufstr_add, 0, 0, 0, 468, "float(float bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS
{"bufstr_free", PF_bufstr_free, 0, 0, 0, 469, "void(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
//end non-menu
// {"undefined", PF_Fixme, 0, 0, 0, 470, ""},
//MENU VM BUILTINS SHARE THE BELOW BUILTINS
{"asin", PF_asin, 0, 0, 0, 471, "float(float s)"},//DP_QC_ASINACOSATANATAN2TAN
@ -9344,8 +9484,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"buf_cvarlist", PF_buf_cvarlist, 0, 0, 0, 517, "void(float strbuf)" STUB},
{"cvar_description",PF_cvar_description,0, 0, 0, 518, "string(string cvarname)"},
{"gettime", PF_Fixme, 0, 0, 0, 519, "float(optional float timetype)"},
// {"keynumtostring", PF_Fixme, 0, 0, 0, 520, "string(float keynum)"},
// {"findkeysforcommand",PF_Fixme, 0, 0, 0, 521, "string(string command, optional float bindmap)"},
{"keynumtostring", PF_Fixme, 0, 0, 0, 520, "string(float keynum)"},
{"findkeysforcommand",PF_Fixme, 0, 0, 0, 521, "string(string command, optional float bindmap)"},
// {"initparticlespawner",PF_Fixme, 0, 0, 0, 522, "void(float max_themes)"},
// {"resetparticle", PF_Fixme, 0, 0, 0, 523, "void()"},
// {"particletheme", PF_Fixme, 0, 0, 0, 524, "void(float theme)"},
@ -9373,31 +9513,31 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB},
{"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB},
// {"setkeydest", PF_Fixme, 0, 0, 0, 601, "void(float dest)"},
// {"getkeydest", PF_Fixme, 0, 0, 0, 602, "float()"},
// {"setmousetarget", PF_Fixme, 0, 0, 0, 603, "void(float trg)"},
// {"getmousetarget", PF_Fixme, 0, 0, 0, 604, "float()"},
{"setkeydest", PF_Fixme, 0, 0, 0, 601, "void(float dest)"},
{"getkeydest", PF_Fixme, 0, 0, 0, 602, "float()"},
{"setmousetarget", PF_Fixme, 0, 0, 0, 603, "void(float trg)"},
{"getmousetarget", PF_Fixme, 0, 0, 0, 604, "float()"},
{"callfunction", PF_callfunction, 0, 0, 0, 605, "void(.../*, string funcname*/)"},
{"writetofile", PF_writetofile, 0, 0, 0, 606, "void(float fh, entity e)"},
{"isfunction", PF_isfunction, 0, 0, 0, 607, "float(string s)"},
// {"getresolution", PF_Fixme, 0, 0, 0, 608, "vector(float number, optional float forfullscreen)"},
// {"keynumtostring", PF_Fixme, 0, 0, 0, 609, "string(float keynum)"},
// {"findkeysforcommand",PF_Fixme, 0, 0, 0, 610, "string()"},
// {"gethostcachevalue",PF_Fixme, 0, 0, 0, 611, "float(float type)"},
// {"gethostcachestring",PF_Fixme, 0, 0, 0, 612, "string(float type, float hostnr)"},
{"getresolution", PF_Fixme, 0, 0, 0, 608, "vector(float vidmode, optional float forfullscreen)"},
{"keynumtostring", PF_Fixme, 0, 0, 0, 609, "string(float keynum)"},
{"findkeysforcommand",PF_Fixme, 0, 0, 0, 610, "string(string command, optional float bindmap)"},
{"gethostcachevalue",PF_Fixme, 0, 0, 0, 611, "float(float type)"},
{"gethostcachestring",PF_Fixme, 0, 0, 0, 612, "string(float type, float hostnr)"},
{"parseentitydata", PF_parseentitydata, 0, 0, 0, 613, "void(entity e, string s)"},
// {"stringtokeynum", PF_Fixme, 0, 0, 0, 614, "float(string key)"},
// {"resethostcachemasks",PF_Fixme, 0, 0, 0, 615, "void()"},
// {"sethostcachemaskstring",PF_Fixme, 0, 0, 0, 616, "void(float mask, float fld, string str, float op)"},
// {"sethostcachemasknumber",PF_Fixme, 0, 0, 0, 617, "void(float mask, float fld, float num, float op)"},
// {"resorthostcache", PF_Fixme, 0, 0, 0, 618, "void()"},
// {"sethostcachesort",PF_Fixme, 0, 0, 0, 619, "void(float fld, float descending)"},
// {"refreshhostcache",PF_Fixme, 0, 0, 0, 620, "void()"},
// {"gethostcachenumber",PF_Fixme, 0, 0, 0, 621, "float(float fld, float hostnr)"},
// {"gethostcacheindexforkey",PF_Fixme, 0, 0, 0, 622, "float(string key)"},
// {"addwantedhostcachekey",PF_Fixme, 0, 0, 0, 623, "void(string key)"},
// {"getextresponse", PF_Fixme, 0, 0, 0, 624, "string()"},
// {"netaddress_resolve",PF_Fixme, 0, 0, 0, 625, "string(string, float)"},
{"stringtokeynum", PF_Fixme, 0, 0, 0, 614, "float(string key)"},
{"resethostcachemasks",PF_Fixme, 0, 0, 0, 615, "void()"},
{"sethostcachemaskstring",PF_Fixme, 0, 0, 0, 616, "void(float mask, float fld, string str, float op)"},
{"sethostcachemasknumber",PF_Fixme, 0, 0, 0, 617, "void(float mask, float fld, float num, float op)"},
{"resorthostcache", PF_Fixme, 0, 0, 0, 618, "void()"},
{"sethostcachesort",PF_Fixme, 0, 0, 0, 619, "void(float fld, float descending)"},
{"refreshhostcache",PF_Fixme, 0, 0, 0, 620, "void()"},
{"gethostcachenumber",PF_Fixme, 0, 0, 0, 621, "float(float fld, float hostnr)"},
{"gethostcacheindexforkey",PF_Fixme, 0, 0, 0, 622, "float(string key)"},
{"addwantedhostcachekey",PF_Fixme, 0, 0, 0, 623, "void(string key)"},
{"getextresponse", PF_Fixme, 0, 0, 0, 624, "string()"},
{"netaddress_resolve",PF_Fixme, 0, 0, 0, 625, "string(string, float)"},
// {"getgamedirinfo", PF_Fixme, 0, 0, 0, 626, "string(float n, float prop)"},
{"sprintf", PF_sprintf, 0, 0, 0, 627, "string(string fmt, ...)"},
{"getsurfacenumtriangles",PF_getsurfacenumtriangles,0,0,0, 628, "float(entity e, float s)"},
@ -9405,15 +9545,15 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
// {"setkeybind", PF_Fixme, 0, 0, 0, 630, "float(float key, string bind, optional float bindmap)"},
// {"getbindmaps", PF_Fixme, 0, 0, 0, 631, "vector()"},
// {"setbindmaps", PF_Fixme, 0, 0, 0, 632, "float(vector bm)"},
// {"crypto_getkeyfp", PF_Fixme, 0, 0, 0, 633, "string(string addr)"},
// {"crypto_getidfp", PF_Fixme, 0, 0, 0, 634, "string(string addr)"},
// {"crypto_getencryptlevel",PF_Fixme, 0, 0, 0, 635, "string(string addr)"},
// {"crypto_getmykeyfp",PF_Fixme, 0, 0, 0, 636, "string(string addr)"},
// {"crypto_getmyidfp",PF_Fixme, 0, 0, 0, 637, "string(float addr)"},
{"crypto_getkeyfp", PF_Fixme, 0, 0, 0, 633, "string(string addr)" STUB},
{"crypto_getidfp", PF_Fixme, 0, 0, 0, 634, "string(string addr)" STUB},
{"crypto_getencryptlevel",PF_Fixme, 0, 0, 0, 635, "string(string addr)" STUB},
{"crypto_getmykeyfp",PF_Fixme, 0, 0, 0, 636, "string(string addr)" STUB},
{"crypto_getmyidfp",PF_Fixme, 0, 0, 0, 637, "string(float addr)" STUB},
// {"VM_CL_RotateMoves",PF_Fixme, 0, 0, 0, 638, ""},
{"digest_hex", PF_digest_hex, 0, 0, 0, 639, "string(string digest, string data, ...)"},
// {"V_CalcRefdef", PF_Fixme, 0, 0, 0, 640, "void(entity e)"},
{"crypto_getmyidstatus",PF_Fixme, 0, 0, 0, 641, "float(float i)"},
{"crypto_getmyidstatus",PF_Fixme, 0, 0, 0, 641, "float(float i)" STUB},
//end dp extras
@ -9729,11 +9869,15 @@ svextqcfields
PR_RegisterFieldVar(svprogfuncs, 0, NULL, 0,0);
}
//targets
#define QW 1
#define NQ 2
#define CS 4
#define FTE 8
#define ALL (QW|NQ|CS)
#define MENU 8
#define H2 16
//mere flags
#define FTE 32
#define ALL (QW|NQ|CS|MENU)
#define CORE
typedef struct
{
@ -9745,6 +9889,7 @@ typedef struct
char *valuestr;
qboolean misc;
} knowndef_t;
#include "cl_master.h"
void PR_DumpPlatform_f(void)
{
#ifdef SERVERONLY
@ -9764,7 +9909,7 @@ void PR_DumpPlatform_f(void)
/*this list is here to ensure that the file can be used as a valid initial qc file (ignoring precompiler options)*/
knowndef_t knowndefs[] =
{
{"self", "entity", QW|NQ|CS},
{"self", "entity", QW|NQ|CS|MENU},
{"other", "entity", QW|NQ|CS},
{"world", "entity", QW|NQ|CS},
{"time", "float", QW|NQ|CS},
@ -9812,7 +9957,7 @@ void PR_DumpPlatform_f(void)
{"ClientDisconnect", "void()", QW|NQ},
{"SetNewParms", "void()", QW|NQ},
{"SetChangeParms", "void()", QW|NQ},
{"end_sys_globals", "void", QW|NQ|CS},
{"end_sys_globals", "void", QW|NQ|CS|MENU},
{"modelindex", ".float", QW|NQ|CS},
{"absmin, absmax", ".vector", QW|NQ|CS},
@ -9901,7 +10046,7 @@ void PR_DumpPlatform_f(void)
{"noise1", ".string", QW|NQ},
{"noise2", ".string", QW|NQ},
{"noise3", ".string", QW|NQ},
{"end_sys_fields", "void", QW|NQ|CS},
{"end_sys_fields", "void", QW|NQ|CS|MENU},
#define comfieldfloat(name) {#name, ".float", FL},
#define comfieldvector(name) {#name, ".vector", FL},
@ -9911,7 +10056,7 @@ void PR_DumpPlatform_f(void)
#define FL QW|NQ
comqcfields
#undef FL
#define FL ALL
#define FL QW|NQ|CS
comextqcfields
#undef FL
#define FL QW|NQ
@ -9926,12 +10071,61 @@ void PR_DumpPlatform_f(void)
#undef comfieldstring
#undef comfieldfunction
{"physics_mode", "var float", QW|NQ|CS, 2},
{"gamespeed", "float", CS},
{"drawfont", "float", CS},
{"SpectatorConnect", "noref void()", QW|NQ},
{"SpectatorDisconnect", "noref void()", QW|NQ},
{"SpectatorThink", "noref void()", QW|NQ},
{"SV_ParseClientCommand", "noref void()", QW|NQ},
{"SV_ParseConnectionlessPacket", "noref void()", QW|NQ},
{"SV_PausedTic", "noref void()", QW|NQ},
{"SV_ShouldPause", "noref void()", QW|NQ},
{"ClassChangeWeapon", "noref void()", H2},
{"SV_RunClientCommand", "noref void()", QW|NQ},
{"SV_AddDebugPolygons", "noref void()", QW|NQ},
{"SV_PlayerPhysics", "noref void()", QW|NQ},
{"EndFrame", "noref void()", QW|NQ},
/* //mvdsv compat
{"UserInfo_Changed", "//noref void()", QW},
{"localinfoChanged", "//noref void()", QW},
{"ChatMessage", "//noref void()", QW},
{"UserCmd", "//noref void()", QW},
{"ConsoleCmd", "//noref void()", QW},
*/
{"TRUE", "const float", QW|NQ|CS, 1},
{"FALSE", "const float", QW|NQ|CS, 0},
{"CSQC_Init", "noref void(float apilevel, string enginename, float engineversion)", CS},
{"CSQC_WorldLoaded", "noref void()", CS},
{"CSQC_Shutdown", "noref void()", CS},
{"CSQC_UpdateView", "noref void(float vwidth, float vheight, float notmenu)", CS},
{"CSQC_Parse_StuffCmd", "noref void(string msg)", CS},
{"CSQC_Parse_CenterPrint", "noref float(string msg)", CS},
{"CSQC_Parse_Print", "noref void(string printmsg, float printlvl)", CS},
{"CSQC_InputEvent", "noref float(float evtype, float scanx, float chary, float devid)", CS},
{"CSQC_Input_Frame", "noref void()", CS},
{"CSQC_ConsoleCommand", "noref float(string cmd)", CS},
{"CSQC_ConsoleLink", "noref float(string text, string info)", CS},
{"CSQC_Ent_Update", "noref void()", CS},
{"CSQC_Ent_Remove", "noref void()", CS},
{"CSQC_Event_Sound", "noref float(float entnum, float channel, float soundname, float vol, float attenuation, vector pos, float pitchmod)", CS},
// {"CSQC_ServerSound", "//void()", CS},
{"CSQC_LoadResource", "noref float(string resname, string restype)", CS},
{"CSQC_Parse_TempEntity", "noref void()", CS},
{"GameCommand", "noref void(string cmdtext)", CS|MENU},
{"m_init", "void()", MENU},
{"m_shutdown", "void()", MENU},
{"m_draw", "void()", MENU},
{"m_keydown", "void(float scan, float chr)", MENU},
{"m_keyup", "void(float scan, float chr)", MENU},
{"m_toggle", "void(float mode)", MENU},
{"physics_mode", "var float", QW|NQ|CS, 2},
{"gamespeed", "float", CS},
{"drawfontscale", "var vector", CS|MENU, 0, "'1 1 0'"},
{"drawfont", "float", CS|MENU},
{"FONT_DEFAULT", "const float", CS|MENU, 0},
{"TRUE", "const float", ALL, 1},
{"FALSE", "const float", ALL, 0},
{"MOVETYPE_NONE", "const float", QW|NQ|CS, MOVETYPE_NONE},
{"MOVETYPE_WALK", "const float", QW|NQ|CS, MOVETYPE_WALK},
@ -10014,17 +10208,17 @@ void PR_DumpPlatform_f(void)
{"PVSF_IGNOREPVS", "const float", QW|NQ, PVSF_IGNOREPVS},
{"PVSF_NOREMOVE", "const float", QW|NQ, PVSF_NOREMOVE},
{"INFOKEY_P_IP", "const string", QW|NQ, 0, "ip"},
{"INFOKEY_P_REALIP", "const string", QW|NQ, 0, "realip"},
{"INFOKEY_P_CSQCACTIVE","const string", QW|NQ, 0, "csqcactive"},
{"INFOKEY_P_PING", "const string", QW|NQ, 0, "ping"},
{"INFOKEY_P_SVPING", "const string", QW|NQ, 0, "svping"},
{"INFOKEY_P_GUID", "const string", QW|NQ, 0, "guid"},
{"INFOKEY_P_CHALLENGE", "const string", QW|NQ, 0, "challenge"},
{"INFOKEY_P_USERID", "const string", QW|NQ, 0, "*userid"},
{"INFOKEY_P_DOWNLOADPCT","const string",QW|NQ, 0, "download"},
{"INFOKEY_P_TRUSTLEVEL","const string", QW|NQ, 0, "trustlevel"},
{"INFOKEY_P_PROTOCOL", "const string", QW|NQ, 0, "protocol"},
{"INFOKEY_P_IP", "const string", QW|NQ, 0, "\"ip\""},
{"INFOKEY_P_REALIP", "const string", QW|NQ, 0, "\"realip\""},
{"INFOKEY_P_CSQCACTIVE","const string", QW|NQ, 0, "\"csqcactive\""},
{"INFOKEY_P_PING", "const string", QW|NQ, 0, "\"ping\""},
{"INFOKEY_P_SVPING", "const string", QW|NQ, 0, "\"svping\""},
{"INFOKEY_P_GUID", "const string", QW|NQ, 0, "\"guid\""},
{"INFOKEY_P_CHALLENGE", "const string", QW|NQ, 0, "\"challenge\""},
{"INFOKEY_P_USERID", "const string", QW|NQ, 0, "\"*userid\""},
{"INFOKEY_P_DOWNLOADPCT","const string",QW|NQ, 0, "\"download\""},
{"INFOKEY_P_TRUSTLEVEL","const string", QW|NQ, 0, "\"trustlevel\""},
{"INFOKEY_P_PROTOCOL", "const string", QW|NQ, 0, "\"protocol\""},
// edict.flags
{"FL_FLY", "const float", QW|NQ|CS, FL_FLY},
@ -10137,9 +10331,9 @@ void PR_DumpPlatform_f(void)
{"CLIENTTYPE_BOT", "const float", QW|NQ, CLIENTTYPE_BOT},
{"CLIENTTYPE_NOTACLIENT","const float",QW|NQ, CLIENTTYPE_NOTACLIENT},
{"FILE_READ", "const float", QW|NQ|CS, FRIK_FILE_READ},
{"FILE_APPEND", "const float", QW|NQ|CS, FRIK_FILE_APPEND},
{"FILE_WRITE", "const float", QW|NQ|CS, FRIK_FILE_WRITE},
{"FILE_READ", "const float", ALL, FRIK_FILE_READ},
{"FILE_APPEND", "const float", ALL, FRIK_FILE_APPEND},
{"FILE_WRITE", "const float", ALL, FRIK_FILE_WRITE},
{"FILE_READNL", "const float", QW|NQ|CS, FRIK_FILE_READNL},
{"FILE_MMAP_READ", "const float", QW|NQ|CS, FRIK_FILE_MMAP_READ},
{"FILE_MMAP_RW", "const float", QW|NQ|CS, FRIK_FILE_MMAP_RW},
@ -10188,6 +10382,25 @@ void PR_DumpPlatform_f(void)
{"TEREDIT_MESH_ADD", "const float", CS, ter_mesh_add},
{"TEREDIT_MESH_KILL", "const float", CS, ter_mesh_kill},
{"TEREDIT_TINT", "const float", CS, ter_tint},
{"SLIST_HOSTCACHEVIEWCOUNT", "const float", MENU, SLIST_HOSTCACHEVIEWCOUNT},
{"SLIST_HOSTCACHETOTALCOUNT", "const float", MENU, SLIST_HOSTCACHETOTALCOUNT},
{"SLIST_MASTERQUERYCOUNT", "const float", MENU, SLIST_MASTERQUERYCOUNT},
{"SLIST_MASTERREPLYCOUNT", "const float", MENU, SLIST_MASTERREPLYCOUNT},
{"SLIST_SERVERQUERYCOUNT", "const float", MENU, SLIST_SERVERQUERYCOUNT},
{"SLIST_SERVERREPLYCOUNT", "const float", MENU, SLIST_SERVERREPLYCOUNT},
{"SLIST_SORTFIELD", "const float", MENU, SLIST_SORTFIELD},
{"SLIST_SORTDESCENDING", "const float", MENU, SLIST_SORTDESCENDING},
{"SLIST_TEST_CONTAINS", "const float", MENU, SLIST_TEST_CONTAINS},
{"SLIST_TEST_NOTCONTAIN", "const float", MENU, SLIST_TEST_NOTCONTAIN},
{"SLIST_TEST_LESSEQUAL", "const float", MENU, SLIST_TEST_LESSEQUAL},
{"SLIST_TEST_LESS", "const float", MENU, SLIST_TEST_LESS},
{"SLIST_TEST_EQUAL", "const float", MENU, SLIST_TEST_EQUAL},
{"SLIST_TEST_GREATER", "const float", MENU, SLIST_TEST_GREATER},
{"SLIST_TEST_GREATEREQUAL", "const float", MENU, SLIST_TEST_GREATEREQUAL},
{"SLIST_TEST_NOTEQUAL", "const float", MENU, SLIST_TEST_NOTEQUAL},
{"SLIST_TEST_STARTSWITH", "const float", MENU, SLIST_TEST_STARTSWITH},
{"SLIST_TEST_NOTSTARTSWITH", "const float", MENU, SLIST_TEST_NOTSTARTSWITH},
NULL
};
@ -10202,6 +10415,10 @@ void PR_DumpPlatform_f(void)
targ |= CS;
if (!stricmp(Cmd_Argv(i), "-Tqw"))
targ |= QW;
if (!stricmp(Cmd_Argv(i), "-Tmenu"))
targ |= MENU;
if (!stricmp(Cmd_Argv(i), "-Th2"))
targ |= H2;
if (!stricmp(Cmd_Argv(i), "-Fdefines"))
defines = true;
if (!stricmp(Cmd_Argv(i), "-Fnodefines"))
@ -10210,7 +10427,7 @@ void PR_DumpPlatform_f(void)
fname = Cmd_Argv(++i);
}
if (!(targ & ALL))
targ |= ALL;
targ |= (QW|NQ|CS|MENU);
if (!*fname)
fname = "fteextensions";
@ -10233,6 +10450,7 @@ void PR_DumpPlatform_f(void)
"-Tnq - dump specifically NQ fields\n"
"-Tqw - dump specifically QW fields\n"
"-Tcs - dump specifically CSQC fields\n"
"-Tmenu - dump specifically menuqc fields\n"
"-Fdefines - generate #defines instead of constants\n"
"-O - write to a different qc file\n"
"*/\n"
@ -10243,23 +10461,55 @@ void PR_DumpPlatform_f(void)
VFS_PRINTF(f, "#pragma warning error Q101 /*too many parms*/\n");
VFS_PRINTF(f, "#pragma warning error Q105 /*too few parms*/\n");
VFS_PRINTF(f, "#pragma warning error Q208 /*system crc unknown*/\n");
VFS_PRINTF(f, "#pragma warning enable F301 /*non-utf-8 strings*/\n");
VFS_PRINTF(f, "#pragma warning enable F302 /*uninitialised locals*/\n");
if (targ&FTE)
VFS_PRINTF(f, "#pragma target FTE\n");
if ((targ&ALL) == CS)
VFS_PRINTF(f, "#define CSQC\n");
VFS_PRINTF(f, "#ifndef CSQC\n"
"#define CSQC\n"
"#endif\n"
);
else if ((targ&ALL) == NQ)
VFS_PRINTF(f, "#define NETQUAKE\n"
"#define SSQC\n"
VFS_PRINTF(f, "#ifndef NETQUAKE\n"
"#define NETQUAKE\n"
"#endif\n"
"#ifndef NQSSQC\n"
"#define NQSSQC\n"
"#endif\n"
"#ifndef SSQC\n"
"#define SSQC\n"
"#endif\n"
);
else if ((targ&ALL) == QW)
VFS_PRINTF(f, "#define QUAKEWORLD\n"
"#define SSQC\n"
VFS_PRINTF(f, "#ifndef QUAKEWORLD\n"
"#define QUAKEWORLD\n"
"#endif\n"
"#ifndef QWSSQC\n"
"#define QWSSQC\n"
"#endif\n"
"#ifndef SSQC\n"
"#define SSQC\n"
"#endif\n"
);
else if ((targ&ALL) == MENU)
VFS_PRINTF(f, "#ifndef MENU\n"
"#define MENU\n"
"#endif\n"
);
else
VFS_PRINTF(f, "#if !defined(CSQC) && !defined(SSQC)\n"
VFS_PRINTF(f, "#if !defined(CSQC) && !defined(NQSSQC) && !defined(QWSSQC)&& !defined(MENU)\n"
"#ifdef QUAKEWORLD\n"
"#define QWSSQC\n"
"#else\n"
"#define NQSSQC\n"
"#endif\n"
"#endif\n"
"#if !defined(SSQC) && (defined(QWSSQC) || defined(NQSSQC))\n"
"#define SSQC\n"
"#endif\n");
"#endif\n"
);
for (i = 0; knowndefs[i].name; i++)
{
@ -10270,43 +10520,70 @@ void PR_DumpPlatform_f(void)
}
}
d = ALL;
d = ALL & ~targ;
for (i = 0; knowndefs[i].name; i++)
{
nd = (knowndefs[i].module & targ) | (~targ & ALL);
if (nd != d)
if (!(nd & targ))
continue;
if ((nd&targ) != (d&targ))
{
if (!(nd & targ))
continue;
if (d != ALL)
if (d != (ALL & ~targ))
VFS_PRINTF(f, "#endif\n");
d = nd;
switch(d)
if (((nd | (~targ)) & ALL) == ALL)
d = ALL & ~targ; //every part of the target is specified, so don't do the ifdef thing.
else
{
case 0:
continue;
case QW:
VFS_PRINTF(f, "#if defined(SSQC) && !defined(NETQUAKE)\n");
break;
case NQ:
VFS_PRINTF(f, "#if defined(SSQC) && defined(NETQUAKE)\n");
break;
case QW|NQ:
VFS_PRINTF(f, "#ifdef SSQC\n");
break;
case CS:
VFS_PRINTF(f, "#ifdef CSQC\n");
break;
case QW|CS:
VFS_PRINTF(f, "#if defined(CSQC) || (defined(SSQC) && !defined(NETQUAKE))\n");
break;
case NQ|CS:
VFS_PRINTF(f, "#if defined(CSQC) || (defined(SSQC) && defined(NETQUAKE))\n");
break;
case ALL:
break;
d = nd;
switch(d & (ALL & targ))
{
case 0:
continue;
case QW:
VFS_PRINTF(f, "#if defined(QWSSQC)\n");
break;
case NQ:
VFS_PRINTF(f, "#if defined(NQSSQC)\n");
break;
case QW|NQ:
VFS_PRINTF(f, "#ifdef SSQC\n");
break;
case CS:
VFS_PRINTF(f, "#ifdef CSQC\n");
break;
case QW|CS:
VFS_PRINTF(f, "#if defined(CSQC) || defined(QWSSQC)\n");
break;
case NQ|CS:
VFS_PRINTF(f, "#if defined(CSQC) || defined(NQSSQC)\n");
break;
case NQ|CS|QW:
VFS_PRINTF(f, "#if defined(CSQC) || defined(SSQC)\n");
break;
case MENU:
VFS_PRINTF(f, "#ifdef MENU\n");
break;
case QW|MENU:
VFS_PRINTF(f, "#if defined(QWSSQC) || defined(MENU)\n");
break;
case NQ|MENU:
VFS_PRINTF(f, "#if defined(NQSSQC) || defined(MENU)\n");
break;
case QW|NQ|MENU:
VFS_PRINTF(f, "#if defined(SSQC) || defined(MENU)\n");
break;
case CS|MENU:
VFS_PRINTF(f, "#if defined(CSQC) || defined(MENU)\n");
break;
case QW|CS|MENU:
VFS_PRINTF(f, "#if defined(CSQC) || defined(QWSSQC) || defined(MENU)\n");
break;
case NQ|CS|MENU:
VFS_PRINTF(f, "#if defined(CSQC) || defined(NQSSQC) || defined(MENU)\n");
break;
case ALL:
break;
}
}
}
if (!strcmp(knowndefs[i].type, "const float"))
@ -10319,13 +10596,13 @@ void PR_DumpPlatform_f(void)
else if (!strcmp(knowndefs[i].type, "const string"))
{
if (defines)
VFS_PRINTF(f, "#define %s \"%s\"\n", knowndefs[i].name, knowndefs[i].valuestr);
VFS_PRINTF(f, "#define %s %s\n", knowndefs[i].name, knowndefs[i].valuestr);
else
VFS_PRINTF(f, "%s %s = \"%s\";\n", knowndefs[i].type, knowndefs[i].name, knowndefs[i].valuestr);
VFS_PRINTF(f, "%s %s = %s;\n", knowndefs[i].type, knowndefs[i].name, knowndefs[i].valuestr);
}
else if (knowndefs[i].valuestr)
{
VFS_PRINTF(f, "%s %s = \"%s\";\n", knowndefs[i].type, knowndefs[i].name, knowndefs[i].valuestr);
VFS_PRINTF(f, "%s %s = %s;\n", knowndefs[i].type, knowndefs[i].name, knowndefs[i].valuestr);
}
else if (knowndefs[i].value)
{
@ -10334,10 +10611,6 @@ void PR_DumpPlatform_f(void)
else
VFS_PRINTF(f, "%s %s;\n", knowndefs[i].type, knowndefs[i].name);
}
if (d != ALL)
VFS_PRINTF(f, "#endif\n");
d = ALL;
for (i = 0; BuiltinList[i].name; i++)
{
if (BuiltinList[i].obsolete)
@ -10349,67 +10622,103 @@ void PR_DumpPlatform_f(void)
idx = BuiltinList[i].nqnum;
else if (BuiltinList[i].qwnum)
idx = BuiltinList[i].qwnum;
else if (BuiltinList[i].h2num)
idx = BuiltinList[i].h2num;
else
idx = 0;
nd = 0;
if (BuiltinList[i].ebfsnum == idx)
nd |= NQ|QW;
if (BuiltinList[i].nqnum == idx)
nd |= NQ;
if (BuiltinList[i].qwnum == idx)
nd |= QW;
if (BuiltinList[i].bifunc != PF_Fixme && BuiltinList[i].bifunc != PF_Ignore)
{
if (BuiltinList[i].ebfsnum == idx)
nd |= NQ|QW;
if (BuiltinList[i].nqnum == idx)
nd |= NQ;
if (BuiltinList[i].qwnum == idx)
nd |= QW;
if (BuiltinList[i].h2num == idx)
nd |= H2;
}
if (idx)
{
if (PR_CSQC_BuiltinValid(BuiltinList[i].name, idx))
{
nd |= CS;
if (BuiltinList[i].bifunc == PF_Fixme || BuiltinList[i].bifunc == PF_Ignore)
nd &= CS; /*csqc only*/
}
else
if (MP_BuiltinValid(BuiltinList[i].name, idx))
nd |= MENU;
if (!nd)
{
if (BuiltinList[i].bifunc == PF_Fixme || BuiltinList[i].bifunc == PF_Ignore)
{
/*neither*/
BuiltinList[i].obsolete = true;
nd = d; /*don't switch ifdefs*/
}
/*no idea what its for*/
BuiltinList[i].obsolete = true;
nd = d; /*don't switch ifdefs*/
}
if (nd != d)
nd |= (~targ & ALL);
if (!(nd & targ))
continue;
if ((nd&targ) != (d&targ))
{
if (!(nd & targ))
continue;
if (d != ALL)
if (d != (ALL & ~targ))
VFS_PRINTF(f, "#endif\n");
d = nd;
switch(d)
if (((nd | (~targ)) & ALL) == ALL)
d = ALL & ~targ;
else
{
case 0:
continue;
case QW:
VFS_PRINTF(f, "#if defined(SSQC) && !defined(NETQUAKE)\n");
break;
case NQ:
VFS_PRINTF(f, "#if defined(SSQC) && defined(NETQUAKE)\n");
break;
case QW|NQ:
VFS_PRINTF(f, "#ifdef SSQC\n");
break;
case CS:
VFS_PRINTF(f, "#ifdef CSQC\n");
break;
case QW|CS:
VFS_PRINTF(f, "#if defined(CSQC) || (defined(SSQC) && !defined(NETQUAKE))\n");
break;
case NQ|CS:
VFS_PRINTF(f, "#if defined(CSQC) || (defined(SSQC) && defined(NETQUAKE))\n");
break;
case ALL:
break;
d = nd;
switch(d & (ALL & targ))
{
case 0:
continue;
case QW:
VFS_PRINTF(f, "#if defined(QWSSQC)\n");
break;
case NQ:
VFS_PRINTF(f, "#if defined(NQSSQC)\n");
break;
case QW|NQ:
VFS_PRINTF(f, "#ifdef SSQC\n");
break;
case CS:
VFS_PRINTF(f, "#ifdef CSQC\n");
break;
case QW|CS:
VFS_PRINTF(f, "#if defined(CSQC) || defined(QWSSQC)\n");
break;
case NQ|CS:
VFS_PRINTF(f, "#if defined(CSQC) || defined(NQSSQC)\n");
break;
case NQ|CS|QW:
VFS_PRINTF(f, "#if defined(CSQC) || defined(SSQC)\n");
break;
case MENU:
VFS_PRINTF(f, "#ifdef MENU\n");
break;
case QW|MENU:
VFS_PRINTF(f, "#if defined(QWSSQC) || defined(MENU)\n");
break;
case NQ|MENU:
VFS_PRINTF(f, "#if defined(NQSSQC) || defined(MENU)\n");
break;
case QW|NQ|MENU:
VFS_PRINTF(f, "#if defined(SSQC) || defined(MENU)\n");
break;
case CS|MENU:
VFS_PRINTF(f, "#if defined(CSQC) || defined(MENU)\n");
break;
case QW|CS|MENU:
VFS_PRINTF(f, "#if defined(CSQC) || defined(QWSSQC) || defined(MENU)\n");
break;
case NQ|CS|MENU:
VFS_PRINTF(f, "#if defined(CSQC) || defined(NQSSQC) || defined(MENU)\n");
break;
case ALL:
break;
default:
VFS_PRINTF(f, "#if 0 //???\n");
break;
}
}
}
VFS_PRINTF(f, "%s%s %s = #%u;", BuiltinList[i].obsolete?"//":"", BuiltinList[i].prototype, BuiltinList[i].name, idx);
@ -10435,7 +10744,7 @@ void PR_DumpPlatform_f(void)
VFS_PRINTF(f, "\n");
}
}
if (d != ALL)
if (d != (ALL & ~targ))
VFS_PRINTF(f, "#endif\n");

View file

@ -907,6 +907,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
sv.spawned_observer_slots--;
}
}
}

View file

@ -142,6 +142,7 @@ typedef struct
int allocated_client_slots; //number of slots available. (used mostly to stop single player saved games cacking up)
int spawned_client_slots; //number of PLAYER slots which are active (ie: putclientinserver was called)
int spawned_observer_slots;
model_t *models[MAX_MODELS];
qbyte *pvs, *phs; // fully expanded and decompressed
@ -1081,6 +1082,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse);
void SV_PostRunCmd(void);
void SV_SendClientPrespawnInfo(client_t *client);
void SV_ClientProtocolExtensionsChanged(client_t *client);
//sv_master.c
void SVM_Think(int port);

View file

@ -603,12 +603,12 @@ void SV_Map_f (void)
gametype->flags |= CVAR_SERVERINFO;
Cvar_ForceSet(gametype, level);
gametype = Cvar_Get("g_gametype", "0", CVAR_LATCH|CVAR_SERVERINFO, "Q3 compatability");
gametype = Cvar_Get("g_gametype", "", CVAR_LATCH|CVAR_SERVERINFO, "Q3 compatability");
gametype->callback = gtcallback;
if (wasspmap)
Cvar_ForceSet(gametype, "2");//singleplayer
else if (gametype->value == 2)
Cvar_ForceSet(gametype, "0");//force to ffa deathmatch
Cvar_ForceSet(gametype, "");//force to ffa deathmatch
}
#endif
@ -628,7 +628,7 @@ void SV_Map_f (void)
{
/*pass the new map's name as an extension, so appropriate loading screens can be shown*/
if (ISNQCLIENT(host_client))
SV_StuffcmdToClient(host_client, va("restart \"%s\"\n", level));
SV_StuffcmdToClient(host_client, va("reconnect \"%s\"\n", level));
else
SV_StuffcmdToClient(host_client, va("changing \"%s\"\n", level));
}
@ -647,6 +647,11 @@ void SV_Map_f (void)
for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
{ //this expanded code cuts out a packet when changing maps...
//but more usefully, it stops dp(and probably nq too) from timing out.
//make sure its all reset.
host_client->sentents.num_entities = 0;
host_client->ratetime = 0;
if (host_client->pendingentbits)
host_client->pendingentbits[0] = UF_REMOVE;
if (host_client->controller)
continue;
if (host_client->state>=cs_connected)

View file

@ -841,7 +841,7 @@ static unsigned int SVFTE_DeltaCalcBits(entity_state_t *from, entity_state_t *to
if (to->hexen2flags != from->hexen2flags)
bits |= UF_DRAWFLAGS;
if (to->abslight != from->abslight)
bits |= UF_ABSLIGHT;
bits |= UF_DRAWFLAGS;
if (to->colormod[0]!=from->colormod[0]||to->colormod[1]!=from->colormod[1]||to->colormod[2]!=from->colormod[2])
bits |= UF_COLORMOD;
@ -1014,10 +1014,16 @@ static void SVFTE_WriteUpdate(unsigned int bits, entity_state_t *state, sizebuf_
MSG_WriteByte(msg, state->trans);
if (bits & UF_SCALE)
MSG_WriteByte(msg, state->scale);
if (bits & UF_ABSLIGHT)
MSG_WriteByte(msg, state->abslight);
if (bits & UF_UNUSED3)
{
// MSG_WriteByte(msg, );
}
if (bits & UF_DRAWFLAGS)
{
MSG_WriteByte(msg, state->hexen2flags);
if ((state->hexen2flags & MLS_MASKIN) == MLS_ABSLIGHT)
MSG_WriteByte(msg, state->abslight);
}
if (bits & UF_TAGINFO)
{
MSG_WriteEntity(msg, state->tagentity);
@ -1091,16 +1097,28 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
unsigned int *resendbits;
unsigned int *resendnum;
unsigned int outno, outmax;
qboolean reset = (client->delta_sequence == -1) || (client->pendingentbits[0] & UF_REMOVE);
int sequence;
if (ISNQCLIENT(client))
sequence = client->netchan.outgoing_unreliable;
else
sequence = client->netchan.incoming_sequence;
if (!client->pendingentbits)
return;
if (client->delta_sequence <= 0)
client->pendingentbits[0] = UF_REMOVE;
//if we're clearing the list and starting from scratch, just wipe all lingering state
if (reset)
if (client->pendingentbits[0] & UF_REMOVE)
{
for (j = 0; j < client->sentents.max_entities; j++)
for (j = 0; j < client->sentents.num_entities; j++)
{
client->sentents.entities[j].number = 0;
client->pendingentbits[j] = 0;
}
client->pendingentbits[0] = UF_REMOVE;
}
//expand client's entstate list
@ -1113,6 +1131,8 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
memset(&client->sentents.entities[client->sentents.max_entities], 0, sizeof(client->sentents.entities[0]) * (j - client->sentents.max_entities));
client->sentents.max_entities = j;
}
if (j > client->sentents.num_entities)
client->sentents.num_entities = j;
}
/*figure out the entitys+bits that changed (removed and active)*/
@ -1142,13 +1162,16 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
}
else
{
//its valid, make sure we don't have a stale/resent remove, and do a cheap reset due to uncertainty.
if (client->pendingentbits[j] & UF_REMOVE)
client->pendingentbits[j] = (client->pendingentbits[j] & ~UF_REMOVE) | UF_RESET2;
client->pendingentbits[j] |= SVFTE_DeltaCalcBits(o, n);
}
*o = *n;
j++;
}
/*gaps are dead entities*/
for (; j < client->sentents.max_entities; j++)
for (; j < client->sentents.num_entities; j++)
{
o = &client->sentents.entities[j];
if (o->number)
@ -1163,18 +1186,21 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
}
/*cache frame info*/
resendbits = client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK].resendentbits;
resendnum = client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK].resendentnum;
resendbits = client->frameunion.frames[sequence & UPDATE_MASK].resendentbits;
resendnum = client->frameunion.frames[sequence & UPDATE_MASK].resendentnum;
outno = 0;
outmax = client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK].entities.max_entities;
outmax = client->frameunion.frames[sequence & UPDATE_MASK].entities.max_entities;
/*start writing the packet*/
MSG_WriteByte (msg, svcfte_updateentities);
if (ISNQCLIENT(client))
{
MSG_WriteLong(msg, client->netchan.incoming_unreliable);
}
// Con_Printf("Gen sequence %i\n", sequence);
MSG_WriteFloat(msg, sv.world.physicstime);
if (reset) /*if we're resetting, the client will see 'remove world' which should be handled as a special case*/
MSG_WriteShort(msg, 0x8000);
for(j = 0; j < client->sentents.max_entities; j++)
for(j = 0; j < client->sentents.num_entities; j++)
{
bits = client->pendingentbits[j];
if (!(bits & ~UF_RESET2)) //skip while there's nothing to send (skip reset2 if there's no other changes, its only to reduce chances of the client getting 'new' entities containing just an origin)*/
@ -1186,10 +1212,10 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
client->pendingentbits[j] = 0;
if (bits & UF_REMOVE)
{
{ //if reset is set, then reset was set eroneously.
SV_EmitDeltaEntIndex(msg, j, true, true);
resendbits[outno] = UF_REMOVE;
// Con_Printf("REMOVE %i @ %i\n", j, client->netchan.incoming_sequence);
// Con_Printf("REMOVE %i @ %i\n", j, sequence);
}
else if (client->sentents.entities[j].number) /*only send a new copy of the ent if they actually have one already*/
{
@ -1198,7 +1224,7 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
/*if reset2, then this is the second packet sent to the client and should have a forced reset (but which isn't tracked)*/
resendbits[outno] = bits & ~UF_RESET2;
bits = UF_RESET | SVFTE_DeltaCalcBits(&EDICT_NUM(svprogfuncs, j)->baseline, &client->sentents.entities[j]);
// Con_Printf("RESET2 %i @ %i\n", j, client->netchan.incoming_sequence);
// Con_Printf("RESET2 %i @ %i\n", j, sequence);
}
else if (bits & UF_RESET)
{
@ -1206,7 +1232,7 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
client->pendingentbits[j] = UF_RESET2;
bits = UF_RESET | SVFTE_DeltaCalcBits(&EDICT_NUM(svprogfuncs, j)->baseline, &client->sentents.entities[j]);
resendbits[outno] = UF_RESET;
// Con_Printf("RESET %i @ %i\n", j, client->netchan.incoming_sequence);
// Con_Printf("RESET %i @ %i\n", j, sequence);
}
else
resendbits[outno] = bits;
@ -1218,8 +1244,8 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
}
MSG_WriteShort(msg, 0);
client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK].entities.num_entities = outno;
client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK].sequence = client->netchan.incoming_sequence;
client->frameunion.frames[sequence & UPDATE_MASK].entities.num_entities = outno;
client->frameunion.frames[sequence & UPDATE_MASK].sequence = sequence;
}
/*
@ -3389,12 +3415,13 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
#ifdef NQPROT
if (ISNQCLIENT(client))
{
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{
SVDP_EmitEntitiesUpdate(client, pack, msg);
SV_EmitCSQCUpdate(client, msg, svcdp_csqcentities);
return;
SVFTE_EmitPacketEntities(client, pack, msg);
client->netchan.incoming_sequence++;
}
else if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
SVDP_EmitEntitiesUpdate(client, pack, msg);
else
{
for (e = 0; e < pack->num_entities; e++)
@ -3404,10 +3431,9 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SVNQ_EmitEntityState(msg, &pack->entities[e]);
}
client->netchan.incoming_sequence++;
SV_EmitCSQCUpdate(client, msg, svcfte_csqcentities);
return;
}
SV_EmitCSQCUpdate(client, msg, svcdp_csqcentities);
return;
}
#endif

View file

@ -134,7 +134,7 @@ cvar_t sv_loadentfiles = CVAR("sv_loadentfiles", "1");
cvar_t sv_maxrate = CVAR("sv_maxrate", "30000");
cvar_t sv_maxdrate = CVARAF("sv_maxdrate", "100000",
"sv_maxdownloadrate", 0);
cvar_t sv_minping = CVARF("sv_minping", "0", CVAR_SERVERINFO);
cvar_t sv_minping = CVARF("sv_minping", "", CVAR_SERVERINFO);
cvar_t sv_bigcoords = CVARFD("sv_bigcoords", "", CVAR_SERVERINFO, "Uses floats for coordinates instead of 16bit values. Affects clients thusly:\nQW: enforces a mandatory protocol extension\nDP: enables DPP7 protocol support\nNQ: uses RMQ protocol (protocol 999).");
cvar_t sv_calcphs = CVARFD("sv_calcphs", "2", CVAR_LATCH, "Enables culling of sound effects. 0=always skip phs. Sounds are globally broadcast. 1=always generate phs. Sounds are always culled. On large maps the phs will be dumped to disk. 2=On large single-player maps, generation of phs is skipped. Otherwise like option 1.");
@ -184,19 +184,18 @@ cvar_t maxspectators = CVARF("maxspectators", "8", CVAR_SERVERINFO);
#ifdef SERVERONLY
cvar_t deathmatch = CVARF("deathmatch", "1", CVAR_SERVERINFO); // 0, 1, or 2
#else
cvar_t deathmatch = CVARF("deathmatch", "0", CVAR_SERVERINFO); // 0, 1, or 2
cvar_t deathmatch = CVARF("deathmatch", "", CVAR_SERVERINFO); // 0, 1, or 2
#endif
cvar_t coop = CVARF("coop", "" , CVAR_SERVERINFO);
cvar_t skill = CVARF("skill", "" , CVAR_SERVERINFO); // 0, 1, 2 or 3
cvar_t spawn = CVARF("spawn", "" , CVAR_SERVERINFO);
cvar_t watervis = CVARF("watervis", "" , CVAR_SERVERINFO);
cvar_t rearview = CVARF("rearview", "" , CVAR_SERVERINFO);
cvar_t allow_luma = CVARF("allow_luma", "1", CVAR_SERVERINFO);
cvar_t allow_luma = CVARF("allow_luma", "", CVAR_SERVERINFO);
#pragma warningmsg("Remove this some time")
cvar_t allow_bump = CVARF("allow_bump", "1", CVAR_SERVERINFO);
cvar_t allow_skybox = CVARF("allow_skybox", "", CVAR_SERVERINFO);
cvar_t sv_allow_splitscreen = CVARF("allow_splitscreen","",CVAR_SERVERINFO);
cvar_t fbskins = CVARF("fbskins", "1", CVAR_SERVERINFO); //to get rid of lame fuhquake fbskins
cvar_t fbskins = CVARF("fbskins", "", CVAR_SERVERINFO); //to get rid of lame fuhquake fbskins
cvar_t mirrors = CVARF("mirrors", "" , CVAR_SERVERINFO);
cvar_t sv_motd[] ={ CVAR("sv_motd1", ""),
@ -523,12 +522,14 @@ void SV_DropClient (client_t *drop)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
}
else if (SpectatorDisconnect)
else
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
if (SpectatorDisconnect)
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
sv.spawned_observer_slots--;
}
}
@ -621,6 +622,7 @@ void SV_DropClient (client_t *drop)
}
drop->laggedpacket_last = NULL;
drop->pendingentbits = NULL;
if (drop->frameunion.frames) //union of the same sort of structure
{
Z_Free(drop->frameunion.frames);
@ -1710,6 +1712,129 @@ static void SV_CheckRecentCrashes(client_t *tellclient)
}
#endif
void SV_ClientProtocolExtensionsChanged(client_t *client)
{
int i;
int maxpacketentities;
extern cvar_t pr_maxedicts;
client->maxmodels = 256;
if (client->fteprotocolextensions & PEXT_256PACKETENTITIES)
maxpacketentities = MAX_EXTENDED_PACKET_ENTITIES;
else
maxpacketentities = MAX_STANDARD_PACKET_ENTITIES; //true for qw,q2
if (ISQWCLIENT(client)) //readd?
{
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{
//you need to reconnect for this to update, of course. so make sure its not *too* low...
client->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS);
client->maxmodels = MAX_MODELS; //protocol limited to 14 bits.
}
else
{
client->max_net_ents = 512;
if (client->fteprotocolextensions & PEXT_ENTITYDBL)
client->max_net_ents += 512;
if (client->fteprotocolextensions & PEXT_ENTITYDBL2)
client->max_net_ents += 1024;
}
if (client->fteprotocolextensions & PEXT_MODELDBL)
client->maxmodels = MAX_MODELS;
}
else if (ISDPCLIENT(client))
{
client->max_net_ents = bound(512, pr_maxedicts.ival, 32768);
client->maxmodels = 1024; //protocol limit of 16 bits. 15 bits for late precaches. client limit of 1k
client->datagram.maxsize = sizeof(host_client->datagram_buf);
}
else if (client->protocol == SCP_FITZ666)
{
client->max_net_ents = bound(512, pr_maxedicts.ival, 32768); //fitzquake supports 65535, but our writeentity builtin works differently.
client->maxmodels = 1024;
maxpacketentities = 512;
client->datagram.maxsize = sizeof(host_client->datagram_buf);
}
else
{
client->datagram.maxsize = MAX_NQDATAGRAM; //vanilla limit
client->max_net_ents = bound(512, pr_maxedicts.ival, 600);
}
client->pendingentbits = NULL;
//initialise the client's frames, based on that client's protocol
switch(client->protocol)
{
#ifdef Q3SERVER
case SCP_QUAKE3:
Huff_PreferedCompressionCRC();
if (client->frameunion.q3frames)
Z_Free(client->frameunion.q3frames);
client->frameunion.q3frames = Z_Malloc(Q3UPDATE_BACKUP*sizeof(*client->frameunion.q3frames));
break;
#endif
#ifdef Q2SERVER
case SCP_QUAKE2:
// build a new connection
// accept the new client
// this is the only place a client_t is ever initialized
client->frameunion.q2frames = client->frameunion.q2frames; //don't touch these.
if (client->frameunion.q2frames)
Z_Free(client->frameunion.q2frames);
client->frameunion.q2frames = Z_Malloc(sizeof(q2client_frame_t)*Q2UPDATE_BACKUP);
break;
#endif
default:
client->frameunion.frames = client->frameunion.frames; //don't touch these.
if (client->frameunion.frames)
Z_Free(client->frameunion.frames);
if ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))// || ISDPCLIENT(&temp))
{
char *ptr;
int maxents = client->max_net_ents;//maxpacketentities; /*this is the max number of ents updated per frame. we can't track more, so...*/
ptr = Z_Malloc( sizeof(client_frame_t)*UPDATE_BACKUP+
sizeof(*client->pendingentbits)*client->max_net_ents+
sizeof(unsigned int)*maxents*UPDATE_BACKUP+
sizeof(unsigned int)*maxents*UPDATE_BACKUP);
client->frameunion.frames = (void*)ptr;
ptr += sizeof(*client->frameunion.frames)*UPDATE_BACKUP;
client->pendingentbits = (void*)ptr;
ptr += sizeof(*client->pendingentbits)*client->max_net_ents;
for (i = 0; i < UPDATE_BACKUP; i++)
{
client->frameunion.frames[i].entities.max_entities = maxents;
client->frameunion.frames[i].resendentnum = (void*)ptr;
ptr += sizeof(*client->frameunion.frames[i].resendentnum)*maxents;
client->frameunion.frames[i].resendentbits = (void*)ptr;
ptr += sizeof(*client->frameunion.frames[i].resendentbits)*maxents;
}
//make sure the reset is sent.
client->pendingentbits[0] = UF_REMOVE;
}
else
{
client->frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
for (i = 0; i < UPDATE_BACKUP; i++)
{
client->frameunion.frames[i].entities.max_entities = maxpacketentities;
client->frameunion.frames[i].entities.entities = (entity_state_t*)(client->frameunion.frames+UPDATE_BACKUP) + i*client->frameunion.frames[i].entities.max_entities;
}
}
break;
}
}
/*
==================
SVC_DirectConnect
@ -1749,15 +1874,13 @@ client_t *SVC_DirectConnect(void)
char basic[80];
qboolean redirect = false;
int maxpacketentities;
int numssclients = 1;
int protocol;
unsigned int protextsupported=0;
unsigned int protextsupported2=0;
extern cvar_t pr_maxedicts, sv_protocol_nq;
extern cvar_t sv_protocol_nq;
char *name;
@ -1940,13 +2063,6 @@ client_t *SVC_DirectConnect(void)
}
msg_badread=false;
if (protextsupported & PEXT_256PACKETENTITIES)
maxpacketentities = MAX_EXTENDED_PACKET_ENTITIES;
else
maxpacketentities = MAX_STANDARD_PACKET_ENTITIES;
/*allow_splitscreen applies only to non-local clients, so that clients have only one enabler*/
if (!sv_allow_splitscreen.ival && net_from.type != NA_LOOPBACK)
numssclients = 1;
@ -2043,41 +2159,6 @@ client_t *SVC_DirectConnect(void)
newcl->protocol = protocol;
Q_strncpyz(newcl->guid, guid, sizeof(newcl->guid));
newcl->maxmodels = 256;
if (protocol == SCP_QUAKEWORLD) //readd?
{
if (newcl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{
//you need to reconnect for this to update, of course. so make sure its not *too* low...
newcl->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS);
newcl->maxmodels = MAX_MODELS; //protocol limited to 14 bits.
}
else
{
newcl->max_net_ents = 512;
if (newcl->fteprotocolextensions & PEXT_ENTITYDBL)
newcl->max_net_ents += 512;
if (newcl->fteprotocolextensions & PEXT_ENTITYDBL2)
newcl->max_net_ents += 1024;
}
if (newcl->fteprotocolextensions & PEXT_MODELDBL)
newcl->maxmodels = MAX_MODELS;
}
else if (ISDPCLIENT(newcl))
{
newcl->max_net_ents = bound(512, pr_maxedicts.ival, 32768);
newcl->maxmodels = 1024; //protocol limit of 16 bits. 15 bits for late precaches. client limit of 1k
}
else if (newcl->protocol == SCP_FITZ666)
{
newcl->max_net_ents = bound(512, pr_maxedicts.ival, 32768); //fitzquake supports 65535, but our writeentity builtin works differently.
newcl->maxmodels = 1024;
maxpacketentities = 512;
}
else
newcl->max_net_ents = bound(512, pr_maxedicts.ival, 600);
if (sv.msgfromdemo)
newcl->wasrecorded = true;
@ -2331,73 +2412,12 @@ client_t *SVC_DirectConnect(void)
break;
}
//initialise the client's frames, based on that client's protocol
switch(temp.protocol)
if (newcl->frameunion.frames)
{
#ifdef Q3SERVER
case SCP_QUAKE3:
Huff_PreferedCompressionCRC();
if (temp.frameunion.q3frames)
Z_Free(temp.frameunion.q3frames);
temp.frameunion.q3frames = Z_Malloc(Q3UPDATE_BACKUP*sizeof(*temp.frameunion.q3frames));
break;
#endif
#ifdef Q2SERVER
case SCP_QUAKE2:
// build a new connection
// accept the new client
// this is the only place a client_t is ever initialized
temp.frameunion.q2frames = newcl->frameunion.q2frames; //don't touch these.
if (temp.frameunion.q2frames)
Z_Free(temp.frameunion.q2frames);
temp.frameunion.q2frames = Z_Malloc(sizeof(q2client_frame_t)*Q2UPDATE_BACKUP);
break;
#endif
default:
temp.frameunion.frames = newcl->frameunion.frames; //don't touch these.
if (temp.frameunion.frames)
{
Con_Printf("Debug: frames were set?\n");
Z_Free(temp.frameunion.frames);
}
if ((temp.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))// || ISDPCLIENT(&temp))
{
char *ptr;
int maxents = temp.max_net_ents;//maxpacketentities; /*this is the max number of ents updated per frame. we can't track more, so...*/
ptr = Z_Malloc( sizeof(client_frame_t)*UPDATE_BACKUP+
sizeof(*temp.pendingentbits)*temp.max_net_ents+
sizeof(unsigned int)*maxents*UPDATE_BACKUP+
sizeof(unsigned int)*maxents*UPDATE_BACKUP);
temp.frameunion.frames = (void*)ptr;
ptr += sizeof(*temp.frameunion.frames)*UPDATE_BACKUP;
temp.pendingentbits = (void*)ptr;
ptr += sizeof(*temp.pendingentbits)*temp.max_net_ents;
for (i = 0; i < UPDATE_BACKUP; i++)
{
temp.frameunion.frames[i].entities.max_entities = maxents;
temp.frameunion.frames[i].resendentnum = (void*)ptr;
ptr += sizeof(*temp.frameunion.frames[i].resendentnum)*maxents;
temp.frameunion.frames[i].resendentbits = (void*)ptr;
ptr += sizeof(*temp.frameunion.frames[i].resendentbits)*maxents;
}
}
else
{
temp.frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
for (i = 0; i < UPDATE_BACKUP; i++)
{
temp.frameunion.frames[i].entities.max_entities = maxpacketentities;
temp.frameunion.frames[i].entities.entities = (entity_state_t*)(temp.frameunion.frames+UPDATE_BACKUP) + i*temp.frameunion.frames[i].entities.max_entities;
}
}
break;
Con_Printf("Client frame info was set\n");
Z_Free(newcl->frameunion.frames);
}
{
char *n, *t;
n = newcl->name;
@ -2448,6 +2468,8 @@ client_t *SVC_DirectConnect(void)
newcl->datagram.prim = svs.netprim;
newcl->netchan.message.prim = svs.netprim;
SV_ClientProtocolExtensionsChanged(newcl);
// spectator mode can ONLY be set at join time
newcl->spectator = spectator;
@ -2562,7 +2584,12 @@ client_t *SVC_DirectConnect(void)
{
SV_AcceptMessage (protocol);
if (redirect)
if (ISNQCLIENT(newcl))
{
//FIXME: we should delay this until we actually have a name.
SV_BroadcastPrintf(PRINT_LOW, "New client connected\n", newcl->name);
}
else if (redirect)
{
}
else if (newcl->spectator)
@ -3941,7 +3968,7 @@ float SV_Frame (void)
#ifndef SERVERONLY
isidle = !isDedicated && sv.allocated_client_slots == 1 && key_dest != key_game && cls.state == ca_active;
/*server is effectively paused if there are no clients*/
if (sv.spawned_client_slots == 0)
if (sv.spawned_client_slots == 0 && sv.spawned_observer_slots == 0 && (cls.state != ca_connected))
isidle = true;
if ((sv.paused & 4) != (isidle?4:0))
sv.paused ^= 4;
@ -4210,7 +4237,6 @@ void SV_InitLocal (void)
Cvar_Register (&rearview, cvargroup_serverinfo);
Cvar_Register (&mirrors, cvargroup_serverinfo);
Cvar_Register (&allow_luma, cvargroup_serverinfo);
Cvar_Register (&allow_bump, cvargroup_serverinfo);
Cvar_Register (&allow_skybox, cvargroup_serverinfo);
Cvar_Register (&sv_allow_splitscreen, cvargroup_serverinfo);
Cvar_Register (&fbskins, cvargroup_serverinfo);

View file

@ -57,15 +57,15 @@ cvar_t sv_gameplayfix_noairborncorpse = SCVAR( "sv_gameplayfix_noairborncorpse",
cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1.");
cvar_t sv_sound_watersplash = CVAR( "sv_sound_watersplash", "misc/h2ohit1.wav");
cvar_t sv_sound_land = CVAR( "sv_sound_land", "demon/dland2.wav");
cvar_t sv_stepheight = CVARAF("pm_stepheight", "18",
"sv_stepheight", CVAR_SERVERINFO);
cvar_t sv_stepheight = CVARAFD("pm_stepheight", "",
"sv_stepheight", CVAR_SERVERINFO, "If empty, the value 18 will be used instead.");
cvar_t pm_ktjump = SCVARF("pm_ktjump", "0", CVAR_SERVERINFO);
cvar_t pm_bunnyspeedcap = SCVARF("pm_bunnyspeedcap", "0", CVAR_SERVERINFO);
cvar_t pm_slidefix = SCVARF("pm_slidefix", "0", CVAR_SERVERINFO);
cvar_t pm_slidyslopes = SCVARF("pm_slidyslopes", "0", CVAR_SERVERINFO);
cvar_t pm_airstep = SCVARF("pm_airstep", "0", CVAR_SERVERINFO);
cvar_t pm_walljump = SCVARF("pm_walljump", "0", CVAR_SERVERINFO);
cvar_t pm_ktjump = SCVARF("pm_ktjump", "", CVAR_SERVERINFO);
cvar_t pm_bunnyspeedcap = SCVARF("pm_bunnyspeedcap", "", CVAR_SERVERINFO);
cvar_t pm_slidefix = SCVARF("pm_slidefix", "", CVAR_SERVERINFO);
cvar_t pm_slidyslopes = SCVARF("pm_slidyslopes", "", CVAR_SERVERINFO);
cvar_t pm_airstep = SCVARF("pm_airstep", "", CVAR_SERVERINFO);
cvar_t pm_walljump = SCVARF("pm_walljump", "", CVAR_SERVERINFO);
#define cvargroup_serverphysics "server physics variables"
void WPhys_Init(void)

View file

@ -876,9 +876,17 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam
int qwflags;
int i;
qboolean use_phs;
qboolean reliable = false;
qboolean reliable;
int requiredextensions = 0;
if (channel & 256)
{
channel -= 256;
reliable = true;
}
else
reliable = false;
if (volume < 0 || volume > 255)
{
Con_Printf ("SV_StartSound: volume = %i", volume);
@ -891,7 +899,7 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam
return;
}
if (channel < 0 || channel > 15)
if (channel < 0 || channel > 255)
{
Con_Printf ("SV_StartSound: channel = %i", channel);
return;
@ -914,17 +922,11 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam
return;
}
if ((channel & 8) || !sv_phs.value) // no PHS flag
{
if (channel & 8)
reliable = true; // sounds that break the phs are reliable
if (reliable || !sv_phs.value) // no PHS flag
use_phs = false;
}
else
use_phs = attenuation!=0;
channel = (channel & 7) | ((channel & 0x1f0) >> 1);
// if (channel == CHAN_BODY || channel == CHAN_VOICE)
// reliable = true;
@ -1187,6 +1189,8 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
#endif
client_t *split;
int pnum=0;
int weaponmodelindex = 0;
qboolean nqjunk = true;
// send the chokecount for r_netgraph
if (ISQWCLIENT(client))
@ -1221,10 +1225,13 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
ent = client->edict;
MSG_WriteByte (msg, svc_time);
MSG_WriteFloat(msg, sv.world.physicstime);
client->nextservertimeupdate = sv.world.physicstime;
// Con_Printf("%f\n", sv.world.physicstime);
if (!(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
{
MSG_WriteByte (msg, svc_time);
MSG_WriteFloat(msg, sv.world.physicstime);
client->nextservertimeupdate = sv.world.physicstime;
// Con_Printf("%f\n", sv.world.physicstime);
}
bits = 0;
@ -1242,9 +1249,27 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
#define SU_INWATER (1<<11) // no data follows, the bit is it
#define SU_WEAPONFRAME (1<<12)
#define SU_ARMOR (1<<13)
#define SU_WEAPON (1<<14)
#define SU_WEAPONMODEL (1<<14)
#define SU_EXTEND1 (1<<15)
#define FITZSU_WEAPONMODEL2 (1<<16) // 1 byte, this is .weaponmodel & 0xFF00 (second byte)
#define FITZSU_ARMOR2 (1<<17) // 1 byte, this is .armorvalue & 0xFF00 (second byte)
#define FITZSU_AMMO2 (1<<18) // 1 byte, this is .currentammo & 0xFF00 (second byte)
#define FITZSU_SHELLS2 (1<<19) // 1 byte, this is .ammo_shells & 0xFF00 (second byte)
#define FITZSU_NAILS2 (1<<20) // 1 byte, this is .ammo_nails & 0xFF00 (second byte)
#define FITZSU_ROCKETS2 (1<<21) // 1 byte, this is .ammo_rockets & 0xFF00 (second byte)
#define FITZSU_CELLS2 (1<<22) // 1 byte, this is .ammo_cells & 0xFF00 (second byte)
#define FITZSU_EXTEND2 (1<<23) // another byte to follow
#define FITZSU_WEAPONFRAME2 (1<<24) // 1 byte, this is .weaponframe & 0xFF00 (second byte)
#define FITZSU_WEAPONALPHA (1<<25) // 1 byte, this is alpha for weaponmodel, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT
#define FITZSU_UNUSED26 (1<<26)
#define FITZSU_UNUSED27 (1<<27)
#define FITZSU_UNUSED28 (1<<28)
#define FITZSU_UNUSED29 (1<<29)
#define FITZSU_UNUSED30 (1<<30)
#define FITZSU_EXTEND3 (1<<31) // another byte to follow, future expansion
if (ent->v->view_ofs[2] != DEFAULT_VIEWHEIGHT)
bits |= SU_VIEWHEIGHT;
@ -1277,17 +1302,55 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
bits |= (SU_VELOCITY1<<i);
}
if (ent->v->weaponframe)
bits |= SU_WEAPONFRAME;
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
{
//bits &= ~SU_ITEMS;
nqjunk = false;
}
else
{
nqjunk = true;
if (ent->v->armorvalue)
bits |= SU_ARMOR;
if (ent->v->weaponframe)
bits |= SU_WEAPONFRAME;
// if (ent->v->weapon)
bits |= SU_WEAPON;
if (ent->v->armorvalue)
bits |= SU_ARMOR;
if (bits >= 65536)
weaponmodelindex = SV_ModelIndex(ent->v->weaponmodel + svprogfuncs->stringtable);
if (weaponmodelindex)
bits |= SU_WEAPONMODEL;
if (client->protocol == SCP_FITZ666)
{
if (weaponmodelindex & 0xff00)
bits |= FITZSU_WEAPONMODEL2;
if ((int)ent->v->armorvalue & 0xff00)
bits |= FITZSU_ARMOR2;
if ((int)ent->v->currentammo & 0xff00)
bits |= FITZSU_AMMO2;
if ((int)ent->v->ammo_shells & 0xff00)
bits |= FITZSU_SHELLS2;
if ((int)ent->v->ammo_nails & 0xff00)
bits |= FITZSU_NAILS2;
if ((int)ent->v->ammo_rockets & 0xff00)
bits |= FITZSU_ROCKETS2;
if ((int)ent->v->ammo_cells & 0xff00)
bits |= FITZSU_CELLS2;
if ((int)ent->v->weaponframe & 0xff00)
bits |= FITZSU_WEAPONFRAME2;
if (ent->xv->alpha && ent->xv->alpha < 1)
bits |= FITZSU_WEAPONALPHA;
}
}
if (bits >= (1u<<16))
bits |= SU_EXTEND1;
if (bits >= (1u<<24))
bits |= FITZSU_EXTEND2;
if (bits >= (1ull<<32))
bits |= FITZSU_EXTEND3;
// send the data
@ -1316,48 +1379,54 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
if (bits & SU_ITEMS)
MSG_WriteLong (msg, items);
if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
return;
if (bits & SU_WEAPONFRAME)
MSG_WriteByte (msg, ent->v->weaponframe);
if (bits & SU_ARMOR)
{
if (ent->v->armorvalue>255)
if (ent->v->armorvalue>255 && !(bits & FITZSU_ARMOR2))
MSG_WriteByte (msg, 255);
else
MSG_WriteByte (msg, ent->v->armorvalue);
}
if (bits & SU_WEAPON)
MSG_WriteByte (msg, SV_ModelIndex(ent->v->weaponmodel + svprogfuncs->stringtable));
if (bits & SU_WEAPONMODEL)
MSG_WriteByte (msg, weaponmodelindex);
MSG_WriteShort (msg, ent->v->health);
MSG_WriteByte (msg, ent->v->currentammo);
MSG_WriteByte (msg, ent->v->ammo_shells);
MSG_WriteByte (msg, ent->v->ammo_nails);
MSG_WriteByte (msg, ent->v->ammo_rockets);
MSG_WriteByte (msg, ent->v->ammo_cells);
//if (other && other->v->weapon)
//MSG_WriteByte (msg, other->v->weapon);
//else
//{
if (standard_quake)
if (nqjunk)
{
MSG_WriteByte (msg, ent->v->weapon);
}
else
{
for(i=0;i<32;i++)
MSG_WriteShort (msg, ent->v->health);
MSG_WriteByte (msg, ent->v->currentammo);
MSG_WriteByte (msg, ent->v->ammo_shells);
MSG_WriteByte (msg, ent->v->ammo_nails);
MSG_WriteByte (msg, ent->v->ammo_rockets);
MSG_WriteByte (msg, ent->v->ammo_cells);
if (standard_quake)
{
if ( ((int)ent->v->weapon) & (1<<i) )
MSG_WriteByte (msg, ent->v->weapon);
}
else
{
for(i=0;i<32;i++)
{
MSG_WriteByte (msg, i);
break;
if ( ((int)ent->v->weapon) & (1<<i) )
{
MSG_WriteByte (msg, i);
break;
}
}
}
}
if (bits & FITZSU_WEAPONMODEL2) MSG_WriteByte (msg, weaponmodelindex >> 8);
if (bits & FITZSU_ARMOR2) MSG_WriteByte (msg, (int)ent->v->armorvalue >> 8);
if (bits & FITZSU_AMMO2) MSG_WriteByte (msg, (int)ent->v->currentammo >> 8);
if (bits & FITZSU_SHELLS2) MSG_WriteByte (msg, (int)ent->v->ammo_shells >> 8);
if (bits & FITZSU_NAILS2) MSG_WriteByte (msg, (int)ent->v->ammo_nails >> 8);
if (bits & FITZSU_ROCKETS2) MSG_WriteByte (msg, (int)ent->v->ammo_rockets >> 8);
if (bits & FITZSU_CELLS2) MSG_WriteByte (msg, (int)ent->v->ammo_cells >> 8);
if (bits & FITZSU_WEAPONFRAME2) MSG_WriteByte (msg, (int)ent->v->weaponframe >> 8);
if (bits & FITZSU_WEAPONALPHA) MSG_WriteByte (msg, ent->xv->alpha*255);
// }
#endif
}
@ -2332,29 +2401,50 @@ void SV_SendClientMessages (void)
continue;
}
#ifdef NQPROT
// only send messages if the client has sent one
// and the bandwidth is not choked
if (ISNQCLIENT(c))
{ //nq clients get artificial choke too
c->send_message = false;
if (c->nextservertimeupdate != pt && c->state != cs_zombie)
{
//tread carefully with NQ:
//while loading models etc, NQ will error out if it receives anything that it wasn't expecting.
//we should still send unreliable nops whenever we want as a keepalive (and we may need to in order to wake up the client).
//other unreliables are disallowed when connecting, due to sync issues.
//reliables may be sent only if some other code has said that its okay (to avoid stray name changes killing clients).
if (c->state == cs_connected)
{
c->send_message = c->netchan.nqreliable_allowed = true;
if (c->nextservertimeupdate > pt + 6)
c->nextservertimeupdate = 0;
if (c->state == cs_connected && !c->datagram.cursize && !c->netchan.message.cursize)
c->netchan.nqunreliableonly = !c->send_message;
c->datagram.cursize = 0;
if (!c->send_message && c->nextservertimeupdate < pt)
{
if (c->nextservertimeupdate < pt)
{ //part of the nq protocols allowed downloading content over isdn
//the nop requirement of the protocol persisted to prevent timeouts when content loading is otherwise slow..
//aditionally we might need this for lost packets, not sure
//but the client isn't able to respond unless we send an occasional datagram
if (c->nextservertimeupdate)
MSG_WriteByte(&c->datagram, svc_nop);
c->nextservertimeupdate = pt+5;
}
if (c->nextservertimeupdate)
MSG_WriteByte(&c->datagram, svc_nop);
c->nextservertimeupdate = pt+5;
}
c->send_message = true;
//we can still send an outgoing packet if something set send_message. This should really only be svnq_new_f and friends.
}
else
{
if (c->nextservertimeupdate > pt + 0.5*2)
c->nextservertimeupdate = 0;
c->netchan.nqunreliableonly = false;
c->send_message = false;
//nq sends one packet only for each server physics frame
if (c->nextservertimeupdate < pt && c->state != cs_zombie)
{
c->send_message = true;
c->nextservertimeupdate = pt;
}
}
}
//qw servers will set send_message on packet reception.
#endif
if (!c->send_message)
continue;
c->send_message = false; // try putting this after choke?

View file

@ -423,9 +423,12 @@ void SVNQ_New_f (void)
extern cvar_t coop;
char message[2048];
int i;
int maxents;
int maxplayers = 0;
int op;
extern cvar_t pr_maxedicts;
unsigned int protext1 = 0, protext2 = 0, protmain = 0, protfl = 0;
host_client->send_message = true;
if (host_client->redirect)
{
char *msg = va("connect \"%s\"\n", sv_fullredirect.string);
@ -477,20 +480,17 @@ void SVNQ_New_f (void)
}
}
MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
protext1 = host_client->fteprotocolextensions;
protext2 = host_client->fteprotocolextensions2;
protmain = NQ_PROTOCOL_VERSION;
protfl = 0;
//force floatcoords as required.
if (sv.nqdatagram.prim.coordsize >= 4)
protext1 |= PEXT_FLOATCOORDS;
else
protext1 &= ~PEXT_FLOATCOORDS;
if (host_client->fteprotocolextensions)
{
MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION_FTE);
MSG_WriteLong (&host_client->netchan.message, host_client->fteprotocolextensions);
}
if (host_client->fteprotocolextensions2)
{
MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION_FTE2);
MSG_WriteLong (&host_client->netchan.message, host_client->fteprotocolextensions2);
}
maxents = host_client->max_net_ents;
op = host_client->protocol;
switch(host_client->protocol)
{
#ifdef NQPROT
@ -500,47 +500,35 @@ void SVNQ_New_f (void)
SV_LogPlayer(host_client, "new (NQ)");
if (sv.nqdatagram.prim.anglesize != 1 || sv.nqdatagram.prim.coordsize != 2 || host_client->protocol == SCP_FITZ666)
{
int rmqfl =
protfl =
((sv.nqdatagram.prim.coordsize==4)?RMQFL_FLOATCOORD:0) |
((sv.nqdatagram.prim.anglesize==2)?RMQFL_SHORTANGLE:0);
host_client->protocol = SCP_FITZ666; /*mneh, close enough, the rmq stuff is just modifiers*/
host_client->datagram.maxsize = sizeof(host_client->datagram_buf);
if (rmqfl)
if (protfl)
{
MSG_WriteLong (&host_client->netchan.message, RMQ_PROTOCOL_VERSION);
MSG_WriteLong (&host_client->netchan.message, rmqfl);
protext1 &= ~PEXT_FLOATCOORDS; //never report floatcoords when using rmq protocol, as the base protocol allows us to be more specific anyway.
protmain = RMQ_PROTOCOL_VERSION;
}
else
{
MSG_WriteLong (&host_client->netchan.message, FITZ_PROTOCOL_VERSION);
}
host_client->maxmodels = 1024;
protmain = FITZ_PROTOCOL_VERSION;
}
else
{
host_client->protocol = (host_client->protocol==SCP_PROQUAKE)?SCP_PROQUAKE:SCP_NETQUAKE; //identical other than the client->server angles
if (host_client->protocol==SCP_PROQUAKE)
host_client->max_net_ents = bound(512, pr_maxedicts.ival, 32767); //modified engines will all want to use proquake's improved aiming protocol.
else //if this breaks your client, upgrade.
host_client->max_net_ents = bound(512, pr_maxedicts.ival, 600);
MSG_WriteLong (&host_client->netchan.message, NQ_PROTOCOL_VERSION);
host_client->datagram.maxsize = MAX_NQDATAGRAM;
host_client->maxmodels = 256;
protmain = NQ_PROTOCOL_VERSION;
}
MSG_WriteByte (&host_client->netchan.message, (sv.allocated_client_slots>16)?16:sv.allocated_client_slots);
maxplayers = 16;
break;
case SCP_DARKPLACES6:
SV_LogPlayer(host_client, "new (DP6)");
MSG_WriteLong (&host_client->netchan.message, DP6_PROTOCOL_VERSION);
MSG_WriteByte (&host_client->netchan.message, sv.allocated_client_slots);
protmain = DP6_PROTOCOL_VERSION;
maxplayers = 255;
break;
case SCP_DARKPLACES7:
SV_LogPlayer(host_client, "new (DP7)");
MSG_WriteLong (&host_client->netchan.message, DP7_PROTOCOL_VERSION);
MSG_WriteByte (&host_client->netchan.message, sv.allocated_client_slots);
protmain = DP7_PROTOCOL_VERSION;
maxplayers = 255;
break;
#endif
default:
@ -548,9 +536,24 @@ void SVNQ_New_f (void)
break;
}
//the protocol limits were recalculated to avoid any nasty surprises when things default to forcing a protocol
if (maxents != host_client->max_net_ents && !(host_client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
host_client->max_net_ents = maxents;
MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
if (protext1)
{
MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION_FTE);
MSG_WriteLong (&host_client->netchan.message, protext1);
}
if (protext2)
{
MSG_WriteLong (&host_client->netchan.message, PROTOCOL_VERSION_FTE2);
MSG_WriteLong (&host_client->netchan.message, protext2);
}
MSG_WriteLong (&host_client->netchan.message, protmain);
if (protmain == RMQ_PROTOCOL_VERSION)
MSG_WriteLong (&host_client->netchan.message, protfl);
MSG_WriteByte (&host_client->netchan.message, (sv.allocated_client_slots>maxplayers)?maxplayers:sv.allocated_client_slots);
if (op != host_client->protocol)
SV_ClientProtocolExtensionsChanged(host_client);
if (!coop.value && deathmatch.value)
MSG_WriteByte (&host_client->netchan.message, GAME_DEATHMATCH);
@ -950,7 +953,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
started = false;
//allows stalling for the soundlist command, for compat.
if (host_client->prespawn_idx & 0x80000000)
if (client->prespawn_idx & 0x80000000)
return;
while (client->netchan.message.cursize < (client->netchan.message.maxsize/2))
@ -993,7 +996,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
MSG_WriteByte (&client->netchan.message, (client->prespawn_idx&0xff)?client->prespawn_idx:0xff);
if (!(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
host_client->prespawn_idx |= 0x80000000;
client->prespawn_idx |= 0x80000000;
}
}
if (client->prespawn_stage == PRESPAWN_MODELLIST)
@ -1001,7 +1004,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
started = false;
//allows stalling for the soundlist command, for compat.
if (host_client->prespawn_idx & 0x80000000)
if (client->prespawn_idx & 0x80000000)
return;
while (client->netchan.message.cursize < (client->netchan.message.maxsize/2))
@ -1078,7 +1081,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
MSG_WriteByte (&client->netchan.message, (client->prespawn_idx&0xff)?client->prespawn_idx:0xff);
if (!(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
host_client->prespawn_idx |= 0x80000000;
client->prespawn_idx |= 0x80000000;
}
}
@ -1171,7 +1174,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{
MSG_WriteByte(&client->netchan.message, svc_spawnstatic2);
MSG_WriteByte(&client->netchan.message, svcfte_spawnstatic2);
SVFTE_EmitBaseline(state, false, &client->netchan.message);
continue;
}
@ -1180,7 +1183,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
/*if it uses some new feature, use the updated spawnstatic*/
if (state->hexen2flags || state->trans || state->modelindex >= 256 || state->frame > 255 || state->scale || state->abslight)
{
MSG_WriteByte(&client->netchan.message, svc_spawnstatic2);
MSG_WriteByte(&client->netchan.message, svcfte_spawnstatic2);
SVQW_WriteDelta(&nullentitystate, state, &client->netchan.message, true, client->fteprotocolextensions);
continue;
}
@ -1317,8 +1320,18 @@ void SV_SendClientPrespawnInfo(client_t *client)
if (!client->prespawn_idx)
{
//we'll spawn the client and then send all the updating stuff only when we know the channel is clear, by pinging the client for it.
MSG_WriteByte (&client->netchan.message, svc_stufftext);
MSG_WriteString (&client->netchan.message, va("cmd spawn %i\n",svs.spawncount) );
if (ISNQCLIENT(client))
{
//effectively a cmd spawn... but also causes the client to actually send the player's name too.
ClientReliableWrite_Begin (client, svc_signonnum, 2);
ClientReliableWrite_Byte (client, 2);
}
else
{
char *cmd = va("cmd spawn %i\n",svs.spawncount);
ClientReliableWrite_Begin(client, svc_stufftext, 2+strlen(cmd));
ClientReliableWrite_String(client, cmd);
}
client->prespawn_idx++;
}
}
@ -1627,6 +1640,7 @@ void SV_Begin_Core(client_t *split)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
}
sv.spawned_observer_slots++;
}
else
{
@ -3591,11 +3605,20 @@ void SV_SetInfo_f (void)
if (basic || (client->fteprotocolextensions & PEXT_BIGUSERINFOS))
{
ClientReliableWrite_Begin(client, svc_setinfo, 1+1+strlen(key)+1+strlen(val)+1);
ClientReliableWrite_Char(client, i);
ClientReliableWrite_Byte(client, i);
ClientReliableWrite_String(client, key);
ClientReliableWrite_String(client, val);
}
}
if (ISNQCLIENT(client))
{
if (!strcmp(key, "name"))
{
ClientReliableWrite_Begin(client, svc_updatename, 1+1+strlen(val)+1);
ClientReliableWrite_Byte(client, i);
ClientReliableWrite_String(client, val);
}
}
}
if (sv.mvdrecording)
@ -4104,6 +4127,7 @@ void Cmd_Join_f (void)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
if (SpectatorDisconnect)
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
sv.spawned_observer_slots--;
SV_SetUpClientEdict (host_client, host_client->edict);
@ -4230,6 +4254,7 @@ void Cmd_Observe_f (void)
}
else
sv_player->v->movetype = MOVETYPE_NOCLIP;
sv.spawned_observer_slots++;
// send notification to all clients
host_client->old_frags = host_client->edict->v->frags;
@ -4416,9 +4441,6 @@ void SVNQ_Spawn_f (void)
ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
ClientReliableWrite_Long (host_client, pr_global_struct->killed_monsters);
SZ_Write (&host_client->netchan.message, sv.signon.data, sv.signon.cursize);
MSG_WriteByte (&host_client->netchan.message, svc_signonnum);
MSG_WriteByte (&host_client->netchan.message, 3);
@ -4462,6 +4484,7 @@ void SVNQ_Begin_f (void)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
}
sv.spawned_observer_slots++;
}
else
{
@ -4531,9 +4554,6 @@ void SVNQ_Begin_f (void)
MSG_WriteAngle (&host_client->netchan.message, 0 );
}
SZ_Write (&host_client->netchan.message, sv.signon.data, sv.signon.cursize);
// MSG_WriteByte (&host_client->netchan.message, svc_signonnum);
// MSG_WriteByte (&host_client->netchan.message, 4);
@ -4661,6 +4681,10 @@ void SV_Pext_f(void)
}
}
Con_DPrintf("%s now using pext: %x, %x\n", host_client->name, host_client->fteprotocolextensions, host_client->fteprotocolextensions2);
SV_ClientProtocolExtensionsChanged(host_client);
if (ISNQCLIENT(host_client))
SVNQ_New_f();
else
@ -6014,6 +6038,25 @@ done:
SV_ClientPrintf(host_client, PRINT_HIGH, "qcrequest \"%s\" not supported\n", rname);
}
void SV_AckEntityFrame(client_t *cl, int framenum)
{
#ifdef PEXT_CSQC
if (cl->lastsequence_acknowledged + UPDATE_BACKUP > framenum)
{
int i;
Con_DPrintf("SV: Acked %i\n", framenum);
for (i = cl->lastsequence_acknowledged+1; i < framenum; i++)
SV_CSQC_DroppedPacket(cl, i);
}
else
{
/*too much loss, we don't know what was sent when, so reset the entire entity state*/
SV_CSQC_DropAll(cl);
}
#endif
cl->lastsequence_acknowledged = framenum;
}
/*
===================
SV_ExecuteClientMessage
@ -6064,19 +6107,6 @@ void SV_ExecuteClientMessage (client_t *cl)
}
}
}
#ifdef PEXT_CSQC
if (cl->lastsequence_acknowledged + UPDATE_BACKUP > cl->netchan.incoming_acknowledged)
{
for (i = cl->lastsequence_acknowledged+1; i < cl->netchan.incoming_acknowledged; i++)
SV_CSQC_DroppedPacket(cl, i);
}
else
{
/*too much loss, we don't know what was sent when, so reset the entire entity state*/
SV_CSQC_DropAll(cl);
}
#endif
cl->lastsequence_acknowledged = cl->netchan.incoming_acknowledged;
if (sv_antilag.ival)
{
@ -6374,9 +6404,15 @@ haveannothergo:
SV_VoiceReadPacket();
break;
#endif
case clcdp_ackframe:
cl->delta_sequence = MSG_ReadLong();
SV_AckEntityFrame(cl, cl->delta_sequence);
break;
}
}
SV_AckEntityFrame(cl, cl->netchan.incoming_acknowledged);
host_client = NULL;
sv_player = NULL;
}
@ -6571,6 +6607,20 @@ void SVNQ_ReadClientMove (usercmd_t *move)
frame->ping_time = sv.time - cltime;
if (frame->ping_time*1000 > sv_minping.value+1)
{
host_client->delay -= 0.001;
if (host_client->delay < 0)
host_client->delay = 0;
}
if (frame->ping_time*1000 < sv_minping.value)
{
host_client->delay += 0.001;
if (host_client->delay > 1)
host_client->delay = 1;
}
// read current angles
for (i=0 ; i<3 ; i++)
{
@ -6731,8 +6781,13 @@ void SVNQ_ExecuteClientMessage (client_t *cl)
sv_player = cl->edict;
break;
case clc_qcrequest:
SV_ReadQCRequest();
break;
case clcdp_ackframe:
cl->delta_sequence = MSG_ReadLong();
SV_AckEntityFrame(cl, cl->delta_sequence);
break;
case clcdp_ackdownloaddata:
SV_DarkPlacesDownloadAck(cl);

View file

@ -3,23 +3,50 @@
!!permu FRAMEBLEND
!!permu SKELETAL
!!permu FOG
!!cvarf r_glsl_offsetmapping_scale
!!cvarf gl_specular
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
#ifdef UPPERLOWER
#define UPPER
#define LOWER
#endif
varying vec2 tc;
varying vec3 light;
#if defined(SPECULAR) || defined(OFFSETMAPPING)
varying vec3 eyevector;
#endif
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
attribute vec2 v_texcoord;
uniform vec3 e_light_dir;
uniform vec3 e_light_mul;
uniform vec3 e_light_ambient;
#if defined(SPECULAR) || defined(OFFSETMAPPING)
uniform vec3 e_eyepos;
#endif
void main ()
{
#if defined(SPECULAR)||defined(OFFSETMAPPING)
vec3 n, s, t, w;
gl_Position = skeletaltransform_wnst(w,n,s,t);
vec3 eyeminusvertex = e_eyepos - w.xyz;
eyevector.x = -dot(eyeminusvertex, s.xyz);
eyevector.y = dot(eyeminusvertex, t.xyz);
eyevector.z = dot(eyeminusvertex, n.xyz);
#else
vec3 n;
gl_Position = skeletaltransform_n(n);
#endif
light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);
tc = v_texcoord;
}
@ -38,24 +65,54 @@ uniform vec3 e_uppercolour;
#ifdef FULLBRIGHT
uniform sampler2D s_t3;
#endif
#if defined(SPECULAR)
uniform sampler2D s_t4;
uniform sampler2D s_t5;
uniform float cvar_gl_specular;
#endif
#ifdef OFFSETMAPPING
#include "sys/offsetmapping.h"
#endif
uniform vec4 e_colourident;
void main ()
{
vec4 col, sp;
#ifdef OFFSETMAPPING
vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);
#define tc tcoffsetmap
#endif
col = texture2D(s_t0, tc);
#ifdef UPPER
vec4 uc = texture2D(s_t2, tc);
col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);
col.rgb += uc.rgb*e_uppercolour*uc.a;
#endif
#ifdef LOWER
vec4 lc = texture2D(s_t1, tc);
col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);
col.rgb += lc.rgb*e_lowercolour*lc.a;
#endif
col.rgb *= light;
#if defined(SPECULAR)
vec3 bumps = normalize(vec3(texture2D(s_t4, tc)) - 0.5);
vec4 specs = texture2D(s_t5, tc);
vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0));
float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
col.rgb += cvar_gl_specular * spec * specs.rgb;
#endif
#ifdef FULLBRIGHT
vec4 fb = texture2D(s_t3, tc);
col.rgb = mix(col.rgb, fb.rgb, fb.a);
#endif
gl_FragColor = fog4(col * e_colourident);
}
#endif

View file

@ -1,5 +1,6 @@
!!permu BUMP
!!permu SKELETAL
!!permu UPPERLOWER
!!permu FOG
!!cvarf r_glsl_offsetmapping_scale
@ -17,6 +18,11 @@
#extension GL_ARB_texture_gather : enable
#endif
#ifdef UPPERLOWER
#define UPPER
#define LOWER
#endif
varying vec2 tcbase;
varying vec3 lightvector;
@ -65,20 +71,20 @@ void main ()
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
uniform sampler2D s_t0;
uniform sampler2D s_t0; //diffuse
#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)
uniform sampler2D s_t1;
uniform sampler2D s_t1; //normalmap
#endif
#ifdef SPECULAR
uniform sampler2D s_t2;
uniform sampler2D s_t2; //specular
#endif
#ifdef CUBEPROJ
uniform samplerCube s_t3;
uniform samplerCube s_t3; //projected cubemap
#endif
#ifdef PCF
#ifdef CUBESHADOW
uniform samplerCubeShadow s_t4;
uniform samplerCubeShadow s_t4; //shadowmap
#else
#if 0//def GL_ARB_texture_gather
uniform sampler2D s_t4;
@ -87,6 +93,14 @@ uniform sampler2DShadow s_t4;
#endif
#endif
#endif
#ifdef LOWER
uniform sampler2D s_t5; //pants colours
uniform vec3 e_lowercolour;
#endif
#ifdef UPPER
uniform sampler2D s_t6; //shirt colours
uniform vec3 e_uppercolour;
#endif
uniform float l_lightradius;
@ -128,7 +142,7 @@ float ShadowmapFilter(void)
//assume z is the major axis (ie: forward from the light)
vec3 t = shadowcoord;
float ma = dir.z;
vec4 axis = vec4(1.0, 1.0, 1.0, 0.0);
vec3 axis = vec3(1.0, 1.0, 1.0);
if (dir.x > ma)
{
ma = dir.x;
@ -200,6 +214,14 @@ void main ()
#define tcbase tcoffsetmap
#endif
vec3 bases = vec3(texture2D(s_t0, tcbase));
#ifdef UPPER
vec4 uc = texture2D(s_t6, tcbase);
bases.rgb += uc.rgb*e_uppercolour*uc.a;
#endif
#ifdef LOWER
vec4 lc = texture2D(s_t5, tcbase);
bases.rgb += lc.rgb*e_lowercolour*lc.a;
#endif
#if defined(BUMP) || defined(SPECULAR)
vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5);
#endif

View file

@ -11,11 +11,11 @@ varying vec2 v_edge;
uniform float e_time;
void main ()
{
gl_Position = ftetransform();
v_stc = (1.0+(gl_Position.xy / gl_Position.w))/2.0;
v_warp.s = e_time * 0.25 + v_texcoord.s;
v_warp.t = e_time * 0.25 + v_texcoord.t;
v_edge = v_texcoord.xy;
gl_Position = ftetransform();
v_stc = (1.0+(gl_Position.xy / gl_Position.w))/2.0;
v_warp.s = e_time * 0.25 + v_texcoord.s;
v_warp.t = e_time * 0.25 + v_texcoord.t;
v_edge = v_texcoord.xy;
}
#endif
#ifdef FRAGMENT_SHADER
@ -25,21 +25,21 @@ varying vec2 v_edge;
uniform sampler2D s_t0;/*$currentrender*/
uniform sampler2D s_t1;/*warp image*/
uniform sampler2D s_t2;/*edge image*/
uniform vec3 e_rendertexturescale;
uniform vec4 e_rendertexturescale;
uniform float cvar_r_waterwarp;
void main ()
{
float amptemp;
vec3 edge;
edge = texture2D( s_t2, v_edge ).rgb;
amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;
vec3 offset;
offset = texture2D( s_t1, v_warp ).rgb;
offset.x = (offset.x - 0.5) * 2.0;
offset.y = (offset.y - 0.5) * 2.0;
vec2 temp;
temp.x = v_stc.x + offset.x * amptemp;
temp.y = v_stc.y + offset.y * amptemp;
gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );
float amptemp;
vec3 edge;
edge = texture2D( s_t2, v_edge ).rgb;
amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;
vec3 offset;
offset = texture2D( s_t1, v_warp ).rgb;
offset.x = (offset.x - 0.5) * 2.0;
offset.y = (offset.y - 0.5) * 2.0;
vec2 temp;
temp.x = v_stc.x + offset.x * amptemp;
temp.y = v_stc.y + offset.y * amptemp;
gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );
}
#endif

View file

@ -339,7 +339,7 @@ static void Dec_ChangeStream(void *vctx, char *newstream)
else if (!strcmp(newstream+4, "unfocus"))
ctx->wnd->unfocus();
else if (!strcmp(newstream+4, "opaque"))
ctx->wnd->setTransparent(true);
ctx->wnd->setTransparent(false);
else if (!strcmp(newstream+4, "stop"))
ctx->wnd->stop();
else if (!strcmp(newstream+4, "back"))

View file

@ -39,7 +39,20 @@ CSQC is able to interact with videos by:
this will 'end' the video. when the shader is next displayed it'll reset from the original url.
7: you can change the url with:
gecko_navigate(texname, "http://fteqw.com");
8: you can send it these navigation commands (in the place of a url). You'll likely want a focus command.
cmd:refresh
cmd:transparent
cmd:focus
cmd:unfocus
cmd:opaque
cmd:stop
cmd:back
cmd:forward
cmd:cut
cmd:copy
cmd:paste
cmd:del
cmd:selectall
Compiling the plugin for Windows: