sdl2 support.

hacky rendertarget stuff. not polished. don't use except for testing. feedback desired.
switched file system to use a qofs_t type instead. define FS_64BIT to make it 64bit (standard on 64bit cpus).
rewrote zip support, ditching unzip.c. this provided zip64 support, and unicode in zips.
changed local address enumeration to not be so stupid.
updated ode support a little to match some dp features.
changed fs_cache scheme, to not rebuild needlessly.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4596 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-02-07 08:38:40 +00:00
parent b9e46e4fa6
commit 1bb752b582
116 changed files with 3885 additions and 5423 deletions

View file

@ -1290,8 +1290,6 @@ void NPP_NQWriteAngle(int dest, float in) //replacement write func (nq to qw)
}
void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
{
short datas = (int)(in*8);
float dataf = in;
NPP_NQCheckDest(dest);
if (!bufferlen)
Con_Printf("NQWriteCoord: Messages should start with WriteByte\n");
@ -1323,11 +1321,15 @@ void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
if (destprim->coordsize==4)
{
float dataf = in;
dataf = LittleFloat(dataf);
NPP_AddData(&dataf, sizeof(float));
}
else
{
short datas = (int)(in*8);
datas = LittleShort(datas);
NPP_AddData(&datas, sizeof(short));
}

View file

@ -9352,6 +9352,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"hash_getkey", PF_hash_getkey, 0, 0, 0, 292, D("string(float table, float idx)", "gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all.")},
{"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(float table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys.")},
{"checkcommand", PF_checkcommand, 0, 0, 0, 294, D("float(string name)", "Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist.")},
{"argescape", PF_argescape, 0, 0, 0, 295, D("string(string s)", "Marks up a string so that it can be reliably tokenized as a single argument later.")},
{"clearscene", PF_Fixme, 0, 0, 0, 300, D("void()", "Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values.")},// (EXT_CSQC)
@ -9675,9 +9676,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
// {"bufstr_find", PF_Fixme, 0, 0, 0, 537, "float(float bufhandle, string match, float matchrule, float startpos)"},
// {"matchpattern", PF_Fixme, 0, 0, 0, 538, "float(string s, string pattern, float matchrule)"},
// {"undefined", PF_Fixme, 0, 0, 0, 539, ""},
{"physics_enable", PF_Ignore, 0, 0, 0, 540, "void(entity e, float physics_enabled)" STUB},
{"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB},
{"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB},
{"physics_enable", PF_physics_enable, 0, 0, 0, 540, D("void(entity e, float physics_enabled)", "Enable or disable the physics attached to a MOVETYPE_PHYSICS entity. Entities which have been disabled in this way will stop taking so much cpu time.")},
{"physics_addforce",PF_physics_addforce,0, 0, 0, 541, D("void(entity e, vector force, vector relative_ofs)", "Apply some impulse directional force upon a MOVETYPE_PHYSICS entity.")},
{"physics_addtorque",PF_physics_addtorque,0, 0, 0, 542, D("void(entity e, vector torque)", "Apply some impulse rotational force upon a MOVETYPE_PHYSICS entity.")},
{"setkeydest", PF_Fixme, 0, 0, 0, 601, "void(float dest)"},
{"getkeydest", PF_Fixme, 0, 0, 0, 602, "float()"},
@ -10529,6 +10531,11 @@ void PR_DumpPlatform_f(void)
{"VF_SCREENPSIZE", "const float", CS, "Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect).", VF_SCREENPSIZE},
{"VF_VIEWENTITY", "const float", CS, "Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too.", VF_VIEWENTITY},
{"VF_RT_DESTCOLOUR", "const float", CS, "The FrameBuffer texture index to write colour info into. 1-based. Additional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy. Written to by both 3d and 2d rendering.", VF_RT_DESTCOLOUR},
{"VF_RT_SOURCECOLOUR", "const float", CS, "The FrameBuffer texture index to use with shaders that specify a $sourcecolour map.", VF_RT_SOURCECOLOUR},
{"VF_RT_DEPTH", "const float", CS, "The FrameBuffer texture index to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16=4,24=5,32=6), sizexy.", VF_RT_DEPTH},
{"VF_RT_RIPPLE", "const float", CS, "The FrameBuffer texture index to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy.", VF_RT_RIPPLE},
{"RF_VIEWMODEL", "const float", CS, "Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob.", CSQCRF_VIEWMODEL},
{"RF_EXTERNALMODEL", "const float", CS, "Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible.", CSQCRF_EXTERNALMODEL},
{"RF_DEPTHHACK", "const float", CS, "Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls.", CSQCRF_DEPTHHACK},

View file

@ -207,6 +207,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldvector(gravitydir,NULL)\
comfieldfunction(camera_transform,".vector(vector org, vector ang)", NULL)\
comfieldfloat(pmove_flags,NULL)/*EXT_CSQC_1*/\
comfieldfloat(geomtype,NULL)/*DP_...PHYSICS*/\
comfieldfloat(friction,NULL)/*DP_...PHYSICS*/\
comfieldfloat(erp,NULL)/*DP_...PHYSICS*/\
comfieldfloat(jointtype,NULL)/*DP_...PHYSICS*/\
@ -240,21 +241,21 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldvector(color,NULL)/*Hexen2 has a .float color, the warnings should be benign*/ \
comfieldfloat(light_lev,NULL)\
comfieldfloat(style,NULL)\
comfieldfloat(pflags,NULL)\
comfieldfloat(pflags,"Realtime lighting flags")\
comfieldfloat(clientcolors,NULL)\
comfieldfloat(dimension_see,NULL)/*EXT_DIMENSION_VISIBLE*/\
comfieldfloat(dimension_seen,NULL)/*EXT_DIMENSION_VISIBLE*/\
comfieldfloat(dimension_ghost,NULL)/*EXT_DIMENSION_GHOST*/\
comfieldfloat(dimension_ghost_alpha,NULL)/*EXT_DIMENSION_GHOST*/\
comfieldfloat(dimension_see,"This is the dimension mask (bitfield) that the client is allowed to see. Entities and events not in this dimension mask will be invisible.")/*EXT_DIMENSION_VISIBLE*/\
comfieldfloat(dimension_seen,"This is the dimension mask (bitfield) that the client is visible within. Clients that cannot see this dimension mask will not see this entity.")/*EXT_DIMENSION_VISIBLE*/\
comfieldfloat(dimension_ghost,"If this entity is visible only within these dimensions, it will become transparent, as if a ghost.")/*EXT_DIMENSION_GHOST*/\
comfieldfloat(dimension_ghost_alpha,"If this entity is subject to dimension_ghost, this is the scaler for its alpha value. If 0, 0.5 will be used instead.")/*EXT_DIMENSION_GHOST*/\
comfieldfloat(playerclass,NULL)/*hexen2 requirements*/\
comfieldfloat(drawflags,NULL)/*hexen2*/\
comfieldfloat(hasted,NULL)/*hexen2 uses this AS WELL as maxspeed*/\
comfieldfloat(light_level,NULL)/*hexen2's grabbing light level from client*/\
comfieldfloat(abslight,NULL)/*hexen2's force a lightlevel*/\
comfieldfloat(abslight,"Allows overriding light levels. Use drawflags to state that this field should actually be used.")/*hexen2's force a lightlevel*/\
comfieldfunction(SendEntity, ".float(entity playerent, float changedflags)",NULL)/*EXT_CSQC*/\
comfieldfloat(SendFlags,NULL)/*EXT_CSQC_1 (one of the DP guys came up with it)*/\
comfieldfloat(Version,NULL)/*EXT_CSQC (obsolete)*/\
comfieldfloat(pvsflags,NULL)/*EXT_CSQC_1*/\
comfieldfloat(Version,"Obsolete")/*EXT_CSQC (obsolete)*/\
comfieldfloat(pvsflags,"Reconfigures when the entity is visible to clients")/*EXT_CSQC_1*/\
comfieldfloat(modelflags,NULL)\
comfieldfloat(uniquespawnid,NULL)/*FTE_ENT_UNIQUESPAWNID*/\
comfieldfunction(customizeentityforclient, ".float()",NULL)
@ -379,7 +380,7 @@ typedef struct
int orientpeer;
//ode info
int shape;
int geomshape;
vec3_t dimensions;
float mass;
} odebodyinfo_t;
@ -411,6 +412,21 @@ typedef struct
vec3_t axis, axis2;
} odejointinfo_t;
typedef struct odecommandqueue_s
{
struct odecommandqueue_s *next;
enum
{
ODECMD_ENABLE,
ODECMD_DISABLE,
ODECMD_FORCE,
ODECMD_TORQUE,
} command;
struct wedict_s *edict;
vec3_t v1;
vec3_t v2;
} odecommandqueue_t;
typedef struct
{
// physics parameters
@ -469,5 +485,7 @@ typedef struct
// max velocity for a 1-unit radius object at current step to prevent
// missed collisions
vec_t ode_movelimit;
odecommandqueue_t *cmdqueuehead;
odecommandqueue_t *cmdqueuetail;
} worldode_t;
#endif

View file

@ -834,7 +834,7 @@ typedef struct
#define SOLID_BSP 4 // bsp clip, touch on edge, block
#define SOLID_PHASEH2 5
#define SOLID_CORPSE 5
#define SOLID_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER
#define SOLID_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER. deprecated. use solid_bsp and skin=-16
#define DAMAGE_NO 0
#define DAMAGE_YES 1
@ -1266,7 +1266,11 @@ void SV_ConSay_f(void);
//this header gives supported version numbers and stuff
typedef struct mvdpendingdest_s {
qboolean error; //disables writers, quit ASAP.
#ifdef _WIN32
qintptr_t socket;
#else
int socket;
#endif
char inbuffer[2048];
char outbuffer[2048];

View file

@ -374,7 +374,7 @@ void SV_Give_f (void)
}
}
int QDECL ShowMapList (const char *name, int flags, void *parm, searchpathfuncs_t *spath)
int QDECL ShowMapList (const char *name, qofs_t flags, void *parm, searchpathfuncs_t *spath)
{
if (name[5] == 'b' && name[6] == '_') //skip box models
return true;
@ -630,10 +630,13 @@ void SV_Map_f (void)
for (i=0, host_client = svs.clients ; i<svs.allocated_client_slots ; i++, host_client++)
{
/*pass the new map's name as an extension, so appropriate loading screens can be shown*/
if (ISNQCLIENT(host_client))
SV_StuffcmdToClient(host_client, va("reconnect \"%s\"\n", level));
else
SV_StuffcmdToClient(host_client, va("changing \"%s\"\n", level));
if (host_client->controller == NULL)
{
if (ISNQCLIENT(host_client))
SV_StuffcmdToClient(host_client, va("reconnect \"%s\"\n", level));
else
SV_StuffcmdToClient(host_client, va("changing \"%s\"\n", level));
}
host_client->prespawn_stage = PRESPAWN_INVALID;
host_client->prespawn_idx = 0;
}
@ -1711,6 +1714,9 @@ void SV_SendServerInfoChange(char *key, const char *value)
FOREACHCLIENT(i, cl)
{
if (cl->controller)
continue;
if (ISQWCLIENT(cl))
{
ClientReliableWrite_Begin(cl, svc_serverinfo, strlen(key) + strlen(value)+3);

View file

@ -29,6 +29,17 @@ extern cvar_t sv_cullentities_trace;
extern cvar_t sv_cullplayers_trace;
extern cvar_t sv_nopvs;
#define SV_PVS_CAMERAS 16
typedef struct
{
int numents;
edict_t *ent[SV_PVS_CAMERAS]; //ents in this list are always sent, even if the server thinks that they are invisible.
vec3_t org[SV_PVS_CAMERAS];
qbyte pvs[(MAX_MAP_LEAFS+7)>>3];
} pvscamera_t;
/*
=============================================================================
@ -917,13 +928,13 @@ static void SVFTE_WriteUpdate(unsigned int bits, entity_state_t *state, sizebuf_
if (bits & 0x0000ff00)
bits |= UF_EXTEND1;
MSG_WriteByte(msg, bits>>0);
MSG_WriteByte(msg, (bits>>0) & 0xff);
if (bits & UF_EXTEND1)
MSG_WriteByte(msg, bits>>8);
MSG_WriteByte(msg, (bits>>8) & 0xff);
if (bits & UF_EXTEND2)
MSG_WriteByte(msg, bits>>16);
MSG_WriteByte(msg, (bits>>16) & 0xff);
if (bits & UF_EXTEND3)
MSG_WriteByte(msg, bits>>24);
MSG_WriteByte(msg, (bits>>24) & 0xff);
if (bits & UF_FRAME)
{
@ -1148,7 +1159,10 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
client->sentents.max_entities = j;
}
while(j > client->sentents.num_entities)
client->pendingentbits[client->sentents.num_entities++] = UF_RESET|UF_RESET2;
{
client->sentents.entities[client->sentents.num_entities].number = 0;
client->sentents.num_entities++;
}
}
/*figure out the entitys+bits that changed (removed and active)*/
@ -1986,32 +2000,37 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
#endif
qboolean Cull_Traceline(edict_t *viewer, edict_t *seen)
qboolean Cull_Traceline(pvscamera_t *cameras, edict_t *seen)
{
int i;
trace_t tr;
vec3_t start;
vec3_t end;
int c;
if (seen->v->solid == SOLID_BSP)
return false; //bsp ents are never culled this way
//stage 1: check against their origin
VectorAdd(viewer->v->origin, viewer->v->view_ofs, start);
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, start, seen->v->origin, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
return false; //wasn't blocked
for (c = 0; c < cameras->numents; c++)
{
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], seen->v->origin, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
return false; //wasn't blocked
}
//stage 2: check against their bbox
for (i = 0; i < 8; i++)
for (c = 0; c < cameras->numents; c++)
{
end[0] = seen->v->origin[0] + ((i&1)?seen->v->mins[0]:seen->v->maxs[0]);
end[1] = seen->v->origin[1] + ((i&2)?seen->v->mins[1]:seen->v->maxs[1]);
end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]);
for (i = 0; i < 8; i++)
{
end[0] = seen->v->origin[0] + ((i&1)?seen->v->mins[0]:seen->v->maxs[0]);
end[1] = seen->v->origin[1] + ((i&2)?seen->v->mins[1]:seen->v->maxs[1]);
end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]);
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, start, end, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
return false; //this trace went through, so don't cull
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, cameras->org[c], end, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
return false; //this trace went through, so don't cull
}
}
return true;
@ -2109,7 +2128,7 @@ SV_WritePlayersToClient
=============
*/
void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *clent, qbyte *pvs, sizebuf_t *msg)
void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *clent, pvscamera_t *cameras, sizebuf_t *msg)
{
qboolean isbot;
int j;
@ -2304,13 +2323,13 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
continue;
// ignore if not touching a PV leaf
if (pvs && !sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &ent->pvsinfo, pvs))
if (cameras && !sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &ent->pvsinfo, cameras->pvs))
continue;
if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost)))
continue; //not in this dimension - sorry...
if (sv_cullplayers_trace.value || sv_cullentities_trace.value)
if (Cull_Traceline(clent, ent))
if (cameras && (sv_cullplayers_trace.value || sv_cullentities_trace.value))
if (Cull_Traceline(cameras, ent))
continue;
}
@ -2951,12 +2970,10 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
}
if (state->effects & DPEF_LOWPRECISION)
state->effects &= DPEF_LOWPRECISION; //we don't support it, nor does dp any more. strip it.
state->effects &= ~DPEF_LOWPRECISION; //we don't support it, nor does dp any more. strip it.
if (state->effects & EF_FULLBRIGHT) //wrap the field for fte clients (this is horrible)
{
state->hexen2flags |= MLS_FULLBRIGHT;
}
if (progstype != PROG_QW && state->effects && client && ISQWCLIENT(client)) //don't send extra nq effects to a qw client.
{
@ -3046,11 +3063,11 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
#pragma warningmsg("TODO: Fix attachments for more vanilla clients")
}
void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, edict_t *clent, qboolean ignorepvs)
void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t *cameras, edict_t *clent)
{
//pvs and clent can be null, but only if the other is also null
int e, i;
edict_t *ent, *trackent, *tracecullent;
edict_t *ent, *tracecullent; //tracecullent is different from ent because attached models cull the parent instead. also, null for entities which are not culled.
entity_state_t *state;
#define DEPTHOPTIMISE
#ifdef DEPTHOPTIMISE
@ -3061,22 +3078,11 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
int pvsflags;
int limit;
int c, maxc = cameras?cameras->numents:0;
if (client->spectator)
trackent = EDICT_NUM(svprogfuncs, client->spec_track);
else if (clent)
trackent = PROG_TO_EDICT(svprogfuncs, clent->xv->view2);
else
trackent = NULL;
if (client->viewent
#ifdef NQPROT
&& ISQWCLIENT(client)
#endif
) //this entity is watching from outside themselves. The client is tricked into thinking that they themselves are in the view ent, and a new dummy ent (the old them) must be spawned.
//this entity is watching from outside themselves. The client is tricked into thinking that they themselves are in the view ent, and a new dummy ent (the old them) must be spawned.
if (client->viewent && ISQWCLIENT(client))
{
//FIXME: this hack needs cleaning up
#ifdef DEPTHOPTIMISE
distances[0] = 0;
@ -3153,21 +3159,26 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
}
pvsflags = ent->xv->pvsflags;
if (ent->xv->viewmodelforclient)
for (c = 0; c < maxc; c++)
{
if (ent == cameras->ent[c])
break;
}
if (c < maxc)
tracecullent = NULL;
else if (ent->xv->viewmodelforclient)
{
if (ent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0))
continue;
tracecullent = NULL;
}
else if (ent == clent || ent == trackent)
tracecullent = NULL;
else
{
// ignore ents without visible models
if (!ent->xv->SendEntity && (!ent->v->modelindex || !*PR_GetString(svprogfuncs, ent->v->model)) && !((int)ent->xv->pflags & PFLAGS_FULLDYNAMIC) && ent->v->skin >= 0)
continue;
if (pvs) //self doesn't get a pvs test, to cover teleporters
if (cameras) //self doesn't get a pvs test, to cover teleporters
{
if ((int)ent->v->effects & EF_NODEPTHTEST)
tracecullent = NULL;
@ -3193,13 +3204,13 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
}
else
{
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)tracecullent)->pvsinfo, pvs))
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)tracecullent)->pvsinfo, cameras->pvs))
continue;
}
}
else
{
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)ent)->pvsinfo, pvs))
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)ent)->pvsinfo, cameras->pvs))
continue;
tracecullent = ent;
}
@ -3255,10 +3266,10 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
continue; //not in this dimension - sorry...
if (!ignorepvs && ent != clent && tracecullent && !((unsigned int)ent->v->effects & (EF_DIMLIGHT|EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_BRIGHTFIELD|EF_NODEPTHTEST)))
if (cameras && tracecullent && !((unsigned int)ent->v->effects & (EF_DIMLIGHT|EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_BRIGHTFIELD|EF_NODEPTHTEST)))
{ //more expensive culling
if ((e <= sv.allocated_client_slots && sv_cullplayers_trace.value) || sv_cullentities_trace.value)
if (Cull_Traceline(clent, tracecullent))
if (Cull_Traceline(cameras, tracecullent))
continue;
}
@ -3339,36 +3350,49 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
}
}
qbyte *SV_Snapshot_SetupPVS(client_t *client, qbyte *pvs, unsigned int pvsbufsize)
void SV_AddCameraEntity(pvscamera_t *cameras, edict_t *ent, vec3_t viewofs)
{
int i;
vec3_t org;
int leavepvs = false;
/*
if (r_novis.ival)
for (i = 0; i < cameras->numents; i++)
{
memset(pvs, 0xff, (sv.world.worldmodel->numleafs+31)>>3);
return pvs;
if (cameras->ent[i] == ent)
return; //don't add the same ent multiple times (.view2 or portals that can see themselves through other portals).
}
*/
if (viewofs)
VectorAdd (ent->v->origin, viewofs, org);
else
VectorCopy (ent->v->origin, org);
sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, cameras->pvs, sizeof(cameras->pvs), cameras->numents!=0);
if (cameras->numents < SV_PVS_CAMERAS)
{
cameras->ent[cameras->numents] = ent;
VectorCopy(org, cameras->org[cameras->numents]);
cameras->numents++;
}
}
void SV_Snapshot_SetupPVS(client_t *client, pvscamera_t *camera)
{
camera->numents = 0;
for (; client; client = client->controlled)
{
if (client->viewent)
{
edict_t *e = PROG_TO_EDICT(svprogfuncs, client->viewent);
VectorAdd (e->v->origin, client->edict->v->view_ofs, org);
}
if (client->viewent) //svc_viewentity hack
SV_AddCameraEntity(camera, EDICT_NUM(svprogfuncs, client->viewent), client->edict->v->view_ofs);
else
VectorAdd (client->edict->v->origin, client->edict->v->view_ofs, org);
sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, pvs, pvsbufsize, leavepvs);
leavepvs = true;
SV_AddCameraEntity(camera, client->edict, client->edict->v->view_ofs);
#ifdef PEXT_VIEW2
if (client->edict->xv->view2) //add a second view point to the pvs
sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, PROG_TO_EDICT(svprogfuncs, client->edict->xv->view2)->v->origin, pvs, pvsbufsize, leavepvs);
#endif
//spectators should always see their targetted player
if (client->spec_track)
SV_AddCameraEntity(camera, EDICT_NUM(svprogfuncs, client->spec_track), client->edict->v->view_ofs);
//view2 support should always see the extra entity
if (client->edict->xv->view2)
SV_AddCameraEntity(camera, PROG_TO_EDICT(svprogfuncs, client->edict->xv->view2), NULL);
}
return pvs;
}
void SV_Snapshot_Clear(packet_entities_t *pack)
@ -3388,11 +3412,10 @@ Builds a temporary q1 style entity packet for a q3 client
*/
void SVQ3Q1_BuildEntityPacket(client_t *client, packet_entities_t *pack)
{
qbyte pvsbuf[(MAX_MAP_LEAFS+7)>>3];
qbyte *pvs;
pvscamera_t cameras;
SV_Snapshot_Clear(pack);
pvs = SV_Snapshot_SetupPVS(client, pvsbuf, sizeof(pvsbuf));
SV_Snapshot_BuildQ1(client, pack, pvs, client->edict, false);
SV_Snapshot_SetupPVS(client, &cameras);
SV_Snapshot_BuildQ1(client, pack, &cameras, client->edict);
}
/*
@ -3408,11 +3431,10 @@ svc_playerinfo messages
void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignorepvs)
{
int e;
qbyte *pvs;
packet_entities_t *pack;
edict_t *clent;
client_frame_t *frame;
qbyte pvsbuffer[(MAX_MAP_LEAFS+7)/8];
pvscamera_t camerasbuf, *cameras = &camerasbuf;
// this is the frame we are creating
frame = &client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK];
@ -3421,21 +3443,21 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
// find the client's PVS
if (ignorepvs)
{
{ //mvd...
clent = NULL;
pvs = NULL;
cameras = NULL;
}
else
{
clent = client->edict;
if (sv_nopvs.ival)
pvs = NULL;
cameras = NULL;
#ifdef HLSERVER
else if (svs.gametype == GT_HALFLIFE)
pvs = SVHL_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer));
#endif
else
pvs = SV_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer));
SV_Snapshot_SetupPVS(client, cameras);
}
host_client = client;
@ -3468,7 +3490,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
SVHL_Snapshot_Build(client, pack, pvs, clent, ignorepvs);
else
#endif
SV_Snapshot_BuildQ1(client, pack, pvs, clent, ignorepvs);
SV_Snapshot_BuildQ1(client, pack, cameras, clent);
}
#ifdef NQPROT
@ -3534,7 +3556,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
if (client == &demo.recorder)
SV_WritePlayersToMVD(client, frame, msg);
else
SV_WritePlayersToClient (client, frame, clent, pvs, msg);
SV_WritePlayersToClient (client, frame, clent, cameras, msg);
}
SVQW_EmitPacketEntities (client, pack, msg);

View file

@ -951,13 +951,17 @@ void SV_FullClientUpdate (client_t *client, client_t *to)
if (ISQWCLIENT(to))
{
int ping = SV_CalcPing (client, false);
if (ping > 0xffff)
ping = 0xffff;
ClientReliableWrite_Begin(to, svc_updatefrags, 4);
ClientReliableWrite_Byte (to, i);
ClientReliableWrite_Short(to, client->old_frags);
ClientReliableWrite_Begin (to, svc_updateping, 4);
ClientReliableWrite_Byte (to, i);
ClientReliableWrite_Short (to, SV_CalcPing (client, false));
ClientReliableWrite_Short (to, ping);
ClientReliableWrite_Begin (to, svc_updatepl, 3);
ClientReliableWrite_Byte (to, i);
@ -3817,6 +3821,7 @@ void SV_GetConsoleCommands (void)
cmd = Sys_ConsoleInput ();
if (!cmd)
break;
Log_String(LOG_CONSOLE, cmd);
Cbuf_AddText (cmd, RESTRICT_LOCAL);
}
}

View file

@ -30,7 +30,7 @@ typedef struct svm_server_s {
} svm_server_t;
typedef struct {
int socketudp;
SOCKET socketudp;
float time;
int port;
@ -151,7 +151,7 @@ void SVM_Think(int port)
net_message.cursize = recvfrom(svm.socketudp, net_message_buffer, sizeof(net_message_buffer)-1, 0, (struct sockaddr *)&addr, &addrlen);
if (net_message.cursize <= 0)
{
addrlen = qerrno;
addrlen = neterrno();
return;

View file

@ -152,8 +152,8 @@ void DestFlush(qboolean compleate)
else
{ //error of some kind. would block or something
int e;
e = qerrno;
if (e != EWOULDBLOCK)
e = neterrno();
if (e != NET_EWOULDBLOCK)
d->error = true;
}
}
@ -229,8 +229,8 @@ void SV_MVD_RunPendingConnections(void)
else
{ //error of some kind. would block or something
int e;
e = qerrno;
if (e != EWOULDBLOCK)
e = neterrno();
if (e != NET_EWOULDBLOCK)
p->error = true;
}
}
@ -550,9 +550,8 @@ void SV_MVD_RunPendingConnections(void)
p->error = true;
else
{ //error of some kind. would block or something
int e;
e = qerrno;
if (e != EWOULDBLOCK)
int e = neterrno();
if (e != NET_EWOULDBLOCK)
p->error = true;
}
}
@ -683,7 +682,7 @@ typedef struct
#define SORT_NO 0
#define SORT_BY_DATE 1
int QDECL Sys_listdirFound(const char *fname, int fsize, void *uptr, searchpathfuncs_t *spath)
int QDECL Sys_listdirFound(const char *fname, qofs_t fsize, void *uptr, searchpathfuncs_t *spath)
{
file_t *f;
dir_t *dir = uptr;
@ -2107,20 +2106,20 @@ void SV_MVD_QTVReverse_f (void)
if ((sock = socket (adrfam, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
Con_Printf ("qtvreverse: socket: %s\n", strerror(qerrno));
Con_Printf ("qtvreverse: socket: %s\n", strerror(neterrno()));
return;
}
if (connect(sock, (void*)&remote, adrsz) == INVALID_SOCKET)
{
closesocket(sock);
Con_Printf ("qtvreverse: connect: %s\n", strerror(qerrno));
Con_Printf ("qtvreverse: connect: %s\n", strerror(neterrno()));
return;
}
if (ioctlsocket (sock, FIONBIO, (u_long *)&nonblocking) == INVALID_SOCKET)
{
closesocket(sock);
Con_Printf ("qtvreverse: ioctl FIONBIO: %s\n", strerror(qerrno));
Con_Printf ("qtvreverse: ioctl FIONBIO: %s\n", strerror(neterrno()));
return;
}
@ -2130,7 +2129,7 @@ void SV_MVD_QTVReverse_f (void)
if (send(sock, data, strlen(data), 0) == INVALID_SOCKET)
{
closesocket(sock);
Con_Printf ("qtvreverse: send: %s\n", strerror(qerrno));
Con_Printf ("qtvreverse: send: %s\n", strerror(neterrno()));
return;
}
@ -2366,9 +2365,9 @@ void SV_MVDEasyRecord_f (void)
}
#ifdef HAVE_TCP
static int MVD_StreamStartListening(int port)
static SOCKET MVD_StreamStartListening(int port)
{
int sock;
SOCKET sock;
struct sockaddr_in address;
// int fromlen;
@ -2383,12 +2382,12 @@ static int MVD_StreamStartListening(int port)
if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
Sys_Error ("MVD_StreamStartListening: socket: %s", strerror(qerrno));
Sys_Error ("MVD_StreamStartListening: socket: %s", strerror(neterrno()));
}
if (ioctlsocket (sock, FIONBIO, (u_long *)&nonblocking) == INVALID_SOCKET)
{
Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));
Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
}
if( bind (sock, (void *)&address, sizeof(address)) == INVALID_SOCKET)
@ -2406,7 +2405,7 @@ static int MVD_StreamStartListening(int port)
void SV_MVDStream_Poll(void)
{
#ifdef HAVE_TCP
static int listensocket=INVALID_SOCKET;
static SOCKET listensocket=INVALID_SOCKET;
static int listenport;
int _true = true;

View file

@ -60,6 +60,8 @@ void SV_FlushRedirect (void)
if (!*outputbuf)
return;
Log_String(LOG_CONSOLE, va("{\n%s}\n", outputbuf));
if (sv_redirected == RD_PACKET)
{
send[0] = 0xff;
@ -111,6 +113,8 @@ SV_BeginRedirect
*/
void SV_BeginRedirect (redirect_t rd, int lang)
{
SV_FlushRedirect();
sv_redirected = rd;
sv_redirectedlang = lang;
outputbuf[0] = 0;
@ -234,6 +238,9 @@ EVENT MESSAGES
//Directly print to a client without translating nor printing into an mvd. generally for error messages due to the lack of mvd thing.
void SV_PrintToClient(client_t *cl, int level, const char *string)
{
if (cl->controller)
cl = cl->controller;
switch (cl->protocol)
{
case SCP_BAD: //bot
@ -385,7 +392,9 @@ void VARGS SV_BroadcastPrintf (int level, char *fmt, ...)
if(strlen(string) >= sizeof(string))
Sys_Error("SV_BroadcastPrintf: Buffer stomped\n");
Sys_Printf ("%s", string); // print to the console
//pretend to print on the server, but not to the client's console
Sys_Printf ("%s", string); // print to the system console
Log_String(LOG_CONSOLE, string); //dump into log
for (i=0, cl = svs.clients ; i<svs.allocated_client_slots ; i++, cl++)
{
@ -428,7 +437,9 @@ void VARGS SV_BroadcastTPrintf (int level, translation_t stringnum, ...)
if(strlen(string) >= sizeof(string))
Sys_Error("SV_BroadcastPrintf: Buffer stomped\n");
//pretend to print on the server, but not to the client's console
Sys_Printf ("%s", string); // print to the console
Log_String(LOG_CONSOLE, string); //dump into log
for (i=0, cl = svs.clients ; i<svs.allocated_client_slots ; i++, cl++)
{

View file

@ -465,59 +465,59 @@ static int do_stdin = 1;
#if 1
char *Sys_LineInputChar(char *line)
{
char c;
char c;
while(*line)
{
c = *line++;
if (c == '\r' || c == '\n')
{
coninput_text[coninput_len] = 0;
putch ('\n');
putch (']');
coninput_len = 0;
fflush(stdout);
return coninput_text;
}
if (c == 8)
{
if (coninput_len)
c = *line++;
if (c == '\r' || c == '\n')
{
putch (c);
putch (' ');
putch (c);
coninput_len--;
coninput_text[coninput_len] = 0;
putch ('\n');
putch (']');
coninput_len = 0;
fflush(stdout);
return coninput_text;
}
continue;
}
if (c == '\t')
{
int i;
char *s = Cmd_CompleteCommand(coninput_text, true, true, 0, NULL);
if(s)
if (c == 8)
{
for (i = 0; i < coninput_len; i++)
putch('\b');
for (i = 0; i < coninput_len; i++)
putch(' ');
for (i = 0; i < coninput_len; i++)
putch('\b');
strcpy(coninput_text, s);
coninput_len = strlen(coninput_text);
printf("%s", coninput_text);
if (coninput_len)
{
putch (c);
putch (' ');
putch (c);
coninput_len--;
coninput_text[coninput_len] = 0;
}
continue;
}
continue;
if (c == '\t')
{
int i;
char *s = Cmd_CompleteCommand(coninput_text, true, true, 0, NULL);
if(s)
{
for (i = 0; i < coninput_len; i++)
putch('\b');
for (i = 0; i < coninput_len; i++)
putch(' ');
for (i = 0; i < coninput_len; i++)
putch('\b');
strcpy(coninput_text, s);
coninput_len = strlen(coninput_text);
printf("%s", coninput_text);
}
continue;
}
putch (c);
coninput_text[coninput_len] = c;
coninput_len++;
coninput_text[coninput_len] = 0;
if (coninput_len == sizeof(coninput_text))
coninput_len = 0;
}
putch (c);
coninput_text[coninput_len] = c;
coninput_len++;
coninput_text[coninput_len] = 0;
if (coninput_len == sizeof(coninput_text))
coninput_len = 0;
}
fflush(stdout);
return NULL;
return NULL;
}
#endif
/*
@ -563,7 +563,8 @@ char *Sys_ConsoleInput (void)
else
{
len = read (0, text, sizeof(text)-1);
if (len == 0) {
if (len == 0)
{
// end of file
do_stdin = 0;
return NULL;
@ -745,7 +746,7 @@ int main(int argc, char *argv[])
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{
DIR *dir;
char apath[MAX_OSPATH];

View file

@ -309,7 +309,7 @@ qboolean Sys_Rename (char *oldfname, char *newfname)
return !rename(oldfname, newfname);
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
{
HANDLE r;
WIN32_FIND_DATA fd;

View file

@ -39,7 +39,7 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer);
qbyte mod_novis[(MAX_MAP_LEAFS+7)/8];
#define MAX_MOD_KNOWN 512
#define MAX_MOD_KNOWN 2048
model_t mod_known[MAX_MOD_KNOWN];
int mod_numknown;

View file

@ -471,9 +471,6 @@ void World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers)
w->worldmodel->funcs.FindTouchedLeafs(w->worldmodel, &ent->pvsinfo, ent->v->absmin, ent->v->absmax);
}
// if (ent->v->solid == SOLID_NOT)
// return;
// find the first node that the ent's box crosses
node = w->areanodes;
while (1)