tweak particle system a little for more compat.

added a couple extra effects to r_particledesc high
try and solve the trailparticles madness once and for all by autodetecting which set of arguments is used.
fix some annoyances with menuqc.
rebuild fs cache when doing vid_restart, to avoid insane reload times.
add profiling support.
qcc: be more permissive with {a,b,} in array definitions.
tweaked logfrag builtin to not loose frags quite so easily. should be more robust now. Whether tools agree or not is a different matter... but there's always the possibility that it'll just work.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4644 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-04-24 01:53:01 +00:00
parent e849ff8003
commit dd8628eb2a
58 changed files with 1171 additions and 442 deletions

View File

@ -100,7 +100,7 @@ void Cam_Lock(playerview_t *pv, int playernum)
pv->cam_spec_track = playernum;
pv->cam_locked = false;
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1); //free floating
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1); //free floating until actually locked
Skin_FlushPlayers();
@ -765,6 +765,7 @@ void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg)
pv->cam_auto = CAM_TRACK;
Cam_Lock(pv, slot);
//and force the lock here and now
pv->cam_locked = true;
pv->viewentity = slot+1;
}

View File

@ -1287,6 +1287,8 @@ void DP5_ParseDelta(entity_state_t *s)
s->glowmod[1] = MSG_ReadByte();
s->glowmod[2] = MSG_ReadByte();
}
if (bits & E5_TRAILEFFECTNUM)
s->u.q1.traileffectnum = MSG_ReadShort();
}
void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o(

View File

@ -4406,75 +4406,90 @@ void CL_SetStatString (int pnum, int stat, char *value)
CL_MuzzleFlash
==============
*/
void CL_MuzzleFlash (int destsplit)
void CL_MuzzleFlash (int entnum)
{
vec3_t fv, rv, uv;
dlight_t *dl=NULL;
int i;
dlight_t *dl;
player_state_t *pl;
packet_entities_t *pack;
entity_state_t *s1;
int pnum;
vec3_t org = {0,0,0};
vec3_t axis[3] = {{0,0,0}};
int dlightkey = 0;
extern int pt_muzzleflash;
extern cvar_t cl_muzzleflash;
i = MSGCL_ReadEntity ();
//was it us?
if (!cl_muzzleflash.ival) // remove all muzzleflashes
return;
if (i-1 == cl.playerview[destsplit].playernum && cl_muzzleflash.value == 2)
if (cl_muzzleflash.value == 2)
{
//muzzleflash 2 removes muzzleflashes on us
for (pnum = 0; pnum < cl.splitclients; pnum++)
if (entnum-1 == cl.playerview[pnum].playernum)
return;
}
if (!dlightkey)
{
pack = &cl.inframes[cl.validsequence&UPDATE_MASK].packet_entities;
for (pnum=0 ; pnum<pack->num_entities ; pnum++) //try looking for an entity with that id first
{
s1 = &pack->entities[pnum];
if (s1->number == entnum)
{
dlightkey = entnum;
VectorCopy(s1->origin, org);
AngleVectors(s1->angles, axis[0], axis[1], axis[2]);
break;
}
}
}
if (!dlightkey)
{ //that ent number doesn't exist, go for a player with that number
if ((unsigned)(entnum) <= cl.allocated_client_slots && entnum > 0)
{
pl = &cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[entnum-1];
if (pl->messagenum == cl.validsequence)
{
dlightkey = -entnum;
VectorCopy(pl->origin, org);
AngleVectors(pl->viewangles, axis[0], axis[1], axis[2]);
if (pl->szmins[2] == 0) /*hull is 0-based, so origin is bottom of model, move the light up slightly*/
org[2] += pl->szmaxs[2]/2;
}
}
}
if (!dlightkey)
return;
pack = &cl.inframes[cl.validsequence&UPDATE_MASK].packet_entities;
for (pnum=0 ; pnum<pack->num_entities ; pnum++) //try looking for an entity with that id first
if (P_RunParticleEffectType(org, NULL, 1, pt_muzzleflash))
{
s1 = &pack->entities[pnum];
dl = CL_AllocDlight (dlightkey);
VectorMA (org, 15, axis[0], dl->origin);
memcpy(dl->axis, axis, sizeof(dl->axis));
if (s1->number == i)
{
dl = CL_AllocDlight (i);
VectorCopy (s1->origin, dl->origin);
AngleVectors(s1->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
break;
}
}
if (pnum==pack->num_entities)
{ //that ent number doesn't exist, go for a player with that number
if ((unsigned)(i) <= cl.allocated_client_slots && i > 0)
{
pl = &cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[i-1];
dl->radius = 200 + (rand()&31);
dl->minlight = 32;
dl->die = cl.time + 0.1;
dl->color[0] = 1.5;
dl->color[1] = 1.3;
dl->color[2] = 1.0;
dl = CL_AllocDlight (-i);
VectorCopy (pl->origin, dl->origin); //set it's origin
if (pl->szmins[2] == 0) /*hull is 0-based, so origin is bottom of model, move the light up slightly*/
dl->origin[2] += pl->szmaxs[2]/2;
AngleVectors(pl->viewangles, dl->axis[0], dl->axis[1], dl->axis[2]);
AngleVectors (pl->viewangles, fv, rv, uv); //shift it up a little
VectorMA (dl->origin, 15, fv, dl->origin);
}
else
return;
}
dl->radius = 200 + (rand()&31);
dl->minlight = 32;
dl->die = cl.time + 0.1;
dl->color[0] = 1.3;
dl->color[1] = 1.3;
dl->color[2] = 1.3;
dl->channelfade[0] = 1.5;
dl->channelfade[1] = 0.75;
dl->channelfade[2] = 0.375;
dl->decay = 500;
dl->channelfade[0] = 1.5;
dl->channelfade[1] = 0.75;
dl->channelfade[2] = 0.375;
dl->decay = 1000;
#ifdef RTLIGHTS
dl->lightcolourscales[2] = 4;
dl->lightcolourscales[2] = 4;
#endif
}
}
#ifdef Q2CLIENT
@ -5761,7 +5776,7 @@ void CLQW_ParseServerMessage (void)
break;
case svc_muzzleflash:
CL_MuzzleFlash (destsplit);
CL_MuzzleFlash (MSGCL_ReadEntity());
break;
case svc_updateuserinfo:

View File

@ -888,6 +888,20 @@ void CL_PredictMovePNum (int seat)
VectorCopy (pv->viewangles, pv->simangles);
}
if (!pv->cam_locked && pv->cam_auto && cl.spectator && pv->cam_spec_track >= 0 && pv->cam_spec_track < cl.allocated_client_slots && pv->viewentity != pv->cam_spec_track+1)
{
if (cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[pv->cam_spec_track].messagenum == cl.validsequence)
{
pv->cam_locked = true;
pv->viewentity = pv->cam_spec_track+1;
}
else if (pv->cam_spec_track+1 < cl.maxlerpents && cl.lerpents[pv->cam_spec_track+1].sequence == cl.lerpentssequence)
{
pv->cam_locked = true;
pv->viewentity = pv->cam_spec_track+1;
}
}
nopred = cl_nopred.ival;
//don't wrap

View File

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
entity_state_t *CL_FindPacketEntity(int num);
int
pt_muzzleflash=P_INVALID,
pt_gunshot=P_INVALID,
ptdp_gunshotquad=P_INVALID,
pt_spike=P_INVALID,
@ -420,6 +421,7 @@ void CL_RegisterParticles(void)
}
}
pt_muzzleflash = P_FindParticleType("TE_MUZZLEFLASH");
pt_gunshot = P_FindParticleType("TE_GUNSHOT"); /*shotgun*/
ptdp_gunshotquad = P_FindParticleType("TE_GUNSHOTQUAD"); /*DP: quadded shotgun*/
pt_spike = P_FindParticleType("TE_SPIKE"); /*nailgun*/
@ -770,6 +772,7 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n
return;
}
b->rflags = RF_NOSHADOW;
b->entity = ent;
b->model = m;
b->particleeffect = btype;
@ -858,7 +861,8 @@ void CL_ParseStream (int type)
Con_Printf ("beam list overflow!\n");
return;
}
b->rflags = RF_NOSHADOW;
b->entity = ent;
b->tag = tag;
b->bflags = flags;
@ -914,7 +918,7 @@ void CL_ParseStream (int type)
b2->emitstate = NULL;
b2->model = Mod_ForName("models/stsunsf2.mdl", MLV_WARN);
b2->alpha = 0.5;
b2->rflags = RF_TRANSLUCENT;
b2->rflags = RF_TRANSLUCENT|RF_NOSHADOW;
}
}
//FIXME: we don't add the blob corners+smoke
@ -1742,7 +1746,7 @@ typedef struct custtentinst_s
} custtentinst_t;
custtentinst_t *activepcusttents;
void CL_SpawnCustomTEnd(custtentinst_t *info)
void CL_SpawnCustomTEnt(custtentinst_t *info)
{
clcustomtents_t *t = info->type;
qboolean failed;
@ -1838,7 +1842,7 @@ void CL_RunPCustomTEnts(void)
lasttime = cl.time;
for (ef = activepcusttents; ef; ef = ef->next)
{
CL_SpawnCustomTEnd(ef);
CL_SpawnCustomTEnt(ef);
}
}
@ -1960,7 +1964,7 @@ void CL_ParseCustomTEnt(void)
}
}
else
CL_SpawnCustomTEnd(&info);
CL_SpawnCustomTEnt(&info);
}
void CL_RefreshCustomTEnts(void)
{
@ -2024,7 +2028,7 @@ int CL_TranslateParticleFromServer(int qceffect)
return cl.particle_csprecache[qceffect];
}
else
return -1;
return P_INVALID;
// else
// {

View File

@ -55,6 +55,7 @@ HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion,
static cvar_t in_dinput = CVARF("in_dinput","0", CVAR_ARCHIVE);
static cvar_t in_builtinkeymap = CVARF("in_builtinkeymap", "0", CVAR_ARCHIVE);
static cvar_t in_simulatemultitouch = CVAR("in_simulatemultitouch", "0");
static cvar_t in_nonstandarddeadkeys = CVARD("in_nonstandarddeadkeys", "1", "Discard input events that result in multiple keys. Only the last key will be used. This results in behaviour that differs from eg notepad. To use a dead key, press it twice instead of the dead key followed by space.");
static cvar_t m_accel_noforce = CVAR("m_accel_noforce", "0");
static cvar_t m_threshold_noforce = CVAR("m_threshold_noforce", "0");
@ -1095,6 +1096,7 @@ void INS_Init (void)
Cvar_Register (&in_dinput, "Input Controls");
Cvar_Register (&in_builtinkeymap, "Input Controls");
Cvar_Register (&in_nonstandarddeadkeys, "Input Controls");
Cvar_Register (&in_simulatemultitouch, "Input Controls");
Cvar_Register (&m_accel_noforce, "Input Controls");
@ -2086,6 +2088,7 @@ void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdev
extern cvar_t in_builtinkeymap;
int qcode;
int unicode;
int chars;
extern int keyshift[256];
extern int shift_down;
@ -2096,11 +2099,16 @@ void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdev
BYTE keystate[256];
WCHAR wchars[2];
GetKeyboardState(keystate);
if (ToUnicode(wParam, HIWORD(lParam), keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0) > 0)
chars = ToUnicode(wParam, HIWORD(lParam), keystate, wchars, sizeof(wchars)/sizeof(wchars[0]), 0);
if (chars > 0)
{
//ignore if more, its probably a compose and > 65535 anyway. we can't represent that.
// if (!wchars[1])
unicode = wchars[0];
if (!in_nonstandarddeadkeys.ival)
{
for (unicode = 0; unicode < chars-1; unicode++)
Key_Event (qdeviceid, 0, wchars[unicode], down);
}
unicode = wchars[chars-1];
}
else unicode = 0;
}
@ -2110,7 +2118,6 @@ void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdev
if (shift_down && unicode < K_MAX && keyshift[unicode])
unicode = keyshift[unicode];
}
Key_Event (qdeviceid, qcode, unicode, down);
}
#endif

View File

@ -1922,7 +1922,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
char *dc, *uc;
char p[16];
int modifierstate;
int conkey = consolekeys[key] || (unicode && (key != '`' || key_linepos>1)); //if the input line is empty, allow ` to toggle the console, otherwise enter it as actual text.
int conkey = consolekeys[key] || ((unicode || key == '`') && (key != '`' || key_linepos>1)); //if the input line is empty, allow ` to toggle the console, otherwise enter it as actual text.
// Con_Printf ("%i : %i : %i\n", key, unicode, down); //@@@

View File

@ -88,6 +88,7 @@ void M_Menu_Options_f (void)
MB_CONSOLECMD("Reset to defaults", "cvarreset *\nexec default.cfg\nplay misc/menu2.wav\n", "Reloads the default configuration."),
MB_CONSOLECMD("Save all settings", "cfg_save\n", "Writes changed settings out to a config file."),
MB_SPACING(4),
MB_SLIDER("Field of View", scr_fov, 80, 110, 5, NULL),
MB_SLIDER("Mouse Speed", sensitivity, 1, 10, 0.2, NULL),
MB_SLIDER("Crosshair", crosshair, 0, 22, 1, NULL), // move this to hud setup?
MB_CHECKBOXFUNC("Always Run", M_Options_AlwaysRun, 0, "Set movement to run at fastest speed by default."),
@ -567,6 +568,8 @@ const char *presetexec[] =
"cl_nolerp 1;"
"r_lerpmuzzlehack 0;"
"v_gunkick 0;"
"cl_rollangle 0;"
"cl_bob 0;"
, // fast options
"gl_texturemode ln;"
@ -600,6 +603,8 @@ const char *presetexec[] =
"cl_nolerp 0;"
"r_lerpmuzzlehack 1;"
"v_gunkick 1;"
"cl_rollangle 2.0;"
"cl_bob 0.02;"
, // nice options
"r_stains 0.75;"

View File

@ -1940,9 +1940,10 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
info->ping = ping;
info->players = 0;
info->maxplayers = atoi(Info_ValueForKey(msg, "maxclients"));
if (!info->maxplayers)
info->maxplayers = atoi(Info_ValueForKey(msg, "sv_maxclients"));
ping = atoi(Info_ValueForKey(msg, "maxclients"));
if (!ping)
ping = atoi(Info_ValueForKey(msg, "sv_maxclients"));
info->maxplayers = bound(0, ping, 255);
info->tl = atoi(Info_ValueForKey(msg, "timelimit"));
info->fl = atoi(Info_ValueForKey(msg, "fraglimit"));

File diff suppressed because it is too large Load Diff

View File

@ -2215,7 +2215,7 @@ static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globa
float *start = G_VECTOR(OFS_PARM2);
float *end = G_VECTOR(OFS_PARM3);
if (csqc_isdarkplaces)
if (G_INT(OFS_PARM1) >= MAX_EDICTS)
{
efnum = G_FLOAT(OFS_PARM1);
ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
@ -5342,7 +5342,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
csqcprogs = InitProgs(&csqcprogparms);
csqc_world.progs = csqcprogs;
csqc_world.usesolidcorpse = true;
PR_Configure(csqcprogs, pr_csqc_memsize.ival, 16);
PR_Configure(csqcprogs, pr_csqc_memsize.ival, 16, pr_enable_profiling.ival);
csqc_world.worldmodel = cl.worldmodel;
csqc_world.Event_Touch = CSQC_Event_Touch;
csqc_world.Event_Think = CSQC_Event_Think;
@ -5688,6 +5688,12 @@ void CSQC_WatchPoint_f(void)
else
Con_Printf("Watchpoint cleared\n");
}
void PR_CSProfile_f(void)
{
if (csqcprogs && csqcprogs->DumpProfile)
if (!csqcprogs->DumpProfile(csqcprogs))
Con_Printf("Please set pr_enable_profiling and restart the map first\n");
}
static void CSQC_GameCommand_f(void);
void CSQC_RegisterCvarsAndThings(void)
@ -5698,6 +5704,7 @@ void CSQC_RegisterCvarsAndThings(void)
Cmd_AddCommand("breakpoint_csqc", CSQC_Breakpoint_f);
Cmd_AddCommand ("watchpoint_csqc", CSQC_WatchPoint_f);
Cmd_AddCommandD("poke_csqc", CSQC_Poke_f, "Allows you to inspect/debug ");
Cmd_AddCommand ("profile_csqc", PR_CSProfile_f);
Cvar_Register(&pr_csqc_formenus, CSQCPROGSGROUP);
Cvar_Register(&pr_csqc_memsize, CSQCPROGSGROUP);

View File

@ -779,6 +779,18 @@ void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_
con->parseflags |= PFS_FORCEUTF8;
}
}
else if (!strcmp(field, "close"))
{
RETURN_TSTRING("0"); //meant to return the old state...
if (value && atoi(value))
Con_Destroy(con);
}
else if (!strcmp(field, "clear"))
{
RETURN_TSTRING(con->linecount?"0":"1");
if (value && atoi(value))
Con_ClearCon(con);
}
else if (!strcmp(field, "hidden"))
{
RETURN_TSTRING((con->flags & CON_HIDDEN)?"1":"0");
@ -985,7 +997,12 @@ static void QCBUILTIN PF_menu_cvar_string (pubprogfuncs_t *prinst, struct global
{
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
cvar_t *cv = Cvar_Get(RemapCvarNameFromDPToFTE(str), "", 0, "QC variables");
G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, cv->string );
if (!cv)
G_INT(OFS_RETURN) = 0;
else if (cv->latched_string)
G_INT(OFS_RETURN) = (int)PR_SetString(prinst, cv->latched_string);
else
G_INT(OFS_RETURN) = (int)PR_SetString(prinst, cv->string);
}
qboolean M_Vid_GetMode(int num, int *w, int *h);
@ -1093,10 +1110,13 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
case 0:
// key_game
if (!(cls.state == ca_active))
if (cls.state == ca_disconnected)
Key_Dest_Add(kdm_console);
Key_Dest_Remove(kdm_menu);
Key_Dest_Remove(kdm_message);
if (Key_Dest_Has(kdm_menu))
{
Key_Dest_Remove(kdm_menu);
Key_Dest_Remove(kdm_message);
}
break;
case 2:
// key_menu
@ -1959,7 +1979,7 @@ qboolean MP_Init (void)
int mprogs;
Con_DPrintf("Initializing menu.dat\n");
menu_world.progs = InitProgs(&menuprogparms);
PR_Configure(menu_world.progs, 64*1024*1024, 1);
PR_Configure(menu_world.progs, 64*1024*1024, 1, pr_enable_profiling.ival);
mprogs = PR_LoadProgs(menu_world.progs, "menu.dat", 10020, NULL, 0);
if (mprogs < 0) //no per-progs builtins.
{
@ -2057,6 +2077,16 @@ void MP_Reload_f(void)
M_Reinit();
}
static void MP_Poke_f(void)
{
if (!SV_MayCheat())
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
else if (svprogfuncs && svprogfuncs->EvaluateDebugString)
Con_TPrintf("Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args()));
else
Con_TPrintf ("not supported.\n");
}
void MP_Breakpoint_f(void)
{
int wasset;
@ -2090,6 +2120,9 @@ void MP_RegisterCvarsAndCmds(void)
Cmd_AddCommand("breakpoint_menu", MP_Breakpoint_f);
Cmd_AddCommand("loadfont", CL_LoadFont_f);
Cmd_AddCommand("poke_menuqc", MP_Poke_f);
Cvar_Register(&forceqmenu, MENUPROGSGROUP);
Cvar_Register(&pr_menuqc_coreonerror, MENUPROGSGROUP);

View File

@ -833,9 +833,9 @@ void R2D_Console_Resize(void)
if (!cwidth && !cheight)
cheight = 480;
if (cheight && !cwidth)
if (cheight && !cwidth && vid.rotpixelheight)
cwidth = (cheight*vid.rotpixelwidth)/vid.rotpixelheight;
if (cwidth && !cheight)
if (cwidth && !cheight && vid.rotpixelwidth)
cheight = (cwidth*vid.rotpixelheight)/vid.rotpixelwidth;
if (!cwidth)

View File

@ -341,8 +341,6 @@ enum imageflags
/*warning: many of these flags only apply the first time it is requested*/
IF_CLAMP = 1<<0,
IF_NEAREST = 1<<1,
IF_UIPIC = 1<<10, //subject to texturemode2d
IF_LINEAR = 1<<11,
IF_NOPICMIP = 1<<2,
IF_NOMIPMAP = 1<<3,
IF_NOALPHA = 1<<4,
@ -353,6 +351,9 @@ enum imageflags
IF_TEXTYPE = (1<<6) | (1<<7) | (1<<8), /*0=2d, 1=3d, 2-7=cubeface*/
IF_TEXTYPESHIFT = 6, /*0=2d, 1=3d, 2-7=cubeface*/
IF_MIPCAP = 1<<9,
IF_UIPIC = 1<<10, //subject to texturemode2d
IF_LINEAR = 1<<11,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
IF_EXACTEXTENSION = 1<<29,
IF_REPLACE = 1<<30,
IF_SUBDIRONLY = 1<<31
@ -433,10 +434,10 @@ void Mod_NowLoadExternal(void);
void GLR_LoadSkys (void);
void R_BloomRegister(void);
int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void Mod_UnRegisterModelFormat(int idx);
void Mod_UnRegisterAllModelFormats(void *module);
int QDECL Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int QDECL Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void QDECL Mod_UnRegisterModelFormat(int idx);
void QDECL Mod_UnRegisterAllModelFormats(void *module);
#ifdef RUNTIMELIGHTING
void LightFace (int surfnum);

View File

@ -857,6 +857,7 @@ rendererinfo_t d3d11rendererinfo;
#ifdef SWQUAKE
rendererinfo_t swrendererinfo;
#endif
rendererinfo_t headlessrenderer;
rendererinfo_t *rendererinfo[] =
{
@ -879,6 +880,7 @@ rendererinfo_t *rendererinfo[] =
#ifndef NPQTV
&dedicatedrendererinfo,
#endif
&headlessrenderer,
};
@ -1017,6 +1019,7 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
extern model_t *loadmodel;
Cache_Flush();
COM_FlushFSCache(); //make sure the fs cache is built if needed. there's lots of loading here.
TRACE(("dbg: R_ApplyRenderer: old renderer closed\n"));

View File

@ -816,6 +816,8 @@ void Sbar_Start (void) //if one of these fails, skip the entire status bar.
}
failedpic = false;
COM_FlushFSCache(); //make sure the fs cache is built if needed. there's lots of loading here.
sbarfailed = false;
for (i=0 ; i<10 ; i++)

View File

@ -574,7 +574,7 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
GLVID_Crashed();
#endif
if (!iswatchdog && pIsDebuggerPresent ())
if (!iswatchdog && pIsDebuggerPresent && pIsDebuggerPresent ())
{
/*if we have a current window, minimize it to bring us out of fullscreen*/
extern qboolean vid_initializing;

View File

@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// a pixel can be one, two, or four bytes
typedef qbyte pixel_t;
typedef enum {QR_NONE, QR_OPENGL, QR_DIRECT3D9, QR_DIRECT3D11, QR_SOFTWARE} r_qrenderer_t;
typedef enum {QR_NONE, QR_HEADLESS, QR_OPENGL, QR_DIRECT3D9, QR_DIRECT3D11, QR_SOFTWARE} r_qrenderer_t;
typedef struct {
//you are not allowed to make anything not work if it's not based on these vars...

View File

@ -633,7 +633,7 @@ uses parent bone info, so don't try to offset for a first bone.
ALWAYS writes dest. Don't force it if you don't want to waste cycles when no conversion is actually needed.
destbonecount is to catch errors, its otherwise ignored for now. no identity padding.
*/
void Alias_ForceConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount)
void QDECL Alias_ForceConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount)
{
float altbuffer[MAX_BONES*12];
const float *buf = Alias_ConvertBoneData(sourcetype, sourcedata, bonecount, bones, desttype, destbuffer, altbuffer, destbonecount);

View File

@ -164,27 +164,27 @@ typedef struct galiasinfo_s
typedef struct
{
int (*RegisterModelFormatText)(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int (*RegisterModelFormatMagic)(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void (*UnRegisterModelFormat)(int idx);
void (*UnRegisterAllModelFormats)(void *module);
int (QDECL *RegisterModelFormatText)(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
int (QDECL *RegisterModelFormatMagic)(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize));
void (QDECL *UnRegisterModelFormat)(int idx);
void (QDECL *UnRegisterAllModelFormats)(void *module);
void *(*ZG_Malloc)(zonegroup_t *ctx, int size);
void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, int size);
void (*ConcatTransforms) (float in1[3][4], float in2[3][4], float out[3][4]);
void (*M3x4_Invert) (const float *in1, float *out);
void (*StripExtension) (const char *in, char *out, int outlen);
void (*GenMatrixPosQuat4Scale)(vec3_t pos, vec4_t quat, vec3_t scale, float result[12]);
void (*ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
void (QDECL *ConcatTransforms) (float in1[3][4], float in2[3][4], float out[3][4]);
void (QDECL *M3x4_Invert) (const float *in1, float *out);
void (QDECL *StripExtension) (const char *in, char *out, int outlen);
void (QDECL *GenMatrixPosQuat4Scale)(vec3_t pos, vec4_t quat, vec3_t scale, float result[12]);
void (QDECL *ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
shader_t *(*RegisterShader) (const char *name, unsigned int usageflags, const char *shaderscript);
shader_t *(*RegisterSkin) (const char *shadername, const char *modname);
void (*BuildDefaultTexnums)(texnums_t *tn, shader_t *shader);
shader_t *(QDECL *RegisterShader) (const char *name, unsigned int usageflags, const char *shaderscript);
shader_t *(QDECL *RegisterSkin) (const char *shadername, const char *modname);
void (QDECL *BuildDefaultTexnums)(texnums_t *tn, shader_t *shader);
} modplugfuncs_t;
#ifdef SKELETALMODELS
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout);
void Alias_ForceConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
void QDECL Alias_ForceConvertBoneData(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount);
#endif
qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, int surfnum, entity_t *e, qboolean allowskel);
void Alias_FlushCache(void);

View File

@ -1759,7 +1759,7 @@ char *COM_SkipPath (const char *pathname)
COM_StripExtension
============
*/
void COM_StripExtension (const char *in, char *out, int outlen)
void QDECL COM_StripExtension (const char *in, char *out, int outlen)
{
char *s;

View File

@ -317,7 +317,7 @@ size_t unicode_strtoupper(const char *in, char *out, size_t outsize, qboolean ma
unsigned int unicode_charcount(const char *in, size_t buffersize, qboolean markup);
char *COM_SkipPath (const char *pathname);
void COM_StripExtension (const char *in, char *out, int outlen);
void QDECL COM_StripExtension (const char *in, char *out, int outlen);
void COM_StripAllExtensions (char *in, char *out, int outlen);
void COM_FileBase (const char *in, char *out, int outlen);
int QDECL COM_FileSize(const char *path);

View File

@ -198,6 +198,7 @@ void Con_ExecuteLine(console_t *con, char *line); //takes normal console command
void Con_CycleConsole (void);
int Con_IsActive (console_t *con);
void Con_Destroy (console_t *con);
void Con_ClearCon(console_t *con);
void Con_SetActive (console_t *con);
qboolean Con_NameForNum(int num, char *buffer, int buffersize);
console_t *Con_FindConsole(const char *name);

View File

@ -2299,7 +2299,7 @@ void COM_Gamedir (const char *dir)
#define QCFG "set allow_download_refpackages 0\n"
/*stuff that makes dp-only mods work a bit better*/
#define DPCOMPAT QCFG "set _cl_playermodel \"\"\n set dpcompat_set 1\n set dpcompat_trailparticles 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n"
#define DPCOMPAT QCFG "set _cl_playermodel \"\"\n set dpcompat_set 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n"
/*nexuiz/xonotic has a few quirks/annoyances...*/
#define NEXCFG DPCOMPAT "set r_particlesdesc effectinfo\nset sv_bigcoords 1\nset sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\npr_enable_uriget 0\n"
/*some modern non-compat settings*/

View File

@ -579,7 +579,7 @@ void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3])
R_ConcatTransforms
================
*/
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4])
void QDECL R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4])
{
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
in1[0][2] * in2[2][0];
@ -757,7 +757,7 @@ void VectorTransform (const vec3_t in1, const matrix3x4 in2, vec3_t out)
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
}
void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float result[12])
void QDECL GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float result[12])
{
float xx, xy, xz, xw, yy, yz, yw, zz, zw;
float x2, y2, z2;
@ -1635,7 +1635,7 @@ void Matrix3x4_Invert (const float *in1, float *out)
Vector4Set (out+8, c[0], c[1], c[2], -DotProduct (c, trans));
}
void Matrix3x4_Invert_Simple (const float *in1, float *out)
void QDECL Matrix3x4_Invert_Simple (const float *in1, float *out)
{
// we only support uniform scaling, so assume the first row is enough
// (note the lack of sqrt here, because we're trying to undo the scaling,

View File

@ -155,7 +155,7 @@ void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out);
void Matrix4x4_Identity(float *outm);
qboolean Matrix4_Invert(const float *m, float *out);
void Matrix3x4_Invert (const float *in1, float *out);
void Matrix3x4_Invert_Simple (const float *in1, float *out);
void QDECL Matrix3x4_Invert_Simple (const float *in1, float *out);
void Matrix3x4_InvertTo4x4_Simple (const float *in1, float *out);
void Matrix3x3_RM_Invert_Simple(const vec3_t in[3], vec3_t out[3]);
void Matrix4x4_RM_CreateTranslate (float *out, float x, float y, float z);
@ -182,7 +182,7 @@ void Matrix3x4_RM_Transform3(const float *matrix, const float *vector, float *p
float *Matrix4x4_CM_NewRotation(float a, float x, float y, float z);
float *Matrix4x4_CM_NewTranslation(float x, float y, float z);
void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float result[12]);
void QDECL GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float result[12]);
#define AngleVectorsFLU(a,f,l,u) do{AngleVectors(a,f,l,u);VectorNegate(l,l);}while(0)
@ -202,7 +202,7 @@ fixed16_t Mul16_30 (fixed16_t multiplier, fixed16_t multiplicand);
int Q_log2 (int val);
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
void R_ConcatRotationsPad (float in1[3][4], float in2[3][4], float out[3][4]);
void R_ConcatTransforms (matrix3x4 in1, matrix3x4 in2, matrix3x4 out);
void QDECL R_ConcatTransforms (matrix3x4 in1, matrix3x4 in2, matrix3x4 out);
void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees);
void RotateLightVector(const vec3_t *axis, const vec3_t origin, const vec3_t lightpoint, vec3_t result);
int VectorCompare (const vec3_t v1, const vec3_t v2);

View File

@ -77,7 +77,7 @@ typedef struct trailstate_s {
#define PARTICLE_Z_CLIP 8.0
typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADDA, BM_ADDC, BM_SUBTRACT, BM_INVMODA, BM_INVMODC } blendmode_t;
typedef enum { BM_BLEND/*SRC_ALPHA ONE_MINUS_SRC_ALPHA*/, BM_BLENDCOLOUR/*SRC_COLOR ONE_MINUS_SRC_COLOR*/, BM_ADDA/*SRC_ALPHA ONE*/, BM_ADDC/*GL_SRC_COLOR GL_ONE*/, BM_SUBTRACT/*SRC_ALPHA ONE_MINUS_SRC_COLOR*/, BM_INVMODA/*ZERO ONE_MINUS_SRC_ALPHA*/, BM_INVMODC/*ZERO ONE_MINUS_SRC_COLOR*/, BM_PREMUL/*ONE ONE_MINUS_SRC_ALPHA*/} blendmode_t;
#define frandom() (rand()*(1.0f/RAND_MAX))
#define crandom() (rand()*(2.0f/RAND_MAX)-1.0f)

View File

@ -16,10 +16,11 @@ static char *cvargroup_progs = "Progs variables";
cvar_t sv_gameplayfix_blowupfallenzombies = CVARD("sv_gameplayfix_blowupfallenzombies", "0", "Allow findradius to find non-solid entities. This may break certain mods.");
cvar_t pr_droptofloorunits = CVAR("pr_droptofloorunits", "");
cvar_t pr_brokenfloatconvert = SCVAR("pr_brokenfloatconvert", "0");
cvar_t pr_tempstringcount = SCVAR("pr_tempstringcount", "");//"16");
cvar_t pr_tempstringsize = SCVAR("pr_tempstringsize", "4096");
cvar_t pr_enable_uriget = SCVAR("pr_enable_uriget", "1");
cvar_t pr_brokenfloatconvert = CVAR("pr_brokenfloatconvert", "0");
cvar_t pr_tempstringcount = CVAR("pr_tempstringcount", "");//"16");
cvar_t pr_tempstringsize = CVAR("pr_tempstringsize", "4096");
cvar_t pr_enable_uriget = CVAR("pr_enable_uriget", "1");
cvar_t pr_enable_profiling = CVARD("pr_enable_profiling", "0", "Enables profiling support. Will run more slowly. Change the map and then use the profile_ssqc/profile_csqc commands to see the results.");
int tokenizeqc(const char *str, qboolean dpfuckage);
void skel_info_f(void);
@ -32,6 +33,7 @@ void PF_Common_RegisterCvars(void)
Cvar_Register (&pr_tempstringcount, cvargroup_progs);
Cvar_Register (&pr_tempstringsize, cvargroup_progs);
Cvar_Register (&pr_enable_uriget, cvargroup_progs);
Cvar_Register (&pr_enable_profiling, cvargroup_progs);
#ifdef RAGDOLL
Cmd_AddCommand("skel_info", skel_info_f);
@ -5092,10 +5094,11 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_CSQC_SKELETONOBJECTS", 15, NULL, { "skel_create", "skel_build", "skel_get_numbones", "skel_get_bonename", "skel_get_boneparent", "skel_find_bone",
"skel_get_bonerel", "skel_get_boneabs", "skel_set_bone", "skel_mul_bone", "skel_mul_bones", "skel_copybones",
"skel_delete", "frameforname", "frameduration"}},
{"FTE_CSQC_RENDERTARGETS_WIP"},
{"FTE_ENT_SKIN_CONTENTS"}, //self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder.
{"FTE_ENT_UNIQUESPAWNID"},
{"FTE_EXTENDEDTEXTCODES"},
{"FTE_FORCESHADER", 1, NULL, {"shaderforname"}},
{"FTE_FORCESHADER", 1, NULL, {"shaderforname"}}, //I'd rename this to _CSQC_ but it does technically provide this builtin to menuqc too, not that the forceshader entity field exists there... but whatever.
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
{"FTE_GFX_QUAKE3SHADERS"},
{"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}},

View File

@ -83,6 +83,7 @@ char *PF_TempStr(pubprogfuncs_t *prinst); //returns a tempstring which can be fi
#define RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_TempString(prinst, s)) //temp (static but cycle buffers)
extern cvar_t pr_tempstringsize;
extern cvar_t pr_tempstringcount;
extern cvar_t pr_enable_profiling;
extern int qcinput_scan;
extern int qcinput_unicode;

View File

@ -1558,9 +1558,9 @@ typedef struct q1usercmd_s
// unused
#define E5_GLOWMOD (1<<24)
// unused
#define E5_UNUSED25 (1<<25)
#define E5_COMPLEXANIMATION (1<<25)
// unused
#define E5_UNUSED26 (1<<26)
#define E5_TRAILEFFECTNUM (1<<26)
// unused
#define E5_UNUSED27 (1<<27)
// unused
@ -1572,4 +1572,4 @@ typedef struct q1usercmd_s
// bits2 > 0
#define E5_EXTEND4 (1<<31)
#define E5_ALLUNUSED (E5_UNUSED25|E5_UNUSED26|E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30)
#define E5_ALLUNUSED (E5_COMPLEXANIMATION|E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30)

View File

@ -1500,7 +1500,7 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen
#endif
#ifdef TERRAIN
if (cl.worldmodel->terrain)
if (cl.worldmodel && cl.worldmodel->terrain)
Terrain_ClipDecal(&dec, center, dec.radius, cl.worldmodel);
#endif

View File

@ -457,10 +457,10 @@ typedef struct zonegroupblock_s
#ifdef USE_MSVCRT_DEBUG
#undef ZG_Malloc
void *ZG_Malloc(zonegroup_t *ctx, int size){return ZG_MallocNamed(ctx, size, "ZG_Malloc", size);}
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size){return ZG_MallocNamed(ctx, size, "ZG_Malloc", size);}
void *ZG_MallocNamed(zonegroup_t *ctx, int size, char *file, int line)
#else
void *ZG_Malloc(zonegroup_t *ctx, int size)
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size)
#endif
{
zonegroupblock_t *newm;

View File

@ -115,7 +115,7 @@ typedef struct zonegroup_s
void *first;
int bytes;
} zonegroup_t;
void *ZG_Malloc(zonegroup_t *ctx, int size);
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size);
void *ZG_MallocNamed(zonegroup_t *ctx, int size, char *file, int line);
void ZG_FreeGroup(zonegroup_t *ctx);

View File

@ -22754,6 +22754,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\vid_headless.c"
>
</File>
<Filter
Name="gl"
>

View File

@ -281,7 +281,8 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
{
Q_strncpyz(skin->mappings[skin->nummappings].surface, com_token, sizeof(skin->mappings[skin->nummappings].surface));
skintext = COM_ParseToken(skintext+1, NULL);
skin->mappings[skin->nummappings].shader = R_RegisterSkin(com_token, skin->skinname);
Q_strncpyz(shadername, com_token, sizeof(shadername));
skin->mappings[skin->nummappings].shader = R_RegisterSkin(shadername, skin->skinname);
R_BuildDefaultTexnums(NULL, skin->mappings[skin->nummappings].shader);
skin->mappings[skin->nummappings].texnums = skin->mappings[skin->nummappings].shader->defaulttextures;
skin->nummappings++;

View File

@ -1321,7 +1321,7 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
else if (scaled_width == width && scaled_height == height)
{
if ((flags&IF_NOMIPMAP)||gl_config.sgis_generate_mipmap) //gotta love this with NPOT textures... :)
if (((flags&IF_NOMIPMAP)||gl_config.sgis_generate_mipmap) && !(flags & IF_PREMULTIPLYALPHA)) //gotta love this with NPOT textures... :)
{
TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n"));
if (type == GL_UNSIGNED_SHORT_5_6_5)
@ -1336,6 +1336,19 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
}
else
GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
if (flags & IF_PREMULTIPLYALPHA)
{
//works for rgba or bgra
int i;
unsigned char *premul = (unsigned char*)scaled;
for (i = 0; i < scaled_width*scaled_height; i++, premul+=4)
{
premul[0] = (premul[0] * premul[3])>>8;
premul[1] = (premul[1] * premul[3])>>8;
premul[2] = (premul[2] * premul[3])>>8;
}
}
if (scaled_width * scaled_height*4 > sizeofuploadmemorybufferintermediate)
{
sizeofuploadmemorybufferintermediate = scaled_width * scaled_height * 4;

View File

@ -715,7 +715,7 @@ static struct
qboolean (QDECL *load) (model_t *mod, void *buffer, size_t buffersize);
} modelloaders[64];
int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize))
int QDECL Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize))
{
int i, free = -1;
for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++)
@ -739,7 +739,7 @@ int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magi
return free+1;
}
int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize))
int QDECL Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize))
{
int i, free = -1;
for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++)
@ -766,7 +766,7 @@ int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned
return free+1;
}
void Mod_UnRegisterModelFormat(int idx)
void QDECL Mod_UnRegisterModelFormat(int idx)
{
idx--;
if ((unsigned int)(idx) >= sizeof(modelloaders)/sizeof(modelloaders[0]))
@ -783,7 +783,7 @@ void Mod_UnRegisterModelFormat(int idx)
//FS_Restart will be needed
}
void Mod_UnRegisterAllModelFormats(void *module)
void QDECL Mod_UnRegisterAllModelFormats(void *module)
{
int i;
for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++)

View File

@ -282,6 +282,7 @@ void R_RenderDlights (void)
float intensity, cscale;
qboolean coronastyle;
qboolean flashstyle;
float dist;
if (!r_coronas.value && !r_flashblend.value)
return;
@ -321,6 +322,16 @@ void R_RenderDlights (void)
if (intensity <= 0 || cscale <= 0)
continue;
//prevent the corona from intersecting with the near clip plane by just fading it away if its too close
VectorSubtract(l->origin, r_refdef.vieworg, waste1);
dist = VectorLength(waste1);
if (dist < 128+256)
{
if (dist <= 128)
continue;
intensity *= (dist-128) / 256;
}
/*coronas use depth testing to compute visibility*/
if (coronastyle)
{

View File

@ -3854,7 +3854,7 @@ void Shader_UpdateRegistration (void)
}
*/
void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
{
char *h;
char imagename[MAX_QPATH];
@ -5145,7 +5145,7 @@ shader_t *R_RegisterPic (const char *name)
return shader;
}
shader_t *R_RegisterShader (const char *name, unsigned int usageflags, const char *shaderscript)
shader_t *QDECL R_RegisterShader (const char *name, unsigned int usageflags, const char *shaderscript)
{
return R_LoadShader (name, usageflags, Shader_DefaultScript, shaderscript);
}
@ -5165,7 +5165,7 @@ shader_t *R_RegisterShader_Flare (const char *name)
return R_LoadShader (name, 0, Shader_DefaultBSPFlare, NULL);
}
shader_t *R_RegisterSkin (const char *shadername, const char *modname)
shader_t *QDECL R_RegisterSkin (const char *shadername, const char *modname)
{
shader_t *shader;
#ifdef _DEBUG

View File

@ -555,13 +555,13 @@ extern int be_maxpasses;
void R_UnloadShader(shader_t *shader);
shader_t *R_RegisterPic (const char *name);
shader_t *R_RegisterShader (const char *name, unsigned int usageflags, const char *shaderscript);
shader_t *QDECL R_RegisterShader (const char *name, unsigned int usageflags, const char *shaderscript);
shader_t *R_RegisterShader_Lightmap (const char *name);
shader_t *R_RegisterShader_Vertex (const char *name);
shader_t *R_RegisterShader_Flare (const char *name);
shader_t *R_RegisterSkin (const char *shadername, const char *modname);
shader_t *QDECL R_RegisterSkin (const char *shadername, const char *modname);
shader_t *R_RegisterCustom (const char *name, unsigned int usageflags, shader_gen_t *defaultgen, const void *args);
void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader);
void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader);
void R_RemapShader(const char *sourcename, const char *destname, float timeoffset);
cin_t *R_ShaderGetCinematic(shader_t *s);

View File

@ -194,6 +194,34 @@ r_part +te_spike
assoc gunshotsmoke
}
r_part te_superspike
{
type sparkfan
count 20
scale 1
scalefactor 1
alpha 0.5
die 0.2
rgb 255 128 0
blend add
spawnmode ball
spawnorg 12
spawnvel 300
}
r_part +te_superspike
{
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
count 1
scale 1
scalefactor 1
scaledelta 190
die 0.1
alpha 0.6
rgb 255 128 0
blend add
assoc gunshotsmoke
}
////////////////////////////////////////////////
//explosion
@ -262,9 +290,10 @@ r_part +te_explosion
//hide lights in explosions.
//r_explosionlight 0
//hide the explosion sprite in nq+qw - WARNING: some mods use this sprite as a flame thrower.
//hide the explosion sprite in qw
cl_expsprite 0
r_effect "progs/s_explod.spr" hidden 1
//hide it in nq - WARNING: some mods use this sprite as a flame thrower.
//r_effect "progs/s_explod.spr" hidden 1
//////////////////////////////////////////
//r_part te_tarexplosion
@ -277,6 +306,7 @@ r_effect "progs/s_explod.spr" hidden 1
//}
//////////////////////////////////////////
//FIXME: what if we don't have glsl support?
r_part te_teleport
{
scale 250
@ -354,6 +384,22 @@ r_part tr_knightspike
lightrgb 0.75 0.37 0.18
}
r_part te_knightspike
{
type sparkfan
count 200
scale 3
scalefactor 1
alpha 0.5
die 0.5
rgb 192 96 48
blend add
spawnmode ball
spawnorg 12
spawnvel 100
stretchfactor 10
}
/////////////////////////////////////////
//vore missiles
r_part tr_vorespike
@ -408,13 +454,13 @@ r_part tr_enforcerlaser
r_trail "progs/laser.mdl" tr_enforcerlaser
/////////////////////////////////////////
//scrag missiles. just use the default trail cos we're lazy
//scrag missiles.
r_part tr_wizspike
{
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
scale 15
step 1
step 4
alpha 0.6
die 0.2
rgb 25 200 25
@ -425,12 +471,54 @@ r_part tr_wizspike
spawnmode spiral
spawnvel 25
blend add
lighttime 0
lighttime 2
lightradiusfade 75
lightshadows 0
lightradius 150
lightrgb 0.1 0.7 0.1
}
r_part tr_wizspike2
{
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
scale 4
step 1
alpha 0.6
die 0.2
rgb 25 200 25
veladd 64
randomvel 64
friction 4
scalefactor 0.825
spawnmode spiral
spawnvel 25
blend add
}
//scrag impact
r_part te_wizspike
{
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
scale 15
alpha 0.6
rgb 25 200 25
friction 0
scalefactor 0.825
blend add
count 5
veladd -256
randomvel 256
die 1
diesubrand 0.5
gravity 800
emit tr_wizspike2
emitinterval -1
bounce 1.5
}
/////////////////////////////////////////
//shambler stuff
r_part shambercharging
{
spawnmode ball
@ -456,7 +544,8 @@ r_part shambercharging
}
r_effect progs/s_light.mdl shambercharging 0
/////////////////////////////////////////
//blood effects
r_part te_blood
{
texture fte_bloodparticle

View File

@ -14,7 +14,6 @@
#if INTSIZE == 16
#define cont cont16
#define reeval reeval16
#define st st16
#define pr_statements pr_statements16
#define fakeop fakeop16
#define dstatement_t dstatement16_t
@ -23,7 +22,6 @@
#elif INTSIZE == 32
#define cont cont32
#define reeval reeval32
#define st st32
#define pr_statements pr_statements32
#define fakeop fakeop32
#define dstatement_t dstatement32_t
@ -44,8 +42,8 @@
#define ENGINEPOINTER(p) ((char*)(p) - progfuncs->funcs.stringtable)
#define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->funcs.stringtable)
#define QCPOINTERM(p) (eval_t *)((p)+progfuncs->funcs.stringtable)
#define QCPOINTERWRITEFAIL(p) ((unsigned int)p->_int-1 >= prinst.addressableused-1) //disallows null writes
#define QCPOINTERREADFAIL(p) ((unsigned int)p->_int >= prinst.addressableused) //permits null writes
#define QCPOINTERWRITEFAIL(p,sz) ((unsigned int)p->_int-1 >= prinst.addressableused-1-sz) //disallows null writes
#define QCPOINTERREADFAIL(p,sz) ((unsigned int)p->_int >= prinst.addressableused-sz) //permits null reads
//rely upon just st
{
@ -80,6 +78,7 @@ cont: //last statement may have been a breakpoint
if (progfuncs->funcs.pr_trace)
s=ShowStep(progfuncs, s);
st = pr_statements + s;
pr_xfunction->profile+=1;
reeval:
#else
@ -324,8 +323,10 @@ reeval:
//store a value to a pointer
case OP_STOREP_IF:
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
if (OPB->_int == -1)
break;
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
}
@ -333,8 +334,10 @@ reeval:
ptr->_float = (float)OPA->_int;
break;
case OP_STOREP_FI:
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(int)))
{
if (OPB->_int == -1)
break;
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
}
@ -347,8 +350,10 @@ reeval:
case OP_STOREP_FLD: // integers
case OP_STOREP_S:
case OP_STOREP_FNC: // pointers
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(int)))
{
if (OPB->_int == -1)
break;
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
@ -356,8 +361,10 @@ reeval:
ptr->_int = OPA->_int;
break;
case OP_STOREP_V:
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
{
if (OPB->_int == -1)
break;
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
@ -368,7 +375,7 @@ reeval:
break;
case OP_STOREP_C: //store character in a string
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(char)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -387,7 +394,7 @@ reeval:
OPB->_vector[2] *= tmpf;
break;
case OP_MULSTOREP_F: // e.f *= f
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -396,7 +403,7 @@ reeval:
OPC->_float = (ptr->_float *= OPA->_float);
break;
case OP_MULSTOREP_VF: // e.v *= f
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -412,7 +419,7 @@ reeval:
OPB->_float /= OPA->_float;
break;
case OP_DIVSTOREP_F: // e.f /= f
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -430,7 +437,7 @@ reeval:
OPB->_vector[2] += OPA->_vector[2];
break;
case OP_ADDSTOREP_F: // e.f += f
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -439,7 +446,7 @@ reeval:
OPC->_float = (ptr->_float += OPA->_float);
break;
case OP_ADDSTOREP_V: // e.v += v
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -459,7 +466,7 @@ reeval:
OPB->_vector[2] -= OPA->_vector[2];
break;
case OP_SUBSTOREP_F: // e.f -= f
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -468,7 +475,7 @@ reeval:
OPC->_float = (ptr->_float -= OPA->_float);
break;
case OP_SUBSTOREP_V: // e.v -= v
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(vec3_t)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
@ -511,6 +518,8 @@ reeval:
st--;
goto cont;
}
OPC->_int = ~0;
break;
}
}
@ -855,7 +864,7 @@ reeval:
break;
case OP_LOADP_C: //load character from a string
i = (unsigned int)OPA->_int + (unsigned int)OPB->_float;
if ((unsigned int)i >= prinst.addressableused)
if ((unsigned int)i > prinst.addressableused-sizeof(char))
{
i = (unsigned int)OPB->_float;
ptr = (eval_t*)PR_StringToNative(&progfuncs->funcs, OPA->_int);
@ -877,8 +886,10 @@ reeval:
case OP_LOADP_S:
case OP_LOADP_FNC:
i = OPA->_int + OPB->_int*4;
if ((unsigned int)i >= prinst.addressableused)
if ((unsigned int)i > prinst.addressableused-sizeof(int))
{
if (i == -1)
break;
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer read in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
}
@ -888,8 +899,10 @@ reeval:
case OP_LOADP_V:
i = OPA->_int + OPB->_int*4;
if ((unsigned int)i >= prinst.addressableused)
if ((unsigned int)i > prinst.addressableused-sizeof(vec3_t))
{
if (i == -1)
break;
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer read in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
}
@ -952,7 +965,7 @@ reeval:
OPB->_float = (float)((int)OPB->_float | (int)OPA->_float);
break;
case OP_BITSETSTOREP_F: // .b (+) a
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
@ -964,7 +977,7 @@ reeval:
OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float));
break;
case OP_BITCLRSTOREP_F: // .b (-) a
if (QCPOINTERWRITEFAIL(OPB))
if (QCPOINTERWRITEFAIL(OPB, sizeof(float)))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
@ -1170,7 +1183,7 @@ reeval:
case OP_GADDRESS: //return glob[aint+bfloat]
//this instruction is not implemented due to the weirdness of it.
//its theoretically a more powerful load... but untyped?
//or is it meant to be an LEA instruction (that could simply be switched with
//or is it meant to be an LEA instruction (that could simply be switched with OP_GLOAD_I)
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "OP_GADDRESS not implemented (found in %s)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
break;
@ -1183,7 +1196,7 @@ reeval:
if (OPA->_int < 0 || OPA->_int*4 >= current_progstate->globals_size)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPA->_int, current_progstate->globals_size);
}
ptr = ((eval_t *)&glob[OPA->_int]);
OPC->_int = ptr->_int;
@ -1192,7 +1205,7 @@ reeval:
if (OPA->_int < 0 || (OPA->_int+2)*4 >= current_progstate->globals_size)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPA->_int, current_progstate->globals_size);
}
ptr = ((eval_t *)&glob[OPA->_int]);
OPC->_vector[0] = ptr->_vector[0];

View File

@ -215,7 +215,7 @@ static void *PDECL PR_memalloc (pubprogfuncs_t *ppf, unsigned int size)
b = prinst.mfreelist;
while (b)
{
if (b < 0 || b >= prinst.addressableused)
if (b < 0 || b+sizeof(qcmemfreeblock_t) >= prinst.addressableused)
{
printf("PF_memalloc: memory corruption\n");
PR_StackTrace(&progfuncs->funcs);
@ -458,7 +458,7 @@ int PDECL PR_InitEnts(pubprogfuncs_t *ppf, int max_ents)
edictrun_t tempedict; //used as a safty buffer
static float tempedictfields[2048];
void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, int max_progs) //can be used to wipe all memory
static void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, int max_progs, pbool profiling) //can be used to wipe all memory
{
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
unsigned int i;
@ -505,6 +505,7 @@ void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, int max_p
prinst.reorganisefields = false;
prinst.profiling = profiling;
maxedicts = 1;
prinst.edicttable = &sv_edicts;
sv_num_edicts = 1; //set up a safty buffer so things won't go horribly wrong too often
@ -1023,6 +1024,58 @@ void PR_FreeTemps (progfuncs_t *progfuncs, int depth)
prinst.numtempstrings = depth;
}
pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf)
{
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
struct progstate_s *ps;
unsigned int i, f, j, s;
struct
{
char *fname;
int profile;
} *sorted, t;
if (!prinst.profiling)
{
printf("Enabling profiling\n");
return true;
}
for (i = 0; i < maxprogs; i++)
{
ps = &pr_progstate[i];
if (ps->progs == NULL) //we havn't loaded it yet, for some reason
continue;
printf("%s:\n", ps->filename);
sorted = malloc(sizeof(*sorted) * ps->progs->numfunctions);
//pull out the functions in order to sort them
for (s = 0, f = 0; f < ps->progs->numfunctions; f++)
{
if (!ps->functions[f].profile)
continue;
sorted[s].fname = ps->functions[f].s_name+progfuncs->funcs.stringtable;
sorted[s].profile = ps->functions[f].profile;
ps->functions[f].profile = 0;
s++;
}
// good 'ol bubble sort
for (f = 0; f < s; f++)
for (j = f; j < s; j++)
if (sorted[f].profile > sorted[j].profile)
{
t = sorted[f];
sorted[f] = sorted[j];
sorted[j] = t;
}
//print it out
for (f = 0; f < s; f++)
printf("%s: %u\n", sorted[f].fname, sorted[f].profile);
free(sorted);
}
return true;
}
static void PDECL PR_CloseProgs(pubprogfuncs_t *ppf);
@ -1130,7 +1183,8 @@ pubprogfuncs_t deffuncs = {
ED_FieldInfo,
PR_UglyValueString,
ED_ParseEval,
PR_SetStringField
PR_SetStringField,
PR_DumpProfiles
};
static int PDECL qclib_null_printf(const char *s, ...)
{

View File

@ -422,7 +422,7 @@ PR_EnterFunction
Returns the new program statement counter
====================
*/
int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, const dfunction_t *f, int progsnum)
int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
{
int i, j, c, o;
@ -1176,7 +1176,7 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
eval_t *t, *swtch=NULL;
int swtchtype = 0; //warning about not being initialized before use
dstatement16_t *fte_restrict st16;
const dstatement16_t *fte_restrict st;
dfunction_t *fte_restrict newf;
int i;
edictrun_t *ed;
@ -1191,8 +1191,8 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
#define OPC ((eval_t *)&glob[st->c])
#define INTSIZE 16
st16 = &pr_statements16[s];
while (progfuncs->funcs.pr_trace || prinst.watch_ptr)
st = &pr_statements16[s];
while (progfuncs->funcs.pr_trace || prinst.watch_ptr || prinst.profiling)
{
#ifdef FTE_TARGET_WEB
//this can generate huge functions, so disable it on systems that can't realiably cope with such things (IE initiates an unwanted denial-of-service attack when pointed our javascript, and firefox prints a warning too)
@ -1223,8 +1223,8 @@ static int PR_ExecuteCode32 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
eval_t *t, *swtch=NULL;
int swtchtype = 0; //warning about not being initialized before use
const dstatement32_t *fte_restrict st32;
const dfunction_t *fte_restrict newf;
const dstatement32_t *fte_restrict st;
dfunction_t *fte_restrict newf;
int i;
edictrun_t *ed;
eval_t *ptr;
@ -1238,8 +1238,8 @@ static int PR_ExecuteCode32 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
#define OPC ((eval_t *)&glob[st->c])
#define INTSIZE 32
st32 = &pr_statements32[s];
while (progfuncs->funcs.pr_trace || prinst.watch_ptr)
st = &pr_statements32[s];
while (progfuncs->funcs.pr_trace || prinst.watch_ptr || prinst.profiling)
{
#ifdef FTE_TARGET_WEB
//this can generate huge functions, so disable it on systems that can't realiably cope with such things (IE initiates an unwanted denial-of-service attack when pointed our javascript, and firefox prints a warning too)
@ -1513,7 +1513,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf)
void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
{
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
const dfunction_t *f, *oldf;
dfunction_t *f, *oldf;
int i,l,ls;
progsnum_t initial_progs;
int oldexitdepth;

View File

@ -61,7 +61,7 @@ typedef struct sharedvar_s
typedef struct
{
int s;
const dfunction_t *f;
dfunction_t *f;
int progsnum;
int pushed;
} prstack_t;
@ -129,7 +129,8 @@ int reorganisefields;
int continuestatement;
int exitdepth;
const dfunction_t *pr_xfunction;
pbool profiling;
dfunction_t *pr_xfunction;
#define pr_xfunction prinst.pr_xfunction
int pr_xstatement;
#define pr_xstatement prinst.pr_xstatement
@ -477,7 +478,7 @@ fdef_t *ED_FindField (progfuncs_t *progfuncs, const char *name);
fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs);
dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, const char *name, progsnum_t *pnum, progsnum_t fromprogs);
func_t PDECL PR_FindFunc(pubprogfuncs_t *progfncs, const char *funcname, progsnum_t pnum);
void PDECL PR_Configure (pubprogfuncs_t *progfncs, size_t addressable_size, int max_progs);
//void PDECL PR_Configure (pubprogfuncs_t *progfncs, size_t addressable_size, int max_progs);
int PDECL PR_InitEnts(pubprogfuncs_t *progfncs, int maxents);
char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val, pbool verbose);
void PDECL QC_ClearEdict (pubprogfuncs_t *progfuncs, struct edict_s *ed);

View File

@ -68,7 +68,7 @@ struct pubprogfuncs_s
void (PDECL *CloseProgs) (pubprogfuncs_t *inst);
void (PDECL *Configure) (pubprogfuncs_t *prinst, size_t addressablesize, int max_progs); //configure buffers and memory. Used to reset and must be called first. Flushes a running VM.
void (PDECL *Configure) (pubprogfuncs_t *prinst, size_t addressablesize, int max_progs, pbool enableprofiling); //configure buffers and memory. Used to reset and must be called first. Flushes a running VM.
progsnum_t (PDECL *LoadProgs) (pubprogfuncs_t *prinst, const char *s, int headercrc, builtin_t *builtins, int numbuiltins); //load a progs
int (PDECL *InitEnts) (pubprogfuncs_t *prinst, int max_ents); //returns size of edicts for use with nextedict macro
void (PDECL *ExecuteProgram) (pubprogfuncs_t *prinst, func_t fnum); //start execution
@ -171,6 +171,7 @@ struct pubprogfuncs_s
char *(PDECL *UglyValueString) (pubprogfuncs_t *progfuncs, etype_t type, union eval_s *val);
pbool (PDECL *ParseEval) (pubprogfuncs_t *progfuncs, union eval_s *eval, int type, const char *s);
void (PDECL *SetStringField) (pubprogfuncs_t *progfuncs, struct edict_s *ed, string_t *fld, const char *str, pbool str_is_static); //if ed is null, fld points to a global. if str_is_static, then s doesn't need its own memory allocated.
pbool (PDECL *DumpProfile) (pubprogfuncs_t *progfuncs);
};
typedef struct progexterns_s {
@ -240,7 +241,7 @@ typedef union eval_s
#ifndef DLL_PROG
#define PR_Configure(pf, memsize, max_progs) (*pf->Configure) (pf, memsize, max_progs)
#define PR_Configure(pf, memsize, max_progs, profiling) (*pf->Configure) (pf, memsize, max_progs, profiling)
#define PR_LoadProgs(pf, s, headercrc, builtins, numb) (*pf->LoadProgs) (pf, s, headercrc, builtins, numb)
#define PR_InitEnts(pf, maxents) (*pf->InitEnts) (pf, maxents)
#define PR_ExecuteProgram(pf, fnum) (*pf->ExecuteProgram) (pf, fnum)

View File

@ -350,7 +350,7 @@ typedef struct QCC_def_s
struct QCC_def_s *scope; // function the var was defined in, or NULL
struct QCC_def_s *deftail; // arrays and structs create multiple globaldef objects providing different types at the different parts of the single object (struct), or alternative names (vectors). this allows us to correctly set the const type based upon how its initialised.
struct QCC_def_s *generatedfor;
int initialized; // 1 when a declaration included "= immediate"
int initialized; // 1 when a declaration included "= immediate". 2 = extern. 3 = don't warn (unless actually called)
int constant; // 1 says we can use the value over and over again
int references;

View File

@ -4228,9 +4228,10 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou
if (!QCC_PR_CheckToken(")"))
{
rettype = QCC_TypeForName(QCC_PR_ParseName());
char *nam = QCC_PR_ParseName();
rettype = QCC_TypeForName(nam);
if (!rettype || rettype->type != ev_entity)
QCC_PR_ParseError(ERR_NOTANAME, "Spawn operator with undefined class");
QCC_PR_ParseError(ERR_NOTANAME, "Spawn operator with undefined class: %s", nam);
}
else
rettype = NULL; //default, corrected to entity later
@ -5542,22 +5543,17 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
if (assumeclass && assumeclass->parentclass)
{ //try getting a member.
QCC_type_t *type;
type = assumeclass;
while(type)
for(type = assumeclass; type && !d; type = type->parentclass)
{
//look for virtual things
sprintf(membername, "%s::"MEMBERFIELDNAME, type->name, name);
d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
if (d)
break;
}
for(type = assumeclass; type && !d; type = type->parentclass)
{
//look for non-virtual things (functions: after virtual stuff, because this will find the actual function def too)
sprintf(membername, "%s::%s", type->name, name);
d = QCC_PR_GetDef (NULL, membername, pr_scope, false, 0, false);
if (d)
break;
type = type->parentclass;
}
}
if (!d)
@ -6516,7 +6512,7 @@ QCC_def_t *QCC_StoreToRef(QCC_ref_t *dest, QCC_def_t *source, pbool readable, pb
if (dest->type == REF_FIELD)
QCC_PR_ParseWarning(WARN_STRICTTYPEMISMATCH, "type mismatch: %s to %s %s.%s", typea, typeb, dest->base->type->name, dest->index->name);
else if (dest->index)
QCC_PR_ParseWarning(WARN_STRICTTYPEMISMATCH, "type mismatch: %s to %s[]", typea, typeb, dest->base->name);
QCC_PR_ParseWarning(WARN_STRICTTYPEMISMATCH, "type mismatch: %s to %s[%s]", typea, typeb, dest->base->name, dest->index->name);
else
QCC_PR_ParseWarning(WARN_STRICTTYPEMISMATCH, "type mismatch: %s to %s %s", typea, typeb, dest->base->name);
}
@ -7002,6 +6998,12 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
{
QCC_PR_ParseError(0, "Type mismatch on assignment. %s %s %s is not supported\n", lhsr->cast->name, opname, rhsd->type->name);
}
else if(lhsr->cast->type == ev_float)
rhsd = QCC_MakeFloatConst(0);
else if(lhsr->cast->type == ev_integer)
rhsd = QCC_MakeIntConst(0);
else
rhsd = QCC_MakeIntConst(0);
}
else
rhsd = QCC_SupplyConversionForAssignment(lhsr->base, rhsd, lhsr->cast->type, true);
@ -7058,11 +7060,10 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags)
{
QCC_PR_DiscardRef(lhsr);
if (!qcc_usefulstatement)
QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Effectless statement");
QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Statement does not do anything");
qcc_usefulstatement = false;
lhsr = QCC_PR_RefExpression(retbuf, TOP_PRIORITY, exprflags);
}
return lhsr;
}
@ -7087,7 +7088,7 @@ void QCC_PR_DiscardExpression (int priority, int exprflags)
{
// int osl = pr_source_line;
// pr_source_line = statementstart;
QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Effectless statement");
QCC_PR_ParseWarning(WARN_POINTLESSSTATEMENT, "Statement does not do anything");
// pr_source_line = osl;
}
qcc_usefulstatement = olduseful;
@ -7291,7 +7292,7 @@ void QCC_PR_ParseStatement (void)
if (QCC_PR_CheckToken (";"))
{
if (pr_scope->type->aux_type->type != ev_void)
QCC_PR_ParseWarning(WARN_MISSINGRETURNVALUE, "\'%s\' should return %s", pr_scope->name, pr_scope->type->aux_type->name);
QCC_PR_ParseWarning(WARN_MISSINGRETURNVALUE, "\'%s\' returned nothing, expected %s", pr_scope->name, pr_scope->type->aux_type->name);
if (opt_return_only)
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_DONE], 0, 0, NULL));
else
@ -9831,9 +9832,6 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
QCC_def_t *def, *first=NULL;
char typebuf[1024];
if (name && !strcmp(name, "ImpulseCommands"))
QCC_PR_Note(0, strings+s_file, pr_source_line, "Defining %s", name);
#define KEYWORD(x) if (!STRCMP(name, #x) && keyword_##x) {if (keyword_##x)QCC_PR_ParseWarning(WARN_KEYWORDDISABLED, "\""#x"\" keyword used as variable name%s", keywords_coexist?" - coexisting":" - disabling");keyword_##x=keywords_coexist;}
if (name)
{
@ -10326,11 +10324,15 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
QCC_PR_Expect("{");
for (i = 0; i < arraysize; i++)
{
if (QCC_PR_CheckToken("}"))
break;
QCC_PR_ParseInitializerType(0, def, type, offset + i*type->size);
if (!QCC_PR_CheckToken(","))
{
QCC_PR_Expect("}");
break;
}
}
QCC_PR_Expect("}");
}
else
{
@ -10441,11 +10443,15 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
isunion = ((type)->type == ev_union);
for (partnum = 0; partnum < (type)->num_parms; partnum++)
{
if (QCC_PR_CheckToken("}"))
break;
QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, def, (type)->params[partnum].type, offset + (type)->params[partnum].ofs);
if (isunion || !QCC_PR_CheckToken(","))
{
QCC_PR_Expect("}");
break;
}
}
QCC_PR_Expect("}");
return;
}
else
@ -11215,7 +11221,7 @@ void QCC_PR_ParseDefs (char *classname)
gd_flags = 0;
if (isstatic)
gd_flags |= GDF_STATIC;
if (isconstant)
if (isconstant || (type->type == ev_function && !isvar))
gd_flags |= GDF_CONST;
if (!nosave)
gd_flags |= GDF_SAVED;
@ -11341,11 +11347,8 @@ void QCC_PR_ParseDefs (char *classname)
}
else
{
if (type->type == ev_function && isvar)
{
if (type->type == ev_function)
isconstant = !isvar;
def->initialized = 1;
}
if (type->type == ev_field)
{

View File

@ -647,7 +647,7 @@ pbool QCC_PR_Precompiler(void)
QCC_PR_SkipToEndOfLine(false);
QCC_PR_ParseError(ERR_HASHERROR, "#Error: %s", msg);
QCC_PR_ParseError(ERR_HASHERROR, "#Error: %s\n", msg);
}
else if (!strncmp(directive, "warning", 7))
{
@ -659,7 +659,7 @@ pbool QCC_PR_Precompiler(void)
QCC_PR_SkipToEndOfLine(false);
QCC_PR_ParseWarning(WARN_PRECOMPILERMESSAGE, "#warning: %s", msg);
QCC_PR_ParseWarning(WARN_PRECOMPILERMESSAGE, "#warning: %s\n", msg);
}
else if (!strncmp(directive, "message", 7))
{
@ -4200,6 +4200,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
while (!QCC_PR_CheckToken("}"))
{
pbool havebody = false;
pbool isnull = false;
pbool isvirt = false;
pbool isnonvirt = false;
pbool isstatic = false;
@ -4279,70 +4280,80 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
if (pr_scope)
QCC_Error(ERR_INTERNAL, "Nested function declaration");
isnull = (QCC_PR_CheckImmediate("0") || QCC_PR_CheckImmediate("0i"));
sprintf(membername, "%s::%s", classname, parmname);
def = QCC_PR_GetDef(newparm, membername, NULL, true, 0, GDF_CONST);
if (newparm->type != ev_function)
QCC_Error(ERR_INTERNAL, "Can only initialise member functions");
if (isnull)
{
def = QCC_PR_GetDef(newparm, membername, NULL, true, 0, 0);
G_FUNCTION(def->ofs) = 0;
def->initialized = 1;
}
else
{
extern unsigned int locals_end, locals_start;
extern QCC_type_t *pr_classtype;
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type);
def = QCC_PR_GetDef(newparm, membername, NULL, true, 0, GDF_CONST);
if (autoprototype)
{
QCC_PR_Expect("{");
{
int blev = 1;
//balance out the { and }
while(blev)
{
if (pr_token_type == tt_eof)
break;
if (QCC_PR_CheckToken("{"))
blev++;
else if (QCC_PR_CheckToken("}"))
blev--;
else
QCC_PR_Lex(); //ignore it.
}
}
}
if (newparm->type != ev_function)
QCC_Error(ERR_INTERNAL, "Can only initialise member functions");
else
{
pr_scope = def;
pr_classtype = newt;
f = QCC_PR_ParseImmediateStatements (newparm);
pr_classtype = NULL;
pr_scope = NULL;
G_FUNCTION(def->ofs) = numfunctions;
f->def = def;
def->initialized = 1;
extern unsigned int locals_end, locals_start;
extern QCC_type_t *pr_classtype;
QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type);
if (numfunctions >= MAX_FUNCTIONS)
QCC_Error(ERR_INTERNAL, "Too many function defs");
// fill in the dfunction
df = &functions[numfunctions];
numfunctions++;
if (f->builtin)
df->first_statement = -f->builtin;
else
df->first_statement = f->code;
if (f->builtin && opt_function_names)
optres_function_names += strlen(f->def->name);
else
df->s_name = QCC_CopyString (f->def->name);
df->s_file = s_file;
df->numparms = f->def->type->num_parms;
df->locals = locals_end - locals_start;
df->parm_start = locals_start;
for (i=0 ; i<df->numparms ; i++)
if (autoprototype)
{
df->parm_size[i] = newparm->params[i].type->size;
QCC_PR_Expect("{");
{
int blev = 1;
//balance out the { and }
while(blev)
{
if (pr_token_type == tt_eof)
break;
if (QCC_PR_CheckToken("{"))
blev++;
else if (QCC_PR_CheckToken("}"))
blev--;
else
QCC_PR_Lex(); //ignore it.
}
}
}
else
{
pr_scope = def;
pr_classtype = newt;
f = QCC_PR_ParseImmediateStatements (newparm);
pr_classtype = NULL;
pr_scope = NULL;
G_FUNCTION(def->ofs) = numfunctions;
f->def = def;
def->initialized = 1;
if (numfunctions >= MAX_FUNCTIONS)
QCC_Error(ERR_INTERNAL, "Too many function defs");
// fill in the dfunction
df = &functions[numfunctions];
numfunctions++;
if (f->builtin)
df->first_statement = -f->builtin;
else
df->first_statement = f->code;
if (f->builtin && opt_function_names)
optres_function_names += strlen(f->def->name);
else
df->s_name = QCC_CopyString (f->def->name);
df->s_file = s_file;
df->numparms = f->def->type->num_parms;
df->locals = locals_end - locals_start;
df->parm_start = locals_start;
for (i=0 ; i<df->numparms ; i++)
{
df->parm_size[i] = newparm->params[i].type->size;
}
}
}
}
@ -4471,7 +4482,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
//actually, that seems pointless.
sprintf(membername, "%s::"MEMBERFIELDNAME, classname, parmname);
// printf("define %s -> %s\n", membername, d->name);
d = QCC_PR_DummyDef(fieldtype, membername, pr_scope, 0, d->ofs, true, GDF_CONST|GDF_STRIP);
d = QCC_PR_DummyDef(fieldtype, membername, pr_scope, 0, d->ofs, true, (isnull?0:GDF_CONST)|GDF_STRIP);
d->references++; //always referenced, so you can inherit safely.
}

View File

@ -1075,7 +1075,7 @@ strofs = (strofs+3)&~3;
}
}
if (debugtarget || opt_filenames)
if (!opt_filenames)
{
statement_linenums = qccHunkAlloc(sizeof(statement_linenums) * numstatements);
for (i = 0; i < numstatements; i++)
@ -1416,7 +1416,7 @@ strofs = (strofs+3)&~3;
progs.ofsbodylessfuncs = SafeSeek (h, 0, SEEK_CUR);
progs.numbodylessfuncs = WriteBodylessFuncs(h);
if (debugtarget)
if (debugtarget && statement_linenums)
{
progs.ofslinenums = SafeSeek (h, 0, SEEK_CUR);
if (progs.blockscompressed&64)
@ -1431,6 +1431,7 @@ strofs = (strofs+3)&~3;
}
else
SafeWrite (h, statement_linenums, numstatements*sizeof(int));
statement_linenums = NULL;
}
else
progs.ofslinenums = 0;
@ -3332,9 +3333,11 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string));
sprintf (qccmprogsdat, "%s", argv[p+1]);
else
{ //look for a preprogs.src... :o)
sprintf (qccmprogsdat, "preprogs.src");
sprintf (qccmprogsdat, "%spreprogs.src", qccmsourcedir);
if (externs->FileSize(qccmprogsdat) <= 0)
sprintf (qccmprogsdat, "progs.src");
else
sprintf (qccmprogsdat, "preprogs.src");
}
numsourcefiles = 0;

View File

@ -61,7 +61,6 @@ cvar_t noexit = CVAR("noexit", "0");
cvar_t pr_ssqc_memsize = CVARD("pr_ssqc_memsize", "-1", "The ammount of memory available to the QC vm. This has a theoretical maximum of 1gb, but that value can only really be used in 64bit builds. -1 will attempt to use some conservative default, but you may need to increase it. Consider also clearing pr_fixbrokenqccarrays if you need to change this cvar.");
/*cvars purely for compat with others*/
cvar_t dpcompat_trailparticles = CVARD("dpcompat_trailparticles", "0", "Swaps the parameter order of the trailparticles builtin so that mods that target DP only can still run.");
cvar_t pr_imitatemvdsv = CVARFD("pr_imitatemvdsv", "0", CVAR_LATCH, "Enables mvdsv-specific builtins, and fakes identifiers so that mods made for mvdsv can run properly and with the full feature set.");
/*compat with frikqcc's arrays (ensures that unknown fields are at the same offsets*/
@ -1054,7 +1053,7 @@ void PR_Decompile_f(void)
if (!svprogfuncs)
{
Q_SetProgsParms(false);
PR_Configure(svprogfuncs, pr_ssqc_memsize.ival, MAX_PROGS);
PR_Configure(svprogfuncs, pr_ssqc_memsize.ival, MAX_PROGS, 0);
}
@ -1126,7 +1125,7 @@ void PR_ApplyCompilation_f (void)
s = PR_SaveEnts(svprogfuncs, NULL, &len, 0, 1);
PR_Configure(svprogfuncs, pr_ssqc_memsize.ival, MAX_PROGS);
PR_Configure(svprogfuncs, pr_ssqc_memsize.ival, MAX_PROGS, pr_enable_profiling.ival);
PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.world.max_edicts);
@ -1222,6 +1221,23 @@ void PR_WatchPoint_f(void)
Cvar_Set(Cvar_FindVar("debugger"), "1");
}
static void PR_SSProfile_f(void)
{
if (svprogfuncs && svprogfuncs->DumpProfile)
if (!svprogfuncs->DumpProfile(svprogfuncs))
Con_Printf("Please set pr_enable_profiling and restart the map first\n");
}
static void PR_SSPoke_f(void)
{
if (!SV_MayCheat())
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
else if (svprogfuncs && svprogfuncs->EvaluateDebugString)
Con_TPrintf("Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args()));
else
Con_TPrintf ("not supported.\n");
}
void PR_SSCoreDump_f(void)
{
if (!svprogfuncs)
@ -1267,6 +1283,8 @@ void PR_Init(void)
Cmd_AddCommand ("compile", PR_Compile_f);
Cmd_AddCommand ("applycompile", PR_ApplyCompilation_f);
Cmd_AddCommand ("coredump_ssqc", PR_SSCoreDump_f);
Cmd_AddCommand ("poke_ssqc", PR_SSPoke_f);
Cmd_AddCommand ("profile_ssqc", PR_SSProfile_f);
Cmd_AddCommand ("extensionlist_ssqc", PR_SVExtensionList_f);
Cmd_AddCommand ("pr_dumpplatform", PR_DumpPlatform_f);
@ -1276,7 +1294,6 @@ void PR_Init(void)
Cmd_AddCommand ("svtestprogs", QCLibTest);
#endif
*/
Cvar_Register(&dpcompat_trailparticles, "Darkplaces compatibility");
Cvar_Register(&pr_imitatemvdsv, cvargroup_progs);
Cvar_Register(&pr_fixbrokenqccarrays, cvargroup_progs);
@ -1353,7 +1370,7 @@ void Q_InitProgs(void)
// load progs to get entity field count
PR_Configure(svprogfuncs, pr_ssqc_memsize.ival, MAX_PROGS);
PR_Configure(svprogfuncs, pr_ssqc_memsize.ival, MAX_PROGS, pr_enable_profiling.ival);
PR_RegisterFields();
@ -5129,26 +5146,40 @@ void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
edict_t *ent1, *ent2;
int e1, e2;
char *s;
sizebuf_t *sz;
ent1 = G_EDICT(prinst, OFS_PARM0);
ent2 = G_EDICT(prinst, OFS_PARM1);
e1 = NUM_FOR_EDICT(prinst, ent1);
e2 = NUM_FOR_EDICT(prinst, ent2);
e1 = NUM_FOR_EDICT(prinst, ent1)-1;
e2 = NUM_FOR_EDICT(prinst, ent2)-1;
if (e1 < 1 || e1 > sv.allocated_client_slots
|| e2 < 1 || e2 > sv.allocated_client_slots)
if (e1 < 0 || e1 >= sv.allocated_client_slots
|| e2 < 0 || e2 >= sv.allocated_client_slots)
return;
#ifdef SVRANKING
if (e1 != e2) //don't get a point for suicide.
svs.clients[e1-1].kills += 1;
svs.clients[e2-1].deaths += 1;
svs.clients[e1].kills += 1;
svs.clients[e2].deaths += 1;
#endif
s = va("\\%s\\%s\\\n",svs.clients[e1-1].name, svs.clients[e2-1].name);
s = va("\\%s\\%s\\\n",svs.clients[e1].name, svs.clients[e2].name);
SZ_Print (&svs.log[svs.logsequence&1], s);
//print it to the fraglog buffer for masters/etc to query
sz = &svs.log[svs.logsequence&(FRAGLOG_BUFFERS-1)];
if (sz->cursize && sz->cursize+strlen(s)+1 >= sz->maxsize)
{
// swap buffers and bump sequence
svs.logtime = realtime;
svs.logsequence++;
sz = &svs.log[svs.logsequence&(FRAGLOG_BUFFERS-1)];
sz->cursize = 0;
Con_TPrintf ("beginning fraglog sequence %i\n", svs.logsequence);
}
SZ_Print (sz, s);
//print it to our local fraglog file.
if (sv_fraglogfile)
{
VFS_WRITE(sv_fraglogfile, s, strlen(s));
@ -7612,7 +7643,7 @@ static void QCBUILTIN PF_sv_trailparticles(pubprogfuncs_t *prinst, struct global
float *end = G_VECTOR(OFS_PARM3);
/*DP gets this wrong*/
if (dpcompat_trailparticles.ival)
if (G_INT(OFS_PARM1) >= MAX_EDICTS)
{
ednum = G_EDICTNUM(prinst, OFS_PARM0);
efnum = G_FLOAT(OFS_PARM1);
@ -9177,7 +9208,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
//DP_QC_FINDFLOAT
{"findfloat", PF_FindFloat, 0, 0, 0, 98, D("entity(entity start, .float fld, float match)", "Equivelent to the find builtin, but instead of comparing strings, this builtin compares floats. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value.\nworld is returned when there are no more entities.")}, // #98 (DP_QC_FINDFLOAT)
{"checkextension", PF_checkextension, 99, 99, 0, 99, D("float(string extname)", "Checks for an extension by its name (eg: checkextension(\"FRIK_FILE\") says that its okay to go ahead and use strcat).\nUse cvar_value(\"pr_checkextension\") to see if this builtin exists.")}, // #99 //darkplaces system - query a string to see if the mod supports X Y and Z.
{"checkextension", PF_checkextension, 99, 99, 0, 99, D("float(string extname)", "Checks for an extension by its name (eg: checkextension(\"FRIK_FILE\") says that its okay to go ahead and use strcat).\nUse cvar(\"pr_checkextension\") to see if this builtin exists.")}, // #99 //darkplaces system - query a string to see if the mod supports X Y and Z.
{"builtin_find", PF_builtinsupported,100, 100, 0, 100, D("float(string builtinname)", "Looks to see if the named builtin is valid, and returns the builtin number it exists at.")}, // #100 //per builtin system.
{"anglemod", PF_anglemod, 0, 0, 0, 102, "float(float value)"},
{"qsg_cvar_string", PF_cvar_string, 0, 0, 0, 103, D("string(string cvarname)","An old/legacy equivelent of more recent/common builtins in order to read a cvar's string value."), true},
@ -9451,7 +9482,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"memsetval", PF_memsetval, 0, 0, 0, 389, D("void(__variant *dst, float ofs, __variant val)", "Changes the 32bit value stored at the specified pointer-with-offset.")},
{"memptradd", PF_memptradd, 0, 0, 0, 390, D("__variant*(__variant *base, float ofs)", "Perform some pointer maths. Woo.")},
{"con_getset", PF_Fixme, 0, 0, 0, 391, D("string(string conname, string field, optional string newvalue)", "Reads or sets a property from a console object. The old value is returned. Iterrate through consoles with the 'next' field.")},
{"con_getset", PF_Fixme, 0, 0, 0, 391, D("string(string conname, string field, optional string newvalue)", "Reads or sets a property from a console object. The old value is returned. Iterrate through consoles with the 'next' field. Valid properties: title, name, next, unseen, markup, forceutf8, close, clear, hidden, linecount")},
{"con_printf", PF_Fixme, 0, 0, 0, 392, D("void(string conname, string messagefmt, ...)", "Prints onto a named console.")},
{"con_draw", PF_Fixme, 0, 0, 0, 393, D("void(string conname, vector pos, vector size, float fontsize)", "Draws the named console.")},
{"con_input", PF_Fixme, 0, 0, 0, 394, D("float(string conname, float inevtype, float parama, float paramb, float paramc)", "Forwards input events to the named console. Mouse updates should be absolute only.")},
@ -10124,7 +10155,7 @@ void PR_DumpPlatform_f(void)
{"ltime", ".float", QW|NQ},
{"entnum", ".float", CS, "The entity number as its known on the server."},
{"drawmask", ".float", CS, "Acts as a filter in the addentities call."},
{"predraw", ".float()", CS, "Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Return true to inhibit addition of the entity, and false for the entity to be added to the scene."},
{"predraw", ".float()", CS, "Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Should return one of the PREDRAW_* constants."},
{"lastruntime", ".float", QW},
{"movetype", ".float", QW|NQ|CS},
{"solid", ".float", QW|NQ|CS},
@ -10497,6 +10528,10 @@ void PR_DumpPlatform_f(void)
{"MF_TRACER2", "const float", QW|NQ, NULL, EF_MF_TRACER2>>24},
{"MF_TRACER3", "const float", QW|NQ, NULL, EF_MF_TRACER3>>24},
{"PFLAGS_NOSHADOW", "const float", QW|NQ|CS, "Associated RT lights attached will not cast shadows, making them significantly faster to draw.", PFLAGS_NOSHADOW},
{"PFLAGS_CORONA", "const float", QW|NQ|CS, "Enables support of coronas on the associated rtlights.", PFLAGS_CORONA},
{"PFLAGS_FULLDYNAMIC", "const float", QW|NQ, "When set in self.pflags, enables fully-customised dynamic lights. Custom rtlight information is not otherwise used.", PFLAGS_FULLDYNAMIC},
//including these for csqc stat types.
// {"EV_VOID", "const float", QW|NQ, NULL, ev_void},
{"EV_STRING", "const float", QW|NQ, NULL, ev_string},
@ -10598,6 +10633,8 @@ void PR_DumpPlatform_f(void)
{"MASK_ENGINE", "const float", CS, "Valid as an argument for addentities. If specified, all non-csqc entities will be added to the scene.", MASK_DELTA},
{"MASK_VIEWMODEL", "const float", CS, "Valid as an argument for addentities. If specified, the regular engine viewmodel will be added to the scene.", MASK_STDVIEWMODEL},
{"PREDRAW_AUTOADD", "const float", CS, "Valid as a return value from the predraw function. Returning this will cause the engine to automatically invoke addentity(self) for you.", false},
{"PREDRAW_NEXT", "const float", CS, "Valid as a return value from the predraw function. Returning this will simply move on to the next entity without the autoadd behaviour, so can be used for particle/invisible/special entites, or entities that were explicitly drawn with addentity.", true},
{"LFIELD_ORIGIN", "const float", CS, NULL, lfield_origin},
{"LFIELD_COLOUR", "const float", CS, NULL, lfield_colour},

View File

@ -6,6 +6,7 @@ extern cvar_t skill;
extern cvar_t deathmatch;
extern cvar_t coop;
extern cvar_t teamplay;
extern cvar_t pr_enable_profiling;
void SV_Savegame_f (void);
@ -259,7 +260,7 @@ void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
Q_SetProgsParms(false);
svs.numprogs = 0;
PR_Configure(svprogfuncs, -1, MAX_PROGS);
PR_Configure(svprogfuncs, -1, MAX_PROGS, pr_enable_profiling.ival);
PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.world.max_edicts); //just in case the max edicts isn't set.
progstype = pt; //presumably the progs.dat will be what they were before.
@ -678,7 +679,7 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
if (progstype != PROG_H2)
{
Q_SetProgsParms(false);
PR_Configure(svprogfuncs, -1, MAX_PROGS);
PR_Configure(svprogfuncs, -1, MAX_PROGS, pr_enable_profiling.ival);
PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.world.max_edicts);
}

View File

@ -807,8 +807,10 @@ typedef struct
// log messages are used so that fraglog processes can get stats
int logsequence; // the message currently being filled
double logtime; // time of last swap
sizebuf_t log[2];
qbyte log_buf[2][MAX_DATAGRAM];
#define FRAGLOG_BUFFERS 8
sizebuf_t log[FRAGLOG_BUFFERS];
qbyte log_buf[FRAGLOG_BUFFERS][MAX_DATAGRAM];
challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting

View File

@ -256,7 +256,7 @@ static void SV_God_f (void)
{
if (!SV_MayCheat())
{
Con_TPrintf ("You must run the server with +sv_cheats 1 to enable this command.\n");
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
return;
}
@ -276,7 +276,7 @@ static void SV_Noclip_f (void)
{
if (!SV_MayCheat())
{
Con_TPrintf ("You must run the server with +sv_cheats 1 to enable this command.\n");
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
return;
}
@ -312,7 +312,7 @@ static void SV_Give_f (void)
if (!SV_MayCheat())
{
Con_TPrintf ("You must run the server with +sv_cheats 1 to enable this command.\n");
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
return;
}

View File

@ -2584,15 +2584,11 @@ int glowsize=0, glowcolor=0, colourmod=0;
//
// write the message
//
#ifdef PARANOID
MSG_WriteByte (msg,(bits | NQU_SIGNAL) & 0xFF); //gets caught on 'range error'
#else
MSG_WriteByte (msg,bits | NQU_SIGNAL);
#endif
MSG_WriteByte (msg,(bits | NQU_SIGNAL) & 0xff); //gets caught on 'range error'
if (bits & NQU_MOREBITS) MSG_WriteByte (msg, bits>>8);
if (bits & DPU_EXTEND1) MSG_WriteByte (msg, bits>>16);
if (bits & DPU_EXTEND2) MSG_WriteByte (msg, bits>>24);
if (bits & NQU_MOREBITS) MSG_WriteByte (msg, (bits>>8)&0xff);
if (bits & DPU_EXTEND1) MSG_WriteByte (msg, (bits>>16)&0xff);
if (bits & DPU_EXTEND2) MSG_WriteByte (msg, (bits>>24)&0xff);
if (bits & NQU_LONGENTITY)
MSG_WriteShort (msg,ent->number);

View File

@ -92,7 +92,7 @@ cvar_t sv_limittics = CVARD("sv_limittics","3", "The maximum number of ticks tha
cvar_t sv_nailhack = CVARD("sv_nailhack","0", "If set to 1, disables the nail entity networking optimisation. This hack was popularised by qizmo which recommends it for better compression. Also allows clients to interplate nail positions and add trails.");
cvar_t sv_nopvs = CVARD("sv_nopvs", "0", "Set to 1 to ignore pvs on the server. This can make wallhacks more dangerous, so should only be used for debugging.");
cvar_t fraglog_public = CVARD("fraglog_public", "1", "Enables support for connectionless fraglog requests");
cvar_t timeout = SCVAR("timeout","65"); // seconds without any message
cvar_t zombietime = SCVAR("zombietime", "2"); // seconds to sink messages
@ -1258,23 +1258,22 @@ SV_CheckLog
===================
*/
#define LOG_HIGHWATER 4096
#define LOG_FLUSH 10*60
void SV_CheckLog (void)
{
sizebuf_t *sz;
sz = &svs.log[svs.logsequence&1];
sz = &svs.log[svs.logsequence&(FRAGLOG_BUFFERS-1)];
// bump sequence if allmost full, or ten minutes have passed and
// bump sequence ten minutes have passed and
// there is something still sitting there
if (sz->cursize > LOG_HIGHWATER
|| (realtime - svs.logtime > LOG_FLUSH && sz->cursize) )
//logfrag does the rotation for a full log.
if (realtime - svs.logtime > LOG_FLUSH && sz->cursize)
{
// swap buffers and bump sequence
svs.logtime = realtime;
svs.logsequence++;
sz = &svs.log[svs.logsequence&1];
sz = &svs.log[svs.logsequence&(FRAGLOG_BUFFERS-1)];
sz->cursize = 0;
Con_TPrintf ("beginning fraglog sequence %i\n", svs.logsequence);
}
@ -1293,27 +1292,41 @@ instead of the data.
*/
void SVC_Log (void)
{
int seq;
unsigned int seq;
char data[MAX_DATAGRAM+64];
char adr[MAX_ADR_SIZE];
if (Cmd_Argc() == 2)
seq = atoi(Cmd_Argv(1));
else
seq = -1;
{
seq = strtoul(Cmd_Argv(1), NULL, 0);
//seq is the last one that the client already has
if (seq == svs.logsequence-1 || !sv_fraglogfile)
{ // they already have this data, or we aren't logging frags
if (seq < svs.logsequence-(FRAGLOG_BUFFERS-1))
seq = svs.logsequence-(FRAGLOG_BUFFERS-1); //send them this sequence
else if (seq == svs.logsequence)
{ //current log isn't available as its not complete yet.
data[0] = A2A_NACK;
NET_SendPacket (NS_SERVER, 1, data, &net_from);
return;
}
else if (seq > svs.logsequence) //future logs are not valid either. reply with the last that was. this is for compat, just in case.
seq = svs.logsequence-1;
else
seq = seq+1; //they will get the next sequence from the one they already have
}
else
seq = 0;
if (!fraglog_public.ival)
{ //frag logs are not public (for DoS protection perhaps?.
data[0] = A2A_NACK;
NET_SendPacket (NS_SERVER, 1, data, &net_from);
return;
}
Con_DPrintf ("sending log %i to %s\n", svs.logsequence-1, NET_AdrToString(adr, sizeof(adr), &net_from));
sprintf (data, "stdlog %i\n", svs.logsequence-1);
strcat (data, (char *)svs.log_buf[((svs.logsequence-1)&1)]);
Con_DPrintf ("sending log %i to %s\n", seq, NET_AdrToString(adr, sizeof(adr), &net_from));
Q_snprintfz(data, sizeof(data), "stdlog %i\n%s", seq, (char *)svs.log_buf[seq&(FRAGLOG_BUFFERS-1)]);
NET_SendPacket (NS_SERVER, strlen(data)+1, data, &net_from);
}
@ -5192,6 +5205,7 @@ void SV_InitLocal (void)
Cvar_Register (&sv_listen_dp, cvargroup_servercontrol);
Cvar_Register (&sv_listen_q3, cvargroup_servercontrol);
sv_listen_qw.restriction = RESTRICT_MAX;
Cvar_Register (&fraglog_public, cvargroup_servercontrol);
SVNET_RegisterCvars();

View File

@ -108,6 +108,8 @@ avplug/libavformat/avformat.h:
distclean:
rm avplug/libavformat/avformat.h
-include Makefile.private
$(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT): avplug/avencode.c avplug/avdecode.c plugin.c qvm_api.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -s -o $(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Iavplug/msvc_lib $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -lavcodec -lavformat -lavutil -lswscale
#native: $(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT)

View File

@ -2881,6 +2881,24 @@ void JCL_ParseMessage(jclient_t *jcl, xmltree_t *tree)
}
}
if (!strcmp(type, "error"))
{
ot = XML_ChildOfTree(tree, "body", 0);
if (ot)
{
unparsable = false;
if (f)
{
if (!strncmp(ot->body, "/me ", 4))
Con_SubPrintf(ctx, "* ^2%s^7%s\n", f, ot->body+3);
else
Con_SubPrintf(ctx, "^2%s^7: %s\n", f, ot->body);
}
}
else
Con_SubPrintf(ctx, "error sending message: %s\r", f);
}
if (f)
{
ot = XML_ChildOfTree(tree, "composing", 0);