Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2010-08-11 03:36:31 +00:00
parent 3a30ac63c4
commit ce07219448
100 changed files with 3805 additions and 2757 deletions

View file

@ -203,11 +203,11 @@ int demo_preparsedemo(unsigned char *buffer, int bytes)
{ {
return parsed; //not got it all return parsed; //not got it all
} }
if ((buffer[1]&dem_mask) == dem_all && (buffer[1] & ~dem_mask) && length < MAX_NQMSGLEN) if ((buffer[1]&dem_mask) == dem_all && (buffer[1] & ~dem_mask) && length < MAX_OVERALLMSGLEN)
{ {
net_message.cursize = length; net_message.cursize = length;
memcpy(net_message.data, buffer+ofs, length); memcpy(net_message.data, buffer+ofs, length);
MSG_BeginReading(); MSG_BeginReading(cls.netchan.netprim);
CL_ParseServerMessage(); CL_ParseServerMessage();
} }
@ -1969,6 +1969,8 @@ void CL_QTVPlay_f (void)
CL_ParseQTVDescriptor(VFSOS_Open(connrequest+1, "rt"), connrequest+1); CL_ParseQTVDescriptor(VFSOS_Open(connrequest+1, "rt"), connrequest+1);
return; return;
} }
strcpy(cls.servername, "qtv:");
Q_strncpyz(cls.servername+4, connrequest, sizeof(cls.servername)-4);
SCR_SetLoadingStage(LS_CONNECTION); SCR_SetLoadingStage(LS_CONNECTION);
@ -2135,6 +2137,8 @@ void CL_FinishTimeDemo (void)
Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time); Con_Printf ("%i frames %5.1f seconds %5.1f fps\n", frames, time, frames/time);
cls.td_startframe = 0; cls.td_startframe = 0;
TP_ExecTrigger ("f_timedemoend");
} }
/* /*

View file

@ -85,6 +85,7 @@ qboolean CL_FilterModelindex(int modelindex, int frame)
void CL_FreeDlights(void) void CL_FreeDlights(void)
{ {
#pragma message("not freeing shadowmeshes")
rtlights_max = cl_maxdlights = 0; rtlights_max = cl_maxdlights = 0;
BZ_Free(cl_dlights); BZ_Free(cl_dlights);
cl_dlights = NULL; cl_dlights = NULL;
@ -98,9 +99,13 @@ void CL_InitDlights(void)
static void CL_ClearDlight(dlight_t *dl, int key) static void CL_ClearDlight(dlight_t *dl, int key)
{ {
void *sm;
texid_t st; texid_t st;
st = dl->stexture; st = dl->stexture;
sm = dl->worldshadowmesh;
memset (dl, 0, sizeof(*dl)); memset (dl, 0, sizeof(*dl));
dl->rebuildcache = true;
dl->worldshadowmesh = sm;
dl->stexture = st; dl->stexture = st;
dl->axis[0][0] = 1; dl->axis[0][0] = 1;
dl->axis[1][1] = 1; dl->axis[1][1] = 1;
@ -857,7 +862,7 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
cl_latestframenum = MSG_ReadLong(); cl_latestframenum = MSG_ReadLong();
if (nq_dp_protocol >=7) if (cls.protocol_nq >= CPNQ_DP7)
cl.ackedinputsequence = MSG_ReadLong(); cl.ackedinputsequence = MSG_ReadLong();
pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities; pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities;
@ -946,48 +951,6 @@ void CLNQ_ParseEntity(unsigned int bits)
static float lasttime; static float lasttime;
packet_entities_t *pack; packet_entities_t *pack;
#define NQU_MOREBITS (1<<0)
#define NQU_ORIGIN1 (1<<1)
#define NQU_ORIGIN2 (1<<2)
#define NQU_ORIGIN3 (1<<3)
#define NQU_ANGLE2 (1<<4)
#define NQU_NOLERP (1<<5) // don't interpolate movement
#define NQU_FRAME (1<<6)
#define NQU_SIGNAL (1<<7) // just differentiates from other updates
// svc_update can pass all of the fast update bits, plus more
#define NQU_ANGLE1 (1<<8)
#define NQU_ANGLE3 (1<<9)
#define NQU_MODEL (1<<10)
#define NQU_COLORMAP (1<<11)
#define NQU_SKIN (1<<12)
#define NQU_EFFECTS (1<<13)
#define NQU_LONGENTITY (1<<14)
// LordHavoc's: protocol extension
#define DPU_EXTEND1 (1<<15)
// LordHavoc: first extend byte
#define DPU_DELTA (1<<16) // no data, while this is set the entity is delta compressed (uses previous frame as a baseline, meaning only things that have changed from the previous frame are sent, except for the forced full update every half second)
#define DPU_ALPHA (1<<17) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 1, and the entity is not sent if <=0 unless it has effects (model effects are checked as well)
#define DPU_SCALE (1<<18) // 1 byte, scale / 16 positive, not sent if 1.0
#define DPU_EFFECTS2 (1<<19) // 1 byte, this is .effects & 0xFF00 (second byte)
#define DPU_GLOWSIZE (1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0
#define DPU_GLOWCOLOR (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set)
// LordHavoc: colormod feature has been removed, because no one used it
#define DPU_COLORMOD (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend...
#define DPU_EXTEND2 (1<<23) // another byte to follow
// LordHavoc: second extend byte
#define DPU_GLOWTRAIL (1<<24) // leaves a trail of particles (of color .glowcolor, or black if it is a negative glowsize)
#define DPU_VIEWMODEL (1<<25) // attachs the model to the view (origin and angles become relative to it), only shown to owner, a more powerful alternative to .weaponmodel and such
#define DPU_FRAME2 (1<<26) // 1 byte, this is .frame & 0xFF00 (second byte)
#define DPU_MODEL2 (1<<27) // 1 byte, this is .modelindex & 0xFF00 (second byte)
#define DPU_EXTERIORMODEL (1<<28) // causes this model to not be drawn when using a first person view (third person will draw it, first person will not)
#define DPU_UNUSED29 (1<<29) // future expansion
#define DPU_UNUSED30 (1<<30) // future expansion
#define DPU_EXTEND3 (1<<31) // another byte to follow, future expansion
if (cls.signon == 4 - 1) if (cls.signon == 4 - 1)
{ // first update is the final signon stage { // first update is the final signon stage
cls.signon = 4; cls.signon = 4;
@ -1093,63 +1056,81 @@ void CLNQ_ParseEntity(unsigned int bits)
else else
state->angles[2] = base->angles[2]; state->angles[2] = base->angles[2];
if (bits & DPU_ALPHA) if (cls.protocol_nq == CPNQ_FITZ666)
i = MSG_ReadByte();
else
i = -1;
#ifdef PEXT_TRANS
if (i == -1)
state->trans = base->trans;
else
state->trans = i;
#endif
if (bits & DPU_SCALE)
i = MSG_ReadByte();
else
i = -1;
#ifdef PEXT_SCALE
if (i == -1)
state->scale = base->scale;
else
state->scale = i;
#endif
if (bits & DPU_EFFECTS2)
state->effects |= MSG_ReadByte() << 8;
if (bits & DPU_GLOWSIZE)
state->glowsize = MSG_ReadByte();
else
state->glowsize = base->glowsize;
if (bits & DPU_GLOWCOLOR)
state->glowcolour = MSG_ReadByte();
else
state->glowcolour = base->glowcolour;
if (bits & DPU_COLORMOD)
{ {
i = MSG_ReadByte(); // follows format RRRGGGBB if (bits & FITZU_ALPHA)
state->colormod[0] = (qbyte)(((i >> 5) & 7) * (32.0f / 7.0f)); state->trans = MSG_ReadByte();
state->colormod[1] = (qbyte)(((i >> 2) & 7) * (32.0f / 7.0f)); else
state->colormod[2] = (qbyte)((i & 3) * (32.0f / 3.0f)); state->trans = base->trans;
if (bits & FITZU_FRAME2)
state->frame |= MSG_ReadByte() << 8;
if (bits & FITZU_MODEL2)
state->modelindex |= MSG_ReadByte() << 8;
if (bits & FITZU_LERPFINISH)
MSG_ReadByte();
} }
else else
{ {
state->colormod[0] = base->colormod[0]; if (bits & DPU_ALPHA)
state->colormod[1] = base->colormod[1]; i = MSG_ReadByte();
state->colormod[2] = base->colormod[2]; else
i = -1;
#ifdef PEXT_TRANS
if (i == -1)
state->trans = base->trans;
else
state->trans = i;
#endif
if (bits & DPU_SCALE)
i = MSG_ReadByte();
else
i = -1;
#ifdef PEXT_SCALE
if (i == -1)
state->scale = base->scale;
else
state->scale = i;
#endif
if (bits & DPU_EFFECTS2)
state->effects |= MSG_ReadByte() << 8;
if (bits & DPU_GLOWSIZE)
state->glowsize = MSG_ReadByte();
else
state->glowsize = base->glowsize;
if (bits & DPU_GLOWCOLOR)
state->glowcolour = MSG_ReadByte();
else
state->glowcolour = base->glowcolour;
if (bits & DPU_COLORMOD)
{
i = MSG_ReadByte(); // follows format RRRGGGBB
state->colormod[0] = (qbyte)(((i >> 5) & 7) * (32.0f / 7.0f));
state->colormod[1] = (qbyte)(((i >> 2) & 7) * (32.0f / 7.0f));
state->colormod[2] = (qbyte)((i & 3) * (32.0f / 3.0f));
}
else
{
state->colormod[0] = base->colormod[0];
state->colormod[1] = base->colormod[1];
state->colormod[2] = base->colormod[2];
}
if (bits & DPU_FRAME2)
state->frame |= MSG_ReadByte() << 8;
if (bits & DPU_MODEL2)
state->modelindex |= MSG_ReadByte() << 8;
} }
if (bits & DPU_FRAME2)
state->frame |= MSG_ReadByte() << 8;
if (bits & DPU_MODEL2)
state->modelindex |= MSG_ReadByte() << 8;
if (cls.demoplayback != DPB_NONE) if (cls.demoplayback != DPB_NONE)
for (pnum = 0; pnum < cl.splitclients; pnum++) for (pnum = 0; pnum < cl.splitclients; pnum++)
if (num == cl.viewentity[pnum]) if (num == cl.viewentity[pnum])
@ -1447,8 +1428,8 @@ void CL_LinkStaticEntities(void *pvs)
model_t *clmodel; model_t *clmodel;
extern cvar_t r_drawflame, gl_part_flame; extern cvar_t r_drawflame, gl_part_flame;
// if (!cl_staticentities.ival) if (r_drawflame.ival < 0)
// return; return;
if (!cl.worldmodel) if (!cl.worldmodel)
return; return;
@ -1460,6 +1441,8 @@ void CL_LinkStaticEntities(void *pvs)
stat = &cl_static_entities[i].ent; stat = &cl_static_entities[i].ent;
clmodel = stat->model; clmodel = stat->model;
if (!clmodel || clmodel->needload)
continue;
if ((!r_drawflame.ival) && (clmodel->engineflags & MDLF_FLAME)) if ((!r_drawflame.ival) && (clmodel->engineflags & MDLF_FLAME))
continue; continue;
@ -2631,6 +2614,8 @@ void CL_AddVWeapModel(entity_t *player, model_t *model)
{ {
entity_t *newent; entity_t *newent;
vec3_t angles; vec3_t angles;
if (!model)
return;
newent = CL_NewTempEntity (); newent = CL_NewTempEntity ();
newent->keynum = player->keynum; newent->keynum = player->keynum;

View file

@ -757,19 +757,24 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
MSG_WriteByte (buf, clc_move); MSG_WriteByte (buf, clc_move);
if (nq_dp_protocol>=7) if (cls.protocol_nq >= CPNQ_DP7)
MSG_WriteLong(buf, cls.netchan.outgoing_sequence); MSG_WriteLong(buf, cls.netchan.outgoing_sequence);
MSG_WriteFloat (buf, cl.gametime); // so server can get ping times MSG_WriteFloat (buf, cl.gametime); // so server can get ping times
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
MSG_WriteAngle (buf, cl.viewangles[pnum][i]); {
if (cls.protocol_nq == CPNQ_FITZ666)
MSG_WriteAngle16 (buf, cl.viewangles[pnum][i]);
else
MSG_WriteAngle (buf, cl.viewangles[pnum][i]);
}
MSG_WriteShort (buf, cmd->forwardmove); MSG_WriteShort (buf, cmd->forwardmove);
MSG_WriteShort (buf, cmd->sidemove); MSG_WriteShort (buf, cmd->sidemove);
MSG_WriteShort (buf, cmd->upmove); MSG_WriteShort (buf, cmd->upmove);
if (nq_dp_protocol >= 6) if (cls.protocol_nq >= CPNQ_DP6)
{ {
CL_UpdatePrydonCursor(cmd, cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber); CL_UpdatePrydonCursor(cmd, cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber);
MSG_WriteLong (buf, cmd->buttons); MSG_WriteLong (buf, cmd->buttons);
@ -781,7 +786,7 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
MSG_WriteByte (buf, cmd->impulse); MSG_WriteByte (buf, cmd->impulse);
if (nq_dp_protocol >= 6) if (cls.protocol_nq >= CPNQ_DP6)
{ {
MSG_WriteShort (buf, cursor_screen[0] * 32767.0f); MSG_WriteShort (buf, cursor_screen[0] * 32767.0f);
MSG_WriteShort (buf, cursor_screen[1] * 32767.0f); MSG_WriteShort (buf, cursor_screen[1] * 32767.0f);
@ -808,7 +813,7 @@ void Name_Callback(struct cvar_s *var, char *oldvalue)
void CLNQ_SendCmd(sizebuf_t *buf) void CLNQ_SendCmd(sizebuf_t *buf)
{ {
extern int cl_latestframenum, nq_dp_protocol; extern int cl_latestframenum;
if (cls.signon == 4) if (cls.signon == 4)
{ {
@ -819,7 +824,7 @@ void CLNQ_SendCmd(sizebuf_t *buf)
CLNQ_SendMove (&independantphysics[0], 0, buf); CLNQ_SendMove (&independantphysics[0], 0, buf);
} }
if (nq_dp_protocol > 0 && cls.signon == 4) if (CPNQ_IS_DP && cls.signon == 4)
{ {
MSG_WriteByte(buf, clcdp_ackframe); MSG_WriteByte(buf, clcdp_ackframe);
MSG_WriteLong(buf, cl_latestframenum); MSG_WriteLong(buf, cl_latestframenum);
@ -1498,6 +1503,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
buf.maxsize = sizeof(data); buf.maxsize = sizeof(data);
buf.cursize = 0; buf.cursize = 0;
buf.data = data; buf.data = data;
buf.prim = cls.netchan.message.prim;
#ifdef IRCCONNECT #ifdef IRCCONNECT
if (cls.netchan.remote_address.type != NA_IRC) if (cls.netchan.remote_address.type != NA_IRC)

View file

@ -135,7 +135,7 @@ cvar_t cl_gunanglex = SCVAR("cl_gunanglex", "0");
cvar_t cl_gunangley = SCVAR("cl_gunangley", "0"); cvar_t cl_gunangley = SCVAR("cl_gunangley", "0");
cvar_t cl_gunanglez = SCVAR("cl_gunanglez", "0"); cvar_t cl_gunanglez = SCVAR("cl_gunanglez", "0");
cvar_t allow_download_csprogs = SCVARF("allow_download_csprogs", "0", CVAR_NOTFROMSERVER); cvar_t allow_download_csprogs = SCVARF("allow_download_csprogs", "1", CVAR_NOTFROMSERVER);
cvar_t allow_download_redirection = SCVARF("allow_download_redirection", "0", CVAR_NOTFROMSERVER); cvar_t allow_download_redirection = SCVARF("allow_download_redirection", "0", CVAR_NOTFROMSERVER);
cvar_t requiredownloads = SCVARF("requiredownloads","1", CVAR_ARCHIVE); cvar_t requiredownloads = SCVARF("requiredownloads","1", CVAR_ARCHIVE);
@ -182,7 +182,8 @@ client_state_t cl;
// alot of this should probably be dynamically allocated // alot of this should probably be dynamically allocated
entity_state_t *cl_baselines; entity_state_t *cl_baselines;
static_entity_t cl_static_entities[MAX_STATIC_ENTITIES]; static_entity_t *cl_static_entities;
unsigned int cl_max_static_entities;
lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
//lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; //lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
dlight_t *cl_dlights; dlight_t *cl_dlights;
@ -1054,6 +1055,8 @@ void CL_ClearState (void)
// clear other arrays // clear other arrays
// memset (cl_dlights, 0, sizeof(cl_dlights)); // memset (cl_dlights, 0, sizeof(cl_dlights));
memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); memset (cl_lightstyle, 0, sizeof(cl_lightstyle));
for (i = 0; i < MAX_LIGHTSTYLES; i++)
cl_lightstyle[i].colour = 7;
rtlights_first = rtlights_max = RTL_FIRST; rtlights_first = rtlights_max = RTL_FIRST;
@ -2018,7 +2021,7 @@ void CL_ConnectionlessPacket (void)
int c; int c;
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
MSG_BeginReading (); MSG_BeginReading (msg_nullnetprim);
MSG_ReadLong (); // skip the -1 MSG_ReadLong (); // skip the -1
Cmd_TokenizeString(net_message.data+4, false, false); Cmd_TokenizeString(net_message.data+4, false, false);
@ -2410,7 +2413,7 @@ void CLNQ_ConnectionlessPacket(void)
char *s; char *s;
int length; int length;
MSG_BeginReading (); MSG_BeginReading (msg_nullnetprim);
length = LongSwap(MSG_ReadLong ()); length = LongSwap(MSG_ReadLong ());
if (!(length & NETFLAG_CTL)) if (!(length & NETFLAG_CTL))
return; //not an nq control packet. return; //not an nq control packet.
@ -2522,7 +2525,7 @@ void CL_ReadPackets (void)
#ifdef NQPROT #ifdef NQPROT
if (cls.demoplayback == DPB_NETQUAKE) if (cls.demoplayback == DPB_NETQUAKE)
{ {
MSG_BeginReading (); MSG_BeginReading (cls.netchan.netprim);
cls.netchan.last_received = realtime; cls.netchan.last_received = realtime;
CLNQ_ParseServerMessage (); CLNQ_ParseServerMessage ();
@ -2534,7 +2537,7 @@ void CL_ReadPackets (void)
#ifdef Q2CLIENT #ifdef Q2CLIENT
if (cls.demoplayback == DPB_QUAKE2) if (cls.demoplayback == DPB_QUAKE2)
{ {
MSG_BeginReading (); MSG_BeginReading (cls.netchan.netprim);
cls.netchan.last_received = realtime; cls.netchan.last_received = realtime;
CLQ2_ParseServerMessage (); CLQ2_ParseServerMessage ();
continue; continue;
@ -2585,6 +2588,7 @@ void CL_ReadPackets (void)
case NQP_DATAGRAM://datagram case NQP_DATAGRAM://datagram
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence - 3; cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence - 3;
case NQP_RELIABLE://reliable case NQP_RELIABLE://reliable
MSG_ChangePrimitives(cls.netchan.netprim);
CLNQ_ParseServerMessage (); CLNQ_ParseServerMessage ();
break; break;
} }
@ -2597,6 +2601,7 @@ void CL_ReadPackets (void)
if (!Netchan_Process(&cls.netchan)) if (!Netchan_Process(&cls.netchan))
continue; // wasn't accepted for some reason continue; // wasn't accepted for some reason
CLQ2_ParseServerMessage (); CLQ2_ParseServerMessage ();
break;
#endif #endif
case CP_QUAKE3: case CP_QUAKE3:
#ifdef Q3CLIENT #ifdef Q3CLIENT
@ -2606,7 +2611,7 @@ void CL_ReadPackets (void)
case CP_QUAKEWORLD: case CP_QUAKEWORLD:
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
MSG_BeginReading(); MSG_BeginReading(cls.netchan.netprim);
cls.netchan.last_received = realtime; cls.netchan.last_received = realtime;
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence; cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
} }
@ -2618,6 +2623,7 @@ void CL_ReadPackets (void)
Con_Printf("Server is from the future! (%i packets)\n", cls.netchan.incoming_sequence - cls.netchan.outgoing_sequence); Con_Printf("Server is from the future! (%i packets)\n", cls.netchan.incoming_sequence - cls.netchan.outgoing_sequence);
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence; cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
} }
MSG_ChangePrimitives(cls.netchan.netprim);
CL_ParseServerMessage (); CL_ParseServerMessage ();
break; break;
case CP_UNKNOWN: case CP_UNKNOWN:
@ -3616,7 +3622,7 @@ void Host_Init (quakeparms_t *parms)
#endif #endif
// Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); // Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
Con_TPrintf (TL_HEAPSIZE, parms->memsize/ (1024*1024.0)); //Con_TPrintf (TL_HEAPSIZE, parms->memsize/ (1024*1024.0));
Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
host_hunklevel = Hunk_LowMark (); host_hunklevel = Hunk_LowMark ();

View file

@ -27,7 +27,6 @@ void CLNQ_ParseDarkPlaces5Entities(void);
void CL_SetStatInt (int pnum, int stat, int value); void CL_SetStatInt (int pnum, int stat, int value);
static qboolean CL_CheckModelResources (char *name); static qboolean CL_CheckModelResources (char *name);
int nq_dp_protocol;
int msgflags; int msgflags;
char cl_dp_csqc_progsname[128]; char cl_dp_csqc_progsname[128];
@ -1767,14 +1766,14 @@ void CLDP_ParseDownloadData(void)
{ {
VFS_SEEK(cls.downloadqw, start); VFS_SEEK(cls.downloadqw, start);
VFS_WRITE(cls.downloadqw, buffer, size); VFS_WRITE(cls.downloadqw, buffer, size);
cls.downloadpercent = start / (float)VFS_GETLEN(cls.downloadqw) * 100;
} }
//this is only reliable because I'm lazy //this is only reliable because I'm lazy
MSG_WriteByte(&cls.netchan.message, clcdp_ackdownloaddata); MSG_WriteByte(&cls.netchan.message, clcdp_ackdownloaddata);
MSG_WriteLong(&cls.netchan.message, start); MSG_WriteLong(&cls.netchan.message, start);
MSG_WriteShort(&cls.netchan.message, size); MSG_WriteShort(&cls.netchan.message, size);
cls.downloadpercent = start / (float)VFS_GETLEN(cls.downloadqw) * 100;
} }
void CLDP_ParseDownloadBegin(char *s) void CLDP_ParseDownloadBegin(char *s)
@ -2096,14 +2095,16 @@ void CL_ParseServerData (void)
if (cls.fteprotocolextensions & PEXT_FLOATCOORDS) if (cls.fteprotocolextensions & PEXT_FLOATCOORDS)
{ {
sizeofcoord = 4; cls.netchan.netprim.coordsize = 4;
sizeofangle = 2; cls.netchan.netprim.anglesize = 2;
} }
else else
{ {
sizeofcoord = 2; cls.netchan.netprim.coordsize = 2;
sizeofangle = 1; cls.netchan.netprim.anglesize = 1;
} }
cls.netchan.message.prim = cls.netchan.netprim;
MSG_ChangePrimitives(cls.netchan.netprim);
svcnt = MSG_ReadLong (); svcnt = MSG_ReadLong ();
@ -2276,8 +2277,9 @@ void CLQ2_ParseServerData (void)
int svcnt; int svcnt;
// int cflag; // int cflag;
sizeofcoord = 2; cls.netchan.netprim.coordsize = 2;
sizeofangle = 1; cls.netchan.netprim.anglesize = 1;
MSG_ChangePrimitives(cls.netchan.netprim);
Con_DPrintf ("Serverdata packet received.\n"); Con_DPrintf ("Serverdata packet received.\n");
// //
@ -2316,6 +2318,7 @@ void CLQ2_ParseServerData (void)
//I can't really blame q2admin for rejecting engines that don't have this cvar, as it could have been renamed via a hex-edit. //I can't really blame q2admin for rejecting engines that don't have this cvar, as it could have been renamed via a hex-edit.
CL_ClearState (); CL_ClearState ();
CLQ2_ClearState ();
cl.minpitch = -89; cl.minpitch = -89;
cl.maxpitch = 89; cl.maxpitch = 89;
cl.servercount = svcnt; cl.servercount = svcnt;
@ -2382,6 +2385,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
char *str; char *str;
int gametype; int gametype;
int protover; int protover;
struct netprim_s netprim;
if (developer.ival) if (developer.ival)
Con_TPrintf (TLC_GOTSVDATAPACKET); Con_TPrintf (TLC_GOTSVDATAPACKET);
SCR_SetLoadingStage(LS_CLIENT); SCR_SetLoadingStage(LS_CLIENT);
@ -2391,29 +2395,35 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
protover = MSG_ReadLong (); protover = MSG_ReadLong ();
sizeofcoord = 2; netprim.coordsize = 2;
sizeofangle = 1; netprim.anglesize = 1;
nq_dp_protocol = 0; cls.protocol_nq = 0;
cls.z_ext = 0; cls.z_ext = 0;
if (protover == 250) if (protover == 250)
Host_EndGame ("Nehahra demo net protocol is not supported\n"); Host_EndGame ("Nehahra demo net protocol is not supported\n");
else if (protover == 666)
{
//fitzquake 0.85
cls.protocol_nq = CPNQ_FITZ666;
Con_DPrintf("FitzQuake 666 protocol\n");
}
else if (protover == 3502) else if (protover == 3502)
{ {
//darkplaces5 //darkplaces5
nq_dp_protocol = 5; cls.protocol_nq = CPNQ_DP5;
sizeofcoord = 4; netprim.coordsize = 4;
sizeofangle = 2; netprim.anglesize = 2;
Con_DPrintf("DP5 protocols\n"); Con_DPrintf("DP5 protocols\n");
} }
else if (protover == DP6_PROTOCOL_VERSION) else if (protover == DP6_PROTOCOL_VERSION)
{ {
//darkplaces6 (it's a small difference from dp5) //darkplaces6 (it's a small difference from dp5)
nq_dp_protocol = 6; cls.protocol_nq = CPNQ_DP6;
sizeofcoord = 4; netprim.coordsize = 4;
sizeofangle = 2; netprim.anglesize = 2;
cls.z_ext = Z_EXT_VIEWHEIGHT; cls.z_ext = Z_EXT_VIEWHEIGHT;
@ -2422,9 +2432,9 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
else if (protover == DP7_PROTOCOL_VERSION) else if (protover == DP7_PROTOCOL_VERSION)
{ {
//darkplaces7 (it's a small difference from dp5) //darkplaces7 (it's a small difference from dp5)
nq_dp_protocol = 7; cls.protocol_nq = CPNQ_DP7;
sizeofcoord = 4; netprim.coordsize = 4;
sizeofangle = 2; netprim.anglesize = 2;
cls.z_ext = Z_EXT_VIEWHEIGHT; cls.z_ext = Z_EXT_VIEWHEIGHT;
@ -2438,6 +2448,8 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
{ {
Con_DPrintf("Standard NQ protocols\n"); Con_DPrintf("Standard NQ protocols\n");
} }
cls.netchan.message.prim = cls.netchan.netprim = netprim;
MSG_ChangePrimitives(netprim);
if (MSG_ReadByte() > MAX_CLIENTS) if (MSG_ReadByte() > MAX_CLIENTS)
{ {
@ -2491,7 +2503,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
} }
strcpy (cl.sound_name[numsounds], str); strcpy (cl.sound_name[numsounds], str);
#pragma message("the logic that we should have here is rather long") #pragma message("CLNQ_ParseServerData: no sound autodownloads")
//CL_CheckOrEnqueDownloadFile(str, NULL, 0); //CL_CheckOrEnqueDownloadFile(str, NULL, 0);
S_TouchSound (str); S_TouchSound (str);
@ -2522,8 +2534,8 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
Info_SetValueForStarKey(cl.serverinfo, "deathmatch", "0", sizeof(cl.serverinfo)); Info_SetValueForStarKey(cl.serverinfo, "deathmatch", "0", sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "teamplay", "0", sizeof(cl.serverinfo)); Info_SetValueForStarKey(cl.serverinfo, "teamplay", "0", sizeof(cl.serverinfo));
//allow shaders //allow some things by default that quakeworld bans by default
Info_SetValueForStarKey(cl.serverinfo, "allow_shaders", "1", sizeof(cl.serverinfo)); Info_SetValueForStarKey(cl.serverinfo, "watervis", "1", sizeof(cl.serverinfo));
//pretend it came from the server, and update cheat/permissions/etc //pretend it came from the server, and update cheat/permissions/etc
CL_CheckServerInfo(); CL_CheckServerInfo();
@ -2557,7 +2569,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
CL_SendClientCommand(true, "spawn %s", ""); CL_SendClientCommand(true, "spawn %s", "");
if (nq_dp_protocol) //dp needs a couple of extras to work properly. if (CPNQ_IS_DP) //dp needs a couple of extras to work properly.
{ {
CL_SendClientCommand(true, "rate %s", rate.string); CL_SendClientCommand(true, "rate %s", rate.string);
@ -2644,7 +2656,7 @@ void CLNQ_ParseClientdata (void)
if (bits & SU_VIEWHEIGHT) if (bits & SU_VIEWHEIGHT)
CL_SetStatInt(0, STAT_VIEWHEIGHT, MSG_ReadChar ()); CL_SetStatInt(0, STAT_VIEWHEIGHT, MSG_ReadChar ());
else if (nq_dp_protocol < 6) else if (CPNQ_IS_DP || cls.protocol_nq == CPNQ_DP5)
CL_SetStatInt(0, STAT_VIEWHEIGHT, DEFAULT_VIEWHEIGHT); CL_SetStatInt(0, STAT_VIEWHEIGHT, DEFAULT_VIEWHEIGHT);
if (bits & SU_IDEALPITCH) if (bits & SU_IDEALPITCH)
@ -2656,7 +2668,7 @@ void CLNQ_ParseClientdata (void)
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
{ {
if (bits & (SU_PUNCH1<<i) ) if (bits & (SU_PUNCH1<<i) )
/*cl.punchangle[i] =*/ nq_dp_protocol?MSG_ReadAngle16():MSG_ReadChar(); /*cl.punchangle[i] =*/ CPNQ_IS_DP?MSG_ReadAngle16():MSG_ReadChar();
// else // else
// cl.punchangle[i] = 0; // cl.punchangle[i] = 0;
@ -2669,7 +2681,7 @@ void CLNQ_ParseClientdata (void)
if (bits & (SU_VELOCITY1<<i) ) if (bits & (SU_VELOCITY1<<i) )
{ {
if (nq_dp_protocol >= 5) if (CPNQ_IS_DP)
/*cl.simvel[0][i] =*/ MSG_ReadFloat(); /*cl.simvel[0][i] =*/ MSG_ReadFloat();
else else
/*cl.mvelocity[0][i] =*/ MSG_ReadChar()/**16*/; /*cl.mvelocity[0][i] =*/ MSG_ReadChar()/**16*/;
@ -2684,10 +2696,7 @@ void CLNQ_ParseClientdata (void)
// cl.onground = (bits & SU_ONGROUND) != 0; // cl.onground = (bits & SU_ONGROUND) != 0;
// cl.inwater = (bits & SU_INWATER) != 0; // cl.inwater = (bits & SU_INWATER) != 0;
if (nq_dp_protocol >= 6) if (cls.protocol_nq == CPNQ_DP5)
{
}
else if (nq_dp_protocol == 5)
{ {
CL_SetStatInt(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned short)MSG_ReadShort():0); CL_SetStatInt(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned short)MSG_ReadShort():0);
CL_SetStatInt(0, STAT_ARMOR, (bits & SU_ARMOR)?MSG_ReadShort():0); CL_SetStatInt(0, STAT_ARMOR, (bits & SU_ARMOR)?MSG_ReadShort():0);
@ -2704,6 +2713,10 @@ void CLNQ_ParseClientdata (void)
CL_SetStatInt(0, STAT_ACTIVEWEAPON, (unsigned short)MSG_ReadShort()); CL_SetStatInt(0, STAT_ACTIVEWEAPON, (unsigned short)MSG_ReadShort());
} }
else if (CPNQ_IS_DP)
{
/*nothing*/
}
else else
{ {
CL_SetStatInt(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned char)MSG_ReadByte():0); CL_SetStatInt(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned char)MSG_ReadByte():0);
@ -2720,20 +2733,54 @@ void CLNQ_ParseClientdata (void)
CL_SetStatInt(0, STAT_CELLS, MSG_ReadByte()); CL_SetStatInt(0, STAT_CELLS, MSG_ReadByte());
CL_SetStatInt(0, STAT_ACTIVEWEAPON, MSG_ReadByte()); CL_SetStatInt(0, STAT_ACTIVEWEAPON, MSG_ReadByte());
if (cls.protocol_nq == CPNQ_FITZ666)
{
#define FITZSU_WEAPON2 (1<<16) // 1 byte, this is .weaponmodel & 0xFF00 (second byte)
#define FITZSU_ARMOR2 (1<<17) // 1 byte, this is .armorvalue & 0xFF00 (second byte)
#define FITZSU_AMMO2 (1<<18) // 1 byte, this is .currentammo & 0xFF00 (second byte)
#define FITZSU_SHELLS2 (1<<19) // 1 byte, this is .ammo_shells & 0xFF00 (second byte)
#define FITZSU_NAILS2 (1<<20) // 1 byte, this is .ammo_nails & 0xFF00 (second byte)
#define FITZSU_ROCKETS2 (1<<21) // 1 byte, this is .ammo_rockets & 0xFF00 (second byte)
#define FITZSU_CELLS2 (1<<22) // 1 byte, this is .ammo_cells & 0xFF00 (second byte)
#define FITZSU_WEAPONFRAME2 (1<<24) // 1 byte, this is .weaponframe & 0xFF00 (second byte)
#define FITZSU_WEAPONALPHA (1<<25) // 1 byte, this is alpha for weaponmodel, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT
if (bits & FITZSU_WEAPON2)
MSG_ReadByte();
if (bits & FITZSU_ARMOR2)
MSG_ReadByte();
if (bits & FITZSU_AMMO2)
MSG_ReadByte();
if (bits & FITZSU_SHELLS2)
MSG_ReadByte();
if (bits & FITZSU_NAILS2)
MSG_ReadByte();
if (bits & FITZSU_ROCKETS2)
MSG_ReadByte();
if (bits & FITZSU_CELLS2)
MSG_ReadByte();
if (bits & FITZSU_WEAPONFRAME2)
MSG_ReadByte();
if (bits & FITZSU_WEAPONALPHA)
MSG_ReadByte();
}
} }
if (bits & DPSU_VIEWZOOM) if (CPNQ_IS_DP || cls.protocol_nq == CPNQ_DP5)
{ {
if (nq_dp_protocol >= 5) if (bits & DPSU_VIEWZOOM)
i = (unsigned short) MSG_ReadShort(); {
if (cls.protocol_nq)
i = (unsigned short) MSG_ReadShort();
else
i = MSG_ReadByte();
if (i < 2)
i = 2;
CL_SetStatInt(0, STAT_VIEWZOOM, i);
}
else else
i = MSG_ReadByte(); CL_SetStatInt(0, STAT_VIEWZOOM, 255);
if (i < 2)
i = 2;
CL_SetStatInt(0, STAT_VIEWZOOM, i);
} }
else if (nq_dp_protocol < 6)
CL_SetStatInt(0, STAT_VIEWZOOM, 255);
} }
#endif #endif
/* /*
@ -3105,6 +3152,28 @@ void CL_ParseBaseline2 (void)
memcpy(cl_baselines + es.number, &es, sizeof(es)); memcpy(cl_baselines + es.number, &es, sizeof(es));
} }
void CLFitz_ParseBaseline2 (entity_state_t *es)
{
int i;
int bits;
memcpy(es, &nullentitystate, sizeof(entity_state_t));
bits = MSG_ReadByte();
es->modelindex = (bits & FITZB_LARGEMODEL) ? MSG_ReadShort() : MSG_ReadByte();
es->frame = (bits & FITZB_LARGEFRAME) ? MSG_ReadShort() : MSG_ReadByte();
es->colormap = MSG_ReadByte();
es->skinnum = MSG_ReadByte();
for (i=0 ; i<3 ; i++)
{
es->origin[i] = MSG_ReadCoord ();
es->angles[i] = MSG_ReadAngle ();
}
es->trans = (bits & FITZB_ALPHA) ? MSG_ReadByte() : 255;
}
void CLQ2_Precache_f (void) void CLQ2_Precache_f (void)
{ {
Model_CheckDownloads(); Model_CheckDownloads();
@ -3157,15 +3226,17 @@ void CL_ParseStatic (int version)
cl.num_statics++; cl.num_statics++;
} }
if (i >= MAX_STATIC_ENTITIES) if (i == cl_max_static_entities)
{ {
cl.num_statics--; cl_max_static_entities += 16;
Con_Printf ("Too many static entities"); cl_static_entities = BZ_Realloc(cl_static_entities, sizeof(*cl_static_entities)*cl_max_static_entities);
return;
} }
cl_static_entities[i].mdlidx = es.modelindex;
cl_static_entities[i].emit = NULL;
ent = &cl_static_entities[i].ent; ent = &cl_static_entities[i].ent;
memset(ent, 0, sizeof(*ent)); memset(ent, 0, sizeof(*ent));
cl_static_entities[i].emit = NULL;
ent->keynum = es.number; ent->keynum = es.number;
@ -3192,13 +3263,14 @@ void CL_ParseStatic (int version)
AngleVectors(es.angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(es.angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
if (!cl.worldmodel) if (!cl.worldmodel || cl.worldmodel->needload)
{ {
Con_TPrintf (TLC_PARSESTATICWITHNOMAP); Con_TPrintf (TLC_PARSESTATICWITHNOMAP);
return; return;
} }
if (ent->model) if (ent->model)
{ {
/*FIXME: compensate for angle*/
VectorAdd(es.origin, ent->model->mins, mins); VectorAdd(es.origin, ent->model->mins, mins);
VectorAdd(es.origin, ent->model->maxs, maxs); VectorAdd(es.origin, ent->model->maxs, maxs);
cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &cl_static_entities[i].pvscache, mins, maxs); cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &cl_static_entities[i].pvscache, mins, maxs);
@ -3366,11 +3438,6 @@ void CLQ2_ParseStartSoundPacket(void)
#endif #endif
#if defined(NQPROT) || defined(PEXT_SOUNDDBL) #if defined(NQPROT) || defined(PEXT_SOUNDDBL)
#define NQSND_VOLUME (1<<0) // a qbyte
#define NQSND_ATTENUATION (1<<1) // a qbyte
#define DPSND_LOOPING (1<<2) // a long, supposedly
#define DPSND_LARGEENTITY (1<<3)
#define DPSND_LARGESOUND (1<<4)
void CLNQ_ParseStartSoundPacket(void) void CLNQ_ParseStartSoundPacket(void)
{ {
vec3_t pos; vec3_t pos;
@ -4519,12 +4586,16 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
Cmd_TokenizeString(stufftext+7, false, false); Cmd_TokenizeString(stufftext+7, false, false);
for (i = 0; i < Cmd_Argc(); i++) for (i = 0; i < Cmd_Argc(); i++)
{ {
mname = va("progs/%s.mdl", Cmd_Argv(i)); mname = Cmd_Argv(i);
Q_strncpyz(cl.model_name_vwep[i], mname, sizeof(cl.model_name_vwep[i])); if (strcmp(mname, "-"))
if (cls.state == ca_active)
{ {
CL_CheckOrEnqueDownloadFile(mname, NULL, 0); mname = va("progs/%s.mdl", Cmd_Argv(i));
cl.model_precache_vwep[i] = Mod_ForName(mname, false); Q_strncpyz(cl.model_name_vwep[i], mname, sizeof(cl.model_name_vwep[i]));
if (cls.state == ca_active)
{
CL_CheckOrEnqueDownloadFile(mname, NULL, 0);
cl.model_precache_vwep[i] = Mod_ForName(mname, false);
}
} }
} }
} }
@ -5640,7 +5711,7 @@ void CLNQ_ParseServerMessage (void)
cl.gametime = MSG_ReadFloat(); cl.gametime = MSG_ReadFloat();
cl.gametimemark = realtime; cl.gametimemark = realtime;
if (nq_dp_protocol<5) if (!CPNQ_IS_DP)
{ {
// cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; // cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.num_entities=0; cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.num_entities=0;
@ -5778,6 +5849,34 @@ void CLNQ_ParseServerMessage (void)
V_ParseDamage (0); V_ParseDamage (0);
break; break;
case svcfitz_skybox:
{
extern cvar_t r_skyboxname;
Cvar_Set(&r_skyboxname, MSG_ReadString());
}
break;
case svcfitz_bf:
Cmd_ExecuteString("bf", RESTRICT_RCON);
break;
case svcfitz_fog:
/*density =*/ MSG_ReadByte();
/*red =*/ MSG_ReadByte();
/*green =*/ MSG_ReadByte();
/*blue =*/ MSG_ReadByte();
/*time =*/ MSG_ReadShort();
break;
case svcfitz_spawnbaseline2:
i = MSG_ReadShort ();
if (!CL_CheckBaselines(i))
Host_EndGame("CLNQ_ParseServerMessage: svcfitz_spawnbaseline2 failed with ent %i", i);
CLFitz_ParseBaseline2 (cl_baselines + i);
break;
// case svcfitz_spawnstatic2:
// break;
// case svcfitz_spawnstaticsound2:
// break;
case svcnq_effect: case svcnq_effect:
CL_ParseEffect(false); CL_ParseEffect(false);
break; break;

View file

@ -363,7 +363,8 @@ void CL_PredictUsercmd (int pnum, player_state_t *from, player_state_t *to, user
extern vec3_t player_mins; extern vec3_t player_mins;
extern vec3_t player_maxs; extern vec3_t player_maxs;
// split up very long moves // split up very long moves
if (u->msec > 50) { if (u->msec > 50)
{
player_state_t temp; player_state_t temp;
usercmd_t split; usercmd_t split;
@ -414,10 +415,10 @@ void CL_PredictUsercmd (int pnum, player_state_t *from, player_state_t *to, user
} }
else else
{ {
VectorCopy(cl.worldmodel->hulls[pmove.hullnum].clip_mins, player_mins); VectorCopy(cl.worldmodel->hulls[pmove.hullnum&(MAX_MAP_HULLSM-1)].clip_mins, player_mins);
VectorCopy(cl.worldmodel->hulls[pmove.hullnum].clip_maxs, player_maxs); VectorCopy(cl.worldmodel->hulls[pmove.hullnum&(MAX_MAP_HULLSM-1)].clip_maxs, player_maxs);
} }
if (DEFAULT_VIEWHEIGHT > player_maxs[2]) if (pmove.hullnum & 128)
{ //this hack is for hexen2. { //this hack is for hexen2.
player_maxs[2] -= player_mins[2]; player_maxs[2] -= player_mins[2];
player_mins[2] = 0; player_mins[2] = 0;
@ -457,7 +458,7 @@ void CL_CatagorizePosition (int pnum)
} }
//Smooth out stair step ups. //Smooth out stair step ups.
//Called before CL_EmitEntities so that the player's lightning model origin is updated properly //Called before CL_EmitEntities so that the player's lightning model origin is updated properly
void CL_CalcCrouch (int pnum) void CL_CalcCrouch (int pnum, float stepchange)
{ {
qboolean teleported; qboolean teleported;
static vec3_t oldorigin[MAX_SPLITS]; static vec3_t oldorigin[MAX_SPLITS];
@ -552,14 +553,16 @@ static void CL_LerpMove (int pnum, float msgtime)
return; return;
#endif #endif
if (cls.netchan.outgoing_sequence < lastsequence) { if (cls.netchan.outgoing_sequence < lastsequence)
{
// reset // reset
lastsequence = -1; lastsequence = -1;
lerp_times[0] = -1; lerp_times[0] = -1;
demo_latency = 0.01; demo_latency = 0.01;
} }
if (cls.netchan.outgoing_sequence > lastsequence) { if (cls.netchan.outgoing_sequence > lastsequence)
{
lastsequence = cls.netchan.outgoing_sequence; lastsequence = cls.netchan.outgoing_sequence;
// move along // move along
lerp_times[2] = lerp_times[1]; lerp_times[2] = lerp_times[1];
@ -586,14 +589,18 @@ static void CL_LerpMove (int pnum, float msgtime)
simtime = realtime - demo_latency; simtime = realtime - demo_latency;
// adjust latency // adjust latency
if (simtime > lerp_times[0]) { if (simtime > lerp_times[0])
{
// Com_DPrintf ("HIGH clamp\n"); // Com_DPrintf ("HIGH clamp\n");
demo_latency = realtime - lerp_times[0]; demo_latency = realtime - lerp_times[0];
} }
else if (simtime < lerp_times[2]) { else if (simtime < lerp_times[2])
{
// Com_DPrintf (" low clamp\n"); // Com_DPrintf (" low clamp\n");
demo_latency = realtime - lerp_times[2]; demo_latency = realtime - lerp_times[2];
} else { }
else
{
// drift towards ideal latency // drift towards ideal latency
float ideal_latency = (lerp_times[0] - lerp_times[2]) * 0.6; float ideal_latency = (lerp_times[0] - lerp_times[2]) * 0.6;
if (demo_latency > ideal_latency) if (demo_latency > ideal_latency)
@ -601,10 +608,13 @@ static void CL_LerpMove (int pnum, float msgtime)
} }
// decide where to lerp from // decide where to lerp from
if (simtime > lerp_times[1]) { if (simtime > lerp_times[1])
{
from = 1; from = 1;
to = 0; to = 0;
} else { }
else
{
from = 2; from = 2;
to = 1; to = 1;
} }
@ -727,6 +737,7 @@ void CL_PredictMovePNum (int pnum)
//these are to make svc_viewentity work better //these are to make svc_viewentity work better
float *vel; float *vel;
float *org; float *org;
float stepheight = 0;
cl.nolocalplayer[pnum] = false; cl.nolocalplayer[pnum] = false;
@ -796,42 +807,7 @@ void CL_PredictMovePNum (int pnum)
vel = vec3_origin; vel = vec3_origin;
goto fixedorg; goto fixedorg;
} }
}
/* entity_state_t *CL_FindOldPacketEntity(int num);
entity_state_t *CL_FindPacketEntity(int num);
entity_state_t *state;
state = CL_FindPacketEntity (cl.viewentity[pnum]);
if (state && state->number < cl.maxlerpents)
{
float f;
extern cvar_t cl_nolerp;
//figure out the lerp factor
if (cl.lerpents[state->number].lerprate<=0)
f = 0;
else
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
if (f<0)
f=0;
if (f>1)
f=1;
f = 1-f;
// Con_Printf("%f\n", f);
// if (cl_nolerp.ival)
// f = 1;
// calculate origin
for (i=0 ; i<3 ; i++)
lrp[i] = cl.lerpents[state->number].origin[i] +
f * (state->origin[i] - cl.lerpents[state->number].origin[i]);
org = lrp;
goto fixedorg;
}
*/ }
#endif #endif
if (!from->playerstate[cl.playernum[pnum]].messagenum) if (!from->playerstate[cl.playernum[pnum]].messagenum)
{ {
@ -925,6 +901,7 @@ fixedorg:
cl.onground[pnum] = pmove.onground; cl.onground[pnum] = pmove.onground;
} }
stepheight = to->playerstate[cl.playernum[pnum]].origin[2] - from->playerstate[cl.playernum[pnum]].origin[2];
} }
pmove.numphysent = oldphysent; pmove.numphysent = oldphysent;
@ -972,7 +949,7 @@ fixedorg:
CL_LerpMove (pnum, to->senttime); CL_LerpMove (pnum, to->senttime);
out: out:
CL_CalcCrouch (pnum); CL_CalcCrouch (pnum, stepheight);
cl.waterlevel[pnum] = pmove.waterlevel; cl.waterlevel[pnum] = pmove.waterlevel;
} }

View file

@ -445,18 +445,20 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p)
p->erase_center = 0; p->erase_center = 0;
if (p->flags & CPRINT_BACKGROUND)
{ //hexen2 style plaque.
int lines, len;
if (rect->width > 320)
{
rect->x = (rect->x + rect->width/2) - 160;
rect->width = 320;
}
}
Font_BeginString(font_conchar, rect->x, rect->y, &left, &top); Font_BeginString(font_conchar, rect->x, rect->y, &left, &top);
Font_BeginString(font_conchar, rect->x+rect->width, rect->y+rect->height, &right, &bottom); Font_BeginString(font_conchar, rect->x+rect->width, rect->y+rect->height, &right, &bottom);
linecount = Font_LineBreaks(p->string, p->string + p->charcount, right - left, MAX_CPRINT_LINES, line_start, line_end); linecount = Font_LineBreaks(p->string, p->string + p->charcount, right - left, MAX_CPRINT_LINES, line_start, line_end);
if (p->flags & CPRINT_BACKGROUND)
{ //hexen2 style plaque.
// int lines, len;
// SCR_CenterPrintBreaks(start, &lines, &len);
// x = rect.x+(rect.width-len*8)/2;
// Draw_TextBox(x-6, y-8, len-1, lines);
}
if (p->flags & CPRINT_TALIGN) if (p->flags & CPRINT_TALIGN)
y = top; y = top;
else if (p->flags & CPRINT_BALIGN) else if (p->flags & CPRINT_BALIGN)
@ -479,6 +481,13 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p)
y = (bottom-top - Font_CharHeight()*linecount) * 0.5 + top; y = (bottom-top - Font_CharHeight()*linecount) * 0.5 + top;
} }
} }
if (p->flags & CPRINT_BACKGROUND)
{ //hexen2 style plaque.
x = rect->x+(rect->width-320)/2;
Draw_TextBox(x-6, y-8, 320/8-1, linecount);
}
for (l = 0; l < linecount; l++, y += Font_CharHeight()) for (l = 0; l < linecount; l++, y += Font_CharHeight())
{ {
if (p->flags & CPRINT_RALIGN) if (p->flags & CPRINT_RALIGN)
@ -1060,7 +1069,10 @@ Keybinding command
*/ */
void SCR_SizeUp_f (void) void SCR_SizeUp_f (void)
{ {
Cvar_SetValue (&scr_viewsize,scr_viewsize.value+10); if (Cmd_FromGamecode())
Cvar_ForceSet(&scr_viewsize,va("%i", scr_viewsize.ival+10));
else
Cvar_SetValue (&scr_viewsize,scr_viewsize.value+10);
} }
@ -1073,7 +1085,10 @@ Keybinding command
*/ */
void SCR_SizeDown_f (void) void SCR_SizeDown_f (void)
{ {
Cvar_SetValue (&scr_viewsize,scr_viewsize.value-10); if (Cmd_FromGamecode())
Cvar_ForceSet(&scr_viewsize,va("%i", scr_viewsize.ival-10));
else
Cvar_SetValue (&scr_viewsize,scr_viewsize.value-10);
} }
//============================================================================ //============================================================================
@ -1228,7 +1243,11 @@ void SCR_DrawFPS (void)
#ifdef GLQUAKE #ifdef GLQUAKE
case 5: case 5:
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
GLR_FrameTimeGraph((int)(1000.0*1.5*host_frametime)); GLR_FrameTimeGraph((int)(1000.0*2*host_frametime));
break;
case 7:
if (qrenderer == QR_OPENGL)
GLR_FrameTimeGraph((int)(1000.0*1*host_frametime));
break; break;
#endif #endif
case 6: case 6:

View file

@ -2861,10 +2861,13 @@ void CL_UpdateExplosions (void)
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
ent->model = ex->model; ent->model = ex->model;
ent->framestate.g[FS_REG].frame[0] = (int)f+firstframe; ent->framestate.g[FS_REG].frame[1] = (int)f+firstframe;
ent->framestate.g[FS_REG].frame[1] = of+firstframe; ent->framestate.g[FS_REG].frame[0] = of+firstframe;
ent->framestate.g[FS_REG].lerpfrac = 1-(f - (int)f); ent->framestate.g[FS_REG].lerpfrac = (f - (int)f);
ent->shaderRGBAf[3] = 1.0 - f/(numframes); if (ent->model->type == mod_sprite)
ent->shaderRGBAf[3] = 1;
else
ent->shaderRGBAf[3] = 1.0 - f/(numframes);
ent->flags = ex->flags; ent->flags = ex->flags;
} }

View file

@ -601,7 +601,6 @@ void VQ3_RenderView(const q3refdef_t *ref)
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
{ {
gl_ztrickdisabled|=16;
qglDisable(GL_ALPHA_TEST); qglDisable(GL_ALPHA_TEST);
qglDisable(GL_BLEND); qglDisable(GL_BLEND);
} }
@ -610,7 +609,6 @@ void VQ3_RenderView(const q3refdef_t *ref)
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
{ {
gl_ztrickdisabled&=~16;
GL_Set2D (); GL_Set2D ();
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_TexEnv(GL_MODULATE); GL_TexEnv(GL_MODULATE);

View file

@ -263,6 +263,7 @@ typedef struct dlight_s
unsigned int flags; unsigned int flags;
//the following are used for rendering (client code should clear on create) //the following are used for rendering (client code should clear on create)
qboolean rebuildcache;
struct shadowmesh_s *worldshadowmesh; struct shadowmesh_s *worldshadowmesh;
texid_t stexture; texid_t stexture;
struct { struct {
@ -315,6 +316,7 @@ typedef struct
// connection information // connection information
cactive_t state; cactive_t state;
/*Specifies which protocol family we're speaking*/
enum { enum {
CP_UNKNOWN, CP_UNKNOWN,
CP_QUAKEWORLD, CP_QUAKEWORLD,
@ -324,6 +326,25 @@ typedef struct
CP_PLUGIN CP_PLUGIN
} protocol; } protocol;
/*QuakeWorld protocol flags*/
#ifdef PROTOCOLEXTENSIONS
unsigned long fteprotocolextensions;
unsigned long fteprotocolextensions2;
#endif
unsigned long z_ext;
/*NQ Protocol flags*/
enum
{
CPNQ_ID,
CPNQ_FITZ666,
CPNQ_DP5,
CPNQ_DP6,
CPNQ_DP7
} protocol_nq;
#define CPNQ_IS_DP (cls.protocol_nq >= CPNQ_DP5)
qboolean resendinfo; qboolean resendinfo;
qboolean findtrack; qboolean findtrack;
@ -397,11 +418,6 @@ typedef struct
float maxfps; //server capped float maxfps; //server capped
enum {GAME_DEATHMATCH, GAME_COOP} gamemode; enum {GAME_DEATHMATCH, GAME_COOP} gamemode;
#ifdef PROTOCOLEXTENSIONS
unsigned long fteprotocolextensions;
unsigned long fteprotocolextensions2;
#endif
unsigned long z_ext;
#ifdef NQPROT #ifdef NQPROT
int signon; int signon;
#endif #endif
@ -412,8 +428,6 @@ typedef struct
extern client_static_t cls; extern client_static_t cls;
extern int nq_dp_protocol;
typedef struct downloadlist_s { typedef struct downloadlist_s {
char rname[128]; char rname[128];
char localname[128]; char localname[128];
@ -695,20 +709,20 @@ extern cvar_t ruleset_allow_sensative_texture_replacements;
extern cvar_t ruleset_allow_localvolume; extern cvar_t ruleset_allow_localvolume;
extern cvar_t ruleset_allow_shaders; extern cvar_t ruleset_allow_shaders;
#define MAX_STATIC_ENTITIES 256 // torches, etc
extern client_state_t cl; extern client_state_t cl;
typedef struct typedef struct
{ {
entity_t ent; entity_t ent;
trailstate_t *emit; trailstate_t *emit;
int mdlidx; /*negative are csqc indexes*/
pvscache_t pvscache; pvscache_t pvscache;
} static_entity_t; } static_entity_t;
// FIXME, allocate dynamically // FIXME, allocate dynamically
extern entity_state_t *cl_baselines; extern entity_state_t *cl_baselines;
extern static_entity_t cl_static_entities[MAX_STATIC_ENTITIES]; extern static_entity_t *cl_static_entities;
extern unsigned int cl_max_static_entities;
extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
extern dlight_t *cl_dlights; extern dlight_t *cl_dlights;
extern unsigned int cl_maxdlights; extern unsigned int cl_maxdlights;
@ -820,6 +834,7 @@ void CL_UpdateTEnts (void);
void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end); void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end);
void CL_ClearState (void); void CL_ClearState (void);
void CLQ2_ClearState(void);
void CL_ReadPackets (void); void CL_ReadPackets (void);
void CL_ClampPitch (int pnum); void CL_ClampPitch (int pnum);

View file

@ -113,6 +113,11 @@ entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
void Q2S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol, float attenuation, float timeofs); void Q2S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol, float attenuation, float timeofs);
void CL_SmokeAndFlash(vec3_t origin); void CL_SmokeAndFlash(vec3_t origin);
void CLQ2_ClearState(void)
{
memset(cl_entities, 0, sizeof(cl_entities));
}
//extern struct model_s *cl_mod_powerscreen; //extern struct model_s *cl_mod_powerscreen;
//PGM //PGM
@ -894,7 +899,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
while (oldnum < newnum) while (oldnum < newnum)
{ // one or more entities from the old packet are unchanged { // one or more entities from the old packet are unchanged
if (cl_shownet.value == 3) if (cl_shownet.ival == 3)
Con_Printf (" unchanged: %i\n", oldnum); Con_Printf (" unchanged: %i\n", oldnum);
CLQ2_DeltaEntity (newframe, oldnum, oldstate, 0); CLQ2_DeltaEntity (newframe, oldnum, oldstate, 0);
@ -911,7 +916,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
if (bits & Q2U_REMOVE) if (bits & Q2U_REMOVE)
{ // the entity present in oldframe is not in the current frame { // the entity present in oldframe is not in the current frame
if (cl_shownet.value == 3) if (cl_shownet.ival == 3)
Con_Printf (" remove: %i\n", newnum); Con_Printf (" remove: %i\n", newnum);
if (oldnum != newnum) if (oldnum != newnum)
Con_Printf ("U_REMOVE: oldnum != newnum\n"); Con_Printf ("U_REMOVE: oldnum != newnum\n");
@ -930,7 +935,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
if (oldnum == newnum) if (oldnum == newnum)
{ // delta from previous state { // delta from previous state
if (cl_shownet.value == 3) if (cl_shownet.ival == 3)
Con_Printf (" delta: %i\n", newnum); Con_Printf (" delta: %i\n", newnum);
CLQ2_DeltaEntity (newframe, newnum, oldstate, bits); CLQ2_DeltaEntity (newframe, newnum, oldstate, bits);
@ -948,7 +953,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
if (oldnum > newnum) if (oldnum > newnum)
{ // delta from baseline { // delta from baseline
if (cl_shownet.value == 3) if (cl_shownet.ival == 3)
Con_Printf (" baseline: %i\n", newnum); Con_Printf (" baseline: %i\n", newnum);
CLQ2_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits); CLQ2_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits);
continue; continue;
@ -959,7 +964,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
// any remaining entities in the old frame are copied over // any remaining entities in the old frame are copied over
while (oldnum != 99999) while (oldnum != 99999)
{ // one or more entities from the old packet are unchanged { // one or more entities from the old packet are unchanged
if (cl_shownet.value == 3) if (cl_shownet.ival == 3)
Con_Printf (" unchanged: %i\n", oldnum); Con_Printf (" unchanged: %i\n", oldnum);
CLQ2_DeltaEntity (newframe, oldnum, oldstate, 0); CLQ2_DeltaEntity (newframe, oldnum, oldstate, 0);
@ -2070,25 +2075,12 @@ void CLQ2_AddEntities (void)
else else
cl.lerpfrac = 1.0 - (cl.q2frame.servertime - cl.time*1000) * 0.01; cl.lerpfrac = 1.0 - (cl.q2frame.servertime - cl.time*1000) * 0.01;
// if (cl_timedemo.value)
// cl.lerpfrac = 1.0;
// CLQ2_AddPacketEntities (&cl.qwframe);
// CLQ2_AddTEnts ();
// CLQ2_AddParticles ();
// CLQ2_AddDLights ();
// CLQ2_AddLightStyles ();
CLQ2_CalcViewValues (); CLQ2_CalcViewValues ();
// PMM - moved this here so the heat beam has the right values for the vieworg, and can lock the beam to the gun
CLQ2_AddPacketEntities (&cl.q2frame); CLQ2_AddPacketEntities (&cl.q2frame);
#if 0 #if 0
CLQ2_AddProjectiles (); CLQ2_AddProjectiles ();
#endif #endif
CL_UpdateTEnts (); CL_UpdateTEnts ();
// CLQ2_AddParticles ();
// CLQ2_AddDLights ();
// CLQ2_AddLightStyles ();
} }
void CL_GetNumberedEntityInfo (int num, float *org, float *ang) void CL_GetNumberedEntityInfo (int num, float *org, float *ang)

View file

@ -623,7 +623,7 @@ void CLQ3_ParseServerMessage (void)
Con_TPrintf (TLC_LINEBREAK_MINUS); Con_TPrintf (TLC_LINEBREAK_MINUS);
net_message.packing = SZ_RAWBYTES; net_message.packing = SZ_RAWBYTES;
MSG_BeginReading(); MSG_BeginReading(msg_nullnetprim);
ccs.serverMessageNum = MSG_ReadLong(); ccs.serverMessageNum = MSG_ReadLong();
net_message.packing = SZ_HUFFMAN; //the rest is huffman compressed. net_message.packing = SZ_HUFFMAN; //the rest is huffman compressed.
net_message.currentbit = msg_readcount*8; net_message.currentbit = msg_readcount*8;

View file

@ -1951,6 +1951,44 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, char *fn
return NULL; return NULL;
} }
static struct
{
char *name;
int enabled;
} tex_extensions[] =
{//reverse order of preference - (match commas with optional file types)
{".pcx", 1}, //pcxes are the original gamedata of q2. So we don't want them to override pngs.
#ifdef AVAIL_JPEGLIB
{".jpg", 1}, //q3 uses some jpegs, for some reason
#endif
{".bmp", 0}, //wtf? at least not lossy
#ifdef AVAIL_PNGLIB
{".png", 1}, //pngs, fairly common, but slow
#endif
{".tga", 1}, //fairly fast to load
#ifdef DDS
{".dds", 1}, //compressed or something
#endif
{"", 1} //someone forgot an extension
};
static struct
{
int args;
char *path;
int enabled;
} tex_path[] =
{
/*if three args, first is the subpath*/
/*the last two args are texturename then extension*/
{2, "%s%s", 1}, /*directly named texture*/
{3, "textures/%s/%s%s", 1}, /*fuhquake compatibility*/
{3, "%s/%s%s", 1}, /*fuhquake compatibility*/
{2, "textures/%s%s", 1}, /*directly named texture with textures/ prefix*/
{2, "override/%s%s", 1} /*tenebrae compatibility*/
};
int image_width, image_height; int image_width, image_height;
qbyte *COM_LoadFile (char *path, int usehunk); qbyte *COM_LoadFile (char *path, int usehunk);
//fixme: should probably get rid of the 'Mod' prefix, and use something more suitable. //fixme: should probably get rid of the 'Mod' prefix, and use something more suitable.
@ -1962,31 +2000,6 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
// int h; // int h;
char fname[MAX_QPATH], nicename[MAX_QPATH]; char fname[MAX_QPATH], nicename[MAX_QPATH];
static char *extensions[] =
{//reverse order of preference - (match commas with optional file types)
".pcx", //pcxes are the original gamedata of q2. So we don't want them to override pngs.
#ifdef AVAIL_JPEGLIB
".jpg",
#endif
".bmp",
#ifdef AVAIL_PNGLIB
".png",
#endif
".tga",
""
};
static char *path[] =
{
/*if three args, first is the subpath*/
/*the last two args are texturename then extension*/
"2%s%s",
"3textures/%s/%s%s",
"3%s/%s%s",
"2textures/%s%s",
"2override/%s%s"
};
int i, e; int i, e;
image_width = 0; image_width = 0;
@ -2020,39 +2033,34 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
i = 1; i = 1;
//should write this nicer. //should write this nicer.
for (; i < sizeof(path)/sizeof(char *); i++) for (; i < sizeof(tex_path)/sizeof(tex_path[0]); i++)
{ {
#ifdef DDS if (!tex_path[i].enabled)
if (path[i][0] >= '3') continue;
for (e = sizeof(tex_extensions)/sizeof(tex_extensions[0])-1; e >=0 ; e--)
{ {
if (!subpath) if (!tex_extensions[e].enabled)
continue; continue;
snprintf(fname, sizeof(fname)-1, path[i]+1, subpath, /*COM_SkipPath*/(nicename), ".dds");
}
else
snprintf(fname, sizeof(fname)-1, path[i]+1, nicename, ".dds");
if ((buf = COM_LoadFile (fname, 5)))
{
tex = GL_LoadTextureDDS(buf, com_filesize);
BZ_Free(buf);
if (TEXVALID(tex))
return tex;
}
#endif
for (e = sizeof(extensions)/sizeof(char *)-1; e >=0 ; e--) if (tex_path[i].args >= 3)
{
if (path[i][0] >= '3')
{ {
if (!subpath) if (!subpath)
continue; continue;
snprintf(fname, sizeof(fname)-1, path[i]+1, subpath, /*COM_SkipPath*/(nicename), extensions[e]); snprintf(fname, sizeof(fname)-1, tex_path[i].path, subpath, nicename, tex_extensions[e].name);
} }
else else
snprintf(fname, sizeof(fname)-1, path[i]+1, nicename, extensions[e]); snprintf(fname, sizeof(fname)-1, tex_path[i].path, nicename, tex_extensions[e].name);
TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname)); TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname));
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
#ifdef DDS
tex = GL_LoadTextureDDS(buf, com_filesize);
if (TEXVALID(tex))
{
BZ_Free(buf);
return tex;
}
#endif
if ((data = Read32BitImageFile(buf, com_filesize, &image_width, &image_height, fname))) if ((data = Read32BitImageFile(buf, com_filesize, &image_width, &image_height, fname)))
{ {
extern cvar_t vid_hardwaregamma; extern cvar_t vid_hardwaregamma;
@ -2132,14 +2140,6 @@ texid_t R_LoadBumpmapTexture(char *name, char *subpath)
"" ""
}; };
static char *path[] =
{
"%s%s",
"textures/%s/%s%s", //this is special... It's special name is Mr Ben Ian Graham Hacksworth.
"textures/%s%s",
"override/%s%s"
};
int i, e; int i, e;
TRACE(("dbg: Mod_LoadBumpmapTexture: texture %s\n", name)); TRACE(("dbg: Mod_LoadBumpmapTexture: texture %s\n", name));
@ -2160,23 +2160,20 @@ texid_t R_LoadBumpmapTexture(char *name, char *subpath)
i = 1; i = 1;
//should write this nicer. //should write this nicer.
for (; i < sizeof(path)/sizeof(char *); i++) for (; i < sizeof(tex_path)/sizeof(tex_path[0]); i++)
{ {
if (!tex_path[i].enabled)
continue;
for (e = sizeof(extensions)/sizeof(char *)-1; e >=0 ; e--) for (e = sizeof(extensions)/sizeof(char *)-1; e >=0 ; e--)
{ {
if (i == 1) if (tex_path[i].args >= 3)
{ {
char map [MAX_QPATH*2]; if (!subpath)
#ifndef CLIENTONLY continue;
if (*sv.name) //server loads before the client knows what's happening. I suppose we could have some sort of param... snprintf(fname, sizeof(fname)-1, tex_path[i].path, subpath, nicename, extensions[e]);
Q_strncpyz(map, sv.name, sizeof(map));
else
#endif
COM_FileBase(cl.model_name[1], map, sizeof(map));
snprintf(fname, sizeof(fname)-1, path[i], map, nicename, extensions[e]);
} }
else else
snprintf(fname, sizeof(fname)-1, path[i], nicename, extensions[e]); snprintf(fname, sizeof(fname)-1, tex_path[i].path, nicename, extensions[e]);
TRACE(("dbg: Mod_LoadBumpmapTexture: opening %s\n", fname)); TRACE(("dbg: Mod_LoadBumpmapTexture: opening %s\n", fname));

View file

@ -106,7 +106,7 @@ void Draw_Hexen2BigFontString(int x, int y, const char *text)
sy=-1; sy=-1;
} }
if(sx>=0) if(sx>=0)
Draw_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*8); Draw_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*4);
x+=20; x+=20;
text++; text++;
} }

View file

@ -85,7 +85,7 @@ static void NM_PrintWhite (int cx, int cy, qbyte *str)
static void NM_PrintColoured (int cx, int cy, int colour, qbyte *str) static void NM_PrintColoured (int cx, int cy, int colour, qbyte *str)
{ {
#pragma message("needs reimplementing") #pragma message("NM_PrintColoured: needs reimplementing")
/* /*
while (*str) while (*str)
{ {
@ -98,7 +98,7 @@ static void NM_PrintColoured (int cx, int cy, int colour, qbyte *str)
static void NM_PrintHighlighted (int cx, int cy, int colour, int bg, qbyte *str) static void NM_PrintHighlighted (int cx, int cy, int colour, int bg, qbyte *str)
{ {
#pragma message("needs reimplementing") #pragma message("NM_PrintHighlighted: needs reimplementing")
/* /*
while (*str) while (*str)
{ {
@ -258,7 +258,7 @@ int M_AddColumn (int right, int y, char *text, int maxchars, int colour, int hig
right = left; right = left;
#pragma message("needs reimplementing") #pragma message("M_AddColumn: needs reimplementing")
/* /*
if (highlight >= 0) if (highlight >= 0)
{ {

View file

@ -920,7 +920,7 @@ void M_Menu_Textures_f (void)
extern cvar_t r_bloom_sample_size, r_bloom_darken, r_bloom_intensity, r_bloom_diamond_size, r_bloom_alpha, r_bloom_fast_sample; extern cvar_t r_bloom_sample_size, r_bloom_darken, r_bloom_intensity, r_bloom_diamond_size, r_bloom_alpha, r_bloom_fast_sample;
#endif #endif
extern cvar_t r_bloom, gl_load24bit, gl_specular, r_waterlayers, gl_bump, gl_detail, gl_detailscale, gl_compress, gl_savecompressedtex, gl_ztrick, gl_triplebuffer, gl_picmip, gl_picmip2d, gl_playermip, gl_max_size, r_stains, r_bloodstains, r_stainfadetime, r_stainfadeammount, gl_skyboxdist, r_drawflat, gl_schematics, gl_texturemode, gl_texture_anisotropic_filtering; extern cvar_t r_bloom, gl_load24bit, gl_specular, r_waterlayers, gl_bump, gl_detail, gl_detailscale, gl_compress, gl_savecompressedtex, gl_triplebuffer, gl_picmip, gl_picmip2d, gl_playermip, gl_max_size, r_stains, r_bloodstains, r_stainfadetime, r_stainfadeammount, gl_skyboxdist, r_drawflat, gl_schematics, gl_texturemode, gl_texture_anisotropic_filtering;
int y; int y;
menu_t *menu = M_Options_Title(&y, sizeof(*info)); menu_t *menu = M_Options_Title(&y, sizeof(*info));
info = menu->data; info = menu->data;
@ -1029,7 +1029,6 @@ void M_Menu_Textures_f (void)
MC_AddSlider(menu, 16, y, " Texture Detail Scale", &gl_detailscale,0,10,1); y+=8; MC_AddSlider(menu, 16, y, " Texture Detail Scale", &gl_detailscale,0,10,1); y+=8;
MC_AddCheckBox(menu, 16, y, " Texture Compression", &gl_compress,0); y+=8; MC_AddCheckBox(menu, 16, y, " Texture Compression", &gl_compress,0); y+=8;
MC_AddCheckBox(menu, 16, y, "Save Compressed Textures", &gl_savecompressedtex,0); y+=8; MC_AddCheckBox(menu, 16, y, "Save Compressed Textures", &gl_savecompressedtex,0); y+=8;
MC_AddCheckBox(menu, 16, y, " Z Trick", &gl_ztrick,0); y+=8;
MC_AddCheckBox(menu, 16, y, " Triple Buffering", &gl_triplebuffer,0); y+=8; MC_AddCheckBox(menu, 16, y, " Triple Buffering", &gl_triplebuffer,0); y+=8;
MC_AddSlider(menu, 16, y, " 3D Texture Picmip", &gl_picmip,0,16,1); y+=8; MC_AddSlider(menu, 16, y, " 3D Texture Picmip", &gl_picmip,0,16,1); y+=8;
MC_AddSlider(menu, 16, y, " 2D Texture Picmip", &gl_picmip2d,0,16,1); y+=8; MC_AddSlider(menu, 16, y, " 2D Texture Picmip", &gl_picmip2d,0,16,1); y+=8;

View file

@ -164,9 +164,18 @@ void M_Menu_SinglePlayer_f (void)
} }
else if (mgt == MGT_HEXEN2) else if (mgt == MGT_HEXEN2)
{ //h2 { //h2
int y;
cvar_t *pc; cvar_t *pc;
qboolean havemp;
static char *classlist[] = { static char *classlist[] = {
"Random", "Random",
"Paladin",
"Crusader",
"Necromancer",
"Assasin",
NULL
};
static char *classlistmp[] = {
"Paladin", "Paladin",
"Crusader", "Crusader",
"Necromancer", "Necromancer",
@ -183,21 +192,34 @@ void M_Menu_SinglePlayer_f (void)
"5", "5",
NULL NULL
}; };
havemp = COM_FCheckExists("maps/keep1.bsp");
menu = M_CreateMenu(0); menu = M_CreateMenu(0);
MC_AddPicture(menu, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); MC_AddPicture(menu, 16, 0, 35, 176, "gfx/menu/hplaque.lmp");
MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title1.lmp"); MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title1.lmp");
menu->selecteditem = (menuoption_t*) y = 64-8;
MC_AddConsoleCommand (menu, 64, 64, "Easy", "closemenu\nskill 0;deathmatch 0; coop 0;map demo1\n");
MC_AddConsoleCommand (menu, 64, 72, "Medium", "closemenu\nskill 1;deathmatch 0; coop 0;map demo1\n");
MC_AddConsoleCommand (menu, 64, 80, "Hard", "closemenu\nskill 2;deathmatch 0; coop 0;map demo1\n");
MC_AddConsoleCommand (menu, 64, 96, "Load Game", "menu_load\n");
MC_AddConsoleCommand (menu, 64, 104, "Save Game", "menu_save\n");
pc = Cvar_Get("cl_playerclass", "1", CVAR_USERINFO|CVAR_ARCHIVE, "Hexen2"); pc = Cvar_Get("cl_playerclass", "1", CVAR_USERINFO|CVAR_ARCHIVE, "Hexen2");
if (pc) if (pc)
MC_AddCvarCombo (menu, 64, 104+16, "Player class", pc, (const char **)classlist, (const char **)classvalues); MC_AddCvarCombo (menu, 64, y+=8, "Player class", pc, havemp?(const char **)classlistmp:(const char **)classlist, (const char **)(classvalues+havemp));
y+=8;
menu->selecteditem = (menuoption_t*)
MC_AddConsoleCommand (menu, 64, y+=8, "Classic: Easy", "closemenu\nskill 0;deathmatch 0; coop 0;disconnect;wait;map demo1\n");
MC_AddConsoleCommand (menu, 64, y+=8, "Classic: Medium", "closemenu\nskill 1;deathmatch 0; coop 0;disconnect;wait;map demo1\n");
MC_AddConsoleCommand (menu, 64, y+=8, "Classic: Hard", "closemenu\nskill 2;deathmatch 0; coop 0;disconnect;wait;map demo1\n");
y+=8;
if (havemp)
{
MC_AddConsoleCommand(menu, 64, y+=8, "Expansion: Easy", "closemenu\nskill 0;deathmatch 0; coop 0;disconnect;wait;map keep1\n");
MC_AddConsoleCommand(menu, 64, y+=8, "Expansion: Medium", "closemenu\nskill 1;deathmatch 0; coop 0;disconnect;wait;map keep1\n");
MC_AddConsoleCommand(menu, 64, y+=8, "Expansion: Hard", "closemenu\nskill 2;deathmatch 0; coop 0;disconnect;wait;map keep1\n");
y+=8;
}
MC_AddConsoleCommand (menu, 64, y+=8, "Load Game", "menu_load\n");
MC_AddConsoleCommand (menu, 64, y+=8, "Save Game", "menu_save\n");
return; return;
} }

View file

@ -57,25 +57,6 @@ typedef enum { ALIAS_SINGLE=0, ALIAS_GROUP, ALIAS_GROUP_SWAPPED=16777216 } alias
typedef enum { ALIAS_SKIN_SINGLE=0, ALIAS_SKIN_GROUP } aliasskintype_t; typedef enum { ALIAS_SKIN_SINGLE=0, ALIAS_SKIN_GROUP } aliasskintype_t;
typedef struct {
int ident;
int version;
vec3_t scale;
vec3_t scale_origin;
float boundingradius;
vec3_t eyeposition;
int numskins;
int skinwidth;
int skinheight;
int numverts;
int numstverts;
int numtris;
int numframes;
synctype_t synctype;
int flags;
float size;
} mmdl_t;
typedef struct { typedef struct {
int ident; int ident;
int version; int version;
@ -90,8 +71,12 @@ typedef struct {
int numtris; int numtris;
int numframes; int numframes;
synctype_t synctype; synctype_t synctype;
//qtest stops here
int flags; int flags;
float size; float size;
//quake stops here
int num_st;
//rapo stops here
} dmdl_t; } dmdl_t;
// TODO: could be shorts // TODO: could be shorts
@ -112,6 +97,12 @@ typedef struct dtriangle_s {
int vertindex[3]; int vertindex[3];
} dtriangle_t; } dtriangle_t;
typedef struct dh2triangle_s {
int facesfront;
unsigned short vertindex[3];
unsigned short stindex[3];
} dh2triangle_t;
typedef struct dmd2triangle_s { typedef struct dmd2triangle_s {
short xyz_index[3]; short xyz_index[3];
short st_index[3]; short st_index[3];
@ -165,7 +156,8 @@ typedef struct {
aliasskintype_t type; aliasskintype_t type;
} daliasskintype_t; } daliasskintype_t;
#define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') #define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') /*little-endian "IDPO"*/
#define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') #define RAPOLYHEADER (('O'<<24)+('P'<<16)+('A'<<8)+'R') /*used by hexen2 mp*/
// little-endian "IDPO" #define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') /*quake3, duh*/

View file

@ -902,7 +902,7 @@ int NET_CheckPollSockets(void)
int c; int c;
char *s; char *s;
MSG_BeginReading (); MSG_BeginReading (msg_nullnetprim);
MSG_ReadLong (); // skip the -1 MSG_ReadLong (); // skip the -1
c = msg_readcount; c = msg_readcount;
@ -995,7 +995,7 @@ int NET_CheckPollSockets(void)
int control; int control;
MSG_BeginReading (); MSG_BeginReading (msg_nullnetprim);
control = BigLong(*((int *)net_message.data)); control = BigLong(*((int *)net_message.data));
MSG_ReadLong(); MSG_ReadLong();
if (control == -1) if (control == -1)

View file

@ -31,7 +31,7 @@ static void PNULL_RunParticleEffect4 (vec3_t org, float radius, int color, int e
static void PNULL_ParticleTrailIndex (vec3_t start, vec3_t end, int color, int crnd, trailstate_t **tsk){} static void PNULL_ParticleTrailIndex (vec3_t start, vec3_t end, int color, int crnd, trailstate_t **tsk){}
static void PNULL_EmitSkyEffectTris(model_t *mod, msurface_t *fa){} static void PNULL_EmitSkyEffectTris(model_t *mod, msurface_t *fa){}
static int PNULL_InitParticles (void) static qboolean PNULL_InitParticles (void)
{ {
CL_RegisterParticles(); CL_RegisterParticles();
return true; return true;

View file

@ -134,6 +134,7 @@ typedef struct {
float scalefactor; float scalefactor;
float invscalefactor; float invscalefactor;
float stretch;
} plooks_t; } plooks_t;
//these could be deltas or absolutes depending on ramping mode. //these could be deltas or absolutes depending on ramping mode.
@ -360,7 +361,8 @@ static part_type_t *P_GetParticleType(char *name)
ptype = &part_type[numparticletypes++]; ptype = &part_type[numparticletypes++];
memset(ptype, 0, sizeof(*ptype)); memset(ptype, 0, sizeof(*ptype));
strcpy(ptype->name, name); strcpy(ptype->name, name);
ptype->assoc=P_INVALID; ptype->assoc = P_INVALID;
ptype->inwater = P_INVALID;
ptype->cliptype = P_INVALID; ptype->cliptype = P_INVALID;
ptype->emit = P_INVALID; ptype->emit = P_INVALID;
@ -470,8 +472,13 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
if (qrenderer == QR_NONE) if (qrenderer == QR_NONE)
return; return;
/*try and load the shader, fail if we would need to generate one*/ if (*ptype->texname)
ptype->looks.shader = R_RegisterCustom(ptype->texname, NULL, NULL); {
/*try and load the shader, fail if we would need to generate one*/
ptype->looks.shader = R_RegisterCustom(ptype->texname, NULL, NULL);
}
else
ptype->looks.shader = NULL;
if (!ptype->looks.shader) if (!ptype->looks.shader)
{ {
@ -1410,6 +1417,8 @@ void FinishParticleType(part_type_t *ptype)
/*too lazy to go through ramps*/ /*too lazy to go through ramps*/
ptype->looks.scalefactor = 1; ptype->looks.scalefactor = 1;
} }
if (ptype->looks.type == PT_TEXTUREDSPARK)
ptype->looks.stretch *= 0.04;
} }
static void P_ImportEffectInfo_f(void) static void P_ImportEffectInfo_f(void)
@ -1499,6 +1508,7 @@ static void P_ImportEffectInfo_f(void)
ptype->looks.invscalefactor = 0; ptype->looks.invscalefactor = 0;
ptype->looks.type = PT_NORMAL; ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_BLEND; ptype->looks.blendmode = BM_BLEND;
ptype->looks.stretch = 1;
} }
else if (!ptype) else if (!ptype)
{ {
@ -1565,7 +1575,7 @@ static void P_ImportEffectInfo_f(void)
ptype->t1 = 1/8.0 * (mini>>3); ptype->t1 = 1/8.0 * (mini>>3);
ptype->t2 = 1/8.0 * (1+(mini>>3)); ptype->t2 = 1/8.0 * (1+(mini>>3));
ptype->texsstride = 1/8.0; ptype->texsstride = 1/8.0;
ptype->randsmax = (maxi - mini)+1; ptype->randsmax = (maxi - mini);
if (ptype->randsmax < 1) if (ptype->randsmax < 1)
ptype->randsmax = 1; ptype->randsmax = 1;
} }
@ -1647,6 +1657,8 @@ static void P_ImportEffectInfo_f(void)
ptype->randdie = atof(arg[1]) - ptype->die; ptype->randdie = atof(arg[1]) - ptype->die;
} }
} }
else if (!strcmp(arg[0], "stretchfactor") && args == 2)
ptype->looks.stretch = atof(arg[1]);
#if 0 #if 0
else if (!strcmp(arg[0], "blend") && args == 2) else if (!strcmp(arg[0], "blend") && args == 2)
; /*overrides blendmode*/ ; /*overrides blendmode*/
@ -1656,8 +1668,6 @@ static void P_ImportEffectInfo_f(void)
; ;
else if (!strcmp(arg[0], "lightcubemapnum") && args == 2) else if (!strcmp(arg[0], "lightcubemapnum") && args == 2)
; ;
else if (!strcmp(arg[0], "stretchfactor") && args == 2)
;
else if (!strcmp(arg[0], "staincolor") && args == 2) else if (!strcmp(arg[0], "staincolor") && args == 2)
; ;
else if (!strcmp(arg[0], "stainalpha") && args == 2) else if (!strcmp(arg[0], "stainalpha") && args == 2)
@ -3340,6 +3350,13 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
offs = ptype->texsstride * (rand()%ptype->randsmax); offs = ptype->texsstride * (rand()%ptype->randsmax);
p->s1 += offs; p->s1 += offs;
p->s2 += offs; p->s2 += offs;
while (p->s1 >= 1)
{
p->s1 -= 1;
p->s2 -= 1;
p->t1 += ptype->texsstride;
p->t2 += ptype->texsstride;
}
} }
if (len < nrfirst || len >= nrlast) if (len < nrfirst || len >= nrlast)
@ -3613,7 +3630,7 @@ static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *typ
} }
if (type->scalefactor == 1) if (type->scalefactor == 1)
scale = p->scale; scale = p->scale*0.25;
else else
{ {
scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
@ -3783,17 +3800,24 @@ static void GL_DrawTexturedSparkParticle(int count, particle_t **plist, plooks_t
Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+3], p->s2, p->t1); Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+3], p->s2, p->t1);
if (type->stretch)
{
VectorMA(p->org, type->stretch, p->vel, o2);
VectorMA(p->org, -type->stretch, p->vel, v);
VectorSubtract(r_refdef.vieworg, v, v);
}
else
{
VectorMA(p->org, 0.1, p->vel, o2);
VectorSubtract(r_refdef.vieworg, p->org, v);
}
VectorSubtract(r_refdef.vieworg, p->org, v);
CrossProduct(v, p->vel, cr); CrossProduct(v, p->vel, cr);
VectorNormalize(cr); VectorNormalize(cr);
VectorMA(p->org, -p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+0]); VectorMA(p->org, -p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+0]);
VectorMA(p->org, p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+1]); VectorMA(p->org, p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+1]);
VectorMA(p->org, 0.1, p->vel, o2);
VectorSubtract(r_refdef.vieworg, o2, v); VectorSubtract(r_refdef.vieworg, o2, v);
CrossProduct(v, p->vel, cr); CrossProduct(v, p->vel, cr);
VectorNormalize(cr); VectorNormalize(cr);

View file

@ -763,19 +763,17 @@ static void PF_cs_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globa
csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0); csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0);
entity_t *ent; entity_t *ent;
if (cl.num_statics >= MAX_STATIC_ENTITIES) if (cl.num_statics == cl_max_static_entities)
{ {
Con_Printf ("Too many static entities"); cl_max_static_entities += 16;
cl_static_entities = BZ_Realloc(cl_static_entities, sizeof(*cl_static_entities) * cl_max_static_entities);
PF_cs_remove(prinst, pr_globals);
return;
} }
ent = &cl_static_entities[cl.num_statics].ent; ent = &cl_static_entities[cl.num_statics].ent;
if (CopyCSQCEdictToEntity(in, ent)) if (CopyCSQCEdictToEntity(in, ent))
{ {
#pragma message("Link static entity")
cl.num_statics++; cl.num_statics++;
cl_static_entities[cl.num_statics].mdlidx = in->v->modelindex;
} }
PF_cs_remove(prinst, pr_globals); PF_cs_remove(prinst, pr_globals);
@ -1370,13 +1368,6 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global
if (cl.worldmodel) if (cl.worldmodel)
R_PushDlights (); R_PushDlights ();
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
gl_ztrickdisabled|=16;
}
#endif
r_refdef.currentplayernum = csqc_lplayernum; r_refdef.currentplayernum = csqc_lplayernum;
VectorCopy (r_refdef.vieworg, cl.viewent[csqc_lplayernum].origin); VectorCopy (r_refdef.vieworg, cl.viewent[csqc_lplayernum].origin);
@ -1387,7 +1378,6 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
{ {
gl_ztrickdisabled&=~16;
GL_Set2D (); GL_Set2D ();
} }
#endif #endif
@ -2281,18 +2271,18 @@ static void PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s *pr_global
ret = "QuakeWorld"; ret = "QuakeWorld";
break; break;
case CP_NETQUAKE: case CP_NETQUAKE:
switch (nq_dp_protocol) switch (cls.protocol_nq)
{ {
default: default:
ret = "NetQuake"; ret = "NetQuake";
break; break;
case 5: case CPNQ_DP5:
ret = "NetQuake DarkPlaces 5"; ret = "NetQuake DarkPlaces 5";
break; break;
case 6: case CPNQ_DP6:
ret = "NetQuake DarkPlaces 6"; ret = "NetQuake DarkPlaces 6";
break; break;
case 7: case CPNQ_DP7:
ret = "NetQuake DarkPlaces 7"; ret = "NetQuake DarkPlaces 7";
break; break;
} }
@ -5461,6 +5451,7 @@ qboolean CSQC_Init (unsigned int checksum)
csqcmapentitydataloaded = true; csqcmapentitydataloaded = true;
csqcprogs = InitProgs(&csqcprogparms); csqcprogs = InitProgs(&csqcprogparms);
csqc_world.progs = csqcprogs; csqc_world.progs = csqcprogs;
csqc_world.usesolidcorpse = true;
PR_Configure(csqcprogs, -1, 16); PR_Configure(csqcprogs, -1, 16);
csqc_world.worldmodel = cl.worldmodel; csqc_world.worldmodel = cl.worldmodel;
csqc_world.Event_Touch = CSQC_Event_Touch; csqc_world.Event_Touch = CSQC_Event_Touch;

View file

@ -339,6 +339,12 @@ void R2D_TileClear (int x, int y, int w, int h)
void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue) void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
{ {
if (qrenderer == QR_NONE)
{
conback = NULL;
return;
}
if (*var->string) if (*var->string)
conback = R_RegisterPic(var->string); conback = R_RegisterPic(var->string);
if (!conback || !conback->width) if (!conback || !conback->width)
@ -346,7 +352,9 @@ void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
conback = R_RegisterCustom("console", NULL, NULL); conback = R_RegisterCustom("console", NULL, NULL);
if (!conback) if (!conback)
{ {
if (M_GameType() == MGT_QUAKE2) if (M_GameType() == MGT_HEXEN2)
conback = R_RegisterPic("gfx/menu/conback.lmp");
else if (M_GameType() == MGT_QUAKE2)
conback = R_RegisterPic("pics/conback.pcx"); conback = R_RegisterPic("pics/conback.pcx");
else else
conback = R_RegisterPic("gfx/conback.lmp"); conback = R_RegisterPic("gfx/conback.lmp");
@ -358,6 +366,13 @@ void R2D_Font_Callback(struct cvar_s *var, char *oldvalue)
{ {
if (font_conchar) if (font_conchar)
Font_Free(font_conchar); Font_Free(font_conchar);
if (qrenderer == QR_NONE)
{
font_conchar = NULL;
return;
}
font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, var->string); font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, var->string);
if (!font_conchar && *var->string) if (!font_conchar && *var->string)
font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, ""); font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, "");

File diff suppressed because it is too large Load diff

View file

@ -177,6 +177,7 @@ void Surf_Clear(struct model_s *mod);
void Surf_BuildLightmaps(void); void Surf_BuildLightmaps(void);
void Surf_BuildSurfaceDisplayList (struct model_s *mod, struct msurface_s *fa); void Surf_BuildSurfaceDisplayList (struct model_s *mod, struct msurface_s *fa);
void Surf_RenderDynamicLightmaps (struct msurface_s *fa, int shift); void Surf_RenderDynamicLightmaps (struct msurface_s *fa, int shift);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int shift, int ambient);
int Surf_LightmapShift (struct model_s *model); int Surf_LightmapShift (struct model_s *model);
#ifndef LMBLOCK_WIDTH #ifndef LMBLOCK_WIDTH
#define LMBLOCK_WIDTH 128 #define LMBLOCK_WIDTH 128
@ -201,7 +202,8 @@ extern lightmapinfo_t **lightmap;
extern int numlightmaps; extern int numlightmaps;
extern texid_t *lightmap_textures; extern texid_t *lightmap_textures;
extern texid_t *deluxmap_textures; extern texid_t *deluxmap_textures;
extern int lightmap_bytes; // 1, 3(, or 4) extern int lightmap_bytes; // 1, 3, or 4
extern qboolean lightmap_bgra; /*true=bgra, false=rgba*/
#endif #endif

View file

@ -137,7 +137,7 @@ cvar_t r_replacemodels = CVARF ("r_replacemodels", IFMINIMAL("","md3 md2"),
//otherwise it would defeat the point. //otherwise it would defeat the point.
cvar_t scr_allowsnap = CVARF ("scr_allowsnap", "1", cvar_t scr_allowsnap = CVARF ("scr_allowsnap", "1",
CVAR_NOTFROMSERVER); CVAR_NOTFROMSERVER);
cvar_t scr_centersbar = CVAR ("scr_centersbar", "0"); cvar_t scr_centersbar = CVAR ("scr_centersbar", "2");
cvar_t scr_centertime = CVAR ("scr_centertime", "2"); cvar_t scr_centertime = CVAR ("scr_centertime", "2");
cvar_t scr_chatmodecvar = CVAR ("scr_chatmode", "0"); cvar_t scr_chatmodecvar = CVAR ("scr_chatmode", "0");
cvar_t scr_conalpha = CVARC ("scr_conalpha", "0.7", cvar_t scr_conalpha = CVARC ("scr_conalpha", "0.7",
@ -234,7 +234,8 @@ rendererstate_t currentrendererstate;
#if defined(GLQUAKE) #if defined(GLQUAKE)
cvar_t vid_gl_context_version = SCVAR ("vid_gl_context_version", ""); cvar_t vid_gl_context_version = SCVAR ("vid_gl_context_version", "");
cvar_t vid_gl_context_forwardcompatible = SCVAR ("vid_gl_context_breakeverything", "0"); //not useful, yet, hence the name cvar_t vid_gl_context_forwardcompatible = SCVAR ("vid_gl_context_forwardcompatible", "0");
cvar_t vid_gl_context_compatibility = SCVAR ("vid_gl_context_compatibility", "1");
cvar_t vid_gl_context_debug = SCVAR ("vid_gl_context_debug", "0"); //for my ati drivers, debug 1 only works if version >= 3 cvar_t vid_gl_context_debug = SCVAR ("vid_gl_context_debug", "0"); //for my ati drivers, debug 1 only works if version >= 3
#endif #endif
@ -308,7 +309,6 @@ cvar_t gl_texturemode2d = CVARFC("gl_texturemode2d", "GL_LINEAR",
cvar_t gl_triplebuffer = SCVARF ("gl_triplebuffer", "1", cvar_t gl_triplebuffer = SCVARF ("gl_triplebuffer", "1",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t gl_ztrick = SCVAR ("gl_ztrick", "0");
cvar_t r_noportals = SCVAR ("r_noportals", "0"); cvar_t r_noportals = SCVAR ("r_noportals", "0");
cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0",
@ -358,6 +358,7 @@ void GLRenderer_Init(void)
Cvar_Register (&vid_gl_context_version, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_version, GLRENDEREROPTIONS);
Cvar_Register (&vid_gl_context_debug, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_debug, GLRENDEREROPTIONS);
Cvar_Register (&vid_gl_context_forwardcompatible, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_forwardcompatible, GLRENDEREROPTIONS);
Cvar_Register (&vid_gl_context_compatibility, GLRENDEREROPTIONS);
//screen //screen
Cvar_Register (&gl_triplebuffer, GLRENDEREROPTIONS); Cvar_Register (&gl_triplebuffer, GLRENDEREROPTIONS);
@ -397,8 +398,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_keeptjunctions, GLRENDEREROPTIONS); Cvar_Register (&gl_keeptjunctions, GLRENDEREROPTIONS);
Cvar_Register (&gl_reporttjunctions, GLRENDEREROPTIONS); Cvar_Register (&gl_reporttjunctions, GLRENDEREROPTIONS);
Cvar_Register (&gl_ztrick, GLRENDEREROPTIONS);
Cvar_Register (&gl_motionblur, GLRENDEREROPTIONS); Cvar_Register (&gl_motionblur, GLRENDEREROPTIONS);
Cvar_Register (&gl_motionblurscale, GLRENDEREROPTIONS); Cvar_Register (&gl_motionblurscale, GLRENDEREROPTIONS);
Cvar_Register (&gl_max_size, GLRENDEREROPTIONS); Cvar_Register (&gl_max_size, GLRENDEREROPTIONS);
@ -1650,19 +1649,6 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
TRACE(("dbg: R_ApplyRenderer: starting on client state\n")); TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
if (cl.worldmodel) if (cl.worldmodel)
{ {
int staticmodelindex[MAX_STATIC_ENTITIES];
for (i = 0; i < cl.num_statics; i++) //static entities contain pointers to the model index.
{
staticmodelindex[i] = 0;
for (j = 1; j < MAX_MODELS; j++)
if (cl_static_entities[i].ent.model == cl.model_precache[j])
{
staticmodelindex[i] = j;
break;
}
}
cl.worldmodel = NULL; cl.worldmodel = NULL;
cl_numvisedicts = 0; cl_numvisedicts = 0;
cl_numstrisidx = 0; cl_numstrisidx = 0;
@ -1745,11 +1731,20 @@ TRACE(("dbg: R_ApplyRenderer: R_NewMap\n"));
TRACE(("dbg: R_ApplyRenderer: efrags\n")); TRACE(("dbg: R_ApplyRenderer: efrags\n"));
for (i = 0; i < cl.num_statics; i++) //make the static entities reappear. for (i = 0; i < cl.num_statics; i++) //make the static entities reappear.
{ {
cl_static_entities[i].ent.model = cl.model_precache[staticmodelindex[i]]; cl_static_entities[i].ent.model = NULL;
if (cl_static_entities[i].ent.model) if (cl_static_entities[i].mdlidx < 0)
cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &cl_static_entities[i].pvscache, NULL, NULL); {
#pragma message("STATIC ENTITITES --- relink") if (cl_static_entities[i].mdlidx > -MAX_CSQCMODELS)
cl_static_entities[i].ent.model = cl.model_csqcprecache[-cl_static_entities[i].mdlidx];
}
else
{
if (cl_static_entities[i].mdlidx < MAX_MODELS)
cl_static_entities[i].ent.model = cl.model_precache[cl_static_entities[i].mdlidx];
}
} }
Skin_FlushPlayers();
} }
#ifdef VM_UI #ifdef VM_UI
else else
@ -2437,6 +2432,24 @@ qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs)
{ {
int i; int i;
vec3_t wmin, wmax; vec3_t wmin, wmax;
#if 1
float mrad = 0, v;
for (i = 0; i < 3; i++)
{
v = fabs(modmins[i]);
if (mrad < v)
mrad = v;
v = fabs(modmaxs[i]);
if (mrad < v)
mrad = v;
}
for (i = 0; i < 3; i++)
{
wmin[i] = e->origin[i]-mrad;
wmax[i] = e->origin[i]+mrad;
}
#else
float fmin, fmax; float fmin, fmax;
//convert the model's bbox to the expanded maximum size of the entity, as drawn with this model. //convert the model's bbox to the expanded maximum size of the entity, as drawn with this model.
@ -2463,7 +2476,7 @@ qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs)
wmax[i] = e->origin[i]+fmin; wmax[i] = e->origin[i]+fmin;
} }
} }
#endif
return R_CullBox(wmin, wmax); return R_CullBox(wmin, wmax);
} }

View file

@ -973,7 +973,13 @@ void Draw_TinyString (int x, int y, const qbyte *str)
#pragma message("hexen2: use a tinychar *6 font") #pragma message("hexen2: use a tinychar *6 font")
if (!font_tiny) if (!font_tiny)
return; {
// font_tiny = Font_LoadFont(6*vid.pixelheight/vid.height, var->string);
// if (!font_tiny && *var->string)
font_tiny = Font_LoadFont(6*vid.pixelheight/vid.height, "gfx/tinyfont");
if (!font_tiny)
return;
}
Font_BeginString(font_tiny, x, y, &x, &y); Font_BeginString(font_tiny, x, y, &x, &y);
xstart = x; xstart = x;
@ -987,7 +993,7 @@ void Draw_TinyString (int x, int y, const qbyte *str)
str++; str++;
continue; continue;
} }
x = Font_DrawChar(x, y, *str++); x = Font_DrawChar(x, y, CON_WHITEMASK|*str++);
} }
Font_EndString(font_tiny); Font_EndString(font_tiny);
} }
@ -1132,7 +1138,7 @@ void Sbar_Hexen2DrawNum (int x, int y, int num, int digits)
else else
frame = *ptr -'0'; frame = *ptr -'0';
Sbar_DrawPic (x, y, FINDOUT, FINDOUT, sb_nums[0][frame]); Sbar_DrawPic (x, y, 12, 16, sb_nums[0][frame]);
x += 13; x += 13;
ptr++; ptr++;
} }
@ -1791,14 +1797,14 @@ void Sbar_DrawScoreboard (void)
void Sbar_Hexen2DrawItem(int pnum, int x, int y, int itemnum) void Sbar_Hexen2DrawItem(int pnum, int x, int y, int itemnum)
{ {
int num; int num;
Sbar_DrawPic(x, y, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/arti%02d.lmp", itemnum))); Sbar_DrawPic(x, y, 29, 28, Draw_SafeCachePic(va("gfx/arti%02d.lmp", itemnum)));
num = cl.stats[pnum][STAT_H2_CNT_TORCH+itemnum]; num = cl.stats[pnum][STAT_H2_CNT_TORCH+itemnum];
if(num > 0) if(num > 0)
{ {
if (num >= 10) if (num >= 10)
Sbar_DrawPic(x+20, y+21, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/artinum%d.lmp", num/10))); Sbar_DrawPic(x+20, y+21, 4, 6, Draw_SafeCachePic(va("gfx/artinum%d.lmp", num/10)));
Sbar_DrawPic(x+20+4, y+21, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/artinum%d.lmp", num%10))); Sbar_DrawPic(x+20+4, y+21, 4, 6, Draw_SafeCachePic(va("gfx/artinum%d.lmp", num%10)));
} }
} }
@ -1814,7 +1820,7 @@ void Sbar_Hexen2DrawInventory(int pnum)
for (i = 0, x=320/2-114; i < 7; i++, x+=33) for (i = 0, x=320/2-114; i < 7; i++, x+=33)
{ {
if ((sb_hexen2_cur_item-3+i+30)%15 == sb_hexen2_cur_item) if ((sb_hexen2_cur_item-3+i+30)%15 == sb_hexen2_cur_item)
Sbar_DrawPic(x+9, y-12, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/artisel.lmp")); Sbar_DrawPic(x+9, y-12, 11, 11, Draw_SafeCachePic("gfx/artisel.lmp"));
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item-3+i+30)%15); Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item-3+i+30)%15);
} }
#else #else
@ -1859,8 +1865,8 @@ void Sbar_Hexen2DrawExtra (int pnum)
//adjust it so there's space //adjust it so there's space
sbar_rect.y -= 46+98-SBAR_HEIGHT; sbar_rect.y -= 46+98-SBAR_HEIGHT;
Sbar_DrawPic(0, 46, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/btmbar1.lmp")); Sbar_DrawPic(0, 46, 160, 98, Draw_SafeCachePic("gfx/btmbar1.lmp"));
Sbar_DrawPic(160, 46, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/btmbar2.lmp")); Sbar_DrawPic(160, 46, 160, 98, Draw_SafeCachePic("gfx/btmbar2.lmp"));
Sbar_DrawTinyString (11, 48, pclassname[pclass]); Sbar_DrawTinyString (11, 48, pclassname[pclass]);
@ -1893,7 +1899,7 @@ void Sbar_Hexen2DrawExtra (int pnum)
{ {
if (cl.stats[pnum][STAT_H2_ARMOUR1+i] > 0) if (cl.stats[pnum][STAT_H2_ARMOUR1+i] > 0)
{ {
Sbar_DrawPic (164+i*40, 115, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/armor%d.lmp", i+1))); Sbar_DrawPic (164+i*40, 115, 28, 19, Draw_SafeCachePic(va("gfx/armor%d.lmp", i+1)));
Sbar_DrawTinyString (168+i*40, 136, va("+%d", cl.stats[pnum][STAT_H2_ARMOUR1+i])); Sbar_DrawTinyString (168+i*40, 136, va("+%d", cl.stats[pnum][STAT_H2_ARMOUR1+i]));
} }
} }
@ -1901,14 +1907,14 @@ void Sbar_Hexen2DrawExtra (int pnum)
{ {
if (cl.stats[pnum][STAT_H2_FLIGHT_T+i] > 0) if (cl.stats[pnum][STAT_H2_FLIGHT_T+i] > 0)
{ {
Sbar_DrawPic (ringpos[i], 119, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/ring_f.lmp"))); Sbar_DrawPic (ringpos[i], 119, 32, 22, Draw_SafeCachePic(va("gfx/ring_f.lmp")));
val = cl.stats[pnum][STAT_H2_FLIGHT_T+i]; val = cl.stats[pnum][STAT_H2_FLIGHT_T+i];
if (val > 100) if (val > 100)
val = 100; val = 100;
if (val < 0) if (val < 0)
val = 0; val = 0;
Sbar_DrawPic(ringpos[i]+29 - (int)(26 * (val/(float)100)),142, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/ringhlth.lmp")); Sbar_DrawPic(ringpos[i]+29 - (int)(26 * (val/(float)100)),142, 26, 1, Draw_SafeCachePic("gfx/ringhlth.lmp"));
Sbar_DrawPic(ringpos[i]+29, 142, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/rhlthcvr.lmp")); Sbar_DrawPic(ringpos[i]+29, 142, 26, 1, Draw_SafeCachePic("gfx/rhlthcvr.lmp"));
} }
} }
@ -1917,23 +1923,23 @@ void Sbar_Hexen2DrawExtra (int pnum)
{ {
if (cl.statsstr[pnum][STAT_H2_PUZZLE1+i]) if (cl.statsstr[pnum][STAT_H2_PUZZLE1+i])
{ {
Sbar_DrawPic (194+(slot%4)*31, slot<4?51:82, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/puzzle/%s.lmp", cl.statsstr[pnum][STAT_H2_PUZZLE1+i]))); Sbar_DrawPic (194+(slot%4)*31, slot<4?51:82, 26, 26, Draw_SafeCachePic(va("gfx/puzzle/%s.lmp", cl.statsstr[pnum][STAT_H2_PUZZLE1+i])));
slot++; slot++;
} }
} }
Sbar_DrawPic(134, 50, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/cport%d.lmp", pclass))); Sbar_DrawPic(134, 50, 49, 56, Draw_SafeCachePic(va("gfx/cport%d.lmp", pclass)));
} }
void Sbar_Hexen2DrawBasic(int pnum) void Sbar_Hexen2DrawBasic(int pnum)
{ {
int chainpos; int chainpos;
int val, maxval; int val, maxval;
Sbar_DrawPic(0, 0, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbar1.lmp")); Sbar_DrawPic(0, 0, 160, 46, Draw_SafeCachePic("gfx/topbar1.lmp"));
Sbar_DrawPic(160, 0, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbar2.lmp")); Sbar_DrawPic(160, 0, 160, 46, Draw_SafeCachePic("gfx/topbar2.lmp"));
Sbar_DrawPic(0, -23, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbumpl.lmp")); Sbar_DrawPic(0, -23, 51, 23, Draw_SafeCachePic("gfx/topbumpl.lmp"));
Sbar_DrawPic(138, -8, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbumpm.lmp")); Sbar_DrawPic(138, -8, 39, 8, Draw_SafeCachePic("gfx/topbumpm.lmp"));
Sbar_DrawPic(269, -23, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbumpr.lmp")); Sbar_DrawPic(269, -23, 51, 23, Draw_SafeCachePic("gfx/topbumpr.lmp"));
//mana1 //mana1
maxval = cl.stats[pnum][STAT_H2_MAXMANA]; maxval = cl.stats[pnum][STAT_H2_MAXMANA];
@ -1942,8 +1948,8 @@ void Sbar_Hexen2DrawBasic(int pnum)
Sbar_DrawTinyString(201, 22, va("%03d", val)); Sbar_DrawTinyString(201, 22, va("%03d", val));
if(val) if(val)
{ {
Sbar_DrawPic(190, 26-(int)((val*18.0)/(float)maxval+0.5), FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/bmana.lmp")); Sbar_DrawPic(190, 26-(int)((val*18.0)/(float)maxval+0.5), 3, 19, Draw_SafeCachePic("gfx/bmana.lmp"));
Sbar_DrawPic(190, 27, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/bmanacov.lmp")); Sbar_DrawPic(190, 27, 3, 19, Draw_SafeCachePic("gfx/bmanacov.lmp"));
} }
//mana2 //mana2
@ -1953,8 +1959,8 @@ void Sbar_Hexen2DrawBasic(int pnum)
Sbar_DrawTinyString(243, 22, va("%03d", val)); Sbar_DrawTinyString(243, 22, va("%03d", val));
if(val) if(val)
{ {
Sbar_DrawPic(232, 26-(int)((val*18.0)/(float)maxval+0.5), FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/gmana.lmp")); Sbar_DrawPic(232, 26-(int)((val*18.0)/(float)maxval+0.5), 3, 19, Draw_SafeCachePic("gfx/gmana.lmp"));
Sbar_DrawPic(232, 27, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/gmanacov.lmp")); Sbar_DrawPic(232, 27, 3, 19, Draw_SafeCachePic("gfx/gmanacov.lmp"));
} }
@ -1972,10 +1978,10 @@ void Sbar_Hexen2DrawBasic(int pnum)
chainpos = (195.0f*cl.stats[pnum][STAT_HEALTH]) / cl.stats[pnum][STAT_H2_MAXHEALTH]; chainpos = (195.0f*cl.stats[pnum][STAT_HEALTH]) / cl.stats[pnum][STAT_H2_MAXHEALTH];
if (chainpos < 0) if (chainpos < 0)
chainpos = 0; chainpos = 0;
Sbar_DrawPic(45+((int)chainpos&7), 38, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/hpchain.lmp")); Sbar_DrawPic(45+((int)chainpos&7), 38, 222, 5, Draw_SafeCachePic("gfx/hpchain.lmp"));
Sbar_DrawPic(45+(int)chainpos, 36, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/hpgem.lmp")); Sbar_DrawPic(45+(int)chainpos, 36, 35, 9, Draw_SafeCachePic("gfx/hpgem.lmp"));
Sbar_DrawPic(43, 36, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/chnlcov.lmp")); Sbar_DrawPic(43, 36, 10, 10, Draw_SafeCachePic("gfx/chnlcov.lmp"));
Sbar_DrawPic(267, 36, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/chnrcov.lmp")); Sbar_DrawPic(267, 36, 10, 10, Draw_SafeCachePic("gfx/chnrcov.lmp"));
Sbar_Hexen2DrawItem(pnum, 144, 3, sb_hexen2_cur_item); Sbar_Hexen2DrawItem(pnum, 144, 3, sb_hexen2_cur_item);
@ -2156,7 +2162,7 @@ void Sbar_Draw (void)
sbar_rect.x = 0; sbar_rect.x = 0;
sbar_rect.y = 0; sbar_rect.y = 0;
if (scr_centersbar.ival) if (scr_centersbar.ival || (scr_centersbar.ival == 2 && !cl.deathmatch))
{ {
sbar_rect.x = (vid.width - 320)/2; sbar_rect.x = (vid.width - 320)/2;
sbar_rect.width -= sbar_rect.x; sbar_rect.width -= sbar_rect.x;

View file

@ -596,10 +596,13 @@ void Skin_Skins_f (void)
Skin_NextDownload (); Skin_NextDownload ();
SCR_SetLoadingStage(LS_NONE); // if (Cmd_FromServer())
{
SCR_SetLoadingStage(LS_NONE);
CL_SendClientCommand(true, "begin %i", cl.servercount); CL_SendClientCommand(true, "begin %i", cl.servercount);
Cache_Report (); // print remaining memory Cache_Report (); // print remaining memory
}
} }

View file

@ -633,6 +633,8 @@ sfxcache_t *S_LoadDoomSpeakerSound (sfx_t *s, qbyte *data, int datalen, int snds
inaccum = inrate; inaccum = inrate;
if (*data) if (*data)
timerfreq = DSPK_BASE * pow((double)2.0, DSPK_EXP * (*data)); timerfreq = DSPK_BASE * pow((double)2.0, DSPK_EXP * (*data));
else
timerfreq = 0;
while (len > 0) while (len > 0)
{ {
@ -920,7 +922,7 @@ WAV loading
=============================================================================== ===============================================================================
*/ */
char *wavname;
qbyte *data_p; qbyte *data_p;
qbyte *iff_end; qbyte *iff_end;
qbyte *last_chunk; qbyte *last_chunk;
@ -972,7 +974,7 @@ unsigned int FindNextChunk(char *name)
} }
if (iff_chunk_len > dataleft) if (iff_chunk_len > dataleft)
{ {
Con_Printf ("Sound file seems truncated by %i bytes\n", iff_chunk_len-dataleft); Con_DPrintf ("\"%s\" seems truncated by %i bytes\n", wavname, iff_chunk_len-dataleft);
#if 1 #if 1
iff_chunk_len = dataleft; iff_chunk_len = dataleft;
#else #else
@ -1038,6 +1040,7 @@ wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
iff_data = wav; iff_data = wav;
iff_end = wav + wavlength; iff_end = wav + wavlength;
wavname = name;
// find "RIFF" chunk // find "RIFF" chunk
chunklen = FindChunk("RIFF"); chunklen = FindChunk("RIFF");

View file

@ -11,6 +11,7 @@
#include "npapi/npupp.h" #include "npapi/npupp.h"
#include "sys_plugfte.h" #include "sys_plugfte.h"
/*work around absolute crapness in the npapi headers*/
#define Q_STRINGZ_TO_NPVARIANT(_val, _v) \ #define Q_STRINGZ_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \ NP_BEGIN_MACRO \
NPString str = { _val, strlen(_val) }; \ NPString str = { _val, strlen(_val) }; \
@ -20,6 +21,15 @@ NP_END_MACRO
#undef STRINGZ_TO_NPVARIANT #undef STRINGZ_TO_NPVARIANT
#define STRINGZ_TO_NPVARIANT Q_STRINGZ_TO_NPVARIANT #define STRINGZ_TO_NPVARIANT Q_STRINGZ_TO_NPVARIANT
#define Q_STRINGN_TO_NPVARIANT(_val, _len, _v) \
NP_BEGIN_MACRO \
NPString str = { _val, _len }; \
(_v).type = NPVariantType_String; \
(_v).value.stringValue = str; \
NP_END_MACRO
#undef STRINGN_TO_NPVARIANT
#define STRINGN_TO_NPVARIANT Q_STRINGN_TO_NPVARIANT
#define FIREFOX_BUGS_OVER_25MB #define FIREFOX_BUGS_OVER_25MB
//TODO: player name input (before allowing them to join) //TODO: player name input (before allowing them to join)
@ -502,13 +512,21 @@ bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
char *ns; char *ns;
int len; int len;
len = strlen(strval); len = strlen(strval);
ns = browserfuncs->memalloc(len); if (!len)
if (ns)
{ {
memcpy(ns, strval, len); STRINGN_TO_NPVARIANT(NULL, 0, *result);
STRINGZ_TO_NPVARIANT(ns, *result);
success = true; success = true;
} }
else
{
ns = browserfuncs->memalloc(len);
if (ns)
{
memcpy(ns, strval, len);
STRINGZ_TO_NPVARIANT(ns, *result);
success = true;
}
}
Plug_GotString(strval); Plug_GotString(strval);
} }
else if (Plug_GetInteger(ctx, prop, &intval)) else if (Plug_GetInteger(ctx, prop, &intval))
@ -646,10 +664,10 @@ NPError OSCALL NP_GetValue(void *instance, NPPVariable variable, void *value)
switch(variable) switch(variable)
{ {
case NPPVpluginNameString: case NPPVpluginNameString:
*(char**)value = "QTV Viewer"; *(char**)value = "FTE QuakeWorld";
break; break;
case NPPVpluginDescriptionString: case NPPVpluginDescriptionString:
*(char**)value = "QTV Viewer"; *(char**)value = "FTE QuakeWorld";
break; break;
default: default:
return NPERR_INVALID_PARAM; return NPERR_INVALID_PARAM;

View file

@ -314,6 +314,7 @@ int Plug_PluginThread(void *ctxptr)
while(host_initialized && !ctx->shutdown && ctx->packagelist) while(host_initialized && !ctx->shutdown && ctx->packagelist)
{ {
int total=0, done=0; int total=0, done=0;
ctx->resetvideo = false;
Sys_LockMutex(ctx->mutex); Sys_LockMutex(ctx->mutex);
for (dl = ctx->packagelist; dl; dl = dl->next) for (dl = ctx->packagelist; dl; dl = dl->next)
{ {
@ -367,10 +368,12 @@ int Plug_PluginThread(void *ctxptr)
} }
else if (ctx->resetvideo) else if (ctx->resetvideo)
{ {
ctx->resetvideo = false;
sys_parentwindow = ctx->windowhnd; sys_parentwindow = ctx->windowhnd;
sys_parentwidth = ctx->windowwidth; sys_parentwidth = ctx->windowwidth;
sys_parentheight = ctx->windowheight; sys_parentheight = ctx->windowheight;
if (ctx->resetvideo == 2)
SetParent(mainwindow, sys_parentwindow);
ctx->resetvideo = false;
Cbuf_AddText("vid_recenter\n", RESTRICT_LOCAL); Cbuf_AddText("vid_recenter\n", RESTRICT_LOCAL);
} }
else else
@ -479,35 +482,27 @@ qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int width, int heigh
{ {
qboolean result = false; qboolean result = false;
Plug_LockPlugin(ctx, true);
//if the window changed //if the window changed
if (ctx->windowhnd != whnd) if (ctx->windowhnd != whnd)
{ {
result = true; result = true;
#ifdef _WIN32
if (ctx->pub.running)
{
Plug_LockPlugin(ctx, true);
if (mainwindow && ctx->windowhnd == sys_parentwindow)
{
sys_parentwindow = ctx->windowhnd;
SetParent(mainwindow, ctx->windowhnd);
}
Plug_LockPlugin(ctx, false);
}
#endif
ctx->windowhnd = whnd; ctx->windowhnd = whnd;
ctx->resetvideo = 2;
} }
if (ctx->windowwidth != width && ctx->windowheight != height) if (ctx->windowwidth != width && ctx->windowheight != height)
{ {
ctx->windowwidth = width; ctx->windowwidth = width;
ctx->windowheight = height; ctx->windowheight = height;
Plug_LockPlugin(ctx, true); if (ctx->pub.running && !ctx->resetvideo)
if (ctx->pub.running)
ctx->resetvideo = true; ctx->resetvideo = true;
Plug_LockPlugin(ctx, false);
} }
Plug_LockPlugin(ctx, false);
while(ctx->pub.running && ctx->resetvideo)
Sleep(10);
return result; return result;
} }
@ -617,12 +612,14 @@ static void UnpackAndExtractPakFiles_Complete(struct dl_download *dl)
Plug_LockPlugin(dl->user_ctx, true); Plug_LockPlugin(dl->user_ctx, true);
zip = zipfilefuncs.OpenNew(dl->file, dl->url); if (dl->status == DL_FINISHED)
zip = zipfilefuncs.OpenNew(dl->file, dl->url);
else
zip = NULL;
/*the zip code will have eaten the file handle*/
dl->file = NULL;
if (zip) if (zip)
{ {
/*the zip code will eat the file handle*/
dl->file = NULL;
/*scan it to extract its contents*/ /*scan it to extract its contents*/
zipfilefuncs.EnumerateFiles(zip, "*.pk3", ExtractDataFile, zip); zipfilefuncs.EnumerateFiles(zip, "*.pk3", ExtractDataFile, zip);
zipfilefuncs.EnumerateFiles(zip, "*.pak", ExtractDataFile, zip); zipfilefuncs.EnumerateFiles(zip, "*.pak", ExtractDataFile, zip);
@ -762,22 +759,34 @@ void pscript_property_running_setb(struct context *ctx, int i)
char *pscript_property_startserver_gets(struct context *ctx) char *pscript_property_startserver_gets(struct context *ctx)
{ {
return ctx->qtvf.server; return strdup(ctx->qtvf.server);
} }
void pscript_property_startserver_sets(struct context *ctx, const char *val) void pscript_property_startserver_sets(struct context *ctx, const char *val)
{ {
if (strchr(val, '$') || strchr(val, ';') || strchr(val, '\n'))
return;
ctx->qtvf.connectiontype = QTVCT_JOIN; ctx->qtvf.connectiontype = QTVCT_JOIN;
Q_strncpyz(ctx->qtvf.server, val, sizeof(ctx->qtvf.server)); Q_strncpyz(ctx->qtvf.server, val, sizeof(ctx->qtvf.server));
} }
char *pscript_property_curserver_gets(struct context *ctx) char *pscript_property_curserver_gets(struct context *ctx)
{ {
extern char lastdemoname[];
if (!pscript_property_running_getb(ctx)) if (!pscript_property_running_getb(ctx))
return pscript_property_startserver_gets(ctx); return pscript_property_startserver_gets(ctx);
return cls.servername; if (cls.demoplayback)
return strdup(va("demo:%s",lastdemoname));
else if (cls.state != ca_disconnected)
return strdup(cls.servername);
else
return strdup("");
} }
void pscript_property_curserver_sets(struct context *ctx, const char *val) void pscript_property_curserver_sets(struct context *ctx, const char *val)
{ {
if (strchr(val, '$') || strchr(val, ';') || strchr(val, '\n'))
return;
if (!pscript_property_running_getb(ctx)) if (!pscript_property_running_getb(ctx))
{ {
pscript_property_startserver_sets(ctx, val); pscript_property_startserver_sets(ctx, val);
@ -790,6 +799,9 @@ void pscript_property_curserver_sets(struct context *ctx, const char *val)
void pscript_property_stream_sets(struct context *ctx, const char *val) void pscript_property_stream_sets(struct context *ctx, const char *val)
{ {
if (strchr(val, '$') || strchr(val, ';') || strchr(val, '\n'))
return;
ctx->qtvf.connectiontype = QTVCT_STREAM; ctx->qtvf.connectiontype = QTVCT_STREAM;
Q_strncpyz(ctx->qtvf.server, val, sizeof(ctx->qtvf.server)); Q_strncpyz(ctx->qtvf.server, val, sizeof(ctx->qtvf.server));
@ -798,8 +810,9 @@ void pscript_property_stream_sets(struct context *ctx, const char *val)
} }
void pscript_property_map_sets(struct context *ctx, const char *val) void pscript_property_map_sets(struct context *ctx, const char *val)
{ {
if (strchr(val, '$') || strchr(val, ';') || strchr(val, '\n'))
return;
ctx->qtvf.connectiontype = QTVCT_MAP; ctx->qtvf.connectiontype = QTVCT_MAP;
FILTER(val)
Q_strncpyz(ctx->qtvf.server, val, sizeof(ctx->qtvf.server)); Q_strncpyz(ctx->qtvf.server, val, sizeof(ctx->qtvf.server));
if (pscript_property_running_getb(ctx)) if (pscript_property_running_getb(ctx))
@ -826,6 +839,9 @@ void pscript_property_datadownload_sets(struct context *ctx, const char *val)
void pscript_property_game_sets(struct context *ctx, const char *val) void pscript_property_game_sets(struct context *ctx, const char *val)
{ {
if (strchr(val, '$') || strchr(val, ';') || strchr(val, '\n'))
return;
if (!strstr(val, ".")) if (!strstr(val, "."))
if (!strstr(val, "/")) if (!strstr(val, "/"))
if (!strstr(val, "\\")) if (!strstr(val, "\\"))
@ -854,6 +870,15 @@ void pscript_property_splash_sets(struct context *ctx, const char *val)
} }
} }
char *pscript_property_build_gets(struct context *ctx)
{
return strdup(DISTRIBUTION " " __DATE__ " " __TIME__
#if defined(DEBUG) || defined(_DEBUG)
" (debug)"
#endif
);
}
extern cvar_t skin, team, topcolor, bottomcolor, vid_fullscreen, cl_download_mapsrc; extern cvar_t skin, team, topcolor, bottomcolor, vid_fullscreen, cl_download_mapsrc;
static struct pscript_property pscript_properties[] = static struct pscript_property pscript_properties[] =
{ {
@ -874,12 +899,14 @@ static struct pscript_property pscript_properties[] =
{"game", false, NULL, NULL, pscript_property_game_sets}, {"game", false, NULL, NULL, pscript_property_game_sets},
{"availver", false, NULL, NULL, NULL, NULL, NULL, NULL, pscript_property_availver_setf}, {"availver", false, NULL, NULL, NULL, NULL, NULL, NULL, pscript_property_availver_setf},
{"plugver", false, NULL, NULL, NULL, NULL, NULL, pscript_property_curver_getf},
{"splash", false, NULL, NULL, pscript_property_splash_sets}, {"splash", false, NULL, NULL, pscript_property_splash_sets},
{"stream", false, NULL, NULL, pscript_property_stream_sets}, {"stream", false, NULL, NULL, pscript_property_stream_sets},
{"map", false, NULL, NULL, pscript_property_map_sets}, {"map", false, NULL, NULL, pscript_property_map_sets},
{"build", false, NULL, pscript_property_build_gets},
/* /*
else if (!stricmp(argn[i], "connType")) else if (!stricmp(argn[i], "connType"))
{ {
@ -1044,9 +1071,13 @@ qboolean Plug_SetFloat(struct context *ctx, struct pscript_property *field, floa
return true; return true;
} }
#pragma message("Plug_Get* not implemented yet")
qboolean Plug_GetString(struct context *ctx, struct pscript_property *field, const char **value) qboolean Plug_GetString(struct context *ctx, struct pscript_property *field, const char **value)
{ {
if (field->getstring)
{
*value = field->getstring(ctx);
return true;
}
return false; return false;
} }
void Plug_GotString(const char *value) void Plug_GotString(const char *value)
@ -1055,10 +1086,20 @@ void Plug_GotString(const char *value)
} }
qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, int *value) qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, int *value)
{ {
if (field->getint)
{
*value = field->getint(ctx);
return true;
}
return false; return false;
} }
qboolean Plug_GetFloat(struct context *ctx, struct pscript_property *field, float *value) qboolean Plug_GetFloat(struct context *ctx, struct pscript_property *field, float *value)
{ {
if (field->getfloat)
{
*value = field->getfloat(ctx);
return true;
}
return false; return false;
} }

View file

@ -162,6 +162,7 @@ void CloseEditor(void)
key_dest = key_console; key_dest = key_console;
editoractive = false; editoractive = false;
editprogfuncs = NULL;
if (!firstblock) if (!firstblock)
return; return;

View file

@ -1093,7 +1093,6 @@ the entity origin, so any view position inside that will be valid
*/ */
extern vrect_t scr_vrect; extern vrect_t scr_vrect;
int gl_ztrickdisabled;
qboolean r_secondaryview; qboolean r_secondaryview;
#ifdef SIDEVIEWS #ifdef SIDEVIEWS
@ -1270,7 +1269,6 @@ void V_RenderPlayerViews(int plnum)
vec3_t dir; vec3_t dir;
extern void vectoangles(vec3_t vec, vec3_t ang); extern void vectoangles(vec3_t vec, vec3_t ang);
gl_ztrickdisabled|=16;
r_refdef.vrect.y -= r_refdef.vrect.height; r_refdef.vrect.y -= r_refdef.vrect.height;
vid.recalc_refdef=true; vid.recalc_refdef=true;
r_secondaryview = 2; r_secondaryview = 2;
@ -1284,8 +1282,6 @@ void V_RenderPlayerViews(int plnum)
R_RenderView (); R_RenderView ();
vid.recalc_refdef=true; vid.recalc_refdef=true;
} }
else
gl_ztrickdisabled&=~16;
#ifdef SIDEVIEWS #ifdef SIDEVIEWS
@ -1296,9 +1292,6 @@ void V_RenderPlayerViews(int plnum)
r_refdef.vrect.height += vsecheight; r_refdef.vrect.height += vsecheight;
} }
*/ */
#ifdef GLQUAKE
gl_ztrickdisabled&=~1;
#endif
for (viewnum = 0; viewnum < SIDEVIEWS; viewnum++) for (viewnum = 0; viewnum < SIDEVIEWS; viewnum++)
if (vsec_scalex[viewnum].value>0&&vsec_scaley[viewnum].value>0 if (vsec_scalex[viewnum].value>0&&vsec_scaley[viewnum].value>0
&& ((vsec_enabled[viewnum].value && vsec_enabled[viewnum].value != 2 && cls.allow_rearview) //rearview if v2_enabled = 1 and not 2 && ((vsec_enabled[viewnum].value && vsec_enabled[viewnum].value != 2 && cls.allow_rearview) //rearview if v2_enabled = 1 and not 2
@ -1312,7 +1305,6 @@ void V_RenderPlayerViews(int plnum)
float ofx; float ofx;
float ofy; float ofy;
gl_ztrickdisabled|=1;
vid.recalc_refdef=true; vid.recalc_refdef=true;
r_secondaryview = true; r_secondaryview = true;
@ -1415,7 +1407,7 @@ void V_RenderView (void)
//work out which packet entities are solid //work out which packet entities are solid
CL_SetSolidEntities (); CL_SetSolidEntities ();
CL_EmitEntities(); // CL_EmitEntities();
// Set up prediction for other players // Set up prediction for other players
CL_SetUpPlayerPrediction(false); CL_SetUpPlayerPrediction(false);
@ -1427,7 +1419,7 @@ void V_RenderView (void)
CL_SetUpPlayerPrediction(true); CL_SetUpPlayerPrediction(true);
// build a refresh entity list // build a refresh entity list
// CL_EmitEntities (); CL_EmitEntities ();
CL_AllowIndependantSendCmd(true); CL_AllowIndependantSendCmd(true);
@ -1445,11 +1437,6 @@ void V_RenderView (void)
alreadyrendering=true; alreadyrendering=true;
#endif #endif
if (cl.splitclients>1)
gl_ztrickdisabled|=8;
else
gl_ztrickdisabled&=~8;
r_secondaryview = 0; r_secondaryview = 0;
for (viewnum = 0; viewnum < cl.splitclients; viewnum++) for (viewnum = 0; viewnum < cl.splitclients; viewnum++)
{ {

View file

@ -24,7 +24,6 @@ extern cvar_t lcd_x;
extern float sw_blend[4]; extern float sw_blend[4];
extern float hw_blend[4]; extern float hw_blend[4];
extern int gl_ztrickdisabled;
extern qboolean r_secondaryview; extern qboolean r_secondaryview;
void V_Init (void); void V_Init (void);

View file

@ -573,14 +573,10 @@ void CL_Skygroup_f(void)
} }
} }
//extern model_t *loadmodel;
char wads[4096]; char wads[4096];
void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this should be in the model code. void Mod_ParseInfoFromEntityLump(model_t *wmodel, char *data, char *mapname) //actually, this should be in the model code.
{ {
extern model_t *loadmodel;
char key[128]; char key[128];
char skyname[64];
mapskys_t *msky; mapskys_t *msky;
cl.skyrotate = 0; cl.skyrotate = 0;
@ -595,16 +591,16 @@ void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this sho
// this hack is necessary to ensure Quake 2 maps get their // this hack is necessary to ensure Quake 2 maps get their
// default skybox // default skybox
if (loadmodel->fromgame == fg_quake2) if (wmodel->fromgame == fg_quake2)
strcpy(skyname, "unit1_"); strcpy(cl.skyname, "unit1_");
else else
skyname[0] = '\0'; cl.skyname[0] = '\0';
for (msky = mapskies; msky; msky = msky->next) for (msky = mapskies; msky; msky = msky->next)
{ {
if (!strcmp(msky->mapname, mapname)) if (!strcmp(msky->mapname, mapname))
{ {
Q_strncpyz(skyname, msky->skyname, sizeof(skyname)); Q_strncpyz(cl.skyname, msky->skyname, sizeof(cl.skyname));
break; break;
} }
} }
@ -626,7 +622,7 @@ void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this sho
break; // error break; // error
if (!strcmp("wad", key)) // for HalfLife maps if (!strcmp("wad", key)) // for HalfLife maps
{ {
if (loadmodel->fromgame == fg_halflife) if (wmodel->fromgame == fg_halflife)
{ {
strncat(wads, ";", 4095); //cache it for later (so that we don't play with any temp memory yet) strncat(wads, ";", 4095); //cache it for later (so that we don't play with any temp memory yet)
strncat(wads, com_token, 4095); //cache it for later (so that we don't play with any temp memory yet) strncat(wads, com_token, 4095); //cache it for later (so that we don't play with any temp memory yet)
@ -634,11 +630,11 @@ void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this sho
} }
else if (!strcmp("skyname", key)) // for HalfLife maps else if (!strcmp("skyname", key)) // for HalfLife maps
{ {
Q_strncpyz(skyname, com_token, sizeof(skyname)); Q_strncpyz(cl.skyname, com_token, sizeof(cl.skyname));
} }
else if (!strcmp("sky", key)) // for Quake2 maps else if (!strcmp("sky", key)) // for Quake2 maps
{ {
Q_strncpyz(skyname, com_token, sizeof(skyname)); Q_strncpyz(cl.skyname, com_token, sizeof(cl.skyname));
} }
else if (!strcmp("skyrotate", key)) else if (!strcmp("skyrotate", key))
{ {

View file

@ -108,10 +108,10 @@ void Wads_Flush (void);
void SwapPic (qpic_t *pic); void SwapPic (qpic_t *pic);
struct model_s;
void Mod_ParseWadsFromEntityLump(char *data); void Mod_ParseWadsFromEntityLump(char *data);
qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *usesalpha); qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *usesalpha);
void Mod_ParseInfoFromEntityLump(char *data, char *mapname); void Mod_ParseInfoFromEntityLump(struct model_s *wmodel, char *data, char *mapname);
qboolean Wad_NextDownload (void); qboolean Wad_NextDownload (void);
qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha); qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha);

View file

@ -141,7 +141,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ZYMOTICMODELS //zymotic skeletal models. #define ZYMOTICMODELS //zymotic skeletal models.
#define HUFFNETWORK //huffman network compression #define HUFFNETWORK //huffman network compression
#define HALFLIFEMODELS //halflife model support (experimental) #define HALFLIFEMODELS //halflife model support (experimental)
// #define DOOMWADS //doom wad/map/sprite support //#define DOOMWADS //doom wad/sprite support
//#define MAP_DOOM //doom map support
//#define MAP_PROC //doom3/quake4 map support
//#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet) //#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet)
#define Q2BSPS //quake 2 bsp support #define Q2BSPS //quake 2 bsp support
#define Q3BSPS //quake 3 bsp support #define Q3BSPS //quake 3 bsp support
@ -424,10 +426,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ON_EPSILON 0.1 // point on plane side epsilon #define ON_EPSILON 0.1 // point on plane side epsilon
#define MAX_NQMSGLEN 8000 // max length of a reliable message #define MAX_NQMSGLEN 65536 // max length of a reliable message
#define MAX_Q2MSGLEN 1400 #define MAX_Q2MSGLEN 1400
#define MAX_QWMSGLEN 1450 #define MAX_QWMSGLEN 1450
#define MAX_OVERALLMSGLEN 8192 // mvdsv sends packets this big #define MAX_OVERALLMSGLEN 65536 // mvdsv sends packets this big
#define MAX_DATAGRAM 1450 // max length of unreliable message #define MAX_DATAGRAM 1450 // max length of unreliable message
#define MAX_Q2DATAGRAM MAX_Q2MSGLEN #define MAX_Q2DATAGRAM MAX_Q2MSGLEN
#define MAX_NQDATAGRAM 1024 // max length of unreliable message #define MAX_NQDATAGRAM 1024 // max length of unreliable message

View file

@ -753,29 +753,45 @@ void R_LightArrays(vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *norm
extern cvar_t r_vertexdlights; extern cvar_t r_vertexdlights;
int i; int i;
float l; float l;
#ifdef SSE_INTRINSICS
__m128 va, vs, vl, vr;
va = _mm_load_ps(ambientlight);
vs = _mm_load_ps(shadelight);
va.m128_f32[3] = 0;
vs.m128_f32[3] = 1;
#endif
for (i = vertcount-1; i >= 0; i--) if (VectorCompare(ambientlight, shadelight))
{ {
l = DotProduct(normals[i], shadevector); for (i = vertcount-1; i >= 0; i--)
{
colours[i][0] = ambientlight[0];
colours[i][1] = ambientlight[1];
colours[i][2] = ambientlight[2];
}
}
else
{
vec3_t meanambient;
#ifdef SSE_INTRINSICS #ifdef SSE_INTRINSICS
vl = _mm_load1_ps(&l); __m128 va, vs, vl, vr;
vr = _mm_mul_ss(va,vl); va = _mm_load_ps(ambientlight);
vr = _mm_add_ss(vr,vs); vs = _mm_load_ps(shadelight);
va.m128_f32[3] = 0;
_mm_storeu_ps(colours[i], vr); vs.m128_f32[3] = 1;
//stomp on colour[i][3] (will be set to 1)
#else
colours[i][0] = l*ambientlight[0]+shadelight[0];
colours[i][1] = l*ambientlight[1]+shadelight[1];
colours[i][2] = l*ambientlight[2]+shadelight[2];
#endif #endif
/*dotproduct will return a value between 1 and -1, so increase the ambient to be correct for normals facing away from the light*/
VectorMA(ambientlight, 1, shadelight, meanambient);
for (i = vertcount-1; i >= 0; i--)
{
l = DotProduct(normals[i], shadevector);
#ifdef SSE_INTRINSICS
vl = _mm_load1_ps(&l);
vr = _mm_mul_ss(va,vl);
vr = _mm_add_ss(vr,vs);
_mm_storeu_ps(colours[i], vr);
//stomp on colour[i][3] (will be set to 1)
#else
colours[i][0] = l*shadelight[0]+meanambient[0];
colours[i][1] = l*shadelight[1]+meanambient[1];
colours[i][2] = l*shadelight[2]+meanambient[2];
#endif
}
} }
if (r_vertexdlights.ival && r_dynamic.ival) if (r_vertexdlights.ival && r_dynamic.ival)
@ -825,8 +841,6 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
extern cvar_t r_nolerp, r_nolightdir; extern cvar_t r_nolerp, r_nolightdir;
float blerp = 1-lerp; float blerp = 1-lerp;
int i; int i;
float l;
int temp;
vecV_t *p1v, *p2v; vecV_t *p1v, *p2v;
vec3_t *p1n, *p2n; vec3_t *p1n, *p2n;
vec3_t *p1s, *p2s; vec3_t *p1s, *p2s;
@ -847,6 +861,7 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
mesh->normals_array = p1n; mesh->normals_array = p1n;
mesh->snormals_array = p1s; mesh->snormals_array = p1s;
mesh->tnormals_array = p1t; mesh->tnormals_array = p1t;
mesh->colors4f_array = NULL;
if (p1v == p2v || r_nolerp.value) if (p1v == p2v || r_nolerp.value)
{ {
@ -854,69 +869,18 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
mesh->snormals_array = p1s; mesh->snormals_array = p1s;
mesh->tnormals_array = p1t; mesh->tnormals_array = p1t;
mesh->xyz_array = p1v; mesh->xyz_array = p1v;
if (r_nolightdir.value || nolightdir)
{
mesh->colors4f_array = NULL;
}
else
{
for (i = 0; i < mesh->numvertexes; i++)
{
l = DotProduct(mesh->normals_array[i], shadevector);
temp = l*ambientlight[0]+shadelight[0];
mesh->colors4f_array[i][0] = temp;
temp = l*ambientlight[1]+shadelight[1];
mesh->colors4f_array[i][1] = temp;
temp = l*ambientlight[2]+shadelight[2];
mesh->colors4f_array[i][2] = temp;
mesh->colors4f_array[i][3] = alpha;
}
}
} }
else else
{ {
if (r_nolightdir.ival || nolightdir) for (i = 0; i < mesh->numvertexes; i++)
{ {
mesh->colors4f_array = NULL; mesh->normals_array[i][0] = p1n[i][0]*lerp + p2n[i][0]*blerp;
for (i = 0; i < mesh->numvertexes; i++) mesh->normals_array[i][1] = p1n[i][1]*lerp + p2n[i][1]*blerp;
{ mesh->normals_array[i][2] = p1n[i][2]*lerp + p2n[i][2]*blerp;
mesh->normals_array[i][0] = p1n[i][0]*lerp + p2n[i][0]*blerp;
mesh->normals_array[i][1] = p1n[i][1]*lerp + p2n[i][1]*blerp;
mesh->normals_array[i][2] = p1n[i][2]*lerp + p2n[i][2]*blerp;
mesh->xyz_array[i][0] = p1v[i][0]*lerp + p2v[i][0]*blerp; mesh->xyz_array[i][0] = p1v[i][0]*lerp + p2v[i][0]*blerp;
mesh->xyz_array[i][1] = p1v[i][1]*lerp + p2v[i][1]*blerp; mesh->xyz_array[i][1] = p1v[i][1]*lerp + p2v[i][1]*blerp;
mesh->xyz_array[i][2] = p1v[i][2]*lerp + p2v[i][2]*blerp; mesh->xyz_array[i][2] = p1v[i][2]*lerp + p2v[i][2]*blerp;
}
}
else
{
for (i = 0; i < mesh->numvertexes; i++)
{
mesh->normals_array[i][0] = p1n[i][0]*lerp + p2n[i][0]*blerp;
mesh->normals_array[i][1] = p1n[i][1]*lerp + p2n[i][1]*blerp;
mesh->normals_array[i][2] = p1n[i][2]*lerp + p2n[i][2]*blerp;
mesh->xyz_array[i][0] = p1v[i][0]*lerp + p2v[i][0]*blerp;
mesh->xyz_array[i][1] = p1v[i][1]*lerp + p2v[i][1]*blerp;
mesh->xyz_array[i][2] = p1v[i][2]*lerp + p2v[i][2]*blerp;
l = DotProduct(mesh->normals_array[i], shadevector);
temp = l*ambientlight[0]+shadelight[0];
mesh->colors4f_array[i][0] = temp;
temp = l*ambientlight[1]+shadelight[1];
mesh->colors4f_array[i][1] = temp;
temp = l*ambientlight[2]+shadelight[2];
mesh->colors4f_array[i][2] = temp;
mesh->colors4f_array[i][3] = alpha;
}
} }
} }
if (expand) if (expand)
@ -1906,6 +1870,132 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
return pframetype; return pframetype;
} }
static void *H1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
{
galiaspose_t *pose;
galiasgroup_t *frame;
dtrivertx_t *pinframe;
daliasframe_t *frameinfo;
int i, j, k;
daliasgroup_t *ingroup;
daliasinterval_t *intervals;
float sinter;
vec3_t *normals, *svec, *tvec;
vecV_t *verts;
frame = (galiasgroup_t*)((char *)galias + galias->groupofs);
for (i = 0; i < pq1inmodel->numframes; i++)
{
switch(LittleLong(pframetype->type))
{
case ALIAS_SINGLE:
frameinfo = (daliasframe_t*)((char *)(pframetype+1));
pinframe = (dtrivertx_t*)((char*)frameinfo+sizeof(daliasframe_t));
pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + (sizeof(vecV_t)+sizeof(vec3_t)*3)*galias->numverts);
frame->poseofs = (char *)pose - (char *)frame;
frame->numposes = 1;
galias->groups++;
Q_strncpyz(frame->name, frameinfo->name, sizeof(frame->name));
verts = (vecV_t *)(pose+1);
normals = (vec3_t*)&verts[galias->numverts];
svec = &normals[galias->numverts];
tvec = &svec[galias->numverts];
pose->ofsverts = (char *)verts - (char *)pose;
#ifndef SERVERONLY
pose->ofsnormals = (char *)normals - (char *)pose;
pose->ofssvector = (char *)svec - (char *)pose;
pose->ofstvector = (char *)tvec - (char *)pose;
#else
#pragma message("wasted memory")
#endif
for (j = 0; j < galias->numverts; j++)
{
verts[j][0] = pinframe[seamremaps[j]].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[seamremaps[j]].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[seamremaps[j]].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[seamremaps[j]].lightnormalindex], normals[j]);
#endif
}
// GL_GenerateNormals((float*)verts, (float*)normals, (int *)((char *)galias + galias->ofs_indexes), galias->numindexes/3, galias->numverts);
pframetype = (daliasframetype_t *)&pinframe[pq1inmodel->numverts];
break;
case ALIAS_GROUP:
case ALIAS_GROUP_SWAPPED: // prerelease
ingroup = (daliasgroup_t *)(pframetype+1);
pose = (galiaspose_t *)Hunk_Alloc(LittleLong(ingroup->numframes)*(sizeof(galiaspose_t) + (sizeof(vecV_t)+sizeof(vec3_t)*3)*galias->numverts));
frame->poseofs = (char *)pose - (char *)frame;
frame->numposes = LittleLong(ingroup->numframes);
frame->loop = true;
galias->groups++;
verts = (vecV_t *)(pose+frame->numposes);
normals = (vec3_t*)&verts[galias->numverts];
svec = &normals[galias->numverts];
tvec = &svec[galias->numverts];
intervals = (daliasinterval_t *)(ingroup+1);
sinter = LittleFloat(intervals->interval);
if (sinter <= 0)
sinter = 0.1;
frame->rate = 1/sinter;
pinframe = (dtrivertx_t *)(intervals+frame->numposes);
for (k = 0; k < frame->numposes; k++)
{
pose->ofsverts = (char *)verts - (char *)pose;
#ifndef SERVERONLY
pose->ofsnormals = (char *)normals - (char *)pose;
pose->ofssvector = (char *)svec - (char *)pose;
pose->ofstvector = (char *)tvec - (char *)pose;
#endif
frameinfo = (daliasframe_t*)pinframe;
pinframe = (dtrivertx_t *)((char *)frameinfo + sizeof(daliasframe_t));
if (k == 0)
Q_strncpyz(frame->name, frameinfo->name, sizeof(frame->name));
for (j = 0; j < galias->numverts; j++)
{
verts[j][0] = pinframe[seamremaps[j]].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[seamremaps[j]].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[seamremaps[j]].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[seamremaps[j]].lightnormalindex], normals[j]);
#endif
}
verts = (vecV_t*)&tvec[galias->numverts];
normals = (vec3_t*)&verts[galias->numverts];
svec = &normals[galias->numverts];
tvec = &svec[galias->numverts];
pose++;
pinframe += pq1inmodel->numverts;
}
// GL_GenerateNormals((float*)verts, (float*)normals, (int *)((char *)galias + galias->ofs_indexes), galias->numindexes/3, galias->numverts);
pframetype = (daliasframetype_t *)pinframe;
break;
default:
Con_Printf(CON_ERROR "Bad frame type in %s\n", loadmodel->name);
return NULL;
}
frame++;
}
return pframetype;
}
//greatly reduced version of Q1_LoadSkins //greatly reduced version of Q1_LoadSkins
//just skips over the data //just skips over the data
static void *Q1_LoadSkins_SV (daliasskintype_t *pskintype, qboolean alpha) static void *Q1_LoadSkins_SV (daliasskintype_t *pskintype, qboolean alpha)
@ -2010,16 +2100,30 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran
if (!TEXVALID(texture)) if (!TEXVALID(texture))
{ {
snprintf(skinname, sizeof(skinname), "%s__%i", loadname, i); snprintf(skinname, sizeof(skinname), "%s__%i", loadname, i);
texture = R_LoadTexture8(skinname, outskin->skinwidth, outskin->skinheight, saved, (skintranstype?0:IF_NOALPHA)|IF_NOGAMMA, skintranstype); switch (skintranstype)
if (r_fb_models.ival)
{ {
snprintf(skinname, sizeof(skinname), "%s__%i_luma", loadname, i); default:
fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA); texture = R_LoadTexture(skinname,outskin->skinwidth,outskin->skinheight, TF_SOLID8, saved, IF_NOALPHA|IF_NOGAMMA);
} if (r_fb_models.ival)
if (gl_bump.ival) {
{ snprintf(skinname, sizeof(skinname), "%s__%i_luma", loadname, i);
snprintf(skinname, sizeof(skinname), "%s__%i_bump", loadname, i); fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA);
bumptexture = R_LoadTexture8BumpPal(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA); }
if (gl_bump.ival)
{
snprintf(skinname, sizeof(skinname), "%s__%i_bump", loadname, i);
bumptexture = R_LoadTexture8BumpPal(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA);
}
break;
case 2:
texture = R_LoadTexture(skinname,outskin->skinwidth,outskin->skinheight, TF_H2_T7G1, saved, IF_NOGAMMA);
break;
case 3:
texture = R_LoadTexture(skinname,outskin->skinwidth,outskin->skinheight, TF_H2_TRANS8_0, saved, IF_NOGAMMA);
break;
case 4:
texture = R_LoadTexture(skinname,outskin->skinwidth,outskin->skinheight, TF_H2_T4A4, saved, IF_NOGAMMA);
break;
} }
} }
} }
@ -2032,7 +2136,27 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran
sprintf(skinname, "%s_%i", loadname, i); sprintf(skinname, "%s_%i", loadname, i);
texnums->shader = R_RegisterSkin(skinname); if (skintranstype == 4)
texnums->shader = R_RegisterShader(skinname,
"{\n"
"{\n"
"map $diffuse\n"
"blendfunc gl_one_minus_src_alpha gl_src_alpha\n"
"rgbgen lightingDiffuse\n"
"cull disable\n"
"}\n"
"}\n");
else if (skintranstype)
texnums->shader = R_RegisterShader(skinname,
"{\n"
"{\n"
"map $diffuse\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"rgbgen lightingDiffuse\n"
"}\n"
"}\n");
else
texnums->shader = R_RegisterSkin(skinname);
R_BuildDefaultTexnums(texnums, texnums->shader); R_BuildDefaultTexnums(texnums, texnums->shader);
texnums->loweroverlay = r_nulltex; texnums->loweroverlay = r_nulltex;
@ -2159,14 +2283,16 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
int version; int version;
int i, onseams; int i, onseams;
dstvert_t *pinstverts; dstvert_t *pinstverts;
dtriangle_t *pintriangles; dtriangle_t *pinq1triangles;
dh2triangle_t *pinh2triangles;
int *seamremap; int *seamremap;
index_t *indexes; index_t *indexes;
qboolean qtest = false;
daliasskintype_t *skinstart; daliasskintype_t *skinstart;
int skintranstype; int skintranstype;
int size; int size;
unsigned int hdrsize;
void *end;
loadmodel=mod; loadmodel=mod;
@ -2174,11 +2300,17 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
pq1inmodel = (dmdl_t *)buffer; pq1inmodel = (dmdl_t *)buffer;
hdrsize = sizeof(dmdl_t) - sizeof(int);
loadmodel->engineflags |= MDLF_NEEDOVERBRIGHT; loadmodel->engineflags |= MDLF_NEEDOVERBRIGHT;
version = LittleLong(pq1inmodel->version); version = LittleLong(pq1inmodel->version);
if (version == QTESTALIAS_VERSION) if (version == QTESTALIAS_VERSION)
qtest = true; {
hdrsize = sizeof(dmdl_t) - sizeof(int)*3;
}
else if (version == 50)
hdrsize = sizeof(dmdl_t);
else if (version != ALIAS_VERSION) else if (version != ALIAS_VERSION)
{ {
Con_Printf (CON_ERROR "%s has wrong version number (%i should be %i)\n", Con_Printf (CON_ERROR "%s has wrong version number (%i should be %i)\n",
@ -2188,10 +2320,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
seamremap = (int*)pq1inmodel; //I like overloading locals. seamremap = (int*)pq1inmodel; //I like overloading locals.
if (qtest) i = hdrsize/4 - 1;
i = sizeof(dmdl_t)/4 - sizeof(int)*2 - 1;
else
i = sizeof(dmdl_t)/4 - 1;
for (; i >= 0; i--) for (; i >= 0; i--)
seamremap[i] = LittleLong(seamremap[i]); seamremap[i] = LittleLong(seamremap[i]);
@ -2207,7 +2336,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
return false; return false;
} }
if (qtest) if (hdrsize <= (unsigned int)&((dmdl_t*)NULL)->flags)
mod->flags = 0; // Qtest has no flags in header mod->flags = 0; // Qtest has no flags in header
else else
mod->flags = pq1inmodel->flags; mod->flags = pq1inmodel->flags;
@ -2226,10 +2355,8 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
galias->nextsurf = 0; galias->nextsurf = 0;
//skins //skins
if (qtest) skinstart = (daliasskintype_t *)((char*)pq1inmodel+hdrsize);
skinstart = (daliasskintype_t *)((char *)buffer + sizeof(dmdl_t) - sizeof(int)*2);
else
skinstart = (daliasskintype_t *)(pq1inmodel+1);
if( mod->flags & EFH2_HOLEY ) if( mod->flags & EFH2_HOLEY )
skintranstype = 3; //hexen2 skintranstype = 3; //hexen2
else if( mod->flags & EFH2_TRANSPARENT ) else if( mod->flags & EFH2_TRANSPARENT )
@ -2252,81 +2379,155 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
break; break;
} }
if (hdrsize == sizeof(dmdl_t))
//count number of verts that are onseam.
for (onseams=0,i = 0; i < pq1inmodel->numverts; i++)
{ {
if (pinstverts[i].onseam) int t, v, k;
onseams++; int *stremap;
} /*separate st + vert lists*/
seamremap = BZ_Malloc(sizeof(int)*pq1inmodel->numverts); pinh2triangles = (dh2triangle_t *)&pinstverts[pq1inmodel->num_st];
galias->numverts = pq1inmodel->numverts+onseams; /*each triangle can use one coord and one st, for each vert, that's a lot of combinations*/
seamremap = BZ_Malloc(sizeof(int)*pq1inmodel->numtris*6);
stremap = seamremap + pq1inmodel->numtris*3;
//st /*output the indicies as we figure out which verts we want*/
#ifndef SERVERONLY galias->numindexes = pq1inmodel->numtris*3;
st_array = Hunk_Alloc(sizeof(*st_array)*(pq1inmodel->numverts+onseams)); indexes = Hunk_Alloc(galias->numindexes*sizeof(*indexes));
galias->ofs_st_array = (char *)st_array - (char *)galias; galias->ofs_indexes = (char *)indexes - (char *)galias;
for (j=pq1inmodel->numverts,i = 0; i < pq1inmodel->numverts; i++) for (i = 0; i < pq1inmodel->numtris; i++)
{
st_array[i][0] = (LittleLong(pinstverts[i].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[i][1] = (LittleLong(pinstverts[i].t)+0.5)/(float)pq1inmodel->skinheight;
if (pinstverts[i].onseam)
{ {
st_array[j][0] = st_array[i][0]+0.5; for (j = 0; j < 3; j++)
st_array[j][1] = st_array[i][1]; {
seamremap[i] = j; v = LittleShort(pinh2triangles[i].vertindex[j]);
j++; t = LittleShort(pinh2triangles[i].stindex[j]);
if (pinstverts[t].onseam && !pinh2triangles[i].facesfront)
t += pq1inmodel->num_st;
for (k = 0; k < galias->numverts; k++) /*big fatoff slow loop*/
{
if (stremap[k] == t && seamremap[k] == v)
break;
}
if (k == galias->numverts)
{
galias->numverts++;
stremap[k] = t;
seamremap[k] = v;
}
indexes[i*3+j] = k;
}
} }
else
seamremap[i] = i;
}
#endif
//trianglelists; st_array = Hunk_Alloc(sizeof(*st_array)*(galias->numverts));
pintriangles = (dtriangle_t *)&pinstverts[pq1inmodel->numverts]; galias->ofs_st_array = (char *)st_array - (char *)galias;
/*generate our st_array now we know which vertexes we want*/
galias->numindexes = pq1inmodel->numtris*3; for (k = 0; k < galias->numverts; k++)
indexes = Hunk_Alloc(galias->numindexes*sizeof(*indexes));
galias->ofs_indexes = (char *)indexes - (char *)galias;
for (i=0 ; i<pq1inmodel->numtris ; i++)
{
if (!pintriangles[i].facesfront)
{ {
indexes[i*3+0] = seamremap[LittleLong(pintriangles[i].vertindex[0])]; if (stremap[k] > pq1inmodel->num_st)
indexes[i*3+1] = seamremap[LittleLong(pintriangles[i].vertindex[1])]; { /*onseam verts? shrink the index, and add half a texture width to the s coord*/
indexes[i*3+2] = seamremap[LittleLong(pintriangles[i].vertindex[2])]; st_array[k][0] = 0.5+(LittleLong(pinstverts[stremap[k]-pq1inmodel->num_st].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[k][1] = (LittleLong(pinstverts[stremap[k]-pq1inmodel->num_st].t)+0.5)/(float)pq1inmodel->skinheight;
}
else
{
st_array[k][0] = (LittleLong(pinstverts[stremap[k]].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[k][1] = (LittleLong(pinstverts[stremap[k]].t)+0.5)/(float)pq1inmodel->skinheight;
}
} }
else
{
indexes[i*3+0] = LittleLong(pintriangles[i].vertindex[0]);
indexes[i*3+1] = LittleLong(pintriangles[i].vertindex[1]);
indexes[i*3+2] = LittleLong(pintriangles[i].vertindex[2]);
}
}
//frames end = &pinh2triangles[pq1inmodel->numtris];
if (qtest)
{ if (H1_LoadFrameGroup((daliasframetype_t *)end, seamremap) == NULL)
if (QTest_LoadFrameGroup((daliasframetype_t *)&pintriangles[pq1inmodel->numtris], seamremap) == NULL)
{ {
BZ_Free(seamremap); BZ_Free(seamremap);
Hunk_FreeToLowMark (hunkstart); Hunk_FreeToLowMark (hunkstart);
return false; return false;
} }
BZ_Free(seamremap);
} }
else else
{ {
if (Q1_LoadFrameGroup((daliasframetype_t *)&pintriangles[pq1inmodel->numtris], seamremap) == NULL) /*onseam means +=skinwidth/2
verticies that are marked as onseam potentially generate two output verticies.
the triangle chooses which side based upon its 'onseam' field.
*/
//count number of verts that are onseam.
for (onseams=0,i = 0; i < pq1inmodel->numverts; i++)
{ {
BZ_Free(seamremap); if (pinstverts[i].onseam)
Hunk_FreeToLowMark (hunkstart); onseams++;
return false;
} }
seamremap = BZ_Malloc(sizeof(int)*pq1inmodel->numverts);
galias->numverts = pq1inmodel->numverts+onseams;
//st
#ifndef SERVERONLY
st_array = Hunk_Alloc(sizeof(*st_array)*(pq1inmodel->numverts+onseams));
galias->ofs_st_array = (char *)st_array - (char *)galias;
for (j=pq1inmodel->numverts,i = 0; i < pq1inmodel->numverts; i++)
{
st_array[i][0] = (LittleLong(pinstverts[i].s)+0.5)/(float)pq1inmodel->skinwidth;
st_array[i][1] = (LittleLong(pinstverts[i].t)+0.5)/(float)pq1inmodel->skinheight;
if (pinstverts[i].onseam)
{
st_array[j][0] = st_array[i][0]+0.5;
st_array[j][1] = st_array[i][1];
seamremap[i] = j;
j++;
}
else
seamremap[i] = i;
}
#endif
//trianglelists;
pinq1triangles = (dtriangle_t *)&pinstverts[pq1inmodel->numverts];
galias->numindexes = pq1inmodel->numtris*3;
indexes = Hunk_Alloc(galias->numindexes*sizeof(*indexes));
galias->ofs_indexes = (char *)indexes - (char *)galias;
for (i=0 ; i<pq1inmodel->numtris ; i++)
{
if (!pinq1triangles[i].facesfront)
{
indexes[i*3+0] = seamremap[LittleLong(pinq1triangles[i].vertindex[0])];
indexes[i*3+1] = seamremap[LittleLong(pinq1triangles[i].vertindex[1])];
indexes[i*3+2] = seamremap[LittleLong(pinq1triangles[i].vertindex[2])];
}
else
{
indexes[i*3+0] = LittleLong(pinq1triangles[i].vertindex[0]);
indexes[i*3+1] = LittleLong(pinq1triangles[i].vertindex[1]);
indexes[i*3+2] = LittleLong(pinq1triangles[i].vertindex[2]);
}
}
end = &pinq1triangles[pq1inmodel->numtris];
//frames
if (hdrsize <= (unsigned int)&((dmdl_t*)NULL)->flags)
{
if (QTest_LoadFrameGroup((daliasframetype_t *)end, seamremap) == NULL)
{
BZ_Free(seamremap);
Hunk_FreeToLowMark (hunkstart);
return false;
}
}
else
{
if (Q1_LoadFrameGroup((daliasframetype_t *)end, seamremap) == NULL)
{
BZ_Free(seamremap);
Hunk_FreeToLowMark (hunkstart);
return false;
}
}
BZ_Free(seamremap);
} }
BZ_Free(seamremap);
Mod_CompileTriangleNeighbours(galias); Mod_CompileTriangleNeighbours(galias);
@ -4139,6 +4340,261 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer)
#endif //ZYMOTICMODELS #endif //ZYMOTICMODELS
#ifdef INTERQUAKEMODELS
#define IQM_MAGIC "INTERQUAKEMODEL"
#define IQM_VERSION 1
struct iqmheader
{
char magic[16];
unsigned int version;
unsigned int filesize;
unsigned int flags;
unsigned int num_text, ofs_text;
unsigned int num_meshes, ofs_meshes;
unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
unsigned int num_triangles, ofs_triangles, ofs_adjacency;
unsigned int num_joints, ofs_joints;
unsigned int num_poses, ofs_poses;
unsigned int num_anims, ofs_anims;
unsigned int num_frames, num_framechannels, ofs_frames, ofs_bounds;
unsigned int num_comment, ofs_comment;
unsigned int num_extensions, ofs_extensions;
};
struct iqmmesh
{
unsigned int name;
unsigned int material;
unsigned int first_vertex, num_vertexes;
unsigned int first_triangle, num_triangles;
};
enum
{
IQM_POSITION = 0,
IQM_TEXCOORD = 1,
IQM_NORMAL = 2,
IQM_TANGENT = 3,
IQM_BLENDINDEXES = 4,
IQM_BLENDWEIGHTS = 5,
IQM_COLOR = 6,
IQM_CUSTOM = 0x10
};
enum
{
IQM_BYTE = 0,
IQM_UBYTE = 1,
IQM_SHORT = 2,
IQM_USHORT = 3,
IQM_INT = 4,
IQM_UINT = 5,
IQM_HALF = 6,
IQM_FLOAT = 7,
IQM_DOUBLE = 8,
};
struct iqmtriangle
{
unsigned int vertex[3];
};
struct iqmjoint
{
unsigned int name;
int parent;
float translate[3], rotate[3], scale[3];
};
struct iqmpose
{
int parent;
unsigned int mask;
float channeloffset[9];
float channelscale[9];
};
struct iqmanim
{
unsigned int name;
unsigned int first_frame, num_frames;
float framerate;
unsigned int flags;
};
enum
{
IQM_LOOP = 1<<0
};
struct iqmvertexarray
{
unsigned int type;
unsigned int flags;
unsigned int format;
unsigned int size;
unsigned int offset;
};
struct iqmbounds
{
float bbmin[3], bbmax[3];
float xyradius, radius;
};
galisskeletaltransforms_t *IQM_ImportTransforms(int *resultcount, int inverts, float *vpos, float *tcoord, float *vnorm, float *vtang, unsigned char *vbone, unsigned char *vweight)
{
galisskeletaltransforms_t *t, *r;
unsigned int num_t = 0;
unsigned int 0;
for (v = 0; v < inverts*4; v++)
{
if (vweight[v])
num_t++;
}
t = r = Hunk_Alloc(sizeof(*r)*num_t);
for (v = 0; v < inverts; v++)
{
for (j = 0; j < 4; j++)
{
if (vweight[v<<2+j])
{
t->boneindex = vbone[v<<2+j];
t->vertexindex = v;
VectorScale(vpos, vweight[v<<2+j]/255.0, t->org);
VectorScale(vnorm, vweight[v<<2+j]/255.0, t->normal);
t++;
}
}
}
return r;
}
galiasinfo_t *Mod_ParseMD5MeshModel(char *buffer)
{
struct iqmheader *h = (struct iqmheader *)buffer;
struct iqmjoint *joint;
struct iqmmesh *mesh;
struct iqmvertexarray *varray;
galiasinfo_t *gai;
if (memcmp(h->magic, IQM_MAGIC, sizeof(h->magic))
{
Con_Printf("%s: format not recognised\n", mod->name);
return false;
}
if (h->version != IQM_VERSION)
{
Con_Printf("%s: unsupported version\n", mod->name);
return false;
}
if (h->filesize != com_filesize)
{
Con_Printf("%s: size (%u != %u)\n", mod->name, h->filesize, com_filesize);
return false;
}
struct iqmjoint
unsigned int name;
int parent;
float translate[3], rotate[3], scale[3];
unsigned int num_meshes, ofs_meshes;
unsigned int num_vertexarrays, num_vertexes, ofs_vertexarrays;
unsigned int num_triangles, ofs_triangles, ofs_adjacency;
unsigned int num_joints, ofs_joints;
float *vpos = NULL, *tcoord = NULL, *vnorm = NULL, *vtang = NULL;
unsigned char *vbone = NULL, *vweight = NULL;
unsigned int type, fmt, size, offset;
varray = (struct iqmvertexarray*)(buffer + h->ofs_vertexarrays);
for (i = 0; i < h->num_vertexarrays; i++)
{
type = LittleLong(varray[i].type);
fmt = LittleLong(varray[i].format);
size = LittleLong(varray[i].size);
offset = LittleLong(varray[i].offset);
if (type == IQM_POSITION && fmt == IQM_FLOAT && size == 3)
vpos = (float*)(buffer + offset);
else if (type == IQM_TEXCOORD && fmt == IQM_FLOAT && size == 2)
tcoord = (float*)(buffer + offset);
else if (type == IQM_NORMAL && fmt == IQM_FLOAT && size == 3)
vnorm = (float*)(buffer + offset);
else if (type == IQM_TANGENT && fmt == IQM_FLOAT && size == 4) /*yup, 4*/
vtang = (float*)(buffer + offset);
else if (type == IQM_BLENDINDEXES && fmt == IQM_UBYTE && size == 4)
vbone = (unsigned char *)(buffer + offset);
else if (type == IQM_BLENDWEIGHTS && fmt == IQM_UBYTE && size == 4)
vweight = (unsigned char *)(buffer + offset);
}
gai = Hunk_Alloc(sizeof(*gai)*h->num_meshes);
for (i = 0; i < h->num_meshes; i++)
{
gai[i].nextsurf = (i == (h->num_meshes-1))?0:sizeof(*gai);
gai[i].sharesverts = false; //used with models with two shaders using the same vertex - use last mesh's verts
gai[i].sharesbones = i != 0;
gai[i].numverts = LittleLong(mesh[i].num_vertexes);
offset = LittleLong(mesh[i].first_vertex);
/*generate transforms for each vertex*/
gai[i].ofstransforms = (char*)IQM_ImportTransforms(&gai[i].numtransforms, gai[i].numverts, vpos+offset*3, tcoord+offset*2, vnorm+offset*3, vtang+offset*4, vbone+offset*4, vweight+offset*4) - (char*)gai;
}
galiasinfo_t
unsigned int name;
unsigned int material;
unsigned int first_vertex, num_vertexes;
unsigned int first_triangle, num_triangles;
}
qboolean Mod_ParseIQMAnim(char *buffer, galiasinfo_t *prototype, void**poseofs, galiasgroup_t *gat)
{
}
qboolean Mod_LoadInterQuakeModel(model_t *mod, void *buffer)
{
galiasinfo_t *root;
struct iqmheader *h = (struct iqmheader *)buffer;
hunkstart = Hunk_LowMark();
root = Mod_ParseMD5MeshModel(buffer);
if (!root)
return false;
hunkend = Hunk_LowMark();
mod->flags = h->flags;
Mod_ClampModelSize(mod);
Hunk_Alloc(0);
hunktotal = hunkend - hunkstart;
Cache_Alloc (&mod->cache, hunktotal, loadname);
mod->type = mod_alias;
if (!mod->cache.data)
{
Hunk_FreeToLowMark (hunkstart);
return false;
}
memcpy (mod->cache.data, root, hunktotal);
Hunk_FreeToLowMark (hunkstart);
return true;
}
#endif
#ifdef MD5MODELS #ifdef MD5MODELS
static void GenMatrix(float x, float y, float z, float qx, float qy, float qz, float result[12]) static void GenMatrix(float x, float y, float z, float qx, float qy, float qz, float result[12])

View file

@ -141,6 +141,9 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer);
qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer); qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer);
qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer); qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer);
#endif #endif
#ifdef MAP_PROC
qboolean Mod_LoadMap_Proc(model_t *mode, void *buffer);
#endif
void Mod_AccumulateTextureVectors(vecV_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx); void Mod_AccumulateTextureVectors(vecV_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx);
void Mod_AccumulateMeshTextureVectors(mesh_t *mesh); void Mod_AccumulateMeshTextureVectors(mesh_t *mesh);

View file

@ -1883,8 +1883,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
ed->ode.ode_geom = (void *)dCreateSphere(world->ode.ode_space, geomsize[0] * 0.5f); ed->ode.ode_geom = (void *)dCreateSphere(world->ode.ode_space, geomsize[0] * 0.5f);
dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f); dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
break; break;
#pragma message("SOLID_PHYSICS_CAPSULE not supported") case SOLID_PHYSICS_CAPSULE:
/* case SOLID_PHYSICS_CAPSULE:
axisindex = 0; axisindex = 0;
if (geomsize[axisindex] < geomsize[1]) if (geomsize[axisindex] < geomsize[1])
axisindex = 1; axisindex = 1;
@ -1896,11 +1895,11 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
// transform to it // transform to it
memset(capsulerot, 0, sizeof(capsulerot)); memset(capsulerot, 0, sizeof(capsulerot));
if (axisindex == 0) if (axisindex == 0)
Matrix4_CreateFromQuakeEntity(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1); Matrix4_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 90, 1);
else if (axisindex == 1) else if (axisindex == 1)
Matrix4_CreateFromQuakeEntity(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1); Matrix4_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 90, 0, 0, 1);
else else
Matrix4_CreateFromQuakeEntity(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1); Matrix4_ModelMatrix(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2], 0, 0, 0, 1);
radius = geomsize[!axisindex] * 0.5f; // any other axis is the radius radius = geomsize[!axisindex] * 0.5f; // any other axis is the radius
length = geomsize[axisindex] - radius*2; length = geomsize[axisindex] - radius*2;
// because we want to support more than one axisindex, we have to // because we want to support more than one axisindex, we have to
@ -1909,7 +1908,6 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
ed->ode.ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, length); ed->ode.ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, length);
dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length); dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length);
break; break;
*/
default: default:
Sys_Error("World_Physics_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid); Sys_Error("World_Physics_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
} }

View file

@ -759,8 +759,6 @@ void MSG_WriteString (sizebuf_t *sb, const char *s)
SZ_Write (sb, s, Q_strlen(s)+1); SZ_Write (sb, s, Q_strlen(s)+1);
} }
int sizeofcoord=2;
int sizeofangle=1;
float MSG_FromCoord(coorddata c, int bytes) float MSG_FromCoord(coorddata c, int bytes)
{ {
switch(bytes) switch(bytes)
@ -829,8 +827,8 @@ coorddata MSG_ToAngle(float f, int bytes) //return value is NOT byteswapped.
void MSG_WriteCoord (sizebuf_t *sb, float f) void MSG_WriteCoord (sizebuf_t *sb, float f)
{ {
coorddata i = MSG_ToCoord(f, sizeofcoord); coorddata i = MSG_ToCoord(f, sb->prim.coordsize);
SZ_Write (sb, (void*)&i, sizeofcoord); SZ_Write (sb, (void*)&i, sb->prim.coordsize);
} }
void MSG_WriteAngle16 (sizebuf_t *sb, float f) void MSG_WriteAngle16 (sizebuf_t *sb, float f)
@ -850,8 +848,10 @@ void MSG_WriteAngle8 (sizebuf_t *sb, float f)
void MSG_WriteAngle (sizebuf_t *sb, float f) void MSG_WriteAngle (sizebuf_t *sb, float f)
{ {
if (sizeofangle==2) if (sb->prim.anglesize==2)
MSG_WriteAngle16(sb, f); MSG_WriteAngle16(sb, f);
else if (sb->prim.anglesize==4)
MSG_WriteFloat(sb, f);
else else
MSG_WriteAngle8 (sb, f); MSG_WriteAngle8 (sb, f);
} }
@ -959,13 +959,20 @@ void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
// //
int msg_readcount; int msg_readcount;
qboolean msg_badread; qboolean msg_badread;
struct netprim_s msg_nullnetprim;
void MSG_BeginReading (void) void MSG_BeginReading (struct netprim_s prim)
{ {
msg_readcount = 0; msg_readcount = 0;
msg_badread = false; msg_badread = false;
net_message.currentbit = 0; net_message.currentbit = 0;
net_message.packing = SZ_RAWBYTES; net_message.packing = SZ_RAWBYTES;
net_message.prim = prim;
}
void MSG_ChangePrimitives(struct netprim_s prim)
{
net_message.prim = prim;
} }
int MSG_GetReadCount(void) int MSG_GetReadCount(void)
@ -1286,8 +1293,8 @@ char *MSG_ReadStringLine (void)
float MSG_ReadCoord (void) float MSG_ReadCoord (void)
{ {
coorddata c = {{0}}; coorddata c = {{0}};
MSG_ReadData(&c, sizeofcoord); MSG_ReadData(&c, net_message.prim.coordsize);
return MSG_FromCoord(c, sizeofcoord); return MSG_FromCoord(c, net_message.prim.coordsize);
} }
void MSG_ReadPos (vec3_t pos) void MSG_ReadPos (vec3_t pos)
@ -1297,12 +1304,14 @@ void MSG_ReadPos (vec3_t pos)
pos[2] = MSG_ReadCoord(); pos[2] = MSG_ReadCoord();
} }
#if defined(Q2CLIENT) || defined(Q2SERVER)
#define Q2NUMVERTEXNORMALS 162 #define Q2NUMVERTEXNORMALS 162
vec3_t bytedirs[Q2NUMVERTEXNORMALS] = vec3_t bytedirs[Q2NUMVERTEXNORMALS] =
{ {
#include "../client/q2anorms.h" #include "../client/q2anorms.h"
}; };
#ifndef SERVERONLY #endif
#ifdef Q2CLIENT
void MSG_ReadDir (vec3_t dir) void MSG_ReadDir (vec3_t dir)
{ {
int b; int b;
@ -1316,6 +1325,7 @@ void MSG_ReadDir (vec3_t dir)
VectorCopy (bytedirs[b], dir); VectorCopy (bytedirs[b], dir);
} }
#endif #endif
#ifdef Q2SERVER
void MSG_WriteDir (sizebuf_t *sb, vec3_t dir) void MSG_WriteDir (sizebuf_t *sb, vec3_t dir)
{ {
int i, best; int i, best;
@ -1340,6 +1350,7 @@ void MSG_WriteDir (sizebuf_t *sb, vec3_t dir)
} }
MSG_WriteByte (sb, best); MSG_WriteByte (sb, best);
} }
#endif
float MSG_ReadAngle16 (void) float MSG_ReadAngle16 (void)
{ {
@ -1347,9 +1358,18 @@ float MSG_ReadAngle16 (void)
} }
float MSG_ReadAngle (void) float MSG_ReadAngle (void)
{ {
if (sizeofangle==2) switch(net_message.prim.anglesize)
{
case 2:
return MSG_ReadAngle16(); return MSG_ReadAngle16();
return MSG_ReadChar() * (360.0/256); case 4:
return MSG_ReadFloat();
case 1:
return MSG_ReadChar() * (360.0/256);
default:
Host_Error("Bad angle size\n");
return 0;
}
} }
void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move) void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move)

View file

@ -38,6 +38,11 @@ typedef enum {false, true} qboolean;
#define MAX_SERVERINFO_STRING 1024 //standard quake has 512 here. #define MAX_SERVERINFO_STRING 1024 //standard quake has 512 here.
#define MAX_LOCALINFO_STRING 32768 #define MAX_LOCALINFO_STRING 32768
struct netprim_s
{
int coordsize;
int anglesize;
};
//============================================================================ //============================================================================
typedef enum { typedef enum {
@ -55,6 +60,8 @@ typedef struct sizebuf_s
int cursize; int cursize;
int packing; int packing;
int currentbit; int currentbit;
struct netprim_s prim;
} sizebuf_t; } sizebuf_t;
void SZ_Clear (sizebuf_t *buf); void SZ_Clear (sizebuf_t *buf);
@ -127,8 +134,6 @@ typedef union { //note: reading from packets can be misaligned
int b4; int b4;
float f; float f;
} coorddata; } coorddata;
extern int sizeofcoord;
extern int sizeofangle;
float MSG_FromCoord(coorddata c, int bytes); float MSG_FromCoord(coorddata c, int bytes);
coorddata MSG_ToCoord(float f, int bytes); coorddata MSG_ToCoord(float f, int bytes);
coorddata MSG_ToAngle(float f, int bytes); coorddata MSG_ToAngle(float f, int bytes);
@ -149,8 +154,10 @@ void MSG_WriteDir (sizebuf_t *sb, float *dir);
extern int msg_readcount; extern int msg_readcount;
extern qboolean msg_badread; // set if a read goes beyond end of message extern qboolean msg_badread; // set if a read goes beyond end of message
struct netprim_s msg_nullnetprim;
void MSG_BeginReading (void); void MSG_BeginReading (struct netprim_s prim);
void MSG_ChangePrimitives(struct netprim_s prim);
int MSG_GetReadCount(void); int MSG_GetReadCount(void);
int MSG_ReadChar (void); int MSG_ReadChar (void);
int MSG_ReadBits(int bits); int MSG_ReadBits(int bits);

View file

@ -148,6 +148,8 @@ char *Cvar_FlagToName(int flag)
return "nounsafeexpand"; return "nounsafeexpand";
case CVAR_RULESETLATCH: case CVAR_RULESETLATCH:
return "rulesetlatch"; return "rulesetlatch";
case CVAR_SHADERSYSTEM:
return "shadersystem";
} }
return NULL; return NULL;

View file

@ -292,12 +292,12 @@ void COM_Locate_f (void)
{ {
if (!*loc.rawname) if (!*loc.rawname)
{ {
Con_Printf("File is compressed inside "); Con_Printf("File is %i bytes compressed inside ", loc.len);
loc.search->funcs->PrintPath(loc.search->handle); loc.search->funcs->PrintPath(loc.search->handle);
} }
else else
{ {
Con_Printf("Inside %s\n", loc.rawname); Con_Printf("Inside %s (%i bytes)\n", loc.rawname, loc.len);
loc.search->funcs->PrintPath(loc.search->handle); loc.search->funcs->PrintPath(loc.search->handle);
} }
} }
@ -1803,6 +1803,7 @@ void COM_Gamedir (const char *dir)
#define DPCOMPAT "set dpcompat_set 1\nset dpcompat_trailparticles 1\n" #define DPCOMPAT "set dpcompat_set 1\nset dpcompat_trailparticles 1\n"
#define NEXCFG DPCOMPAT "set sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\nset r_particlesdesc effectinfo\n" #define NEXCFG DPCOMPAT "set sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\nset r_particlesdesc effectinfo\n"
#define DMFCFG "set com_parseutf8 1\npm_airstep 1\n" #define DMFCFG "set com_parseutf8 1\npm_airstep 1\n"
#define HEX2CFG "set sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\n"
typedef struct { typedef struct {
const char *protocolname; //sent to the master server when this is the current gamemode. const char *protocolname; //sent to the master server when this is the current gamemode.
@ -1828,9 +1829,11 @@ const gamemode_info_t gamemode_info[] = {
{"DMF", "dmf", "-dmf", "base/src/progs.src",DMFCFG,{"base", }, "DMF"}, {"DMF", "dmf", "-dmf", "base/src/progs.src",DMFCFG,{"base", }, "DMF"},
//supported commercial mods (some are currently only partially supported) //supported commercial mods (some are currently only partially supported)
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", NULL, {"data1", "fteh2"}, "Hexen II"}, {"FTE-H2MP", "h2mp", "-portals", "portals/hexen.rc", HEX2CFG,{"data1", "portals", "fteh2"}, "Hexen II MP"},
{"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", HEX2CFG,{"data1", "fteh2"}, "Hexen II"},
{"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", NULL, {"baseq2", "fteq2"}, "Quake II"}, {"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", NULL, {"baseq2", "fteq2"}, "Quake II"},
{"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", NULL, {"baseq3", "fteq3"}, "Quake III Arena"}, {"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", NULL, {"baseq3", "fteq3"}, "Quake III Arena"},
{"FTE-Quake4", "q4", "-q4", "q4base/pak00.pk4", NULL, {"q4base", "fteq4"}, "Quake 4"},
{"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, {"base", "fte"}, "Jedi Knight II: Jedi Outcast"}, {"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", NULL, {"base", "fte"}, "Jedi Knight II: Jedi Outcast"},

View file

@ -3886,7 +3886,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
} }
#ifndef SERVERONLY #ifndef SERVERONLY
Mod_ParseInfoFromEntityLump(loadmodel->entities, loadname); //only done for client's world model (or server if the server is loading it for client) Mod_ParseInfoFromEntityLump(loadmodel, loadmodel->entities, loadname); //only done for client's world model (or server if the server is loading it for client)
#endif #endif
CM_InitBoxHull (); CM_InitBoxHull ();

View file

@ -595,7 +595,7 @@ beginning from specified offset
void Huff_EncryptPacket(sizebuf_t *msg, int offset) void Huff_EncryptPacket(sizebuf_t *msg, int offset)
{ {
tree_t tree; tree_t tree;
qbyte buffer[MAX_NQMSGLEN]; qbyte buffer[MAX_OVERALLMSGLEN];
qbyte *data; qbyte *data;
int outLen; int outLen;
int inLen; int inLen;
@ -603,7 +603,7 @@ void Huff_EncryptPacket(sizebuf_t *msg, int offset)
data = msg->data + offset; data = msg->data + offset;
inLen = msg->cursize - offset; inLen = msg->cursize - offset;
if (inLen <= 0 || inLen >= MAX_NQMSGLEN) if (inLen <= 0 || inLen >= MAX_OVERALLMSGLEN)
{ {
return; return;
} }
@ -638,7 +638,7 @@ beginning from specified offset
void Huff_DecryptPacket(sizebuf_t *msg, int offset) void Huff_DecryptPacket(sizebuf_t *msg, int offset)
{ {
tree_t tree; tree_t tree;
qbyte buffer[MAX_NQMSGLEN]; qbyte buffer[MAX_OVERALLMSGLEN];
qbyte *data; qbyte *data;
int outLen; int outLen;
int inLen; int inLen;
@ -784,7 +784,7 @@ beginning from specified offset
*/ */
void Huff_CompressPacket( sizebuf_t *msg, int offset ) void Huff_CompressPacket( sizebuf_t *msg, int offset )
{ {
qbyte buffer[MAX_NQMSGLEN]; qbyte buffer[MAX_OVERALLMSGLEN];
qbyte *data; qbyte *data;
int outLen; int outLen;
int inLen; int inLen;
@ -795,7 +795,7 @@ void Huff_CompressPacket( sizebuf_t *msg, int offset )
data = msg->data + offset; data = msg->data + offset;
inLen = msg->cursize - offset; inLen = msg->cursize - offset;
if (inLen <= 0 || inLen >= MAX_NQMSGLEN) if (inLen <= 0 || inLen >= MAX_OVERALLMSGLEN)
{ {
return; return;
} }
@ -803,7 +803,7 @@ void Huff_CompressPacket( sizebuf_t *msg, int offset )
outLen = 0; outLen = 0;
for (i=0; i < inLen; i++) for (i=0; i < inLen; i++)
{ {
if (i == MAX_NQMSGLEN) if (i == MAX_OVERALLMSGLEN)
Sys_Error("Compression became too large\n"); Sys_Error("Compression became too large\n");
Huff_EmitByte(data[i], buffer, &outLen); Huff_EmitByte(data[i], buffer, &outLen);
@ -841,7 +841,7 @@ beginning from specified offset
*/ */
void Huff_DecompressPacket(sizebuf_t *msg, int offset) void Huff_DecompressPacket(sizebuf_t *msg, int offset)
{ {
qbyte buffer[MAX_NQMSGLEN]; qbyte buffer[MAX_OVERALLMSGLEN];
qbyte *data; qbyte *data;
int outLen; int outLen;
int inLen; int inLen;
@ -852,7 +852,7 @@ void Huff_DecompressPacket(sizebuf_t *msg, int offset)
data = msg->data + offset; data = msg->data + offset;
inLen = msg->cursize - offset; inLen = msg->cursize - offset;
if (inLen <= 0 || inLen >= MAX_NQMSGLEN) if (inLen <= 0 || inLen >= MAX_OVERALLMSGLEN)
{ {
return; return;
} }
@ -872,7 +872,7 @@ void Huff_DecompressPacket(sizebuf_t *msg, int offset)
outLen = 0; outLen = 0;
for(i=0; outLen < inLen; i++) for(i=0; outLen < inLen; i++)
{ {
if (i == MAX_NQMSGLEN) if (i == MAX_OVERALLMSGLEN)
Sys_Error("Decompression became too large\n"); Sys_Error("Decompression became too large\n");
buffer[i] = Huff_GetByte(data, &outLen); buffer[i] = Huff_GetByte(data, &outLen);
} }

View file

@ -1061,6 +1061,36 @@ void Matrix4_ModelMatrixFromAxis(float *modelview, const vec3_t pn, const vec3_t
Matrix4_Multiply(Matrix4_NewTranslation(vieworg[0], vieworg[1], vieworg[2]), tempmat, modelview); // put Z going up Matrix4_Multiply(Matrix4_NewTranslation(vieworg[0], vieworg[1], vieworg[2]), tempmat, modelview); // put Z going up
} }
void Matrix4_ModelMatrix(float *modelview, vec_t x, vec_t y, vec_t z, vec_t pitch, vec_t yaw, vec_t roll, vec_t scale)
{
float tempmat[16];
//load identity.
memset(modelview, 0, sizeof(*modelview)*16);
#if FULLYGL
modelview[0] = 1;
modelview[5] = 1;
modelview[10] = 1;
modelview[15] = 1;
Matrix4_Multiply(modelview, Matrix4_NewRotation(-90, 1, 0, 0), tempmat); // put Z going up
Matrix4_Multiply(tempmat, Matrix4_NewRotation(90, 0, 0, 1), modelview); // put Z going up
#else
//use this lame wierd and crazy identity matrix..
modelview[2] = -1;
modelview[4] = -1;
modelview[9] = 1;
modelview[15] = 1;
#endif
//figure out the current modelview matrix
//I would if some of these, but then I'd still need a couple of copys
Matrix4_Multiply(modelview, Matrix4_NewRotation(-roll, 1, 0, 0), tempmat);
Matrix4_Multiply(tempmat, Matrix4_NewRotation(-pitch, 0, 1, 0), modelview);
Matrix4_Multiply(modelview, Matrix4_NewRotation(-yaw, 0, 0, 1), tempmat);
Matrix4_Multiply(tempmat, Matrix4_NewTranslation(x, y, z), modelview);
}
void Matrix4_Identity(float *outm) void Matrix4_Identity(float *outm)
{ {
outm[ 0] = 1; outm[ 0] = 1;

View file

@ -137,6 +137,7 @@ void Matrix4Q_Invert_Simple (const float *in1, float *out);
void Matrix4_CreateTranslate (float *out, float x, float y, float z); void Matrix4_CreateTranslate (float *out, float x, float y, float z);
void Matrix4Q_CreateTranslate (float *out, float x, float y, float z); void Matrix4Q_CreateTranslate (float *out, float x, float y, float z);
void Matrix4_ModelMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg); void Matrix4_ModelMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg);
void Matrix4_ModelMatrix(float *modelview, vec_t x, vec_t y, vec_t z, vec_t pitch, vec_t yaw, vec_t roll, vec_t scale);
void Matrix4_ModelViewMatrix (float *modelview, const vec3_t viewangles, const vec3_t vieworg); void Matrix4_ModelViewMatrix (float *modelview, const vec3_t viewangles, const vec3_t vieworg);
void Matrix4_ModelViewMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg); void Matrix4_ModelViewMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg);
void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale); void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale);

View file

@ -117,6 +117,7 @@ typedef struct
#ifdef NQPROT #ifdef NQPROT
qboolean isnqprotocol; qboolean isnqprotocol;
struct netprim_s netprim;
#endif #endif
float last_received; // for timeouts float last_received; // for timeouts

View file

@ -244,7 +244,7 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
int sequence; int sequence;
int drop; int drop;
MSG_BeginReading (); MSG_BeginReading (chan->netprim);
header = LongSwap(MSG_ReadLong()); header = LongSwap(MSG_ReadLong());
if (net_message.cursize != (header & NETFLAG_LENGTH_MASK)) if (net_message.cursize != (header & NETFLAG_LENGTH_MASK))
@ -326,7 +326,7 @@ nqprot_t NQNetChan_Process(netchan_t *chan)
SZ_Clear(&net_message); SZ_Clear(&net_message);
SZ_Write(&net_message, chan->in_fragment_buf, chan->in_fragment_length); SZ_Write(&net_message, chan->in_fragment_buf, chan->in_fragment_length);
chan->in_fragment_length = 0; chan->in_fragment_length = 0;
MSG_BeginReading(); MSG_BeginReading(chan->netprim);
return NQP_RELIABLE; //we can read it now return NQP_RELIABLE; //we can read it now
} }
} }
@ -548,7 +548,7 @@ qboolean Netchan_Process (netchan_t *chan)
return false; return false;
// get sequence numbers // get sequence numbers
MSG_BeginReading (); MSG_BeginReading (chan->netprim);
sequence = MSG_ReadLong (); sequence = MSG_ReadLong ();
sequence_ack = MSG_ReadLong (); sequence_ack = MSG_ReadLong ();

View file

@ -952,18 +952,18 @@ void PM_NudgePosition (void)
vec3_t base; vec3_t base;
int x, y, z; int x, y, z;
int i; int i;
static int sign[3] = {0, -1, 1}; static int sign[5] = {0, -1, 1, -2, 2};
VectorCopy (pmove.origin, base); VectorCopy (pmove.origin, base);
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
pmove.origin[i] = ((int)(pmove.origin[i]*8)) * 0.125; pmove.origin[i] = ((int)(pmove.origin[i]*8)) * 0.125;
for (z=0 ; z<=2 ; z++) for (z=0 ; z<=4 ; z++)
{ {
for (x=0 ; x<=2 ; x++) for (x=0 ; x<=4 ; x++)
{ {
for (y=0 ; y<=2 ; y++) for (y=0 ; y<=4 ; y++)
{ {
pmove.origin[0] = base[0] + (sign[x] * 1.0/8); pmove.origin[0] = base[0] + (sign[x] * 1.0/8);
pmove.origin[1] = base[1] + (sign[y] * 1.0/8); pmove.origin[1] = base[1] + (sign[y] * 1.0/8);

View file

@ -363,18 +363,24 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end)
if (pe->nonsolid) if (pe->nonsolid)
continue; continue;
if (!pe->model) if (!pe->model || pe->model->needload)
{ {
vec3_t mins, maxs; vec3_t mins, maxs;
VectorSubtract (pe->mins, player_maxs, mins); VectorSubtract (pe->mins, player_maxs, mins);
VectorSubtract (pe->maxs, player_mins, maxs); VectorSubtract (pe->maxs, player_mins, maxs);
PM_HullForBox (mins, maxs); PM_HullForBox (mins, maxs);
}
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
if (!PM_TransformedHullCheck (pe->model, start, end, &trace, pe->origin, pe->angles)) if (!PM_TransformedHullCheck (NULL, start, end, &trace, pe->origin, pe->angles))
continue; continue;
}
else
{
// trace a line through the apropriate clipping hull
if (!PM_TransformedHullCheck (pe->model, start, end, &trace, pe->origin, pe->angles))
continue;
}
if (trace.allsolid) if (trace.allsolid)
trace.startsolid = true; trace.startsolid = true;

View file

@ -2833,6 +2833,7 @@ lh_extension_t QSG_Extensions[] = {
{"ZQ_MOVETYPE_NOCLIP"}, {"ZQ_MOVETYPE_NOCLIP"},
{"ZQ_MOVETYPE_NONE"}, {"ZQ_MOVETYPE_NONE"},
// {"ZQ_QC_PARTICLE"}, //particle builtin works in QW ( we don't mimic ZQ fully though) // {"ZQ_QC_PARTICLE"}, //particle builtin works in QW ( we don't mimic ZQ fully though)
{"ZQ_VWEP", 1, NULL, {"precache_vwep_model"}},
{"ZQ_QC_STRINGS", 7, NULL, {"stof", "strlen","strcat","substring","stov","strzone","strunzone"}} //a trimmed down FRIK_FILE. {"ZQ_QC_STRINGS", 7, NULL, {"stof", "strlen","strcat","substring","stov","strzone","strunzone"}} //a trimmed down FRIK_FILE.

View file

@ -270,6 +270,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svcfte_cgamepacket 83 #define svcfte_cgamepacket 83
//fitz svcs
#define svcfitz_skybox 37
#define svcfitz_bf 40
#define svcfitz_fog 41
#define svcfitz_spawnbaseline2 42
#define svcfitz_spawnstatic2 43
#define svcfitz_spawnstaticsound2 44
//DP extended svcs //DP extended svcs
#define svcdp_downloaddata 50 #define svcdp_downloaddata 50
#define svcdp_updatestatbyte 51 #define svcdp_updatestatbyte 51
@ -497,6 +505,55 @@ enum clcq2_ops_e
#endif #endif
#ifdef NQPROT
#define NQU_MOREBITS (1<<0)
#define NQU_ORIGIN1 (1<<1)
#define NQU_ORIGIN2 (1<<2)
#define NQU_ORIGIN3 (1<<3)
#define NQU_ANGLE2 (1<<4)
#define NQU_NOLERP (1<<5) // don't interpolate movement
#define NQU_FRAME (1<<6)
#define NQU_SIGNAL (1<<7) // just differentiates from other updates
// svc_update can pass all of the fast update bits, plus more
#define NQU_ANGLE1 (1<<8)
#define NQU_ANGLE3 (1<<9)
#define NQU_MODEL (1<<10)
#define NQU_COLORMAP (1<<11)
#define NQU_SKIN (1<<12)
#define NQU_EFFECTS (1<<13)
#define NQU_LONGENTITY (1<<14)
// LordHavoc's: protocol extension
#define DPU_EXTEND1 (1<<15)
// LordHavoc: first extend byte
#define DPU_DELTA (1<<16) // no data, while this is set the entity is delta compressed (uses previous frame as a baseline, meaning only things that have changed from the previous frame are sent, except for the forced full update every half second)
#define DPU_ALPHA (1<<17) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 1, and the entity is not sent if <=0 unless it has effects (model effects are checked as well)
#define DPU_SCALE (1<<18) // 1 byte, scale / 16 positive, not sent if 1.0
#define DPU_EFFECTS2 (1<<19) // 1 byte, this is .effects & 0xFF00 (second byte)
#define DPU_GLOWSIZE (1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0
#define DPU_GLOWCOLOR (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set)
// LordHavoc: colormod feature has been removed, because no one used it
#define DPU_COLORMOD (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend...
#define DPU_EXTEND2 (1<<23) // another byte to follow
// LordHavoc: second extend byte
#define DPU_GLOWTRAIL (1<<24) // leaves a trail of particles (of color .glowcolor, or black if it is a negative glowsize)
#define DPU_VIEWMODEL (1<<25) // attachs the model to the view (origin and angles become relative to it), only shown to owner, a more powerful alternative to .weaponmodel and such
#define DPU_FRAME2 (1<<26) // 1 byte, this is .frame & 0xFF00 (second byte)
#define DPU_MODEL2 (1<<27) // 1 byte, this is .modelindex & 0xFF00 (second byte)
#define DPU_EXTERIORMODEL (1<<28) // causes this model to not be drawn when using a first person view (third person will draw it, first person will not)
#define DPU_UNUSED29 (1<<29) // future expansion
#define DPU_UNUSED30 (1<<30) // future expansion
#define DPU_EXTEND3 (1<<31) // another byte to follow, future expansion
#define FITZU_ALPHA (1<<16)
#define FITZU_FRAME2 (1<<17)
#define FITZU_MODEL2 (1<<18)
#define FITZU_LERPFINISH (1<<19)
#endif
@ -1285,3 +1342,7 @@ typedef struct q1usercmd_s
#define E5_EXTEND4 (1<<31) #define E5_EXTEND4 (1<<31)
#define E5_ALLUNUSED (E5_UNUSED24|E5_UNUSED25|E5_UNUSED26|E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30) #define E5_ALLUNUSED (E5_UNUSED24|E5_UNUSED25|E5_UNUSED26|E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30)
#define FITZB_LARGEMODEL (1<<0) // modelindex is short instead of byte
#define FITZB_LARGEFRAME (1<<1) // frame is short instead of byte
#define FITZB_ALPHA (1<<2) // 1 byte, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT

View file

@ -545,7 +545,7 @@ qboolean Netchan_ProcessQ3 (netchan_t *chan)
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
// Get sequence number // Get sequence number
MSG_BeginReading(); MSG_BeginReading(msg_nullnetprim);
sequence = MSG_ReadBits(32); sequence = MSG_ReadBits(32);
// Read the qport if we are a server // Read the qport if we are a server
@ -657,7 +657,7 @@ qboolean Netchan_ProcessQ3 (netchan_t *chan)
MSG_WriteLong(&net_message, sequence); MSG_WriteLong(&net_message, sequence);
SZ_Write(&net_message, chan->in_fragment_buf, chan->in_fragment_length); SZ_Write(&net_message, chan->in_fragment_buf, chan->in_fragment_length);
MSG_BeginReading(); MSG_BeginReading(msg_nullnetprim);
MSG_ReadLong(); MSG_ReadLong();
// No more fragments // No more fragments

View file

@ -126,6 +126,7 @@ struct world_s
FTE_DEPRECATED unsigned int edict_size; //still used in copyentity FTE_DEPRECATED unsigned int edict_size; //still used in copyentity
wedict_t *edicts; // can NOT be array indexed. wedict_t *edicts; // can NOT be array indexed.
struct progfuncs_s *progs; struct progfuncs_s *progs;
qboolean usesolidcorpse;
model_t *worldmodel; model_t *worldmodel;
areanode_t areanodes[AREA_NODES]; areanode_t areanodes[AREA_NODES];
int numareanodes; int numareanodes;

View file

@ -1126,12 +1126,6 @@ void (D3D9_R_LessenStains) (void);
qboolean (D3D9_VID_Init) (rendererstate_t *info, unsigned char *palette); qboolean (D3D9_VID_Init) (rendererstate_t *info, unsigned char *palette);
void (D3D9_VID_DeInit) (void); void (D3D9_VID_DeInit) (void);
void (D3D9_VID_LockBuffer) (void);
void (D3D9_VID_UnlockBuffer) (void);
void (D3D9_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height);
void (D3D9_D_EndDirectRect) (int x, int y, int width, int height);
void (D3D9_VID_ForceLockState) (int lk);
int (D3D9_VID_ForceUnlockedAndReturnState) (void);
void (D3D9_VID_SetPalette) (unsigned char *palette); void (D3D9_VID_SetPalette) (unsigned char *palette);
void (D3D9_VID_ShiftPalette) (unsigned char *palette); void (D3D9_VID_ShiftPalette) (unsigned char *palette);
char *(D3D9_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight); char *(D3D9_VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight);

View file

@ -871,25 +871,6 @@ void (D3D9_VID_DeInit) (void)
mainwindow = NULL; mainwindow = NULL;
} }
} }
void (D3D9_VID_LockBuffer) (void)
{
}
void (D3D9_VID_UnlockBuffer) (void)
{
}
void (D3D9_D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height)
{
}
void (D3D9_D_EndDirectRect) (int x, int y, int width, int height)
{
}
void (D3D9_VID_ForceLockState) (int lk)
{
}
int (D3D9_VID_ForceUnlockedAndReturnState) (void)
{
return 0;
}
void (D3D9_VID_SetPalette) (unsigned char *palette) void (D3D9_VID_SetPalette) (unsigned char *palette)
{ {

View file

@ -119,7 +119,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../fteglqw_dbg.exe" /libpath:"../libs/dxsdk7/lib" # ADD LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../fteglqwvc6.exe" /libpath:"../libs/dxsdk7/lib"
# SUBTRACT LINK32 /pdb:none # SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
@ -2116,6 +2116,41 @@ SOURCE=..\client\p_null.c
# Begin Source File # Begin Source File
SOURCE=..\client\p_qmb.c SOURCE=..\client\p_qmb.c
!IF "$(CFG)" == "ftequake - Win32 Release"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3"
!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug"
!ENDIF
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -3521,6 +3556,41 @@ SOURCE=..\gl\gl_font.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\gl\gl_glsl.c
!IF "$(CFG)" == "ftequake - Win32 Release"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3"
!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\gl\gl_heightmap.c SOURCE=..\gl\gl_heightmap.c
!IF "$(CFG)" == "ftequake - Win32 Release" !IF "$(CFG)" == "ftequake - Win32 Release"

View file

@ -18,6 +18,18 @@ Package=<4>
############################################################################### ###############################################################################
Project: "ftecs"=..\..\QUAKEC\ftecs\ftecs.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "ftequake"=.\ftequake.dsp - Package Owner=<4> Project: "ftequake"=.\ftequake.dsp - Package Owner=<4>
Package=<5> Package=<5>

View file

@ -728,7 +728,14 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{ {
if (e->flags & Q2RF_WEAPONMODEL) if (e->flags & Q2RF_WEAPONMODEL)
{
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir); cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir);
for (i = 0; i < 3; i++)
{ /*viewmodels may not be pure black*/
if (ambientlight[i] < 24)
ambientlight[i] = 24;
}
}
else else
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, e->origin, shadelight, ambientlight, lightdir); cl.worldmodel->funcs.LightPointValues(cl.worldmodel, e->origin, shadelight, ambientlight, lightdir);
} }
@ -770,17 +777,8 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int
{ {
if (ambientlight[i] > 128) if (ambientlight[i] > 128)
ambientlight[i] = 128; ambientlight[i] = 128;
if (ambientlight[i] + shadelight[i] > 192) if (shadelight[i] > 192)
shadelight[i] = 192 - ambientlight[i]; shadelight[i] = 192;
}
if (e->flags & Q2RF_WEAPONMODEL)
{
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 24)
ambientlight[i] = shadelight[i] = 24;
}
} }
//MORE HUGE HACKS! WHEN WILL THEY CEASE! //MORE HUGE HACKS! WHEN WILL THEY CEASE!
@ -850,7 +848,7 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int
{ {
vec3_t temp; vec3_t temp;
temp[0] = DotProduct(shadevector, vpn); temp[0] = DotProduct(shadevector, vpn);
temp[1] = DotProduct(shadevector, vright); temp[1] = -DotProduct(shadevector, vright);
temp[2] = DotProduct(shadevector, vup); temp[2] = DotProduct(shadevector, vup);
VectorCopy(temp, shadevector); VectorCopy(temp, shadevector);
@ -945,7 +943,7 @@ void R_DrawGAliasModel (entity_t *e, unsigned int rmode)
{ {
bef |= BEF_FORCEADDITIVE; bef |= BEF_FORCEADDITIVE;
} }
else if (e->drawflags & DRF_TRANSLUCENT) else if (e->drawflags & DRF_TRANSLUCENT) //hexen2
{ {
bef |= BEF_FORCETRANSPARENT; bef |= BEF_FORCETRANSPARENT;
e->shaderRGBAf[3] = r_wateralpha.value; e->shaderRGBAf[3] = r_wateralpha.value;
@ -964,7 +962,7 @@ void R_DrawGAliasModel (entity_t *e, unsigned int rmode)
//BEFIXME: this needs to generate the right sort of default instead //BEFIXME: this needs to generate the right sort of default instead
//(alpha test) //(alpha test)
} }
else if (e->shaderRGBAf[3] < 1) else if (e->shaderRGBAf[3] < 1 && cls.protocol != CP_QUAKE3)
bef |= BEF_FORCETRANSPARENT; bef |= BEF_FORCETRANSPARENT;
BE_SelectMode(rmode, bef); BE_SelectMode(rmode, bef);

View file

@ -657,6 +657,8 @@ static void RevertToKnownState(void)
qglEnableClientState(GL_VERTEX_ARRAY); qglEnableClientState(GL_VERTEX_ARRAY);
checkerror(); checkerror();
GL_TexEnv(GL_REPLACE);
qglColor3f(1,1,1); qglColor3f(1,1,1);
shaderstate.shaderbits &= ~(SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY); shaderstate.shaderbits &= ~(SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY);
@ -2585,6 +2587,9 @@ static void BaseBrushTextures(entity_t *ent)
model = ent->model; model = ent->model;
if (R_CullEntityBox (ent, model->mins, model->maxs))
return;
#ifdef RTLIGHTS #ifdef RTLIGHTS
if (BE_LightCullModel(ent->origin, model)) if (BE_LightCullModel(ent->origin, model))
return; return;
@ -2617,10 +2622,18 @@ static void BaseBrushTextures(entity_t *ent)
} }
shift = Surf_LightmapShift(model); shift = Surf_LightmapShift(model);
if ((ent->drawflags & MLS_MASKIN) == MLS_ABSLIGHT)
//update lightmaps. {
for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) //update lightmaps.
Surf_RenderDynamicLightmaps (s, shift); for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++)
Surf_RenderAmbientLightmaps (s, shift, ent->abslight);
}
else
{
//update lightmaps.
for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++)
Surf_RenderDynamicLightmaps (s, shift);
}
} }
memset(&batch, 0, sizeof(batch)); memset(&batch, 0, sizeof(batch));
@ -2699,10 +2712,17 @@ void BE_BaseEntTextures(void)
switch(currententity->model->type) switch(currententity->model->type)
{ {
case mod_brush: case mod_brush:
if (r_drawentities.ival == 2)
continue;
bef = BEF_PUSHDEPTH; bef = BEF_PUSHDEPTH;
if (currententity->flags & Q2RF_ADDITIVE) if (currententity->flags & Q2RF_ADDITIVE)
bef |= BEF_FORCEADDITIVE; bef |= BEF_FORCEADDITIVE;
else if (currententity->shaderRGBAf[3] < 1) else if (currententity->drawflags & DRF_TRANSLUCENT && r_wateralpha.value != 1)
{
bef |= BEF_FORCETRANSPARENT;
currententity->shaderRGBAf[3] = r_wateralpha.value;
}
else if (currententity->shaderRGBAf[3] < 1 && cls.protocol != CP_QUAKE3)
bef |= BEF_FORCETRANSPARENT; bef |= BEF_FORCETRANSPARENT;
if (currententity->flags & RF_NODEPTHTEST) if (currententity->flags & RF_NODEPTHTEST)
bef |= BEF_FORCENODEPTH; bef |= BEF_FORCENODEPTH;
@ -2710,6 +2730,8 @@ void BE_BaseEntTextures(void)
BaseBrushTextures(currententity); BaseBrushTextures(currententity);
break; break;
case mod_alias: case mod_alias:
if (r_drawentities.ival == 3)
continue;
R_DrawGAliasModel (currententity, shaderstate.mode); R_DrawGAliasModel (currententity, shaderstate.mode);
break; break;
} }
@ -2752,37 +2774,6 @@ static void BE_SubmitBatch(batch_t *batch)
} }
else else
{ {
if (lightmap[lm]->modified)
{
glRect_t *theRect;
lightmap[lm]->modified = false;
theRect = &lightmap[lm]->rectchange;
GL_Bind(lightmap_textures[lm]);
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, ((lightmap_bytes==3)?GL_RGB:GL_LUMINANCE), GL_UNSIGNED_BYTE,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*lightmap_bytes);
theRect->l = LMBLOCK_WIDTH;
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
checkerror();
if (lightmap[lm]->deluxmodified)
{
lightmap[lm]->deluxmodified = false;
theRect = &lightmap[lm]->deluxrectchange;
GL_Bind(deluxmap_textures[lm]);
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, GL_RGB, GL_UNSIGNED_BYTE,
lightmap[lm]->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3);
theRect->l = LMBLOCK_WIDTH;
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
checkerror();
}
}
shaderstate.curlightmap = lightmap_textures[lm]; shaderstate.curlightmap = lightmap_textures[lm];
shaderstate.curdeluxmap = deluxmap_textures[lm]; shaderstate.curdeluxmap = deluxmap_textures[lm];
} }
@ -2888,12 +2879,70 @@ void BE_SubmitMeshes (void)
currententity = &r_worldentity; currententity = &r_worldentity;
} }
static void BE_UpdateLightmaps(void)
{
int lm;
for (lm = 0; lm < numlightmaps; lm++)
{
if (!lightmap[lm])
continue;
if (lightmap[lm]->modified)
{
extern cvar_t temp1;
glRect_t *theRect;
lightmap[lm]->modified = false;
theRect = &lightmap[lm]->rectchange;
GL_Bind(lightmap_textures[lm]);
switch (lightmap_bytes)
{
case 4:
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, (lightmap_bgra?GL_BGRA_EXT:GL_RGBA), GL_UNSIGNED_INT_8_8_8_8_REV,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*4);
break;
case 3:
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*3);
break;
case 1:
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, GL_LUMINANCE, GL_UNSIGNED_BYTE,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH);
break;
}
theRect->l = LMBLOCK_WIDTH;
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
checkerror();
if (lightmap[lm]->deluxmodified)
{
lightmap[lm]->deluxmodified = false;
theRect = &lightmap[lm]->deluxrectchange;
GL_Bind(deluxmap_textures[lm]);
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, GL_RGB, GL_UNSIGNED_BYTE,
lightmap[lm]->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3);
theRect->l = LMBLOCK_WIDTH;
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
checkerror();
}
}
}
}
void BE_DrawWorld (qbyte *vis) void BE_DrawWorld (qbyte *vis)
{ {
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps; extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
RSpeedLocals(); RSpeedLocals();
GL_DoSwap(); GL_DoSwap();
BE_UpdateLightmaps();
//make sure the world draws correctly //make sure the world draws correctly
r_worldentity.shaderRGBAf[0] = 1; r_worldentity.shaderRGBAf[0] = 1;
r_worldentity.shaderRGBAf[1] = 1; r_worldentity.shaderRGBAf[1] = 1;

View file

@ -45,9 +45,9 @@ cvar_t r_bloom_fast_sample = CVARF("r_bloom_fast_sample", "0", CVAR_RENDERERLAT
typedef struct { typedef struct {
//texture numbers //texture numbers
texid_t tx_screen; texid_t tx_screen; /*a copy of the screen*/
texid_t tx_effect; texid_t tx_effect; /*blured copy of bright pixels*/
texid_t tx_backup; texid_t tx_backup; /*a copy of the screen to replace the pixels that we'll clobber. FIXME: use a FBO instead*/
texid_t tx_downsample; texid_t tx_downsample;
//the viewport dimensions //the viewport dimensions
@ -506,8 +506,8 @@ void R_BloomBlend (void)
bs.scr_h < bs.size_sample) bs.scr_h < bs.size_sample)
return; return;
#pragma message("backend fixme") PPL_RevertToKnownState();
Con_Printf("bloom is not updated for the backend\n"); #pragma message("Note: Bloom doesn't use the backend.")
//set up full screen workspace //set up full screen workspace
qglViewport(0, 0, vid.pixelwidth, vid.pixelheight); qglViewport(0, 0, vid.pixelwidth, vid.pixelheight);
@ -578,6 +578,8 @@ void R_BloomBlend (void)
if (qglGetError()) if (qglGetError())
Con_Printf("GL Error whilst rendering bloom\n"); Con_Printf("GL Error whilst rendering bloom\n");
PPL_RevertToKnownState();
} }
#endif #endif

View file

@ -108,6 +108,13 @@ texid_t GL_LoadTextureFmt (char *name, int width, int height, enum uploadfmt fmt
case TF_SOLID8: case TF_SOLID8:
return GL_LoadTexture(name, width, height, data, flags, 0); return GL_LoadTexture(name, width, height, data, flags, 0);
case TF_H2_T7G1:
return GL_LoadTexture(name, width, height, data, flags, 2);
case TF_H2_TRANS8_0:
return GL_LoadTexture(name, width, height, data, flags, 3);
case TF_H2_T4A4:
return GL_LoadTexture(name, width, height, data, flags, 4);
case TF_HEIGHT8PAL: case TF_HEIGHT8PAL:
case TF_HEIGHT8: case TF_HEIGHT8:
return GL_LoadTexture8Bump(name, width, height, data, flags, r_shadow_bumpscale_basetexture.value); return GL_LoadTexture8Bump(name, width, height, data, flags, r_shadow_bumpscale_basetexture.value);
@ -161,8 +168,6 @@ mpic_t *conback;
hashtable_t gltexturetable; hashtable_t gltexturetable;
bucket_t *gltexturetablebuckets[256]; bucket_t *gltexturetablebuckets[256];
int gl_lightmap_format = 4;
int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
int gl_filter_max = GL_LINEAR; int gl_filter_max = GL_LINEAR;
int gl_filter_max_2d = GL_LINEAR; int gl_filter_max_2d = GL_LINEAR;
@ -739,107 +744,12 @@ void GLDraw_FadeScreen (void)
extern cvar_t gl_menutint_shader; extern cvar_t gl_menutint_shader;
extern texid_t scenepp_texture; extern texid_t scenepp_texture;
extern int scenepp_mt_program, scenepp_mt_parm_colorf, scenepp_mt_parm_inverti; extern int scenepp_mt_program, scenepp_mt_parm_colorf, scenepp_mt_parm_inverti;
extern shader_t *scenepp_mt_shader;
if (!faderender) if (!faderender)
return; return;
#pragma message("Warning: This doesn't use the backend")
if (scenepp_mt_program && gl_menutint_shader.ival)
{
float vwidth = 1, vheight = 1;
float vs, vt;
// get the powers of 2 for the size of the texture that will hold the scene R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_mt_shader);
while (vwidth < vid.pixelwidth)
vwidth *= 2;
while (vheight < vid.pixelheight)
vheight *= 2;
// get the maxtexcoords while we're at it (cache this or just use largest?)
vs = vid.pixelwidth / vwidth;
vt = vid.pixelheight / vheight;
// 2d mode, but upside down to quake's normal 2d drawing
// this makes grabbing the sreen a lot easier
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
qglMatrixMode(GL_PROJECTION);
// Push the matrices to go into 2d mode, that matches opengl's mode
qglPushMatrix();
qglLoadIdentity ();
// TODO: use actual window width and height
qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999);
qglMatrixMode(GL_MODELVIEW);
qglPushMatrix();
qglLoadIdentity ();
GL_Bind(scenepp_texture);
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (qglGetError())
Con_Printf(CON_ERROR "GL Error after qglCopyTexImage2D\n");
GLSlang_UseProgram(scenepp_mt_program);
qglUniform3fvARB(scenepp_mt_parm_colorf, 1, fadecolor);
if (faderender == GL_ONE_MINUS_DST_COLOR)
qglUniform1iARB(scenepp_mt_parm_inverti, 1);
else
qglUniform1iARB(scenepp_mt_parm_inverti, 0);
if (qglGetError())
Con_Printf(CON_ERROR "GL Error after GLSlang_UseProgram\n");
qglEnable(GL_TEXTURE_2D);
GL_Bind(scenepp_texture);
qglBegin(GL_QUADS);
qglTexCoord2f (0, 0);
qglVertex2f(0, 0);
qglTexCoord2f (vs, 0);
qglVertex2f(vid.pixelwidth, 0);
qglTexCoord2f (vs, vt);
qglVertex2f(vid.pixelwidth, vid.pixelheight);
qglTexCoord2f (0, vt);
qglVertex2f(0, vid.pixelheight);
qglEnd();
GLSlang_UseProgram(0);
// After all the post processing, pop the matrices
qglMatrixMode(GL_PROJECTION);
qglPopMatrix();
qglMatrixMode(GL_MODELVIEW);
qglPopMatrix();
if (qglGetError())
Con_Printf(CON_ERROR "GL Error after drawing with shaderobjects\n");
}
else
{
// shaderless way
qglEnable (GL_BLEND);
qglBlendFunc(faderender, GL_ZERO);
qglDisable(GL_ALPHA_TEST);
qglDisable (GL_TEXTURE_2D);
qglColor4f (fadecolor[0], fadecolor[1], fadecolor[2], 1);
qglBegin (GL_QUADS);
qglVertex2f (0,0);
qglVertex2f (vid.width, 0);
qglVertex2f (vid.width, vid.height);
qglVertex2f (0, vid.height);
qglEnd ();
qglColor4f (1,1,1,1);
qglEnable (GL_TEXTURE_2D);
qglDisable (GL_BLEND);
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglEnable(GL_ALPHA_TEST);
}
Sbar_Changed(); Sbar_Changed();
} }

View file

@ -802,6 +802,63 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
f = Z_Malloc(sizeof(*f)); f = Z_Malloc(sizeof(*f));
f->charheight = height; f->charheight = height;
if (!strcmp(fontfilename, "gfx/tinyfont"))
{
unsigned int *img;
int x, y;
unsigned char *w = W_SafeGetLumpName(fontfilename+4);
if (!w)
{
Z_Free(f);
return NULL;
}
img = Z_Malloc(PLANEWIDTH*PLANEWIDTH*4);
for (y = 0; y < 32; y++)
for (x = 0; x < 128; x++)
img[x + y*PLANEWIDTH] = w[x + y*128]?d_8to24rgbtable[w[x + y*128]]:0;
f->singletexture = R_LoadTexture(fontfilename,PLANEWIDTH,PLANEWIDTH,TF_RGBA32,img,IF_NOPICMIP|IF_NOMIPMAP);
Z_Free(img);
for (i = 0x00; i <= 0xff; i++)
{
f->chars[i].advance = height;
f->chars[i].left = 0;
f->chars[i].top = 0;
f->chars[i].nextchar = 0; //these chars are not linked in
f->chars[i].pad = 0;
f->chars[i].texplane = BITMAPPLANE; /*if its a 'raster' font, don't use the default chars, always use the raster images*/
if (i >= 'a' && i <= 'z')
{
f->chars[i].bmx = ((i - 64)&15)*8;
f->chars[i].bmy = ((i - 64)/16)*8;
f->chars[i].bmh = 8;
f->chars[i].bmw = 8;
}
else if (i >= 32 && i < 96)
{
f->chars[i].bmx = ((i - 32)&15)*8;
f->chars[i].bmy = ((i - 32)/16)*8;
f->chars[i].bmh = 8;
f->chars[i].bmw = 8;
}
else
{
f->chars[i].bmh = 0;
f->chars[i].bmw = 0;
f->chars[i].bmx = 0;
f->chars[i].bmy = 0;
}
}
for (i = 0xe000; i <= 0xe0ff; i++)
{
f->chars[i] = f->chars[i&0xff];
}
return f;
}
if (!Font_LoadFreeTypeFont(f, height, fontfilename)) if (!Font_LoadFreeTypeFont(f, height, fontfilename))
{ {
if (*fontfilename) if (*fontfilename)

View file

@ -571,6 +571,7 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
switch (LittleLong(*(unsigned *)buf)) switch (LittleLong(*(unsigned *)buf))
{ {
//The binary 3d mesh model formats //The binary 3d mesh model formats
case RAPOLYHEADER:
case IDPOLYHEADER: case IDPOLYHEADER:
if (!Mod_LoadQ1Model(mod, buf)) if (!Mod_LoadQ1Model(mod, buf))
continue; continue;
@ -931,8 +932,11 @@ void Mod_FinishTexture(texture_t *tx, texnums_t tn)
extern cvar_t gl_shadeq1_name; extern cvar_t gl_shadeq1_name;
char altname[MAX_QPATH]; char altname[MAX_QPATH];
char *star; char *star;
/*skies? just replace with the override sky*/
if (!strncmp(tx->name, "sky", 3) && *cl.skyname)
tx->shader = R_RegisterCustom (va("skybox_%s", cl.skyname), Shader_DefaultSkybox, NULL); //just load the regular name.
//find the * //find the *
if (!*gl_shadeq1_name.string || !strcmp(gl_shadeq1_name.string, "*")) else if (!*gl_shadeq1_name.string || !strcmp(gl_shadeq1_name.string, "*"))
tx->shader = R_RegisterCustom (tx->name, Shader_DefaultBSPQ1, NULL); //just load the regular name. tx->shader = R_RegisterCustom (tx->name, Shader_DefaultBSPQ1, NULL); //just load the regular name.
else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(tx->name)+1>=sizeof(altname))) //it's got to fit. else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(tx->name)+1>=sizeof(altname))) //it's got to fit.
tx->shader = R_RegisterCustom (gl_shadeq1_name.string, Shader_DefaultBSPQ1, NULL); tx->shader = R_RegisterCustom (gl_shadeq1_name.string, Shader_DefaultBSPQ1, NULL);
@ -2889,6 +2893,19 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
crouchhullfile = NULL; crouchhullfile = NULL;
#ifndef CLIENTONLY
if (sv.state) //if the server is running
{
if (!strcmp(loadmodel->name, va("maps/%s.bsp", sv.name)))
Mod_ParseInfoFromEntityLump(loadmodel, mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
}
else
#endif
{
if (!cl.model_precache[1]) //not copied across yet
Mod_ParseInfoFromEntityLump(loadmodel, mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
}
// load into heap // load into heap
if (!isDedicated || ode) if (!isDedicated || ode)
{ {
@ -2939,19 +2956,6 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
return false; return false;
} }
#ifndef CLIENTONLY
if (sv.state) //if the server is running
{
if (!strcmp(loadmodel->name, va("maps/%s.bsp", sv.name)))
Mod_ParseInfoFromEntityLump(mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
}
else
#endif
{
if (!cl.model_precache[1]) //not copied across yet
Mod_ParseInfoFromEntityLump(mod_base + header->lumps[LUMP_ENTITIES].fileofs, loadname);
}
Q1BSP_SetModelFuncs(mod); Q1BSP_SetModelFuncs(mod);
mod->funcs.LightPointValues = GLQ1BSP_LightPointValues; mod->funcs.LightPointValues = GLQ1BSP_LightPointValues;
mod->funcs.StainNode = Q1BSP_StainNode; mod->funcs.StainNode = Q1BSP_StainNode;
@ -2983,7 +2987,7 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
mod->hulls[j].firstclipnode = bm->headnode[j]; mod->hulls[j].firstclipnode = bm->headnode[j];
mod->hulls[j].lastclipnode = mod->numclipnodes-1; mod->hulls[j].lastclipnode = mod->numclipnodes-1;
mod->hulls[j].available = bm->hullavailable[j]; mod->hulls[j].available &= bm->hullavailable[j];
if (mod->hulls[j].firstclipnode > mod->hulls[j].lastclipnode) if (mod->hulls[j].firstclipnode > mod->hulls[j].lastclipnode)
mod->hulls[j].available = false; mod->hulls[j].available = false;
@ -3184,14 +3188,11 @@ void * RMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum,
if (!TEXVALID(texnum)) if (!TEXVALID(texnum))
texnum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), IF_NOGAMMA); texnum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), IF_NOGAMMA);
} }
#pragma message("no hl sprites")
#ifdef R_LoadTexture8Pal32
else if (version == SPRITEHL_VERSION) else if (version == SPRITEHL_VERSION)
{ {
if (!TEXVALID(texnum)) if (!TEXVALID(texnum))
texnum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, IF_NOGAMMA); texnum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, IF_NOGAMMA);
} }
#endif
else else
{ {
if (!TEXVALID(texnum)) if (!TEXVALID(texnum))

View file

@ -47,7 +47,7 @@ void R_AnimateLight (void)
f = 0; f = 0;
i = (int)f; i = (int)f;
if (r_lightstylesmooth.value) if (r_lightstylesmooth.ival)
f -= i; //this can require updates at 1000 times a second.. Depends on your framerate of course f -= i; //this can require updates at 1000 times a second.. Depends on your framerate of course
else else
f = 0; //only update them 10 times a second f = 0; //only update them 10 times a second
@ -741,13 +741,6 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
float scale; float scale;
int maps; int maps;
if (!cl.worldmodel->lightdata)
{
l[0]=255;l[1]=255;l[2]=255;
l[3]=0;l[4]=1;l[5]=1;
return l;
}
if (cl.worldmodel->fromgame == fg_quake2) if (cl.worldmodel->fromgame == fg_quake2)
{ {
if (node->contents != -1) if (node->contents != -1)
@ -939,6 +932,23 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse,
vec3_t end; vec3_t end;
float *r; float *r;
if (!cl.worldmodel->lightdata || r_fullbright.ival)
{
res_diffuse[0] = 0;
res_diffuse[1] = 0;
res_diffuse[2] = 0;
res_ambient[0] = 255;
res_ambient[1] = 255;
res_ambient[2] = 255;
res_dir[0] = 1;
res_dir[1] = 1;
res_dir[2] = 0.1;
VectorNormalize(res_dir);
return;
}
end[0] = point[0]; end[0] = point[0];
end[1] = point[1]; end[1] = point[1];
end[2] = point[2] - 2048; end[2] = point[2] - 2048;
@ -964,17 +974,16 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse,
res_diffuse[1] = r[1]; res_diffuse[1] = r[1];
res_diffuse[2] = r[2]; res_diffuse[2] = r[2];
res_ambient[0] = r[0]; res_ambient[0] = 0;
res_ambient[1] = r[1]; res_ambient[1] = 0;
res_ambient[2] = r[2]; res_ambient[2] = 0;
res_dir[0] = r[3]; res_dir[0] = r[3];
res_dir[1] = r[4]; res_dir[1] = r[4];
res_dir[2] = -r[5]; res_dir[2] = -r[5];
VectorNormalize(res_dir);
if (!res_dir[0] && !res_dir[1] && !res_dir[2]) if (!res_dir[0] && !res_dir[1] && !res_dir[2])
res_dir[1] = res_dir[2] = 1; res_dir[1] = res_dir[2] = 1;
VectorNormalize(res_dir);
} }
} }

View file

@ -108,23 +108,16 @@ extern cvar_t gl_blendsprites;
cvar_t r_xflip = SCVAR("leftisright", "0"); cvar_t r_xflip = SCVAR("leftisright", "0");
#endif #endif
extern cvar_t gl_ztrick;
extern cvar_t scr_fov; extern cvar_t scr_fov;
shader_t *scenepp_waterwarp; shader_t *scenepp_waterwarp;
shader_t *scenepp_mt_shader;
// post processing stuff // post processing stuff
texid_t sceneblur_texture; texid_t sceneblur_texture;
texid_t scenepp_texture;
texid_t scenepp_texture_warp; texid_t scenepp_texture_warp;
texid_t scenepp_texture_edge; texid_t scenepp_texture_edge;
int scenepp_ww_program;
int scenepp_ww_parm_texture0i;
int scenepp_ww_parm_texture1i;
int scenepp_ww_parm_texture2i;
int scenepp_ww_parm_ampscalef;
int scenepp_mt_program; int scenepp_mt_program;
int scenepp_mt_parm_texture0i; int scenepp_mt_parm_texture0i;
int scenepp_mt_parm_colorf; int scenepp_mt_parm_colorf;
@ -141,7 +134,6 @@ int scenepp_panorama_parm_fov;
// processing shaders // processing shaders
void GL_InitSceneProcessingShaders_WaterWarp (void) void GL_InitSceneProcessingShaders_WaterWarp (void)
{ {
#if 1
/* /*
inputs: inputs:
texcoords: edge points texcoords: edge points
@ -221,70 +213,6 @@ void GL_InitSceneProcessingShaders_WaterWarp (void)
scenepp_waterwarp->defaulttextures.upperoverlay = scenepp_texture_warp; scenepp_waterwarp->defaulttextures.upperoverlay = scenepp_texture_warp;
scenepp_waterwarp->defaulttextures.loweroverlay = scenepp_texture_edge; scenepp_waterwarp->defaulttextures.loweroverlay = scenepp_texture_edge;
} }
#else
char *genericvert = "\
varying vec2 v_texCoord0;\
varying vec2 v_texCoord1;\
varying vec2 v_texCoord2;\
void main (void)\
{\
vec4 v = vec4( gl_Vertex.x, gl_Vertex.y, gl_Vertex.z, 1.0 );\
gl_Position = gl_ModelViewProjectionMatrix * v;\
v_texCoord0 = gl_MultiTexCoord0.xy;\
v_texCoord1 = gl_MultiTexCoord1.xy;\
v_texCoord2 = gl_MultiTexCoord2.xy;\
}\
";
char *wwfrag = "\
varying vec2 v_texCoord0;\
varying vec2 v_texCoord1;\
varying vec2 v_texCoord2;\
uniform sampler2D theTexture0;\
uniform sampler2D theTexture1;\
uniform sampler2D theTexture2;\
uniform float ampscale;\
void main (void)\
{\
float amptemp;\
vec3 edge;\
edge = texture2D( theTexture2, v_texCoord2 ).rgb;\
amptemp = ampscale * edge.x;\
vec3 offset;\
offset = texture2D( theTexture1, v_texCoord1 ).rgb;\
offset.x = (offset.x - 0.5) * 2.0;\
offset.y = (offset.y - 0.5) * 2.0;\
vec2 temp;\
temp.x = v_texCoord0.x + offset.x * amptemp;\
temp.y = v_texCoord0.y + offset.y * amptemp;\
gl_FragColor = texture2D( theTexture0, temp );\
}\
";
if (qglGetError())
Con_Printf("GL Error before initing shader object\n");
scenepp_ww_program = GLSlang_CreateProgram(NULL, genericvert, wwfrag);
if (!scenepp_ww_program)
return;
scenepp_ww_parm_texture0i = GLSlang_GetUniformLocation(scenepp_ww_program, "theTexture0");
scenepp_ww_parm_texture1i = GLSlang_GetUniformLocation(scenepp_ww_program, "theTexture1");
scenepp_ww_parm_texture2i = GLSlang_GetUniformLocation(scenepp_ww_program, "theTexture2");
scenepp_ww_parm_ampscalef = GLSlang_GetUniformLocation(scenepp_ww_program, "ampscale");
GLSlang_UseProgram(scenepp_ww_program);
GLSlang_SetUniform1i(scenepp_ww_parm_texture0i, 0);
GLSlang_SetUniform1i(scenepp_ww_parm_texture1i, 1);
GLSlang_SetUniform1i(scenepp_ww_parm_texture2i, 2);
GLSlang_UseProgram(0);
if (qglGetError())
Con_Printf(CON_ERROR "GL Error initing shader object\n");
#endif
} }
void GL_InitFisheyeFov(void) void GL_InitFisheyeFov(void)
@ -350,49 +278,66 @@ void GL_InitFisheyeFov(void)
void GL_InitSceneProcessingShaders_MenuTint(void) void GL_InitSceneProcessingShaders_MenuTint(void)
{ {
char *vshader = "\ extern cvar_t gl_menutint_shader;
varying vec2 texcoord;\ if (gl_config.arb_shader_objects && gl_menutint_shader.ival)
void main(void)\ {
{\ scenepp_mt_shader = R_RegisterShader("menutint",
texcoord = gl_MultiTexCoord0.xy;\ "{\n"
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\ "glslprogram\n"
}"; "{\n"
char *fshader = "\ "#ifdef VERTEX_SHADER\n"
varying vec2 texcoord;\ "\
uniform vec3 colorparam;\ varying vec2 texcoord;\
uniform sampler2D source;\ uniform vec3 rendertexturescale;\
uniform int invert;\ void main(void)\
const vec3 lumfactors = vec3(0.299, 0.587, 0.114);\ {\
const vec3 invertvec = vec3(1.0, 1.0, 1.0);\ texcoord.x = gl_MultiTexCoord0.x*rendertexturescale.x;\
void main(void)\ texcoord.y = (1-gl_MultiTexCoord0.y)*rendertexturescale.y;\
{\ gl_Position = ftransform();\
vec3 texcolor = texture2D(source, texcoord).rgb;\ }\
float luminance = dot(lumfactors, texcolor);\ \n"
texcolor = vec3(luminance, luminance, luminance);\ "#endif\n"
texcolor *= colorparam;\ "#ifdef FRAGMENT_SHADER\n"
texcolor = invert > 0 ? (invertvec - texcolor) : texcolor;\ "\
gl_FragColor = vec4(texcolor, 1.0);\ varying vec2 texcoord;\
}"; uniform vec3 colorparam;\
uniform sampler2D source;\
uniform int invert;\
const vec3 lumfactors = vec3(0.299, 0.587, 0.114);\
const vec3 invertvec = vec3(1.0, 1.0, 1.0);\
void main(void)\
{\
vec3 texcolor = texture2D(source, texcoord).rgb;\
float luminance = dot(lumfactors, texcolor);\
texcolor = vec3(luminance, luminance, luminance);\
texcolor *= colorparam;\
texcolor = invert > 0 ? (invertvec - texcolor) : texcolor;\
gl_FragColor = vec4(texcolor, 1.0);\
}\n"
"#endif\n"
"}\n"
"param cvari r_menutint_inverse invert\n"
"param cvar3f r_menutint colorparam\n"
"param texture 0 source\n"
if (qglGetError()) "{\n"
Con_Printf("GL Error before initing shader object\n"); "map $currentrender\n"
"}\n"
scenepp_mt_program = GLSlang_CreateProgram(NULL, vshader, fshader); "param rendertexturescale rendertexturescale\n"
"}");
if (!scenepp_mt_program) }
return; if (!scenepp_mt_shader)
{
scenepp_mt_parm_texture0i = GLSlang_GetUniformLocation(scenepp_mt_program, "source"); scenepp_mt_shader = R_RegisterShader("menutint",
scenepp_mt_parm_colorf = GLSlang_GetUniformLocation(scenepp_mt_program, "colorparam"); "{\n"
scenepp_mt_parm_inverti = GLSlang_GetUniformLocation(scenepp_mt_program, "invert"); "{\n"
"map $whitetexture\n"
GLSlang_UseProgram(scenepp_mt_program); "blendfunc gl_dst_color gl_zero\n"
GLSlang_SetUniform1i(scenepp_mt_parm_texture0i, 0); "rgbgen const $r_menutint\n"
"}\n"
GLSlang_UseProgram(0); "}\n"
);
if (qglGetError()) }
Con_Printf(CON_ERROR "GL Error initing shader object\n");
} }
void GL_InitSceneProcessingShaders (void) void GL_InitSceneProcessingShaders (void)
@ -421,7 +366,6 @@ void GL_SetupSceneProcessingTextures (void)
if (!gl_config.arb_shader_objects) if (!gl_config.arb_shader_objects)
return; return;
scenepp_texture = GL_AllocNewTexture();
scenepp_texture_warp = GL_AllocNewTexture(); scenepp_texture_warp = GL_AllocNewTexture();
scenepp_texture_edge = GL_AllocNewTexture(); scenepp_texture_edge = GL_AllocNewTexture();
@ -664,7 +608,7 @@ void R_DrawSpriteModel (entity_t *e)
unsigned int fl; unsigned int fl;
unsigned int sprtype; unsigned int sprtype;
static vec2_t texcoords[4]={{0, 0},{0,1},{1,1},{1,0}}; static vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}};
static index_t indexes[6] = {0, 1, 2, 0, 2, 3}; static index_t indexes[6] = {0, 1, 2, 0, 2, 3};
vecV_t vertcoords[4]; vecV_t vertcoords[4];
avec4_t colours[4]; avec4_t colours[4];
@ -1227,6 +1171,7 @@ r_refdef must be set before the first call
*/ */
void R_RenderScene (void) void R_RenderScene (void)
{ {
int tmpvisents = cl_numvisedicts; /*world rendering is allowed to add additional ents, but we don't want to keep them for recursive views*/
if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap)) if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap))
r_refdef.flags |= Q2RDF_NOWORLDMODEL; r_refdef.flags |= Q2RDF_NOWORLDMODEL;
@ -1260,6 +1205,8 @@ void R_RenderScene (void)
P_DrawParticles (); P_DrawParticles ();
} }
RQ_RenderBatchClear(); RQ_RenderBatchClear();
cl_numvisedicts = tmpvisents;
} }
/*generates a new modelview matrix, as well as vpn vectors*/ /*generates a new modelview matrix, as well as vpn vectors*/
static void R_MirrorMatrix(plane_t *plane) static void R_MirrorMatrix(plane_t *plane)
@ -1514,32 +1461,6 @@ void R_Clear (void)
{ {
/*tbh, this entire function should be in the backend*/ /*tbh, this entire function should be in the backend*/
GL_ForceDepthWritable(); GL_ForceDepthWritable();
#ifdef SIDEVIEWS
if (gl_ztrick.value && !gl_ztrickdisabled)
#else
if (gl_ztrick.value)
#endif
{
static int trickframe;
if (gl_clear.value && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
qglClear (GL_COLOR_BUFFER_BIT);
trickframe++;
if (trickframe & 1)
{
gldepthmin = 0;
gldepthmax = 0.49999;
gldepthfunc=GL_LEQUAL;
}
else
{
gldepthmin = 1;
gldepthmax = 0.5;
gldepthfunc=GL_GEQUAL;
}
}
else
{ {
if (gl_clear.value && !r_secondaryview && !(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (gl_clear.value && !r_secondaryview && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -1680,148 +1601,6 @@ static void R_RenderMotionBlur(void)
PPL_RevertToKnownState(); PPL_RevertToKnownState();
} }
static void R_RenderWaterWarp(void)
{
float vwidth = 1, vheight = 1;
float vs, vt;
PPL_RevertToKnownState();
#pragma message("backend fixme")
Con_Printf("waterwarp is not updated for the backend\n");
// get the powers of 2 for the size of the texture that will hold the scene
if (gl_config.arb_texture_non_power_of_two)
{
vwidth = vid.pixelwidth;
vheight = vid.pixelheight;
}
else
{
while (vwidth < vid.pixelwidth)
{
vwidth *= 2;
}
while (vheight < vid.pixelheight)
{
vheight *= 2;
}
}
// get the maxtexcoords while we're at it
vs = vid.pixelwidth / vwidth;
vt = vid.pixelheight / vheight;
// 2d mode, but upside down to quake's normal 2d drawing
// this makes grabbing the sreen a lot easier
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
qglMatrixMode(GL_PROJECTION);
// Push the matrices to go into 2d mode, that matches opengl's mode
qglPushMatrix();
qglLoadIdentity ();
// TODO: use actual window width and height
qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999);
qglMatrixMode(GL_MODELVIEW);
qglPushMatrix();
qglLoadIdentity ();
qglDisable (GL_DEPTH_TEST);
GL_CullFace(0);
qglDisable (GL_BLEND);
qglEnable (GL_ALPHA_TEST);
// copy the scene to texture
GL_Bind(scenepp_texture);
qglEnable(GL_TEXTURE_2D);
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (qglGetError())
Con_Printf(CON_ERROR "GL Error after qglCopyTexImage2D\n");
// Here we apply the shaders - currently just waterwarp
GLSlang_UseProgram(scenepp_ww_program);
//keep the amp proportional to the size of the scene in texture coords
// WARNING - waterwarp can change the amplitude, but if it's too big it'll exceed
// the size determined by the edge texture, after which black bits will be shown.
// Suggest clamping to a suitable range.
if (r_waterwarp.value<0)
{
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*(-r_waterwarp.value));
}
else
{
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*r_waterwarp.value);
}
if (qglGetError())
Con_Printf("GL Error after GLSlang_UseProgram\n");
{
float xmin, xmax, ymin, ymax;
xmin = cl.time * 0.25;
ymin = cl.time * 0.25;
xmax = xmin + 1;
ymax = ymin + 1/vt*vs;
GL_SelectTexture(1);
qglEnable(GL_TEXTURE_2D);
GL_Bind (scenepp_texture_warp);
GL_SelectTexture(2);
qglEnable(GL_TEXTURE_2D);
GL_Bind(scenepp_texture_edge);
qglBegin(GL_QUADS);
qglMTexCoord2fSGIS (mtexid0, 0, 0);
qglMTexCoord2fSGIS (mtexid1, xmin, ymin);
qglMTexCoord2fSGIS (mtexid1+1, 0, 0);
qglVertex2f(0, 0);
qglMTexCoord2fSGIS (mtexid0, vs, 0);
qglMTexCoord2fSGIS (mtexid1, xmax, ymin);
qglMTexCoord2fSGIS (mtexid1+1, 1, 0);
qglVertex2f(vid.pixelwidth, 0);
qglMTexCoord2fSGIS (mtexid0, vs, vt);
qglMTexCoord2fSGIS (mtexid1, xmax, ymax);
qglMTexCoord2fSGIS (mtexid1+1, 1, 1);
qglVertex2f(vid.pixelwidth, vid.pixelheight);
qglMTexCoord2fSGIS (mtexid0, 0, vt);
qglMTexCoord2fSGIS (mtexid1, xmin, ymax);
qglMTexCoord2fSGIS (mtexid1+1, 0, 1);
qglVertex2f(0, vid.pixelheight);
qglEnd();
qglDisable(GL_TEXTURE_2D);
GL_SelectTexture(1);
qglDisable(GL_TEXTURE_2D);
GL_SelectTexture(0);
}
// Disable shaders
GLSlang_UseProgram(0);
// After all the post processing, pop the matrices
qglMatrixMode(GL_PROJECTION);
qglPopMatrix();
qglMatrixMode(GL_MODELVIEW);
qglPopMatrix();
PPL_RevertToKnownState();
if (qglGetError())
Con_Printf("GL Error after drawing with shaderobjects\n");
}
#ifdef FISH #ifdef FISH
/*FIXME: we could use geometry shaders to draw to all 6 faces at once*/ /*FIXME: we could use geometry shaders to draw to all 6 faces at once*/
qboolean R_RenderScene_Fish(void) qboolean R_RenderScene_Fish(void)
@ -2128,8 +1907,6 @@ void GLR_RenderView (void)
GL_Set2D(); GL_Set2D();
if (scenepp_waterwarp) if (scenepp_waterwarp)
R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_waterwarp); R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_waterwarp);
else if (scenepp_ww_program)
R_RenderWaterWarp();
} }

View file

@ -969,6 +969,9 @@ void GLR_NewMap (void)
r_viewcluster = -1; r_viewcluster = -1;
r_oldviewcluster = 0; r_oldviewcluster = 0;
r_viewcluster2 = -1; r_viewcluster2 = -1;
Mod_ParseInfoFromEntityLump(cl.worldmodel, cl.worldmodel->entities, cl.worldmodel->name);
TRACE(("dbg: GLR_NewMap: clear particles\n")); TRACE(("dbg: GLR_NewMap: clear particles\n"));
P_ClearParticles (); P_ClearParticles ();
TRACE(("dbg: GLR_NewMap: wiping them stains (getting the cloth out)\n")); TRACE(("dbg: GLR_NewMap: wiping them stains (getting the cloth out)\n"));

View file

@ -298,10 +298,24 @@ void BE_UploadAllLightmaps(void)
GL_Bind(lightmap_textures[i]); GL_Bind(lightmap_textures[i]);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes switch (lightmap_bytes)
, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, 0, {
((lightmap_bytes==3)?GL_RGB:GL_LUMINANCE), GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); case 4:
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, (lightmap_bgra?GL_BGRA_EXT:GL_RGBA), GL_UNSIGNED_INT_8_8_8_8_REV,
lightmap[i]->lightmaps);
break;
case 3:
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
lightmap[i]->lightmaps);
break;
case 1:
qglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
lightmap[i]->lightmaps);
break;
}
if (gl_bump.ival) if (gl_bump.ival)
{ {
lightmap[i]->deluxmodified = false; lightmap[i]->deluxmodified = false;

View file

@ -99,6 +99,9 @@ void GLVID_Console_Resize(void)
vid.recalc_refdef = true; vid.recalc_refdef = true;
if (font_tiny)
Font_Free(font_tiny);
font_tiny = NULL;
if (font_conchar) if (font_conchar)
Font_Free(font_conchar); Font_Free(font_conchar);
font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, gl_font.string); font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, gl_font.string);

View file

@ -206,6 +206,55 @@ static void Shader_ReadShader(shader_t *s, char *shadersource);
//=========================================================================== //===========================================================================
static qboolean Shader_EvaluateCondition(char **ptr)
{
char *token;
cvar_t *cv;
qboolean conditiontrue = true;
token = COM_ParseExt ( ptr, false );
if (*token == '!')
{
conditiontrue = false;
token++;
}
if (*token == '$')
{
extern cvar_t gl_bump;
token++;
if (!Q_stricmp(token, "lightmap"))
conditiontrue = conditiontrue == !r_fullbright.value;
else if (!Q_stricmp(token, "deluxmap") )
conditiontrue = conditiontrue == !!gl_bump.value;
//normalmaps are generated if they're not already known.
else if (!Q_stricmp(token, "normalmap") )
conditiontrue = conditiontrue == !!gl_bump.value;
#pragma message("shader fixme")
else if (!Q_stricmp(token, "diffuse") )
conditiontrue = conditiontrue == true;
else if (!Q_stricmp(token, "specular") )
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "fullbright") )
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "topoverlay") )
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "loweroverlay") )
conditiontrue = conditiontrue == false;
else
conditiontrue = conditiontrue == false;
}
else
{
cv = Cvar_Get(token, "", 0, "Shader Conditions");
if (cv)
conditiontrue = conditiontrue == !!cv->value;
}
return conditiontrue;
}
static char *Shader_ParseString ( char **ptr ) static char *Shader_ParseString ( char **ptr )
{ {
char *token; char *token;
@ -269,6 +318,7 @@ static void Shader_ParseVector ( char **ptr, vec3_t v )
v[2] = 1; v[2] = 1;
return; return;
} }
var->flags |= CVAR_SHADERSYSTEM;
ptr = &scratch; ptr = &scratch;
scratch = var->string; scratch = var->string;
@ -568,9 +618,9 @@ static void Shader_SurfaceParm ( shader_t *shader, shaderpass_t *pass, char **pt
token = Shader_ParseString ( ptr ); token = Shader_ParseString ( ptr );
if ( !Q_stricmp( token, "nodraw" ) ) if ( !Q_stricmp( token, "nodraw" ) )
shader->flags = SHADER_NODRAW; shader->flags |= SHADER_NODRAW;
else if ( !Q_stricmp( token, "nodlight" ) ) else if ( !Q_stricmp( token, "nodlight" ) )
shader->flags = SHADER_NODLIGHT; shader->flags |= SHADER_NODLIGHT;
} }
static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr ) static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr )
@ -596,6 +646,8 @@ static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr )
shader->sort = SHADER_SORT_UNDERWATER; shader->sort = SHADER_SORT_UNDERWATER;
} else if( !Q_stricmp( token, "nearest" ) ) { } else if( !Q_stricmp( token, "nearest" ) ) {
shader->sort = SHADER_SORT_NEAREST; shader->sort = SHADER_SORT_NEAREST;
} else if( !Q_stricmp( token, "blend" ) ) {
shader->sort = SHADER_SORT_BLEND;
} else { } else {
shader->sort = atoi ( token ); shader->sort = atoi ( token );
clamp ( shader->sort, SHADER_SORT_NONE, SHADER_SORT_NEAREST ); clamp ( shader->sort, SHADER_SORT_NONE, SHADER_SORT_NEAREST );
@ -728,6 +780,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
cvar_t *cv; cvar_t *cv;
int specialint = 0; int specialint = 0;
float specialfloat = 0; float specialfloat = 0;
vec3_t specialvec = {0};
enum shaderprogparmtype_e parmtype = SP_BAD; enum shaderprogparmtype_e parmtype = SP_BAD;
char *token; char *token;
qboolean silent = false; qboolean silent = false;
@ -750,7 +803,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters"); cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv) if (cv)
{ //Cvar_Get returns null if the cvar is the name of a command { //Cvar_Get returns null if the cvar is the name of a command
specialint = atoi(cv->string); specialint = cv->ival;
specialfloat = cv->value; specialfloat = cv->value;
} }
parmtype = SP_CVARI; parmtype = SP_CVARI;
@ -761,11 +814,21 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters"); cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv) if (cv)
{ //Cvar_Get returns null if the cvar is the name of a command { //Cvar_Get returns null if the cvar is the name of a command
specialint = atoi(cv->string); specialint = cv->ival;
specialfloat = cv->value; specialfloat = cv->value;
} }
parmtype = SP_CVARF; parmtype = SP_CVARF;
} }
else if (!Q_stricmp(token, "cvar3f"))
{
token = Shader_ParseSensString(ptr);
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv)
{
SCR_StringToRGB(cv->string, specialvec, 1);
}
parmtype = SP_CVAR3F;
}
else if (!Q_stricmp(token, "time")) else if (!Q_stricmp(token, "time"))
parmtype = SP_TIME; parmtype = SP_TIME;
else if (!Q_stricmp(token, "eyepos")) else if (!Q_stricmp(token, "eyepos"))
@ -816,10 +879,13 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
break; break;
case SP_TEXTURE: case SP_TEXTURE:
case SP_CVARI: case SP_CVARI:
GLSlang_SetUniform1i(uniformloc, specialint); qglUniform1iARB(uniformloc, specialint);
break; break;
case SP_CVARF: case SP_CVARF:
GLSlang_SetUniform1f(uniformloc, specialfloat); qglUniform1fARB(uniformloc, specialfloat);
break;
case SP_CVAR3F:
qglUniform3fvARB(uniformloc, 1, specialvec);
break; break;
default: default:
shader->progparm[shader->numprogparams].type = parmtype; shader->progparm[shader->numprogparams].type = parmtype;
@ -1774,6 +1840,23 @@ void Shader_Readpass (shader_t *shader, char **ptr)
{ {
break; break;
} }
else if (!Q_stricmp(token, "if"))
{
qboolean conditionistrue = Shader_EvaluateCondition(ptr);
while (*ptr)
{
token = COM_ParseExt (ptr, true);
if ( !token[0] )
continue;
else if (token[0] == ']')
break;
else if (conditionistrue)
{
Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr);
}
}
}
else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) ) else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) )
{ {
break; break;
@ -1827,55 +1910,6 @@ void Shader_Readpass (shader_t *shader, char **ptr)
} }
} }
static qboolean Shader_EvaluateCondition(char **ptr)
{
char *token;
cvar_t *cv;
qboolean conditiontrue = true;
token = COM_ParseExt ( ptr, false );
if (*token == '!')
{
conditiontrue = false;
token++;
}
if (*token == '$')
{
extern cvar_t gl_bump;
token++;
if (!Q_stricmp(token, "lightmap"))
conditiontrue = conditiontrue == !r_fullbright.value;
else if (!Q_stricmp(token, "deluxmap") )
conditiontrue = conditiontrue == !!gl_bump.value;
//normalmaps are generated if they're not already known.
else if (!Q_stricmp(token, "normalmap") )
conditiontrue = conditiontrue == !!gl_bump.value;
#pragma message("shader fixme")
else if (!Q_stricmp(token, "diffuse") )
conditiontrue = conditiontrue == true;
else if (!Q_stricmp(token, "specular") )
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "fullbright") )
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "topoverlay") )
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "loweroverlay") )
conditiontrue = conditiontrue == false;
else
conditiontrue = conditiontrue == false;
}
else
{
cv = Cvar_Get(token, "", 0, "Shader Conditions");
if (cv)
conditiontrue = conditiontrue == !!cv->value;
}
return conditiontrue;
}
static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr) static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr)
{ {
shaderkey_t *key; shaderkey_t *key;
@ -2310,6 +2344,10 @@ done:;
} }
Shader_SetFeatures(s); Shader_SetFeatures(s);
#ifdef FORCEGLSL
BE_GenerateProgram(s);
#endif
} }
/* /*
void Shader_UpdateRegistration (void) void Shader_UpdateRegistration (void)
@ -2416,7 +2454,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
if (!builtin) if (!builtin)
builtin = ( builtin = (
"{\n" "{\n"
"if $deluxmap\n" "if gl_bump\n"
"[\n" "[\n"
"{\n" "{\n"
"map $normalmap\n" "map $normalmap\n"
@ -2431,19 +2469,19 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"tcgen base\n" "tcgen base\n"
"if $deluxmap\n" "if gl_bump\n"
"[\n" "[\n"
"blendfunc gl_one gl_zero\n" "blendfunc gl_one gl_zero\n"
"]\n" "]\n"
"}\n" "}\n"
"if $lightmap\n" "if !r_fullbright\n"
"[\n" "[\n"
"{\n" "{\n"
"map $lightmap\n" "map $lightmap\n"
"blendfunc gl_dst_color gl_zero\n" "blendfunc gl_dst_color gl_zero\n"
"}\n" "}\n"
"]\n" "]\n"
"if r_fb_bmodels\n" "if gl_fb_bmodels\n"
"[\n" "[\n"
"{\n" "{\n"
"map $fullbright\n" "map $fullbright\n"
@ -2590,6 +2628,7 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"alphagen const $r_mirroralpha\n" "alphagen const $r_mirroralpha\n"
"depthwrite\n" "depthwrite\n"
"}\n" "}\n"
"surfaceparm nodlight\n"
"}\n"; "}\n";
} }
@ -2602,10 +2641,12 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
{ {
builtin = ( builtin = (
"{\n" "{\n"
"sort seethrough\n"
"{\n" "{\n"
"map $whiteimage\n" "map $whiteimage\n"
"rgbgen $r_fastturbcolour\n" "rgbgen const $r_fastturbcolour\n"
"}\n" "}\n"
"surfaceparm nodlight\n"
"}\n" "}\n"
); );
} }
@ -2630,6 +2671,7 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D watertexture;\n" "uniform sampler2D watertexture;\n"
"uniform float time;\n" "uniform float time;\n"
"uniform float wateralpha;\n"
"varying vec2 tc;\n" "varying vec2 tc;\n"
"void main (void)\n" "void main (void)\n"
@ -2639,16 +2681,19 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
" ntc.t = tc.t + sin(tc.s+time)*0.125;\n" " ntc.t = tc.t + sin(tc.s+time)*0.125;\n"
" vec3 ts = vec3(texture2D(watertexture, ntc));\n" " vec3 ts = vec3(texture2D(watertexture, ntc));\n"
" gl_FragColor.rgb = ts;\n" " gl_FragColor = vec4(ts, wateralpha);\n"
"}\n" "}\n"
"#endif\n" "#endif\n"
"}\n" "}\n"
"param time time\n" "param time time\n"
"param texture 0 watertexture\n" "param texture 0 watertexture\n"
"param cvarf r_wateralpha wateralpha\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"}\n" "}\n"
"sort blend\n"
"}\n" "}\n"
); );
} }
@ -2675,12 +2720,14 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"map $whiteimage\n" "map $whiteimage\n"
"rgbgen const $r_fastskycolour\n" "rgbgen const $r_fastskycolour\n"
"}\n" "}\n"
"surfaceparm nodlight\n"
"}\n" "}\n"
); );
else if (*r_skyboxname.string) else if (*r_skyboxname.string)
builtin = ( builtin = (
"{\n" "{\n"
"skyparms $r_skybox - -\n" "skyparms $r_skybox - -\n"
"surfaceparm nodlight\n"
"}\n" "}\n"
); );
#ifdef GLQUAKE #ifdef GLQUAKE
@ -2929,33 +2976,21 @@ void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args)
} }
void Shader_Default2D(char *shortname, shader_t *s, const void *genargs) void Shader_Default2D(char *shortname, shader_t *s, const void *genargs)
{ {
shaderpass_t *pass; Shader_DefaultScript(shortname, s,
pass = &s->passes[0]; "{\n"
pass->flags = SHADER_PASS_NOCOLORARRAY; "{\n"
pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA; "map $diffuse\n"
pass->shaderbits |= SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA; "rgbgen vertex\n"
pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, IF_NOPICMIP|IF_NOMIPMAP); "alphagen vertex\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"}\n"
"sort additive\n"
"}\n"
);
s->defaulttextures.base = R_LoadHiResTexture(shortname, NULL, IF_NOPICMIP|IF_NOMIPMAP);
s->width = image_width; s->width = image_width;
s->height = image_height; s->height = image_height;
pass->rgbgen = RGB_GEN_VERTEX;
pass->alphagen = ALPHA_GEN_VERTEX;
pass->numtcmods = 0;
pass->tcgen = TC_GEN_BASE;
pass->numMergedPasses = 1;
Shader_SetBlendmode(pass);
if (!TEXVALID(pass->anim_frames[0]))
{
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname );
pass->anim_frames[0] = missing_texture;
}
s->numpasses = 1;
s->numdeforms = 0;
s->flags = SHADER_NOPICMIP|SHADER_NOMIPMAPS|SHADER_BLEND;
s->features = MF_STCOORDS|MF_COLORS;
s->sort = SHADER_SORT_ADDITIVE;
s->uses = 1;
} }
//loads a shader string into an existing shader object, and finalises it and stuff //loads a shader string into an existing shader object, and finalises it and stuff

View file

@ -68,120 +68,114 @@ static int sh_vertnum; //vertex number (set to 0 at SH_Begin)
static shadowmesh_t *sh_shmesh, sh_tempshmesh; static shadowmesh_t *sh_shmesh, sh_tempshmesh;
/* functions to add geometry to the shadow mesh */ /* functions to add geometry to the shadow mesh */
static void SHM_Begin (GLenum e) static void SHM_BeginQuads (void)
{ {
sh_type = e;
sh_firstindex = sh_shmesh->numverts; sh_firstindex = sh_shmesh->numverts;
} }
static void SHM_End (void) static void SHM_End (void)
{ {
int i; int i;
int v1, v2; i = (sh_shmesh->numindicies+(sh_vertnum/4)*6+inc+5)&~(inc-1); //and a bit of padding
switch(sh_type) if (sh_shmesh->maxindicies != i)
{ {
case GL_POLYGON: sh_shmesh->maxindicies = i;
i = (sh_shmesh->numindicies+(sh_vertnum-2)*3+inc+5)&~(inc-1); //and a bit of padding sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies));
if (sh_shmesh->maxindicies != i)
{
sh_shmesh->maxindicies = i;
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies));
}
//decompose the poly into a triangle fan.
v1 = sh_firstindex + 0;
v2 = sh_firstindex + 1;
for (i = 2; i < sh_vertnum; i++)
{
sh_shmesh->indicies[sh_shmesh->numindicies++] = v1;
sh_shmesh->indicies[sh_shmesh->numindicies++] = v2;
sh_shmesh->indicies[sh_shmesh->numindicies++] = v2 = sh_firstindex + i;
}
sh_vertnum = 0;
break;
case GL_TRIANGLES:
i = (sh_shmesh->numindicies+(sh_vertnum)+inc+5)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxindicies != i)
{
sh_shmesh->maxindicies = i;
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies));
}
//add the extra triangles
for (i = 0; i < sh_vertnum; i+=3)
{
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+1;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2;
}
sh_vertnum = 0;
break;
case GL_QUADS:
i = (sh_shmesh->numindicies+(sh_vertnum/4)*6+inc+5)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxindicies != i)
{
sh_shmesh->maxindicies = i;
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies));
}
//add the extra triangles
for (i = 0; i < sh_vertnum; i+=4)
{
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+1;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+3;
}
sh_vertnum = 0;
break;
default:
if (sh_vertnum)
Sys_Error("SH_End: verticies were left");
} }
//add the extra triangles
for (i = 0; i < sh_vertnum; i+=4)
{
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+1;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2;
sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+3;
}
sh_vertnum = 0;
} }
static void SHM_Vertex3f (GLfloat x, GLfloat y, GLfloat z) static void SHM_Vertex3fv (const GLfloat *v)
{ {
int i; int i;
//add the verts as we go //add the verts as we go
i = (sh_shmesh->numverts+inc+5)&~(inc-1); //and a bit of padding i = (sh_shmesh->numverts+inc+5)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxverts != i) if (sh_shmesh->maxverts < i)
{ {
sh_shmesh->maxverts = i; sh_shmesh->maxverts = i;
sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, i * sizeof(*sh_shmesh->verts)); sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, i * sizeof(*sh_shmesh->verts));
} }
sh_shmesh->verts[sh_shmesh->numverts][0] = x; sh_shmesh->verts[sh_shmesh->numverts][0] = v[0];
sh_shmesh->verts[sh_shmesh->numverts][1] = y; sh_shmesh->verts[sh_shmesh->numverts][1] = v[1];
sh_shmesh->verts[sh_shmesh->numverts][2] = z; sh_shmesh->verts[sh_shmesh->numverts][2] = v[2];
sh_vertnum++; sh_vertnum++;
sh_shmesh->numverts++; sh_shmesh->numverts++;
switch(sh_type)
if (sh_vertnum == 4)
{ {
case GL_POLYGON: SHM_End();
break; sh_firstindex = sh_shmesh->numverts;
case GL_TRIANGLES:
if (sh_vertnum == 3)
{
SHM_End();
sh_firstindex = sh_shmesh->numverts;
}
break;
case GL_QUADS:
if (sh_vertnum == 4)
{
SHM_End();
sh_firstindex = sh_shmesh->numverts;
}
break;
default:
Sys_Error("SH_Vertex3f: bad type");
} }
} }
static void APIENTRY SHM_Vertex3fv (const GLfloat *v)
void SHM_TriangleFan(int numverts, vecV_t *verts, vec3_t lightorg, float pd)
{ {
SHM_Vertex3f(v[0], v[1], v[2]); int v, i, idxs;
float *v1;
vec3_t v3;
vecV_t *outv;
index_t *outi;
/*make sure there's space*/
v = (sh_shmesh->numverts+numverts*2 + inc)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxverts < v)
{
sh_shmesh->maxverts = v;
sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, v * sizeof(*sh_shmesh->verts));
}
outv = sh_shmesh->verts + sh_shmesh->numverts;
for (v = 0; v < numverts; v++)
{
v1 = verts[v];
VectorCopy(v1, outv[v]);
v3[0] = ( v1[0]-lightorg[0] )*pd;
v3[1] = ( v1[1]-lightorg[1] )*pd;
v3[2] = ( v1[2]-lightorg[2] )*pd;
outv[v+numverts][0] = v1[0]+v3[0];
outv[v+numverts][1] = v1[1]+v3[1];
outv[v+numverts][2] = v1[2]+v3[2];
}
idxs = (numverts-2)*3;
/*now add the verts in a fan*/
v = (sh_shmesh->numindicies+idxs*2+inc)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxindicies < v)
{
sh_shmesh->maxindicies = v;
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, v * sizeof(*sh_shmesh->indicies));
}
outi = sh_shmesh->indicies + sh_shmesh->numindicies;
for (v = 2, i = 0; v < numverts; v++, i+=3)
{
outi[i+0] = sh_shmesh->numverts;
outi[i+1] = sh_shmesh->numverts+v-1;
outi[i+2] = sh_shmesh->numverts+v;
outi[i+0+idxs] = sh_shmesh->numverts+numverts+v;
outi[i+1+idxs] = sh_shmesh->numverts+numverts+v-1;
outi[i+2+idxs] = sh_shmesh->numverts+numverts;
}
/*we added this many*/
sh_shmesh->numverts += numverts*2;
sh_shmesh->numindicies += i*2;
} }
static void SHM_Shadow_Cache_Surface(msurface_t *surf) static void SHM_Shadow_Cache_Surface(msurface_t *surf)
@ -209,27 +203,50 @@ static void SHM_Shadow_Cache_Leaf(mleaf_t *leaf)
sh_shmesh->litleaves[i>>3] |= 1<<(i&7); sh_shmesh->litleaves[i>>3] |= 1<<(i&7);
} }
void SH_FreeShadowMesh(shadowmesh_t *sm)
{
unsigned int i;
for (i = 0; i < sm->numsurftextures; i++)
Z_Free(sm->litsurfs[i].s);
Z_Free(sm->litsurfs);
Z_Free(sm->indicies);
Z_Free(sm->verts);
Z_Free(sm);
}
static void SHM_BeginShadowMesh(dlight_t *dl) static void SHM_BeginShadowMesh(dlight_t *dl)
{ {
unsigned int i; unsigned int i;
unsigned int lb;
sh_vertnum = 0; sh_vertnum = 0;
if (!dl->die) lb = (cl.worldmodel->numleafs+7)/8;
if (!dl->die || !dl->key)
{ {
sh_shmesh = Z_Malloc(sizeof(*sh_shmesh) + (cl.worldmodel->numleafs+7)/8); sh_shmesh = dl->worldshadowmesh;
sh_shmesh->leafbytes = (cl.worldmodel->numleafs+7)/8; if (!sh_shmesh || sh_shmesh->leafbytes != lb)
sh_shmesh->litleaves = (unsigned char*)(sh_shmesh+1); {
/*this shouldn't happen too often*/
if (sh_shmesh)
{
SH_FreeShadowMesh(sh_shmesh);
}
dl->worldshadowmesh = sh_shmesh; /*Create a new shadowmesh for this light*/
sh_shmesh = Z_Malloc(sizeof(*sh_shmesh) + lb);
sh_shmesh->leafbytes = lb;
sh_shmesh->litleaves = (unsigned char*)(sh_shmesh+1);
dl->worldshadowmesh = sh_shmesh;
}
dl->rebuildcache = false;
} }
else else
{ {
unsigned int lb;
//FIXME: many dynamic lights are static. cache for a frame and see if it can be reused.
sh_shmesh = &sh_tempshmesh; sh_shmesh = &sh_tempshmesh;
lb = (cl.worldmodel->numleafs+7)/8;
if (sh_shmesh->leafbytes != lb) if (sh_shmesh->leafbytes != lb)
{ {
/*this happens on map changes*/
sh_shmesh->leafbytes = lb; sh_shmesh->leafbytes = lb;
Z_Free(sh_shmesh->litleaves); Z_Free(sh_shmesh->litleaves);
sh_shmesh->litleaves = Z_Malloc(lb); sh_shmesh->litleaves = Z_Malloc(lb);
@ -240,7 +257,7 @@ static void SHM_BeginShadowMesh(dlight_t *dl)
sh_shmesh->maxindicies = 0; sh_shmesh->maxindicies = 0;
sh_shmesh->numindicies = 0; sh_shmesh->numindicies = 0;
if (sh_shmesh->numsurftextures < cl.worldmodel->numtextures) if (sh_shmesh->numsurftextures != cl.worldmodel->numtextures)
{ {
if (sh_shmesh->litsurfs) if (sh_shmesh->litsurfs)
{ {
@ -281,9 +298,6 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
double dot; double dot;
int v; int v;
float *v1;
vec3_t v3;
float l, maxdist; float l, maxdist;
int j, s, t; int j, s, t;
vec3_t impact; vec3_t impact;
@ -407,9 +421,7 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
{ {
SHM_Shadow_Cache_Surface(surf); SHM_Shadow_Cache_Surface(surf);
#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff
#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff
//build a list of the edges that are to be drawn. //build a list of the edges that are to be drawn.
for (v = 0; v < surf->numedges; v++) for (v = 0; v < surf->numedges; v++)
@ -454,26 +466,7 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
} }
} }
//fixme:this only works becuse q1bsps don't have combined meshes yet... SHM_TriangleFan(surf->mesh->numvertexes, surf->mesh->xyz_array, dl->origin, PROJECTION_DISTANCE);
SHM_Begin(GL_POLYGON);
for (v = 0; v < surf->mesh->numvertexes; v++)
{
SHM_Vertex3fv(surf->mesh->xyz_array[v]);
}
SHM_End();
//back (depth precision doesn't matter)
SHM_Begin(GL_POLYGON);
for (v = surf->mesh->numvertexes-1; v >=0; v--)
{
v1 = surf->mesh->xyz_array[v];
v3[0] = ( v1[0]-dl->origin[0] )*PROJECTION_DISTANCE;
v3[1] = ( v1[1]-dl->origin[1] )*PROJECTION_DISTANCE;
v3[2] = ( v1[2]-dl->origin[2] )*PROJECTION_DISTANCE;
SHM_Vertex3f( v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2] );
}
SHM_End();
} }
} }
} }
@ -492,9 +485,6 @@ static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
double dot; double dot;
int v; int v;
float *v1;
vec3_t v3;
float l, maxdist; float l, maxdist;
int j, s, t; int j, s, t;
vec3_t impact; vec3_t impact;
@ -665,25 +655,7 @@ static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
} }
} }
SHM_Begin(GL_POLYGON); SHM_TriangleFan(surf->mesh->numvertexes, surf->mesh->xyz_array, dl->origin, PROJECTION_DISTANCE);
for (v = 0; v < surf->mesh->numvertexes; v++)
{
SHM_Vertex3fv(surf->mesh->xyz_array[v]);
}
SHM_End();
//back (depth precision doesn't matter)
SHM_Begin(GL_POLYGON);
for (v = surf->mesh->numvertexes-1; v >=0; v--)
{
v1 = surf->mesh->xyz_array[v];
v3[0] = ( v1[0]-dl->origin[0] )*PROJECTION_DISTANCE;
v3[1] = ( v1[1]-dl->origin[1] )*PROJECTION_DISTANCE;
v3[2] = ( v1[2]-dl->origin[2] )*PROJECTION_DISTANCE;
SHM_Vertex3f( v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2] );
}
SHM_End();
} }
} }
} }
@ -851,8 +823,6 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
unsigned int sno; unsigned int sno;
unsigned int vno, vno2; unsigned int vno, vno2;
unsigned int fvert, lvert; unsigned int fvert, lvert;
float *v1;
vec3_t v3;
mesh_t *sm; mesh_t *sm;
for (tno = 0; tno < sh_shmesh->numsurftextures; tno++) for (tno = 0; tno < sh_shmesh->numsurftextures; tno++)
{ {
@ -870,27 +840,7 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
//continue; //continue;
fvert = sh_shmesh->numverts; fvert = sh_shmesh->numverts;
//front SHM_TriangleFan(sm->numvertexes, sm->xyz_array, dl->origin, PROJECTION_DISTANCE);
SHM_Begin(GL_POLYGON);
for (vno = 0; vno < sm->numvertexes; vno++)
{
SHM_Vertex3fv(sm->xyz_array[vno]);
}
SHM_End();
//back (depth precision doesn't matter)
SHM_Begin(GL_POLYGON);
for (vno = sm->numvertexes; vno > 0; )
{
vno--;
v1 = sm->xyz_array[vno];
v3[0] = (v1[0]-dl->origin[0])*PROJECTION_DISTANCE;
v3[1] = (v1[1]-dl->origin[1])*PROJECTION_DISTANCE;
v3[2] = (v1[2]-dl->origin[2])*PROJECTION_DISTANCE;
SHM_Vertex3f(v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2]);
}
SHM_End();
vno = (sh_shmesh->numindicies+sm->numvertexes*6); //and a bit of padding vno = (sh_shmesh->numindicies+sm->numvertexes*6); //and a bit of padding
if (sh_shmesh->maxindicies < vno) if (sh_shmesh->maxindicies < vno)
@ -944,7 +894,7 @@ static struct shadowmesh_s *SHM_BuildShadowVolumeMesh(dlight_t *dl, unsigned cha
float *v1, *v2; float *v1, *v2;
vec3_t v3, v4; vec3_t v3, v4;
if (dl->worldshadowmesh) if (dl->worldshadowmesh && !dl->rebuildcache)
return dl->worldshadowmesh; return dl->worldshadowmesh;
if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife) if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife)
@ -981,7 +931,7 @@ static struct shadowmesh_s *SHM_BuildShadowVolumeMesh(dlight_t *dl, unsigned cha
else else
return NULL; return NULL;
SHM_Begin(GL_QUADS); SHM_BeginQuads();
while(firstedge) while(firstedge)
{ {
//border //border
@ -1461,12 +1411,7 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
checkerror(); checkerror();
} }
if (l->worldshadowmesh) smesh = SHM_BuildShadowVolumeMesh(l, lvis, NULL);
smesh = l->worldshadowmesh;
else
{
smesh = SHM_BuildShadowVolumeMesh(l, lvis, NULL);
}
/*polygon offsets. urgh.*/ /*polygon offsets. urgh.*/
qglEnable(GL_POLYGON_OFFSET_FILL); qglEnable(GL_POLYGON_OFFSET_FILL);
@ -1678,6 +1623,8 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
currententity = &r_worldentity; currententity = &r_worldentity;
sm = light->worldshadowmesh; sm = light->worldshadowmesh;
if (light->rebuildcache)
sm = &sh_tempshmesh;
if (sm) if (sm)
{ {
for (tno = 0; tno < sm->numsurftextures; tno++) for (tno = 0; tno < sm->numsurftextures; tno++)
@ -1690,16 +1637,12 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
BE_BaseEntTextures(); BE_BaseEntTextures();
} }
else
{
#pragma message("FIXME: For dynamic lights, the entire view is redrawn! Bad!")
BE_SubmitMeshes();
}
} }
#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff #define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff
/*Fixme: this is brute forced*/ /*Fixme: this is brute forced*/
#pragma message("brush shadows are bruteforced")
static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e) static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
{ {
int v; int v;
@ -1902,7 +1845,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
maxs[1] = dl->origin[1] + dl->radius; maxs[1] = dl->origin[1] + dl->radius;
maxs[2] = dl->origin[2] + dl->radius; maxs[2] = dl->origin[2] + dl->radius;
if (dl->worldshadowmesh) if (!dl->rebuildcache)
{ {
//fixme: check head node first? //fixme: check head node first?
if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis)) if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis))
@ -2091,7 +2034,7 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
return; //this should be the more common case return; //this should be the more common case
} }
if (dl->worldshadowmesh) if (!dl->rebuildcache)
{ {
//fixme: check head node first? //fixme: check head node first?
if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis)) if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis))

View file

@ -171,6 +171,7 @@ extern cvar_t vid_preservegamma;
extern cvar_t vid_gl_context_version; extern cvar_t vid_gl_context_version;
extern cvar_t vid_gl_context_debug; extern cvar_t vid_gl_context_debug;
extern cvar_t vid_gl_context_forwardcompatible; extern cvar_t vid_gl_context_forwardcompatible;
extern cvar_t vid_gl_context_compatibility;
int window_center_x, window_center_y, window_x, window_y, window_width, window_height; int window_center_x, window_center_y, window_x, window_y, window_width, window_height;
RECT window_rect; RECT window_rect;
@ -238,7 +239,12 @@ HGLRC (APIENTRY *qwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, cons
#define WGL_CONTEXT_FLAGS_ARB 0x2094 #define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define ERROR_INVALID_VERSION_ARB 0x2095 #define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
qboolean GLInitialise (char *renderer) qboolean GLInitialise (char *renderer)
@ -857,7 +863,6 @@ qboolean VID_AttachGL (rendererstate_t *info)
#ifdef USE_D3D #ifdef USE_D3D
if (!Q_strcasecmp(info->glrenderer, "D3D")) if (!Q_strcasecmp(info->glrenderer, "D3D"))
{ {
extern cvar_t gl_ztrick;
int zbpp = info->bpp > 16 ? 24 : 16; int zbpp = info->bpp > 16 ? 24 : 16;
gl_canstencil = false; gl_canstencil = false;
TRACE(("dbg: VID_AttachGL: D3DInitialize\n")); TRACE(("dbg: VID_AttachGL: D3DInitialize\n"));
@ -869,16 +874,12 @@ qboolean VID_AttachGL (rendererstate_t *info)
TRACE(("dbg: VID_AttachGL: d3dSetMode\n")); TRACE(("dbg: VID_AttachGL: d3dSetMode\n"));
d3dSetMode(info->fullscreen, info->width, info->height, info->bpp, zbpp); //d3d cheats to get it's dimensions and stuff... One that we can currently live with though. d3dSetMode(info->fullscreen, info->width, info->height, info->bpp, zbpp); //d3d cheats to get it's dimensions and stuff... One that we can currently live with though.
gl_ztrickdisabled |= 2; //ztrick does funny things.
Cvar_Set(&gl_ztrick, "0");
maindc = GetDC(mainwindow); maindc = GetDC(mainwindow);
Con_Printf(CON_NOTICE "OpenGL to Direct3D wrapper enabled\n"); //green to make it show. Con_Printf(CON_NOTICE "OpenGL to Direct3D wrapper enabled\n"); //green to make it show.
break; break;
} }
#endif #endif
gl_ztrickdisabled &= ~2;
TRACE(("dbg: VID_AttachGL: GLInitialise\n")); TRACE(("dbg: VID_AttachGL: GLInitialise\n"));
if (GLInitialise(info->glrenderer)) if (GLInitialise(info->glrenderer))
{ {
@ -967,6 +968,14 @@ qboolean VID_AttachGL (rendererstate_t *info)
i += 2; i += 2;
} }
attribs[i+1] = 0;
if (vid_gl_context_compatibility.value)
attribs[i+1] |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
else
attribs[i+1] |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
attribs[i] = WGL_CONTEXT_PROFILE_MASK_ARB;
i+=2;
attribs[i] = 0; attribs[i] = 0;
if (!i) if (!i)

View file

@ -222,8 +222,6 @@ extern int d_lightstylevalue[256]; // 8.8 fraction of base light value
extern texid_t netgraphtexture; // netgraph texture extern texid_t netgraphtexture; // netgraph texture
extern int gl_lightmap_format;
extern int mirrortexturenum; // quake texturenum, not gltexturenum extern int mirrortexturenum; // quake texturenum, not gltexturenum
extern qboolean mirror; extern qboolean mirror;
extern mplane_t *mirror_plane; extern mplane_t *mirror_plane;

View file

@ -40,10 +40,14 @@ extern qlpMTex2FUNC qglMultiTexCoord2fARB;
./gl/gl_draw.c:3251: error: for each function it appears in.) ./gl/gl_draw.c:3251: error: for each function it appears in.)
*/ */
#ifndef GL_EXT_bgra #ifndef GL_EXT_bgra
#define GL_BGR_EXT 0x80E0 #define GL_BGR_EXT 0x80E0 /*core in opengl 1.2*/
#define GL_BGRA_EXT 0x80E1 #define GL_BGRA_EXT 0x80E1
#endif #endif
#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 /*opengl 1.2*/
#endif
#ifndef GL_ARB_multitexture #ifndef GL_ARB_multitexture
#define GL_ARB_multitexture 1 #define GL_ARB_multitexture 1
#define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE0_ARB 0x84C0

View file

@ -264,6 +264,7 @@ typedef struct {
SP_FIRSTIMMEDIATE, //never set SP_FIRSTIMMEDIATE, //never set
SP_CVARI, SP_CVARI,
SP_CVARF, SP_CVARF,
SP_CVAR3F,
SP_TEXTURE SP_TEXTURE
} type; } type;
unsigned int handle; unsigned int handle;
@ -405,6 +406,8 @@ void BE_GenBrushModelVBO(model_t *mod);
void BE_ClearVBO(vbo_t *vbo); void BE_ClearVBO(vbo_t *vbo);
//Uploads all modified lightmaps //Uploads all modified lightmaps
void BE_UploadAllLightmaps(void); void BE_UploadAllLightmaps(void);
//Builds a hardware shader from the software representation
void BE_GenerateProgram(shader_t *shader);
#ifdef RTLIGHTS #ifdef RTLIGHTS
void BE_PushOffsetShadow(qboolean foobar); void BE_PushOffsetShadow(qboolean foobar);

View file

@ -9,21 +9,21 @@
#endif #endif
// hash init assumes we get clean memory // hash init assumes we get clean memory
void Hash_InitTable(hashtable_t *table, int numbucks, void *mem) void Hash_InitTable(hashtable_t *table, unsigned int numbucks, void *mem)
{ {
table->numbuckets = numbucks; table->numbuckets = numbucks;
table->bucket = (bucket_t **)mem; table->bucket = (bucket_t **)mem;
} }
int Hash_Key(const char *name, int modulus) unsigned int Hash_Key(const char *name, unsigned int modulus)
{ //fixme: optimize. { //fixme: optimize.
unsigned int key; unsigned int key;
for (key=0;*name; name++) for (key=0;*name; name++)
key += ((key<<3) + (key>>28) + *name); key += ((key<<3) + (key>>28) + *name);
return (int)(key%modulus); return (key%modulus);
} }
int Hash_KeyInsensative(const char *name, int modulus) unsigned int Hash_KeyInsensative(const char *name, unsigned int modulus)
{ //fixme: optimize. { //fixme: optimize.
unsigned int key; unsigned int key;
for (key=0;*name; name++) for (key=0;*name; name++)
@ -34,12 +34,12 @@ int Hash_KeyInsensative(const char *name, int modulus)
key += ((key<<3) + (key>>28) + *name); key += ((key<<3) + (key>>28) + *name);
} }
return (int)(key%modulus); return (key%modulus);
} }
void *Hash_Get(hashtable_t *table, const char *name) void *Hash_Get(hashtable_t *table, const char *name)
{ {
int bucknum = Hash_Key(name, table->numbuckets); unsigned int bucknum = Hash_Key(name, table->numbuckets);
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -55,7 +55,7 @@ void *Hash_Get(hashtable_t *table, const char *name)
} }
void *Hash_GetInsensative(hashtable_t *table, const char *name) void *Hash_GetInsensative(hashtable_t *table, const char *name)
{ {
int bucknum = Hash_KeyInsensative(name, table->numbuckets); unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -69,9 +69,9 @@ void *Hash_GetInsensative(hashtable_t *table, const char *name)
} }
return NULL; return NULL;
} }
void *Hash_GetKey(hashtable_t *table, int key) void *Hash_GetKey(hashtable_t *table, unsigned int key)
{ {
int bucknum = key%table->numbuckets; unsigned int bucknum = key%table->numbuckets;
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -87,7 +87,7 @@ void *Hash_GetKey(hashtable_t *table, int key)
} }
void *Hash_GetNext(hashtable_t *table, const char *name, void *old) void *Hash_GetNext(hashtable_t *table, const char *name, void *old)
{ {
int bucknum = Hash_Key(name, table->numbuckets); unsigned int bucknum = Hash_Key(name, table->numbuckets);
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -117,7 +117,7 @@ void *Hash_GetNext(hashtable_t *table, const char *name, void *old)
} }
void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old) void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old)
{ {
int bucknum = Hash_KeyInsensative(name, table->numbuckets); unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -149,7 +149,7 @@ void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old)
void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck) void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck)
{ {
int bucknum = Hash_Key(name, table->numbuckets); unsigned int bucknum = Hash_Key(name, table->numbuckets);
buck->data = data; buck->data = data;
buck->key.string = name; buck->key.string = name;
@ -160,7 +160,7 @@ void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck)
} }
void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck) void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck)
{ {
int bucknum = Hash_KeyInsensative(name, table->numbuckets); unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
buck->data = data; buck->data = data;
buck->key.string = name; buck->key.string = name;
@ -169,9 +169,9 @@ void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, buck
return buck; return buck;
} }
void *Hash_AddKey(hashtable_t *table, int key, void *data, bucket_t *buck) void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck)
{ {
int bucknum = key%table->numbuckets; unsigned int bucknum = key%table->numbuckets;
buck->data = data; buck->data = data;
buck->key.value = key; buck->key.value = key;
@ -183,7 +183,7 @@ void *Hash_AddKey(hashtable_t *table, int key, void *data, bucket_t *buck)
void Hash_Remove(hashtable_t *table, const char *name) void Hash_Remove(hashtable_t *table, const char *name)
{ {
int bucknum = Hash_Key(name, table->numbuckets); unsigned int bucknum = Hash_Key(name, table->numbuckets);
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -210,7 +210,7 @@ void Hash_Remove(hashtable_t *table, const char *name)
void Hash_RemoveData(hashtable_t *table, const char *name, void *data) void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
{ {
int bucknum = Hash_Key(name, table->numbuckets); unsigned int bucknum = Hash_Key(name, table->numbuckets);
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];
@ -238,9 +238,9 @@ void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
} }
void Hash_RemoveKey(hashtable_t *table, int key) void Hash_RemoveKey(hashtable_t *table, unsigned int key)
{ {
int bucknum = key%table->numbuckets; unsigned int bucknum = key%table->numbuckets;
bucket_t *buck; bucket_t *buck;
buck = table->bucket[bucknum]; buck = table->bucket[bucknum];

View file

@ -5,34 +5,34 @@
#ifndef HASH_H__ #ifndef HASH_H__
#define HASH_H__ #define HASH_H__
#define Hash_BytesForBuckets(b) (sizeof(bucket_t*)*b) #define Hash_BytesForBuckets(b) (sizeof(bucket_t*)*(b))
#define STRCMP(s1,s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1)) //saves about 2-6 out of 120 - expansion of idea from fastqcc #define STRCMP(s1,s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1)) //saves about 2-6 out of 120 - expansion of idea from fastqcc
typedef struct bucket_s { typedef struct bucket_s {
void *data; void *data;
union { union {
const char *string; const char *string;
int value; unsigned int value;
} key; } key;
struct bucket_s *next; struct bucket_s *next;
} bucket_t; } bucket_t;
typedef struct hashtable_s { typedef struct hashtable_s {
int numbuckets; unsigned int numbuckets;
bucket_t **bucket; bucket_t **bucket;
} hashtable_t; } hashtable_t;
void Hash_InitTable(hashtable_t *table, int numbucks, void *mem); //mem must be 0 filled. (memset(mem, 0, size)) void Hash_InitTable(hashtable_t *table, unsigned int numbucks, void *mem); //mem must be 0 filled. (memset(mem, 0, size))
int Hash_Key(const char *name, int modulus); unsigned int Hash_Key(const char *name, unsigned int modulus);
void *Hash_Get(hashtable_t *table, const char *name); void *Hash_Get(hashtable_t *table, const char *name);
void *Hash_GetInsensative(hashtable_t *table, const char *name); void *Hash_GetInsensative(hashtable_t *table, const char *name);
void *Hash_GetKey(hashtable_t *table, int key); void *Hash_GetKey(hashtable_t *table, unsigned int key);
void *Hash_GetNext(hashtable_t *table, const char *name, void *old); void *Hash_GetNext(hashtable_t *table, const char *name, void *old);
void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old); void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old);
void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck); void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck);
void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck); void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck);
void Hash_Remove(hashtable_t *table, const char *name); void Hash_Remove(hashtable_t *table, const char *name);
void Hash_RemoveData(hashtable_t *table, const char *name, void *data); void Hash_RemoveData(hashtable_t *table, const char *name, void *data);
void Hash_RemoveKey(hashtable_t *table, int key); void Hash_RemoveKey(hashtable_t *table, unsigned int key);
void *Hash_AddKey(hashtable_t *table, int key, void *data, bucket_t *buck); void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck);
#endif #endif

View file

@ -504,7 +504,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
fdef = ED_FindField (progfuncs, assignment); fdef = ED_FindField (progfuncs, assignment);
if (!fdef) if (!fdef)
{ {
int l,nl = strlen(assignment); size_t l,nl = strlen(assignment);
strcpy(buf, "Can't find field "); strcpy(buf, "Can't find field ");
l = strlen(buf); l = strlen(buf);
if (nl > sizeof(buf)-l-2) if (nl > sizeof(buf)-l-2)
@ -537,7 +537,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
func = ED_FindFunction (progfuncs, s, &i, progsnum); func = ED_FindFunction (progfuncs, s, &i, progsnum);
if (!func) if (!func)
{ {
int l,nl = strlen(s); size_t l,nl = strlen(s);
assignment[-1] = '='; assignment[-1] = '=';

View file

@ -540,6 +540,7 @@ CompilerConstant_t *QCC_PR_DefineName(char *name);
void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin); void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin);
#ifndef COMMONINLINES #ifndef COMMONINLINES
pbool QCC_PR_CheckImmediate (char *string);
pbool QCC_PR_CheckToken (char *string); pbool QCC_PR_CheckToken (char *string);
pbool QCC_PR_CheckName (char *string); pbool QCC_PR_CheckName (char *string);
void QCC_PR_Expect (char *string); void QCC_PR_Expect (char *string);

View file

@ -7931,7 +7931,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
{ {
if (!pHash_Get(&globalstable, "end_sys_fields")) if (!pHash_Get(&globalstable, "end_sys_fields"))
first->references++; //anything above needs to be left in, and so warning about not using it is just going to pee people off. first->references++; //anything above needs to be left in, and so warning about not using it is just going to pee people off.
if (arraysize <= 1) if (arraysize <= 1 && first->type->type != ev_field)
first->constant = false; first->constant = false;
if (scope) if (scope)
pHash_Add(&localstable, first->name, first, qccHunkAlloc(sizeof(bucket_t))); pHash_Add(&localstable, first->name, first, qccHunkAlloc(sizeof(bucket_t)));
@ -9044,13 +9044,14 @@ void QCC_PR_ParseDefs (char *classname)
continue; continue;
} }
#pragma message("this is experimental")
if (pr_scope) if (pr_scope)
{ {
d = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); d = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
if (typecmp(def->type, d->type))
QCC_PR_ParseError (ERR_BADIMMEDIATETYPE, "wrong immediate type for %s", name);
if (d->constant) if (d->constant)
{ {
for (i = 0; i < d->type->size; i++) for (i = 0; (unsigned)i < def->type->size; i++)
G_INT(def->ofs+i) = G_INT(d->ofs+i); G_INT(def->ofs+i) = G_INT(d->ofs+i);
def->constant = !isvar; def->constant = !isvar;
def->initialized = 1; def->initialized = 1;
@ -9599,8 +9600,15 @@ void QCC_PR_ParseDefs (char *classname)
def->initialized = 1; def->initialized = 1;
} }
if (isconstant && type->type == ev_field) if (type->type == ev_field)
def->constant = 2; //special flag on fields, 2, makes the pointer obtained from them also constant. {
if (isconstant)
def->constant = 2; //special flag on fields, 2, makes the pointer obtained from them also constant.
else if (isvar)
def->constant = 0;
else
def->constant = 1;
}
else else
def->constant = isconstant; def->constant = isconstant;
} }

View file

@ -3121,7 +3121,6 @@ newstyle:
{ {
while (pr_file_p=QCC_COM_Parse(pr_file_p)) while (pr_file_p=QCC_COM_Parse(pr_file_p))
{ {
struct stat s;
if (stat(qcc_token, &s) == -1 || s.st_mtime > os.st_mtime) if (stat(qcc_token, &s) == -1 || s.st_mtime > os.st_mtime)
{ {
printf("%s changed\n", qcc_token); printf("%s changed\n", qcc_token);

View file

@ -1,6 +1,564 @@
#include "qwsvdef.h" #include "qwsvdef.h"
#ifndef CLIENTONLY #ifndef CLIENTONLY
/*Testing this code should typically be done with the three following mods:
Prydon gate
Nexuiz
FrikBots (both NQ+QW).
If those 3 mods work, then pretty much everything else will
*/
//#define NEWPREPARSE
/*I want to rewrite this
to use something like
*/
#ifdef NEWPREPARSE
enum protocol_type
{
PPT_FLOAT,
PPT_ENT,
PPT_COORD,
PPT_ANGLE,
PPT_BYTE,
PPT_SHORT,
PPT_LONG,
PPT_STRING
};
#define PPT_POS PPT_COORD,PPT_COORD,PPT_COORD
union protocol_data
{
float fd;
int id;
unsigned char *str;
};
static union protocol_data pp_data[1024];
static enum protocol_type pp_temptypes[1024], *pp_types;
static unsigned char pp_sdata[4096];
static unsigned int pp_sdata_offset;
static int pp_dest;
static qboolean pp_fault;
static unsigned int pp_expectedelements;
static unsigned int pp_receivedelements;
static qboolean (*pp_curdecision) (enum protocol_type *pt, union protocol_data *pd);
static enum protocol_type pp_root[] = {PPT_BYTE};
static qboolean pp_root_decide(enum protocol_type *pt, union protocol_data *pd);
static void decide(enum protocol_type *types, unsigned int numtypes, qboolean (*newdecision) (enum protocol_type *pt, union protocol_data *pd))
{
pp_types = types;
pp_expectedelements = numtypes;
pp_curdecision = newdecision;
}
static void pp_flush(multicast_t to, vec3_t origin, void (*flushfunc)(client_t *cl, sizebuf_t *msg, enum protocol_type *pt, union protocol_data *pd), enum protocol_type *pt, union protocol_data *pd)
{
client_t *client;
qbyte *mask;
int leafnum;
int j;
qboolean reliable;
decide(pp_root, 1, pp_root_decide);
{
reliable = false;
switch (to)
{
case MULTICAST_ALL_R:
reliable = true; // intentional fallthrough
case MULTICAST_ALL:
mask = sv.pvs; // leaf 0 is everything;
break;
case MULTICAST_PHS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PHS:
if (!sv.phs)
mask = sv.pvs;
else
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
}
break;
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin);
mask = sv.pvs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
break;
default:
return;
}
// send the data to all relevent clients
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
{
if (client->state != cs_spawned)
continue;
if (client->controller)
continue; //FIXME: send if at least one of the players is near enough.
if (!((int)client->edict->xv->dimension_see & (int)pr_global_struct->dimension_send))
continue;
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS)
{
vec3_t delta;
VectorSubtract(origin, client->edict->v->origin, delta);
if (Length(delta) <= 1024)
goto inrange;
}
// -1 is because pvs rows are 1 based, not 0 based like leafs
if (mask != sv.pvs)
{
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, client->edict->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
{
continue;
}
}
inrange:
if (client->protocol == SCP_BAD)
{
/*bot*/
continue;
}
if (reliable)
flushfunc(client, &client->netchan.message, pt, pd);
else
flushfunc(client, &client->datagram, pt, pd);
}
}
/*
if (sv.mvdrecording && !with) //mvds don't get the pext stuff
{
flushfunc(&dem.recorder,
if (reliable)
{
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
SZ_Write((sizebuf_t*)demo.dbuf, sv.multicast.data, sv.multicast.cursize);
} else
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
}*/
pp_sdata_offset = 0;
pp_receivedelements = 0;
}
#define DECIDE(t) decide(t, sizeof(t)/sizeof(*t), t##_decide)
#define DECIDE2(t,f) decide(t, sizeof(t)/sizeof(*t), f)
static void pp_identity_flush(client_t *cl, sizebuf_t *msg, enum protocol_type *pt, union protocol_data *pd)
{
unsigned int i;
for (i = 0; i < pp_receivedelements; i++)
{
switch(pt[i])
{
case PPT_BYTE:
MSG_WriteByte(msg, pd[i].id);
break;
case PPT_ENT:
case PPT_SHORT:
MSG_WriteShort(msg, pd[i].id);
break;
case PPT_COORD:
MSG_WriteCoord(msg, pd[i].fd);
break;
case PPT_ANGLE:
MSG_WriteAngle(msg, pd[i].fd);
break;
case PPT_STRING:
MSG_WriteString(msg, pd[i].str);
break;
}
}
}
/*flush is our last attempt to cope with unrecognised/invalid messages, it will send stuff though as it was, and most likely get things wrong*/
void NPP_Flush(void)
{
pp_fault = false;
pp_flush(MULTICAST_ALL_R, NULL, pp_identity_flush, pp_types, pp_data);
}
static void pp_entry(int dest, enum protocol_type pt, union protocol_data pd)
{
if (pp_receivedelements)
{
if (pp_dest != dest)
{
if (!pp_fault)
Con_Printf("Preparse: MSG destination changed in the middle of a packet 0x%x.\n", pp_data[0].id);
NPP_Flush();
}
}
pp_dest = dest;
if (pp_fault)
{
pp_types[pp_receivedelements] = pt;
pp_data[pp_receivedelements] = pd;
pp_receivedelements++;
}
else if (pp_types[pp_receivedelements] != pt)
{
Con_Printf("Preparse: Unmatched expectation at entry %i in svc 0x%x.\n", pp_receivedelements+1, pp_data[0].id);
pp_types[pp_receivedelements] = pt;
pp_data[pp_receivedelements] = pd;
pp_receivedelements++;
faulted:
pp_fault = true;
if (pp_temptypes != pp_types)
{
memcpy(pp_temptypes, pp_types, sizeof(*pp_temptypes)*pp_receivedelements);
pp_types = pp_temptypes;
}
}
else
{
pp_data[pp_receivedelements++] = pd;
if (pp_expectedelements == pp_receivedelements)
{
if (!pp_curdecision(pp_types, pp_data))
{
if (pp_types[pp_receivedelements-1] == PPT_BYTE)
Con_Printf("Preparse: Unhandled byte %i@%i in svc%i.\n", pd.id, pp_receivedelements, pp_data[0].id);
else
Con_Printf("Preparse: Unhandled data @%i in svc%i.\n", pp_receivedelements, pp_data[0].id);
goto faulted;
}
}
}
}
void NPP_NQWriteByte(int dest, qbyte data)
{
union protocol_data pd;
pd.id = data;
pp_entry(dest, PPT_BYTE, pd);
}
void NPP_NQWriteChar(int dest, char data)
{
union protocol_data pd;
pd.id = (unsigned char)data;
pp_entry(dest, PPT_BYTE, pd);
}
void NPP_NQWriteShort(int dest, short data)
{
union protocol_data pd;
pd.id = (unsigned char)data;
pp_entry(dest, PPT_SHORT, pd);
}
void NPP_NQWriteLong(int dest, long data)
{
union protocol_data pd;
pd.id = data;
pp_entry(dest, PPT_LONG, pd);
}
void NPP_NQWriteAngle(int dest, float data)
{
union protocol_data pd;
pd.fd = data;
pp_entry(dest, PPT_ANGLE, pd);
}
void NPP_NQWriteCoord(int dest, float data)
{
union protocol_data pd;
pd.fd = data;
pp_entry(dest, PPT_COORD, pd);
}
void NPP_NQWriteString(int dest, char *data)
{
unsigned int l;
union protocol_data pd;
l = strlen(data)+1;
if (pp_sdata_offset + l > sizeof(pp_sdata))
SV_Error("preparse string overflow\n");
pd.str = pp_sdata + pp_sdata_offset;
memcpy(pd.str, data, l);
pp_entry(dest, PPT_STRING, pd);
}
void NPP_NQWriteEntity(int dest, short data)
{
union protocol_data pd;
pd.id = (unsigned short)data;
pp_entry(dest, PPT_COORD, pd);
}
void NPP_QWWriteByte(int dest, qbyte data)
{
NPP_NQWriteByte(dest, data);
}
void NPP_QWWriteChar(int dest, char data)
{
NPP_NQWriteChar(dest, data);
}
void NPP_QWWriteShort(int dest, short data)
{
NPP_NQWriteShort(dest, data);
}
void NPP_QWWriteLong(int dest, long data)
{
NPP_NQWriteLong(dest, data);
}
void NPP_QWWriteAngle(int dest, float data)
{
NPP_NQWriteAngle(dest, data);
}
void NPP_QWWriteCoord(int dest, float data)
{
NPP_NQWriteCoord(dest, data);
}
void NPP_QWWriteString(int dest, char *data)
{
NPP_NQWriteString(dest, data);
}
void NPP_QWWriteEntity(int dest, short data)
{
NPP_NQWriteEntity(dest, data);
}
static enum protocol_type pp_svc_temp_entity_beam[] = {PPT_BYTE, PPT_BYTE, PPT_ENT, PPT_POS, PPT_POS};
static void pp_svc_temp_entity_beam_flush(client_t *cl, sizebuf_t *msg, enum protocol_type *pt, union protocol_data *pd)
{
MSG_WriteByte(msg, pd[0].id);
MSG_WriteByte(msg, pd[1].id);
MSG_WriteShort(msg, pd[2].id);
MSG_WriteCoord(msg, pd[3].fd);
MSG_WriteCoord(msg, pd[4].fd);
MSG_WriteCoord(msg, pd[5].fd);
MSG_WriteCoord(msg, pd[6].fd);
MSG_WriteCoord(msg, pd[7].fd);
MSG_WriteCoord(msg, pd[8].fd);
}
static qboolean pp_svc_temp_entity_beam_decide(enum protocol_type *pt, union protocol_data *pd)
{
vec3_t org;
org[0] = pd[3].fd;
org[1] = pd[4].fd;
org[2] = pd[5].fd;
pp_flush(MULTICAST_PHS, org, pp_svc_temp_entity_beam_flush, pt, pd);
return true;
}
static void pp_svc_temp_entity_gunshot_flush(client_t *cl, sizebuf_t *msg, enum protocol_type *pt, union protocol_data *pd)
{
int offset = (progstype == PROG_QW)?3:2;
int count = (offset == 3)?pd[2].id:1;
while (count > 0)
{
MSG_WriteByte(msg, pd[0].id);
MSG_WriteByte(msg, pd[1].id);
if (cl->protocol == SCP_QUAKEWORLD)
{
if (count > 255)
{
MSG_WriteByte(msg, 255);
count-=255;
}
else
{
MSG_WriteByte(msg, count);
count = 0;
}
}
else
count--;
MSG_WriteCoord(msg, pd[offset+0].fd);
MSG_WriteCoord(msg, pd[offset+1].fd);
MSG_WriteCoord(msg, pd[offset+2].fd);
}
}
static qboolean pp_svc_temp_entity_gunshot(enum protocol_type *pt, union protocol_data *pd)
{
vec3_t org;
int offset = (progstype == PROG_QW)?3:2;
org[0] = pd[offset+0].fd;
org[1] = pd[offset+1].fd;
org[2] = pd[offset+2].fd;
pp_flush(MULTICAST_PHS, org, pp_svc_temp_entity_gunshot_flush, pt, pd);
return true;
}
static qboolean pp_decide_pvs_2(enum protocol_type *pt, union protocol_data *pd)
{
vec3_t org;
org[0] = pd[2].fd;
org[1] = pd[3].fd;
org[2] = pd[4].fd;
pp_flush(MULTICAST_PVS, org, pp_identity_flush, pt, pd);
return true;
}
static qboolean pp_decide_phs_2(enum protocol_type *pt, union protocol_data *pd)
{
vec3_t org;
org[0] = pd[2].fd;
org[1] = pd[3].fd;
org[2] = pd[4].fd;
pp_flush(MULTICAST_PHS, org, pp_identity_flush, pt, pd);
return true;
}
static enum protocol_type pp_svc_temp_entity[] = {PPT_BYTE, PPT_BYTE};
static qboolean pp_svc_temp_entity_decide(enum protocol_type *pt, union protocol_data *pd)
{
switch(pd[1].id)
{
case TE_LIGHTNING1:
case TE_LIGHTNING2:
case TE_LIGHTNING3:
DECIDE(pp_svc_temp_entity_beam);
return true;
case TE_EXPLOSION:
case TEDP_EXPLOSIONQUAD:
case TE_SPIKE:
case TE_SUPERSPIKE:
case TEDP_SPIKEQUAD:
case TEDP_SUPERSPIKEQUAD:
case TEDP_SMALLFLASH:
{
static enum protocol_type fmt[] = {PPT_BYTE, PPT_BYTE, PPT_POS};
DECIDE2(fmt, pp_decide_phs_2);
}
return true;
case TEDP_GUNSHOTQUAD:
case TE_TAREXPLOSION:
case TE_WIZSPIKE:
case TE_KNIGHTSPIKE:
case TE_LAVASPLASH:
case TE_TELEPORT:
{
static enum protocol_type fmt[] = {PPT_BYTE, PPT_BYTE, PPT_POS};
DECIDE2(fmt, pp_decide_pvs_2);
}
return true;
case TE_GUNSHOT:
if (progstype == PROG_QW)
{
static enum protocol_type fmt[] = {PPT_BYTE, PPT_BYTE, PPT_BYTE, PPT_POS};
DECIDE2(fmt, pp_svc_temp_entity_gunshot);
}
else
{
static enum protocol_type fmt[] = {PPT_BYTE, PPT_BYTE, PPT_POS};
DECIDE2(fmt, pp_svc_temp_entity_gunshot);
}
return true;
case 12:
if (progstype == PROG_QW)
{
/*TEQW_BLOOD*/
}
else
{
/*TENQ_EXPLOSION2*/
}
return false;
case 13:
if (progstype == PROG_QW)
{
/*TEQW_LIGHTNINGBLOOD*/
}
else
{
/*TENQ_BEAM*/
}
return false;
case TEDP_BLOOD:
case TEDP_SPARK:
{
static enum protocol_type fmt[] = {PPT_BYTE, PPT_BYTE, PPT_POS, PPT_BYTE,PPT_BYTE,PPT_BYTE, PPT_BYTE};
DECIDE2(fmt, pp_decide_pvs_2);
}
return true;
case TE_BULLET:
case TE_SUPERBULLET:
case TE_RAILTRAIL:
// hexen 2
case TEH2_STREAM_CHAIN:
case TEH2_STREAM_SUNSTAFF1:
case TEH2_STREAM_SUNSTAFF2:
case TEH2_STREAM_LIGHTNING:
case TEH2_STREAM_COLORBEAM:
case TEH2_STREAM_ICECHUNKS:
case TEH2_STREAM_GAZE:
case TEH2_STREAM_FAMINE:
case TEDP_BLOODSHOWER:
case TEDP_EXPLOSIONRGB:
case TEDP_PARTICLECUBE:
case TEDP_PARTICLERAIN: // [vector] min [vector] max [vector] dir [short] count [byte] color
case TEDP_PARTICLESNOW: // [vector] min [vector] max [vector] dir [short] count [byte] color
case TEDP_CUSTOMFLASH:
case TEDP_FLAMEJET:
case TEDP_PLASMABURN:
case TEDP_TEI_G3:
case TEDP_SMOKE:
case TEDP_TEI_BIGEXPLOSION:
case TEDP_TEI_PLASMAHIT:
default:
return false;
}
}
qboolean pp_root_decide(enum protocol_type *pt, union protocol_data *pd)
{
switch (pd[0].id)
{
case svc_temp_entity:
DECIDE(pp_svc_temp_entity);
return true;
default:
return false;
}
}
#else
static sizebuf_t *writedest; static sizebuf_t *writedest;
static client_t *cldest; static client_t *cldest;
@ -194,12 +752,12 @@ void NPP_NQFlush(void)
vec3_t org; vec3_t org;
coorddata cd; coorddata cd;
memcpy(&cd, &buffer[multicastpos+sizeofcoord*0], sizeofcoord); memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*0], writedest->prim.coordsize);
org[0] = MSG_FromCoord(cd, sizeofcoord); org[0] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+sizeofcoord*1], sizeofcoord); memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*1], writedest->prim.coordsize);
org[1] = MSG_FromCoord(cd, sizeofcoord); org[1] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+sizeofcoord*2], sizeofcoord); memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*2], writedest->prim.coordsize);
org[2] = MSG_FromCoord(cd, sizeofcoord); org[2] = MSG_FromCoord(cd, writedest->prim.coordsize);
SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, requireextension, 0); SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, requireextension, 0);
} }
@ -360,7 +918,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
switch(majortype) switch(majortype)
{ {
case svc_sound: case svc_sound:
protocollen = 5+sizeofcoord*3; protocollen = 5+writedest->prim.coordsize*3;
if (data & NQSND_VOLUME) if (data & NQSND_VOLUME)
protocollen++; protocollen++;
if (data & NQSND_ATTENUATION) if (data & NQSND_ATTENUATION)
@ -383,7 +941,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_LIGHTNING3: case TE_LIGHTNING3:
multicastpos=4; multicastpos=4;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
protocollen = sizeofcoord*6+sizeof(short)+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*2;
break; break;
case TE_GUNSHOT: case TE_GUNSHOT:
multicastpos=3; multicastpos=3;
@ -392,14 +950,14 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
//emit it here and we don't need to remember to play with temp_entity later //emit it here and we don't need to remember to play with temp_entity later
NPP_AddData(&data, sizeof(qbyte)); NPP_AddData(&data, sizeof(qbyte));
data = 1; data = 1;
protocollen = sizeofcoord*3+sizeof(qbyte)*3; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*3;
break; break;
case TE_EXPLOSION: case TE_EXPLOSION:
case TE_SPIKE: case TE_SPIKE:
case TE_SUPERSPIKE: case TE_SUPERSPIKE:
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PHS_R; multicasttype=MULTICAST_PHS_R;
protocollen = sizeofcoord*3+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
break; break;
case TE_TAREXPLOSION: case TE_TAREXPLOSION:
case TE_WIZSPIKE: case TE_WIZSPIKE:
@ -408,25 +966,25 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_TELEPORT: case TE_TELEPORT:
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PVS; multicasttype=MULTICAST_PVS;
protocollen = sizeofcoord*3+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
break; break;
case TE_EXPLOSION3_NEH: case TE_EXPLOSION3_NEH:
protocollen = sizeof(qbyte) + sizeofcoord*6; protocollen = sizeof(qbyte) + writedest->prim.coordsize*6;
ignoreprotocol = true; ignoreprotocol = true;
break; break;
case TENQ_EXPLOSION2: case TENQ_EXPLOSION2:
protocollen = sizeof(qbyte)*4 + sizeofcoord*3; protocollen = sizeof(qbyte)*4 + writedest->prim.coordsize*3;
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PHS_R; multicasttype=MULTICAST_PHS_R;
break; break;
case TE_EXPLOSIONSMALL2: case TE_EXPLOSIONSMALL2:
data = TE_EXPLOSION; data = TE_EXPLOSION;
protocollen = sizeof(qbyte)*2 + sizeofcoord*3; protocollen = sizeof(qbyte)*2 + writedest->prim.coordsize*3;
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case TE_RAILTRAIL: case TE_RAILTRAIL:
protocollen = sizeofcoord*6+sizeof(qbyte)*1; protocollen = writedest->prim.coordsize*6+sizeof(qbyte)*1;
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
@ -437,42 +995,42 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TEH2_STREAM_ICECHUNKS: case TEH2_STREAM_ICECHUNKS:
case TEH2_STREAM_GAZE: case TEH2_STREAM_GAZE:
case TEH2_STREAM_FAMINE: case TEH2_STREAM_FAMINE:
protocollen = sizeofcoord*6+sizeof(short)+sizeof(qbyte)*(2+2); protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*(2+2);
multicastpos = 8; multicastpos = 8;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case TEH2_STREAM_COLORBEAM: case TEH2_STREAM_COLORBEAM:
protocollen = sizeofcoord*6+sizeof(short)+sizeof(qbyte)*(3+2); protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*(3+2);
multicastpos = 8; multicastpos = 8;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case TEDP_FLAMEJET: //TE_FLAMEJET case TEDP_FLAMEJET: //TE_FLAMEJET
protocollen = sizeofcoord*6 +sizeof(qbyte)*3; protocollen = writedest->prim.coordsize*6 +sizeof(qbyte)*3;
multicastpos = 2; multicastpos = 2;
multicasttype=MULTICAST_PVS; multicasttype=MULTICAST_PVS;
break; break;
case TEDP_TEI_G3: case TEDP_TEI_G3:
protocollen = sizeofcoord*9+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*9+sizeof(qbyte)*2;
multicastpos = 2; multicastpos = 2;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case TEDP_SMOKE: case TEDP_SMOKE:
protocollen = sizeofcoord*6+sizeof(qbyte)*3; protocollen = writedest->prim.coordsize*6+sizeof(qbyte)*3;
multicastpos = 2; multicastpos = 2;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case TEDP_TEI_BIGEXPLOSION: case TEDP_TEI_BIGEXPLOSION:
protocollen = sizeofcoord*3+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
multicastpos = 2; multicastpos = 2;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case TEDP_TEI_PLASMAHIT: case TEDP_TEI_PLASMAHIT:
protocollen = sizeofcoord*6+sizeof(qbyte)*3; protocollen = writedest->prim.coordsize*6+sizeof(qbyte)*3;
multicastpos = 2; multicastpos = 2;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
@ -647,7 +1205,7 @@ void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
MSG_WriteCoord (NQWriteDest(dest), in); MSG_WriteCoord (NQWriteDest(dest), in);
#endif #endif
if (sizeofcoord==4) if (writedest->prim.coordsize==4)
{ {
dataf = LittleFloat(dataf); dataf = LittleFloat(dataf);
NPP_AddData(&dataf, sizeof(float)); NPP_AddData(&dataf, sizeof(float));
@ -933,7 +1491,7 @@ void NPP_QWFlush(void)
NPP_AddData(&svc, sizeof(qbyte)); NPP_AddData(&svc, sizeof(qbyte));
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
if (sizeofcoord == 4) if (writedest->prim.coordsize == 4)
NPP_AddData(&org[i], sizeof(float)); NPP_AddData(&org[i], sizeof(float));
else else
{ {
@ -991,12 +1549,12 @@ void NPP_QWFlush(void)
vec3_t org; vec3_t org;
coorddata cd; coorddata cd;
memcpy(&cd, &buffer[multicastpos+sizeofcoord*0], sizeofcoord); memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*0], writedest->prim.coordsize);
org[0] = MSG_FromCoord(cd, sizeofcoord); org[0] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+sizeofcoord*1], sizeofcoord); memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*1], writedest->prim.coordsize);
org[1] = MSG_FromCoord(cd, sizeofcoord); org[1] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+sizeofcoord*2], sizeofcoord); memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*2], writedest->prim.coordsize);
org[2] = MSG_FromCoord(cd, sizeofcoord); org[2] = MSG_FromCoord(cd, writedest->prim.coordsize);
qwsize = sv.multicast.cursize; qwsize = sv.multicast.cursize;
sv.multicast.cursize = 0; sv.multicast.cursize = 0;
@ -1167,13 +1725,13 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_LIGHTNING3: case TE_LIGHTNING3:
multicastpos=4; multicastpos=4;
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
protocollen = sizeofcoord*6+sizeof(short)+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*2;
break; break;
case TEQW_BLOOD: //needs to be converted to a particle case TEQW_BLOOD: //needs to be converted to a particle
case TE_GUNSHOT: //needs qbyte 2 removed case TE_GUNSHOT: //needs qbyte 2 removed
multicastpos=3; multicastpos=3;
multicasttype=MULTICAST_PVS; multicasttype=MULTICAST_PVS;
protocollen = sizeofcoord*3+sizeof(qbyte)*3; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*3;
break; break;
case TEQW_LIGHTNINGBLOOD: case TEQW_LIGHTNINGBLOOD:
case TE_EXPLOSION: case TE_EXPLOSION:
@ -1181,7 +1739,7 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_SUPERSPIKE: case TE_SUPERSPIKE:
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PHS_R; multicasttype=MULTICAST_PHS_R;
protocollen = sizeofcoord*3+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
break; break;
case TE_TAREXPLOSION: case TE_TAREXPLOSION:
case TE_WIZSPIKE: case TE_WIZSPIKE:
@ -1190,12 +1748,12 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_TELEPORT: case TE_TELEPORT:
multicastpos=2; multicastpos=2;
multicasttype=MULTICAST_PVS; multicasttype=MULTICAST_PVS;
protocollen = sizeofcoord*3+sizeof(qbyte)*2; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
break; break;
case TE_RAILTRAIL: case TE_RAILTRAIL:
multicastpos=1; multicastpos=1;
multicasttype=MULTICAST_PVS; multicasttype=MULTICAST_PVS;
protocollen = sizeofcoord*3+sizeof(qbyte)*1; protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*1;
break; break;
default: default:
protocollen = sizeof(buffer); protocollen = sizeof(buffer);
@ -1260,7 +1818,7 @@ void NPP_QWWriteLong(int dest, long data) //replacement write func (nq to qw)
} }
void NPP_QWWriteAngle(int dest, float in) //replacement write func (nq to qw) void NPP_QWWriteAngle(int dest, float in) //replacement write func (nq to qw)
{ {
if (sizeofangle==1) if (writedest->prim.anglesize==1)
{ {
char data = (int)(in*256/360) & 255; char data = (int)(in*256/360) & 255;
NPP_QWWriteChar(dest, data); NPP_QWWriteChar(dest, data);
@ -1273,7 +1831,7 @@ void NPP_QWWriteAngle(int dest, float in) //replacement write func (nq to qw)
} }
void NPP_QWWriteCoord(int dest, float in) //replacement write func (nq to qw) void NPP_QWWriteCoord(int dest, float in) //replacement write func (nq to qw)
{ {
if (sizeofcoord==4) if (writedest->prim.coordsize==4)
{ {
NPP_QWWriteFloat(dest, in); NPP_QWWriteFloat(dest, in);
} }
@ -2318,3 +2876,4 @@ void NPP_Flush(void)
#endif #endif
} }
#endif #endif
#endif

View file

@ -62,7 +62,7 @@ cvar_t pr_maxedicts = SCVARF("pr_maxedicts", "2048", CVAR_LATCH);
cvar_t pr_no_playerphysics = SCVARF("pr_no_playerphysics", "0", CVAR_LATCH); cvar_t pr_no_playerphysics = SCVARF("pr_no_playerphysics", "0", CVAR_LATCH);
cvar_t progs = SCVARF("progs", "", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_NOTFROMSERVER); cvar_t progs = CVARAF("progs", "", "sv_progs", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_NOTFROMSERVER);
cvar_t qc_nonetaccess = SCVAR("qc_nonetaccess", "0"); //prevent write_... builtins from doing anything. This means we can run any mod, specific to any engine, on the condition that it also has a qw or nq crc. cvar_t qc_nonetaccess = SCVAR("qc_nonetaccess", "0"); //prevent write_... builtins from doing anything. This means we can run any mod, specific to any engine, on the condition that it also has a qw or nq crc.
cvar_t pr_overridebuiltins = SCVAR("pr_overridebuiltins", "1"); cvar_t pr_overridebuiltins = SCVAR("pr_overridebuiltins", "1");
@ -764,7 +764,7 @@ progsnum_t AddProgs(char *name)
} }
} }
} }
sv.world.usesolidcorpse = (progstype != PROG_H2);
if (num != -1) if (num != -1)
{ {
PR_LoadGlabalStruct(); PR_LoadGlabalStruct();
@ -1725,7 +1725,55 @@ char *Translate(char *message);
*/ */
static void SV_Effect(vec3_t org, int mdlidx, int startframe, int endframe, int framerate)
{
if (startframe>255 || mdlidx>255)
{
MSG_WriteByte (&sv.multicast, svcfte_effect2);
MSG_WriteCoord (&sv.multicast, org[0]);
MSG_WriteCoord (&sv.multicast, org[1]);
MSG_WriteCoord (&sv.multicast, org[2]);
MSG_WriteShort (&sv.multicast, mdlidx);
MSG_WriteShort (&sv.multicast, startframe);
MSG_WriteByte (&sv.multicast, endframe);
MSG_WriteByte (&sv.multicast, framerate);
#ifdef NQPROT
MSG_WriteByte (&sv.nqmulticast, svcnq_effect2);
MSG_WriteCoord (&sv.nqmulticast, org[0]);
MSG_WriteCoord (&sv.nqmulticast, org[1]);
MSG_WriteCoord (&sv.nqmulticast, org[2]);
MSG_WriteShort (&sv.nqmulticast, mdlidx);
MSG_WriteShort (&sv.nqmulticast, startframe);
MSG_WriteByte (&sv.nqmulticast, endframe);
MSG_WriteByte (&sv.nqmulticast, framerate);
#endif
}
else
{
MSG_WriteByte (&sv.multicast, svcfte_effect);
MSG_WriteCoord (&sv.multicast, org[0]);
MSG_WriteCoord (&sv.multicast, org[1]);
MSG_WriteCoord (&sv.multicast, org[2]);
MSG_WriteByte (&sv.multicast, mdlidx);
MSG_WriteByte (&sv.multicast, startframe);
MSG_WriteByte (&sv.multicast, endframe);
MSG_WriteByte (&sv.multicast, framerate);
#ifdef NQPROT
MSG_WriteByte (&sv.nqmulticast, svcnq_effect);
MSG_WriteCoord (&sv.nqmulticast, org[0]);
MSG_WriteCoord (&sv.nqmulticast, org[1]);
MSG_WriteCoord (&sv.nqmulticast, org[2]);
MSG_WriteByte (&sv.nqmulticast, mdlidx);
MSG_WriteByte (&sv.nqmulticast, startframe);
MSG_WriteByte (&sv.nqmulticast, endframe);
MSG_WriteByte (&sv.nqmulticast, framerate);
#endif
}
SV_Multicast(org, MULTICAST_PVS);
}
@ -1792,11 +1840,21 @@ static void PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_globals)
(*prinst->pr_trace) = 2; (*prinst->pr_trace) = 2;
else else
{ {
ED_Free (prinst, ed); Con_Printf("Program error: %s\n", s);
if (developer.value)
prinst->AbortStack(prinst); {
struct globalvars_s *pr_globals = PR_globals(prinst, PR_CURRENT);
PR_BIError (prinst, "Program error: %s", s); *prinst->pr_trace = 1;
G_INT(OFS_RETURN)=0; //just in case it was a float and should be an ent...
G_INT(OFS_RETURN+1)=0;
G_INT(OFS_RETURN+2)=0;
}
else
{
ED_Free (prinst, ed);
PR_StackTrace(prinst);
PR_AbortStack(prinst);
}
if (sv.time > 10) if (sv.time > 10)
Cbuf_AddText("restart\n", RESTRICT_LOCAL); Cbuf_AddText("restart\n", RESTRICT_LOCAL);
@ -2691,7 +2749,7 @@ void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent->xv->hull = savedhull; ent->xv->hull = savedhull;
if (trace.startsolid) if (trace.startsolid)
if (!sv_gameplayfix_honest_tracelines.value) if (!sv_gameplayfix_honest_tracelines.ival)
trace.fraction = 1; trace.fraction = 1;
pr_global_struct->trace_allsolid = trace.allsolid; pr_global_struct->trace_allsolid = trace.allsolid;
@ -2734,7 +2792,7 @@ static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent->xv->hull = savedhull; ent->xv->hull = savedhull;
if (trace.startsolid) if (trace.startsolid)
if (!sv_gameplayfix_honest_tracelines.value) if (!sv_gameplayfix_honest_tracelines.ival)
trace.fraction = 1; trace.fraction = 1;
pr_global_struct->trace_allsolid = trace.allsolid; pr_global_struct->trace_allsolid = trace.allsolid;
@ -2774,7 +2832,7 @@ static void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent->xv->hull = savedhull; ent->xv->hull = savedhull;
if (trace.startsolid) if (trace.startsolid)
if (!sv_gameplayfix_honest_tracelines.value) if (!sv_gameplayfix_honest_tracelines.ival)
trace.fraction = 1; trace.fraction = 1;
pr_global_struct->trace_allsolid = trace.allsolid; pr_global_struct->trace_allsolid = trace.allsolid;
@ -4645,59 +4703,42 @@ int SV_ModelIndex (char *name);
void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
edict_t *ent; edict_t *ent;
int mdlindex, i; int mdlindex;
entity_state_t *state; entity_state_t *state;
ent = G_EDICT(prinst, OFS_PARM0); ent = G_EDICT(prinst, OFS_PARM0);
SV_FlushSignon ();
mdlindex = SV_ModelIndex(PR_GetString(prinst, ent->v->model)); mdlindex = SV_ModelIndex(PR_GetString(prinst, ent->v->model));
if (ent->xv->drawflags || ent->xv->alpha || mdlindex > 255 || ent->v->frame > 255 || ent->xv->scale || ent->xv->abslight) if (sv.num_static_entities == sv_max_staticentities)
{ {
if (sv.numextrastatics==sizeof(sv.extendedstatics)/sizeof(sv.extendedstatics[0])) sv_max_staticentities += 16;
return; //fail the whole makestatic thing. sv_staticentities = BZ_Realloc(sv_staticentities, sizeof(*sv_staticentities) * sv_max_staticentities);
state = &sv.extendedstatics[sv.numextrastatics++];
memset(state, 0, sizeof(*state));
state->number = sv.numextrastatics;
state->flags = 0;
VectorCopy (ent->v->origin, state->origin);
VectorCopy (ent->v->angles, state->angles);
state->modelindex = mdlindex;//ent->v->modelindex;
state->frame = ent->v->frame;
state->colormap = ent->v->colormap;
state->skinnum = ent->v->skin;
state->effects = ent->v->effects;
state->hexen2flags = ent->xv->drawflags;
state->abslight = (int)(ent->xv->abslight*255) & 255;
state->trans = ent->xv->alpha*255;
if (!ent->xv->alpha)
state->trans = 255;
state->fatness = ent->xv->fatness;
state->scale = ent->xv->scale*16.0;
if (!ent->xv->scale)
state->scale = 1*16;
if (progstype != PROG_QW) //don't send extra nq effects to a qw client.
state->effects &= EF_BRIGHTLIGHT | EF_DIMLIGHT;
} }
else
{
MSG_WriteByte (&sv.signon,svc_spawnstatic);
MSG_WriteByte (&sv.signon, mdlindex&255); state = &sv_staticentities[sv.num_static_entities++];
memset(state, 0, sizeof(*state));
state->number = sv.num_static_entities;
state->flags = 0;
VectorCopy (ent->v->origin, state->origin);
VectorCopy (ent->v->angles, state->angles);
state->modelindex = mdlindex;//ent->v->modelindex;
state->frame = ent->v->frame;
state->colormap = ent->v->colormap;
state->skinnum = ent->v->skin;
state->effects = ent->v->effects;
state->hexen2flags = ent->xv->drawflags;
state->abslight = (int)(ent->xv->abslight*255) & 255;
state->trans = ent->xv->alpha*255;
if (!ent->xv->alpha)
state->trans = 255;
state->fatness = ent->xv->fatness;
state->scale = ent->xv->scale*16.0;
if (!ent->xv->scale)
state->scale = 1*16;
MSG_WriteByte (&sv.signon, ent->v->frame); if (progstype != PROG_QW) //don't send extra nq effects to a qw client.
MSG_WriteByte (&sv.signon, (int)ent->v->colormap); state->effects &= EF_BRIGHTLIGHT | EF_DIMLIGHT;
MSG_WriteByte (&sv.signon, (int)ent->v->skin);
for (i=0 ; i<3 ; i++)
{
MSG_WriteCoord(&sv.signon, ent->v->origin[i]);
MSG_WriteAngle(&sv.signon, ent->v->angles[i]);
}
}
// throw the entity away now // throw the entity away now
ED_Free (svprogfuncs, ent); ED_Free (svprogfuncs, ent);
@ -7096,7 +7137,91 @@ void PF_h2matchAngleToSlope(progfuncs_t *prinst, struct globalvars_s *pr_globals
void PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
Con_DPrintf("Start effect %i\n", (int)G_FLOAT(OFS_PARM0)); switch((int)G_FLOAT(OFS_PARM0))
{
case 4:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/whtsmk1.spr"), 0, 5, 20);
break;
case 6:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/spark.spr"), 0, 10, 20);
break;
case 7:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/fcircle.spr"), 0, 6, 20);
break;
case 9:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/sm_white.spr"), 0, 3, 20);
break;
case 11:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/yr_flash.spr"), 0, 21, 20);
break;
case 13:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/bluflash.spr"), 0, 5, 20);
break;
case 14:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/redspt.spr"), 0, 5, 20);
break;
case 15:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/sm_expld.spr"), 0, 12, 20);
break;
case 16:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/bg_expld.spr"), 0, 12, 20);
break;
case 17:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/fl_expld.spr"), 0, 20, 20);
break;
case 24:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/rspark.spr"), 0, 10, 20);
break;
case 25:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/gspark.spr"), 0, 10, 20);
break;
case 26:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/telesmk1.spr"), 0, 4, 20);
break;
case 28:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/icehit.spr"), 0, 6, 20);
break;
case 33:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/gen_expl.spr"), 0, 14, 20);
break;
case 34:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/mm_explod.spr"), 0, 50, 20);
break;
case 42:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/flamestr.spr"), 0, 12, 20);
break;
case 45:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/xplsn_1.spr"), 0, 7, 20);
break;
case 47:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/axplsn_2.spr"), 0, 14, 20);
break;
case 48:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/firewal1.spr"), 0, 18, 20);
break;
case 49:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/firewal5.spr"), 0, 30, 20);
break;
case 50:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/firewal4.spr"), 0, 29, 20);
break;
case 56:
SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/pow.spr"), 0, 6, 20);
break;
case 40:
// SV_Effect(G_VECTOR(OFS_PARM1), PF_precache_model_Internal(prinst, "models/boneshot.mdl"), 0, 50, 20);
// break;
case 2:
case 55:
Con_DPrintf("Start unsupported effect %i\n", (int)G_FLOAT(OFS_PARM0));
break;
default:
Con_Printf("Start effect %i\n", (int)G_FLOAT(OFS_PARM0));
break;
}
} }
void PF_h2endeffect(progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_h2endeffect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -7112,6 +7237,10 @@ void PF_h2StopSound(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
} }
void PF_h2updatesoundpos(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
}
void PF_h2getstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_h2getstring(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *s = T_GetString(G_FLOAT(OFS_PARM0)-1); char *s = T_GetString(G_FLOAT(OFS_PARM0)-1);
@ -7916,52 +8045,7 @@ static void PF_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
float framerate = G_FLOAT(OFS_PARM4); float framerate = G_FLOAT(OFS_PARM4);
int index = SV_ModelIndex(name); int index = SV_ModelIndex(name);
if (startframe>255 || index>255) SV_Effect(org, index, startframe, endframe, framerate);
{
MSG_WriteByte (&sv.multicast, svcfte_effect2);
MSG_WriteCoord (&sv.multicast, org[0]);
MSG_WriteCoord (&sv.multicast, org[1]);
MSG_WriteCoord (&sv.multicast, org[2]);
MSG_WriteShort (&sv.multicast, index);
MSG_WriteShort (&sv.multicast, startframe);
MSG_WriteByte (&sv.multicast, endframe);
MSG_WriteByte (&sv.multicast, framerate);
#ifdef NQPROT
MSG_WriteByte (&sv.nqmulticast, svcnq_effect2);
MSG_WriteCoord (&sv.nqmulticast, org[0]);
MSG_WriteCoord (&sv.nqmulticast, org[1]);
MSG_WriteCoord (&sv.nqmulticast, org[2]);
MSG_WriteShort (&sv.nqmulticast, index);
MSG_WriteShort (&sv.nqmulticast, startframe);
MSG_WriteByte (&sv.nqmulticast, endframe);
MSG_WriteByte (&sv.nqmulticast, framerate);
#endif
}
else
{
MSG_WriteByte (&sv.multicast, svcfte_effect);
MSG_WriteCoord (&sv.multicast, org[0]);
MSG_WriteCoord (&sv.multicast, org[1]);
MSG_WriteCoord (&sv.multicast, org[2]);
MSG_WriteByte (&sv.multicast, index);
MSG_WriteByte (&sv.multicast, startframe);
MSG_WriteByte (&sv.multicast, endframe);
MSG_WriteByte (&sv.multicast, framerate);
#ifdef NQPROT
MSG_WriteByte (&sv.nqmulticast, svcnq_effect);
MSG_WriteCoord (&sv.nqmulticast, org[0]);
MSG_WriteCoord (&sv.nqmulticast, org[1]);
MSG_WriteCoord (&sv.nqmulticast, org[2]);
MSG_WriteByte (&sv.nqmulticast, index);
MSG_WriteByte (&sv.nqmulticast, startframe);
MSG_WriteByte (&sv.nqmulticast, endframe);
MSG_WriteByte (&sv.nqmulticast, framerate);
#endif
}
SV_Multicast(org, MULTICAST_PVS);
} }
//DP_TE_PLASMABURN //DP_TE_PLASMABURN
@ -8475,7 +8559,12 @@ void PF_sv_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals)
return; return;
} }
#pragma message("This function doesn't honour attachments") if (ent->xv->tag_entity)
{
#pragma message("PF_sv_gettaginfo: This function doesn't honour attachments")
Con_Printf("PF_sv_gettaginfo doesn't support attachments\n");
}
EdictToTransform(ent, transent); EdictToTransform(ent, transent);
R_ConcatTransforms((void*)transent, (void*)transtag, (void*)result); R_ConcatTransforms((void*)transent, (void*)transtag, (void*)result);
@ -9194,6 +9283,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"precache_sound4", PF_precache_sound, 0, 0, 101, 0}, {"precache_sound4", PF_precache_sound, 0, 0, 101, 0},
{"precache_model4", PF_precache_model, 0, 0, 102, 0}, {"precache_model4", PF_precache_model, 0, 0, 102, 0},
{"precache_file4", PF_precache_file, 0, 0, 103, 0}, {"precache_file4", PF_precache_file, 0, 0, 103, 0},
{"dowhiteflash", PF_Fixme, 0, 0, 104, 0},
{"updatesoundpos", PF_h2updatesoundpos,0, 0, 105, 0},
{"stopsound", PF_h2StopSound, 0, 0, 106, 0}, {"stopsound", PF_h2StopSound, 0, 0, 106, 0},
{"precache_model4", PF_precache_model, 0, 0, 116, 0},//please don't use... {"precache_model4", PF_precache_model, 0, 0, 116, 0},//please don't use...

View file

@ -458,7 +458,7 @@ static eval_t *Q1QVMPF_GetEdictFieldValue(progfuncs_t *pf, edict_t *e, char *fie
{ {
if (!strcmp(fieldname, "message")) if (!strcmp(fieldname, "message"))
{ {
return (eval_t*)&e->v->message; return (eval_t*)&e->v->_message;
} }
return NULL; return NULL;
} }
@ -1452,6 +1452,7 @@ qboolean PR_LoadQ1QVM(void)
sv.world.progs = &q1qvmprogfuncs; sv.world.progs = &q1qvmprogfuncs;
sv.world.edicts = (wedict_t*)EDICT_NUM(svprogfuncs, 0); sv.world.edicts = (wedict_t*)EDICT_NUM(svprogfuncs, 0);
sv.world.usesolidcorpse = true;
return true; return true;
} }

View file

@ -181,7 +181,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldentity(dmg_inflictor,_dmg_inflictor,_dmg_inflictor);\ comfieldentity(dmg_inflictor,_dmg_inflictor,_dmg_inflictor);\
comfieldentity(owner,owner,owner);\ comfieldentity(owner,owner,owner);\
comfieldvector(movedir,movedir,movedir);\ comfieldvector(movedir,movedir,movedir);\
comfieldstring(message,_message,_message); /*not used directly, hexen2 uses floats, so we go via qclib for message*/\ comfieldstring(_message,_message,_message); /*not used directly, hexen2 uses floats, so we go via qclib for message*/\
comfieldfloat(sounds,_sounds,_sounds);\ comfieldfloat(sounds,_sounds,_sounds);\
comfieldstring(_noise,_noise,_noise);\ comfieldstring(_noise,_noise,_noise);\
comfieldstring(_noise1,_noise1,_noise1);\ comfieldstring(_noise1,_noise1,_noise1);\

View file

@ -103,6 +103,9 @@ typedef struct
char fatness; char fatness;
} mvdentity_state_t; } mvdentity_state_t;
extern entity_state_t *sv_staticentities;
extern int sv_max_staticentities;
typedef struct typedef struct
{ {
qboolean active; // false when server is going down qboolean active; // false when server is going down
@ -160,7 +163,7 @@ typedef struct
// the multicast buffer is used to send a message to a set of clients // the multicast buffer is used to send a message to a set of clients
sizebuf_t multicast; sizebuf_t multicast;
qbyte multicast_buf[MAX_NQMSGLEN]; qbyte multicast_buf[MAX_QWMSGLEN];
#ifdef NQPROT #ifdef NQPROT
sizebuf_t nqdatagram; sizebuf_t nqdatagram;
@ -264,8 +267,7 @@ typedef struct
#endif #endif
//==================================================== //====================================================
entity_state_t extendedstatics[MAX_STATIC_ENTITIES]; int num_static_entities;
int numextrastatics;
// movevars_t demomovevars; //FIXME:! // movevars_t demomovevars; //FIXME:!
//end this lot... (demo playback) //end this lot... (demo playback)
@ -499,6 +501,7 @@ typedef struct client_s
unsigned long fteprotocolextensions2; unsigned long fteprotocolextensions2;
#endif #endif
unsigned long zquake_extensions; unsigned long zquake_extensions;
unsigned int max_net_ents;
enum { enum {
SCP_BAD, //don't send (a bot) SCP_BAD, //don't send (a bot)
@ -756,6 +759,7 @@ typedef struct
unsigned long fteprotocolextensions; unsigned long fteprotocolextensions;
unsigned long fteprotocolextensions2; unsigned long fteprotocolextensions2;
#endif #endif
struct netprim_s netprim;
qboolean demoplayback; qboolean demoplayback;
qboolean demorecording; qboolean demorecording;
@ -892,6 +896,7 @@ extern netadr_t master_adr[MAX_MASTERS]; // address of the master server
extern cvar_t spawn; extern cvar_t spawn;
extern cvar_t teamplay; extern cvar_t teamplay;
extern cvar_t deathmatch; extern cvar_t deathmatch;
extern cvar_t coop;
extern cvar_t fraglimit; extern cvar_t fraglimit;
extern cvar_t timelimit; extern cvar_t timelimit;
@ -971,6 +976,7 @@ void SV_BuildClientFrame (client_t *client);
void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg); void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg);
#ifdef Q2SERVER #ifdef Q2SERVER
void MSGQ2_WriteDeltaEntity (q2entity_state_t *from, q2entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean newentity); void MSGQ2_WriteDeltaEntity (q2entity_state_t *from, q2entity_state_t *to, sizebuf_t *msg, qboolean force, qboolean newentity);
void SVQ2_BuildBaselines(void);
#endif #endif
//q3 stuff //q3 stuff

View file

@ -437,7 +437,7 @@ void SV_Map_f (void)
nextserver = 0; nextserver = 0;
#ifndef SERVERONLY #ifndef SERVERONLY
if (!Renderer_Started()) if (!Renderer_Started() && !isDedicated)
{ {
Cbuf_AddText(va("wait;map %s\n", Cmd_Args()), Cmd_ExecLevel); Cbuf_AddText(va("wait;map %s\n", Cmd_Args()), Cmd_ExecLevel);
return; return;
@ -1374,6 +1374,7 @@ void SV_Status_f (void)
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
int columns = 80; int columns = 80;
extern cvar_t sv_listen_qw, sv_listen_nq, sv_listen_dp, sv_listen_q3;
if (sv_redirected != RD_OBLIVION && (sv_redirected != RD_NONE if (sv_redirected != RD_OBLIVION && (sv_redirected != RD_NONE
#ifndef SERVERONLY #ifndef SERVERONLY
@ -1414,6 +1415,7 @@ void SV_Status_f (void)
if (sv.csqcdebug) if (sv.csqcdebug)
Con_Printf("csqc debug : true\n"); Con_Printf("csqc debug : true\n");
Con_Printf("public : %s\n", sv_public.value?"yes":"no"); Con_Printf("public : %s\n", sv_public.value?"yes":"no");
Con_Printf("client types :%s%s%s%s\n", sv_listen_qw.ival?" QW":"", sv_listen_nq.ival?" NQ":"", sv_listen_dp.ival?" DP":"", sv_listen_q3.ival?" Q3":"");
// min fps lat drp // min fps lat drp
if (columns < 80) if (columns < 80)

View file

@ -275,6 +275,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg)
csqcmsgbuffer.data = messagebuffer; csqcmsgbuffer.data = messagebuffer;
csqcmsgbuffer.maxsize = sizeof(messagebuffer); csqcmsgbuffer.maxsize = sizeof(messagebuffer);
csqcmsgbuffer.packing = msg->packing; csqcmsgbuffer.packing = msg->packing;
csqcmsgbuffer.prim = msg->prim;
for (en = 0; en < csqcnuments; en++) for (en = 0; en < csqcnuments; en++)
{ {
@ -438,12 +439,12 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
// send an update // send an update
bits = 0; bits = 0;
if (sizeofcoord == 2) if (msg->prim.coordsize == 2)
{ {
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
{ {
coordd[i] = MSG_ToCoord(to->origin[i], sizeofcoord); coordd[i] = MSG_ToCoord(to->origin[i], msg->prim.coordsize);
if (MSG_ToCoord(from->origin[i], sizeofcoord).b4 != coordd[i].b4) if (MSG_ToCoord(from->origin[i], msg->prim.coordsize).b4 != coordd[i].b4)
bits |= U_ORIGIN1<<i; bits |= U_ORIGIN1<<i;
else else
to->origin[i] = from->origin[i]; to->origin[i] = from->origin[i];
@ -453,26 +454,26 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
{ {
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
{ {
coordd[i] = MSG_ToCoord(to->origin[i], sizeofcoord); coordd[i] = MSG_ToCoord(to->origin[i], msg->prim.coordsize);
if (to->origin[i] != from->origin[i]) if (to->origin[i] != from->origin[i])
bits |= U_ORIGIN1<<i; bits |= U_ORIGIN1<<i;
} }
} }
angled[0] = MSG_ToAngle(to->angles[0], sizeofangle); angled[0] = MSG_ToAngle(to->angles[0], msg->prim.anglesize);
if (MSG_ToAngle(from->angles[0], sizeofcoord).b4 != angled[0].b4) if (MSG_ToAngle(from->angles[0], msg->prim.anglesize).b4 != angled[0].b4)
bits |= U_ANGLE1; bits |= U_ANGLE1;
else else
to->angles[0] = from->angles[0]; to->angles[0] = from->angles[0];
angled[1] = MSG_ToAngle(to->angles[1], sizeofangle); angled[1] = MSG_ToAngle(to->angles[1], msg->prim.anglesize);
if (MSG_ToAngle(from->angles[1], sizeofcoord).b4 != angled[1].b4) if (MSG_ToAngle(from->angles[1], msg->prim.anglesize).b4 != angled[1].b4)
bits |= U_ANGLE2; bits |= U_ANGLE2;
else else
to->angles[1] = from->angles[1]; to->angles[1] = from->angles[1];
angled[2] = MSG_ToAngle(to->angles[2], sizeofangle); angled[2] = MSG_ToAngle(to->angles[2], msg->prim.anglesize);
if (MSG_ToAngle(from->angles[2], sizeofcoord).b4 != angled[2].b4) if (MSG_ToAngle(from->angles[2], msg->prim.anglesize).b4 != angled[2].b4)
bits |= U_ANGLE3; bits |= U_ANGLE3;
else else
to->angles[2] = from->angles[2]; to->angles[2] = from->angles[2];
@ -610,17 +611,17 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
if (bits & U_EFFECTS) if (bits & U_EFFECTS)
MSG_WriteByte (msg, to->effects&0x00ff); MSG_WriteByte (msg, to->effects&0x00ff);
if (bits & U_ORIGIN1) if (bits & U_ORIGIN1)
SZ_Write(msg, &coordd[0], sizeofcoord); SZ_Write(msg, &coordd[0], msg->prim.coordsize);
if (bits & U_ANGLE1) if (bits & U_ANGLE1)
SZ_Write(msg, &angled[0], sizeofangle); SZ_Write(msg, &angled[0], msg->prim.anglesize);
if (bits & U_ORIGIN2) if (bits & U_ORIGIN2)
SZ_Write(msg, &coordd[1], sizeofcoord); SZ_Write(msg, &coordd[1], msg->prim.coordsize);
if (bits & U_ANGLE2) if (bits & U_ANGLE2)
SZ_Write(msg, &angled[1], sizeofangle); SZ_Write(msg, &angled[1], msg->prim.anglesize);
if (bits & U_ORIGIN3) if (bits & U_ORIGIN3)
SZ_Write(msg, &coordd[2], sizeofcoord); SZ_Write(msg, &coordd[2], msg->prim.coordsize);
if (bits & U_ANGLE3) if (bits & U_ANGLE3)
SZ_Write(msg, &angled[2], sizeofangle); SZ_Write(msg, &angled[2], msg->prim.anglesize);
#ifdef U_SCALE #ifdef U_SCALE
if (evenmorebits & U_SCALE) if (evenmorebits & U_SCALE)
@ -1104,7 +1105,7 @@ int SV_HullNumForPlayer(int h2hull, float *mins, float *maxs)
} }
if (h2hull) if (h2hull)
return h2hull-1; return h2hull-1 | (mins[2]?0:128);
hullnum = 0; hullnum = 0;
@ -1661,7 +1662,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
#endif #endif
for (j=0,cl=svs.clients ; j<sv.allocated_client_slots ; j++,cl++) for (j=0,cl=svs.clients ; j<sv.allocated_client_slots ; j++,cl++)
{ {
if (cl->state != cs_spawned || (cl->state == cs_free && cl->name[0])) //this includes bots, and nq bots if (cl->state != cs_spawned && !(cl->state == cs_free && cl->name[0])) //this includes bots, and nq bots
continue; continue;
isbot = (!cl->name[0] || cl->protocol == SCP_BAD); isbot = (!cl->name[0] || cl->protocol == SCP_BAD);
@ -1841,45 +1842,6 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
void SVNQ_EmitEntityState(sizebuf_t *msg, entity_state_t *ent) void SVNQ_EmitEntityState(sizebuf_t *msg, entity_state_t *ent)
{ {
entity_state_t *baseline = &EDICT_NUM(svprogfuncs, ent->number)->baseline; entity_state_t *baseline = &EDICT_NUM(svprogfuncs, ent->number)->baseline;
#define NQU_MOREBITS (1<<0)
#define NQU_ORIGIN1 (1<<1)
#define NQU_ORIGIN2 (1<<2)
#define NQU_ORIGIN3 (1<<3)
#define NQU_ANGLE2 (1<<4)
#define NQU_STEP (1<<5) // don't interpolate movement
#define NQU_FRAME (1<<6)
#define NQU_SIGNAL (1<<7) // just differentiates from other updates
// svc_update can pass all of the fast update bits, plus more
#define NQU_ANGLE1 (1<<8)
#define NQU_ANGLE3 (1<<9)
#define NQU_MODEL (1<<10)
#define NQU_COLORMAP (1<<11)
#define NQU_SKIN (1<<12)
#define NQU_EFFECTS (1<<13)
#define NQU_LONGENTITY (1<<14)
// LordHavoc's: protocol extension
#define DPU_EXTEND1 (1<<15)
// LordHavoc: first extend byte
#define DPU_DELTA (1<<16) // no data, while this is set the entity is delta compressed (uses previous frame as a baseline, meaning only things that have changed from the previous frame are sent, except for the forced full update every half second)
#define DPU_ALPHA (1<<17) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 1, and the entity is not sent if <=0 unless it has effects (model effects are checked as well)
#define DPU_SCALE (1<<18) // 1 byte, scale / 16 positive, not sent if 1.0
#define DPU_EFFECTS2 (1<<19) // 1 byte, this is .effects & 0xFF00 (second byte)
#define DPU_GLOWSIZE (1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0
#define DPU_GLOWCOLOR (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set)
// LordHavoc: colormod feature has been removed, because no one used it
#define DPU_COLORMOD (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend...
#define DPU_EXTEND2 (1<<23) // another byte to follow
// LordHavoc: second extend byte
#define DPU_GLOWTRAIL (1<<24) // leaves a trail of particles (of color .glowcolor, or black if it is a negative glowsize)
#define DPU_VIEWMODEL (1<<25) // attachs the model to the view (origin and angles become relative to it), only shown to owner, a more powerful alternative to .weaponmodel and such
#define DPU_FRAME2 (1<<26) // 1 byte, this is .frame & 0xFF00 (second byte)
#define DPU_MODEL2 (1<<27) // 1 byte, this is .modelindex & 0xFF00 (second byte)
#define DPU_EXTERIORMODEL (1<<28) // causes this model to not be drawn when using a first person view (third person will draw it, first person will not)
#define DPU_UNUSED29 (1<<29) // future expansion
#define DPU_UNUSED30 (1<<30) // future expansion
#define DPU_EXTEND3 (1<<31) // another byte to follow, future expansion
int i, eff; int i, eff;
float miss; float miss;
@ -1904,7 +1866,7 @@ int glowsize=0, glowcolor=0, colourmod=0;
bits |= NQU_ANGLE3; bits |= NQU_ANGLE3;
if (ent->dpflags & RENDER_STEP) if (ent->dpflags & RENDER_STEP)
bits |= NQU_STEP; // don't mess up the step animation bits |= NQU_NOLERP; // don't mess up the step animation
if (baseline->colormap != ent->colormap && ent->colormap>=0) if (baseline->colormap != ent->colormap && ent->colormap>=0)
bits |= NQU_COLORMAP; bits |= NQU_COLORMAP;
@ -2446,6 +2408,23 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
continue; continue;
} }
if (progstype != PROG_QW)
{
// if (progstype == PROG_H2)
// if (ent->v->effects == H2EF_NODRAW)
// continue;
if ((int)ent->v->effects & EF_MUZZLEFLASH)
{
if (needcleanup < e)
{
needcleanup = e;
MSG_WriteByte(&sv.multicast, svc_muzzleflash);
MSG_WriteShort(&sv.multicast, e);
SV_Multicast(ent->v->origin, MULTICAST_PVS);
}
}
}
if (ent->xv->viewmodelforclient) if (ent->xv->viewmodelforclient)
{ {
if (ent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0)) if (ent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0))
@ -2463,23 +2442,6 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
continue; continue;
pvsflags = ent->xv->pvsflags; pvsflags = ent->xv->pvsflags;
if (progstype != PROG_QW)
{
// if (progstype == PROG_H2)
// if (ent->v->effects == H2EF_NODRAW)
// continue;
if ((int)ent->v->effects & EF_MUZZLEFLASH)
{
if (needcleanup < e)
{
needcleanup = e;
MSG_WriteByte(&sv.multicast, svc_muzzleflash);
MSG_WriteShort(&sv.multicast, e);
SV_Multicast(ent->v->origin, MULTICAST_PVS);
}
}
}
if (pvs && ent != clent) //self doesn't get a pvs test, to cover teleporters if (pvs && ent != clent) //self doesn't get a pvs test, to cover teleporters
{ {
if ((int)ent->v->effects & EF_NODEPTHTEST) if ((int)ent->v->effects & EF_NODEPTHTEST)
@ -2509,13 +2471,16 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
{ {
int leafnum; int leafnum;
unsigned char *mask; unsigned char *mask;
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, host_client->edict->v->origin); if (sv.phs)
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, ent->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
{ {
continue; leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, host_client->edict->v->origin);
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, ent->v->origin)-1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
{
continue;
}
} }
} }
@ -2569,20 +2534,8 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
//FIXME: add an option to drop clients... entity fog could be killed in this way. //FIXME: add an option to drop clients... entity fog could be killed in this way.
if (!ISDPCLIENT(client)) if (!ISDPCLIENT(client))
{ {
if (e >= 512) if (e >= client->max_net_ents)
{ continue;
if (!(client->fteprotocolextensions & PEXT_ENTITYDBL))
{
continue;
}
else if (e >= 1024)
{
if (!(client->fteprotocolextensions & PEXT_ENTITYDBL2))
continue;
else if (e >= 2048)
continue;
}
}
#ifdef PEXT_MODELDBL #ifdef PEXT_MODELDBL
if (ent->v->modelindex >= 256 && !(client->fteprotocolextensions & PEXT_MODELDBL)) if (ent->v->modelindex >= 256 && !(client->fteprotocolextensions & PEXT_MODELDBL))
continue; continue;
@ -2657,7 +2610,13 @@ qbyte *SV_Snapshot_SetupPVS(client_t *client, qbyte *pvs, unsigned int pvsbufsiz
for (; client; client = client->controlled) for (; client; client = client->controlled)
{ {
VectorAdd (client->edict->v->origin, client->edict->v->view_ofs, org); if (client->viewent)
{
edict_t *e = PROG_TO_EDICT(svprogfuncs, client->viewent);
VectorAdd (e->v->origin, client->edict->v->view_ofs, org);
}
else
VectorAdd (client->edict->v->origin, client->edict->v->view_ofs, org);
sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, pvs, pvsbufsize, leavepvs); sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, pvs, pvsbufsize, leavepvs);
leavepvs = true; leavepvs = true;

View file

@ -28,6 +28,9 @@ char *T_GetString(int num);
server_static_t svs; // persistant server info server_static_t svs; // persistant server info
server_t sv; // local server server_t sv; // local server
entity_state_t *sv_staticentities;
int sv_max_staticentities;
char localmodels[MAX_MODELS][5]; // inline model names for precache char localmodels[MAX_MODELS][5]; // inline model names for precache
char localinfo[MAX_LOCALINFO_STRING+1]; // local game info char localinfo[MAX_LOCALINFO_STRING+1]; // local game info
@ -39,6 +42,7 @@ extern cvar_t sv_gamespeed;
extern cvar_t sv_csqcdebug; extern cvar_t sv_csqcdebug;
extern cvar_t sv_csqc_progname; extern cvar_t sv_csqc_progname;
extern qboolean sv_allow_cheats; extern qboolean sv_allow_cheats;
extern cvar_t sv_calcphs;
/* /*
================ ================
@ -107,6 +111,7 @@ void SV_FlushSignon (void)
sv.signon.data = sv.signon_buffers[sv.num_signon_buffers]; sv.signon.data = sv.signon_buffers[sv.num_signon_buffers];
sv.num_signon_buffers++; sv.num_signon_buffers++;
sv.signon.cursize = 0; sv.signon.cursize = 0;
sv.signon.prim = svs.netprim;
} }
#ifdef SERVER_DEMO_PLAYBACK #ifdef SERVER_DEMO_PLAYBACK
void SV_FlushDemoSignon (void) void SV_FlushDemoSignon (void)
@ -471,6 +476,13 @@ void SV_CalcPHS (void)
} }
} }
if (!sv_calcphs.ival || (sv_calcphs.ival == 2 && (rowbytes*num >= 0x100000 || (!deathmatch.ival && !coop.ival))))
{
Con_DPrintf("Skipping PHS\n");
sv.phs = NULL;
return;
}
/*this routine takes an exponential amount of time, so cache it if its too big*/ /*this routine takes an exponential amount of time, so cache it if its too big*/
if (rowbytes*num >= 0x100000) if (rowbytes*num >= 0x100000)
{ {
@ -665,8 +677,21 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
T_FreeStrings(); T_FreeStrings();
} }
if (sv_bigcoords.value)
{
svs.netprim.coordsize = 4;
svs.netprim.anglesize = 2;
}
else
{
svs.netprim.coordsize = 2;
svs.netprim.anglesize = 1;
}
for (i = 0; i < MAX_CLIENTS; i++) for (i = 0; i < MAX_CLIENTS; i++)
{ {
svs.clients[i].datagram.prim = svs.netprim;
svs.clients[i].netchan.message.prim = svs.netprim;
svs.clients[i].nextservertimeupdate = 0; svs.clients[i].nextservertimeupdate = 0;
if (!svs.clients[i].state) //bots with the net_preparse module. if (!svs.clients[i].state) //bots with the net_preparse module.
svs.clients[i].userinfo[0] = '\0'; //clear the userinfo to clear the name svs.clients[i].userinfo[0] = '\0'; //clear the userinfo to clear the name
@ -679,17 +704,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
svs.clients[i].csqcactive = false; svs.clients[i].csqcactive = false;
} }
if (sv_bigcoords.value)
{
sizeofcoord = 4;
sizeofangle = 2;
}
else
{
sizeofcoord = 2;
sizeofangle = 1;
}
VoteFlushAll(); VoteFlushAll();
#ifndef SERVERONLY #ifndef SERVERONLY
cl.worldmodel = NULL; cl.worldmodel = NULL;
@ -728,43 +742,54 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
sv.datagram.maxsize = sizeof(sv.datagram_buf); sv.datagram.maxsize = sizeof(sv.datagram_buf);
sv.datagram.data = sv.datagram_buf; sv.datagram.data = sv.datagram_buf;
sv.datagram.allowoverflow = true; sv.datagram.allowoverflow = true;
sv.datagram.prim = svs.netprim;
sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf); sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
sv.reliable_datagram.data = sv.reliable_datagram_buf; sv.reliable_datagram.data = sv.reliable_datagram_buf;
sv.reliable_datagram.prim = svs.netprim;
sv.multicast.maxsize = sizeof(sv.multicast_buf); sv.multicast.maxsize = sizeof(sv.multicast_buf);
sv.multicast.data = sv.multicast_buf; sv.multicast.data = sv.multicast_buf;
sv.multicast.prim = svs.netprim;
#ifdef NQPROT #ifdef NQPROT
sv.nqdatagram.maxsize = sizeof(sv.nqdatagram_buf); sv.nqdatagram.maxsize = sizeof(sv.nqdatagram_buf);
sv.nqdatagram.data = sv.nqdatagram_buf; sv.nqdatagram.data = sv.nqdatagram_buf;
sv.nqdatagram.allowoverflow = true; sv.nqdatagram.allowoverflow = true;
sv.nqdatagram.prim = svs.netprim;
sv.nqreliable_datagram.maxsize = sizeof(sv.nqreliable_datagram_buf); sv.nqreliable_datagram.maxsize = sizeof(sv.nqreliable_datagram_buf);
sv.nqreliable_datagram.data = sv.nqreliable_datagram_buf; sv.nqreliable_datagram.data = sv.nqreliable_datagram_buf;
sv.nqreliable_datagram.prim = svs.netprim;
sv.nqmulticast.maxsize = sizeof(sv.nqmulticast_buf); sv.nqmulticast.maxsize = sizeof(sv.nqmulticast_buf);
sv.nqmulticast.data = sv.nqmulticast_buf; sv.nqmulticast.data = sv.nqmulticast_buf;
sv.nqmulticast.prim = svs.netprim;
#endif #endif
#ifdef Q2SERVER
sv.q2datagram.maxsize = sizeof(sv.q2datagram_buf); sv.q2datagram.maxsize = sizeof(sv.q2datagram_buf);
sv.q2datagram.data = sv.q2datagram_buf; sv.q2datagram.data = sv.q2datagram_buf;
sv.q2datagram.allowoverflow = true; sv.q2datagram.allowoverflow = true;
sv.q2datagram.prim = svs.netprim;
sv.q2reliable_datagram.maxsize = sizeof(sv.q2reliable_datagram_buf); sv.q2reliable_datagram.maxsize = sizeof(sv.q2reliable_datagram_buf);
sv.q2reliable_datagram.data = sv.q2reliable_datagram_buf; sv.q2reliable_datagram.data = sv.q2reliable_datagram_buf;
sv.q2reliable_datagram.prim = svs.netprim;
sv.q2multicast.maxsize = sizeof(sv.q2multicast_buf); sv.q2multicast.maxsize = sizeof(sv.q2multicast_buf);
sv.q2multicast.data = sv.q2multicast_buf; sv.q2multicast.data = sv.q2multicast_buf;
sv.q2multicast.prim = svs.netprim;
#endif
sv.master.maxsize = sizeof(sv.master_buf); sv.master.maxsize = sizeof(sv.master_buf);
sv.master.data = sv.master_buf; sv.master.data = sv.master_buf;
sv.master.prim = msg_nullnetprim;
sv.signon.maxsize = sizeof(sv.signon_buffers[0]); sv.signon.maxsize = sizeof(sv.signon_buffers[0]);
sv.signon.data = sv.signon_buffers[0]; sv.signon.data = sv.signon_buffers[0];
sv.signon.prim = svs.netprim;
sv.num_signon_buffers = 1; sv.num_signon_buffers = 1;
sv.numextrastatics = 0;
strcpy (sv.name, server); strcpy (sv.name, server);
#ifndef SERVERONLY #ifndef SERVERONLY
@ -1370,6 +1395,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
// SV_CreateBaseline (); // SV_CreateBaseline ();
if (svprogfuncs) if (svprogfuncs)
SVNQ_CreateBaseline(); SVNQ_CreateBaseline();
#ifdef Q2SERVER
SVQ2_BuildBaselines();
#endif
sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize; sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize;
// all spawning is completed, any further precache statements // all spawning is completed, any further precache statements

View file

@ -142,6 +142,7 @@ cvar_t sv_maxdrate = CVARAF("sv_maxdrate", "10000",
cvar_t sv_minping = CVARF("sv_minping", "0", CVAR_SERVERINFO); cvar_t sv_minping = CVARF("sv_minping", "0", CVAR_SERVERINFO);
cvar_t sv_bigcoords = CVARF("sv_bigcoords", "", CVAR_SERVERINFO); cvar_t sv_bigcoords = CVARF("sv_bigcoords", "", CVAR_SERVERINFO);
cvar_t sv_calcphs = CVAR("sv_calcphs", "2");
cvar_t sv_cullplayers_trace = CVARF("sv_cullplayers_trace", "", CVAR_SERVERINFO); cvar_t sv_cullplayers_trace = CVARF("sv_cullplayers_trace", "", CVAR_SERVERINFO);
cvar_t sv_cullentities_trace = CVARF("sv_cullentities_trace", "", CVAR_SERVERINFO); cvar_t sv_cullentities_trace = CVARF("sv_cullentities_trace", "", CVAR_SERVERINFO);
@ -1700,7 +1701,7 @@ client_t *SVC_DirectConnect(void)
//it's a darkplaces client. //it's a darkplaces client.
s = Info_ValueForKey(userinfo[0], "protocols"); s = Info_ValueForKey(userinfo[0], "protocols");
if (sizeofcoord != 4) if (svs.netprim.coordsize != 4)
{ //we allow nq with sv_listen_nq 0... { //we allow nq with sv_listen_nq 0...
//reason: dp is too similar for concerns about unsupported code, while the main reason why we disable nq is because of the lack of challenges //reason: dp is too similar for concerns about unsupported code, while the main reason why we disable nq is because of the lack of challenges
//(and no, this isn't a way to bypass invalid challenges) //(and no, this isn't a way to bypass invalid challenges)
@ -1879,6 +1880,19 @@ client_t *SVC_DirectConnect(void)
newcl->fteprotocolextensions2 = protextsupported2; newcl->fteprotocolextensions2 = protextsupported2;
newcl->protocol = protocol; newcl->protocol = protocol;
if (protocol == SCP_QUAKEWORLD) //readd?
{
newcl->max_net_ents = 512;
if (newcl->fteprotocolextensions & PEXT_ENTITYDBL)
newcl->max_net_ents += 512;
if (newcl->fteprotocolextensions & PEXT_ENTITYDBL2)
newcl->max_net_ents += 1024;
}
else if (ISDPCLIENT(newcl))
newcl->max_net_ents = 32767;
else
newcl->max_net_ents = 600;
if (sv.msgfromdemo) if (sv.msgfromdemo)
newcl->wasrecorded = true; newcl->wasrecorded = true;
@ -2174,7 +2188,7 @@ client_t *SVC_DirectConnect(void)
} }
newcl->zquake_extensions &= SUPPORTED_Z_EXTENSIONS; newcl->zquake_extensions &= SUPPORTED_Z_EXTENSIONS;
Netchan_Setup (NS_SERVER, &newcl->netchan , adr, qport); Netchan_Setup (NS_SERVER, &newcl->netchan, adr, qport);
if (huffcrc) if (huffcrc)
newcl->netchan.compress = true; newcl->netchan.compress = true;
@ -2195,6 +2209,10 @@ client_t *SVC_DirectConnect(void)
newcl->datagram.data = newcl->datagram_buf; newcl->datagram.data = newcl->datagram_buf;
newcl->datagram.maxsize = sizeof(newcl->datagram_buf); newcl->datagram.maxsize = sizeof(newcl->datagram_buf);
newcl->netchan.netprim = svs.netprim;
newcl->datagram.prim = svs.netprim;
newcl->netchan.message.prim = svs.netprim;
// spectator mode can ONLY be set at join time // spectator mode can ONLY be set at join time
newcl->spectator = spectator; newcl->spectator = spectator;
@ -2632,7 +2650,7 @@ qboolean SV_ConnectionlessPacket (void)
char *c; char *c;
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
MSG_BeginReading (); MSG_BeginReading (svs.netprim);
if (net_message.cursize >= MAX_QWMSGLEN) //add a null term in message space if (net_message.cursize >= MAX_QWMSGLEN) //add a null term in message space
{ {
@ -2676,7 +2694,7 @@ qboolean SV_ConnectionlessPacket (void)
{ //if name isn't in the string, assume they're q3 { //if name isn't in the string, assume they're q3
//this isn't quite true though, hence the listen check. but users shouldn't be connecting with an empty name anyway. more fool them. //this isn't quite true though, hence the listen check. but users shouldn't be connecting with an empty name anyway. more fool them.
Huff_DecryptPacket(&net_message, 12); Huff_DecryptPacket(&net_message, 12);
MSG_BeginReading(); MSG_BeginReading(svs.netprim);
MSG_ReadLong(); MSG_ReadLong();
s = MSG_ReadStringLine(); s = MSG_ReadStringLine();
Cmd_TokenizeString(s, false, false); Cmd_TokenizeString(s, false, false);
@ -2734,7 +2752,7 @@ void SVNQ_ConnectionlessPacket(void)
if (sv_bigcoords.value) if (sv_bigcoords.value)
return; //no, start using dp7 instead. return; //no, start using dp7 instead.
MSG_BeginReading(); MSG_BeginReading(svs.netprim);
header = LongSwap(MSG_ReadLong()); header = LongSwap(MSG_ReadLong());
if (!(header & NETFLAG_CTL)) if (!(header & NETFLAG_CTL))
return; //no idea what it is. return; //no idea what it is.
@ -2966,7 +2984,7 @@ qboolean SV_ReadPackets (void)
// read the qport out of the message so we can fix up // read the qport out of the message so we can fix up
// stupid address translating routers // stupid address translating routers
MSG_BeginReading (); MSG_BeginReading (svs.netprim);
MSG_ReadLong (); // sequence number MSG_ReadLong (); // sequence number
MSG_ReadLong (); // sequence number MSG_ReadLong (); // sequence number
qport = MSG_ReadShort () & 0xffff; qport = MSG_ReadShort () & 0xffff;
@ -3653,7 +3671,7 @@ void SV_InitLocal (void)
Cvar_Register (&secure, cvargroup_serverpermissions); Cvar_Register (&secure, cvargroup_serverpermissions);
Cvar_Register (&sv_highchars, cvargroup_servercontrol); Cvar_Register (&sv_highchars, cvargroup_servercontrol);
Cvar_Register (&sv_calcphs, cvargroup_servercontrol);
Cvar_Register (&sv_phs, cvargroup_servercontrol); Cvar_Register (&sv_phs, cvargroup_servercontrol);
Cvar_Register (&sv_cullplayers_trace, cvargroup_servercontrol); Cvar_Register (&sv_cullplayers_trace, cvargroup_servercontrol);
Cvar_Register (&sv_cullentities_trace, cvargroup_servercontrol); Cvar_Register (&sv_cullentities_trace, cvargroup_servercontrol);

View file

@ -162,10 +162,10 @@ void SVM_Think(int port)
SVM_RemoveOldServers(); SVM_RemoveOldServers();
MSG_BeginReading(); MSG_BeginReading(msg_nullnetprim);
if (MSG_ReadLong() != -1 || msg_badread) if (MSG_ReadLong() != -1 || msg_badread)
{ //go back to start... { //go back to start...
MSG_BeginReading(); MSG_BeginReading(msg_nullnetprim);
} }
s = MSG_ReadStringLine(); s = MSG_ReadStringLine();
s = COM_Parse(s); s = COM_Parse(s);

View file

@ -1645,7 +1645,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
gamedir = "qw"; gamedir = "qw";
MSG_WriteByte (&buf, svc_serverdata); MSG_WriteByte (&buf, svc_serverdata);
if (sizeofcoord == 4) //sorry. if (svs.netprim.coordsize == 4) //sorry.
{ {
MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE); MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE);
MSG_WriteLong (&buf, PEXT_FLOATCOORDS); MSG_WriteLong (&buf, PEXT_FLOATCOORDS);

View file

@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "qwsvdef.h" #include "qwsvdef.h"
#ifndef CLIENTONLY #ifndef CLIENTONLY
#include "pr_common.h"
#pragma message("fixme, fix this up before adding to csqc") #pragma message("fixme, fix this up before adding to csqc")
extern nqglobalvars_t realpr_nqglobal_struct; extern nqglobalvars_t realpr_nqglobal_struct;
@ -928,6 +930,7 @@ if (l > 1.0/64)
{ {
// Con_Printf ("**** snap: %f\n", Length (l)); // Con_Printf ("**** snap: %f\n", Length (l));
VectorCopy (oldorg, ent->v->origin); VectorCopy (oldorg, ent->v->origin);
VectorCopy (oldang, ent->v->angles);
SV_Push (ent, move, amove); SV_Push (ent, move, amove);
} }
@ -1125,11 +1128,17 @@ static void SV_Physics_Toss (edict_t *ent)
if (ent->v->movetype == MOVETYPE_BOUNCE) if (ent->v->movetype == MOVETYPE_BOUNCE)
backoff = 1.5; backoff = 1.5;
else if (ent->v->movetype == MOVETYPE_BOUNCEMISSILE) else if (ent->v->movetype == MOVETYPE_BOUNCEMISSILE)
backoff = 2; {
// if (progstype == PROG_H2 && ent->v->solid == SOLID_PHASEH2 && ((int)((wedict_t*)trace.ent)->v->flags & (FL_MONSTER|FL_CLIENT)))
// backoff = 0;
// else
backoff = 2;
}
else else
backoff = 1; backoff = 1;
ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, backoff); if (backoff)
ClipVelocity (ent->v->velocity, trace.plane.normal, ent->v->velocity, backoff);
// stop if on ground // stop if on ground
@ -2092,7 +2101,7 @@ qboolean SV_Physics (void)
break; break;
if (host_frametime > sv_maxtic.value) if (host_frametime > sv_maxtic.value)
{ {
if (--maxtics == 0) if (maxtics-- <= 0)
{ {
//timewarp, as we're running too slowly //timewarp, as we're running too slowly
sv.world.physicstime = sv.time; sv.world.physicstime = sv.time;

View file

@ -633,7 +633,10 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
case MULTICAST_PHS_R: case MULTICAST_PHS_R:
reliable = true; // intentional fallthrough reliable = true; // intentional fallthrough
case MULTICAST_PHS: case MULTICAST_PHS:
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5); if (!sv.phs) /*broadcast if no pvs*/
mask = sv.pvs;
else
mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5);
break; break;
case MULTICAST_PVS_R: case MULTICAST_PVS_R:
@ -1639,6 +1642,7 @@ qboolean SV_SendClientDatagram (client_t *client)
msg.cursize = 0; msg.cursize = 0;
msg.allowoverflow = true; msg.allowoverflow = true;
msg.overflowed = false; msg.overflowed = false;
msg.prim = client->datagram.prim;
if (sv.world.worldmodel && !client->controller) if (sv.world.worldmodel && !client->controller)
{ {

View file

@ -236,7 +236,7 @@ void SV_New_f (void)
SZ_Clear(&host_client->netchan.message); SZ_Clear(&host_client->netchan.message);
} }
*/ */
if (sizeofcoord > 2 && !(host_client->fteprotocolextensions & PEXT_FLOATCOORDS)) if (svs.netprim.coordsize > 2 && !(host_client->fteprotocolextensions & PEXT_FLOATCOORDS))
{ {
SV_ClientPrintf(host_client, 2, "\n\n\n\nSorry, but your client does not appear to support FTE's bigcoords\nFTE users will need to set cl_nopext to 0 and then reconnect, or to upgrade\n"); SV_ClientPrintf(host_client, 2, "\n\n\n\nSorry, but your client does not appear to support FTE's bigcoords\nFTE users will need to set cl_nopext to 0 and then reconnect, or to upgrade\n");
Con_Printf("%s does not support bigcoords\n", host_client->name); Con_Printf("%s does not support bigcoords\n", host_client->name);
@ -251,7 +251,7 @@ void SV_New_f (void)
if (host_client->fteprotocolextensions)//let the client know if (host_client->fteprotocolextensions)//let the client know
{ {
ClientReliableWrite_Long (host_client, PROTOCOL_VERSION_FTE); ClientReliableWrite_Long (host_client, PROTOCOL_VERSION_FTE);
if (sizeofcoord == 2) //we're not using float orgs on this level. if (svs.netprim.coordsize == 2) //we're not using float orgs on this level.
ClientReliableWrite_Long (host_client, host_client->fteprotocolextensions&~PEXT_FLOATCOORDS); ClientReliableWrite_Long (host_client, host_client->fteprotocolextensions&~PEXT_FLOATCOORDS);
else else
ClientReliableWrite_Long (host_client, host_client->fteprotocolextensions); ClientReliableWrite_Long (host_client, host_client->fteprotocolextensions);
@ -962,7 +962,7 @@ void SV_Modellist_f (void)
Q_strncpy(mname, sv.strings.vw_model_precache[i], sizeof(mname)); Q_strncpy(mname, sv.strings.vw_model_precache[i], sizeof(mname));
//strip .mdl extensions //strip .mdl extensions
if (!strcmp(COM_FileExtension(mname), ".mdl")) if (!strcmp(COM_FileExtension(mname), "mdl"))
COM_StripExtension(mname, mname, sizeof(mname)); COM_StripExtension(mname, mname, sizeof(mname));
//add it to the vweap command, taking care of any remaining spaces in names. //add it to the vweap command, taking care of any remaining spaces in names.
@ -1026,12 +1026,10 @@ void SV_Modellist_f (void)
#endif #endif
{ {
for (i = 1+n; for (i = 1+n;
i < maxclientsupportedmodels && sv.strings.model_precache[i] && host_client->netchan.message.cursize < (MAX_QWMSGLEN/2); //make sure we don't send a 0 next... i < maxclientsupportedmodels && sv.strings.model_precache[i] && (((i-1)&255)==0 || host_client->netchan.message.cursize < (MAX_QWMSGLEN/2)); //make sure we don't send a 0 next...
i++) i++)
{ {
MSG_WriteString (&host_client->netchan.message, sv.strings.model_precache[i]); MSG_WriteString (&host_client->netchan.message, sv.strings.model_precache[i]);
if (((n&255)==255) && n != i-1)
break;
} }
n = i-1; n = i-1;
@ -1080,7 +1078,7 @@ void SV_PreSpawn_f (void)
else else
#endif #endif
bufs = sv.num_signon_buffers; bufs = sv.num_signon_buffers;
statics = sv.numextrastatics; statics = sv.num_static_entities;
buf = atoi(Cmd_Argv(2)); buf = atoi(Cmd_Argv(2));
if (buf >= bufs+statics+sv.world.num_edicts+255) if (buf >= bufs+statics+sv.world.num_edicts+255)
@ -1140,21 +1138,29 @@ void SV_PreSpawn_f (void)
memset(&from, 0, sizeof(from)); memset(&from, 0, sizeof(from));
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //static entities while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //static entities
{ {
if (buf - bufs >= sv.numextrastatics) if (buf - bufs >= sv.num_static_entities)
break; break;
state = &sv.extendedstatics[buf - bufs]; state = &sv_staticentities[buf - bufs];
buf++;
if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2) if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
{ {
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2); /*if it uses some new feature, use the updated spawnstatic*/
SV_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions); if (state->hexen2flags || state->trans || state->modelindex >= 256 || state->frame > 255 || state->scale || state->abslight)
{
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2);
SV_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
continue;
}
} }
else if (state->modelindex < 256) /*couldn't use protocol extensions?
use the fallback, unless the model is invalid as that's silly*/
if (state->modelindex < 256)
{ {
MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic); MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic);
MSG_WriteByte (&host_client->netchan.message, state->modelindex&255); MSG_WriteByte (&host_client->netchan.message, state->modelindex);
MSG_WriteByte (&host_client->netchan.message, state->frame); MSG_WriteByte (&host_client->netchan.message, state->frame);
MSG_WriteByte (&host_client->netchan.message, (int)state->colormap); MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
@ -1164,15 +1170,15 @@ void SV_PreSpawn_f (void)
MSG_WriteCoord(&host_client->netchan.message, state->origin[i]); MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
MSG_WriteAngle(&host_client->netchan.message, state->angles[i]); MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
} }
continue;
} }
buf++;
} }
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines
{ {
if (buf - bufs - sv.numextrastatics >= sv.world.num_edicts) if (buf - bufs - sv.num_static_entities >= sv.world.num_edicts)
break; break;
ent = EDICT_NUM(svprogfuncs, buf - bufs - sv.numextrastatics); ent = EDICT_NUM(svprogfuncs, buf - bufs - sv.num_static_entities);
state = &ent->baseline; state = &ent->baseline;
if (!state->number || !state->modelindex) if (!state->number || !state->modelindex)
@ -1185,7 +1191,7 @@ void SV_PreSpawn_f (void)
{ {
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline); MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.numextrastatics); MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.num_static_entities);
MSG_WriteByte (&host_client->netchan.message, 0); MSG_WriteByte (&host_client->netchan.message, 0);
@ -1207,7 +1213,7 @@ void SV_PreSpawn_f (void)
{ {
MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline); MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);
MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.numextrastatics); MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.num_static_entities);
MSG_WriteByte (&host_client->netchan.message, state->modelindex); MSG_WriteByte (&host_client->netchan.message, state->modelindex);
@ -1225,7 +1231,7 @@ void SV_PreSpawn_f (void)
} }
while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))
{ {
i = buf - bufs - sv.numextrastatics - sv.world.num_edicts; i = buf - bufs - sv.num_static_entities - sv.world.num_edicts;
if (i >= 255) if (i >= 255)
break; break;
@ -1264,7 +1270,7 @@ void SV_PreSpawn_f (void)
} }
else if (buf >= bufs) else if (buf >= bufs)
{ {
buf = bufs+sv.numextrastatics+sv.world.num_edicts+255; buf = bufs+sv.num_static_entities+sv.world.num_edicts+255;
} }
else else
{ {
@ -1291,7 +1297,7 @@ void SV_PreSpawn_f (void)
} }
} }
} }
if (buf == bufs+sv.numextrastatics+sv.world.num_edicts+255) if (buf == bufs+sv.num_static_entities+sv.world.num_edicts+255)
{ // all done prespawning { // all done prespawning
MSG_WriteByte (&host_client->netchan.message, svc_stufftext); MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i\n",svs.spawncount) ); MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i\n",svs.spawncount) );
@ -3682,7 +3688,8 @@ void Cmd_Join_f (void)
// FIXME, bump the client's userid? // FIXME, bump the client's userid?
// call the progs to get default spawn parms for the new client // call the progs to get default spawn parms for the new client
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms); if (pr_nqglobal_struct->SetNewParms)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
for (i=0 ; i<NUM_SPAWN_PARMS ; i++) for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
{ {
if (spawnparamglobals[i]) if (spawnparamglobals[i])
@ -3773,7 +3780,8 @@ void Cmd_Observe_f (void)
// FIXME, bump the client's userid? // FIXME, bump the client's userid?
// call the progs to get default spawn parms for the new client // call the progs to get default spawn parms for the new client
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms); if (pr_nqglobal_struct->SetNewParms)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
for (i=0 ; i<NUM_SPAWN_PARMS ; i++) for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
{ {
if (spawnparamglobals[i]) if (spawnparamglobals[i])
@ -4283,7 +4291,7 @@ void SVNQ_Begin_f (void)
if (pmodel != sv.model_player_checksum || if (pmodel != sv.model_player_checksum ||
emodel != sv.eyes_player_checksum) emodel != sv.eyes_player_checksum)
SV_BroadcastTPrintf (PRINT_HIGH, STL_POSSIBLEMODELCHEAT, host_client->name); SV_BroadcastPrintf (PRINT_HIGH, "warning: %s eyes or player model not verified\n", host_client->name);
} }
@ -4332,7 +4340,7 @@ void SVNQ_PreSpawn_f (void)
return; return;
} }
for (e = 1; e < sv.world.num_edicts; e++) for (e = 1; e < sv.world.num_edicts && e < host_client->max_net_ents; e++)
{ {
ent = EDICT_NUM(svprogfuncs, e); ent = EDICT_NUM(svprogfuncs, e);
state = &ent->baseline; state = &ent->baseline;
@ -4361,7 +4369,7 @@ void SVNQ_PreSpawn_f (void)
} }
else else
{ {
if (host_client->protocol != SCP_NETQUAKE && (state->modelindex > 255 || state->frame > 255)) if (ISDPCLIENT(host_client) && (state->modelindex > 255 || state->frame > 255))
{ {
MSG_WriteByte(&host_client->netchan.message, svcdp_spawnbaseline2); MSG_WriteByte(&host_client->netchan.message, svcdp_spawnbaseline2);
@ -4900,6 +4908,8 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
double tmp_time; double tmp_time;
qboolean jumpable; qboolean jumpable;
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
vec3_t new_vel;
vec3_t old_vel;
// DMW copied this KK hack copied from QuakeForge anti-cheat // DMW copied this KK hack copied from QuakeForge anti-cheat
// (also extra inside parm on all SV_RunCmds that follow) // (also extra inside parm on all SV_RunCmds that follow)
@ -5098,7 +5108,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
if (progstype != PROG_QW) if (progstype != PROG_QW)
{ {
#define FL_JUMPRELEASED 4096 #define FL_JUMPRELEASED 4096
jumpable = (int)sv_player->v->flags & FL_JUMPRELEASED; jumpable = ((int)sv_player->v->flags & FL_JUMPRELEASED) && ((int)sv_player->v->flags & FL_ONGROUND);
pmove.waterjumptime = sv_player->v->teleport_time; pmove.waterjumptime = sv_player->v->teleport_time;
if (pmove.waterjumptime > sv.time) if (pmove.waterjumptime > sv.time)
@ -5232,17 +5242,7 @@ if (sv_player->v->health > 0 && before && !after )
else else
sv_player->v->flags = (int)sv_player->v->flags & ~FL_ONGROUND; sv_player->v->flags = (int)sv_player->v->flags & ~FL_ONGROUND;
for (i=0 ; i<3 ; i++) VectorCopy (pmove.origin, sv_player->v->origin);
sv_player->v->origin[i] = pmove.origin[i];// - (sv_player->v->mins[i] - player_mins[i]);
#if 0
// truncate velocity the same way the net protocol will
for (i=0 ; i<3 ; i++)
sv_player->v->velocity[i] = (int)pmove.velocity[i];
#else
VectorCopy (pmove.velocity, sv_player->v->velocity);
#endif
VectorCopy (pmove.angles, sv_player->v->v_angle); VectorCopy (pmove.angles, sv_player->v->v_angle);
player_mins[0] = -16; player_mins[0] = -16;
@ -5253,6 +5253,12 @@ if (sv_player->v->health > 0 && before && !after )
player_maxs[1] = 16; player_maxs[1] = 16;
player_maxs[2] = 32; player_maxs[2] = 32;
VectorCopy(sv_player->v->velocity, old_vel);
VectorCopy(pmove.velocity, new_vel);
if (progstype == PROG_QW)
VectorCopy(new_vel, sv_player->v->velocity);
if (!host_client->spectator) if (!host_client->spectator)
{ {
// link into place and touch triggers // link into place and touch triggers
@ -5304,6 +5310,12 @@ if (sv_player->v->health > 0 && before && !after )
playertouch[n/8] |= 1 << (n%8); playertouch[n/8] |= 1 << (n%8);
} }
} }
if (progstype != PROG_QW)
{
if (VectorCompare(sv_player->v->velocity, old_vel))
VectorCopy(new_vel, sv_player->v->velocity);
}
} }
/* /*

View file

@ -751,6 +751,25 @@ void SV_BuildClientFrame (client_t *client)
} }
} }
void SVQ2_BuildBaselines(void)
{
unsigned int e;
q2edict_t *ent;
q2entity_state_t *base;
if (!ge)
return;
for (e=1 ; e<ge->num_edicts ; e++)
{
ent = Q2EDICT_NUM(e);
base = &ent->s;
if (base->modelindex || base->sound || base->effects)
sv_baselines[e] = *base;
}
}
void SVQ2_Ents_Init(void) void SVQ2_Ents_Init(void)
{ {
extern cvar_t maxclients; extern cvar_t maxclients;

View file

@ -3050,7 +3050,7 @@ void SVQ3_HandleClient(void)
if (net_message.cursize<6) if (net_message.cursize<6)
return; //urm. :/ return; //urm. :/
MSG_BeginReading(); MSG_BeginReading(msg_nullnetprim);
MSG_ReadBits(32); MSG_ReadBits(32);
qport = (unsigned short)MSG_ReadBits(16); qport = (unsigned short)MSG_ReadBits(16);

View file

@ -1468,13 +1468,15 @@ static void World_ClipToEverything (world_t *w, moveclip_t *clip)
if (clip->passedict) if (clip->passedict)
{ {
// don't clip corpse against character if (w->usesolidcorpse)
if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE)) {
continue; // don't clip corpse against character
// don't clip character against corpse if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE))
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE) continue;
continue; // don't clip character against corpse
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
}
if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid)) if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue; continue;
} }
@ -1620,13 +1622,15 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip)
if (clip->passedict) if (clip->passedict)
{ {
// don't clip corpse against character if (w->usesolidcorpse)
if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE)) {
continue; // don't clip corpse against character
// don't clip character against corpse if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE))
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE) continue;
continue; // don't clip character against corpse
if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
}
if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid)) if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue; continue;
} }
@ -1906,13 +1910,15 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
if (clip.passedict) if (clip.passedict)
{ {
// don't clip corpse against character if (w->usesolidcorpse)
if (clip.passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE)) {
continue; // don't clip corpse against character
// don't clip character against corpse if (clip.passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE))
if (clip.passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE) continue;
continue; // don't clip character against corpse
if (clip.passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE)
continue;
}
if (!((int)clip.passedict->xv->dimension_hit & (int)touch->xv->dimension_solid)) if (!((int)clip.passedict->xv->dimension_hit & (int)touch->xv->dimension_solid))
continue; continue;
} }