mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
implemented autotracking, hightrack is no longer quite so obnoxious.
implement cfg_save_all cvar, so cfg_save can save all. downloads attempt to avoid using the fte/ gamedir actually registering r_tracker_frags cvar. fix ezhud wad image issues. fix mouse binds not working when running fullscreen. dedicated servers can now use getsurface builtins. gl_font can now attempt to use conchars subdir too. terrain editor can now display the areas which cannot accept the selected texture for painting. this should help reduce edges. attempt to fix some of the less-supported ports. don't be annoying with entity foo = someclass; fteqcc now offers to create files if you try opening one that doesn't exist. plugins can now query ping etc info properly. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4893 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
daa4496b7c
commit
3fd21ea6ea
52 changed files with 1097 additions and 437 deletions
|
@ -37,14 +37,163 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
char cl_spectatorgroup[] = "Spectator Tracking";
|
||||
|
||||
enum
|
||||
{
|
||||
TM_USER, //user hit jump and changed pov explicitly
|
||||
TM_HIGHTRACK, //tracking the player with the highest frags
|
||||
TM_KILLER, //switch to the previous person's killer.
|
||||
TM_MODHINTS, //using the mod's //at hints
|
||||
TM_STATS //parsing mvd stats and making our own choices
|
||||
} autotrackmode;
|
||||
int autotrack_hint; //the latest hint from the mod, might be negative for invalid.
|
||||
int autotrack_killer; //if someone kills the guy we're tracking, this is the guy we should switch to.
|
||||
char *autotrack_statsrule;
|
||||
static void QDECL CL_AutoTrackChanged(cvar_t *v, char *oldval)
|
||||
{
|
||||
Cam_AutoTrack_Update(v->string);
|
||||
}
|
||||
// track high fragger
|
||||
cvar_t cl_autotrack = CVARCD("cl_autotrack", "auto", CL_AutoTrackChanged, "Specifies the default tracking mode at the start of the map. Use the 'autotrack' command to reset/apply an auto-tracking mode without changing the default.\nValid values are: high, ^hkiller^h, mod, user. Other values are treated as weighting scripts for mvd playback, where available.");
|
||||
cvar_t cl_hightrack = SCVAR("cl_hightrack", "0");
|
||||
|
||||
cvar_t cl_chasecam = SCVAR("cl_chasecam", "1");
|
||||
cvar_t cl_selfcam = SCVAR("cl_selfcam", "1");
|
||||
|
||||
//cvar_t cl_camera_maxpitch = {"cl_camera_maxpitch", "10" };
|
||||
//cvar_t cl_camera_maxyaw = {"cl_camera_maxyaw", "30" };
|
||||
cvar_t cl_chasecam = SCVAR("cl_chasecam", "1");
|
||||
cvar_t cl_selfcam = SCVAR("cl_selfcam", "1");
|
||||
|
||||
void Cam_AutoTrack_Update(const char *mode)
|
||||
{
|
||||
if (!mode)
|
||||
mode = cl_autotrack.string;
|
||||
Z_Free(autotrack_statsrule);
|
||||
autotrack_statsrule = NULL;
|
||||
if (!*mode || !Q_strcasecmp(mode, "auto"))
|
||||
{
|
||||
if (cl_hightrack.ival)
|
||||
autotrackmode = TM_HIGHTRACK;
|
||||
else
|
||||
autotrackmode = TM_MODHINTS;
|
||||
}
|
||||
else if (!Q_strcasecmp(mode, "high"))
|
||||
autotrackmode = TM_HIGHTRACK;
|
||||
else if (!Q_strcasecmp(mode, "killer"))
|
||||
autotrackmode = TM_KILLER;
|
||||
else if (!Q_strcasecmp(mode, "mod"))
|
||||
autotrackmode = TM_MODHINTS;
|
||||
else if (!Q_strcasecmp(mode, "user") || !Q_strcasecmp(mode, "off"))
|
||||
autotrackmode = TM_USER;
|
||||
else
|
||||
{
|
||||
autotrackmode = TM_STATS;
|
||||
autotrack_statsrule = Z_StrDup(mode);
|
||||
}
|
||||
}
|
||||
static void Cam_AutoTrack_f(void)
|
||||
{
|
||||
if (*Cmd_Argv(1))
|
||||
Cam_AutoTrack_Update(Cmd_Argv(1));
|
||||
else
|
||||
Cam_AutoTrack_Update(NULL);
|
||||
}
|
||||
|
||||
|
||||
static float CL_TrackScore(player_info_t *pl, char *rule)
|
||||
{
|
||||
float score = 0;
|
||||
float val;
|
||||
int r;
|
||||
while (*rule)
|
||||
{
|
||||
r = *rule++;
|
||||
if (r == 'f')
|
||||
val = pl->frags;
|
||||
else if (r == 'l')
|
||||
val = pl->ping;
|
||||
else if (r == 'h')
|
||||
val = pl->statsf[STAT_HEALTH];
|
||||
else if (r == 'q')
|
||||
val = (pl->stats[STAT_ITEMS] & IT_QUAD)?1:0;
|
||||
else if (r == 'p')
|
||||
val = (pl->stats[STAT_ITEMS] & IT_INVULNERABILITY)?1:0;
|
||||
else if (r == 's')
|
||||
{
|
||||
int i = strtol(rule, &rule, 10);
|
||||
val = pl->statsf[i];
|
||||
}
|
||||
else if (r == '#')
|
||||
val = strtod(rule, &rule);
|
||||
else
|
||||
val = 0;
|
||||
|
||||
if (*rule == '*')
|
||||
{
|
||||
val *= strtod(rule+1, &rule);
|
||||
}
|
||||
|
||||
score += val;
|
||||
if (*rule == '+')
|
||||
rule++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
//returns the player with the highest frags
|
||||
static int CL_FindHighTrack(int seat, char *rule)
|
||||
{
|
||||
int j = -1;
|
||||
int i, k;
|
||||
float max, score;
|
||||
player_info_t *s;
|
||||
|
||||
//set a default to the currently tracked player, to reuse the current player we're tracking if someone lower equalises.
|
||||
j = cl.playerview[seat].cam_spec_track;
|
||||
if (j >= 0)
|
||||
max = CL_TrackScore(&cl.players[j], rule);
|
||||
else
|
||||
max = -9999;
|
||||
|
||||
for (i = 0; i < cl.allocated_client_slots; i++)
|
||||
{
|
||||
s = &cl.players[i];
|
||||
score = CL_TrackScore(s, rule);
|
||||
if (s->name[0] && !s->spectator && score > max)
|
||||
{
|
||||
if (j == i) //this was our default.
|
||||
continue;
|
||||
//skip it if an earlier seat is watching it already
|
||||
for (k = 0; k < seat; k++)
|
||||
{
|
||||
if (Cam_TrackNum(&cl.playerview[k]) == i)
|
||||
break;
|
||||
}
|
||||
if (cl.teamplay && seat && cl.playerview[0].cam_spec_track >= 0 && strcmp(cl.players[cl.playerview[0].cam_spec_track].team, s->team))
|
||||
continue; //when using multiview, keep tracking the team
|
||||
if (k == seat)
|
||||
{
|
||||
max = CL_TrackScore(s, rule);
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
static int CL_AutoTrack_Choose(int seat)
|
||||
{
|
||||
int best = -1;
|
||||
if (autotrackmode == TM_KILLER)
|
||||
best = autotrack_killer;
|
||||
if (autotrackmode == TM_MODHINTS && seat == 0 && autotrack_hint >= 0)
|
||||
best = autotrack_hint;
|
||||
if (autotrackmode == TM_STATS && cls.demoplayback == DPB_MVD)
|
||||
best = CL_FindHighTrack(seat, autotrack_statsrule);
|
||||
if (autotrackmode == TM_HIGHTRACK || best == -1)
|
||||
best = CL_FindHighTrack(seat, "f");
|
||||
//TM_USER should generally avoid autotracking
|
||||
autotrack_killer = best; //killer should continue to track whatever is currently tracked until its changed by frag message parsing
|
||||
return best;
|
||||
}
|
||||
|
||||
static int Cam_FindSortedPlayer(int number);
|
||||
|
||||
|
@ -111,6 +260,8 @@ void Cam_Lock(playerview_t *pv, int playernum)
|
|||
memcpy(&pv->stats, cl.players[playernum].stats, sizeof(pv->stats));
|
||||
pv->cam_locked = true; //instantly lock if the player is valid.
|
||||
pv->viewentity = playernum+1;
|
||||
if (cls.z_ext & Z_EXT_VIEWHEIGHT)
|
||||
pv->viewheight = cl.players[playernum].statsf[STAT_VIEWHEIGHT];
|
||||
}
|
||||
|
||||
Sbar_Changed();
|
||||
|
@ -245,32 +396,13 @@ static qboolean InitFlyby(playerview_t *pv, vec3_t selforigin, vec3_t playerorig
|
|||
|
||||
static void Cam_CheckHighTarget(playerview_t *pv)
|
||||
{
|
||||
int i, j, max;
|
||||
player_info_t *s;
|
||||
int j;
|
||||
playerview_t *spv;
|
||||
|
||||
j = -1;
|
||||
for (i = 0, max = -9999; i < cl.allocated_client_slots; i++)
|
||||
{
|
||||
s = &cl.players[i];
|
||||
if (s->name[0] && !s->spectator && s->frags > max)
|
||||
{
|
||||
//skip it if an earlier seat is watching it already
|
||||
for (spv = pv-1; spv >= cl.playerview && spv < &cl.playerview[cl.splitclients]; spv--)
|
||||
{
|
||||
if (Cam_TrackNum(spv) == i)
|
||||
break;
|
||||
}
|
||||
if (!(spv >= cl.playerview && spv < &cl.playerview[cl.splitclients]))
|
||||
{
|
||||
max = s->frags;
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
j = CL_AutoTrack_Choose(pv - cl.playerview);
|
||||
if (j >= 0)
|
||||
{
|
||||
if (!pv->cam_locked || cl.players[j].frags > cl.players[pv->cam_spec_track].frags)
|
||||
if (!pv->cam_locked || pv->cam_spec_track != j)
|
||||
{
|
||||
Cam_Lock(pv, j);
|
||||
//un-lock any higher seats watching our new target. this keeps things ordered.
|
||||
|
@ -350,7 +482,7 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
if (!cl.spectator || !cl.worldmodel) //can happen when the server changes level
|
||||
return;
|
||||
|
||||
if (cl_hightrack.value && !pv->cam_locked)
|
||||
if (autotrackmode != TM_USER && !pv->cam_locked)
|
||||
Cam_CheckHighTarget(pv);
|
||||
|
||||
if (!pv->cam_auto || cls.state != ca_active || cl.worldmodel->loadstate != MLS_LOADED)
|
||||
|
@ -359,7 +491,7 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
if (pv->cam_locked && (!cl.players[pv->cam_spec_track].name[0] || cl.players[pv->cam_spec_track].spectator))
|
||||
{
|
||||
pv->cam_locked = false;
|
||||
if (cl_hightrack.value)
|
||||
if (autotrackmode != TM_USER)
|
||||
Cam_CheckHighTarget(pv);
|
||||
else
|
||||
Cam_Unlock(pv);
|
||||
|
@ -443,7 +575,18 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
|
||||
void Cam_SetAutoTrack(int userid)
|
||||
{ //this is a hint from the server about who to track
|
||||
|
||||
int slot;
|
||||
playerview_t *pv = &cl.playerview[0];
|
||||
autotrack_hint = -1;
|
||||
for (slot = 0; slot < cl.allocated_client_slots; slot++)
|
||||
{
|
||||
if (cl.players[slot].userid == userid)
|
||||
{
|
||||
autotrack_hint = slot;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Con_Printf("//at: invalid userid\n");
|
||||
}
|
||||
|
||||
void Cam_TrackCrosshairedPlayer(playerview_t *pv)
|
||||
|
@ -594,10 +737,15 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (pv->cam_auto && cl_hightrack.ival)
|
||||
if (pv->cam_auto && autotrackmode != TM_USER)
|
||||
{
|
||||
Cam_CheckHighTarget(pv);
|
||||
return;
|
||||
if ((cmd->buttons & BUTTON_JUMP) && !(pv->cam_oldbuttons & BUTTON_JUMP))
|
||||
autotrackmode = TM_USER;
|
||||
else
|
||||
{
|
||||
Cam_CheckHighTarget(pv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pv->cam_locked)
|
||||
|
@ -692,7 +840,7 @@ static int Cam_FindSortedPlayer(int number)
|
|||
void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[seat];
|
||||
int slot, sortednum;
|
||||
int slot;
|
||||
player_info_t *s;
|
||||
char *e;
|
||||
|
||||
|
@ -840,12 +988,14 @@ void Cam_Track4_f(void)
|
|||
|
||||
void CL_InitCam(void)
|
||||
{
|
||||
Cvar_Register (&cl_autotrack, cl_spectatorgroup);
|
||||
Cvar_Register (&cl_hightrack, cl_spectatorgroup);
|
||||
Cvar_Register (&cl_chasecam, cl_spectatorgroup);
|
||||
// Cvar_Register (&cl_camera_maxpitch, cl_spectatorgroup);
|
||||
// Cvar_Register (&cl_camera_maxyaw, cl_spectatorgroup);
|
||||
// Cvar_Register (&cl_selfcam, cl_spectatorgroup);
|
||||
|
||||
Cmd_AddCommand("autotrack", Cam_AutoTrack_f); //reset it, if they jumped or something.
|
||||
Cmd_AddCommand("track", Cam_Track_f);
|
||||
Cmd_AddCommand("track1", Cam_Track1_f);
|
||||
Cmd_AddCommand("track2", Cam_Track2_f);
|
||||
|
|
|
@ -473,6 +473,9 @@ qboolean CL_GetDemoMessage (void)
|
|||
if (cls.timedemo)
|
||||
if (cls.td_startframe == -1 && cls.state == ca_active)
|
||||
{ //start the timer only once we are connected.
|
||||
//make sure everything is loaded, to avoid stalls
|
||||
COM_WorkerFullSync();
|
||||
|
||||
cls.td_starttime = Sys_DoubleTime();
|
||||
cls.td_startframe = host_framecount;
|
||||
|
||||
|
@ -748,6 +751,7 @@ readit:
|
|||
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
||||
{
|
||||
int seat;
|
||||
cl.defaultnetsplit = 0;
|
||||
switch(cls_lasttype)
|
||||
{
|
||||
case dem_multiple:
|
||||
|
@ -764,20 +768,30 @@ readit:
|
|||
olddemotime = demotime;
|
||||
goto readnext;
|
||||
}
|
||||
cl.defaultnetsplit = seat;
|
||||
break;
|
||||
case dem_single:
|
||||
for (seat = 0; seat < cl.splitclients; seat++)
|
||||
{
|
||||
tracknum = cl.playerview[seat].cam_spec_track;
|
||||
if (!cl.playerview[seat].cam_auto)
|
||||
tracknum = -1;
|
||||
if (tracknum == -1 || !(cls_lastto != tracknum))
|
||||
continue;
|
||||
}
|
||||
if (seat == cl.splitclients)
|
||||
{
|
||||
olddemotime = demotime;
|
||||
goto readnext;
|
||||
int maxseat = cl.splitclients;
|
||||
//only accept single messages that are directed to the first player view.
|
||||
//this is too problematic otherwise (apparently mvdsv doesn't use dem_multiple for team says any more).
|
||||
if (1)
|
||||
maxseat = 1;
|
||||
for (seat = 0; seat < maxseat; seat++)
|
||||
{
|
||||
tracknum = cl.playerview[seat].cam_spec_track;
|
||||
if (!cl.playerview[seat].cam_auto)
|
||||
tracknum = -1;
|
||||
if (tracknum == -1 || (cls_lastto != tracknum))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (seat == maxseat)
|
||||
{
|
||||
olddemotime = demotime;
|
||||
goto readnext;
|
||||
}
|
||||
cl.defaultnetsplit = seat;
|
||||
}
|
||||
break;
|
||||
case dem_all:
|
||||
|
|
|
@ -2015,6 +2015,7 @@ void CL_InitInput (void)
|
|||
Cmd_AddCommand ("+jump", IN_JumpDown);
|
||||
Cmd_AddCommand ("-jump", IN_JumpUp);
|
||||
Cmd_AddCommand ("impulse", IN_Impulse);
|
||||
Cmd_AddCommandD("weapon", IN_Impulse, "Partial implementation for compatibility"); //for pseudo-compat with ezquake.
|
||||
Cmd_AddCommand ("+klook", IN_KLookDown);
|
||||
Cmd_AddCommand ("-klook", IN_KLookUp);
|
||||
Cmd_AddCommand ("+mlook", IN_MLookDown);
|
||||
|
|
|
@ -62,7 +62,8 @@ extern cvar_t net_compress;
|
|||
|
||||
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_NOTFROMSERVER);
|
||||
cvar_t cfg_save_name = CVARFD("cfg_save_name", "fte", CVAR_ARCHIVE|CVAR_NOTFROMSERVER, "This is the config name that is saved by default when no argument is specified.");
|
||||
cvar_t cfg_save_all = CVARFD("cfg_save_all", "", CVAR_ARCHIVE|CVAR_NOTFROMSERVER, "If 1, cfg_save ALWAYS saves all cvars. If 0, cfg_save only ever saves archived cvars. If empty, cfg_saves all cvars only when an explicit filename was given.");
|
||||
|
||||
cvar_t cl_splitscreen = CVARD("cl_splitscreen", "0", "Enables splitscreen support. See also: allow_splitscreen, in_rawinput*, the \"p\" command.");
|
||||
|
||||
|
@ -297,6 +298,12 @@ void CL_UpdateWindowTitle(void)
|
|||
Q_snprintfz(title, sizeof(title), "%s: %s", fs_gamename.string, sv.name);
|
||||
else
|
||||
#endif
|
||||
if (cls.demoplayback)
|
||||
{
|
||||
extern char lastdemoname[];
|
||||
Q_snprintfz(title, sizeof(title), "%s: %s", fs_gamename.string, lastdemoname);
|
||||
}
|
||||
else
|
||||
Q_snprintfz(title, sizeof(title), "%s: %s", fs_gamename.string, cls.servername);
|
||||
break;
|
||||
case ca_disconnected:
|
||||
|
@ -3551,6 +3558,7 @@ void CL_Init (void)
|
|||
Cvar_Register (&developer, cl_controlgroup);
|
||||
|
||||
Cvar_Register (&cfg_save_name, cl_controlgroup);
|
||||
Cvar_Register (&cfg_save_all, cl_controlgroup);
|
||||
|
||||
Cvar_Register (&cl_sendguid, cl_controlgroup);
|
||||
Cvar_Register (&cl_defaultport, cl_controlgroup);
|
||||
|
@ -3809,6 +3817,7 @@ void CL_Init (void)
|
|||
|
||||
Ignore_Init();
|
||||
|
||||
Stats_Init();
|
||||
CL_ClearState(); //make sure the cl.* fields are set properly if there's no ssqc or whatever.
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ int CL_CalcNet (float scale)
|
|||
return percent;
|
||||
}
|
||||
|
||||
float CL_CalcNet2 (float *ping, float *ping_min, float *ping_max, float *ping_stddev)
|
||||
void CL_CalcNet2 (float *pings, float *pings_min, float *pings_max, float *pingms_stddev, float *pingfr, int *pingfr_min, int *pingfr_max, float *dropped, float *choked, float *invalid)
|
||||
{
|
||||
int i;
|
||||
outframe_t *frame;
|
||||
|
@ -365,11 +365,19 @@ float CL_CalcNet2 (float *ping, float *ping_min, float *ping_max, float *ping_st
|
|||
int pending = 0;
|
||||
int sent;
|
||||
int valid = 0;
|
||||
int fr;
|
||||
int nchoked = 0;
|
||||
int ninvalid = 0;
|
||||
// char st[80];
|
||||
|
||||
*ping = 0;
|
||||
*ping_max = 0;
|
||||
*ping_min = 1000000000000;
|
||||
*pings = 0;
|
||||
*pings_max = 0;
|
||||
*pings_min = 1000000000000;
|
||||
*pingfr = 0;
|
||||
*pingfr_max = 0;
|
||||
*pingfr_min = 0x7fffffff;
|
||||
*pingms_stddev = 0;
|
||||
|
||||
|
||||
sent = NET_TIMINGS;
|
||||
|
||||
|
@ -386,28 +394,53 @@ float CL_CalcNet2 (float *ping, float *ping_min, float *ping_max, float *ping_st
|
|||
else if (frame->latency == -1)
|
||||
lost++; // lost
|
||||
else if (frame->latency == -2)
|
||||
; // choked
|
||||
nchoked++; // choked
|
||||
else if (frame->latency == -3)
|
||||
sent--; // c2spps
|
||||
// else if (frame->invalid)
|
||||
// packet_latency[i&NET_TIMINGSMASK] = 9998; // invalid delta
|
||||
else if (frame->latency == -4)
|
||||
ninvalid++; //corrupt/wrong/dodgy/egads
|
||||
else
|
||||
{
|
||||
*ping += frame->latency;
|
||||
if (*ping_max < frame->latency)
|
||||
*ping_max = frame->latency;
|
||||
if (*ping_min > frame->latency)
|
||||
*ping_min = frame->latency;
|
||||
*pings += frame->latency;
|
||||
if (*pings_max < frame->latency)
|
||||
*pings_max = frame->latency;
|
||||
if (*pings_min > frame->latency)
|
||||
*pings_min = frame->latency;
|
||||
|
||||
fr = frame->cmd_sequence-frame->server_message_num;
|
||||
*pingfr += fr;
|
||||
if (*pingfr_max < fr)
|
||||
*pingfr_max = fr;
|
||||
if (*pingfr_min > fr)
|
||||
*pingfr_min = fr;
|
||||
valid++;
|
||||
}
|
||||
}
|
||||
|
||||
*ping /= valid;
|
||||
if (valid)
|
||||
{
|
||||
*pings /= valid;
|
||||
*pingfr /= valid;
|
||||
|
||||
//determine stddev, in milliseconds instead of seconds.
|
||||
for (i=cl.movesequence-UPDATE_BACKUP+1; i <= cl.movesequence; i++)
|
||||
{
|
||||
frame = &cl.outframes[i&UPDATE_MASK];
|
||||
if (i <= cl.lastackedmovesequence && frame->latency >= 0)
|
||||
{
|
||||
float dev = (frame->latency - *pings) * 1000;
|
||||
*pingms_stddev += dev*dev;
|
||||
}
|
||||
}
|
||||
*pingms_stddev = sqrt(*pingms_stddev/valid);
|
||||
}
|
||||
|
||||
if (pending == sent || sent < 1)
|
||||
return 1; //shouldn't ever happen.
|
||||
*dropped = 1; //shouldn't ever happen.
|
||||
else
|
||||
return lost / sent;
|
||||
*dropped = (float)lost / sent;
|
||||
*choked = (float)nchoked / sent;
|
||||
*invalid = (float)ninvalid / sent;
|
||||
}
|
||||
|
||||
void CL_AckedInputFrame(int inseq, int outseq, qboolean worldstateokay)
|
||||
|
@ -1725,7 +1758,7 @@ qboolean DL_Begun(qdownload_t *dl)
|
|||
else if (!strncmp(dl->tempname,"skins/",6))
|
||||
dl->fsroot = FS_PUBBASEGAMEONLY; //shared between gamedirs, so only use the basegame.
|
||||
else
|
||||
dl->fsroot = FS_GAMEONLY; //other files are relative to the active gamedir.
|
||||
dl->fsroot = FS_PUBGAMEONLY;//FS_GAMEONLY; //other files are relative to the active gamedir.
|
||||
|
||||
Q_snprintfz(dl->dclname, sizeof(dl->dclname), "%s.dcl", dl->tempname);
|
||||
|
||||
|
@ -3040,6 +3073,7 @@ void CLQW_ParseServerData (void)
|
|||
|
||||
// now waiting for downloads, etc
|
||||
cls.state = ca_onserver;
|
||||
Cam_AutoTrack_Update(NULL);
|
||||
|
||||
cl.sendprespawn = false;
|
||||
|
||||
|
@ -3107,6 +3141,7 @@ void CLQ2_ParseServerData (void)
|
|||
cl.minpitch = -89;
|
||||
cl.maxpitch = 89;
|
||||
cl.servercount = svcnt;
|
||||
Cam_AutoTrack_Update(NULL);
|
||||
|
||||
Stats_NewMap();
|
||||
|
||||
|
@ -3352,6 +3387,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
|||
|
||||
cls.signon = 0;
|
||||
cls.state = ca_onserver;
|
||||
Cam_AutoTrack_Update(NULL);
|
||||
|
||||
|
||||
//fill in the csqc stuff
|
||||
|
@ -5500,14 +5536,17 @@ void CL_PrintChat(player_info_t *plr, char *msg, int plrflags)
|
|||
// CL_PrintStandardMessage: takes non-chat net messages and performs name coloring
|
||||
// NOTE: msg is considered destroyable
|
||||
char acceptedchars[] = {'.', '?', '!', '\'', ',', ':', ' ', '\0'};
|
||||
void CL_PrintStandardMessage(char *msg, int printlevel)
|
||||
void CL_PrintStandardMessage(char *msgtext, int printlevel)
|
||||
{
|
||||
int i;
|
||||
player_info_t *p;
|
||||
extern cvar_t cl_standardmsg;
|
||||
char *begin = msg;
|
||||
extern cvar_t cl_standardmsg, msg;
|
||||
char *begin = msgtext;
|
||||
char fullmessage[2048];
|
||||
|
||||
if (printlevel < msg.ival)
|
||||
return;
|
||||
|
||||
fullmessage[0] = 0;
|
||||
|
||||
// search for player names in message
|
||||
|
@ -5523,7 +5562,7 @@ void CL_PrintStandardMessage(char *msg, int printlevel)
|
|||
if (!(*name))
|
||||
continue;
|
||||
len = strlen(name);
|
||||
v = strstr(msg, name);
|
||||
v = strstr(msgtext, name);
|
||||
while (v)
|
||||
{
|
||||
// name parsing rules
|
||||
|
@ -5554,8 +5593,8 @@ void CL_PrintStandardMessage(char *msg, int printlevel)
|
|||
*v = 0; // cut off message
|
||||
|
||||
// print msg chunk
|
||||
Q_strncatz(fullmessage, msg, sizeof(fullmessage));
|
||||
msg = v + len; // update search point
|
||||
Q_strncatz(fullmessage, msgtext, sizeof(fullmessage));
|
||||
msgtext = v + len; // update search point
|
||||
|
||||
// get name color
|
||||
if (p->spectator || cl_standardmsg.ival)
|
||||
|
@ -5573,7 +5612,7 @@ void CL_PrintStandardMessage(char *msg, int printlevel)
|
|||
}
|
||||
|
||||
// print final chunk
|
||||
Q_strncatz(fullmessage, msg, sizeof(fullmessage));
|
||||
Q_strncatz(fullmessage, msgtext, sizeof(fullmessage));
|
||||
Con_Printf("%s", fullmessage);
|
||||
}
|
||||
|
||||
|
@ -5704,6 +5743,11 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
|
|||
{
|
||||
Cam_SetAutoTrack(atoi(stufftext+5));
|
||||
}
|
||||
else if (!strncmp(stufftext, "//wps ", 5))
|
||||
{
|
||||
//weapon stats, eg:
|
||||
//wps CLIENT WNAME attacks hits
|
||||
}
|
||||
else if (!strncmp(stufftext, "//kickfile ", 11))
|
||||
{
|
||||
flocation_t loc;
|
||||
|
@ -5958,7 +6002,7 @@ void CLQW_ParseServerMessage (void)
|
|||
cmd = MSG_ReadByte();
|
||||
}
|
||||
else
|
||||
destsplit = 0;
|
||||
destsplit = cl.defaultnetsplit;
|
||||
|
||||
if (cmd == -1)
|
||||
{
|
||||
|
|
|
@ -529,12 +529,20 @@ typedef struct {
|
|||
int seats;
|
||||
struct
|
||||
{
|
||||
float avg;
|
||||
float mn;
|
||||
float mx;
|
||||
float stddev;
|
||||
float loss;
|
||||
float s_avg;
|
||||
float s_mn;
|
||||
float s_mx;
|
||||
float ms_stddev;
|
||||
float fr_avg;
|
||||
int fr_mn;
|
||||
int fr_mx;
|
||||
} ping;
|
||||
struct
|
||||
{ //decimals
|
||||
float dropped;
|
||||
float choked;
|
||||
float invalid;
|
||||
} loss;
|
||||
float mlatency;
|
||||
float mrate;
|
||||
float vlatency;
|
||||
|
@ -555,6 +563,7 @@ typedef struct {
|
|||
float out_pps;
|
||||
float out_bps;
|
||||
} svrate;
|
||||
int capturing;
|
||||
} vmnetinfo_t;
|
||||
#define has(x) (((quintptr_t)&((vmnetinfo_t*)NULL)->x + sizeof(((vmnetinfo_t*)NULL)->x)) <= outlen)
|
||||
//aka: misc other hud timing crap
|
||||
|
@ -564,11 +573,20 @@ static qintptr_t VARGS Plug_GetNetworkInfo(void *offset, quintptr_t mask, const
|
|||
unsigned int outlen = VM_LONG(arg[1]);
|
||||
if (VM_OOB(arg[0], outlen))
|
||||
return false;
|
||||
|
||||
if (has(capturing))
|
||||
{
|
||||
#ifdef NOMEDIA
|
||||
outptr->capturing = 0;
|
||||
#else
|
||||
outptr->capturing = Media_Capturing();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (has(seats))
|
||||
outptr->seats = cl.splitclients;
|
||||
if (has(ping))
|
||||
outptr->ping.loss = CL_CalcNet2 (&outptr->ping.avg, &outptr->ping.mn, &outptr->ping.mx, &outptr->ping.stddev);
|
||||
CL_CalcNet2 (&outptr->ping.s_avg, &outptr->ping.s_mn, &outptr->ping.s_mx, &outptr->ping.ms_stddev, &outptr->ping.fr_avg, &outptr->ping.fr_mn, &outptr->ping.fr_mx, &outptr->loss.dropped, &outptr->loss.choked, &outptr->loss.invalid);
|
||||
|
||||
if (has(mlatency))
|
||||
outptr->mlatency = 0;
|
||||
|
@ -975,7 +993,7 @@ void Plug_Client_Init(void)
|
|||
Plug_RegisterBuiltin("GetLocalPlayerNumbers", Plug_GetLocalPlayerNumbers, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("GetServerInfo", Plug_GetServerInfo, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("SetUserInfo", Plug_SetUserInfo, PLUG_BIF_NEEDSRENDERER);
|
||||
// Plug_RegisterBuiltin("GetNetworkInfo", Plug_GetNetworkInfo, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("GetNetworkInfo", Plug_GetNetworkInfo, PLUG_BIF_NEEDSRENDERER);
|
||||
|
||||
Plug_RegisterBuiltin("S_RawAudio", Plug_S_RawAudio, PLUG_BIF_NEEDSRENDERER);
|
||||
|
||||
|
|
|
@ -1399,38 +1399,6 @@ void SCR_DrawFPS (void)
|
|||
SCR_StringXY(str, show_fps_x.value, show_fps_y.value);
|
||||
}
|
||||
|
||||
void SCR_DrawUPS (void)
|
||||
{
|
||||
extern cvar_t show_speed;
|
||||
static double lastupstime;
|
||||
double t;
|
||||
static float lastups;
|
||||
char str[80];
|
||||
float *vel;
|
||||
int track;
|
||||
|
||||
if (!show_speed.ival)
|
||||
return;
|
||||
|
||||
t = Sys_DoubleTime();
|
||||
if ((t - lastupstime) >= 1.0/20)
|
||||
{
|
||||
if (cl.spectator)
|
||||
track = Cam_TrackNum(&cl.playerview[0]);
|
||||
else
|
||||
track = -1;
|
||||
if (track != -1)
|
||||
vel = cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[track].velocity;
|
||||
else
|
||||
vel = cl.playerview[0].simvel;
|
||||
lastups = sqrt((vel[0]*vel[0]) + (vel[1]*vel[1]));
|
||||
lastupstime = t;
|
||||
}
|
||||
|
||||
sprintf(str, "%3.1f UPS", lastups);
|
||||
SCR_StringXY(str, show_speed_x.value, show_speed_y.value);
|
||||
}
|
||||
|
||||
void SCR_DrawClock(void)
|
||||
{
|
||||
struct tm *newtime;
|
||||
|
@ -2486,7 +2454,6 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
|||
SCR_DrawNet ();
|
||||
SCR_DrawDisk();
|
||||
SCR_DrawFPS ();
|
||||
SCR_DrawUPS ();
|
||||
SCR_DrawClock();
|
||||
SCR_DrawGameClock();
|
||||
SCR_DrawTurtle ();
|
||||
|
@ -2494,12 +2461,7 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
|||
SCR_ShowPics_Draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
SCR_DrawFPS ();
|
||||
SCR_DrawUPS ();
|
||||
SCR_DrawClock();
|
||||
SCR_DrawGameClock();
|
||||
}
|
||||
SCR_CheckDrawCenterString ();
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ typedef struct player_info_s
|
|||
int prevcount;
|
||||
|
||||
int stats[MAX_CL_STATS];
|
||||
int statsf[MAX_CL_STATS];
|
||||
float statsf[MAX_CL_STATS];
|
||||
} player_info_t;
|
||||
|
||||
|
||||
|
@ -708,6 +708,7 @@ typedef struct
|
|||
//when running splitscreen, we have multiple viewports all active at once
|
||||
int splitclients; //we are running this many clients split screen.
|
||||
playerview_t playerview[MAX_SPLITS];
|
||||
int defaultnetsplit;//which multiview splitscreen to parse the message for (set by mvd playback code)
|
||||
|
||||
// localized movement vars
|
||||
float bunnyspeedcap;
|
||||
|
@ -1092,7 +1093,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result);
|
|||
#define NET_TIMINGSMASK 255
|
||||
extern int packet_latency[NET_TIMINGS];
|
||||
int CL_CalcNet (float scale);
|
||||
float CL_CalcNet2 (float *ping, float *ping_min, float *ping_max, float *ping_stddev);
|
||||
void CL_CalcNet2 (float *pings, float *pings_min, float *pings_max, float *pingms_stddev, float *pingfr, int *pingfr_min, int *pingfr_max, float *dropped, float *choked, float *invalid);
|
||||
void CL_ClearParseState(void);
|
||||
void CL_Parse_Disconnected(void);
|
||||
void CL_DumpPacket(void);
|
||||
|
@ -1284,6 +1285,7 @@ void Cam_Reset(void);
|
|||
void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg);
|
||||
void Cam_Lock(playerview_t *pv, int playernum);
|
||||
void CL_InitCam(void);
|
||||
void Cam_AutoTrack_Update(const char *mode);
|
||||
|
||||
void QDECL vectoangles(vec3_t fwd, vec3_t ang);
|
||||
|
||||
|
@ -1484,6 +1486,7 @@ int qm_stricmp(char *s1, char *s2);
|
|||
qboolean Stats_ParsePrintLine(char *line);
|
||||
void Stats_NewMap(void);
|
||||
void Stats_Clear(void);
|
||||
void Stats_Init(void);
|
||||
|
||||
enum uploadfmt;
|
||||
typedef struct
|
||||
|
|
|
@ -524,6 +524,10 @@ void Stats_Clear(void)
|
|||
|
||||
#define Z_Copy(tk) tz = Z_Malloc(strlen(tk)+1);strcpy(tz, tk) //remember the braces
|
||||
|
||||
void Stats_Init(void)
|
||||
{
|
||||
Cvar_Register(&r_tracker_frags, NULL);
|
||||
}
|
||||
static void Stats_LoadFragFile(char *name)
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
|
|
|
@ -2281,6 +2281,7 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
|
|||
{
|
||||
texid_t tex = ctx;
|
||||
struct pendingtextureinfo *mips = data;
|
||||
|
||||
tex->width = mips->mip[0].width;
|
||||
tex->height = mips->mip[0].height;
|
||||
if (rf->IMG_LoadTextureMips(tex, mips))
|
||||
|
@ -2288,6 +2289,16 @@ static void Image_LoadTextureMips(void *ctx, void *data, size_t a, size_t b)
|
|||
else
|
||||
tex->status = TEX_FAILED;
|
||||
BZ_Free(mips);
|
||||
|
||||
if (!strncmp(tex->ident, "gfx/", 4))
|
||||
{
|
||||
qpic_t *pic = W_SafeGetLumpName(tex->ident+4);
|
||||
if (pic)
|
||||
{
|
||||
tex->width = pic->width;
|
||||
tex->height = pic->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
|
||||
|
@ -4432,6 +4443,8 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
|
|||
Image_GenerateMips(&mips, flags);
|
||||
Image_ChangeFormat(&mips, fmt);
|
||||
rf->IMG_LoadTextureMips(tex, &mips);
|
||||
tex->width = mips.mip[0].width;
|
||||
tex->height = mips.mip[0].height;
|
||||
tex->status = TEX_LOADED;
|
||||
}
|
||||
|
||||
|
|
|
@ -2314,9 +2314,12 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
|
||||
if (key == K_MOUSE1 && IN_MouseDevIsTouch(devid))
|
||||
{
|
||||
dc = SCR_ShowPics_ClickCommand(mousecursor_x, mousecursor_y);
|
||||
if (dc)
|
||||
char *button = SCR_ShowPics_ClickCommand(mousecursor_x, mousecursor_y);
|
||||
if (button)
|
||||
{
|
||||
dc = button;
|
||||
bl = RESTRICT_INSECURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bkey = Sbar_TranslateHudClick();
|
||||
|
@ -2327,7 +2330,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
}
|
||||
}
|
||||
|
||||
if (!dc) //no buttons to click,
|
||||
if (!button) //no buttons to click,
|
||||
{
|
||||
bkey = IN_TranslateMButtonPress(devid);
|
||||
if (bkey)
|
||||
|
@ -2335,7 +2338,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
dc = keybindings[bkey][modifierstate];
|
||||
bl = bindcmdlevel[bkey][modifierstate];
|
||||
}
|
||||
else
|
||||
else if (!Key_MouseShouldBeFree())
|
||||
{
|
||||
key_repeats[key] = 0;
|
||||
return;
|
||||
|
|
|
@ -2536,6 +2536,7 @@ struct capture_raw_ctx
|
|||
vfsfile_t *audio;
|
||||
};
|
||||
|
||||
qboolean FS_FixPath(char *path, size_t pathsize);
|
||||
static void *QDECL capture_raw_begin (char *streamname, int videorate, int width, int height, int *sndkhz, int *sndchannels, int *sndbits)
|
||||
{
|
||||
struct capture_raw_ctx *ctx = Z_Malloc(sizeof(*ctx));
|
||||
|
@ -2550,6 +2551,11 @@ static void *QDECL capture_raw_begin (char *streamname, int videorate, int width
|
|||
Z_Free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
if (!FS_FixPath(ctx->videonameprefix, sizeof(ctx->videonameprefix)))
|
||||
{
|
||||
Z_Free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->fsroot = FS_SYSTEM;
|
||||
ctx->audio = NULL;
|
||||
if (*sndkhz)
|
||||
|
@ -2563,7 +2569,7 @@ static void *QDECL capture_raw_begin (char *streamname, int videorate, int width
|
|||
*sndchannels = 6;
|
||||
if (*sndchannels < 1)
|
||||
*sndchannels = 1;
|
||||
Q_snprintfz(filename, sizeof(filename), "%s/audio_%ichan_%ikhz_%ib.raw", ctx->videonameprefix, *sndchannels, *sndkhz/1000, *sndbits);
|
||||
Q_snprintfz(filename, sizeof(filename), "%saudio_%ichan_%ikhz_%ib.raw", ctx->videonameprefix, *sndchannels, *sndkhz/1000, *sndbits);
|
||||
FS_CreatePath(filename, ctx->fsroot);
|
||||
ctx->audio = FS_OpenVFS(filename, "wb", ctx->fsroot);
|
||||
}
|
||||
|
@ -2580,7 +2586,7 @@ static void QDECL capture_raw_video (void *vctx, void *data, int frame, int widt
|
|||
struct capture_raw_ctx *ctx = vctx;
|
||||
char filename[MAX_OSPATH];
|
||||
ctx->frames = frame+1;
|
||||
Q_snprintfz(filename, sizeof(filename), "%s/%8.8i.%s", ctx->videonameprefix, frame, ctx->videonameextension);
|
||||
Q_snprintfz(filename, sizeof(filename), "%s%8.8i.%s", ctx->videonameprefix, frame, ctx->videonameextension);
|
||||
SCR_ScreenShot(filename, ctx->fsroot, data, width, height);
|
||||
}
|
||||
static void QDECL capture_raw_audio (void *vctx, void *data, int bytes)
|
||||
|
@ -3205,6 +3211,12 @@ void Media_RecordDemo_f(void)
|
|||
}
|
||||
|
||||
CL_PlayDemo(Cmd_Argv(1), false);
|
||||
if (!cls.demoplayback)
|
||||
{
|
||||
Con_Printf("unable to play demo, not capturing\n");
|
||||
return;
|
||||
}
|
||||
//FIXME: mamke sure it loaded okay
|
||||
if (Cmd_Argc() > 2)
|
||||
Cmd_ShiftArgs(1, false);
|
||||
Media_RecordFilm_f();
|
||||
|
|
|
@ -105,7 +105,7 @@ void M_DrawTextBox (int x, int y, int width, int lines)
|
|||
M_DrawScalePic (cx, cy+8, 8, 8, p);
|
||||
}
|
||||
|
||||
int M_FindKeysForBind (char *command, int *keylist, int *keymods, int total)
|
||||
int M_FindKeysForBind (const char *command, int *keylist, int *keymods, int total)
|
||||
{
|
||||
int count;
|
||||
int j, m;
|
||||
|
|
|
@ -468,7 +468,7 @@ void M_Keyup (int key, int unicode);
|
|||
void M_Draw (int uimenu);
|
||||
#endif
|
||||
void M_FindKeysForCommand (int pnum, const char *command, int *twokeys);
|
||||
int M_FindKeysForBind (char *command, int *keylist, int *keymods, int total);
|
||||
int M_FindKeysForBind (const char *command, int *keylist, int *keymods, int total);
|
||||
|
||||
void M_Media_Draw (void);
|
||||
void M_Media_Key (int key);
|
||||
|
|
|
@ -389,7 +389,10 @@ static void PClassic_DrawParticles(void)
|
|||
particleframe = -1;
|
||||
}
|
||||
|
||||
r_partscale = 0.004 * tan (r_refdef.fov_x * (M_PI / 180) * 0.5f);
|
||||
if (r_refdef.useperspective)
|
||||
r_partscale = 0.004 * tan (r_refdef.fov_x * (M_PI / 180) * 0.5f);
|
||||
else
|
||||
r_partscale = 0;
|
||||
VectorScale (vup, 1.5, up);
|
||||
VectorScale (vright, 1.5, right);
|
||||
|
||||
|
|
|
@ -1310,17 +1310,21 @@ void buildmatricies(void)
|
|||
float modelview[16];
|
||||
float proj[16];
|
||||
float ofovx = r_refdef.fov_x,ofovy=r_refdef.fov_y;
|
||||
extern cvar_t gl_mindist, gl_maxdist;
|
||||
|
||||
V_ApplyAFov(csqc_playerview);
|
||||
|
||||
/*build modelview and projection*/
|
||||
/*build view and projection matricies*/
|
||||
Matrix4x4_CM_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg);
|
||||
Matrix4x4_CM_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4);
|
||||
if (r_refdef.useperspective)
|
||||
Matrix4x4_CM_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4);
|
||||
else
|
||||
Matrix4x4_CM_Orthographic(proj, -r_refdef.fov_x/2, r_refdef.fov_x/2, -r_refdef.fov_y/2, r_refdef.fov_y/2, gl_mindist.value, gl_maxdist.value>=1?gl_maxdist.value:9999);
|
||||
|
||||
/*build the project matrix*/
|
||||
/*build the vp matrix*/
|
||||
Matrix4_Multiply(proj, modelview, csqc_proj_matrix);
|
||||
|
||||
/*build the unproject matrix (inverted project matrix)*/
|
||||
/*build the unproject matrix (inverted vp matrix)*/
|
||||
Matrix4_Invert(csqc_proj_matrix, csqc_proj_matrix_inverse);
|
||||
|
||||
csqc_rebuildmatricies = false;
|
||||
|
@ -1378,7 +1382,7 @@ static void QCBUILTIN PF_cs_unproject (pubprogfuncs_t *prinst, struct globalvars
|
|||
ty = 1-ty;
|
||||
v[0] = tx*2-1;
|
||||
v[1] = ty*2-1;
|
||||
v[2] = in[2];//*2-1;
|
||||
v[2] = in[2]*2-1; //gl projection matrix scales -1 to 1 (unlike d3d, which is 0 to 1)
|
||||
v[3] = 1;
|
||||
|
||||
//don't use 1, because the far clip plane really is an infinite distance away. and that tends to result division by infinity.
|
||||
|
@ -4229,7 +4233,7 @@ qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state)
|
|||
|
||||
csqcdelta_playerents[playernum] = ent;
|
||||
|
||||
return true;
|
||||
return G_FLOAT(OFS_RETURN);
|
||||
}
|
||||
else if (csqcdelta_playerents[playernum])
|
||||
{
|
||||
|
|
|
@ -366,23 +366,12 @@ mpic_t *R2D_SafeCachePic (const char *path)
|
|||
|
||||
mpic_t *R2D_SafePicFromWad (const char *name)
|
||||
{
|
||||
char newnamewad[32];
|
||||
char newnamegfx[32];
|
||||
void Shader_Default2D(const char *shortname, shader_t *s, const void *genargs);
|
||||
shader_t *s;
|
||||
|
||||
snprintf(newnamewad, sizeof(newnamewad), "wad/%s", name);
|
||||
snprintf(newnamegfx, sizeof(newnamegfx), "gfx/%s", name);
|
||||
|
||||
/*
|
||||
s = R_RegisterPic(newnamewad);
|
||||
if (!(s->flags & SHADER_NOIMAGE))
|
||||
return s;
|
||||
*/
|
||||
s = R_RegisterPic(newnamegfx);
|
||||
// if (!(s->flags & SHADER_NOIMAGE))
|
||||
return s;
|
||||
|
||||
// return NULL;
|
||||
if (!qrenderer)
|
||||
return NULL;
|
||||
s = R_RegisterCustom (va("gfx/%s", name), SUF_2D, Shader_Default2D, "wad");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2615,6 +2615,42 @@ static void Sbar_Voice(int y)
|
|||
#endif
|
||||
}
|
||||
|
||||
void SCR_StringXY(char *str, float x, float y);
|
||||
void SCR_DrawClock(void);
|
||||
void SCR_DrawGameClock(void);
|
||||
static void Sbar_DrawUPS(playerview_t *pv)
|
||||
{
|
||||
extern cvar_t show_speed;
|
||||
static double lastupstime;
|
||||
double t;
|
||||
static float lastups;
|
||||
char str[80];
|
||||
float *vel;
|
||||
int track;
|
||||
extern cvar_t show_speed_x;
|
||||
extern cvar_t show_speed_y;
|
||||
|
||||
if (!show_speed.ival)
|
||||
return;
|
||||
|
||||
t = Sys_DoubleTime();
|
||||
if ((t - lastupstime) >= 1.0/20)
|
||||
{
|
||||
if (cl.spectator)
|
||||
track = Cam_TrackNum(pv);
|
||||
else
|
||||
track = -1;
|
||||
if (track != -1)
|
||||
vel = cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[track].velocity;
|
||||
else
|
||||
vel = pv->simvel;
|
||||
lastups = sqrt((vel[0]*vel[0]) + (vel[1]*vel[1]));
|
||||
lastupstime = t;
|
||||
}
|
||||
|
||||
sprintf(str, "%3.1f UPS", lastups);
|
||||
SCR_StringXY(str, show_speed_x.value, show_speed_y.value);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -2807,6 +2843,11 @@ void Sbar_Draw (playerview_t *pv)
|
|||
if (scr_chatmode)
|
||||
Sbar_ChatModeOverlay(pv);
|
||||
}
|
||||
|
||||
|
||||
Sbar_DrawUPS (pv);
|
||||
SCR_DrawClock();
|
||||
SCR_DrawGameClock();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -2455,16 +2455,19 @@ void S_StopAllSounds(qboolean clear)
|
|||
if (sc->channel[i].sfx)
|
||||
{
|
||||
s = sc->channel[i].sfx;
|
||||
sc->channel[i].sfx = NULL;
|
||||
if (s->loadstate == SLS_LOADING)
|
||||
COM_WorkerPartialSync(s, &s->loadstate, SLS_LOADING);
|
||||
if (s->decoder.ended)
|
||||
if (!S_IsPlayingSomewhere(s)) //if we aint playing it elsewhere, free it compleatly.
|
||||
;//COM_WorkerPartialSync(s, &s->loadstate, SLS_LOADING);
|
||||
else
|
||||
{
|
||||
s->decoder.ended(s);
|
||||
sc->channel[i].sfx = NULL;
|
||||
if (s->decoder.ended)
|
||||
if (!S_IsPlayingSomewhere(s)) //if we aint playing it elsewhere, free it compleatly.
|
||||
{
|
||||
s->decoder.ended(s);
|
||||
}
|
||||
if (sc->ChannelUpdate)
|
||||
sc->ChannelUpdate(sc, &sc->channel[i], true);
|
||||
}
|
||||
if (sc->ChannelUpdate)
|
||||
sc->ChannelUpdate(sc, &sc->channel[i], true);
|
||||
}
|
||||
|
||||
sc->total_chans = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS + NUM_MUSICS; // no statics
|
||||
|
|
|
@ -33,40 +33,40 @@ void Sys_CloseLibrary(dllhandle_t *lib)
|
|||
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
|
||||
{
|
||||
char soname[MAX_OSPATH];
|
||||
int i;
|
||||
dllhandle_t lib;
|
||||
int i;
|
||||
dllhandle_t *lib;
|
||||
|
||||
lib = NULL;
|
||||
if (!lib)
|
||||
lib = NULL;
|
||||
if (!lib)
|
||||
{
|
||||
Q_snprintfz(soname, sizeof(soname), "%s.so", name);
|
||||
lib = dlopen (soname, RTLD_LAZY);
|
||||
lib = (dllhandle_t*)dlopen (soname, RTLD_LAZY);
|
||||
}
|
||||
if (!lib)
|
||||
lib = (dllhandle_t*)dlopen (name, RTLD_LAZY);
|
||||
if (!lib)
|
||||
{
|
||||
Con_Printf("%s\n", dlerror());
|
||||
return NULL;
|
||||
}
|
||||
if (!lib)
|
||||
lib = dlopen (name, RTLD_LAZY);
|
||||
if (!lib)
|
||||
{
|
||||
Con_Printf("%s\n", dlerror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (funcs)
|
||||
{
|
||||
for (i = 0; funcs[i].name; i++)
|
||||
{
|
||||
*funcs[i].funcptr = dlsym(lib, funcs[i].name);
|
||||
if (!*funcs[i].funcptr)
|
||||
break;
|
||||
}
|
||||
if (funcs[i].name)
|
||||
{
|
||||
Con_Printf("Unable to find symbol \"%s\" in \"%s\"\n", funcs[i].name, name);
|
||||
Sys_CloseLibrary((dllhandle_t*)lib);
|
||||
lib = NULL;
|
||||
}
|
||||
}
|
||||
if (funcs)
|
||||
{
|
||||
for (i = 0; funcs[i].name; i++)
|
||||
{
|
||||
*funcs[i].funcptr = dlsym(lib, funcs[i].name);
|
||||
if (!*funcs[i].funcptr)
|
||||
break;
|
||||
}
|
||||
if (funcs[i].name)
|
||||
{
|
||||
Con_Printf("Unable to find symbol \"%s\" in \"%s\"\n", funcs[i].name, name);
|
||||
Sys_CloseLibrary((dllhandle_t*)lib);
|
||||
lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (dllhandle_t*)lib;
|
||||
return (dllhandle_t*)lib;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -578,7 +578,7 @@ vfsfile_t *VFSPIPE_Open(void)
|
|||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
qboolean MyRegGetStringValue(HKEY base, const char *keyname, const char *valuename, void *data, size_t datalen)
|
||||
qboolean MyRegGetStringValue(void *base, const char *keyname, const char *valuename, void *data, size_t datalen)
|
||||
{
|
||||
qboolean result = false;
|
||||
HKEY subkey;
|
||||
|
|
|
@ -721,7 +721,7 @@ void Sys_Sleep (double seconds)
|
|||
|
||||
|
||||
#ifdef HAVEAUTOUPDATE
|
||||
int Sys_GetAutoUpdateSetting(void);
|
||||
int Sys_GetAutoUpdateSetting(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -2883,21 +2883,23 @@ qboolean Sys_CheckUpdated(char *bindir, size_t bindirsize)
|
|||
|
||||
if (*updatedpath)
|
||||
{
|
||||
//fixme: unicode paths/commandline.
|
||||
GetModuleFileName(NULL, frontendpath, sizeof(frontendpath)-1);
|
||||
if (CreateProcess(updatedpath, va("\"%s\" %s --fromfrontend \"%s\" \"%s\"", frontendpath, COM_Parse(GetCommandLineA()), SVNREVISIONSTR, frontendpath), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo))
|
||||
if (CreateProcess(updatedpath, va("%s --fromfrontend \"%s\" \"%s\"", GetCommandLineA(), SVNREVISIONSTR, frontendpath), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char frontendpath[MAX_OSPATH];
|
||||
// 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))
|
||||
{
|
||||
wchar_t wide1[2048];
|
||||
//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))
|
||||
// GetModuleFileName(NULL, frontendpath, sizeof(frontendpath)-1);
|
||||
if (CreateProcessW(widen(wide1, sizeof(wide1), com_argv[ffe+2]), GetCommandLineW(), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo))
|
||||
return true;
|
||||
}
|
||||
if (com_argv[ffe+2])
|
||||
|
@ -3167,7 +3169,11 @@ int MessageBoxU(HWND hWnd, char *lpText, char *lpCaption, UINT uType)
|
|||
#ifdef WEBCLIENT
|
||||
//using this like posix' access function, but with much more code, microsoftisms, and no errno codes/info
|
||||
//no, I don't really have a clue why it needs to be so long.
|
||||
#include <svrapi.h>
|
||||
//#include <svrapi.h>
|
||||
#ifndef ACCESS_READ
|
||||
#define ACCESS_READ 0x1
|
||||
#define ACCESS_WRITE 0x2
|
||||
#endif
|
||||
static BOOL microsoft_accessW(LPWSTR pszFolder, DWORD dwAccessDesired)
|
||||
{
|
||||
HANDLE hToken;
|
||||
|
@ -3354,8 +3360,8 @@ static INT CALLBACK StupidBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LP
|
|||
}
|
||||
}
|
||||
break;
|
||||
case BFFM_IUNKNOWN:
|
||||
break;
|
||||
// case BFFM_IUNKNOWN:
|
||||
// break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -526,23 +526,27 @@ void Validation_Apply_Ruleset(void)
|
|||
rulesetrule_t *rule;
|
||||
cvar_t *var;
|
||||
int i;
|
||||
char *rulesetname = ruleset.string;
|
||||
|
||||
if (!strcmp(rulesetname, "smackdown")) //officially, smackdown cannot authorise this, thus we do not use that name. however, imported configs tend to piss people off.
|
||||
rulesetname = "strict";
|
||||
|
||||
#ifdef warningmsg
|
||||
#pragma warningmsg("fixme: the following line should not be needed. ensure this is the case")
|
||||
#endif
|
||||
Validation_DelatchRulesets(); //make sure there's no old one
|
||||
|
||||
if (!*ruleset.string || !strcmp(ruleset.string, "none") || !strcmp(ruleset.string, "default"))
|
||||
if (!*rulesetname || !strcmp(rulesetname, "none") || !strcmp(rulesetname, "default"))
|
||||
return; //no ruleset is set
|
||||
|
||||
for (rs = rulesets; rs->rulesetname; rs++)
|
||||
{
|
||||
if (!stricmp(rs->rulesetname, ruleset.string))
|
||||
if (!stricmp(rs->rulesetname, rulesetname))
|
||||
break;
|
||||
}
|
||||
if (!rs->rulesetname)
|
||||
{
|
||||
Con_Printf("Cannot apply ruleset %s - not recognised\n", ruleset.string);
|
||||
Con_Printf("Cannot apply ruleset %s - not recognised\n", rulesetname);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -2950,6 +2950,7 @@ void Cmd_WriteConfig_f(void)
|
|||
char fname[MAX_OSPATH];
|
||||
char sysname[MAX_OSPATH];
|
||||
qboolean all = true;
|
||||
extern cvar_t cfg_save_all;
|
||||
|
||||
if (Cmd_IsInsecure() && Cmd_Argc() > 1)
|
||||
{
|
||||
|
@ -2969,7 +2970,7 @@ void Cmd_WriteConfig_f(void)
|
|||
FS_CreatePath(fname, FS_GAMEONLY);
|
||||
f = FS_OpenVFS(fname, "wbp", FS_GAMEONLY);
|
||||
|
||||
all = false;
|
||||
all = cfg_save_all.ival;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2985,7 +2986,7 @@ void Cmd_WriteConfig_f(void)
|
|||
FS_CreatePath(fname, FS_BASEGAMEONLY);
|
||||
f = FS_OpenVFS(fname, "wbp", FS_BASEGAMEONLY);
|
||||
|
||||
all = true;
|
||||
all = cfg_save_all.ival || !*cfg_save_all.string;
|
||||
}
|
||||
if (!f)
|
||||
{
|
||||
|
|
|
@ -1937,7 +1937,7 @@ void COM_FileBase (const char *in, char *out, int outlen)
|
|||
|
||||
s = in + strlen(in) - 1;
|
||||
|
||||
while (s > in && *s != '.')
|
||||
while (s > in && *s != '.' && *s != '/')
|
||||
s--;
|
||||
|
||||
for (s2 = s ; s2 > in && *s2 && *s2 != '/' ; s2--)
|
||||
|
|
|
@ -436,7 +436,8 @@ enum fs_relative{
|
|||
FS_ROOT, //./ (the root basepath or root homepath.)
|
||||
FS_GAMEONLY, //$gamedir/
|
||||
FS_GAMEDOWNLOADCACHE, //typically the same as FS_GAMEONLY
|
||||
FS_BASEGAMEONLY, //fte/ (fixme: should be the last basegame.)
|
||||
FS_BASEGAMEONLY, //fte/
|
||||
FS_PUBGAMEONLY, //$gamedir/ or qw/ but not fte/
|
||||
FS_PUBBASEGAMEONLY, //qw/ (fixme: should be the last non-private basedir)
|
||||
FS_SYSTEM //a system path. absolute paths are explicitly allowed and expected.
|
||||
};
|
||||
|
|
|
@ -1438,6 +1438,24 @@ qboolean FS_NativePath(const char *fname, enum fs_relative relativeto, char *out
|
|||
else
|
||||
snprintf(out, outlen, "%s%s/%s", com_gamepath, last, fname);
|
||||
break;
|
||||
case FS_PUBGAMEONLY:
|
||||
last = NULL;
|
||||
for (i = 0; i < sizeof(fs_manifest->gamepath)/sizeof(fs_manifest->gamepath[0]); i++)
|
||||
{
|
||||
if (fs_manifest->gamepath[i].path)
|
||||
{
|
||||
if (*fs_manifest->gamepath[i].path == '*')
|
||||
continue;
|
||||
last = fs_manifest->gamepath[i].path;
|
||||
}
|
||||
}
|
||||
if (!last)
|
||||
return false; //eep?
|
||||
if (com_homepathenabled)
|
||||
snprintf(out, outlen, "%s%s/%s", com_homepath, last, fname);
|
||||
else
|
||||
snprintf(out, outlen, "%s%s/%s", com_gamepath, last, fname);
|
||||
break;
|
||||
case FS_PUBBASEGAMEONLY:
|
||||
last = NULL;
|
||||
for (i = 0; i < sizeof(fs_manifest->gamepath)/sizeof(fs_manifest->gamepath[0]); i++)
|
||||
|
@ -1512,14 +1530,19 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r
|
|||
return VFSOS_Open(fullname, mode);
|
||||
}
|
||||
return NULL;
|
||||
case FS_PUBGAMEONLY:
|
||||
FS_NativePath(filename, relativeto, fullname, sizeof(fullname));
|
||||
if (*mode == 'w')
|
||||
COM_CreatePath(fullname);
|
||||
return VFSOS_Open(fullname, mode);
|
||||
case FS_GAME: //load from paks in preference to system paths. overwriting be damned.
|
||||
case FS_PUBBASEGAMEONLY: //load from paks in preference to system paths. overwriting be damned.
|
||||
FS_NativePath(filename, relativeto, fullname, sizeof(fullname));
|
||||
break;
|
||||
case FS_BINARYPATH:
|
||||
FS_NativePath(filename, relativeto, fullname, sizeof(fullname));
|
||||
if (*mode == 'w')
|
||||
COM_CreatePath(fullname);
|
||||
FS_NativePath(filename, relativeto, fullname, sizeof(fullname));
|
||||
return VFSOS_Open(fullname, mode);
|
||||
case FS_ROOT: //always bypass packs and gamedirs
|
||||
if (com_installer)
|
||||
|
@ -3327,13 +3350,13 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
|
|||
Q_snprintfz(syspath, sizeof(syspath), "%sid1/pak0.pak", prefix[i]);
|
||||
if (GetFileAttributesU(syspath) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
Q_strncpyz(basepath, prefix[i], sizeof(basepath));
|
||||
Q_strncpyz(basepath, prefix[i], basepathlen);
|
||||
return true;
|
||||
}
|
||||
Q_snprintfz(syspath, sizeof(syspath), "%squake.exe", prefix[i]);
|
||||
if (GetFileAttributesU(syspath) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
Q_strncpyz(basepath, prefix[i], sizeof(basepath));
|
||||
Q_strncpyz(basepath, prefix[i], basepathlen);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ fragmentation works like IP, offset and morefrags. offset is *8 (decode: (offset
|
|||
int net_drop;
|
||||
cvar_t showpackets = SCVAR("showpackets", "0");
|
||||
cvar_t showdrop = SCVAR("showdrop", "0");
|
||||
cvar_t qport = CVARF("qport", "0", CVAR_NOSAVE);
|
||||
cvar_t qport = CVARF("qport_", "0", CVAR_NOSAVE);
|
||||
cvar_t net_mtu = CVARD("net_mtu", "1440", "Specifies a maximum udp payload size, above which packets will be fragmented. If routers all worked properly this could be some massive value, and some massive value may work really nicely for lans. Use smaller values than the default if you're connecting through nested tunnels through routers that fail with IP fragmentation.");
|
||||
cvar_t net_compress = CVARD("net_compress", "0", "Enables huffman compression of network packets.");
|
||||
|
||||
|
|
|
@ -2338,8 +2338,15 @@ int FTENET_Generic_GetLocalAddresses(struct ftenet_generic_connection_s *con, un
|
|||
!*(int*)&adr.address.ip6[12])
|
||||
{
|
||||
//ipv6 socket bound to the ipv4-any address is a bit weird, but oh well.
|
||||
//FIXME: should we first validate that we support hybrid sockets?
|
||||
#ifdef _WIN32
|
||||
//win32 is buggy and treats binding to [::] as [::ffff:0.0.0.0] (even with pure ipv6 sockets)
|
||||
//explicitly binding to [::ffff:0.0.0.0] appears to fail in windows, thus any such socket will definitely support ipv6.
|
||||
qboolean canipv4 = (con->addrtype[0] == NA_IP) || (con->addrtype[1] == NA_IP);
|
||||
found = FTENET_GetLocalAddress(adr.port, false, canipv4, true, adrflags, addresses, maxaddresses);
|
||||
#else
|
||||
//FIXME: we should validate that we support hybrid sockets?
|
||||
found = FTENET_GetLocalAddress(adr.port, false, true, false, adrflags, addresses, maxaddresses);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2357,13 +2364,7 @@ int FTENET_Generic_GetLocalAddresses(struct ftenet_generic_connection_s *con, un
|
|||
ipx = true;
|
||||
else if (adr.type == NA_IPV6)
|
||||
{
|
||||
#ifdef IPV6_V6ONLY
|
||||
int ipv6only = true;
|
||||
int optlen = sizeof(ipv6only);
|
||||
getsockopt(con->thesocket, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6only, &optlen);
|
||||
if (!ipv6only)
|
||||
ipv4 = true;
|
||||
#endif
|
||||
ipv4 = (con->addrtype[0] == NA_IP) || (con->addrtype[1] == NA_IP);
|
||||
ipv6 = true;
|
||||
}
|
||||
|
||||
|
@ -2633,6 +2634,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
|
|||
*/
|
||||
((struct sockaddr_in6*)&qs)->sin6_port = port;
|
||||
temp = sizeof(struct sockaddr_in6);
|
||||
adr.type = NA_IPV6;
|
||||
hybrid = true;
|
||||
}
|
||||
else
|
||||
|
@ -5000,6 +5002,7 @@ void NET_PrintAddresses(ftenet_connections_t *collection)
|
|||
netadr_t addr[64];
|
||||
struct ftenet_generic_connection_s *con[sizeof(addr)/sizeof(addr[0])];
|
||||
int flags[sizeof(addr)/sizeof(addr[0])];
|
||||
qboolean warn = true;
|
||||
|
||||
if (!collection)
|
||||
return;
|
||||
|
@ -5008,11 +5011,73 @@ void NET_PrintAddresses(ftenet_connections_t *collection)
|
|||
|
||||
for (i = 0; i < m; i++)
|
||||
{
|
||||
if (addr[i].type == NA_INVALID)
|
||||
Con_Printf("net address (%s): no addresses\n", con[i]->name);
|
||||
else
|
||||
if (addr[i].type != NA_INVALID)
|
||||
{
|
||||
warn = false;
|
||||
if (addr[i].type == NA_LOOPBACK)
|
||||
{
|
||||
//we don't list 127.0.0.1 or ::1, so don't bother with this either. its not interesting.
|
||||
// Con_Printf("internal address (%s): %s\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if (addr[i].type == NA_IPV6)
|
||||
{
|
||||
if ((*(int*)addr[i].address.ip6&BigLong(0xffc00000)) == BigLong(0xfe800000)) //fe80::/10
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (link-local)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if ((*(int*)addr[i].address.ip6&BigLong(0xfe000000)) == BigLong(0xfc00000)) //fc::/7
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (ULA/private)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if (*(int*)addr[i].address.ip6 == BigLong(0x20010000)) //2001::/32
|
||||
{
|
||||
Con_Printf("net address (%s): %s (toredo)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if ((*(int*)addr[i].address.ip6&BigLong(0xffff0000)) == BigLong(0x20020000)) //2002::/16
|
||||
{
|
||||
Con_Printf("net address (%s): %s (6to4)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (addr[i].type == NA_IP)
|
||||
{
|
||||
if ((*(int*)addr[i].address.ip&BigLong(0xffff0000)) == BigLong(0xA9FE0000)) //169.254.x.x/16
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (link-local)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if ((*(int*)addr[i].address.ip&BigLong(0xff000000)) == BigLong(0x0a000000)) //10.x.x.x/8
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (private)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if ((*(int*)addr[i].address.ip&BigLong(0xfff00000)) == BigLong(0xac100000)) //172.16.x.x/12
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (private)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if ((*(int*)addr[i].address.ip&BigLong(0xffff0000)) == BigLong(0xc0a80000)) //192.168.x.x/16
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (private)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
if ((*(int*)addr[i].address.ip&BigLong(0xffc00000)) == BigLong(0x64400000)) //10.64.x.x/10
|
||||
{
|
||||
Con_Printf("lan address (%s): %s (CGNAT)\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Con_Printf("net address (%s): %s\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (warn)
|
||||
Con_Printf("net address (%s): no addresses\n", con[i]->name);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -279,7 +279,10 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
if (wantquit)
|
||||
return DEBUG_TRACE_ABORT;
|
||||
if (!*filename || !line || !*line) //don't try editing an empty line, it won't work
|
||||
{
|
||||
Con_Printf("Unable to debug, pelase disable optimisations\n");
|
||||
return DEBUG_TRACE_OFF;
|
||||
}
|
||||
Sys_SendKeyEvents();
|
||||
debuggerresume = -1;
|
||||
debuggerresumeline = *line;
|
||||
|
@ -532,6 +535,13 @@ void VARGS PR_CB_Free(void *mem)
|
|||
////////////////////////////////////////////////////
|
||||
//model functions
|
||||
//DP_QC_GETSURFACE
|
||||
static void PF_BuildSurfaceMesh(model_t *model, unsigned int surfnum)
|
||||
{
|
||||
void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *cookie);
|
||||
if (model->fromgame == fg_quake)
|
||||
ModQ1_Batches_BuildQ1Q2Poly(model, &model->surfaces[surfnum], NULL);
|
||||
//fixme: q3...
|
||||
}
|
||||
// #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
|
||||
void QCBUILTIN PF_getsurfacenumpoints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -551,9 +561,11 @@ void QCBUILTIN PF_getsurfacenumpoints(pubprogfuncs_t *prinst, struct globalvars_
|
|||
{
|
||||
surfnum += model->firstmodelsurface;
|
||||
if (!model->surfaces[surfnum].mesh)
|
||||
G_FLOAT(OFS_RETURN) = 0; //not loaded properly.
|
||||
else
|
||||
PF_BuildSurfaceMesh(model, surfnum);
|
||||
if (model->surfaces[surfnum].mesh)
|
||||
G_FLOAT(OFS_RETURN) = model->surfaces[surfnum].mesh->numvertexes;
|
||||
else
|
||||
G_FLOAT(OFS_RETURN) = 0; //not loaded properly.
|
||||
}
|
||||
}
|
||||
// #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
|
||||
|
@ -701,6 +713,13 @@ static float getsurface_clippointtri(model_t *model, msurface_t *surf, vec3_t po
|
|||
float dist;
|
||||
int e;
|
||||
float *v1, *v2;
|
||||
if (!mesh)
|
||||
{
|
||||
PF_BuildSurfaceMesh(model, surf - model->surfaces);
|
||||
mesh = surf->mesh;
|
||||
if (!mesh)
|
||||
return 0;
|
||||
}
|
||||
for (j = 0; j < mesh->numindexes; j+=3)
|
||||
{
|
||||
//calculate the distance from the plane
|
||||
|
@ -765,7 +784,7 @@ void QCBUILTIN PF_getsurfacenearpoint(pubprogfuncs_t *prinst, struct globalvars_
|
|||
if (!model || model->type != mod_brush)
|
||||
return;
|
||||
|
||||
if (model->fromgame == fg_quake)
|
||||
if (model->fromgame == fg_quake || model->fromgame == fg_quake2)
|
||||
{
|
||||
//all polies, we can skip parts. special case.
|
||||
surf = model->surfaces + model->firstmodelsurface;
|
||||
|
@ -855,7 +874,12 @@ void QCBUILTIN PF_getsurfacenumtriangles(pubprogfuncs_t *prinst, struct globalva
|
|||
else
|
||||
{
|
||||
surfnum += model->firstmodelsurface;
|
||||
G_FLOAT(OFS_RETURN) = model->surfaces[surfnum].mesh->numindexes/3;
|
||||
if (!model->surfaces[surfnum].mesh)
|
||||
PF_BuildSurfaceMesh(model, surfnum);
|
||||
if (model->surfaces[surfnum].mesh)
|
||||
G_FLOAT(OFS_RETURN) = model->surfaces[surfnum].mesh->numindexes/3;
|
||||
else
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
}
|
||||
}
|
||||
// #629 float(entity e, float s) getsurfacetriangle
|
||||
|
@ -876,6 +900,9 @@ void QCBUILTIN PF_getsurfacetriangle(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
{
|
||||
surfnum += model->firstmodelsurface;
|
||||
|
||||
if (!model->surfaces[surfnum].mesh)
|
||||
PF_BuildSurfaceMesh(model, surfnum);
|
||||
if (model->surfaces[surfnum].mesh)
|
||||
if (firstidx+2 < model->surfaces[surfnum].mesh->numindexes)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN+0) = model->surfaces[surfnum].mesh->indexes[firstidx+0];
|
||||
|
@ -905,6 +932,8 @@ void QCBUILTIN PF_getsurfacepointattribute(pubprogfuncs_t *prinst, struct global
|
|||
if (model && model->type == mod_brush && surfnum < model->nummodelsurfaces)
|
||||
{
|
||||
surfnum += model->firstmodelsurface;
|
||||
if (!model->surfaces[surfnum].mesh)
|
||||
PF_BuildSurfaceMesh(model, surfnum);
|
||||
if (model->surfaces[surfnum].mesh)
|
||||
if (pointnum < model->surfaces[surfnum].mesh->numvertexes)
|
||||
{
|
||||
|
@ -1367,12 +1396,20 @@ void QCBUILTIN PF_memalloc (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
{
|
||||
int size = G_INT(OFS_PARM0);
|
||||
void *ptr = prinst->AddressableAlloc(prinst, size);
|
||||
memset(ptr, 0, size);
|
||||
G_INT(OFS_RETURN) = (char*)ptr - prinst->stringtable;
|
||||
if (ptr)
|
||||
{
|
||||
memset(ptr, 0, size);
|
||||
G_INT(OFS_RETURN) = (char*)ptr - prinst->stringtable;
|
||||
}
|
||||
else
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
}
|
||||
void QCBUILTIN PF_memfree (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
prinst->AddressableFree(prinst, prinst->stringtable + G_INT(OFS_PARM0));
|
||||
int qcptr = G_INT(OFS_PARM0);
|
||||
void *cptr = prinst->stringtable + G_INT(OFS_PARM0);
|
||||
if (qcptr)
|
||||
prinst->AddressableFree(prinst, cptr);
|
||||
}
|
||||
void QCBUILTIN PF_memcpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -1731,7 +1768,7 @@ qboolean QC_FixFileName(const char *name, const char **result, const char **fall
|
|||
|
||||
*fallbackread = name;
|
||||
//if its a user config, ban any fallback locations so that csqc can't read passwords or whatever.
|
||||
if ((!strchr(name, '/') || strnicmp(name, "configs/", 8)) && !stricmp(COM_FileExtension(name, ext, sizeof(ext)), "cfg"))
|
||||
if ((!strchr(name, '/') || strnicmp(name, "configs/", 8)) && !stricmp(COM_FileExtension(name, ext, sizeof(ext)), "cfg") && strnicmp(name, "particles/", 10))
|
||||
*fallbackread = NULL;
|
||||
*result = va("data/%s", name);
|
||||
return true;
|
||||
|
|
|
@ -736,6 +736,8 @@ enum terrainedit_e
|
|||
|
||||
// ter_autopaint_h, //vector pos, float radius, float percent, string tex1, string tex2 (paint tex1/tex2
|
||||
// ter_autopaint_n //vector pos, float radius, float percent, string tex1, string tex2
|
||||
|
||||
ter_tex_mask //string tex
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
|
@ -135,8 +135,6 @@ typedef struct areanode_s
|
|||
link_t edicts;
|
||||
} areanode_t;
|
||||
|
||||
#define AREA_DEPTH 4
|
||||
#define AREA_NODES 32 //pow(2, AREA_DEPTH+1)
|
||||
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,wedict_t,area)
|
||||
|
||||
typedef struct wedict_s wedict_t;
|
||||
|
@ -186,7 +184,8 @@ struct world_s
|
|||
struct pubprogfuncs_s *progs;
|
||||
qboolean usesolidcorpse; //to disable SOLID_CORPSE when running hexen2 due to conflict.
|
||||
model_t *worldmodel;
|
||||
areanode_t areanodes[AREA_NODES];
|
||||
areanode_t *areanodes;
|
||||
int areanodedepth;
|
||||
int numareanodes;
|
||||
areanode_t portallist;
|
||||
|
||||
|
|
|
@ -1371,7 +1371,7 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
|
|||
//default to only map the ascii-compatible chars from the quake font.
|
||||
if (*fontfilename)
|
||||
{
|
||||
f->singletexture = R_LoadHiResTexture(fontfilename, "fonts", IF_UIPIC|IF_NOMIPMAP);
|
||||
f->singletexture = R_LoadHiResTexture(fontfilename, "fonts:charsets", IF_UIPIC|IF_NOMIPMAP);
|
||||
if (f->singletexture->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(f->singletexture, &f->singletexture->status, TEX_LOADING);
|
||||
}
|
||||
|
|
|
@ -341,6 +341,7 @@ typedef struct heightmap_s
|
|||
|
||||
|
||||
|
||||
char *texmask; //for editing - visually masks off the areas which CANNOT accept this texture
|
||||
struct relight_ctx_s *relightcontext;
|
||||
struct llightinfo_s *lightthreadmem;
|
||||
qboolean inheritedlightthreadmem;
|
||||
|
@ -462,6 +463,7 @@ static qboolean Terr_InitLightmap(hmsection_t *s, qboolean initialise)
|
|||
hm->numusedlmsects++;
|
||||
|
||||
Z_Free(lms);
|
||||
initialise = true;
|
||||
}
|
||||
|
||||
if (initialise && s->lightmap >= 0)
|
||||
|
@ -1873,7 +1875,7 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy
|
|||
for (x = 0; x < SECTIONSPERBLOCK; x++)
|
||||
{
|
||||
s = Terr_GetSection(hm, sx+x, sy+y, TGS_WAITLOAD|TGS_NODOWNLOAD);
|
||||
if (s && s->loadstate == TSLS_LOADED)
|
||||
if (s && s->loadstate == TSLS_LOADED && Terr_InitLightmap(s, false))
|
||||
{
|
||||
dbh.offset[y*SECTIONSPERBLOCK + x] = VFS_TELL(f);
|
||||
Terr_Save(hm, s, f, sx+x, sy+y, writever);
|
||||
|
@ -1974,6 +1976,7 @@ static hmsection_t *Terr_GetSection(heightmap_t *hm, int x, int y, unsigned int
|
|||
if (section->loadstate == TSLS_FAILED && (flags & TGS_DEFAULTONFAIL))
|
||||
{
|
||||
section->flags = (section->flags & ~TSF_EDITED);
|
||||
section->loadstate = TSLS_LOADED;
|
||||
Terr_ClearSection(section);
|
||||
Terr_GenerateDefault(hm, section);
|
||||
}
|
||||
|
@ -2972,6 +2975,24 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h)
|
|||
if (R_CullBox(mins, maxs))
|
||||
return;
|
||||
|
||||
|
||||
if (hm->texmask)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (!*s->texname[i])
|
||||
break;
|
||||
if (!strcmp(s->texname[i], hm->texmask))
|
||||
break;
|
||||
}
|
||||
if (i == 4)
|
||||
{ //flicker if the surface cannot accept the named texture
|
||||
int xor = (x&1)^(y&1);
|
||||
if (((int)(realtime*10) & 1) ^ xor)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
b = BE_GetTempBatch();
|
||||
if (!b)
|
||||
return;
|
||||
|
@ -3864,8 +3885,8 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
|
|||
*/
|
||||
|
||||
//make sure the start tile is valid
|
||||
for (y = pos[1] + emins[1]; y <= pos[1] + emaxs[1]; y++)
|
||||
for (x = pos[0] + emins[0]; x <= pos[0] + emaxs[0]; x++)
|
||||
for (y = pos[1] + emins[1]; y <= (int)(pos[1] + emaxs[1]); y++)
|
||||
for (x = pos[0] + emins[0]; x <= (int)(pos[0] + emaxs[0]); x++)
|
||||
Heightmap_Trace_Square(&hmtrace, x, y);
|
||||
for(;;)
|
||||
{
|
||||
|
@ -4239,7 +4260,7 @@ static void ted_texpaint(void *ctx, hmsection_t *s, int idx, float wx, float wy,
|
|||
unsigned char *lm = ted_getlightmap(s, idx);
|
||||
const char *texname = ctx;
|
||||
int t;
|
||||
vec3_t newval;
|
||||
vec4_t newval;
|
||||
if (w > 1)
|
||||
w = 1;
|
||||
|
||||
|
@ -4249,12 +4270,21 @@ static void ted_texpaint(void *ctx, hmsection_t *s, int idx, float wx, float wy,
|
|||
{
|
||||
if (!strncmp(s->texname[t], texname, sizeof(s->texname[t])-1))
|
||||
{
|
||||
int extra;
|
||||
newval[0] = (t == 0);
|
||||
newval[1] = (t == 1);
|
||||
newval[2] = (t == 2);
|
||||
newval[3] = (t == 3);
|
||||
extra = 255 - (lm[0]+lm[1]+lm[2]);
|
||||
lm[2] = lm[2]*(1-w) + (255*newval[0]*(w));
|
||||
lm[1] = lm[1]*(1-w) + (255*newval[1]*(w));
|
||||
lm[0] = lm[0]*(1-w) + (255*newval[2]*(w));
|
||||
extra = extra*(1-w) + (255*newval[3]*(w));
|
||||
|
||||
//the extra stuff is to cope with numerical precision. add any lost values to the new texture instead of the implicit one
|
||||
extra = 255 - (extra+lm[0]+lm[1]+lm[2]);
|
||||
if (t != 3)
|
||||
lm[2-t] += extra;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4651,6 +4681,15 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
G_INT(OFS_RETURN) = PR_TempString(prinst, s->texname[x]);
|
||||
}
|
||||
break;
|
||||
case ter_tex_mask:
|
||||
Z_Free(hm->texmask);
|
||||
hm->texmask = NULL;
|
||||
|
||||
if (G_INT(OFS_PARM1) == 0)
|
||||
hm->texmask = NULL;
|
||||
else
|
||||
hm->texmask = Z_StrDup(PR_GetStringOfs(prinst, OFS_PARM1));
|
||||
break;
|
||||
case ter_tex_kill:
|
||||
{
|
||||
int x, y;
|
||||
|
|
|
@ -2531,7 +2531,6 @@ qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, lump_t *
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *cookie)
|
||||
{
|
||||
unsigned int vertidx;
|
||||
|
@ -2543,6 +2542,22 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
|
|||
int sty;
|
||||
// int w,h;
|
||||
|
||||
if (!mesh)
|
||||
{
|
||||
mesh = surf->mesh = ZG_Malloc(&mod->memgroup, sizeof(mesh_t) + (sizeof(vecV_t)+sizeof(vec2_t)*(1+1)+sizeof(vec3_t)*3+sizeof(vec4_t)*1)* surf->numedges + sizeof(index_t)*(surf->numedges-2)*3);
|
||||
mesh->numvertexes = surf->numedges;
|
||||
mesh->numindexes = (mesh->numvertexes-2)*3;
|
||||
mesh->istrifan = true;
|
||||
mesh->xyz_array = (vecV_t*)(mesh+1);
|
||||
mesh->st_array = (vec2_t*)(mesh->xyz_array+mesh->numvertexes);
|
||||
mesh->lmst_array[0] = (vec2_t*)(mesh->st_array+mesh->numvertexes);
|
||||
mesh->normals_array = (vec3_t*)(mesh->lmst_array[0]+mesh->numvertexes);
|
||||
mesh->snormals_array = (vec3_t*)(mesh->normals_array+mesh->numvertexes);
|
||||
mesh->tnormals_array = (vec3_t*)(mesh->snormals_array+mesh->numvertexes);
|
||||
mesh->colors4f_array[0] = (vec4_t*)(mesh->tnormals_array+mesh->numvertexes);
|
||||
mesh->indexes = (index_t*)(mesh->colors4f_array[0]+mesh->numvertexes);
|
||||
}
|
||||
|
||||
//output the mesh's indicies
|
||||
for (i=0 ; i<mesh->numvertexes-2 ; i++)
|
||||
{
|
||||
|
@ -2580,10 +2595,15 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
|
|||
else
|
||||
*/
|
||||
{
|
||||
mesh->st_array[i][0] = s/surf->texinfo->texture->width;
|
||||
mesh->st_array[i][1] = t/surf->texinfo->texture->height;
|
||||
mesh->st_array[i][0] = s;
|
||||
mesh->st_array[i][1] = t;
|
||||
if (surf->texinfo->texture->width)
|
||||
mesh->st_array[i][0] /= surf->texinfo->texture->width;
|
||||
if (surf->texinfo->texture->height)
|
||||
mesh->st_array[i][1] /= surf->texinfo->texture->height;
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
if (gl_lightmap_average.ival)
|
||||
{
|
||||
for (sty = 0; sty < 1; sty++)
|
||||
|
@ -2593,6 +2613,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
|
|||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (sty = 0; sty < 1; sty++)
|
||||
{
|
||||
|
@ -2635,6 +2656,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *co
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindicies, void (*build)(model_t *mod, msurface_t *surf, builddata_t *bd), builddata_t *bd)
|
||||
{
|
||||
batch_t *batch;
|
||||
|
|
|
@ -489,7 +489,7 @@ void R_SetupGL (float stereooffset)
|
|||
}
|
||||
else
|
||||
{
|
||||
Matrix4x4_CM_Orthographic(r_refdef.m_projection, -fov_x/2, fov_x/2, -fov_y/2, fov_y/2, 0, gl_maxdist.value>=1?gl_maxdist.value:9999);
|
||||
Matrix4x4_CM_Orthographic(r_refdef.m_projection, -fov_x/2, fov_x/2, -fov_y/2, fov_y/2, gl_mindist.value, gl_maxdist.value>=1?gl_maxdist.value:9999);
|
||||
}
|
||||
|
||||
newa[0] = r_refdef.viewangles[0];
|
||||
|
|
|
@ -3253,8 +3253,6 @@ void Shader_Reset(shader_t *s)
|
|||
Shader_Free(s);
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->flags |= SHADER_IMAGEPENDING;
|
||||
|
||||
s->remapto = s;
|
||||
s->id = id;
|
||||
s->width = w;
|
||||
|
@ -5127,7 +5125,7 @@ void Shader_DefaultBSPVertex(const char *shortname, shader_t *s, const void *arg
|
|||
|
||||
s->numpasses = 1;
|
||||
s->numdeforms = 0;
|
||||
s->flags = SHADER_IMAGEPENDING|SHADER_DEPTHWRITE|SHADER_CULL_FRONT;
|
||||
s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT;
|
||||
s->sort = SHADER_SORT_OPAQUE;
|
||||
s->uses = 1;
|
||||
}
|
||||
|
@ -5138,7 +5136,7 @@ void Shader_DefaultBSPFlare(const char *shortname, shader_t *s, const void *args
|
|||
return;
|
||||
|
||||
pass = &s->passes[0];
|
||||
pass->flags = SHADER_IMAGEPENDING|SHADER_PASS_NOCOLORARRAY;
|
||||
pass->flags = SHADER_PASS_NOCOLORARRAY;
|
||||
pass->shaderbits |= SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ONE;
|
||||
pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0);
|
||||
pass->rgbgen = RGB_GEN_VERTEX_LIGHTING;
|
||||
|
@ -5156,7 +5154,7 @@ void Shader_DefaultBSPFlare(const char *shortname, shader_t *s, const void *args
|
|||
|
||||
s->numpasses = 1;
|
||||
s->numdeforms = 0;
|
||||
s->flags = SHADER_IMAGEPENDING|SHADER_FLARE;
|
||||
s->flags = SHADER_FLARE;
|
||||
s->sort = SHADER_SORT_ADDITIVE;
|
||||
s->uses = 1;
|
||||
|
||||
|
@ -5243,7 +5241,7 @@ void Shader_Default2D(const char *shortname, shader_t *s, const void *genargs)
|
|||
"sort additive\n"
|
||||
"}\n"
|
||||
);
|
||||
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, NULL, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP));
|
||||
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, genargs, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5260,7 +5258,7 @@ void Shader_Default2D(const char *shortname, shader_t *s, const void *genargs)
|
|||
"sort additive\n"
|
||||
"}\n"
|
||||
);
|
||||
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, NULL, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP));
|
||||
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, genargs, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5374,7 +5372,7 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode)
|
|||
parsestate.mode = parsemode;
|
||||
|
||||
// set defaults
|
||||
s->flags = SHADER_IMAGEPENDING|SHADER_CULL_FRONT;
|
||||
s->flags = SHADER_CULL_FRONT;
|
||||
s->uses = 1;
|
||||
|
||||
while (Shader_ReadShaderTerms(s, &shadersource, parsemode, &conddepth, sizeof(cond)/sizeof(cond[0]), cond))
|
||||
|
@ -5849,7 +5847,7 @@ int R_GetShaderSizes(shader_t *shader, int *width, int *height, qboolean blockti
|
|||
{
|
||||
if (!shader)
|
||||
return false;
|
||||
if (shader->flags & SHADER_IMAGEPENDING)
|
||||
if (!shader->width && !shader->height)
|
||||
{
|
||||
int i;
|
||||
if (width)
|
||||
|
@ -5872,7 +5870,6 @@ int R_GetShaderSizes(shader_t *shader, int *width, int *height, qboolean blockti
|
|||
}
|
||||
}
|
||||
|
||||
shader->flags &= ~SHADER_IMAGEPENDING;
|
||||
for (i = 0; i < shader->numpasses; i++)
|
||||
{
|
||||
if (shader->passes[i].texgen == T_GEN_SINGLEMAP)
|
||||
|
|
|
@ -530,7 +530,7 @@ struct shader_s
|
|||
SHADER_DEFORMV_BULGE = 1 << 5,
|
||||
SHADER_AUTOSPRITE = 1 << 6,
|
||||
SHADER_FLARE = 1 << 7,
|
||||
SHADER_IMAGEPENDING = 1 << 8, //FIXME
|
||||
//8
|
||||
SHADER_ENTITY_MERGABLE = 1 << 9,
|
||||
SHADER_VIDEOMAP = 1 << 10,
|
||||
SHADER_DEPTHWRITE = 1 << 11, //some pass already wrote depth. not used by the renderer.
|
||||
|
|
|
@ -395,7 +395,7 @@ static void FSPPAPI_ClosePath(searchpathfuncs_t *handle)
|
|||
Z_Free(handle);
|
||||
}
|
||||
|
||||
int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
|
||||
int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
|
||||
{
|
||||
int rootlen = strlen(rootpath);
|
||||
char *sub;
|
||||
|
@ -412,7 +412,7 @@ int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(con
|
|||
sub++;
|
||||
if (wildcmp(match, sub))
|
||||
{
|
||||
if (!func(sub, f->length, parm, spath))
|
||||
if (!func(sub, f->length, (time_t)0, parm, spath))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ void startquake(char *manif)
|
|||
Sys_Printf("Starting up (Built "__DATE__ ", " __TIME__")\n");
|
||||
|
||||
COM_InitArgv(parms.argc, parms.argv);
|
||||
TL_InitLanguages();
|
||||
TL_InitLanguages("");
|
||||
#ifdef SERVERONLY
|
||||
SV_Init(&parms);
|
||||
#else
|
||||
|
|
|
@ -6408,6 +6408,92 @@ QCC_sref_t QCC_PR_GenerateLogicalNot(QCC_sref_t e, const char *errormessage)
|
|||
}
|
||||
}
|
||||
|
||||
QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit)
|
||||
{
|
||||
//casting from an accessor uses the base type of that accessor (this allows us to properly read void* accessors)
|
||||
if (src.cast->type == ev_accessor)
|
||||
src.cast = src.cast->parentclass;
|
||||
|
||||
/*you may cast from a type to itself*/
|
||||
if (!typecmp(src.cast, cast))
|
||||
{
|
||||
//no-op
|
||||
}
|
||||
/*you may cast from const 0 to any other basic type for free (from either int or float for simplicity). things get messy when its a struct*/
|
||||
else if (QCC_SRef_IsNull(src) && cast->type != ev_struct && cast->type != ev_union)
|
||||
{
|
||||
QCC_FreeTemp(src);
|
||||
if (cast->size == 3)// || cast->type == ev_variant)
|
||||
src = QCC_MakeVectorConst(0,0,0);
|
||||
else
|
||||
src = QCC_MakeIntConst(0);
|
||||
src.cast = cast;
|
||||
}
|
||||
/*cast from int->float will convert*/
|
||||
else if (cast->type == ev_float && src.cast->type == ev_integer)
|
||||
src = QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], src, nullsref, NULL);
|
||||
/*cast from float->int will convert*/
|
||||
else if (cast->type == ev_integer && src.cast->type == ev_float)
|
||||
src = QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], src, nullsref, NULL);
|
||||
else if (cast->type == ev_entity && src.cast->type == ev_entity)
|
||||
{
|
||||
if (implicit)
|
||||
{ //this is safe if the source inherits from the dest type
|
||||
//but we should warn if the other way around
|
||||
QCC_type_t *t = src.cast;
|
||||
while(t)
|
||||
{
|
||||
if (!typecmp_lax(t, cast))
|
||||
break;
|
||||
t = t->parentclass;
|
||||
}
|
||||
if (!t)
|
||||
{
|
||||
char typea[256];
|
||||
char typeb[256];
|
||||
TypeName(src.cast, typea, sizeof(typea));
|
||||
TypeName(cast, typeb, sizeof(typeb));
|
||||
QCC_PR_ParseWarning(0, "Implicit cast from %s to %s\n", typea, typeb);
|
||||
}
|
||||
}
|
||||
src.cast = cast;
|
||||
}
|
||||
/*variants can be cast from/to anything without warning, even implicitly. FIXME: size issues*/
|
||||
else if (cast->type == ev_variant || src.cast->type == ev_variant)
|
||||
src.cast = cast;
|
||||
/*these casts are fine when explicit*/
|
||||
else if (
|
||||
/*you may explicitly cast between pointers and ints (strings count as pointers - WARNING: some strings may not be expressable as pointers)*/
|
||||
((cast->type == ev_pointer || cast->type == ev_string || cast->type == ev_integer) && (src.cast->type == ev_pointer || src.cast->type == ev_string || src.cast->type == ev_integer))
|
||||
//functions can be explicitly cast from one to another
|
||||
|| (cast->type == ev_function && src.cast->type == ev_function)
|
||||
//ents->ints || ints->ents. WARNING: the integer value of ent types is engine specific.
|
||||
|| (cast->type == ev_entity && src.cast->type == ev_integer)
|
||||
|| (cast->type == ev_integer && src.cast->type == ev_entity)
|
||||
)
|
||||
{
|
||||
//direct cast
|
||||
if (implicit && typecmp_lax(src.cast, cast))
|
||||
{
|
||||
char typea[256];
|
||||
char typeb[256];
|
||||
TypeName(src.cast, typea, sizeof(typea));
|
||||
TypeName(cast, typeb, sizeof(typeb));
|
||||
QCC_PR_ParseWarning(0, "Implicit cast from %s to %s\n", typea, typeb);
|
||||
}
|
||||
src.cast = cast;
|
||||
}
|
||||
else
|
||||
{
|
||||
char typea[256];
|
||||
char typeb[256];
|
||||
TypeName(src.cast, typea, sizeof(typea));
|
||||
TypeName(cast, typeb, sizeof(typeb));
|
||||
QCC_PR_ParseError(0, "Cannot cast from %s to %s\n", typea, typeb);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PR_Term
|
||||
|
@ -6583,55 +6669,7 @@ QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags)
|
|||
//not a single term, so we can cast the result of function calls. just make sure its not too high a priority
|
||||
//and yeah, okay, use defs not refs. whatever.
|
||||
e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||
|
||||
//casting from an accessor uses the base type of that accessor (this allows us to properly read void* accessors)
|
||||
if (e.cast->type == ev_accessor)
|
||||
e.cast = e.cast->parentclass;
|
||||
|
||||
/*you may cast from a type to itself*/
|
||||
if (!typecmp(e.cast, newtype))
|
||||
{
|
||||
}
|
||||
/*you may cast from const 0 to any type of same size for free (from either int or float for simplicity)*/
|
||||
else if (newtype->size == e.cast->size && QCC_SRef_IsNull(e))
|
||||
{
|
||||
e.sym->referenced = true;
|
||||
//direct cast
|
||||
return QCC_PR_BuildRef(retbuf, REF_GLOBAL, e, nullsref, newtype, true);
|
||||
}
|
||||
/*cast from int->float will convert*/
|
||||
else if (newtype->type == ev_float && e.cast->type == ev_integer)
|
||||
return QCC_DefToRef(retbuf, QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], e, nullsref, NULL));
|
||||
/*cast from float->int will convert*/
|
||||
else if (newtype->type == ev_integer && e.cast->type == ev_float)
|
||||
return QCC_DefToRef(retbuf, QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], e, nullsref, NULL));
|
||||
/*you may freely cast between pointers (and ints, as this is explicit) (strings count as pointers - WARNING: some strings may not be expressable as pointers)*/
|
||||
else if (
|
||||
//pointers
|
||||
((newtype->type == ev_pointer || newtype->type == ev_string || newtype->type == ev_integer) && (e.cast->type == ev_pointer || e.cast->type == ev_string || e.cast->type == ev_integer))
|
||||
//ents/classs
|
||||
|| (newtype->type == ev_entity && e.cast->type == ev_entity)
|
||||
//functions can be explicitly cast from one to another
|
||||
|| (newtype->type == ev_function && e.cast->type == ev_function)
|
||||
//variants are fine too
|
||||
|| (newtype->type == ev_variant || e.cast->type == ev_variant)
|
||||
// || (newtype->type == ev_accessor && newtype->parentclass->type == e.cast->type)
|
||||
// || (e->type->type == ev_accessor && e.cast->parentclass->type == newtype->type)
|
||||
|| !typecmp(e.cast, newtype)
|
||||
)
|
||||
{
|
||||
e.sym->referenced = true;
|
||||
//direct cast
|
||||
return QCC_PR_BuildRef(retbuf, REF_GLOBAL, e, nullsref, newtype, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
char typea[256];
|
||||
char typeb[256];
|
||||
TypeName(e.cast, typea, sizeof(typea));
|
||||
TypeName(newtype, typeb, sizeof(typeb));
|
||||
QCC_PR_ParseError(0, "Cannot cast from %s to %s\n", typea, typeb);
|
||||
}
|
||||
e = QCC_EvaluateCast(e, newtype, false);
|
||||
}
|
||||
return QCC_DefToRef(retbuf, e);
|
||||
}
|
||||
|
@ -11468,16 +11506,19 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
|||
{
|
||||
//arrays go recursive
|
||||
QCC_PR_Expect("{");
|
||||
for (i = 0; i < arraysize; i++)
|
||||
if (!QCC_PR_CheckToken("}"))
|
||||
{
|
||||
if (QCC_PR_CheckToken("}"))
|
||||
break;
|
||||
QCC_PR_ParseInitializerType(0, basedef, def);
|
||||
def.ofs += def.cast->size;
|
||||
if (!QCC_PR_CheckToken(","))
|
||||
for (i = 0; i < arraysize; i++)
|
||||
{
|
||||
QCC_PR_Expect("}");
|
||||
break;
|
||||
QCC_PR_ParseInitializerType(0, basedef, def);
|
||||
def.ofs += def.cast->size;
|
||||
if (!QCC_PR_CheckToken(","))
|
||||
{
|
||||
QCC_PR_Expect("}");
|
||||
break;
|
||||
}
|
||||
if (QCC_PR_CheckToken("}"))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11649,35 +11690,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
|||
else
|
||||
{
|
||||
tmp = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||
if (typecmp(type, tmp.cast))
|
||||
{
|
||||
/*you can cast from const 0 to anything*/
|
||||
if (tmp.cast->size == type->size && QCC_SRef_IsNull(tmp))
|
||||
{
|
||||
}
|
||||
/*universal pointers can assign without casts*/
|
||||
else if (type->type == ev_pointer && tmp.cast->type == ev_pointer && (type->aux_type->type == ev_void || tmp.cast->aux_type->type == ev_void || type->aux_type->type == ev_variant || tmp.cast->aux_type->type == ev_variant))
|
||||
{
|
||||
}
|
||||
/*cast from int->float will convert*/
|
||||
else if (type->type == ev_float && tmp.cast->type == ev_integer)
|
||||
tmp = QCC_PR_Statement (&pr_opcodes[OP_CONV_ITOF], tmp, nullsref, NULL);
|
||||
/*cast from float->int will convert*/
|
||||
else if (type->type == ev_integer && tmp.cast->type == ev_float)
|
||||
tmp = QCC_PR_Statement (&pr_opcodes[OP_CONV_FTOI], tmp, nullsref, NULL);
|
||||
else if ( (type->type == ev_accessor && type->parentclass->type == tmp.cast->type)
|
||||
|| (tmp.cast->type == ev_accessor && tmp.cast->parentclass->type == type->type))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
char gottype[256];
|
||||
char needtype[256];
|
||||
TypeName(tmp.cast, gottype, sizeof(gottype));
|
||||
TypeName(type, needtype, sizeof(needtype));
|
||||
QCC_PR_ParseErrorPrintSRef (ERR_BADIMMEDIATETYPE, def, "wrong initializer type for %s. got %s, needed %s", QCC_GetSRefName(def), gottype, needtype);
|
||||
}
|
||||
}
|
||||
tmp = QCC_EvaluateCast(tmp, type, true);
|
||||
}
|
||||
|
||||
if (!pr_scope || basedef->constant || basedef->isstatic)
|
||||
|
@ -11686,7 +11699,14 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
|
|||
if (!tmp.sym->constant)
|
||||
{
|
||||
QCC_PR_ParseWarning(ERR_BADIMMEDIATETYPE, "initializer is not constant");
|
||||
QCC_PR_ParsePrintSRef(ERR_BADIMMEDIATETYPE, def);
|
||||
QCC_PR_ParsePrintSRef(ERR_BADIMMEDIATETYPE, tmp);
|
||||
}
|
||||
|
||||
if (!tmp.sym->initialized)
|
||||
{
|
||||
//FIXME: we NEED to support relocs somehow
|
||||
QCC_PR_ParseWarning(WARN_UNINITIALIZED, "initializer is not initialised, %s will be treated as 0", QCC_GetSRefName(tmp));
|
||||
QCC_PR_ParsePrintSRef(WARN_UNINITIALIZED, tmp);
|
||||
}
|
||||
|
||||
if (basedef->initialized && basedef->initialized != 3)
|
||||
|
@ -12237,7 +12257,11 @@ void QCC_PR_ParseDefs (char *classname)
|
|||
break;
|
||||
}
|
||||
else if (depth == 1 && QCC_PR_CheckToken(","))
|
||||
{
|
||||
if (QCC_PR_CheckToken("}"))
|
||||
break;
|
||||
arraysize++;
|
||||
}
|
||||
else if (QCC_PR_CheckToken("{") || QCC_PR_CheckToken("["))
|
||||
depth++;
|
||||
else if (QCC_PR_CheckToken("}") || QCC_PR_CheckToken("]"))
|
||||
|
@ -12444,7 +12468,10 @@ void QCC_PR_ParseDefs (char *classname)
|
|||
else
|
||||
{
|
||||
QCC_PR_CheckToken("#");
|
||||
QCC_PR_Lex();
|
||||
do
|
||||
{
|
||||
QCC_PR_Lex();
|
||||
} while (*pr_token && strcmp(pr_token, ",") && strcmp(pr_token, ";"));
|
||||
}
|
||||
}
|
||||
QCC_FreeDef(def);
|
||||
|
|
|
@ -3824,6 +3824,10 @@ int typecmp_lax(QCC_type_t *a, QCC_type_t *b)
|
|||
if (typecmp_lax(a->aux_type, b->aux_type))
|
||||
return 1;
|
||||
|
||||
//variants and args don't make sense, and are considered equivelent(ish).
|
||||
if (a->type == ev_variant || b->type == ev_variant)
|
||||
return 0;
|
||||
|
||||
//optional arg types must match, even if they're not specified in one.
|
||||
for (t = 0; t < minargs; t++)
|
||||
{
|
||||
|
@ -4308,6 +4312,8 @@ extern char *basictypenames[];
|
|||
extern QCC_type_t **basictypes[];
|
||||
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope, int arraysize, QCC_def_t *rootsymbol, unsigned int ofs, int referable, unsigned int flags);
|
||||
|
||||
void QCC_PR_ParseInitializerDef(QCC_def_t *def);
|
||||
|
||||
pbool type_inlinefunction;
|
||||
/*newtype=true: creates a new type always
|
||||
silentfail=true: function is permitted to return NULL if it was not given a type, otherwise never returns NULL
|
||||
|
@ -4576,6 +4582,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
QCC_def_t *d;
|
||||
QCC_type_t *pc;
|
||||
pbool found = false;
|
||||
int assumevirtual = 0; //0=erk, 1=yes, -1=no
|
||||
|
||||
parmname = QCC_PR_ParseName();
|
||||
classname = qccHunkAlloc(strlen(parmname)+1);
|
||||
|
@ -4643,6 +4650,9 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
pbool isnonvirt = false;
|
||||
pbool isstatic = false;
|
||||
pbool isignored = false;
|
||||
pbool ispublic = false;
|
||||
pbool isprivate = false;
|
||||
pbool isprotected = false;
|
||||
while(1)
|
||||
{
|
||||
if (QCC_PR_CheckKeyword(1, "nonvirtual"))
|
||||
|
@ -4655,9 +4665,23 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
isignored = true;
|
||||
else if (QCC_PR_CheckKeyword(1, "strip"))
|
||||
isignored = true;
|
||||
else if (QCC_PR_CheckKeyword(1, "public"))
|
||||
ispublic = true;
|
||||
else if (QCC_PR_CheckKeyword(1, "private"))
|
||||
isprivate = true;
|
||||
else if (QCC_PR_CheckKeyword(1, "protected"))
|
||||
isprotected = true;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (QCC_PR_CheckToken(":"))
|
||||
{
|
||||
if (isvirt && !isnonvirt)
|
||||
assumevirtual = 1;
|
||||
else if (isnonvirt && !isvirt)
|
||||
assumevirtual = -1;
|
||||
continue;
|
||||
}
|
||||
newparm = QCC_PR_ParseType(false, false);
|
||||
|
||||
if (!newparm)
|
||||
|
@ -4693,8 +4717,12 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
}
|
||||
else if (!isvirt && !isnonvirt && !isstatic)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_MISSINGMEMBERQUALIFIER, "%s::%s was not qualified. Assuming non-virtual.", classname, parmname);
|
||||
isnonvirt = true;
|
||||
if (assumevirtual == 1)
|
||||
isvirt = true;
|
||||
else if (assumevirtual == -1)
|
||||
isnonvirt = true;
|
||||
else
|
||||
QCC_PR_ParseWarning(WARN_MISSINGMEMBERQUALIFIER, "%s::%s was not qualified. Assuming non-virtual.", classname, parmname);
|
||||
}
|
||||
if (isvirt+isnonvirt+isstatic != 1)
|
||||
QCC_PR_ParseError(ERR_INTERNAL, "Multiple conflicting qualifiers on %s::%s.", classname, pr_token);
|
||||
|
@ -4718,7 +4746,6 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
if (havebody)
|
||||
{
|
||||
QCC_def_t *def;
|
||||
QCC_function_t *f;
|
||||
if (pr_scope)
|
||||
QCC_Error(ERR_INTERNAL, "Nested function declaration");
|
||||
|
||||
|
@ -4748,6 +4775,15 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
{
|
||||
if (autoprototype || isignored)
|
||||
{
|
||||
if (QCC_PR_CheckToken("["))
|
||||
{
|
||||
while (!QCC_PR_CheckToken("]"))
|
||||
{
|
||||
if (pr_token_type == tt_eof)
|
||||
break;
|
||||
QCC_PR_Lex();
|
||||
}
|
||||
}
|
||||
QCC_PR_Expect("{");
|
||||
|
||||
{
|
||||
|
@ -4769,12 +4805,16 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
else
|
||||
{
|
||||
pr_classtype = newt;
|
||||
QCC_PR_ParseInitializerDef(def);
|
||||
QCC_FreeDef(def);
|
||||
pr_classtype = NULL;
|
||||
/*
|
||||
f = QCC_PR_ParseImmediateStatements (def, newparm);
|
||||
pr_classtype = NULL;
|
||||
pr_scope = NULL;
|
||||
def->symboldata[def->ofs].function = f - functions;
|
||||
f->def = def;
|
||||
def->initialized = 1;
|
||||
def->initialized = 1;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ void GUI_RevealOptions(void);
|
|||
#define SCI_GETLINE 2153
|
||||
#define SCI_LINEFROMPOSITION 2166
|
||||
#define SCI_POSITIONFROMLINE 2167
|
||||
#define SCI_REPLACESEL 2170
|
||||
#define SCI_SETTEXT 2181
|
||||
#define SCI_GETTEXT 2182
|
||||
#define SCI_CALLTIPSHOW 2200
|
||||
|
@ -757,6 +758,8 @@ LRESULT CALLBACK MySubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
EditFile(line+10, -1, false);
|
||||
else if (!strncmp(line, "prototyping ", 12))
|
||||
EditFile(line+12, -1, false);
|
||||
else if (!strncmp(line, "Couldn't open file ", 19))
|
||||
EditFile(line+19, -1, false);
|
||||
Edit_SetSel(hWnd, selrange.cpMin, selrange.cpMin); //deselect it.
|
||||
}
|
||||
}
|
||||
|
@ -1709,7 +1712,7 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
if (pos == linestart)
|
||||
{
|
||||
scin_get_line_indent(editor->editpane, lineidx, linebuf, sizeof(linebuf));
|
||||
SendMessage(editor->editpane, EM_REPLACESEL, 0, (LPARAM)linebuf);
|
||||
SendMessage(editor->editpane, SCI_REPLACESEL, 0, (LPARAM)linebuf);
|
||||
}
|
||||
}
|
||||
else if (0)//(!SendMessage(editor->editpane, SCI_AUTOCACTIVE, 0, 0))
|
||||
|
@ -1912,9 +1915,9 @@ void EditFile(char *name, int line, pbool setcontrol)
|
|||
|
||||
if (QCC_RawFileSize(name) == -1)
|
||||
{
|
||||
QC_snprintfz(title, sizeof(title), "File not found.\n%s", name);
|
||||
MessageBox(NULL, title, "Error", 0);
|
||||
return;
|
||||
QC_snprintfz(title, sizeof(title), "File not found:\n%s\nCreate it?", name);
|
||||
if (MessageBox(NULL, title, "Error", MB_ICONWARNING|MB_YESNO|MB_DEFBUTTON2) != IDYES)
|
||||
return;
|
||||
}
|
||||
|
||||
neweditor = malloc(sizeof(editor_t));
|
||||
|
|
|
@ -298,7 +298,8 @@ static void ASMCALL CStateOp (pubprogfuncs_t *prinst, float first, float last, f
|
|||
e->v->nextthink = pr_global_struct->time+0.1;
|
||||
e->v->think = currentfunc;
|
||||
|
||||
pr_global_struct->cycle_wrapped = false;
|
||||
if (pr_global_ptrs->cycle_wrapped)
|
||||
pr_global_struct->cycle_wrapped = false;
|
||||
|
||||
if (first > last)
|
||||
{ //going backwards
|
||||
|
@ -319,7 +320,8 @@ static void ASMCALL CStateOp (pubprogfuncs_t *prinst, float first, float last, f
|
|||
frame += step;
|
||||
if (frame < min || frame > max)
|
||||
{ //became out of range, must have wrapped
|
||||
pr_global_struct->cycle_wrapped = true;
|
||||
if (pr_global_ptrs->cycle_wrapped)
|
||||
pr_global_struct->cycle_wrapped = true;
|
||||
frame = first;
|
||||
}
|
||||
}
|
||||
|
@ -8034,6 +8036,23 @@ static void QCBUILTIN PF_te_beam(pubprogfuncs_t *prinst, struct globalvars_s *pr
|
|||
SV_beam_tempentity(G_EDICTNUM(prinst, OFS_PARM0), G_VECTOR(OFS_PARM1), G_VECTOR(OFS_PARM2), TEQW_BEAM);
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_te_muzzleflash(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
edict_t *e = G_EDICT(prinst, OFS_PARM0);
|
||||
//this is for lamers with old (or unsupported) clients
|
||||
if (progstype == PROG_QW)
|
||||
{
|
||||
MSG_WriteByte (&sv.multicast, svc_muzzleflash);
|
||||
MSG_WriteEntity (&sv.multicast, NUM_FOR_EDICT(prinst, e));
|
||||
|
||||
SV_MulticastProtExt (e->v->origin, MULTICAST_PHS, pr_global_struct->dimension_send, 0, 0);
|
||||
}
|
||||
else
|
||||
{ //consistent with nq, this'll be cleaned up elsewhere.
|
||||
e->v->effects = (int)e->v->effects | EF_MUZZLEFLASH;
|
||||
}
|
||||
}
|
||||
|
||||
//DP_TE_SPARK
|
||||
static void QCBUILTIN PF_te_spark(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -9443,7 +9462,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"fgets", PF_fgets, 0, 0, 0, 112, "string(filestream fhandle)"}, // (FRIK_FILE)
|
||||
{"fputs", PF_fputs, 0, 0, 0, 113, "void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)"}, // (FRIK_FILE)
|
||||
{"strlen", PF_strlen, 0, 0, 0, 114, "float(string s)"}, // (FRIK_FILE)
|
||||
{"strcat", PF_strcat, 0, 0, 0, 115, "string(string s1, optional string s2, ...)"}, // (FRIK_FILE)
|
||||
{"strcat", PF_strcat, 0, 0, 0, 115, "string(string s1, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, string s8)"}, // (FRIK_FILE)
|
||||
{"substring", PF_substring, 0, 0, 0, 116, "string(string s, float start, float length)"}, // (FRIK_FILE)
|
||||
{"stov", PF_stov, 0, 0, 0, 117, "vector(string s)"}, // (FRIK_FILE)
|
||||
#ifdef QCGC
|
||||
|
@ -9528,6 +9547,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"skinforname", PF_skinforname, 0, 0, 0, 237, "float(float mdlindex, string skinname)"}, // #237
|
||||
{"shaderforname", PF_Fixme, 0, 0, 0, 238, D("float(string shadername, optional string defaultshader, ...)", "Caches the named shader and returns a handle to it.\nIf the shader could not be loaded from disk (missing file or ruleset_allow_shaders 0), it will be created from the 'defaultshader' string if specified, or a 'skin shader' default will be used.\ndefaultshader if not empty should include the outer {} that you would ordinarily find in a shader.")},
|
||||
{"te_bloodqw", PF_te_bloodqw, 0, 0, 0, 239, "void(vector org, optional float count)"},
|
||||
{"te_muzzleflash", PF_te_muzzleflash, 0, 0, 0, 0, "void(entity ent)"},
|
||||
|
||||
{"checkpvs", PF_checkpvs, 0, 0, 0, 240, "float(vector viewpos, entity entity)"},
|
||||
{"matchclientname", PF_matchclient, 0, 0, 0, 241, "entity(string match, optional float matchnum)"},
|
||||
|
@ -11101,11 +11121,12 @@ void PR_DumpPlatform_f(void)
|
|||
{"TEREDIT_TEX_UNIFY", "const float", CS, NULL, ter_tex_concentrate},
|
||||
{"TEREDIT_TEX_NOISE", "const float", CS, NULL, ter_tex_noise},
|
||||
{"TEREDIT_TEX_BLUR", "const float", CS, NULL, ter_tex_blur},
|
||||
{"TEREDIT_TEX_REPLACE", "const float", CS, NULL, ter_tex_replace},
|
||||
{"TEREDIT_TEX_SETMASK", "const float", CS, NULL, ter_tex_mask},
|
||||
{"TEREDIT_WATER_SET", "const float", CS, NULL, ter_water_set},
|
||||
{"TEREDIT_MESH_ADD", "const float", CS, NULL, ter_mesh_add},
|
||||
{"TEREDIT_MESH_KILL", "const float", CS, NULL, ter_mesh_kill},
|
||||
{"TEREDIT_TINT", "const float", CS, NULL, ter_tint},
|
||||
{"TEREDIT_TEX_REPLACE", "const float", CS, NULL, ter_tex_replace},
|
||||
{"TEREDIT_RESET_SECT", "const float", CS, NULL, ter_reset},
|
||||
{"TEREDIT_RELOAD_SECT", "const float", CS, NULL, ter_reloadsect},
|
||||
|
||||
|
|
|
@ -247,6 +247,8 @@ and the extension fields are added on the end and can have extra vm-specific stu
|
|||
comfieldfloat(style,"Used by the light util to decide how an entity's light should animate. On an entity with pflags set, this also affects realtime lights.")\
|
||||
comfieldfloat(pflags,"Realtime lighting flags")\
|
||||
comfieldfloat(clientcolors,NULL)\
|
||||
/*comfieldfloat(baseframe,"Specifies the current frame(group) to use for the lower (numerically) bones of a skeletal model. The basebone field specifies the bone where the regular frame field takes over.")*/ /*FTESS_QC_BASEFRAME*/\
|
||||
/*comfieldfloat(basebone,"Specifies the bone at which the baseframe* fields stop being effective.")*/ /*FTE_SSQC_BASEFRAME*/\
|
||||
comfieldfloat(dimension_see,"This is the dimension mask (bitfield) that the client is allowed to see. Entities and events not in this dimension mask will be invisible.")/*EXT_DIMENSION_VISIBLE*/\
|
||||
comfieldfloat(dimension_seen,"This is the dimension mask (bitfield) that the client is visible within. Clients that cannot see this dimension mask will not see this entity.")/*EXT_DIMENSION_VISIBLE*/\
|
||||
comfieldfloat(dimension_ghost,"If this entity is visible only within these dimensions, it will become transparent, as if a ghost.")/*EXT_DIMENSION_GHOST*/\
|
||||
|
|
|
@ -76,22 +76,23 @@ extern cvar_t password;
|
|||
#endif
|
||||
cvar_t spectator_password = CVARF("spectator_password", "", CVAR_NOUNSAFEEXPAND); // password for entering as a sepctator
|
||||
|
||||
cvar_t allow_download = CVAR("allow_download", "1");
|
||||
cvar_t allow_download_skins = CVAR("allow_download_skins", "1");
|
||||
cvar_t allow_download_models = CVAR("allow_download_models", "1");
|
||||
cvar_t allow_download_sounds = CVAR("allow_download_sounds", "1");
|
||||
cvar_t allow_download_demos = CVAR("allow_download_demos", "1");
|
||||
cvar_t allow_download_maps = CVAR("allow_download_maps", "1");
|
||||
cvar_t allow_download_anymap = CVAR("allow_download_pakmaps", "0");
|
||||
cvar_t allow_download_pakcontents = CVARD("allow_download_pakcontents", "1", "controls whether clients connected to this server are allowed to download files from within packages. Does NOT implicitly allow downloading bsps, set allow_download_pakmaps to enable that.");
|
||||
cvar_t allow_download_root = CVARD("allow_download_root", "0", "If set, enables downloading from the root of the gamedir (not the basedir). This setting is dangerous as it can allow downloading configs.");
|
||||
cvar_t allow_download_textures = CVAR("allow_download_textures", "1");
|
||||
cvar_t allow_download_packages = CVAR("allow_download_packages", "1");
|
||||
cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If set to 1, packages that contain files needed during spawn functions will be become 'referenced' and automatically downloaded to clients.\nThis cvar should probably not be set if you have large packages that provide replacement pickup models on public servers.\nThe path command will show a '(ref)' tag next to packages which clients will automatically attempt to download.");
|
||||
cvar_t allow_download_wads = CVAR("allow_download_wads", "1");
|
||||
cvar_t allow_download_configs = CVAR("allow_download_configs", "0");
|
||||
cvar_t allow_download_copyrighted = CVAR("allow_download_copyrighted", "0");
|
||||
cvar_t allow_download_other = CVAR("allow_download_other", "0");
|
||||
cvar_t allow_download = CVARD("allow_download", "1", "If 1, permits downloading. Set to 0 to unconditionally block *ALL* downloads.");
|
||||
cvar_t allow_download_skins = CVARD("allow_download_skins", "1", "0 blocks downloading of any file in the skins/ directory");
|
||||
cvar_t allow_download_models = CVARD("allow_download_models", "1", "0 blocks downloading of any file in the progs/ or models/ directory");
|
||||
cvar_t allow_download_sounds = CVARD("allow_download_sounds", "1", "0 blocks downloading of any file in the sound/ directory");
|
||||
cvar_t allow_download_demos = CVARD("allow_download_demos", "1", "0 blocks downloading of any file in the demos/ directory");
|
||||
cvar_t allow_download_maps = CVARD("allow_download_maps", "1", "0 blocks downloading of any file in the maps/ directory");
|
||||
cvar_t allow_download_logs = CVARD("allow_download_logs", "0", "1 permits downloading files with the extension .log\n"CON_ERROR"THIS IS DANGEROUS AS IT POTENTIALLY ALLOWS PEOPLE TO SEE PASSWORDS OR OTHER PRIVATE INFORMATION.\nNote that it can be switch on/off via rcon.");
|
||||
cvar_t allow_download_anymap = CVARD("allow_download_pakmaps", "0", "If 1, permits downloading of maps from within packages. This is normally disabled in order to prevent copyrighted content from being downloaded.");
|
||||
cvar_t allow_download_pakcontents = CVARD("allow_download_pakcontents", "1", "controls whether clients connected to this server are allowed to download files from within packages.\nDoes NOT implicitly allow downloading bsps, set allow_download_pakmaps to enable that.\nWhile treating each file contained within packages is often undesirable, this is often needed for compatibility with legacy clients (despite it potentially allowing copyright violations).");
|
||||
cvar_t allow_download_root = CVARD("allow_download_root", "0", "If set, enables downloading from the root of the gamedir (not the basedir). This setting has a lower priority than extension-based checks.");
|
||||
cvar_t allow_download_textures = CVARD("allow_download_textures", "1", "0 blocks downloading of any file in the textures/ directory");
|
||||
cvar_t allow_download_packages = CVARD("allow_download_packages", "1", "if 1, permits downloading files (from root directory or elsewhere) with known package extensions (eg: pak+pk3). Packages with a name starting 'pak' are covered by allow_download_copyrighted as well. This does not prevent ");
|
||||
cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If set to 1, packages that contain files needed during spawn functions will be become 'referenced' and automatically downloaded to clients.\nThis cvar should probably not be set if you have large packages that provide replacement pickup models on public servers.\nThe path command will show a '(ref)' tag next to packages which clients will automatically attempt to download.");
|
||||
cvar_t allow_download_wads = CVARD("allow_download_wads", "1", "0 blocks downloading of any file in the wads/ directory, or is in the root directory with the extension .wad");
|
||||
cvar_t allow_download_configs = CVARD("allow_download_configs", "0", "1 allows downloading of config files, either with the extension .cfg or in the subdir configs/.\n"CON_ERROR"THIS IS DANGEROUS AS IT CAN ALLOW PEOPLE TO READ YOUR RCON PASSWORD.");
|
||||
cvar_t allow_download_copyrighted = CVARD("allow_download_copyrighted", "0", "0 blocks download of packages that are considered copyrighted. Specifically, this means packages with a leading 'pak' prefix on the filename.\nIf you take your copyrights seriously, you should also set allow_download_pakmaps 0 and allow_download_pakcontents 0.");
|
||||
cvar_t allow_download_other = CVARD("allow_download_other", "0", "0 blocks downloading of any file that was not covered by any of the directory download blocks.");
|
||||
|
||||
cvar_t sv_serverip = CVARD("sv_serverip", "", "Set this cvar to the server's public ip address if the server is behind a firewall and cannot detect its own public address. Providing a port is required if the firewall/nat remaps it, but is otherwise optional.");
|
||||
cvar_t sv_public = CVAR("sv_public", "0");
|
||||
|
|
|
@ -2657,6 +2657,7 @@ qboolean SV_AllowDownload (const char *name)
|
|||
extern cvar_t allow_download_packages;
|
||||
extern cvar_t allow_download_wads;
|
||||
extern cvar_t allow_download_root;
|
||||
extern cvar_t allow_download_logs;
|
||||
extern cvar_t allow_download_configs;
|
||||
extern cvar_t allow_download_copyrighted;
|
||||
extern cvar_t allow_download_other;
|
||||
|
@ -2689,7 +2690,9 @@ qboolean SV_AllowDownload (const char *name)
|
|||
|
||||
//block attempts to download logs
|
||||
if (!Q_strcasecmp("log", ext))
|
||||
return false;
|
||||
return !!allow_download_logs.value;
|
||||
if (strncmp(name, "logs/", 5) == 0)
|
||||
return !!allow_download_logs.value;
|
||||
|
||||
if (!strncmp(name, "package/", 8))
|
||||
{
|
||||
|
@ -2727,10 +2730,13 @@ qboolean SV_AllowDownload (const char *name)
|
|||
if (strncmp(name, "textures/", 9) == 0)
|
||||
return !!allow_download_textures.value;
|
||||
|
||||
if (strncmp(name, "config/", 9) == 0)
|
||||
return !!allow_download_configs.value;
|
||||
|
||||
//wads
|
||||
if (strncmp(name, "wads/", 5) == 0)
|
||||
return !!allow_download_wads.value;
|
||||
if (!strcmp("wad", ext))
|
||||
if (!strchr(name, '/') && !strcmp("wad", ext))
|
||||
return !!allow_download_wads.value;
|
||||
|
||||
//pak/pk3s.
|
||||
|
@ -2739,7 +2745,7 @@ qboolean SV_AllowDownload (const char *name)
|
|||
if (strnicmp(name, "pak", 3)) //don't give out core pak/pk3 files. This matches q3 logic.
|
||||
return !!allow_download_packages.value;
|
||||
else
|
||||
return !!allow_download_copyrighted.value;
|
||||
return !!allow_download_packages.value && !!allow_download_copyrighted.value;
|
||||
}
|
||||
|
||||
if (!strcmp("cfg", ext))
|
||||
|
@ -2754,7 +2760,7 @@ qboolean SV_AllowDownload (const char *name)
|
|||
}
|
||||
|
||||
//any other subdirs are allowed
|
||||
return !!allow_download_other.value;;
|
||||
return !!allow_download_other.value;
|
||||
}
|
||||
|
||||
static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementname, qboolean redirectpaks)
|
||||
|
@ -3360,6 +3366,12 @@ void SV_Say (qboolean team)
|
|||
if (PR_QCChat(p, team)) //true if handled.
|
||||
return;
|
||||
|
||||
if (strstr(p, "password"))
|
||||
{
|
||||
Z_Free(host_client->centerprintstring);
|
||||
host_client->centerprintstring = Z_StrDup("big brother is watching you");
|
||||
}
|
||||
|
||||
Q_strcat(text, p);
|
||||
|
||||
//filter out '\n' and '\r'
|
||||
|
|
|
@ -225,7 +225,7 @@ static areanode_t *World_CreateAreaNode (world_t *w, int depth, vec3_t mins, vec
|
|||
|
||||
ClearLink (&anode->edicts);
|
||||
|
||||
if (depth == AREA_DEPTH)
|
||||
if (depth == w->areanodedepth)
|
||||
{
|
||||
anode->axis = -1;
|
||||
anode->children[0] = anode->children[1] = NULL;
|
||||
|
@ -260,23 +260,37 @@ SV_ClearWorld
|
|||
*/
|
||||
void World_ClearWorld (world_t *w)
|
||||
{
|
||||
int maxdepth;
|
||||
vec3_t mins, maxs;
|
||||
if (w->worldmodel)
|
||||
{
|
||||
VectorCopy(w->worldmodel->mins, mins);
|
||||
VectorCopy(w->worldmodel->maxs, maxs);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet(mins, -4096, -4096, -4096);
|
||||
VectorSet(maxs, 4096, 4096, 4096);
|
||||
}
|
||||
|
||||
World_InitBoxHull ();
|
||||
|
||||
memset (&w->portallist, 0, sizeof(w->portallist));
|
||||
ClearLink (&w->portallist.edicts);
|
||||
w->portallist.axis = -1;
|
||||
|
||||
memset (w->areanodes, 0, sizeof(w->areanodes));
|
||||
w->numareanodes = 0;
|
||||
if (!w->worldmodel)
|
||||
maxdepth = 4;
|
||||
|
||||
if (!w->areanodes || w->areanodedepth != maxdepth)
|
||||
{
|
||||
vec3_t mins, maxs;
|
||||
VectorSet(mins, -4096, -4096, -4096);
|
||||
VectorSet(maxs, 4096, 4096, 4096);
|
||||
World_CreateAreaNode (w, 0, mins, maxs);
|
||||
Z_Free(w->areanodes);
|
||||
w->areanodedepth = maxdepth;
|
||||
w->areanodes = Z_Malloc(sizeof(*w->areanodes) * pow(2, w->areanodedepth+1));
|
||||
}
|
||||
else
|
||||
World_CreateAreaNode (w, 0, w->worldmodel->mins, w->worldmodel->maxs);
|
||||
memset (w->areanodes, 0, sizeof(w->areanodes));
|
||||
w->numareanodes = 0;
|
||||
World_CreateAreaNode (w, 0, mins, maxs);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -223,8 +223,51 @@ char *TP_ItemName(unsigned int itbit)
|
|||
return "Dunno";
|
||||
}
|
||||
|
||||
void Replace_In_String(char *string, size_t strsize, char leadchar, int patterns, ...)
|
||||
void Replace_In_String(char *src, size_t strsize, char leadchar, int patterns, ...)
|
||||
{
|
||||
char orig[1024];
|
||||
char *out, *outstop;
|
||||
va_list ap;
|
||||
int i;
|
||||
|
||||
strlcpy(orig, src, sizeof(orig));
|
||||
out = src;
|
||||
outstop = out + strsize-1;
|
||||
src = orig;
|
||||
|
||||
while(*src)
|
||||
{
|
||||
if (out == outstop)
|
||||
break;
|
||||
if (*src != leadchar)
|
||||
*out++ = *src++;
|
||||
else if (*++src == leadchar)
|
||||
*out++ = leadchar;
|
||||
else
|
||||
{
|
||||
va_start(ap, patterns);
|
||||
for (i = 0; i < patterns; i++)
|
||||
{
|
||||
const char *arg = va_arg(ap, const char *);
|
||||
const char *val = va_arg(ap, const char *);
|
||||
size_t alen = strlen(arg);
|
||||
if (!strncmp(src, arg, strlen(arg)))
|
||||
{
|
||||
strlcpy(out, val, (outstop-out)+1);
|
||||
out += strlen(out);
|
||||
src += alen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == patterns)
|
||||
{
|
||||
strlcpy(out, "unknown", (outstop-out)+1);
|
||||
out += strlen(out);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
int SCR_GetClockStringWidth(const char *s, qbool big, float scale)
|
||||
|
@ -356,6 +399,13 @@ void SCR_DrawSmallClock(int x, int y, int style, int blink, float scale, const c
|
|||
}
|
||||
}
|
||||
|
||||
#include "builtin_huds.h"
|
||||
void EZHud_UseNquake_f(void)
|
||||
{
|
||||
const char *hudstr = builtin_hud_nquake;
|
||||
pCmd_AddText(hudstr, true);
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
xcommand_t cmd;
|
||||
|
@ -577,6 +627,7 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
Plug_Export("Tick", EZHud_Tick) &&
|
||||
Plug_Export("ExecuteCommand", EZHud_ExecuteCommand))
|
||||
{
|
||||
Cmd_AddCommand("ezhud_nquake", EZHud_UseNquake_f);
|
||||
HUD_Init();
|
||||
HUD_Editor_Init();
|
||||
return 1;
|
||||
|
|
|
@ -393,6 +393,10 @@ void SCR_HUD_DrawFPS(hud_t *hud)
|
|||
|
||||
if (HUD_PrepareDraw(hud, strlen(st)*8, 8, &x, &y))
|
||||
{
|
||||
vmnetinfo_t *netinfo = GetNetworkInfo();
|
||||
if (netinfo->capturing == 2) //don't show fps if its locked to something anyway.
|
||||
return;
|
||||
|
||||
if ((hud_fps_style->value) == 1)
|
||||
Draw_Alt_String(x, y, st);
|
||||
else if ((hud_fps_style->value) == 2) {
|
||||
|
@ -674,11 +678,11 @@ static void SCR_HUD_DrawPing(hud_t *hud)
|
|||
|
||||
// period = max(hud_ping_period->value, 0);
|
||||
|
||||
ping_avg = (int)(netinfo->ping.avg*1000 + 0.5);
|
||||
ping_min = (int)(netinfo->ping.mn*1000 + 0.5);
|
||||
ping_max = (int)(netinfo->ping.mx*1000 + 0.5);
|
||||
ping_dev = netinfo->ping.stddev;
|
||||
pl = netinfo->ping.loss*100;
|
||||
ping_avg = (int)(netinfo->ping.s_avg*1000 + 0.5);
|
||||
ping_min = (int)(netinfo->ping.s_mn*1000 + 0.5);
|
||||
ping_max = (int)(netinfo->ping.s_mx*1000 + 0.5);
|
||||
ping_dev = netinfo->ping.ms_stddev;
|
||||
pl = netinfo->loss.dropped*100;
|
||||
|
||||
clamp(ping_avg, 0, 999);
|
||||
clamp(ping_min, 0, 999);
|
||||
|
@ -937,28 +941,28 @@ static void SCR_NetStats(int x, int y, float period, vmnetinfo_t *netinfo)
|
|||
|
||||
last_calculated = t;
|
||||
|
||||
ping_avg = (int)(netinfo->ping.avg + 0.5);
|
||||
ping_min = (int)(netinfo->ping.mn + 0.5);
|
||||
ping_max = (int)(netinfo->ping.mx + 0.5);
|
||||
ping_dev = netinfo->ping.stddev;
|
||||
ping_avg = (int)(netinfo->ping.s_avg*1000 + 0.5);
|
||||
ping_min = (int)(netinfo->ping.s_mn*1000 + 0.5);
|
||||
ping_max = (int)(netinfo->ping.s_mx*1000 + 0.5);
|
||||
ping_dev = netinfo->ping.ms_stddev;
|
||||
|
||||
clamp(ping_avg, 0, 999);
|
||||
clamp(ping_min, 0, 999);
|
||||
clamp(ping_max, 0, 999);
|
||||
clamp(ping_dev, 0, 99.9);
|
||||
|
||||
f_avg = -1;//(int)(result.ping_f_avg + 0.5);
|
||||
f_min = -1;//(int)(result.ping_f_min + 0.5);
|
||||
f_max = -1;//(int)(result.ping_f_max + 0.5);
|
||||
f_avg = (int)(netinfo->ping.fr_avg+0.5);
|
||||
f_min = netinfo->ping.fr_mn;
|
||||
f_max = netinfo->ping.fr_mx;
|
||||
|
||||
clamp(f_avg, 0, 99.9);
|
||||
clamp(f_min, 0, 99.9);
|
||||
clamp(f_max, 0, 99.9);
|
||||
clamp(f_avg, 0, 99);
|
||||
clamp(f_min, 0, 99);
|
||||
clamp(f_max, 0, 99);
|
||||
|
||||
lost_lost = (int)(netinfo->ping.loss + 0.5);
|
||||
lost_rate = -1;//(int)(result.lost_rate + 0.5);
|
||||
lost_delta = -1;//(int)(result.lost_delta + 0.5);
|
||||
lost_total = -1;//(int)(result.lost_lost + result.lost_rate + result.lost_delta + 0.5);
|
||||
lost_lost = (int)(netinfo->loss.dropped*100 + 0.5);
|
||||
lost_rate = (int)(netinfo->loss.choked*100 + 0.5);
|
||||
lost_delta = (int)(netinfo->loss.invalid*100 + 0.5);
|
||||
lost_total = (int)((netinfo->loss.dropped + netinfo->loss.choked + netinfo->loss.invalid)*100 + 0.5);
|
||||
|
||||
clamp(lost_lost, 0, 100);
|
||||
clamp(lost_rate, 0, 100);
|
||||
|
@ -966,9 +970,9 @@ static void SCR_NetStats(int x, int y, float period, vmnetinfo_t *netinfo)
|
|||
clamp(lost_total, 0, 100);
|
||||
|
||||
//per packet sizes
|
||||
// size_in = (int)(netinfo->clrate.size_in + 0.5);
|
||||
// size_out = (int)(netinfo->size_out + 0.5);
|
||||
// size_all = (int)(netinfo->size_in + result.size_out + 0.5);
|
||||
size_in = (int)(netinfo->clrate.in_bps/netinfo->clrate.in_pps + 0.5);
|
||||
size_out = (int)(netinfo->clrate.out_bps/netinfo->clrate.out_pps + 0.5);
|
||||
size_all = (int)(netinfo->clrate.in_bps/netinfo->clrate.in_pps + netinfo->clrate.out_bps/netinfo->clrate.out_pps + 0.5);
|
||||
|
||||
//overall rate
|
||||
bandwidth_in = (int)(netinfo->clrate.in_bps + 0.5);
|
||||
|
@ -982,25 +986,25 @@ static void SCR_NetStats(int x, int y, float period, vmnetinfo_t *netinfo)
|
|||
clamp(bandwidth_out, 0, 99999);
|
||||
clamp(bandwidth_all, 0, 99999);
|
||||
|
||||
// with_delta = result.delta;
|
||||
with_delta = !pCvar_GetFloat("cl_nodelta");
|
||||
}
|
||||
|
||||
Draw_Alt_String(x+36, y, "latency");
|
||||
y+=12;
|
||||
|
||||
snprintf (line, sizeof (line), "min %4.1f %3d ms", f_min, ping_min);
|
||||
snprintf (line, sizeof (line), "min %4f %3d ms", f_min, ping_min);
|
||||
Draw_String(x, y, line);
|
||||
y+=8;
|
||||
|
||||
snprintf(line, sizeof (line), "avg %4.1f %3d ms", f_avg, ping_avg);
|
||||
snprintf(line, sizeof (line), "avg %4f %3d ms", f_avg, ping_avg);
|
||||
Draw_String(x, y, line);
|
||||
y+=8;
|
||||
|
||||
snprintf(line, sizeof (line), "max %4.1f %3d ms", f_max, ping_max);
|
||||
snprintf(line, sizeof (line), "max %4f %3d ms", f_max, ping_max);
|
||||
Draw_String(x, y, line);
|
||||
y+=8;
|
||||
|
||||
snprintf(line, sizeof (line), "dev %5.2f ms", ping_dev);
|
||||
snprintf(line, sizeof (line), "dev %f ms", ping_dev);
|
||||
Draw_String(x, y, line);
|
||||
y+=12;
|
||||
|
||||
|
@ -1060,9 +1064,11 @@ static void SCR_HUD_DrawNetStats(hud_t *hud)
|
|||
width = 16*8 ;
|
||||
height = 12 + 8 + 8 + 8 + 8 + 16 + 8 + 8 + 8 + 8 + 16 + 8 + 8 + 8;
|
||||
|
||||
if (HUD_PrepareDraw(hud, width, height, &x, &y))
|
||||
if (!netinfo || netinfo->capturing==2)
|
||||
HUD_PrepareDraw(hud, 0, 0, &x, &y);
|
||||
else if (HUD_PrepareDraw(hud, width, height, &x, &y))
|
||||
{
|
||||
// SCR_NetStats(x, y, hud_net_period->value);
|
||||
SCR_NetStats(x, y, hud_net_period->value, netinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2401,7 +2407,7 @@ static void SCR_HUD_NetProblem (hud_t *hud) {
|
|||
if(scale == NULL)
|
||||
scale = HUD_FindVar(hud, "scale");
|
||||
|
||||
if (netinfo->ping.loss < 1)
|
||||
if (netinfo->loss.dropped < 1)
|
||||
{
|
||||
if (hud_editor)
|
||||
HUD_PrepareDraw(hud, picwidth, picheight, &x, &y);
|
||||
|
@ -2440,7 +2446,12 @@ void SCR_HUD_DrawGroup(hud_t *hud, int width, int height, mpic_t *pic, int pic_s
|
|||
float picwidth = 64;
|
||||
float picheight = 64;
|
||||
|
||||
pDraw_ImageSize((intptr_t)pic, &picwidth, &picheight);
|
||||
if (pic && pDraw_ImageSize((intptr_t)pic, &picwidth, &picheight) <= 0)
|
||||
{
|
||||
pic = NULL;
|
||||
picwidth = 64;
|
||||
picheight = 64;
|
||||
}
|
||||
|
||||
clamp(width, 1, 99999);
|
||||
clamp(height, 1, 99999);
|
||||
|
@ -7862,7 +7873,7 @@ void CommonDraw_Init(void)
|
|||
HUD_Register("tracking", NULL, "Shows the name of tracked player.",
|
||||
HUD_PLUSMINUS, ca_active, 9, SCR_HUD_DrawTracking,
|
||||
"1", "face", "center", "before", "0", "0", "0", "0 0 0", NULL,
|
||||
"format", "^mTracking:^m %t %n, ^mJUMP^m for next", //"Tracking: team name, JUMP for next", "Tracking:" and "JUMP" are brown. default: "Tracking %t %n, [JUMP] for next"
|
||||
"format", "^mTracking:^m %t %n"/*, ^mJUMP^m for next"*/, //"Tracking: team name, JUMP for next", "Tracking:" and "JUMP" are brown. default: "Tracking %t %n, [JUMP] for next"
|
||||
"scale", "1",
|
||||
NULL);
|
||||
|
||||
|
|
|
@ -87,14 +87,14 @@ BUILTIN(void, Con_SetConsoleString, (const char *conname, const char *attribname
|
|||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,message
|
||||
BUILTIN(void, Sys_Error, (char *message)); //abort the entire engine.
|
||||
BUILTIN(void, Sys_Error, (const char *message)); //abort the entire engine.
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES
|
||||
BUILTINR(unsigned int, Sys_Milliseconds, (void)); //get the time the engine has been running.
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,buffer
|
||||
BUILTINR(int, Cmd_AddCommand, (char *buffer)); //register a command.
|
||||
BUILTINR(int, Cmd_AddCommand, (const char *buffer)); //register a command.
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,buffer,bufsize
|
||||
BUILTIN(void, Cmd_Args, (char *buffer, int bufsize)); //retrieve some arguments.
|
||||
|
@ -110,23 +110,23 @@ BUILTIN(void, Cmd_TokenizeString, (char *msg)); //tokenize a string.
|
|||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,text,insert
|
||||
BUILTIN(void, Cmd_AddText, (char *text, qboolean insert)); //add stuff to the console input.
|
||||
BUILTIN(void, Cmd_AddText, (const char *text, qboolean insert)); //add stuff to the console input.
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,name,value
|
||||
BUILTIN(void, Cvar_SetString, (char *name, char *value)); //set a cvar string
|
||||
BUILTIN(void, Cvar_SetString, (const char *name, char *value)); //set a cvar string
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,name,PASSFLOAT(value)
|
||||
BUILTIN(void, Cvar_SetFloat, (char *name, float value)); //set a cvar float
|
||||
BUILTIN(void, Cvar_SetFloat, (const char *name, float value)); //set a cvar float
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,name,retstring,sizeofretstring
|
||||
BUILTINR(qboolean, Cvar_GetString, (char *name, char *retstring, int sizeofretstring)); //retrieve a cvar string
|
||||
BUILTINR(qboolean, Cvar_GetString, (const char *name, char *retstring, int sizeofretstring)); //retrieve a cvar string
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,name
|
||||
BUILTINR(float, Cvar_GetFloat, (char *name)); //get a cvar's value
|
||||
BUILTINR(float, Cvar_GetFloat, (const char *name)); //get a cvar's value
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,name,defaultval,flags,grouphint
|
||||
BUILTINR(qhandle_t, Cvar_Register, (char *name, char *defaultval, int flags, char *grouphint)); //register a new cvar
|
||||
BUILTINR(qhandle_t, Cvar_Register, (const char *name, const char *defaultval, int flags, const char *grouphint)); //register a new cvar
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,handle,modificationcount,stringv,floatv
|
||||
BUILTINR(int, Cvar_Update, (qhandle_t handle, int *modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
|
||||
|
@ -148,15 +148,15 @@ BUILTINR(int, GetLocalPlayerNumbers, (int firstseat, int numseats, int *playernu
|
|||
BUILTIN(void, GetServerInfo, (char *info, int infolen));
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,key,value
|
||||
BUILTIN(void, SetUserInfo, (char *key, char *value));
|
||||
BUILTIN(void, SetUserInfo, (const char *key, const char *value));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,pos,buffer,bufferlen
|
||||
BUILTIN(void, GetLocationName, (float *pos, char *buffer, int bufferlen));
|
||||
BUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,soundname
|
||||
BUILTIN(void, LocalSound, (char *soundname));
|
||||
BUILTIN(void, LocalSound, (const char *soundname));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,plugnum, buffer, bufsize
|
||||
|
|
|
@ -206,45 +206,53 @@ EBUILTIN(void, Con_SetConsoleFloat, (const char *conname, const char *attribname
|
|||
EBUILTIN(int, Con_GetConsoleString, (const char *conname, const char *attribname, const char *value, unsigned int valuesize));
|
||||
EBUILTIN(void, Con_SetConsoleString, (const char *conname, const char *attribname, const char *newvalue));
|
||||
|
||||
EBUILTIN(void, Sys_Error, (char *message)); //abort the entire engine.
|
||||
EBUILTIN(void, Sys_Error, (const char *message)); //abort the entire engine.
|
||||
EBUILTIN(unsigned int, Sys_Milliseconds, ());
|
||||
|
||||
EBUILTIN(int, Cmd_AddCommand, (char *buffer)); //abort the entire engine.
|
||||
EBUILTIN(int, Cmd_AddCommand, (const char *buffer)); //abort the entire engine.
|
||||
EBUILTIN(void, Cmd_Args, (char *buffer, int bufsize)); //abort the entire engine.
|
||||
EBUILTIN(void, Cmd_Argv, (int argnum, char *buffer, int bufsize)); //abort the entire engine.
|
||||
EBUILTIN(int, Cmd_Argc, (void)); //abort the entire engine.
|
||||
EBUILTIN(void, Cmd_AddText, (char *text, qboolean insert));
|
||||
EBUILTIN(void, Cmd_Tokenize, (char *msg)); //abort the entire engine.
|
||||
EBUILTIN(void, Cmd_AddText, (const char *text, qboolean insert));
|
||||
EBUILTIN(void, Cmd_Tokenize, (const char *msg)); //abort the entire engine.
|
||||
|
||||
EBUILTIN(void, Cvar_SetString, (char *name, char *value));
|
||||
EBUILTIN(void, Cvar_SetFloat, (char *name, float value));
|
||||
EBUILTIN(qboolean, Cvar_GetString, (char *name, char *retstring, int sizeofretstring));
|
||||
EBUILTIN(float, Cvar_GetFloat, (char *name));
|
||||
EBUILTIN(qhandle_t, Cvar_Register, (char *name, char *defaultval, int flags, char *grouphint));
|
||||
EBUILTIN(void, Cvar_SetString, (const char *name, char *value));
|
||||
EBUILTIN(void, Cvar_SetFloat, (const char *name, float value));
|
||||
EBUILTIN(qboolean, Cvar_GetString, (const char *name, char *retstring, int sizeofretstring));
|
||||
EBUILTIN(float, Cvar_GetFloat, (const char *name));
|
||||
EBUILTIN(qhandle_t, Cvar_Register, (const char *name, const char *defaultval, int flags, const char *grouphint));
|
||||
EBUILTIN(int, Cvar_Update, (qhandle_t handle, int *modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
|
||||
|
||||
EBUILTIN(void, GetPluginName, (int plugnum, char *buffer, int bufsize));
|
||||
EBUILTIN(void, LocalSound, (char *soundname));
|
||||
EBUILTIN(void, LocalSound, (const char *soundname));
|
||||
EBUILTIN(int, CL_GetStats, (int pnum, unsigned int *stats, int maxstats));
|
||||
EBUILTIN(int, GetPlayerInfo, (int pnum, plugclientinfo_t *info));
|
||||
|
||||
EBUILTIN(int, LocalPlayerNumber, (void)); //deprecated
|
||||
EBUILTIN(int, GetLocalPlayerNumbers, (int firstseat, int numseats, int *playernums, int *spectracks));
|
||||
EBUILTIN(void, GetServerInfo, (char *info, int infolen));
|
||||
EBUILTIN(void, SetUserInfo, (char *key, char *value));
|
||||
EBUILTIN(void, GetLocationName, (float *pos, char *buffer, int bufferlen));
|
||||
EBUILTIN(void, GetLocationName, (float *pos, char *buffer, int bufferlen));
|
||||
EBUILTIN(void, SetUserInfo, (const char *key, const char *value));
|
||||
EBUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
EBUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
|
||||
typedef struct {
|
||||
int seats;
|
||||
struct
|
||||
{
|
||||
float avg;
|
||||
float mn;
|
||||
float mx;
|
||||
float stddev;
|
||||
float loss;
|
||||
float s_avg;
|
||||
float s_mn;
|
||||
float s_mx;
|
||||
float ms_stddev; //calculated in milliseconds for more sane numbers
|
||||
float fr_avg;
|
||||
int fr_mn;
|
||||
int fr_mx;
|
||||
} ping;
|
||||
struct
|
||||
{ //decimals
|
||||
float dropped;
|
||||
float choked;
|
||||
float invalid;
|
||||
} loss;
|
||||
float mlatency;
|
||||
float mrate;
|
||||
float vlatency;
|
||||
|
@ -265,6 +273,7 @@ typedef struct {
|
|||
float out_pps;
|
||||
float out_bps;
|
||||
} svrate;
|
||||
int capturing; //avi capturing
|
||||
} vmnetinfo_t;
|
||||
EBUILTIN(int, GetNetworkInfo, (vmnetinfo_t *ni, unsigned int sizeofni));
|
||||
|
||||
|
|
Loading…
Reference in a new issue