Lets try using _LARGEFILE64_SOURCE in 32bit linux builds. Not that anyone will notice.

Clarify the 'too many alternate clients' messages.
Gamepad movement should respond to +speed.
favour fte's nq protocols over dp ones when both are supported by the client, to boost compat with qss.
try to generate proper utf-8 filenames from player/team names when recording mvds, instead of bad char encodings.
Fix loading saved games with splitscreen enabled.
pr_dumpplatform can now optionally filter symbols via some specific external files, adding deprecated tags for any symbol not also supported by DP and QSS.
Rework CSQC globals to use macros, to ensure completeness and consistency.
rework sv_csqcdebug to use special svcs. This should make it more robust.
Fix some scary warnings when vid_reloading the vulkan renderer.
Fix a possible segfault from opengl+rtlights.
Mousewheel will now interact better with engine menus.



git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5757 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2020-09-08 05:11:09 +00:00
parent a5371f0027
commit b380421e42
43 changed files with 1913 additions and 1278 deletions

View File

@ -1474,6 +1474,11 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
CL_CFLAGS=-DMULTITHREAD -DDYNAMIC_SDL $(HAVE_EGL) $(HAVE_WAYLAND) -DX11QUAKE -DAUDIO_PULSE -DAUDIO_ALSA -DAUDIO_OSS -DAUDIO_SDL
BASELDFLAGS+=-Wl,--warn-common
ifeq ($(BITS),32)
CL_CFLAGS+=-D_LARGEFILE64_SOURCE
SV_CFLAGS+=-D_LARGEFILE64_SOURCE
endif
QCC_DIR=linqcc$(BITS)
NPFTE_OBJS=httpclient.o image.o sys_linux_threads.o sys_npfte.o sys_axfte.o sys_plugfte.o

View File

@ -35,12 +35,12 @@ static cvar_t cl_movement = CVARD("cl_movement","1", "Specifies whether to send
cvar_t cl_nodelta = CVAR("cl_nodelta","0");
cvar_t cl_c2sdupe = CVAR("cl_c2sdupe", "0");
cvar_t cl_c2spps = CVAR("cl_c2spps", "0");
cvar_t cl_c2sImpulseBackup = CVAR("cl_c2sImpulseBackup","3");
cvar_t cl_netfps = CVAR("cl_netfps", "150");
cvar_t cl_sparemsec = CVARC("cl_sparemsec", "10", CL_SpareMsec_Callback);
cvar_t cl_queueimpulses = CVAR("cl_queueimpulses", "0");
cvar_t cl_smartjump = CVAR("cl_smartjump", "1");
cvar_t cl_c2spps = CVARD("cl_c2spps", "0", "Reduces outgoing packet rates by dropping up to a third of outgoing packets.");
cvar_t cl_c2sImpulseBackup = CVARD("cl_c2sImpulseBackup","3", "Prevents the cl_c2spps setting from dropping redundant packets that contain impulses, in an attempt to keep impulses more reliable.");
cvar_t cl_netfps = CVARD("cl_netfps", "150", "Send up to this many packets to the server per second. The rate used is also limited by the server which usually forces a cap to this setting of 77. Low packet rates can result in extra extrapolation to try to hide the resulting latencies.");
cvar_t cl_sparemsec = CVARCD("cl_sparemsec", "10", CL_SpareMsec_Callback, "Allows the 'banking' of a little extra time, so that one slow frame will not delay the timing of the following frame so much.");
cvar_t cl_queueimpulses = CVARD("cl_queueimpulses", "0", "Queues unsent impulses instead of replacing them. This avoids the need for extra wait commands (and the timing issues of such commands), but potentially increases latency and can cause scripts to be desynced with regard to buttons and impulses.");
cvar_t cl_smartjump = CVARD("cl_smartjump", "1", "Makes the jump button act as +moveup when in water. This is typically quieter and faster.");
cvar_t cl_iDrive = CVARFD("cl_iDrive", "1", CVAR_SEMICHEAT, "Effectively releases movement keys when the opposing key is pressed. This avoids dead-time when both keys are pressed. This can be emulated with various scripts, but that's messy.");
cvar_t cl_run = CVARD("cl_run", "0", "Enables autorun, inverting the state of the +speed key.");
cvar_t cl_fastaccel = CVARD("cl_fastaccel", "1", "Begin moving at full speed instantly, instead of waiting a frame or so.");

View File

@ -5064,7 +5064,7 @@ void CL_Init (void)
Cmd_AddCommandD ("fog", CL_Fog_f, "fog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("skyroomfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("skyroomfog", CL_Fog_f, "skyroomfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("skygroup", CL_Skygroup_f, "Provides a way to associate a skybox name with a series of maps, so that the requested skybox will override on a per-map basis.");
//
// Windows commands

View File

@ -165,10 +165,10 @@ static const char *svc_qwstrings[] =
"svcfte_updateentities",
"svcfte_brushedit",
"svcfte_updateseats",
"svcfte_setinfoblob", //89
"NEW PROTOCOL(90)",
"NEW PROTOCOL(91)",
"NEW PROTOCOL(92)",
"svcfte_setinfoblob", //89
"svcfte_cgamepacket_sized", //90
"svcfte_temp_entity_sized", //91
"svcfte_csqcentities_sized", //92
"NEW PROTOCOL(93)",
"NEW PROTOCOL(94)",
"NEW PROTOCOL(95)",
@ -287,7 +287,10 @@ static const char *svc_nqstrings[] =
"nqsvcfte_updateentities", //86
"NEW PROTOCOL(87)", //87
"NEW PROTOCOL(88)", //88
"svcfte_setinfoblob"//89
"svcfte_setinfoblob", //89
"svcfte_cgamepacket_sized", //90
"svcfte_temp_entity_sized", //91
"svcfte_csqcentities_sized", //92
};
#endif
@ -3356,8 +3359,8 @@ static void CLQW_ParseServerData (void)
cl.allocated_client_slots = MSG_ReadByte();
if (cl.allocated_client_slots > MAX_CLIENTS)
{
Con_Printf(CON_ERROR"Server has too many client slots (%u > %u)\n", cl.allocated_client_slots, MAX_CLIENTS);
cl.allocated_client_slots = MAX_CLIENTS;
Host_EndGame("Server sent us too many alternate clients\n");
}
/*parsing here is slightly different to allow us 255 max players instead of 127*/
@ -3368,7 +3371,7 @@ static void CLQW_ParseServerData (void)
cl.splitclients &= ~128;
}
if (cl.splitclients > MAX_SPLITS)
Host_EndGame("Server sent us too many alternate clients\n");
Host_EndGame("Server sent us too many seats (%u > %u)\n", cl.splitclients, MAX_SPLITS);
for (pnum = 0; pnum < cl.splitclients; pnum++)
{
cl.playerview[pnum].spectator = true;
@ -3387,7 +3390,7 @@ static void CLQW_ParseServerData (void)
for (clnum = 0; ; clnum++)
{
if (clnum == MAX_SPLITS)
Host_EndGame("Server sent us too many alternate clients\n");
Host_EndGame("Server sent us over %u seats\n", MAX_SPLITS);
if (cls.z_ext & Z_EXT_VIEWHEIGHT)
cl.playerview[pnum].viewheight = 0;
cl.playerview[clnum].playernum = pnum;
@ -6871,7 +6874,7 @@ void CLQW_ParseServerMessage (void)
int destsplit;
vec3_t ang;
float f;
qboolean csqcpacket = false;
qboolean suggestcsqcdebug = false;
inframe_t *inf;
extern vec3_t demoangles;
unsigned int cmdstart;
@ -6971,7 +6974,7 @@ void CLQW_ParseServerMessage (void)
{
default:
CL_DumpPacket();
Host_EndGame ("CLQW_ParseServerMessage: Illegible server message (%i@%i)%s", cmd, msg_readcount-1, (!cl.csqcdebug && csqcpacket)?"\n'sv_csqcdebug 1' might aid in debugging this.":"" );
Host_EndGame ("CLQW_ParseServerMessage: Illegible server message (%i@%i)%s", cmd, msg_readcount-1, (!cl.csqcdebug && suggestcsqcdebug)?"\n'sv_csqcdebug 1' might aid in debugging this.":"" );
return;
case svc_time:
@ -7210,6 +7213,9 @@ void CLQW_ParseServerMessage (void)
CL_ParseTEnt ();
#endif
break;
case svcfte_temp_entity_sized:
CL_ParseTEnt_Sized();
break;
case svcfte_customtempent:
CL_ParseCustomTEnt();
break;
@ -7423,8 +7429,11 @@ void CLQW_ParseServerMessage (void)
#ifdef CSQC_DAT
case svcfte_csqcentities:
csqcpacket = true;
CSQC_ParseEntities();
suggestcsqcdebug = true;
CSQC_ParseEntities(cl.csqcdebug);
break;
case svcfte_csqcentities_sized:
CSQC_ParseEntities(true);
break;
#endif
case svcfte_precache:
@ -7441,14 +7450,21 @@ void CLQW_ParseServerMessage (void)
CL_ParsePointParticles(true);
break;
case svcfte_cgamepacket_sized:
#ifdef CSQC_DAT
if (CSQC_ParseGamePacket(destsplit, true))
break;
#endif
Con_Printf("Unable to parse gamecode packet\n");
break;
case svcfte_cgamepacket:
csqcpacket = true;
suggestcsqcdebug = true;
#ifdef HLCLIENT
if (CLHL_ParseGamePacket())
break;
#endif
#ifdef CSQC_DAT
if (CSQC_ParseGamePacket(destsplit))
if (CSQC_ParseGamePacket(destsplit, cl.csqcdebug))
break;
#endif
Con_Printf("Unable to parse gamecode packet\n");
@ -8089,13 +8105,20 @@ void CLNQ_ParseServerMessage (void)
CL_ParseBaselineDelta ();
break;
case svcfte_cgamepacket_sized:
#ifdef CSQC_DAT
if (CSQC_ParseGamePacket(destsplit, true))
break;
#endif
Con_Printf("Unable to parse gamecode packet\n");
break;
case svcfte_cgamepacket:
#ifdef HLCLIENT
if (CLHL_ParseGamePacket())
break;
#endif
#ifdef CSQC_DAT
if (CSQC_ParseGamePacket(destsplit))
if (CSQC_ParseGamePacket(destsplit, cl.csqcdebug))
break;
#endif
Con_Printf("Unable to parse gamecode packet\n");
@ -8332,6 +8355,9 @@ void CLNQ_ParseServerMessage (void)
case svc_temp_entity:
CL_ParseTEnt (true);
break;
case svcfte_temp_entity_sized:
CL_ParseTEnt_Sized();
break;
case svc_particle:
CLNQ_ParseParticleEffect ();
@ -8445,7 +8471,10 @@ void CLNQ_ParseServerMessage (void)
#ifdef CSQC_DAT
case svcdp_csqcentities:
CSQC_ParseEntities();
CSQC_ParseEntities(false);
break;
case svcfte_csqcentities_sized:
CSQC_ParseEntities(true);
break;
#endif

View File

@ -1131,19 +1131,29 @@ void CL_ParseTEnt (void)
if (cl_shownet.ival >= 2)
{
static char *te_names[] = {
"spike", "superspike", "qwgunshot", "qwexplosion",
"tarexplosion", "lightning1", "lightning2", "wizspike",
"knightspike", "lightning3", "lavasplash", "teleport",
"blood", "lightningblood", "bullet", "superbullet", //bullets deprecated
"neh_explosion3", "railtrail/neh_lightning4", "beam", "explosion2",
"nqexplosion", "nqgunshot", "?", "?",
#ifdef HEXEN2
"h2lightsml", "h2chain", "h2sunstf1", "h2sunstf2",
"h2light", "h2cb", "h2ic", "h2gaze",
"h2famine", "h2partexp"
#endif
/* 0*/"spike", "superspike", "qwgunshot", "qwexplosion",
/* 4*/"tarexplosion", "lightning1", "lightning2", "wizspike",
/* 8*/"knightspike", "lightning3", "lavasplash", "teleport",
/*12*/"blood", "lightningblood", "bullet", "superbullet", //bullets deprecated
/*16*/"neh_explosion3", "railtrail", "beam", "explosion2",
/*20*/"nqexplosion", "nqgunshot", NULL, NULL,
/*24*/"h2lightsml", "h2chain", "h2sunstf1", "h2sunstf2",
/*28*/"h2light", "h2cb", "h2ic", "h2gaze",
/*32*/"h2famine", "h2partexp",NULL,NULL,
/*36*/NULL,NULL,NULL,NULL,
/*40*/NULL,NULL,NULL,NULL,
/*44*/NULL,NULL,NULL,NULL,
/*48*/NULL,NULL,"dpblood","dpspark"
/*52*/"dpbloodshower","dpexplosionrgb","dpparticlecube","dpparticlerain",
/*56*/"dpparticlesnow","dpgunshotquad","dpspikequad","dpsuperspikequad",
/*60*/NULL,NULL,NULL,NULL,
/*64*/NULL,NULL,NULL,NULL,
/*68*/NULL,NULL,"dpexplosionquad",NULL,
/*72*/"dpsmallflash","dpcustomflash","dpflamejet","dpplasmaburn",
/*76*/"dpteig3","dpsmoke","dpteibigexplosion","dpteiplasmahit",
/*80*/
};
if (type < countof(te_names))
if (type < countof(te_names) && te_names[type])
Con_Printf(" te_%s\n", te_names[type]);
else
Con_Printf(" te_unknown_%i\n", type);
@ -1891,6 +1901,47 @@ void CL_ParseTEnt (void)
}
}
void CL_ParseTEnt_Sized (void)
{
unsigned short sz = MSG_ReadShort();
int start = msg_readcount;
for(;;)
{
#ifdef NQPROT
if (sz&0x8000)
{
sz&=~0x8000;
CL_ParseTEnt(true);
}
else
CL_ParseTEnt(false);
#else
CL_ParseTEnt();
#endif
if (msg_readcount < start + sz)
{ //try to be more compatible with xonotic.
int next = MSG_ReadByte();
if (next == svc_temp_entity)
continue;
msg_readcount--;
Con_Printf("Sized temp_entity data too large (next byte %i, %i bytes unread)\n", next, (start+sz)-msg_readcount);
msg_readcount = start + sz;
return;
}
break;
}
if (msg_readcount != start + sz)
{
Con_Printf("Tempentity size did not match parsed size misread a gamecode packet (%i bytes too much)\n", msg_readcount - (start+sz));
msg_readcount = start + sz;
}
}
void MSG_ReadPos (vec3_t pos);
void MSG_ReadDir (vec3_t dir);
typedef struct {

View File

@ -786,7 +786,7 @@ typedef struct
int protocol_qw;
float gamespeed;
qboolean csqcdebug;
qboolean csqcdebug; //redundant, remove '*csqcdebug' serverinfo key.
qboolean allowsendpacket;
qboolean stillloading; // set when doing something slow, and the game is still loading.
@ -1216,6 +1216,7 @@ void CL_ParseTEnt (qboolean nqprot);
#else
void CL_ParseTEnt (void);
#endif
void CL_ParseTEnt_Sized (void);
void CL_UpdateTEnts (void);
enum beamtype_e
@ -1472,7 +1473,7 @@ qboolean CSQC_StuffCmd(int lplayernum, char *cmd, char *cmdend);
void CSQC_MapEntityEdited(int modelindex, int idx, const char *newe);
//qboolean CSQC_LoadResource(char *resname, char *restype);
qboolean CSQC_ParsePrint(char *message, int printlevel);
qboolean CSQC_ParseGamePacket(int seat);
qboolean CSQC_ParseGamePacket(int seat, qboolean sized);
qboolean CSQC_CenterPrint(int seat, const char *cmd);
void CSQC_ServerInfoChanged(void);
void CSQC_PlayerInfoChanged(int player);
@ -1489,7 +1490,7 @@ qboolean CSQC_JoystickAxis(int axis, float value, unsigned int devid);
qboolean CSQC_Accelerometer(float x, float y, float z);
qboolean CSQC_Gyroscope(float x, float y, float z);
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation, float pitchmod, float timeofs, unsigned int flags);
void CSQC_ParseEntities(void);
void CSQC_ParseEntities(qboolean sized);
const char *CSQC_GetExtraFieldInfo(void *went, char *out, size_t outsize);
void CSQC_ResetTrails(void);

View File

@ -2636,6 +2636,322 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, float displayscrol
void Draw_ExpandedString(float x, float y, conchar_t *str);
static void Con_DrawModelPreview(model_t *model, float x, float y, float w, float h)
{
playerview_t pv;
entity_t ent;
vec3_t fwd, rgt, up;
vec3_t lightpos = {1, 1, 0};
float transforms[12];
float scale;
if (R2D_Flush)
R2D_Flush();
memset(&pv, 0, sizeof(pv));
CL_DecayLights ();
CL_ClearEntityLists();
V_ClearRefdef(&pv);
r_refdef.drawsbar = false;
V_CalcRefdef(&pv);
r_refdef.grect.width = w;
r_refdef.grect.height = h;
r_refdef.grect.x = x;
r_refdef.grect.y = y;
r_refdef.time = realtime;
r_refdef.flags = RDF_NOWORLDMODEL;
r_refdef.afov = 60;
r_refdef.fov_x = 0;
r_refdef.fov_y = 0;
r_refdef.dirty |= RDFD_FOV;
VectorClear(r_refdef.viewangles);
r_refdef.viewangles[0] = 20;
// r_refdef.viewangles[1] = realtime * 90;
AngleVectors(r_refdef.viewangles, fwd, rgt, up);
VectorScale(fwd, -64, r_refdef.vieworg);
memset(&ent, 0, sizeof(ent));
ent.model = model;
ent.scale = 1;
ent.angles[1] = realtime*90;//mods->yaw;
// ent.angles[0] = realtime*23.4;//mods->pitch;
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorInverse(ent.axis[1]);
//ent.origin[2] -= (ent.model->maxs[2]-ent.model->mins[2]) * 0.5 + ent.model->mins[2];
ent.scale = 1;
scale = max(max(fabs(ent.model->maxs[0]-ent.model->mins[0]), fabs(ent.model->maxs[1]-ent.model->mins[1])), fabs(ent.model->maxs[2]-ent.model->mins[2]));
scale = scale?64.0/scale:1;
ent.origin[2] -= (ent.model->maxs[2]-ent.model->mins[2]) * 0.5 + ent.model->mins[2];
Vector4Set(ent.shaderRGBAf, 1, 1, 1, 1);
VectorScale(ent.axis[0], scale, ent.axis[0]);
VectorScale(ent.axis[1], scale, ent.axis[1]);
VectorScale(ent.axis[2], scale, ent.axis[2]);
/*if (strstr(model->name, "player"))
{
ent.bottomcolour = genhsv(realtime*0.1 + 0, 1, 1);
ent.topcolour = genhsv(realtime*0.1 + 0.5, 1, 1);
}
else*/
{
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
}
// ent.fatness = sin(realtime)*5;
ent.playerindex = -1;
ent.skinnum = 0;
ent.shaderTime = 0;//realtime;
ent.framestate.g[FS_REG].lerpweight[0] = 1;
// ent.framestate.g[FS_REG].frame[0] = animationnum;
ent.framestate.g[FS_REG].frametime[0] = ent.framestate.g[FS_REG].frametime[1] = realtime;
ent.framestate.g[FS_REG].endbone = 0x7fffffff;
// ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
Vector4Set(ent.shaderRGBAf, 1,1,1,1);
VectorSet(ent.glowmod, 1,1,1);
ent.light_avg[0] = ent.light_avg[1] = ent.light_avg[2] = 0.66;
ent.light_range[0] = ent.light_range[1] = ent.light_range[2] = 0.33;
V_ApplyRefdef();
if (ent.model->camerabone>0 && Mod_GetTag(ent.model, ent.model->camerabone, &ent.framestate, transforms))
{
VectorClear(ent.origin);
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorInverse(ent.axis[1]);
scale = 1;
{
vec3_t fwd, up;
float camera[12], et[12] = {
ent.axis[0][0], ent.axis[1][0], ent.axis[2][0], ent.origin[0],
ent.axis[0][1], ent.axis[1][1], ent.axis[2][1], ent.origin[1],
ent.axis[0][2], ent.axis[1][2], ent.axis[2][2], ent.origin[2],
};
R_ConcatTransforms((void*)et, (void*)transforms, (void*)camera);
VectorSet(fwd, camera[2], camera[6], camera[10]);
VectorNegate(fwd, fwd);
VectorSet(up, camera[1], camera[5], camera[9]);
VectorSet(r_refdef.vieworg, camera[3], camera[7], camera[11]);
VectorAngles(fwd, up, r_refdef.viewangles, false);
}
}
else
{
ent.angles[1] = realtime*90;//mods->yaw;
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorScale(ent.axis[0], scale, ent.axis[0]);
VectorScale(ent.axis[1], -scale, ent.axis[1]);
VectorScale(ent.axis[2], scale, ent.axis[2]);
}
ent.scale = scale;
VectorNormalize(lightpos);
ent.light_dir[0] = DotProduct(lightpos, ent.axis[0]);
ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]);
ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]);
ent.light_known = 2;
V_AddEntity(&ent);
R_RenderView();
}
static void Con_DrawMouseOver(console_t *mouseconsole)
{
char *tiptext = NULL;
shader_t *shader = NULL;
model_t *model = NULL;
char *mouseover;
if (!mouseconsole->mouseover || !mouseconsole->mouseover(mouseconsole, &tiptext, &shader))
{
mouseover = Con_CopyConsole(mouseconsole, false, true, true);
if (mouseover)
{
char *end = strstr(mouseover, "^]");
char *info = strchr(mouseover, '\\');
if (!info)
info = "";
if (end)
*end = 0;
#ifdef PLUGINS
if (!Plug_ConsoleLinkMouseOver(mousecursor_x, mousecursor_y, mouseover+2, info))
#endif
{
char *key;
key = Info_ValueForKey(info, "tipimg");
if (*key)
{
char *fl = Info_ValueForKey(info, "tipimgtype");
if (*fl)
shader = R_RegisterCustom(key, atoi(fl), NULL, NULL);
else
shader = R2D_SafeCachePic(key);
}
else
{
image_t *img = NULL;
key = Info_ValueForKey(info, "tiprawimg");
if (*key)
{
img = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA|IF_TEXTYPE_ANY);
if (!img)
img = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_TEXTYPE_ANY);
if (!img)
{
size_t fsize;
char *buf;
img = Image_CreateTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA|IF_TEXTYPE_ANY);
if ((buf = FS_LoadMallocFile (key, &fsize)))
Image_LoadTextureFromMemory(img, img->flags|IF_NOWORKER, key, key, buf, fsize);
}
}
key = Info_ValueForKey(info, "tipimgptr");
if (*key)
img = Image_TextureIsValid(strtoull(key, NULL, 0));
if (img && img->status == TEX_LOADED)
{
if ((img->flags & IF_TEXTYPEMASK)==IF_TEXTYPE_CUBE)
{
shader = R_RegisterShader("tiprawimgcube", 0, "{\nprogram postproc_equirectangular\n{\nmap \"$cube:$reflectcube\"\n}\n}");
shader->defaulttextures->reflectcube = img;
}
else if ((img->flags&IF_TEXTYPEMASK) == IF_TEXTYPE_2D)
{
shader = R2D_SafeCachePic("tiprawimg");
shader->defaulttextures->base = img;
}
if (shader)
{
shader->width = img->width;
shader->height = img->height;
if (shader->width > 320)
{
shader->height *= 320.0/shader->width;
shader->width = 320;
}
if (shader->height > 240)
{
shader->width *= 240.0/shader->height;
shader->height = 240;
}
}
}
else
shader = NULL;
key = Info_ValueForKey(info, "modelviewer");
if (*key)
{
model = Mod_ForName(key, MLV_WARN);
if (model->loadstate != MLS_LOADED)
model = NULL;
}
}
tiptext = Info_ValueForKey(info, "tip");
}
Z_Free(mouseover);
}
}
if ((tiptext && *tiptext) || shader || model)
{
//FIXME: draw a proper background.
//FIXME: support line breaks.
conchar_t buffer[2048], *starts[64], *ends[countof(starts)];
int lines, i, px, py;
float tw, th;
float ih = 0, iw = 0;
float x = mousecursor_x+8;
float y = mousecursor_y+8;
Font_BeginString(font_console, x, y, &px, &py);
lines = Font_LineBreaks(buffer, COM_ParseFunString(CON_WHITEMASK, tiptext, buffer, sizeof(buffer), false), (256.0 * vid.pixelwidth) / vid.width, countof(starts), starts, ends);
th = (Font_CharHeight()*lines * vid.height) / vid.pixelheight;
if (model)
{
iw = 128;
ih = 128;
}
else if (shader)
{
int w, h;
if (R_GetShaderSizes(shader, &w, &h, false) >= 0)
{
iw = w;
ih = h;
}
else
shader = NULL;
}
if (iw > (vid.width/4.0))
{
ih *= (vid.width/4.0)/iw;
iw *= (vid.width/4.0)/iw;
}
if (ih > (vid.height/4.0))
{
iw *= (vid.width/4.0)/ih;
ih *= (vid.width/4.0)/ih;
}
if (x + iw/2 + 8 + 256 > vid.width)
x = vid.width - (iw/2 + 8 + 256);
if (x < iw/2)
x = iw/2;
x += iw/2 + 8;
if (y+max(th, ih) > vid.height)
y = mousecursor_y - 8 - max(th, ih);
if (y < 0)
y = 0;
Font_BeginString(font_console, x, y + (max(th, ih) - th)/2, &px, &py);
for (i = 0, tw = 0; i < lines; i++)
{
int lw = Font_LineWidth(starts[i], ends[i]);
if (lw > tw)
tw = lw;
}
tw *= (float)vid.width / vid.pixelwidth;
Font_EndString(font_console);
R2D_ImageColours(0, 0, 0, .75);
R2D_FillBlock(x, y + (max(th, ih) - th)/2, tw, th);
R2D_ImageColours(1, 1, 1, 1);
Font_BeginString(font_console, x, y + (max(th, ih) - th)/2, &px, &py);
for (i = 0; i < lines; i++)
{
Font_LineDraw(px, py, starts[i], ends[i]);
py += Font_CharHeight();
}
Font_EndString(font_console);
if (model)
Con_DrawModelPreview(model, x-8-iw, y+((th>ih)?(th-ih)/2:0), iw, ih);
if (shader)
{
if (th > ih)
y += (th-ih)/2;
R2D_Image(x-8-iw, y, iw, ih, 0, 0, 1, 1, shader);
}
}
}
/*
================
Con_DrawConsole
@ -2923,318 +3239,7 @@ void Con_DrawConsole (int lines, qboolean noback)
mouseconsole = con_mouseover?con_mouseover:NULL;
if (mouseconsole && mouseconsole->selstartline)
{
char *tiptext = NULL;
shader_t *shader = NULL;
model_t *model = NULL;
char *mouseover;
if (!mouseconsole->mouseover || !mouseconsole->mouseover(mouseconsole, &tiptext, &shader))
{
mouseover = Con_CopyConsole(mouseconsole, false, true, true);
if (mouseover)
{
char *end = strstr(mouseover, "^]");
char *info = strchr(mouseover, '\\');
if (!info)
info = "";
if (end)
*end = 0;
#ifdef PLUGINS
if (!Plug_ConsoleLinkMouseOver(mousecursor_x, mousecursor_y, mouseover+2, info))
#endif
{
char *key;
key = Info_ValueForKey(info, "tipimg");
if (*key)
{
char *fl = Info_ValueForKey(info, "tipimgtype");
if (*fl)
shader = R_RegisterCustom(key, atoi(fl), NULL, NULL);
else
shader = R2D_SafeCachePic(key);
}
else
{
image_t *img = NULL;
key = Info_ValueForKey(info, "tiprawimg");
if (*key)
{
img = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA|IF_TEXTYPE_ANY);
if (!img)
img = Image_FindTexture(key, NULL, IF_NOREPLACE|IF_TEXTYPE_ANY);
if (!img)
{
size_t fsize;
char *buf;
img = Image_CreateTexture(key, NULL, IF_NOREPLACE|IF_PREMULTIPLYALPHA|IF_TEXTYPE_ANY);
if ((buf = FS_LoadMallocFile (key, &fsize)))
Image_LoadTextureFromMemory(img, img->flags|IF_NOWORKER, key, key, buf, fsize);
}
}
key = Info_ValueForKey(info, "tipimgptr");
if (*key)
img = Image_TextureIsValid(strtoull(key, NULL, 0));
if (img && img->status == TEX_LOADED)
{
if ((img->flags & IF_TEXTYPEMASK)==IF_TEXTYPE_CUBE)
{
shader = R_RegisterShader("tiprawimgcube", 0, "{\nprogram postproc_equirectangular\n{\nmap \"$cube:$reflectcube\"\n}\n}");
shader->defaulttextures->reflectcube = img;
}
else if ((img->flags&IF_TEXTYPEMASK) == IF_TEXTYPE_2D)
{
shader = R2D_SafeCachePic("tiprawimg");
shader->defaulttextures->base = img;
}
if (shader)
{
shader->width = img->width;
shader->height = img->height;
if (shader->width > 320)
{
shader->height *= 320.0/shader->width;
shader->width = 320;
}
if (shader->height > 240)
{
shader->width *= 240.0/shader->height;
shader->height = 240;
}
}
}
else
shader = NULL;
key = Info_ValueForKey(info, "modelviewer");
if (*key)
{
model = Mod_ForName(key, MLV_WARN);
if (model->loadstate != MLS_LOADED)
model = NULL;
}
}
tiptext = Info_ValueForKey(info, "tip");
}
Z_Free(mouseover);
}
}
if ((tiptext && *tiptext) || shader || model)
{
//FIXME: draw a proper background.
//FIXME: support line breaks.
conchar_t buffer[2048], *starts[64], *ends[countof(starts)];
int lines, i, px, py;
float tw, th;
float ih = 0, iw = 0;
float x = mousecursor_x+8;
float y = mousecursor_y+8;
Font_BeginString(font_console, x, y, &px, &py);
lines = Font_LineBreaks(buffer, COM_ParseFunString(CON_WHITEMASK, tiptext, buffer, sizeof(buffer), false), (256.0 * vid.pixelwidth) / vid.width, countof(starts), starts, ends);
th = (Font_CharHeight()*lines * vid.height) / vid.pixelheight;
if (model)
{
iw = 128;
ih = 128;
}
else if (shader)
{
int w, h;
if (R_GetShaderSizes(shader, &w, &h, false) >= 0)
{
iw = w;
ih = h;
}
else
shader = NULL;
}
if (iw > (vid.width/4.0))
{
ih *= (vid.width/4.0)/iw;
iw *= (vid.width/4.0)/iw;
}
if (ih > (vid.height/4.0))
{
iw *= (vid.width/4.0)/ih;
ih *= (vid.width/4.0)/ih;
}
if (x + iw/2 + 8 + 256 > vid.width)
x = vid.width - (iw/2 + 8 + 256);
if (x < iw/2)
x = iw/2;
x += iw/2 + 8;
if (y+max(th, ih) > vid.height)
y = mousecursor_y - 8 - max(th, ih);
if (y < 0)
y = 0;
Font_BeginString(font_console, x, y + (max(th, ih) - th)/2, &px, &py);
for (i = 0, tw = 0; i < lines; i++)
{
int lw = Font_LineWidth(starts[i], ends[i]);
if (lw > tw)
tw = lw;
}
tw *= (float)vid.width / vid.pixelwidth;
Font_EndString(font_console);
R2D_ImageColours(0, 0, 0, .75);
R2D_FillBlock(x, y + (max(th, ih) - th)/2, tw, th);
R2D_ImageColours(1, 1, 1, 1);
Font_BeginString(font_console, x, y + (max(th, ih) - th)/2, &px, &py);
for (i = 0; i < lines; i++)
{
Font_LineDraw(px, py, starts[i], ends[i]);
py += Font_CharHeight();
}
Font_EndString(font_console);
if (model)
{
playerview_t pv;
entity_t ent;
vec3_t fwd, rgt, up;
vec3_t lightpos = {1, 1, 0};
float transforms[12];
float scale;
if (R2D_Flush)
R2D_Flush();
memset(&pv, 0, sizeof(pv));
CL_DecayLights ();
CL_ClearEntityLists();
V_ClearRefdef(&pv);
r_refdef.drawsbar = false;
V_CalcRefdef(&pv);
r_refdef.grect.width = iw;
r_refdef.grect.height = ih;
r_refdef.grect.x = x-8-iw;
r_refdef.grect.y = y+((th>ih)?(th-ih)/2:0);
r_refdef.time = realtime;
r_refdef.flags = RDF_NOWORLDMODEL;
r_refdef.afov = 60;
r_refdef.fov_x = 0;
r_refdef.fov_y = 0;
r_refdef.dirty |= RDFD_FOV;
VectorClear(r_refdef.viewangles);
r_refdef.viewangles[0] = 20;
// r_refdef.viewangles[1] = realtime * 90;
AngleVectors(r_refdef.viewangles, fwd, rgt, up);
VectorScale(fwd, -64, r_refdef.vieworg);
memset(&ent, 0, sizeof(ent));
ent.scale = 1;
ent.angles[1] = realtime*90;//mods->yaw;
// ent.angles[0] = realtime*23.4;//mods->pitch;
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorInverse(ent.axis[1]);
ent.model = model;
if (!ent.model)
return; //panic!
//ent.origin[2] -= (ent.model->maxs[2]-ent.model->mins[2]) * 0.5 + ent.model->mins[2];
ent.scale = 1;
scale = max(max(fabs(ent.model->maxs[0]-ent.model->mins[0]), fabs(ent.model->maxs[1]-ent.model->mins[1])), fabs(ent.model->maxs[2]-ent.model->mins[2]));
scale = scale?64.0/scale:1;
ent.origin[2] -= (ent.model->maxs[2]-ent.model->mins[2]) * 0.5 + ent.model->mins[2];
Vector4Set(ent.shaderRGBAf, 1, 1, 1, 1);
VectorScale(ent.axis[0], scale, ent.axis[0]);
VectorScale(ent.axis[1], scale, ent.axis[1]);
VectorScale(ent.axis[2], scale, ent.axis[2]);
/*if (strstr(model->name, "player"))
{
ent.bottomcolour = genhsv(realtime*0.1 + 0, 1, 1);
ent.topcolour = genhsv(realtime*0.1 + 0.5, 1, 1);
}
else*/
{
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
}
// ent.fatness = sin(realtime)*5;
ent.playerindex = -1;
ent.skinnum = 0;
ent.shaderTime = 0;//realtime;
ent.framestate.g[FS_REG].lerpweight[0] = 1;
// ent.framestate.g[FS_REG].frame[0] = animationnum;
ent.framestate.g[FS_REG].frametime[0] = ent.framestate.g[FS_REG].frametime[1] = realtime;
ent.framestate.g[FS_REG].endbone = 0x7fffffff;
// ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
VectorSet(ent.glowmod, 1,1,1);
ent.light_avg[0] = ent.light_avg[1] = ent.light_avg[2] = 0.66;
ent.light_range[0] = ent.light_range[1] = ent.light_range[2] = 0.33;
V_ApplyRefdef();
if (ent.model->camerabone>0 && Mod_GetTag(ent.model, ent.model->camerabone, &ent.framestate, transforms))
{
VectorClear(ent.origin);
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorInverse(ent.axis[1]);
scale = 1;
{
vec3_t fwd, up;
float camera[12], et[12] = {
ent.axis[0][0], ent.axis[1][0], ent.axis[2][0], ent.origin[0],
ent.axis[0][1], ent.axis[1][1], ent.axis[2][1], ent.origin[1],
ent.axis[0][2], ent.axis[1][2], ent.axis[2][2], ent.origin[2],
};
R_ConcatTransforms((void*)et, (void*)transforms, (void*)camera);
VectorSet(fwd, camera[2], camera[6], camera[10]);
VectorNegate(fwd, fwd);
VectorSet(up, camera[1], camera[5], camera[9]);
VectorSet(r_refdef.vieworg, camera[3], camera[7], camera[11]);
VectorAngles(fwd, up, r_refdef.viewangles, false);
}
}
else
{
ent.angles[1] = realtime*90;//mods->yaw;
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorScale(ent.axis[0], scale, ent.axis[0]);
VectorScale(ent.axis[1], -scale, ent.axis[1]);
VectorScale(ent.axis[2], scale, ent.axis[2]);
}
ent.scale = scale;
VectorNormalize(lightpos);
ent.light_dir[0] = DotProduct(lightpos, ent.axis[0]);
ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]);
ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]);
ent.light_known = 2;
V_AddEntity(&ent);
R_RenderView();
}
if (shader)
{
if (th > ih)
y += (th-ih)/2;
R2D_Image(x-8-iw, y, iw, ih, 0, 0, 1, 1, shader);
}
}
}
Con_DrawMouseOver(mouseconsole);
}
void Con_DrawOneConsole(console_t *con, qboolean focused, struct font_s *font, float fx, float fy, float fsx, float fsy, float lineagelimit)

View File

@ -630,10 +630,8 @@ static void Stats_LoadFragFile(char *name)
Con_DPrintf("Loaded %s\n", filename);
oend = 1;
for (;*file;)
for (;oend;)
{
if (!oend)
break;
for (end = file; *end && *end != '\n'; end++)
;
oend = *end;

View File

@ -943,14 +943,18 @@ void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float framet
mag = pow(mag, joy_exponent.value);
jlook[0] *= mag;
jlook[1] *= mag;
mag = joydeadzone(fabs(jlook[2]), joy_anglethreshold[2].value);
mag = pow(mag, joy_exponent.value);
jlook[2] *= mag;
mag = joydeadzone(sqrt(jstrafe[0]*jstrafe[0] + jstrafe[1]*jstrafe[1]), sqrt(joy_movethreshold[0].value*joy_movethreshold[0].value + joy_movethreshold[1].value*joy_movethreshold[1].value));
mag = pow(mag, joy_exponent.value);
jstrafe[0] *= mag;
jstrafe[1] *= mag;
mag = joydeadzone(fabs(jstrafe[2]), joy_movethreshold[2].value);
mag = pow(mag, joy_exponent.value);
jstrafe[2] *= mag;
}
else
@ -992,9 +996,12 @@ void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float framet
V_StopPitchDrift (&cl.playerview[pnum]);
//movement
movements[0] += joy_movesens[0].value * cl_forwardspeed.value * jstrafe[0];
movements[1] += joy_movesens[1].value * cl_sidespeed.value * jstrafe[1];
movements[2] += joy_movesens[2].value * cl_upspeed.value * jstrafe[2];
mag = 1;
if ((in_speed.state[pnum] & 1) ^ cl_run.ival)
mag *= cl_movespeedkey.value;
movements[0] += joy_movesens[0].value * mag*cl_forwardspeed.value * jstrafe[0];
movements[1] += joy_movesens[1].value * mag*cl_sidespeed.value * jstrafe[1];
movements[2] += joy_movesens[2].value * mag*cl_upspeed.value * jstrafe[2];
}
void IN_Move (float *movements, int pnum, float frametime)

View File

@ -348,7 +348,7 @@ keyname_t keynames[] =
#if defined(CSQC_DAT) || defined(MENU_DAT)
int MP_TranslateFTEtoQCCodes(int code);
void Key_PrintQCDefines(vfsfile_t *f)
void Key_PrintQCDefines(vfsfile_t *f, qboolean defines)
{
int i, j;
for (i = 0; keynames[i].name; i++)
@ -357,7 +357,12 @@ void Key_PrintQCDefines(vfsfile_t *f)
if (keynames[j].keynum == keynames[i].keynum)
break;
if (j == i)
VFS_PRINTF(f, "#define K_%s\t%i\n", keynames[i].name, MP_TranslateFTEtoQCCodes(keynames[j].keynum));
{
if (defines)
VFS_PRINTF(f, "#define K_%s\t%i\n", keynames[i].name, MP_TranslateFTEtoQCCodes(keynames[j].keynum));
else
VFS_PRINTF(f, "const float K_%s = %i;\n", keynames[i].name, MP_TranslateFTEtoQCCodes(keynames[j].keynum));
}
}
}
#endif
@ -3199,10 +3204,10 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
//these may be redefined later...
case K_GP_LEFT_SHOULDER: dc = "impulse 12"; goto defaultedbind; //matches QS's default.cfg
case K_GP_RIGHT_SHOULDER: dc = "impulse 10"; goto defaultedbind; //matches QS's default.cfg
case K_GP_LEFT_TRIGGER: dc = "+jump"; goto defaultedbind; //matches QS's default.cfg
case K_GP_LEFT_TRIGGER: dc = "+button3"; goto defaultedbind; //matches QS's default.cfg
case K_GP_RIGHT_TRIGGER: dc = "+attack"; goto defaultedbind; //matches QS's default.cfg
case K_GP_START: dc = "togglemenu"; goto defaultedbind;
case K_GP_A: dc = "+button3"; goto defaultedbind;
case K_GP_A: dc = "+jump"; goto defaultedbind;
case K_GP_B: dc = "+button4"; goto defaultedbind;
case K_GP_X: dc = "+button5"; goto defaultedbind;
case K_GP_Y: dc = "+button6"; goto defaultedbind;

View File

@ -480,6 +480,8 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
int pw,ph;
int framescroll = 0;
menuframe_t *framescroller = NULL;
if (option && option->common.type == mt_box && !option->common.ishidden)
{ //FIXME: why is this here? why is this special?
Draw_ApproxTextBox(xpos+option->common.posx, ypos+option->common.posy, option->box.width, option->box.height);
@ -491,6 +493,22 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
if (option->common.ishidden)
continue;
if (framescroller && option == menu->selecteditem)
{
if (ypos+option->common.posy < framescroller->common.posy)
{
framescroller->frac -= 0.1;
if (framescroller->frac < 0)
framescroller->frac = 0;
}
else if (ypos+option->common.posy+option->common.height > framescroller->common.posy+framescroller->common.height)
{
framescroller->frac += 0.1;
if (framescroller->frac > 1)
framescroller->frac = 1;
}
}
if (&menu->menu == topmenu && menu->mouseitem == option && option->common.type != mt_frameend)
{
float alphamax = 0.5, alphamin = 0.2;
@ -565,6 +583,8 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
if (R2D_Flush)
R2D_Flush();
BE_Scissor(NULL);
framescroller = NULL;
break;
case mt_frameend:
{
@ -606,8 +626,9 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
srect.y = (1-srect.y) - srect.height;
BE_Scissor(&srect);
framescroll += option->frame.frac * maxy;
ypos -= option->frame.frac * maxy;
framescroller = &option->frame;
framescroll += framescroller->frac * maxy;
ypos -= framescroller->frac * maxy;
}
}
break;
@ -1995,6 +2016,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
case K_DOWNARROW:
case K_KP_DOWNARROW:
case K_GP_DPAD_DOWN:
godown:
currentmenu->selecteditem = M_NextSelectableItem(currentmenu, currentmenu->selecteditem);
if (currentmenu->selecteditem)
@ -2013,6 +2035,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
case K_UPARROW:
case K_KP_UPARROW:
case K_GP_DPAD_UP:
goup:
currentmenu->selecteditem = M_PrevSelectableItem(currentmenu, currentmenu->selecteditem);
if (currentmenu->selecteditem)
@ -2029,6 +2052,46 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
}
break;
case K_MWHEELUP:
case K_MWHEELDOWN:
if (currentmenu->mouseitem)
{
qboolean handled = false;
switch(currentmenu->mouseitem->common.type)
{
case mt_combo:
if (mousecursor_x >= currentmenu->xpos + currentmenu->mouseitem->common.posx + currentmenu->mouseitem->combo.captionwidth + 3*8)
{
MC_Combo_Key(&currentmenu->mouseitem->combo, key);
handled = true;
}
break;
case mt_checkbox:
if (mousecursor_x >= currentmenu->xpos + currentmenu->mouseitem->common.posx + currentmenu->mouseitem->check.textwidth + 3*8)
{
MC_CheckBox_Key(&currentmenu->mouseitem->check, currentmenu, key);
handled = true;
}
break;
case mt_custom:
if (currentmenu->mouseitem->custom.key)
handled = currentmenu->mouseitem->custom.key(&currentmenu->mouseitem->custom, currentmenu, key, unicode);
break;
default:
break;
}
if (handled)
{
currentmenu->selecteditem = currentmenu->mouseitem;
if (currentmenu->cursoritem)
currentmenu->cursoritem->common.posy = currentmenu->selecteditem->common.posy;
break;
}
else if (key == K_MWHEELUP)
goto goup;
else goto godown;
}
case K_MOUSE1:
case K_MOUSE3:
case K_MOUSE4:
@ -2038,8 +2101,6 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
case K_MOUSE8:
case K_MOUSE9:
case K_MOUSE10:
case K_MWHEELUP:
case K_MWHEELDOWN:
if (!currentmenu->mouseitem)
break;
if (currentmenu->mouseitem && currentmenu->selecteditem != currentmenu->mouseitem)

View File

@ -1171,7 +1171,7 @@ void QCBUILTIN PF_cl_getgamedirinfo(pubprogfuncs_t *prinst, struct globalvars_s
RETURN_TSTRING(mod->manifest->defaultexec);
break;
case GGDI_LOADCOMMAND: //load command
RETURN_TSTRING(va("fs_changegame %u", (unsigned int)diridx+1u));
RETURN_TSTRING(va("fs_changegame %u\n", (unsigned int)diridx+1u));
break;
case GGDI_ICON: //icon
{

File diff suppressed because it is too large Load Diff

View File

@ -19,13 +19,6 @@ void M_Init_Internal (void);
void M_DeInit_Internal (void);
extern unsigned int r2d_be_flags;
#define DRAWFLAG_NORMAL 0
#define DRAWFLAG_ADD 1
#define DRAWFLAG_MODULATE 2
#define DRAWFLAG_MODULATE2 3
#define DRAWFLAG_2D (1u<<2)
#define DRAWFLAG_TWOSIDED 0x400
#define DRAWFLAG_LINES 0x800
static unsigned int PF_SelectDPDrawFlag(pubprogfuncs_t *prinst, int flag)
{
if (r_refdef.warndraw)

View File

@ -2607,6 +2607,12 @@ void QCBUILTIN PF_gettaginfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
}
bonemat_toqcvectors(result, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
/* //extra info for dp compat.
gettaginfo_parent = parentofbone(tagnum);
gettaginfo_name = nameofbone(tagnum);
bonemat_toqcvectors(relbonetransform(fstate, tagnum), gettaginfo_forward, gettaginfo_right, gettaginfo_up, gettaginfo_offset);
*/
}
//writes to axis+origin. returns root entity.

View File

@ -291,7 +291,7 @@ cvar_t scr_fov_viewmodel = CVARFD("r_viewmodel_fov", "", CVAR_ARCHIVE,
"field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.");
cvar_t scr_printspeed = CVAR ("scr_printspeed", "16");
cvar_t scr_showpause = CVAR ("showpause", "1");
cvar_t scr_showturtle = CVAR ("showturtle", "0");
cvar_t scr_showturtle = CVARD ("showturtle", "0", "Enables a low-framerate indicator.");
cvar_t scr_turtlefps = CVAR ("scr_turtlefps", "10");
cvar_t scr_sshot_compression = CVAR ("scr_sshot_compression", "75");
cvar_t scr_sshot_type = CVARD ("scr_sshot_type", "png", "This specifies the default extension(and thus file format) for screenshots.\nKnown extensions are: png, jpg/jpeg, bmp, pcx, tga, ktx, dds.");

View File

@ -1103,7 +1103,6 @@ int main (int c, const char **v)
quakeparms_t parms;
int i;
// char cwd[1024];
char bindir[1024];
signal(SIGFPE, SIG_IGN);
@ -1167,7 +1166,33 @@ int main (int c, const char **v)
}
}
parms.basedir = realpath(".", NULL);
#if _POSIX_C_SOURCE >= 200809L
{
char *path = realpath(".", NULL);
if (path)
{
size_t l = strlen(path)+2;
char *npath = malloc(strlen(path)+2);
Q_snprintfz(npath, l, "%s/", path);
parms.basedir = npath;
free(path);
}
}
#elif _POSIX_C_SOURCE >= 200112L && defined(PATH_MAX)
{
char path[PATH_MAX];
if (realpath(".", path))
{
size_t l = strlen(path)+2;
char *npath = malloc(strlen(path)+2);
Q_snprintfz(npath, l, "%s/", path);
parms.basedir = npath;
}
}
#else
parms.basedir = ""; //play it safe when realpath is too awkward to use. don't depend upon "./" working, and hope that the user uses -basedir or simply doesn't care about path prints (hopefully its only windows libraries that change the working dir without the program's permission).
#endif
memset(bindir, 0, sizeof(bindir)); //readlink does NOT null terminate, apparently.
#ifdef __linux__
//attempt to figure out where the exe is located
@ -1233,7 +1258,7 @@ int main (int c, const char **v)
#endif
if (parms.binarydir)
Sys_Printf("Binary is located at \"%s\"\n", bindir);
Sys_Printf("Binary is located at \"%s\"\n", parms.binarydir);
#ifndef CLIENTONLY
if (isDedicated) //compleate denial to switch to anything else - many of the client structures are not initialized.
@ -1369,7 +1394,7 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres
#define SYS_CLIPBOARD_SIZE 256
static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0};
void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, char *utf8), void *ctx)
void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, const char *utf8), void *ctx)
{
callback(ctx, clipboard_buffer);
}

View File

@ -619,17 +619,35 @@ typedef struct
#define TI_SLICK 0x2 // effects game physics
#define TI_SKY 0x4 // don't draw, but add to skybox
#define TI_WARP 0x8 // turbulent water warp
#define TI_TRANS33 0x10
#define TI_TRANS66 0x20
#define TI_FLOWING 0x40 // scroll towards angle
#define TI_SKY 0x4 // don't draw, but add to skybox
#define TI_WARP 0x8 // turbulent water warp
#define TI_TRANS33 0x10
#define TI_TRANS66 0x20
#define TI_FLOWING 0x40 // scroll towards angle
#define TI_NODRAW 0x80 // don't bother referencing the texture
#define TI_ALPHATEST 0x100
//Surface flags
#define Q3SURF_LADDER 0x8 //wee
//#define Q3SURFACEFLAG_NODAMAGE 0x1 // never give falling damage
//#define Q3SURFACEFLAG_SLICK 0x2 // effects game physics
//#define Q3SURFACEFLAG_SKY 0x4 // lighting from environment map
#define Q3SURFACEFLAG_LADDER 0x8
//#define Q3SURFACEFLAG_NOIMPACT 0x10 // don't make missile explosions
//#define Q3SURFACEFLAG_NOMARKS 0x20 // don't leave missile marks
//#define Q3SURFACEFLAG_FLESH 0x40 // make flesh sounds and effects
//#define Q3SURFACEFLAG_NODRAW 0x80 // don't generate a drawsurface at all
//#define Q3SURFACEFLAG_HINT 0x100 // make a primary bsp splitter
//#define Q3SURFACEFLAG_SKIP 0x200 // completely ignore, allowing non-closed brushes
//#define Q3SURFACEFLAG_NOLIGHTMAP 0x400 // surface doesn't need a lightmap
//#define Q3SURFACEFLAG_POINTLIGHT 0x800 // generate lighting info at vertexes
//#define Q3SURFACEFLAG_METALSTEPS 0x1000 // clanking footsteps
//#define Q3SURFACEFLAG_NOSTEPS 0x2000 // no footstep sounds
//#define Q3SURFACEFLAG_NONSOLID 0x4000 // don't collide against curves with this set
//#define Q3SURFACEFLAG_LIGHTFILTER 0x8000 // act as a light filter during q3map -light
//#define Q3SURFACEFLAG_ALPHASHADOW 0x10000 // do per-pixel light shadow casting in q3map
//#define Q3SURFACEFLAG_NODLIGHT 0x20000 // don't dlight even if solid (solid lava, skies)
//#define Q3SURFACEFLAG_DUST 0x40000 // leave a dust trail when walking on this surface
// content masks. Allow q2contents_window in here
//#define MASK_ALL (-1)

View File

@ -4277,7 +4277,6 @@ void Cmd_Init (void)
Cmd_AddCommandAD ("seta_calc", Cmd_set_f, Cmd_Set_c, "Sets the named cvar to the result of a (complex) expression. Also forces the archive flag so that the cvar will always be written into any saved configs.");
Cmd_AddCommandD ("vstr", Cmd_Vstr_f, "Executes the string value of the cvar, much like if it were an alias. For compatibility with q3.");
Cmd_AddCommandAD ("inc", Cvar_Inc_f, Cmd_Set_c, "Adds a value to the named cvar. Use a negative value if you wish to decrease the cvar's value.");
//FIXME: Add seta some time.
Cmd_AddCommand ("if", Cmd_if_f);
Cmd_AddCommand ("cmdlist", Cmd_List_f);
@ -4312,6 +4311,7 @@ void Cmd_Init (void)
Cmd_AddCommandD ("in", Cmd_In_f, "Issues the given command after a time delay. Disabled if ruleset_allow_in is 0.");
#ifdef HAVE_LEGACY
Cmd_AddCommandD ("defer", Cmd_In_f, "Issues the given command after a time delay. Disabled if ruleset_allow_in is 0.");
Cvar_Register(&dpcompat_set, "Darkplaces compatibility");
Cvar_Register(&dpcompat_console, "Darkplaces compatibility");
#endif

View File

@ -37,7 +37,9 @@ static int QDECL VFSSTDIO_WriteBytes (struct vfsfile_s *file, const void *buffer
static qboolean QDECL VFSSTDIO_Seek (struct vfsfile_s *file, qofs_t pos)
{
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
#if _POSIX_C_SOURCE >= 200112L
#ifdef __USE_LARGEFILE64
return fseeko64(intfile->handle, (off64_t)pos, SEEK_SET) == 0;
#elif _POSIX_C_SOURCE >= 200112L
return fseeko(intfile->handle, (off_t)pos, SEEK_SET) == 0;
#else
return fseek(intfile->handle, pos, SEEK_SET) == 0;
@ -46,7 +48,9 @@ static qboolean QDECL VFSSTDIO_Seek (struct vfsfile_s *file, qofs_t pos)
static qofs_t QDECL VFSSTDIO_Tell (struct vfsfile_s *file)
{
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
#if _POSIX_C_SOURCE >= 200112L
#ifdef __USE_LARGEFILE64
idhgr sdrg ser gser greturn (qofs_t)ftello64(intfile->handle);
#elif _POSIX_C_SOURCE >= 200112L
return (qofs_t)ftello(intfile->handle);
#else
return ftell(intfile->handle);
@ -61,7 +65,14 @@ static qofs_t QDECL VFSSTDIO_GetSize (struct vfsfile_s *file)
{
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
#if _POSIX_C_SOURCE >= 200112L
#ifdef __USE_LARGEFILE64
off64_t curpos;
qofs_t maxlen;
curpos = ftello64(intfile->handle);
fseeko64(intfile->handle, 0, SEEK_END);
maxlen = (qofs_t)ftello64(intfile->handle);
fseeko64(intfile->handle, curpos, SEEK_SET);
#elif _POSIX_C_SOURCE >= 200112L
off_t curpos;
qofs_t maxlen;
curpos = ftello(intfile->handle);
@ -122,8 +133,12 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
file->funcs.Close = VFSSTDIO_CloseTemp;
strcpy((char*)(file+1), fname);
free(fname);
#else
#ifdef __USE_LARGEFILE64
f = tmpfile64();
#else
f = tmpfile();
#endif
if (!f)
return NULL;
@ -189,7 +204,11 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsfl
#endif
newmode[modec++] = '\0';
#ifdef __USE_LARGEFILE64
f = fopen64(osname, newmode);
#else
f = fopen(osname, newmode);
#endif
if (!f)
return NULL;
@ -298,7 +317,7 @@ static unsigned int QDECL FSSTDIO_CreateLoc(searchpathfuncs_t *handle, flocation
static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
stdiopath_t *sp = (void*)handle;
int len;
qofs_t len;
char netpath[MAX_OSPATH];
if (hashedresult && (void *)hashedresult != handle)
@ -326,12 +345,24 @@ static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t
}
#else
{
#ifdef __USE_LARGEFILE64
FILE *f = fopen64(netpath, "rb");
#else
FILE *f = fopen(netpath, "rb");
#endif
if (!f)
return FF_NOTFOUND;
#ifdef __USE_LARGEFILE64
fseeko64(f, 0, SEEK_END);
len = ftello64(f);
#elif _POSIX_C_SOURCE >= 200112L
fseeko(f, 0, SEEK_END);
len = ftello(f);
#else
fseek(f, 0, SEEK_END);
len = ftell(f);
#endif
fclose(f);
}
#endif
@ -349,10 +380,20 @@ static void QDECL FSSTDIO_ReadFile(searchpathfuncs_t *handle, flocation_t *loc,
FILE *f;
size_t result;
#ifdef __USE_LARGEFILE64
f = fopen64(loc->rawname, "rb");
#else
f = fopen(loc->rawname, "rb");
#endif
if (!f) //err...
return;
#ifdef __USE_LARGEFILE64
fseeko64(f, loc->offset, SEEK_SET);
#elif _POSIX_C_SOURCE >= 200112L
fseeko(f, loc->offset, SEEK_SET);
#else
fseek(f, loc->offset, SEEK_SET);
#endif
result = fread(buffer, 1, loc->len, f); // do soemthing with result
if (result != loc->len)

View File

@ -791,6 +791,7 @@ qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize,
if (certlog_curprompt)
return false;
COM_AssertMainThread("CertLog_ConnectOkay");
if (!certlog_inited)
CertLog_Import(NULL);

View File

@ -517,7 +517,6 @@ static int QDECL SSL_CheckCert(gnutls_session_t session)
gnutlsfile_t *file = qgnutls_session_get_ptr (session);
unsigned int certstatus;
qboolean preverified = false;
int errcode = GNUTLS_E_CERTIFICATE_ERROR;
size_t knownsize;
qbyte *knowndata = TLS_GetKnownCertificate(file->certname, &knownsize);
@ -576,23 +575,31 @@ static int QDECL SSL_CheckCert(gnutls_session_t session)
#ifdef GNUTLS_HAVE_VERIFY3
if (qgnutls_certificate_verify_peers3(session, file->certname, &certstatus) >= 0)
{
gnutls_datum_t out = {NULL,0};
gnutls_certificate_type_t type;
int ret;
if (preverified && (certstatus&~GNUTLS_CERT_EXPIRED) == (GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_FOUND))
return 0;
ret = SSL_CheckUserTrust(session, file, certstatus);
if (!ret)
return ret;
type = qgnutls_certificate_type_get (session);
if (qgnutls_certificate_verification_status_print(certstatus, type, &out, 0) >= 0)
{
gnutls_datum_t out;
gnutls_certificate_type_t type;
int ret;
if (preverified && (certstatus&~GNUTLS_CERT_EXPIRED) == (GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_FOUND))
return 0;
ret = SSL_CheckUserTrust(session, file, certstatus);
if (!ret)
return ret;
type = qgnutls_certificate_type_get (session);
if (qgnutls_certificate_verification_status_print(certstatus, type, &out, 0) >= 0)
{
Con_Printf(CON_ERROR "%s: %s (%x)\n", file->certname, out.data, certstatus);
//looks like its static anyway. qgnutls_free(out.data);
Con_Printf(CON_ERROR "%s: %s (%x)\n", file->certname, out.data, certstatus);
(*qgnutls_free)(out.data);
}
else
Con_Printf(CON_ERROR "%s: UNKNOWN STATUS (%x)\n", file->certname, certstatus);
if (tls_ignorecertificateerrors.ival)
{
Con_Printf(CON_ERROR "%s: Ignoring certificate errors (tls_ignorecertificateerrors is %i)\n", file->certname, tls_ignorecertificateerrors.ival);
return 0;
}
}
#else
if (qgnutls_certificate_verify_peers2(session, &certstatus) >= 0)
{
@ -625,7 +632,6 @@ static int QDECL SSL_CheckCert(gnutls_session_t session)
Con_Printf(CON_ERROR "%s: Certificate signature failure\n", file->certname);
else
Con_Printf(CON_ERROR "%s: Certificate error\n", file->certname);
#endif
if (tls_ignorecertificateerrors.ival)
{
Con_Printf(CON_ERROR "%s: Ignoring certificate errors (tls_ignorecertificateerrors is %i)\n", file->certname, tls_ignorecertificateerrors.ival);
@ -636,9 +642,10 @@ static int QDECL SSL_CheckCert(gnutls_session_t session)
Con_DPrintf(CON_ERROR "%s: certificate is for a different domain\n", file->certname);
}
}
#endif
Con_DPrintf(CON_ERROR "%s: rejecting certificate\n", file->certname);
return errcode;
return GNUTLS_E_CERTIFICATE_ERROR;
}
//return 1 to read data.
@ -1052,6 +1059,7 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
qboolean SSL_InitGlobal(qboolean isserver)
{
int err;
static int initstatus[2];
isserver = !!isserver;
if (COM_CheckParm("-notls"))
@ -1087,7 +1095,9 @@ qboolean SSL_InitGlobal(qboolean isserver)
qgnutls_certificate_allocate_credentials (&xcred[isserver]);
#ifdef GNUTLS_HAVE_SYSTEMTRUST
qgnutls_certificate_set_x509_system_trust (xcred[isserver]);
err = qgnutls_certificate_set_x509_system_trust (xcred[isserver]);
if (err <= 0)
Con_Printf("gnutls_certificate_set_x509_system_trust: error %i.\n", err);
#else
qgnutls_certificate_set_x509_trust_file (xcred[isserver], CAFILE, GNUTLS_X509_FMT_PEM);
#endif
@ -1227,7 +1237,7 @@ int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize)
gnutls_datum_t cb;
gnutlsfile_t *f = (gnutlsfile_t*)vf;
if (vf->Close != SSL_CloseFile)
return -1; //err, not a tls connection.
return -1; //err, not a gnutls connection.
if (qgnutls_session_channel_binding(f->session, GNUTLS_CB_TLS_UNIQUE, &cb))
{ //error of some kind

View File

@ -1022,7 +1022,7 @@ void PM_CategorizePosition (void)
VectorMA (pmove.origin, 24, flatforward, fwd1);
pmove.physents[0].model->funcs.NativeTrace(pmove.physents[0].model, 0, PE_FRAMESTATE, NULL, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, pmove.capsule, MASK_PLAYERSOLID, &t);
if (t.surface && t.surface->flags & Q3SURF_LADDER)
if (t.surface && t.surface->flags & Q3SURFACEFLAG_LADDER)
{
pmove.onladder = true;
pmove.onground = false; // too steep

View File

@ -1590,17 +1590,17 @@ void QCBUILTIN PF_cvar_type (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
cvar_t *v = Cvar_FindVar(str); //this builtin MUST NOT create cvars implicitly, otherwise there would be no way to test if it exists.
if (v)
{
ret |= 1; // CVAR_EXISTS
ret |= CVAR_TYPEFLAG_EXISTS;
if(v->flags & CVAR_ARCHIVE)
ret |= 2; // CVAR_TYPE_SAVED
ret |= CVAR_TYPEFLAG_SAVED;
if(v->flags & (CVAR_NOTFROMSERVER|CVAR_NOUNSAFEEXPAND))
ret |= 4; // CVAR_TYPE_PRIVATE
ret |= CVAR_TYPEFLAG_PRIVATE;
if(!(v->flags & CVAR_USERCREATED))
ret |= 8; // CVAR_TYPE_ENGINE
ret |= CVAR_TYPEFLAG_ENGINE;
if (v->description)
ret |= 16; // CVAR_TYPE_HASDESCRIPTION
ret |= CVAR_TYPEFLAG_HASDESCRIPTION;
if (v->flags & CVAR_NOSET)
ret |= 32; // CVAR_TYPE_READONLY
ret |= CVAR_TYPEFLAG_READONLY;
}
G_FLOAT(OFS_RETURN) = ret;
}
@ -4114,7 +4114,15 @@ void QCBUILTIN PF_ftoi (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
}
void QCBUILTIN PF_itof (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = G_INT(OFS_PARM0);
if (prinst->callargc > 1)
{
unsigned int value = G_INT(OFS_PARM0);
unsigned int shift = G_FLOAT(OFS_PARM1);
unsigned int count = G_FLOAT(OFS_PARM2);
G_FLOAT(OFS_RETURN) = (value >> shift) & ((1u<<count)-1u);
}
else
G_FLOAT(OFS_RETURN) = G_INT(OFS_PARM0);
}
//tstring(integer input) itos
@ -7557,7 +7565,7 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_QC_NPCCHAT", 1, NULL, {"chat"}}, //server looks at chat files. It automagically branches through calling qc functions as requested.
#endif
#ifdef PSET_SCRIPT
{"FTE_PART_SCRIPT", 0, NULL, {NULL}, "Specifies that the r_particledesc cvar can be used to select a list of particle effects to load from particles/*.cfg, the format of which is documented elsewhere."},
{"FTE_PART_SCRIPT", 0, NULL, {NULL}, "Specifies that the r_particledesc cvar can be used to select a list of particle effects to load from particles/foo.cfg, the format of which is documented elsewhere."},
{"FTE_PART_NAMESPACES", 0, NULL, {NULL}, "Specifies that the engine can use foo.bar to load effect foo from particle description bar. When used via ssqc, this should cause the client to download whatever effects as needed."},
#ifdef HAVE_LEGACY
{"FTE_PART_NAMESPACE_EFFECTINFO", 0, NULL, {NULL}, "Specifies that effectinfo.bar can load effects from effectinfo.txt for DP compatibility."},

View File

@ -205,6 +205,16 @@ void QCBUILTIN PF_generateentitydata(pubprogfuncs_t *prinst, struct globalvars_s
void QCBUILTIN PF_WasFreed (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_break (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_crc16 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
enum
{ //return values for cvar_type builtin.
CVAR_TYPEFLAG_EXISTS =1u<<0, //cvar actually exists.
CVAR_TYPEFLAG_SAVED =1u<<1, //cvar is flaged for archival (might need cfg_save to actually save)
CVAR_TYPEFLAG_PRIVATE =1u<<2, //QC is not allowed to read.
CVAR_TYPEFLAG_ENGINE =1u<<3, //cvar was created by the engine itself (not user/mod created)
CVAR_TYPEFLAG_HASDESCRIPTION=1u<<4, //cvar_description will return something (hopefully) useful
CVAR_TYPEFLAG_READONLY =1u<<5, //cvar may not be changed by qc.
};
void QCBUILTIN PF_cvar_type (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_uri_escape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_uri_unescape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -398,6 +408,13 @@ void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *p
void QCBUILTIN PF_cvar_description (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
//these functions are from pr_menu.c
#define DRAWFLAG_NORMAL 0
#define DRAWFLAG_ADD 1
#define DRAWFLAG_MODULATE 2
//#define DRAWFLAG_MODULATE2 3
#define DRAWFLAG_2D (1u<<2)
#define DRAWFLAG_TWOSIDED 0x400
#define DRAWFLAG_LINES 0x800
void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_SubConPrintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_SubConDraw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -765,7 +782,7 @@ typedef enum
//WARNING: update fteqcc when new entries are added.
VF_DP_CLEARSCREEN = 201, // weird behaviour that disables a whole load of things.
VF_DP_CLEARSCREEN = 201, //misnomer - NOTOVERLAY would be a better name. when set to false prevents any and all post-proc things that might write colour values in areas with no geometry there.
//fuck DP and their complete lack of respect for existing implemenetations
VF_DP_FOG_DENSITY = 202, //misassigned
VF_DP_FOG_COLOR = 203, //misassigned
@ -784,14 +801,22 @@ typedef enum
/*FIXME: this should be changed*/
#define CSQC_API_VERSION 1.0f
#define CSQCRF_VIEWMODEL 1 //Not drawn in mirrors
#define CSQCRF_EXTERNALMODEL 2 //drawn ONLY in mirrors
#define CSQCRF_DEPTHHACK 4 //fun depthhack
#define CSQCRF_ADDITIVE 8 //add instead of blend
#define CSQCRF_USEAXIS 16 //use v_forward/v_right/v_up as an axis/matrix - predraw is needed to use this properly
#define CSQCRF_NOSHADOW 32 //don't cast shadows upon other entities (can still be self shadowing, if the engine wishes, and not additive)
#define CSQCRF_FRAMETIMESARESTARTTIMES 64 //EXT_CSQC_1: frame times should be read as (time-frametime).
#define CSQCRF_REMOVED 128 //was stupid
#define CSQCRF_VIEWMODEL 1 //Not drawn in mirrors
#define CSQCRF_EXTERNALMODEL 2 //drawn ONLY in mirrors
#define CSQCRF_DEPTHHACK 4 //fun depthhack
#define CSQCRF_ADDITIVE 8 //add instead of blend
#define CSQCRF_USEAXIS 16 //use v_forward/v_right/v_up as an axis/matrix - predraw is needed to use this properly
#define CSQCRF_NOSHADOW 32 //don't cast shadows upon other entities (can still be self shadowing, if the engine wishes, and not additive)
#define CSQCRF_FRAMETIMESARESTARTTIMES 64 //EXT_CSQC_1: frame times should be read as (time-frametime).
//#define CSQCRFDP_USETRANSPARENTOFFSET 64 // Allows QC to customize origin used for transparent sorting via transparent_origin global, helps to fix transparent sorting bugs on a very large entities
////#define CSQCRF_NOAUTOADD 128 // removed in favour of predraw return values.
//#define CSQCRFDP_WORLDOBJECT 128 // for large outdoor entities that should not be culled.
//#define CSQCRFDP_FULLBRIGHT 256
//#define CSQCRFDP_NOSHADOW 512
//#define CSQCRF_UNUSED 1024
//#define CSQCRF_UNUSED 2048
//#define CSQCRFDP_MODELLIGHT 4096 // CSQC-set model light
//#define CSQCRFDP_DYNAMICMODELLIGHT 8192 // origin-dependent model light
/*only read+append+write are standard frik_file*/
#define FRIK_FILE_READ 0 /*read-only*/
@ -964,6 +989,137 @@ enum
// GE_MOVEMENT,
// GE_VELOCITY,
};
//If I do it like this, I'll never forget to register something...
#define ENDLIST
#ifndef HAVE_LEGACY
#define legacycsqcglobals
#else
#define legacycsqcglobals \
globalstring(trace_dphittexturename) /*for dp compat*/ \
globalfloatdep (trace_dpstartcontents, "Does not support mod-specific contents.") /*for dp compat*/ \
globalfloatdep (trace_dphitcontents, "Does not support mod-specific contents.") /*for dp compat*/ \
globalfloatdep (trace_dphitq3surfaceflags, "Does not support mod-specific surface flags") /*for dp compat*/ \
globalfloatdep (trace_surfaceflagsf, "Does not support all mod-specific surface flags.") /*float written by traceline, for mods that lack ints*/ \
globalfloatdep (trace_endcontentsf, "Does not support all mod-specific contents.") /*float written by traceline EXT_CSQC_1, for mods that lack ints*/ \
ENDLIST
#endif
#define csqcglobals \
globalfunction(CSQC_Init, "void(float apilevel, string enginename, float engineversion)") \
globalfunction(CSQC_WorldLoaded, "void()") \
globalfunction(CSQC_Shutdown, "void()") \
globalfunction(CSQC_UpdateView, "void(float vwidth, float vheight, float notmenu)") \
globalfunction(CSQC_UpdateViewLoading, "void(float vwidth, float vheight, float notmenu)") \
globalfunction(CSQC_DrawHud, "void(vector viewsize, float scoresshown)")/*simple csqc*/ \
globalfunction(CSQC_DrawScores, "void(vector viewsize, float scoresshown)")/*simple csqc*/ \
globalfunction(CSQC_Parse_StuffCmd, "void(string msg)") \
globalfunction(CSQC_Parse_CenterPrint, "float(string msg)") \
globalfunction(CSQC_Parse_Print, "void(string printmsg, float printlvl)") \
globalfunction(CSQC_Parse_Event, "void()") \
globalfunction(CSQC_Parse_Damage, "float(float save, float take, vector inflictororg)") \
globalfunction(CSQC_Parse_SetAngles, "float(vector angles, float isdelta)") \
globalfunction(CSQC_PlayerInfoChanged, "void(float playernum)") \
globalfunction(CSQC_ServerInfoChanged, "void()") \
globalfunction(CSQC_InputEvent, "float(float evtype, float scanx, float chary, float devid)") \
globalfunction(CSQC_Input_Frame, "void()")/*EXT_CSQC_1*/ \
globalfunction(CSQC_RendererRestarted, "void(string rendererdescription)") \
globalfunction(CSQC_ConsoleCommand, "float(string cmd)") \
globalfunction(CSQC_ConsoleLink, "float(string text, string info)") \
globalfunction(GameCommand, "void(string cmdtext)") /*DP extension*/\
\
globalfunction(CSQC_Ent_Spawn, "void(float newentnum)") \
globalfunction(CSQC_Ent_Update, "void(float isnew)") \
globalfunction(CSQC_Ent_Remove, "void()") \
\
globalfunction(CSQC_Event_Sound, "float(float entnum, float channel, string soundname, float vol, float attenuation, vector pos, float pitchmod, float flags"/*", float timeofs*/")") \
globalfunction(CSQC_ServerSound, "DEP(\"use CSQC_Event_Sound\") float(float channel, string soundname, vector pos, float vol, float attenuation, float flags"/*", float timeofs*/")")/*obsolete, use event_sound*/ \
/*globalfunction(CSQC_LoadResource, "float(string resname, string restype)")*//*EXT_CSQC_1*/ \
globalfunction(CSQC_Parse_TempEntity, "float()")/*EXT_CSQC_ABSOLUTLY_VILE*/ \
\
globalfunction(CSQC_MapEntityEdited, "void(int entidx, string newentdata)")\
\
/*These are pointers to the csqc's globals.*/ \
globalfloat (time) /*float The simulation(aka: smoothed server) time, speed drifts based upon latency*/ \
globalfloat (frametime) /*float Client render frame interval*/ \
globalfloat (gamespeed) /*float Multiplier for real time -> simulation time*/ \
globalfloat (cltime) /*float Clientside map uptime indepent of gamespeed, latency, and the server in general*/ \
globalfloat (clframetime) /*float time since last video frame*/ \
globalfloat (servertime) /*float Server time of latest inbound network frame*/ \
globalfloat (serverprevtime) /*float Server time of previous inbound network frame */ \
globalfloat (serverdeltatime) /*float new-old */ \
globalfloat (physics_mode) /*float Written before entering most qc functions*/ \
globalentity(self) /*entity Written before entering most qc functions*/ \
globalentity(other) /*entity Written before entering most qc functions*/ \
\
globalfloat (deathmatch) /*for simplecsqc*/ \
globalfloat (coop) /*for simplecsqc*/ \
\
globalfloat (maxclients) /*float max number of players allowed*/ \
globalfloat (numclientseats) /*float number of seats/splitscreen clients running on this client*/ \
\
globalvector(v_forward) /*vector written by anglevectors*/ \
globalvector(v_right) /*vector written by anglevectors*/ \
globalvector(v_up) /*vector written by anglevectors*/ \
\
globalfloat (trace_allsolid) /*bool written by traceline*/ \
globalfloat (trace_startsolid) /*bool written by traceline*/ \
globalfloat (trace_fraction) /*float written by traceline*/ \
globalfloat (trace_inwater) /*bool written by traceline*/ \
globalfloat (trace_inopen) /*bool written by traceline*/ \
globalvector(trace_endpos) /*vector written by traceline*/ \
globalvector(trace_plane_normal) /*vector written by traceline*/ \
globalfloat (trace_plane_dist) /*float written by traceline*/ \
globalentity(trace_ent) /*entity written by traceline*/ \
globalint (trace_surfaceflagsi) /*int written by traceline*/ \
globalstring(trace_surfacename) /*string written by traceline*/ \
globalint (trace_endcontentsi) /*int written by traceline EXT_CSQC_1*/ \
globalint (trace_brush_id) /*int written by traceline*/ \
globalint (trace_brush_faceid) /*int written by traceline*/ \
globalint (trace_surface_id) /*int written by traceline*/ \
globalint (trace_bone_id) /*int written by traceline*/ \
globalint (trace_triangle_id) /*int written by traceline*/ \
globalfloat (trace_networkentity) /*float written by traceline*/ \
legacycsqcglobals \
\
globalfloat(clientcommandframe) /*float the next frame that will be sent*/ \
globalfloat(servercommandframe) /*float the most recent frame received from the server*/ \
\
globalfloat(player_localentnum) /*float the entity number the local player is looking out from*/ \
globalfloat(player_localnum) /*float the player number of the local player*/ \
globalfloat(intermission) /*float set when the client receives svc_intermission*/ \
globalfloat(intermission_time) /*float set when the client receives svc_intermission*/ \
globalvector(view_angles) /*float set to the view angles at the start of each new frame (EXT_CSQC_1)*/ \
\
globalvector(pmove_org) /*deprecated. read/written by runplayerphysics*/ \
globalvector(pmove_vel) /*deprecated. read/written by runplayerphysics*/ \
globalvector(pmove_mins) /*deprecated. read/written by runplayerphysics*/ \
globalvector(pmove_maxs) /*deprecated. read/written by runplayerphysics*/ \
globalfloat (pmove_jump_held) /*deprecated. read/written by runplayerphysics*/ \
globalfloat (pmove_waterjumptime) /*deprecated. read/written by runplayerphysics*/ \
globalfloat (pmove_onground) /*deprecated. read/written by runplayerphysics*/ \
\
globalfloat (input_timelength) /*float filled by getinputstate, read by runplayerphysics*/ \
globalvector(input_angles) /*vector filled by getinputstate, read by runplayerphysics*/ \
globalvector(input_movevalues) /*vector filled by getinputstate, read by runplayerphysics*/ \
globalfloat (input_buttons) /*float filled by getinputstate, read by runplayerphysics*/ \
globalfloat (input_impulse) /*float filled by getinputstate, read by runplayerphysics*/ \
globalfloat (input_lightlevel) /*unused float filled by getinputstate, read by runplayerphysics*/ \
globalfloat (input_weapon) /*unused float filled by getinputstate, read by runplayerphysics*/ \
globalfloat (input_servertime) /*float filled by getinputstate, read by runplayerphysics*/ \
globalfloat (input_clienttime) /*float filled by getinputstate, read by runplayerphysics*/ \
globalvector(input_cursor_screen) /*float filled by getinputstate*/ \
globalvector(input_cursor_trace_start) /*float filled by getinputstate*/ \
globalvector(input_cursor_trace_endpos) /*float filled by getinputstate*/ \
globalfloat (input_cursor_entitynumber) /*float filled by getinputstate*/ \
\
globalvector(global_gravitydir) /*vector used when .gravitydir is 0 0 0 */ \
globalfloat (dimension_default) /*float default value for dimension_hit+dimension_solid*/ \
globalfloat (autocvar_vid_conwidth) /*float hackfix for dp mods*/ \
globalfloat (autocvar_vid_conheight) /*float hackfix for dp mods*/ \
globalfloat (cycle_wrapped) \
ENDLIST
#ifdef __cplusplus
};
#endif

View File

@ -326,7 +326,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svcfte_brushedit 87 // networked brush editing, paired with clcfte_brushedit.
#define svcfte_updateseats 88 // byte count, byte playernum[count]
#define svcfte_setinfoblob 89 // [8] 1-based index [string] key [32] isfinal<<31|offset [16] chunksize [chunksize] data
#define svcfte_cgamepacket_sized 90 //svcfte_cgamepacket with an extra short size right after the svc.
#define svcfte_temp_entity_sized 91 //svc_temp_entity with an extra short size right after the svc (high bit means nq, unset means qw).
#define svcfte_csqcentities_sized 92 //entity lump for csqc (with size info)
//fitz svcs
#define svcfitz_skybox 37

View File

@ -4917,11 +4917,8 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
if (!mod)
return;
if (!mod->terrain)
{
if (mod->loadstate == MLS_LOADING)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
}
if (mod->loadstate == MLS_LOADING)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
if (mod->loadstate != MLS_LOADED)
return;

View File

@ -7318,7 +7318,7 @@ void R_UnloadShader(shader_t *shader)
return;
if (shader->uses <= 0)
{
Con_Printf("Shader double free (%s %i)\n", shader->name, shader->usageflags);
Con_Printf("Shader double free (%p %s %i)\n", shader, shader->name, shader->usageflags);
return;
}
if (--shader->uses == 0)

View File

@ -2319,7 +2319,7 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
);
}
if (!prog || !prog->explicitsyms)
if (prog && !prog->explicitsyms)
{ //for compat with our vulkan processor, which injects samplers in order to control layouts.
const char *defaultsamplernames[] =
{

View File

@ -56,7 +56,11 @@ none of these issues will be fixed by a compositing window manager, because ther
#include "quakedef.h"
#ifndef NO_X11
#ifdef NO_X11
#ifdef VKQUAKE
rendererinfo_t vkrendererinfo;
#endif
#else
#include <X11/Xlib.h>
#include <X11/Xatom.h>
@ -208,6 +212,7 @@ static struct
qXErrorHandler (*pXSetErrorHandler)(XErrorHandler);
int (*pXGetErrorText)(Display *display, int code, char *buffer_return, int length);
int (*pXGrabServer)(Display *display);
int (*pXUngrabServer)(Display *display);
@ -245,8 +250,8 @@ static struct
static int X11_ErrorHandler(Display *dpy, XErrorEvent *e)
{
char msg[80];
// XGetErrorText(dpy, e->error_code, msg, sizeof(msg));
*msg = 0;
x11.pXGetErrorText(dpy, e->error_code, msg, sizeof(msg));
Con_Printf(CON_ERROR "XLib Error %d (%s): request %d.%d\n", e->error_code, msg, e->request_code, e->minor_code);
return 0; //ignored.
}
@ -329,8 +334,9 @@ static qboolean x11_initlib(void)
if (x11.lib)
{
x11.pXSetErrorHandler = Sys_GetAddressForName(x11.lib, "XSetErrorHandler");
x11.pXGetErrorText = Sys_GetAddressForName(x11.lib, "XGetErrorText");
if (x11.pXSetErrorHandler)
if (x11.pXSetErrorHandler && x11.pXGetErrorText)
x11.pXSetErrorHandler(X11_ErrorHandler);
//raw input (yay mouse deltas)
@ -872,7 +878,7 @@ static void XRandR_RevertMode(void)
{
x11.pXGrabServer(vid_dpy);
if (xrandr.nvidiabug == 1)
{
{ //attempt to undo at least part of the damage we inflicted to work around nvidia's defects.
if (Success == xrandr.pSetCrtcConfig(vid_dpy, xrandr.res, xrandr.crtc, CurrentTime, c->x, c->y, None, c->rotation, NULL, 0))
xrandr.pSetScreenSize(vid_dpy, DefaultRootWindow(vid_dpy), xrandr.origscreenwidth, xrandr.origscreenheight, xrandr.origscreenwidthmm, xrandr.origscreenheightmm);
}
@ -1137,13 +1143,13 @@ static void XRandR_SelectMode(const char *devicename, int *x, int *y, int *width
if (xrandr.nvidiabug && (c->x != 0 || c->y != 0 || c->noutput>1))
{
Con_Printf("Nvidia and multimonitor detected. XRandR cannot be used safely under in this situation.\n");
Con_Printf("Nvidia and multimonitor detected. XRandR cannot be used safely in this situation.\n");
xrandr.crtcmode = NULL;
}
else
{
if (xrandr.nvidiabug)
Con_Printf(CON_ERROR "Attempting NVIDIA panning workaround. Try 'xrandr --output foo --auto' to fix if this goes south..\n");
Con_Printf(CON_ERROR "Attempting NVIDIA panning workaround. Try 'xrandr --output foo --auto' to fix if this breaks things.\n");
fullscreenflags |= FULLSCREEN_XRANDR;
if (XRandR_ApplyMode())
@ -3639,6 +3645,7 @@ static qboolean XCursor_Init(void)
#else
static qboolean XCursor_Init(void)
{
return false;
}
#endif

View File

@ -835,45 +835,60 @@ void NPP_NQFlush(void)
break;
case svcfte_cgamepacket:
if (writedest != &sv.multicast)
if (sv_csqcdebug.ival || writedest != &sv.multicast)
{
Con_Printf(CON_WARNING"Warning: svc_cgamepacket used outside of a multicast\n");
if (sv.csqcdebug)
{
/*shift the data up by two bytes*/
memmove(buffer+3, buffer+1, bufferlen-1);
if (writedest != &sv.multicast)
Con_Printf(CON_WARNING"Warning: svc_cgamepacket used outside of a multicast\n");
/*shift the data up by two bytes*/
memmove(buffer+3, buffer+1, bufferlen-1);
/*add a length in the 2nd/3rd bytes*/
buffer[1] = (bufferlen-1);
buffer[2] = (bufferlen-1) >> 8;
buffer[0] = svcfte_cgamepacket_sized;
/*add a length in the 2nd/3rd bytes*/
buffer[1] = (bufferlen-1);
buffer[2] = (bufferlen-1) >> 8;
bufferlen += 2;
}
bufferlen += 2;
if(multicastpos) multicastpos += 2;
}
break;
case svc_temp_entity:
if (sv_csqcdebug.ival)
{
if (te_515sevilhackworkaround && writedest != &sv.multicast)
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
/*shift the data up by two bytes, but don't care about the first byte*/
memmove(buffer+3, buffer+1, bufferlen-1);
buffer[0] = svcfte_temp_entity_sized;
/*add a length in the 2nd/3rd bytes, if needed*/
buffer[1] = (bufferlen-1) & 0xff;
buffer[2] = ((bufferlen-1) >> 8);
if (te_515sevilhackworkaround) //we don't know how to translate it, so the qw receiver must be told to interpret as the nq version
buffer[2] |= 0x80;
bufferlen += 2;
if(multicastpos) multicastpos += 2;
break;
}
switch (buffer[1])
{
default:
if (te_515sevilhackworkaround)
{
if (writedest != &sv.multicast)
{
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
if (sv.csqcdebug)
{
/*shift the data up by two bytes, but don't care about the first byte*/
memmove(buffer+3, buffer+1, bufferlen-1);
/*shift the data up by two bytes, but don't care about the first byte*/
memmove(buffer+3, buffer+1, bufferlen-1);
/*add a length in the 2nd/3rd bytes, if needed*/
buffer[1] = (bufferlen-1) & 0xff;
buffer[2] = (bufferlen-1) >> 8;
buffer[0] = svcfte_temp_entity_sized;
/*add a length in the 2nd/3rd bytes, if needed*/
buffer[1] = (bufferlen-1) & 0xff;
buffer[2] = ((bufferlen-1) >> 8);
if (te_515sevilhackworkaround) //we don't know how to translate it, so the qw receiver must be told to interpret as the nq version
buffer[2] |= 0x80;
bufferlen += 2;
}
}
/*replace the svc itself*/
buffer[0] = svcfte_cgamepacket;
bufferlen += 2;
if(multicastpos) multicastpos += 2;
}
break;
case TENQ_NQEXPLOSION:
@ -1895,45 +1910,59 @@ void NPP_QWFlush(void)
break;
case svcfte_cgamepacket:
if (writedest != &sv.nqmulticast)
if (sv_csqcdebug.ival || writedest != &sv.nqmulticast)
{
Con_Printf(CON_WARNING"Warning: svc_cgamepacket used outside of a multicast\n");
if (sv.csqcdebug)
{
/*shift the data up by two bytes*/
memmove(buffer+3, buffer+1, bufferlen-1);
if (writedest != &sv.nqmulticast)
Con_Printf(CON_WARNING"Warning: svc_cgamepacket used outside of a multicast\n");
/*shift the data up by two bytes*/
memmove(buffer+3, buffer+1, bufferlen-1);
/*add a length in the 2nd/3rd bytes*/
buffer[1] = (bufferlen-1);
buffer[2] = (bufferlen-1) >> 8;
buffer[0] = svcfte_cgamepacket_sized;
/*add a length in the 2nd/3rd bytes*/
buffer[1] = (bufferlen-1);
buffer[2] = (bufferlen-1) >> 8;
bufferlen += 2;
}
bufferlen += 2;
if(multicastpos) multicastpos += 2;
}
break;
case svc_temp_entity:
if (sv_csqcdebug.ival)
{
if (te_515sevilhackworkaround && writedest != &sv.multicast)
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
/*shift the data up by two bytes, but don't care about the first byte*/
memmove(buffer+3, buffer+1, bufferlen-1);
buffer[0] = svcfte_temp_entity_sized;
/*add a length in the 2nd/3rd bytes, if needed*/
buffer[1] = (bufferlen-1) & 0xff;
buffer[2] = (bufferlen-1) >> 8;
if (!te_515sevilhackworkaround) //we translated it from qw, let the client know that its now the nq version
buffer[2] |= 0x80;
bufferlen += 2;
if(multicastpos) multicastpos += 2;
break;
}
switch(minortype)
{
default:
if (te_515sevilhackworkaround)
{
if (writedest != &sv.nqmulticast)
{
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
if (sv.csqcdebug)
{
/*shift the data up by two bytes*/
memmove(buffer+3, buffer+1, bufferlen-1);
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
/*shift the data up by two bytes*/
memmove(buffer+3, buffer+1, bufferlen-1);
/*add a length in the 2nd/3rd bytes*/
buffer[1] = (bufferlen-1);
buffer[2] = (bufferlen-1) >> 8;
buffer[0] = svcfte_temp_entity_sized;
/*add a length in the 2nd/3rd bytes*/
buffer[1] = (bufferlen-1);
buffer[2] = (bufferlen-1) >> 8;
if (!te_515sevilhackworkaround) //we translated it from qw, let the client know that its now the nq version
buffer[2] |= 0x80;
bufferlen += 2;
}
}
/*replace the svc itself*/
buffer[0] = svcfte_cgamepacket;
bufferlen += 2;
if(multicastpos) multicastpos += 2;
}
break;
case TEQW_LIGHTNINGBLOOD:
@ -2249,7 +2278,9 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
break;
default:
protocollen = sizeof(buffer);
Con_Printf("QWWriteByte: bad tempentity - %i\n", data);
if (writedest != &sv.nqmulticast)
Con_Printf("QWWriteByte: bad tempentity - %i\n", data);
te_515sevilhackworkaround = true;
break;
}
break;

File diff suppressed because it is too large Load Diff

View File

@ -243,7 +243,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(dimension_hit,"This is the bitmask of dimensions which the entity will be blocked by. If other.dimension_solid & self.dimension_hit, our traces will impact and not proceed. If its false, the traces will NOT impact, allowing self to pass straight through.")/*EXT_DIMENSION_PHYSICS*/\
/*comfieldfloat_legacy(hitcontentsmask,"Traces performed for this entity will impact against surfaces that match this contents mask.")*/ \
comfieldint(hitcontentsmaski,"Traces performed for this entity will impact against surfaces that match this contents mask (CONTENTBITS_* constants).")\
comfieldfloat_legacy(dphitcontentsmask, "Some crappy field that inefficiently requires translating to the native contents flags. Ditch the 'dp', do it properly.")\
comfieldfloatdep_legacy(dphitcontentsmask, "Some crappy field that inefficiently requires translating to the native contents flags. Ditch the 'dp', do it properly.", "Does not support mos-ecific contents.")\
comfieldfloat(scale,"Multiplier that resizes the entity. 1 is normal sized, 2 is double sized. scale 0 is remapped to 1. In SSQC, this is limited to 1/16th precision, with a maximum just shy of 16.")/*DP_ENT_SCALE*/\
comfieldfloat(fatness,"How many QuakeUnits to push the entity's verticies along their normals by.")/*FTE_PEXT_FATNESS*/\
comfieldfloat(alpha,"The transparency of the entity. 1 means opaque, 0.0001 means virtually invisible. 0 is remapped to 1, for compatibility.")/*DP_ENT_ALPHA*/\
@ -312,7 +312,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloatdep_legacy(Version,"Obsolete", "Use SendFlags instead.")/*EXT_CSQC (obsolete)*/\
comfieldfloatdep_legacy(clientcolors,NULL, "Doesn't support RGB player colours.")\
comfieldfloat_legacy(viewzoom,NULL)/*DP_VIEWZOOM, stats*/\
comfieldfloat_legacy(items2,NULL) /*added in quake 1.09 (for hipnotic). legacy because of stats*/\
comfieldfloat_legacy(items2,"stub. commented by default, to prevent items2 being networked instead of runes.") /*added in quake 1.09 (for hipnotic). legacy because of stats*/\
svextqcfieldshexen2 \
comfieldfloat(pvsflags,"Reconfigures when the entity is visible to clients")/*EXT_CSQC_1*/\
comfieldfloat(uniquespawnid,"Incremented by 1 whenever the entity is respawned. Persists across remove calls, for when the two-second grace period is insufficient.")/*FTE_ENT_UNIQUESPAWNID*/\

View File

@ -1462,6 +1462,25 @@ void SV_LoadPlayers(loadplayer_t *lp, size_t slots)
size_t clnum, p, p2;
int to[255];
//kick any splitscreen seats. they'll get re-added after load (filling slots like connecting players would)
for (clnum = 0; clnum < svs.allocated_client_slots; clnum++)
{
cl = &svs.clients[clnum];
cl->controlled = NULL; //kill the links.
if (cl->controller) //its a slave
{
//unlink it
cl->controller = NULL;
//make it into a pseudo-bot so the kicking doesn't do weird stuff.
cl->netchan.remote_address.type = NA_INVALID; //so the remaining client doesn't get the kick too.
cl->protocol = SCP_BAD; //make it a bit like a bot, so we don't try sending any datagrams/reliables at someone that isn't able to receive anything.
//okay, it can get lost now.
cl->drop = true;
}
}
//despawn any entity data, and try to find the loaded player to move them to
for (clnum = 0; clnum < svs.allocated_client_slots; clnum++) //clear the server for the level change.
{
@ -1578,8 +1597,10 @@ static void SV_GameLoaded(loadplayer_t *lp, size_t slots, const char *savename)
cl = &svs.clients[clnum];
cl->spawned = !!*lp[clnum].name;
if (cl->spawned)
{
sv.spawned_client_slots++;
Q_strncpyz(cl->namebuf, lp[clnum].name, sizeof(cl->namebuf));
}
cl->name = PR_AddString(svprogfuncs, cl->namebuf, sizeof(cl->namebuf), false);
cl->team = PR_AddString(svprogfuncs, cl->teambuf, sizeof(cl->teambuf), false);

View File

@ -110,7 +110,6 @@ typedef struct
server_state_t state; // precache commands are only valid during load
float gamespeed; //time progression multiplier, fixed per-level.
qboolean csqcdebug;
unsigned int csqcchecksum;
qboolean mapchangelocked;
qboolean restarting;
@ -1092,6 +1091,7 @@ void SV_Master_Shutdown(void);
void SV_Master_Heartbeat (void);
extern cvar_t pr_ssqc_progs;
extern cvar_t sv_csqcdebug;
extern cvar_t spawn;
extern cvar_t teamplay;
extern cvar_t deathmatch;

View File

@ -2120,7 +2120,7 @@ static void SV_Status_f (void)
Con_TPrintf("particles : %i/%i\n", count, MAX_SSPARTICLESPRE);
}
Con_TPrintf("gamedir : %s\n", FS_GetGamedir(true));
if (sv.csqcdebug)
if (sv_csqcdebug.ival)
Con_TPrintf("csqc debug : true\n");
#ifdef MVD_RECORDING
SV_Demo_PrintOutputs();

View File

@ -326,6 +326,9 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
csqcmsgbuffer.packing = msg->packing;
csqcmsgbuffer.prim = msg->prim;
if (sv_csqcdebug.ival)
svcnumber = svcfte_csqcentities_sized;
for (en = 0, entnum = 0; en < csqcnuments; en++, entnum++)
{
ent = csqcent[en];
@ -422,7 +425,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
MSG_WriteByte(msg, svcnumber);
}
SV_EmitDeltaEntIndex(msg, entnum, false, client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS);
if (sv.csqcdebug) //optional extra length prefix.
if (svcnumber == svcfte_csqcentities_sized) //optional extra length prefix.
{
if (!csqcmsgbuffer.cursize)
Con_Printf("Warning: empty csqc packet on %s\n", PR_GetString(svprogfuncs, ent->v->classname));

View File

@ -42,7 +42,6 @@ extern cvar_t skill;
extern cvar_t sv_cheats;
extern cvar_t sv_bigcoords;
extern cvar_t sv_gamespeed;
extern cvar_t sv_csqcdebug;
extern cvar_t sv_csqc_progname;
extern cvar_t sv_calcphs;
extern cvar_t sv_playerslots, maxclients, maxspectators;
@ -1103,12 +1102,6 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
InfoBuf_SetValueForStarKey(&svs.info, "*csprogssize", "");
InfoBuf_SetValueForStarKey(&svs.info, "*csprogsname", "");
}
sv.csqcdebug = sv_csqcdebug.value;
if (sv.csqcdebug)
InfoBuf_SetValueForStarKey(&svs.info, "*csqcdebug", "1");
else
InfoBuf_RemoveKey(&svs.info, "*csqcdebug");
#endif
if (svs.gametype == GT_PROGS)

View File

@ -214,6 +214,7 @@ vfsfile_t *sv_fraglogfile;
void SV_AcceptClient (netadr_t *adr, int userid, char *userinfo);
void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc);
void SV_DeDupeName(const char *val, client_t *cl, char *newname, size_t newnamesize);
int nextuserid;
@ -2183,7 +2184,8 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
int i, j;
int curclients;
qboolean loadgame;
const char *name;
// const char *name;
char newname[80];
unsigned int clients = 0, spectators = 0;
qboolean asspec;
@ -2233,12 +2235,12 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
}
*/
name = Info_ValueForKey(info, "name");
SV_DeDupeName(Info_ValueForKey(info, "name"), cl, newname, sizeof(newname));
for (i=0,cl=svs.clients ; i<sv.allocated_client_slots ; i++,cl++)
{
if (cl->state == cs_loadzombie && !controller->spectator)
{ //if this is a loadzombie with the same name as the new seat is trying to use then lets use that slot.
if (!strcmp(cl->name, name))
if (!strcmp(cl->name, newname))
break;
}
}
@ -2279,6 +2281,27 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
return NULL;
}
{ //save off anything we might want to preserve
qboolean tobeloaded = cl->istobeloaded;
qboolean spawned = cl->spawned;
unsigned int userid = cl->userid;
float spawn_parms[NUM_SPAWN_PARMS];
memcpy(spawn_parms, cl->spawn_parms, sizeof(spawn_parms));
//now actually wipe the player slot
memset(cl, 0, sizeof(*cl));
//and restore preserved stuff, if its appropriate.
if (loadgame)
{
cl->istobeloaded = tobeloaded;
cl->spawned = spawned;
cl->userid = userid;
memcpy(cl->spawn_parms, spawn_parms, sizeof(cl->spawn_parms));
}
}
cl->spectator = asspec;
cl->netchan.remote_address = controller->netchan.remote_address;
cl->netchan.message.prim = controller->netchan.message.prim;
@ -2601,6 +2624,7 @@ void SV_DoDirectConnect(svconnectinfo_t *fte_restrict info)
newcl = cl;
preserveparms = true;
temp.istobeloaded = cl->istobeloaded;
temp.spawned = cl->spawned;
memcpy(temp.spawn_parms, cl->spawn_parms, sizeof(temp.spawn_parms));
if (cl->userid)
temp.userid = cl->userid;
@ -5565,6 +5589,70 @@ void SV_FixupName(const char *in, char *out, unsigned int outlen)
p[1] = 0;
}
void SV_DeDupeName(const char *val, client_t *cl, char *newname, size_t newnamesize)
{
int i;
client_t *client;
int dupc = 1;
char basic[80];
const char *p;
if (!val)
val = "";
//we block large names here because a) they're unwieldly. b) they might cause players to be invisible to older clients/server browsers/etc.
//bots with no name skip the fixup, to avoid default names(they're expected to be given a name eventually, so are allowed to be invisible for now)
if (cl && cl->protocol == SCP_BAD && !*val)
newname[0] = 0;
else
{
SV_FixupName(val, newname, newnamesize);
if (strlen(newname) > 40)
newname[40] = 0;
}
//strip weirdness
deleetstring(basic, newname);
if (!cl || cl->protocol != SCP_BAD)
{ //don't bother validating bot names. The gamecode is expected to not be stupid.
if (!basic[0] || strstr(basic, "console"))
strcpy(newname, "unnamed");
// check to see if another user by the same name exists
while (1)
{
for (i=0, client = svs.clients ; i<svs.allocated_client_slots ; i++, client++)
{
if (client->state < cs_connected || client == cl)
continue;
if (!stricmp(client->name, newname))
break;
}
if (i != svs.allocated_client_slots)
{ // dup name
char tmpname[80];
if (strlen(newname) > sizeof(cl->namebuf) - 1)
newname[sizeof(cl->namebuf) - 4] = 0;
p = newname;
if (newname[0] == '(')
{
if (newname[2] == ')')
p = newname + 3;
else if (val[3] == ')')
p = newname + 4;
}
memcpy(tmpname, p, strlen(p)+1);
Q_snprintfz(newname, newnamesize, "(%d)%-.40s", dupc++, tmpname);
}
else
break;
}
}
}
qboolean ReloadRanking(client_t *cl, const char *newname)
{
@ -5631,10 +5719,7 @@ into a more C freindly form.
void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose)
{
const char *val, *p;
int i;
client_t *client;
int dupc = 1;
char newname[80], basic[80];
char newname[80];
#ifdef SVRANKING
extern cvar_t rank_filename;
#endif
@ -5658,58 +5743,10 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose)
// name for C code
val = InfoBuf_BlobForKey (&cl->userinfo, "name", &blobsize, &large);
if (!val)
if (large) //don't allow it if there's even anything weird in there (simplies the necessary qc).
val = "";
//we block large names here because a) they're unwieldly. b) they might cause players to be invisible to older clients/server browsers/etc.
//bots with no name skip the fixup, to avoid default names(they're expected to be given a name eventually, so are allowed to be invisible for now)
if (large || (cl->protocol == SCP_BAD && !*val))
newname[0] = 0;
else
{
SV_FixupName(val, newname, sizeof(newname));
if (strlen(newname) > 40)
newname[40] = 0;
}
deleetstring(basic, newname);
if (cl->protocol != SCP_BAD)
{ //don't bother validating bot names. The gamecode is expected to not be stupid.
if (!basic[0] || strstr(basic, "console"))
strcpy(newname, "unnamed");
// check to see if another user by the same name exists
while (1)
{
for (i=0, client = svs.clients ; i<svs.allocated_client_slots ; i++, client++)
{
if (client->state < cs_connected || client == cl)
continue;
if (!stricmp(client->name, newname))
break;
}
if (i != svs.allocated_client_slots)
{ // dup name
char tmpname[80];
if (strlen(newname) > sizeof(cl->namebuf) - 1)
newname[sizeof(cl->namebuf) - 4] = 0;
p = newname;
if (newname[0] == '(')
{
if (newname[2] == ')')
p = newname + 3;
else if (val[3] == ')')
p = newname + 4;
}
memcpy(tmpname, p, strlen(p)+1);
sprintf(newname, "(%d)%-.40s", dupc++, tmpname);
}
else
break;
}
}
//fixup and dedupe
SV_DeDupeName(val, cl, newname, sizeof(newname));
if (!cl->drop && strncmp(newname, cl->name, sizeof(cl->namebuf)-1))
{

View File

@ -2425,6 +2425,39 @@ int Dem_CountTeamPlayers (char *t)
return count;
}
//takes a quake-mark-up string (subject to com_parseutf and ^ etc) and spits out a usable utf-8 name
//in and out may overlap.
static char *FS_UTF8FromQuakeFilename(const char *in, qboolean dequake, qboolean keepmarkup, qboolean blockdirsep, char *out, size_t outsize)
{
conchar_t cline[8192], *c;
char *outend = out+outsize-1; //-1 for our null
unsigned int charflags, codepoint;
COM_ParseFunString(CON_WHITEMASK, in, cline, sizeof(cline), keepmarkup);
for (c = cline; *c; )
{
c = Font_Decode(c, &charflags, &codepoint);
if (charflags & CON_HIDDEN)
continue;
if (dequake)
codepoint = COM_DeQuake(codepoint);
if (codepoint == '/' && blockdirsep) codepoint = '-'; //spreading across multiple dirs is just awkward
else if (codepoint < ' ' ) codepoint = '-'; //C0 chars are all kinds of problematic
else if (codepoint == '\\') codepoint = '-'; //windows sucks. or string escapes do.
else if (codepoint == ':' ) codepoint = '-'; //drives, or Alternative Data Streams (read: often hidden)
else if (codepoint == '\"') codepoint = '-'; //erk! escapes necessitate escapes...
else if (codepoint == '<' ) codepoint = '-'; //pipe stuff sucks
else if (codepoint == '>' ) codepoint = '-'; //pipe stuff sucks
else if (codepoint == '|' ) codepoint = '-'; //pipe stuff sucks
else if (codepoint == '?' ) codepoint = '-'; //wildcards complicate things
else if (codepoint == '*' ) codepoint = '-'; //wildcards complicate things
out += utf8_encode(out, codepoint, outend-out);
}
*out = 0;
return out;
}
// <-
void SV_MVDEasyRecord_f (void)
@ -2454,10 +2487,8 @@ void SV_MVDEasyRecord_f (void)
if (c == 2)
{
char *c;
Q_strncpyz (name, Cmd_Argv(1), sizeof(name));
while((c = strchr(name, ':')))
*c = '-';
FS_UTF8FromQuakeFilename(name, true, false, false, name, sizeof(name));
}
else
{
@ -2493,6 +2524,9 @@ void SV_MVDEasyRecord_f (void)
snprintf (name, sizeof(name), "ffa_%s(%d)", svs.name, i);
}
}
//convert to utf-8, so its readable on most systems (we convert utf-8 to utf-16 for windows, while linux tends to just use utf-8 in the first place)
FS_UTF8FromQuakeFilename(name, true, false, true, name, sizeof(name));
}
// <-

View File

@ -275,7 +275,7 @@ void SV_New_f (void)
if (dpcompat_nopreparse.ival && progstype != PROG_QW)
{
SV_PrintToClient(host_client, PRINT_HIGH, "This server now has network preparsing disabled, and thus only supports NetQuake clients\n");
SV_PrintToClient(host_client, PRINT_HIGH, "This server has network preparsing disabled, and thus only supports NetQuake clients\n");
Con_Printf("%s was not using NQ protocols\n", host_client->name);
host_client->drop = true;
return;
@ -364,7 +364,6 @@ void SV_New_f (void)
#ifdef SVRANKING
split->stats_started = realtime;
#endif
splitnum++;
}
}
else
@ -533,7 +532,7 @@ void SVNQ_New_f (void)
if (dpcompat_nopreparse.ival && progstype == PROG_QW)
{
SV_PrintToClient(host_client, PRINT_HIGH, "This server now has network preparsing disabled, and thus only supports QuakeWorld clients\n");
SV_PrintToClient(host_client, PRINT_HIGH, "This server has network preparsing disabled, and thus only supports QuakeWorld clients\n");
Con_Printf("%s was not using QW protocols\n", host_client->name);
host_client->drop = true;
return;
@ -560,17 +559,25 @@ void SVNQ_New_f (void)
{
int id;
qboolean big; //used as a filter to exclude protocols that don't match our coord+angles mode
qboolean pextonly;
} preferedprot[] =
{
//favour fitz over dp's. this is on the assumption that we can use pext stuff when both are available.
{SCP_FITZ666, true, true}, //actually fte+999... shh...
{SCP_FITZ666, false, true}, //actually fte+666.
//next best is probably dp's stuff
{SCP_DARKPLACES7, true},
{SCP_DARKPLACES6, true},
//unextended fitz is kinda lame, but has some bells on it.
{SCP_FITZ666, true}, //actually 999... shh...
{SCP_FITZ666, false},
//well, we can still get bigger model/soundindexes out of this
{SCP_BJP3, false} //should we only use this when we have >255 models/sounds?
};
for (i = 0; i < countof(preferedprot); i++)
{
if (preferedprot[i].big == !!(protext1 & PEXT_FLOATCOORDS))
if (!preferedprot[i].pextonly || (protext2&PEXT2_REPLACEMENTDELTAS))
{
if (host_client->supportedprotocols & (1u<<preferedprot[i].id))
{
@ -1073,19 +1080,13 @@ void SV_SendClientPrespawnInfo(client_t *client)
{
static const char *prioritykeys[] = {"*", "fpd", "teamplay", "deathmatch", "maxfps", NULL}; //make sure these are in there.
static const char *ignorekeys[] = {"mapname"/*here for q3, useless for qw*/, NULL};
if (!ISNQCLIENT(client) || (client->fteprotocolextensions2 & PEXT2_PREDINFO))
if (!ISNQCLIENT(client) || (client->fteprotocolextensions & PEXT_CSQC) || (client->fteprotocolextensions2 & PEXT2_PREDINFO))
{ //nq does not normally get serverinfo sent to it.
i = InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), prioritykeys, ignorekeys, NULL, &client->infosync, &svs.info);
Info_SetValueForStarKey(buffer, "*z_ext", va("%i", client->zquake_extensions), sizeof(buffer)); //should already be in there, so this should only ever make it shorter.
ClientReliableWrite_Begin(client, svc_stufftext, 20 + i);
ClientReliableWrite_String (client, va("fullserverinfo \"%s\"\n", buffer) );
}
else if (sv.csqcdebug)
{
i = InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), prioritykeys, ignorekeys, NULL, &client->infosync, &svs.info);
ClientReliableWrite_Begin(client, svc_stufftext, 22 + i);
ClientReliableWrite_String (client, va("//fullserverinfo \"%s\"\n", buffer) );
}
}
else if (client->prespawn_idx == 3)
{

View File

@ -2511,7 +2511,7 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip)
else
{
trace.ent = w->edicts; //misreport world
clip->trace.entnum = touch->number; //with an ssqc ent number
trace.entnum = touch->number; //with an ssqc ent number
}
clip->trace = trace;
}

View File

@ -1119,8 +1119,8 @@ void VK_Draw_Init(void)
void VK_Draw_Shutdown(void)
{
R2D_Shutdown();
Image_Shutdown();
Shader_Shutdown();
Image_Shutdown();
}
void VK_CreateSampler(unsigned int flags, vk_image_t *img)
@ -2094,6 +2094,8 @@ void VK_R_DeInit (void)
VK_Shutdown_PostProc();
VK_DestroySwapChain();
VKBE_Shutdown();
R2D_Shutdown();
Shader_Shutdown();
Image_Shutdown();
}