1
0
Fork 0
forked from fte/fteqw

we can connect to DP servers, dynamic lighting code was revised a little, a new cvar was added to control the extra feature, lights can be flagged with where they should appear, skin code was revised (to include models), fruity textures fixed, r_loadlit 2 failing to save is fixed. NQ demos smoothed.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@537 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2004-11-27 08:16:25 +00:00
parent f468184e98
commit 9af4c7df7f
25 changed files with 923 additions and 154 deletions

View file

@ -72,7 +72,7 @@ dlight_t *CL_AllocDlight (int key)
dl = cl_dlights; dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
{ {
if (dl->die < cl.time) if (!dl->radius)
{ {
memset (dl, 0, sizeof(*dl)); memset (dl, 0, sizeof(*dl));
dl->key = key; dl->key = key;
@ -101,7 +101,7 @@ dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float
dl->origin[1] = y; dl->origin[1] = y;
dl->origin[2] = z; dl->origin[2] = z;
dl->radius = radius; dl->radius = radius;
dl->die = cl.time + time; dl->die = (float)cl.time + time;
if (type == 0) { if (type == 0) {
dl->color[0] = 0.2; dl->color[0] = 0.2;
dl->color[1] = 0.1; dl->color[1] = 0.1;
@ -156,9 +156,15 @@ void CL_DecayLights (void)
dl = cl_dlights; dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
{ {
if (dl->die < cl.time || !dl->radius) if (!dl->radius)
continue; continue;
if (dl->die < (float)cl.time)
{
dl->radius = 0;
continue;
}
dl->radius -= host_frametime*dl->decay; dl->radius -= host_frametime*dl->decay;
if (dl->radius < 0) if (dl->radius < 0)
dl->radius = 0; dl->radius = 0;
@ -591,6 +597,324 @@ entity_state_t *CL_FindOldPacketEntity(int num)
} }
return NULL; return NULL;
} }
// reset all entity fields (typically used if status changed)
#define E5_FULLUPDATE (1<<0)
// E5_ORIGIN32=0: short[3] = s->origin[0] * 8, s->origin[1] * 8, s->origin[2] * 8
// E5_ORIGIN32=1: float[3] = s->origin[0], s->origin[1], s->origin[2]
#define E5_ORIGIN (1<<1)
// E5_ANGLES16=0: byte[3] = s->angle[0] * 256 / 360, s->angle[1] * 256 / 360, s->angle[2] * 256 / 360
// E5_ANGLES16=1: short[3] = s->angle[0] * 65536 / 360, s->angle[1] * 65536 / 360, s->angle[2] * 65536 / 360
#define E5_ANGLES (1<<2)
// E5_MODEL16=0: byte = s->modelindex
// E5_MODEL16=1: short = s->modelindex
#define E5_MODEL (1<<3)
// E5_FRAME16=0: byte = s->frame
// E5_FRAME16=1: short = s->frame
#define E5_FRAME (1<<4)
// byte = s->skin
#define E5_SKIN (1<<5)
// E5_EFFECTS16=0 && E5_EFFECTS32=0: byte = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=0: short = s->effects
// E5_EFFECTS16=0 && E5_EFFECTS32=1: int = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=1: int = s->effects
#define E5_EFFECTS (1<<6)
// bits >= (1<<8)
#define E5_EXTEND1 (1<<7)
// byte = s->renderflags
#define E5_FLAGS (1<<8)
// byte = bound(0, s->alpha * 255, 255)
#define E5_ALPHA (1<<9)
// byte = bound(0, s->scale * 16, 255)
#define E5_SCALE (1<<10)
// flag
#define E5_ORIGIN32 (1<<11)
// flag
#define E5_ANGLES16 (1<<12)
// flag
#define E5_MODEL16 (1<<13)
// byte = s->colormap
#define E5_COLORMAP (1<<14)
// bits >= (1<<16)
#define E5_EXTEND2 (1<<15)
// short = s->tagentity
// byte = s->tagindex
#define E5_ATTACHMENT (1<<16)
// short[4] = s->light[0], s->light[1], s->light[2], s->light[3]
// byte = s->lightstyle
// byte = s->lightpflags
#define E5_LIGHT (1<<17)
// byte = s->glowsize
// byte = s->glowcolor
#define E5_GLOW (1<<18)
// short = s->effects
#define E5_EFFECTS16 (1<<19)
// int = s->effects
#define E5_EFFECTS32 (1<<20)
// flag
#define E5_FRAME16 (1<<21)
// unused
#define E5_UNUSED22 (1<<22)
// bits >= (1<<24)
#define E5_EXTEND3 (1<<23)
// unused
#define E5_UNUSED24 (1<<24)
// unused
#define E5_UNUSED25 (1<<25)
// unused
#define E5_UNUSED26 (1<<26)
// unused
#define E5_UNUSED27 (1<<27)
// unused
#define E5_UNUSED28 (1<<28)
// unused
#define E5_UNUSED29 (1<<29)
// unused
#define E5_UNUSED30 (1<<30)
// bits2 > 0
#define E5_EXTEND4 (1<<31)
static entity_state_t defaultstate;
void DP5_ParseDelta(entity_state_t *s)
{
int bits;
bits = MSG_ReadByte();
if (bits & E5_EXTEND1)
{
bits |= MSG_ReadByte() << 8;
if (bits & E5_EXTEND2)
{
bits |= MSG_ReadByte() << 16;
if (bits & E5_EXTEND3)
bits |= MSG_ReadByte() << 24;
}
}
if (bits & E5_FULLUPDATE)
{
*s = defaultstate;
// s->active = true;
}
if (bits & E5_FLAGS)
s->flags = MSG_ReadByte();
if (bits & E5_ORIGIN)
{
if (bits & E5_ORIGIN32)
{
s->origin[0] = MSG_ReadFloat();
s->origin[1] = MSG_ReadFloat();
s->origin[2] = MSG_ReadFloat();
}
else
{
s->origin[0] = MSG_ReadShort()*(1/8.0f);
s->origin[1] = MSG_ReadShort()*(1/8.0f);
s->origin[2] = MSG_ReadShort()*(1/8.0f);
}
}
if (bits & E5_ANGLES)
{
if (bits & E5_ANGLES16)
{
s->angles[0] = MSG_ReadAngle16();
s->angles[1] = MSG_ReadAngle16();
s->angles[2] = MSG_ReadAngle16();
}
else
{
s->angles[0] = MSG_ReadChar() * (360.0/256);
s->angles[1] = MSG_ReadChar() * (360.0/256);
s->angles[2] = MSG_ReadChar() * (360.0/256);
}
}
if (bits & E5_MODEL)
{
if (bits & E5_MODEL16)
s->modelindex = (unsigned short) MSG_ReadShort();
else
s->modelindex = MSG_ReadByte();
}
if (bits & E5_FRAME)
{
if (bits & E5_FRAME16)
s->frame = (unsigned short) MSG_ReadShort();
else
s->frame = MSG_ReadByte();
}
if (bits & E5_SKIN)
s->skinnum = MSG_ReadByte();
if (bits & E5_EFFECTS)
{
if (bits & E5_EFFECTS32)
s->effects = (unsigned int) MSG_ReadLong();
else if (bits & E5_EFFECTS16)
s->effects = (unsigned short) MSG_ReadShort();
else
s->effects = MSG_ReadByte();
}
if (bits & E5_ALPHA)
s->trans = MSG_ReadByte()/255.0f;
if (bits & E5_SCALE)
s->scale = MSG_ReadByte()/255.0f;
if (bits & E5_COLORMAP)
s->colormap = MSG_ReadByte();
if (bits & E5_ATTACHMENT)
{
MSG_ReadShort();
MSG_ReadByte();
// s->tagentity = (unsigned short) MSG_ReadShort();
// s->tagindex = MSG_ReadByte();
}
if (bits & E5_LIGHT)
{
MSG_ReadShort();
MSG_ReadShort();
MSG_ReadShort();
MSG_ReadShort();
MSG_ReadByte();
MSG_ReadByte();
// s->light[0] = (unsigned short) MSG_ReadShort();
// s->light[1] = (unsigned short) MSG_ReadShort();
// s->light[2] = (unsigned short) MSG_ReadShort();
// s->light[3] = (unsigned short) MSG_ReadShort();
// s->lightstyle = MSG_ReadByte();
// s->lightpflags = MSG_ReadByte();
}
if (bits & E5_GLOW)
{
MSG_ReadByte();
MSG_ReadByte();
// s->glowsize = MSG_ReadByte();
// s->glowcolor = MSG_ReadByte();
}
}
int cl_latestframenum;
void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
{
//the incoming entities do not come in in any order. :(
//well, they come in in order of priorities, but that's not useful to us.
//I guess this means we'll have to go slowly.
packet_entities_t *pack, *oldpack;
entity_state_t *to, *from;
unsigned short read;
int oldi;
qboolean remove;
cls.netchan.incoming_sequence++;
cl.validsequence=1;
cl_latestframenum = MSG_ReadLong();
pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities;
oldpack = &cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities;
from = oldpack->entities;
oldi = 0;
pack->num_entities = 0;
for (oldi = 0; oldi < oldpack->num_entities; oldi++)
{
from = &oldpack->entities[oldi];
from->flags &= ~0x80000000;
}
for (read = MSG_ReadShort(); read!=0x8000; read = MSG_ReadShort())
{
if (msg_badread)
Host_EndGame("Corrupt entitiy message packet\n");
remove = !!(read&0x8000);
read&=~0x8000;
from = &defaultstate;
for (oldi=0 ; oldi<oldpack->num_entities ; oldi++)
{
if (read == oldpack->entities[oldi].number)
{
from = &oldpack->entities[oldi];
break;
}
}
from->flags = 0x80000000;
if (remove)
{
continue;
}
if (pack->num_entities==pack->max_entities)
{
pack->max_entities = pack->num_entities+16;
pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities);
}
to = &pack->entities[pack->num_entities];
pack->num_entities++;
memcpy(to, from, sizeof(*to));
DP5_ParseDelta(to);
to->number = read;
if (!from || to->modelindex != from->modelindex || to->number != from->number) //model changed... or entity changed...
cl.lerpents[to->number].lerptime = -10;
else if (to->frame != from->frame || to->origin[0] != from->origin[0] || to->origin[1] != from->origin[1] || to->origin[2] != from->origin[2])
{
cl.lerpents[to->number].origin[0] = from->origin[0];
cl.lerpents[to->number].origin[1] = from->origin[1];
cl.lerpents[to->number].origin[2] = from->origin[2];
cl.lerpents[to->number].angles[0] = from->angles[0];
cl.lerpents[to->number].angles[1] = from->angles[1];
cl.lerpents[to->number].angles[2] = from->angles[2];
//we have three sorts of movement.
//1: stepping monsters. These have frames and tick at 10fps.
//2: physics. Objects moving acording to gravity.
//3: both. This is really awkward. And I'm really lazy.
cl.lerpents[to->number].lerprate = cl.time-cl.lerpents[to->number].lerptime; //time per update
cl.lerpents[to->number].frame = from->frame;
cl.lerpents[to->number].lerptime = cl.time;
if (cl.lerpents[to->number].lerprate>0.5)
cl.lerpents[to->number].lerprate=0.1;
//store this off for new ents to use.
// if (new)
// cl.lerpents[state->number].lerptime = newlerprate;
// else
if (to->frame == from->frame)
newlerprate = cl.time-cl.lerpents[to->number].lerptime;
}
to->flags &= ~0x80000000;
}
//the pack has all the new ones in it, now copy the old ones in that wern't removed (or changed).
for (oldi = 0; oldi < oldpack->num_entities; oldi++)
{
from = &oldpack->entities[oldi];
if (from->flags & 0x80000000)
continue;
if (pack->num_entities==pack->max_entities)
{
pack->max_entities = pack->num_entities+16;
pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities);
}
to = &pack->entities[pack->num_entities];
pack->num_entities++;
from = &oldpack->entities[oldi];
memcpy(to, from, sizeof(*to));
}
}
void CLNQ_ParseEntity(unsigned int bits) void CLNQ_ParseEntity(unsigned int bits)
{ {
@ -688,7 +1012,7 @@ void CLNQ_ParseEntity(unsigned int bits)
state = &pack->entities[pack->num_entities++]; state = &pack->entities[pack->num_entities++];
} }
from = CL_FindOldPacketEntity(num); from = CL_FindOldPacketEntity(num); //this could be optimised.
base = &cl_baselines[num]; base = &cl_baselines[num];
@ -902,7 +1226,8 @@ void CL_LinkPacketEntities (void)
vec3_t old_origin; vec3_t old_origin;
float autorotate; float autorotate;
int i; int i;
int pnum, spnum; int pnum;
//, spnum;
dlight_t *dl; dlight_t *dl;
vec3_t angles; vec3_t angles;
@ -916,20 +1241,20 @@ void CL_LinkPacketEntities (void)
// spawn light flashes, even ones coming from invisible objects // spawn light flashes, even ones coming from invisible objects
if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED)) if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 3); CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0, 3);
else if (s1->effects & EF_BLUE) else if (s1->effects & EF_BLUE)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 1); CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0, 1);
else if (s1->effects & EF_RED) else if (s1->effects & EF_RED)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 2); CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0, 2);
else if (s1->effects & EF_BRIGHTLIGHT) else if (s1->effects & EF_BRIGHTLIGHT)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand()&31), 0.1, 0); CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand()&31), 0, 0);
else if (s1->effects & EF_DIMLIGHT) else if (s1->effects & EF_DIMLIGHT)
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0.1, 0); CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand()&31), 0, 0);
// if set to invisible, skip // if set to invisible, skip
if (!s1->modelindex) if (s1->modelindex<0)
continue; continue;
#if 0
for (spnum = 0; spnum < cl.splitclients; spnum++) for (spnum = 0; spnum < cl.splitclients; spnum++)
{ {
if (s1->number == cl.viewentity[spnum]) if (s1->number == cl.viewentity[spnum])
@ -973,7 +1298,7 @@ void CL_LinkPacketEntities (void)
}*/ }*/
} }
} }
#endif
// create a new entity // create a new entity
if (cl_numvisedicts == MAX_VISEDICTS) if (cl_numvisedicts == MAX_VISEDICTS)
break; // object list is full break; // object list is full
@ -1023,7 +1348,7 @@ void CL_LinkPacketEntities (void)
// set colormap // set colormap
if (s1->colormap && (s1->colormap <= MAX_CLIENTS) if (s1->colormap && (s1->colormap <= MAX_CLIENTS)
&& (gl_nocolors.value == -1 || (ent->model && s1->modelindex == cl_playerindex))) && (gl_nocolors.value == -1 || (ent->model/* && s1->modelindex == cl_playerindex*/)))
{ {
ent->colormap = cl.players[s1->colormap-1].translations; ent->colormap = cl.players[s1->colormap-1].translations;
ent->scoreboard = &cl.players[s1->colormap-1]; ent->scoreboard = &cl.players[s1->colormap-1];
@ -1167,7 +1492,7 @@ void CL_LinkPacketEntities (void)
dl = CL_AllocDlight (s1->number); dl = CL_AllocDlight (s1->number);
VectorCopy (ent->origin, dl->origin); VectorCopy (ent->origin, dl->origin);
dl->radius = 200; dl->radius = 200;
dl->die = cl.time + 0.1; dl->die = (float)cl.time;
dl->color[0] = 0.20; dl->color[0] = 0.20;
dl->color[1] = 0.1; dl->color[1] = 0.1;
dl->color[2] = 0.05; dl->color[2] = 0.05;
@ -1178,21 +1503,21 @@ void CL_LinkPacketEntities (void)
dl = CL_AllocDlight (i); dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin); VectorCopy (ent->origin, dl->origin);
dl->radius = 120 - (rand() % 20); dl->radius = 120 - (rand() % 20);
dl->die = cl.time + 0.01; dl->die = (float)cl.time;
} }
else if (model->flags & EF_ACIDBALL) else if (model->flags & EF_ACIDBALL)
{ {
dl = CL_AllocDlight (i); dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin); VectorCopy (ent->origin, dl->origin);
dl->radius = 120 - (rand() % 20); dl->radius = 120 - (rand() % 20);
dl->die = cl.time + 0.01; dl->die = (float)cl.time;
} }
else if (model->flags & EF_SPIT) else if (model->flags & EF_SPIT)
{ {
dl = CL_AllocDlight (i); dl = CL_AllocDlight (i);
VectorCopy (ent->origin, dl->origin); VectorCopy (ent->origin, dl->origin);
dl->radius = -120 - (rand() % 20); dl->radius = -120 - (rand() % 20);
dl->die = cl.time + 0.05; dl->die = (float)cl.time;
} }
} }
} }
@ -1898,7 +2223,7 @@ void CL_SetSolidEntities (void)
{ {
state = &pak->entities[i]; state = &pak->entities[i];
if (!state->modelindex) if (state->modelindex<0)
continue; continue;
if (!cl.model_precache[state->modelindex]) if (!cl.model_precache[state->modelindex])
continue; continue;
@ -2077,6 +2402,9 @@ void CL_EmitEntities (void)
{ {
if (cls.state != ca_active) if (cls.state != ca_active)
return; return;
CL_DecayLights ();
#ifdef Q2CLIENT #ifdef Q2CLIENT
if (cls.q2server) if (cls.q2server)
{ {

View file

@ -617,6 +617,7 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum)
} }
void CLNQ_SendCmd(void) void CLNQ_SendCmd(void)
{ {
extern int cl_latestframenum, nq_dp_protocol;
usercmd_t cmd; usercmd_t cmd;
if (cls.state <= ca_connected) if (cls.state <= ca_connected)
@ -642,6 +643,13 @@ void CLNQ_SendCmd(void)
MSG_WriteString(&cls.netchan.message, va("name \"%s\"\n", name.string)); MSG_WriteString(&cls.netchan.message, va("name \"%s\"\n", name.string));
} }
if (nq_dp_protocol > 0)
{
MSG_WriteByte(&cls.netchan.message, 50);
MSG_WriteLong(&cls.netchan.message, cl_latestframenum);
}
// send the reliable message // send the reliable message
if (!cls.netchan.message.cursize) if (!cls.netchan.message.cursize)
return; // no message at all return; // no message at all

View file

@ -2548,7 +2548,6 @@ CL_RequestNextDownload();
if (cls.state == ca_active) if (cls.state == ca_active)
{ {
S_Update (r_origin, vpn, vright, vup); S_Update (r_origin, vpn, vright, vup);
CL_DecayLights ();
} }
else else
S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin);

View file

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h" #include "quakedef.h"
void CL_GetNumberedEntityInfo (int num, float *org, float *ang); void CL_GetNumberedEntityInfo (int num, float *org, float *ang);
void CLNQ_ParseDarkPlaces5Entities(void);
void R_ParseParticleEffect2 (void); void R_ParseParticleEffect2 (void);
void R_ParseParticleEffect3 (void); void R_ParseParticleEffect3 (void);
@ -312,7 +313,7 @@ void R_ParseParticleEffect4 (void);
#define Q2MZ2_WIDOW2_BEAM_SWEEP_11 210 #define Q2MZ2_WIDOW2_BEAM_SWEEP_11 210
int nq_dp_protocol;
@ -579,6 +580,8 @@ qboolean CL_CheckOrDownloadFile (char *filename, int nodelay)
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname)); MSG_WriteString (&cls.netchan.message, va("download %s", cls.downloadname));
SCR_EndLoadingPlaque(); //release console.
return false; return false;
} }
@ -1200,6 +1203,17 @@ void CL_ParseServerData (void)
Host_EndGame ("Server returned version %i, not %i\nYou probably need to upgrade.\nCheck http://www.quakeworld.net/", protover, PROTOCOL_VERSION); Host_EndGame ("Server returned version %i, not %i\nYou probably need to upgrade.\nCheck http://www.quakeworld.net/", protover, PROTOCOL_VERSION);
#endif #endif
if (cls.fteprotocolextensions & PEXT_FLOATCOORDS)
{
sizeofcoord = 4;
sizeofangle = 1;
}
else
{
sizeofcoord = 2;
sizeofangle = 1;
}
svcnt = MSG_ReadLong (); svcnt = MSG_ReadLong ();
// game directory // game directory
@ -1325,6 +1339,9 @@ void CLQ2_ParseServerData (void)
int svcnt; int svcnt;
// int cflag; // int cflag;
sizeofcoord = 2;
sizeofangle = 1;
Con_DPrintf ("Serverdata packet received.\n"); Con_DPrintf ("Serverdata packet received.\n");
// //
// wipe the client_state_t struct // wipe the client_state_t struct
@ -1416,8 +1433,20 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
protover = MSG_ReadLong (); protover = MSG_ReadLong ();
sizeofcoord = 2;
sizeofangle = 1;
nq_dp_protocol = 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 == 3502)
{
//darkplaces5
nq_dp_protocol = 5;
sizeofcoord = 4;
sizeofangle = 2;
}
else if (protover != NQ_PROTOCOL_VERSION) else if (protover != NQ_PROTOCOL_VERSION)
{ {
Host_EndGame ("Server returned version %i, not %i\nYou will need to use a different client.", protover, NQ_PROTOCOL_VERSION); Host_EndGame ("Server returned version %i, not %i\nYou will need to use a different client.", protover, NQ_PROTOCOL_VERSION);
@ -1573,12 +1602,40 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
#define SU_WEAPONFRAME (1<<12) #define SU_WEAPONFRAME (1<<12)
#define SU_ARMOR (1<<13) #define SU_ARMOR (1<<13)
#define SU_WEAPON (1<<14) #define SU_WEAPON (1<<14)
#define DPSU_EXTEND1 (1<<15)
// first extend byte
#define DPSU_PUNCHVEC1 (1<<16)
#define DPSU_PUNCHVEC2 (1<<17)
#define DPSU_PUNCHVEC3 (1<<18)
#define DPSU_VIEWZOOM (1<<19) // byte factor (0 = 0.0 (not valid), 255 = 1.0)
#define DPSU_UNUSED20 (1<<20)
#define DPSU_UNUSED21 (1<<21)
#define DPSU_UNUSED22 (1<<22)
#define DPSU_EXTEND2 (1<<23) // another byte to follow, future expansion
// second extend byte
#define DPSU_UNUSED24 (1<<24)
#define DPSU_UNUSED25 (1<<25)
#define DPSU_UNUSED26 (1<<26)
#define DPSU_UNUSED27 (1<<27)
#define DPSU_UNUSED28 (1<<28)
#define DPSU_UNUSED29 (1<<29)
#define DPSU_UNUSED30 (1<<30)
#define DPSU_EXTEND3 (1<<31) // another byte to follow, future expansion
#define DEFAULT_VIEWHEIGHT 22 #define DEFAULT_VIEWHEIGHT 22
void CLNQ_ParseClientdata (int bits) void CLNQ_ParseClientdata (int bits)
{ {
extern player_state_t *view_message;
int i, j; int i, j;
bits &= 0xffff;
if (bits & DPSU_EXTEND1)
bits |= (MSG_ReadByte() << 16);
if (bits & DPSU_EXTEND2)
bits |= (MSG_ReadByte() << 24);
if (bits & SU_VIEWHEIGHT) if (bits & SU_VIEWHEIGHT)
cl.viewheight[0] = MSG_ReadChar (); cl.viewheight[0] = MSG_ReadChar ();
else else
@ -1593,11 +1650,24 @@ void CLNQ_ParseClientdata (int bits)
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] =*/ MSG_ReadChar(); /*cl.punchangle[i] =*/ nq_dp_protocol?MSG_ReadAngle16():MSG_ReadChar();
// else // else
// cl.punchangle[i] = 0; // cl.punchangle[i] = 0;
if (bits & (DPSU_PUNCHVEC1<<i))
{
/*cl.punchvector[i] =*/ MSG_ReadCoord();
}
// else
// cl.punchvector[i] = 0;
if (bits & (SU_VELOCITY1<<i) ) if (bits & (SU_VELOCITY1<<i) )
{
if (nq_dp_protocol == 5)
/*cl.simvel[0][i] =*/ MSG_ReadFloat();
else
/*cl.mvelocity[0][i] =*/ MSG_ReadChar()/**16*/; /*cl.mvelocity[0][i] =*/ MSG_ReadChar()/**16*/;
}
// else // else
// cl.mvelocity[0][i] = 0; // cl.mvelocity[0][i] = 0;
} }
@ -1617,14 +1687,70 @@ void CLNQ_ParseClientdata (int bits)
// 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 == 5)
{
if (bits & SU_WEAPONFRAME)
i = MSG_ReadShort ();
else
i = 0;
cl.stats[0][STAT_WEAPONFRAME] = i;
if (bits & SU_ARMOR)
i = MSG_ReadShort ();
else
i = 0;
if (cl.stats[0][STAT_ARMOR] != i)
{
cl.stats[0][STAT_ARMOR] = i;
Sbar_Changed ();
}
if (bits & SU_WEAPON)
i = MSG_ReadShort ();
else
i = 0;
if (cl.stats[0][STAT_WEAPON] != i)
{
cl.stats[0][STAT_WEAPON] = i;
Sbar_Changed ();
}
i = MSG_ReadShort ();
if (cl.stats[0][STAT_HEALTH] != i)
{
cl.stats[0][STAT_HEALTH] = i;
Sbar_Changed ();
}
i = MSG_ReadShort ();
if (cl.stats[0][STAT_AMMO] != i)
{
cl.stats[0][STAT_AMMO] = i;
Sbar_Changed ();
}
for (i=0 ; i<4 ; i++)
{
j = MSG_ReadShort ();
if (cl.stats[0][STAT_SHELLS+i] != j)
{
cl.stats[0][STAT_SHELLS+i] = j;
Sbar_Changed ();
}
}
i = MSG_ReadShort ();
}
else
{
if (bits & SU_WEAPONFRAME) if (bits & SU_WEAPONFRAME)
i = MSG_ReadByte (); i = MSG_ReadByte ();
else else
i = 0; i = 0;
cl.stats[0][STAT_WEAPONFRAME] = i; cl.stats[0][STAT_WEAPONFRAME] = i;
if (view_message)
view_message->weaponframe = i;
if (bits & SU_ARMOR) if (bits & SU_ARMOR)
i = MSG_ReadByte (); i = MSG_ReadByte ();
@ -1671,6 +1797,7 @@ void CLNQ_ParseClientdata (int bits)
} }
i = MSG_ReadByte (); i = MSG_ReadByte ();
}
if (standard_quake) if (standard_quake)
{ {
@ -1688,6 +1815,21 @@ void CLNQ_ParseClientdata (int bits)
Sbar_Changed (); Sbar_Changed ();
} }
} }
if (bits & DPSU_VIEWZOOM)
{
if (nq_dp_protocol == 5)
i = (unsigned short) MSG_ReadShort();
else
i = MSG_ReadByte();
if (i < 2)
i = 2;
// cl.viewzoomnew = (float) i * (1.0f / 255.0f);
}
// else
// cl.viewzoomnew = 1;
} }
#endif #endif
/* /*
@ -2370,6 +2512,8 @@ void CL_ProcessUserInfo (int slot, player_info_t *player)
if (slot == cl.playernum[0] && player->name[0]) if (slot == cl.playernum[0] && player->name[0])
cl.spectator = player->spectator; cl.spectator = player->spectator;
player->model = NULL;
if (cls.state == ca_active) if (cls.state == ca_active)
Skin_Find (player); Skin_Find (player);
@ -3290,6 +3434,7 @@ int getplayerchatcolour(char *msg)
} }
#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
#define SHOWNET2(x, y) if(cl_shownet.value==2)Con_Printf ("%3i:%3i:%s\n", msg_readcount-1, y, x);
/* /*
===================== =====================
CL_ParseServerMessage CL_ParseServerMessage
@ -3941,7 +4086,7 @@ void CLNQ_ParseServerMessage (void)
continue; continue;
} }
SHOWNET(svc_nqstrings[cmd>(sizeof(svc_nqstrings)/sizeof(char*))?0:cmd]); SHOWNET2(svc_nqstrings[cmd>(sizeof(svc_nqstrings)/sizeof(char*))?0:cmd], cmd);
// other commands // other commands
switch (cmd) switch (cmd)
@ -4040,8 +4185,12 @@ void CLNQ_ParseServerMessage (void)
cl.last_servermessage = realtime; cl.last_servermessage = realtime;
cl.gametime = MSG_ReadFloat(); cl.gametime = MSG_ReadFloat();
cl.gametimemark = realtime; cl.gametimemark = realtime;
cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; if (nq_dp_protocol!=5)
{
cls.netchan.incoming_sequence++;
// 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;
}
break; break;
case svc_updatename: case svc_updatename:
@ -4156,6 +4305,16 @@ void CLNQ_ParseServerMessage (void)
case svcnq_effect2: case svcnq_effect2:
CL_ParseEffect(true); CL_ParseEffect(true);
break; break;
case 57://svc_entities
if (cls.signon == 4 - 1)
{ // first update is the final signon stage
cls.signon = 4;
CLNQ_SignonReply ();
}
//well, it's really any protocol, but we're only going to support version 5.
CLNQ_ParseDarkPlaces5Entities();
break;
} }
} }
} }

View file

@ -533,6 +533,7 @@ void CL_PredictMovePNum (int pnum)
float f; float f;
frame_t *from, *to = NULL; frame_t *from, *to = NULL;
int oldphysent; int oldphysent;
vec3_t lrp;
//these are to make svc_viewentity work better //these are to make svc_viewentity work better
float *vel; float *vel;
@ -609,17 +610,36 @@ void CL_PredictMovePNum (int pnum)
#ifdef PEXT_SETVIEW #ifdef PEXT_SETVIEW
if (cl.viewentity[pnum]) if (cl.viewentity[pnum])
{ {
entity_state_t *CL_FindOldPacketEntity(int num);
entity_state_t *CL_FindPacketEntity(int num); entity_state_t *CL_FindPacketEntity(int num);
entity_state_t *state; entity_state_t *state, *old;
state = CL_FindPacketEntity (cl.viewentity[pnum]); state = CL_FindPacketEntity (cl.viewentity[pnum]);
old = CL_FindOldPacketEntity (cl.viewentity[pnum]);
if (state) if (state)
{ {
if (old)
{
float f = (cl.time-cl.lerpents[cl.viewentity[pnum]].lerptime)/cl.lerpents[cl.viewentity[pnum]].lerprate;
f=1-f;
if (f<0)f=0;
if (f>1)f=1;
for (i=0 ; i<3 ; i++)
lrp[i] = state->origin[i] +
f * (old->origin[i] - state->origin[i]);
org = lrp;
}
else
org = state->origin; org = state->origin;
goto fixedorg;
} }
} }
#endif #endif
if ((cl_nopred.value|| cl.fixangle)) if ((cl_nopred.value|| cl.fixangle))
{ {
fixedorg:
VectorCopy (vel, cl.simvel[pnum]); VectorCopy (vel, cl.simvel[pnum]);
VectorCopy (org, cl.simorg[pnum]); VectorCopy (org, cl.simorg[pnum]);

View file

@ -1278,8 +1278,8 @@ void UI_Start (void)
return; return;
uivm = VM_Create(NULL, "vm/qwui", UI_SystemCalls, UI_SystemCallsEx); uivm = VM_Create(NULL, "vm/qwui", UI_SystemCalls, UI_SystemCallsEx);
// if (!uivm) //broken currently, I believe. if (!uivm) //broken currently, I believe.
// uivm = VM_Create(NULL, "vm/ui", UI_SystemCalls, UI_SystemCallsEx); uivm = VM_Create(NULL, "vm/ui", UI_SystemCalls, UI_SystemCallsEx);
if (uivm) if (uivm)
{ {
apiversion = VM_Call(uivm, UI_GETAPIVERSION, UI_API_VERSION); apiversion = VM_Call(uivm, UI_GETAPIVERSION, UI_API_VERSION);

View file

@ -205,11 +205,11 @@ typedef struct
// //
// client_state_t should hold all pieces of the client state // client_state_t should hold all pieces of the client state
// //
#define MAX_DLIGHTS 32 #define MAX_DLIGHTS 256
typedef struct dlight_s typedef struct dlight_s
{ {
int key; // so entities can reuse same entry int key; // so entities can reuse same entry
qboolean noppl; qboolean noppl, nodynamic, noflash, isstatic;
vec3_t origin; vec3_t origin;
float radius; float radius;
float die; // stop lighting after this time float die; // stop lighting after this time
@ -217,6 +217,8 @@ typedef struct dlight_s
float minlight; // don't add when contributing less float minlight; // don't add when contributing less
float color[3]; float color[3];
float channelfade[3]; float channelfade[3];
struct shadowmesh_s *worldshadowmesh;
} dlight_t; } dlight_t;
typedef struct typedef struct

View file

@ -147,6 +147,7 @@ cvar_t gl_specular = {"gl_specular", "0"};
cvar_t gl_waterripples = {"gl_waterripples", "0"}; cvar_t gl_waterripples = {"gl_waterripples", "0"};
cvar_t gl_detail = {"gl_detail", "0", NULL, CVAR_ARCHIVE}; cvar_t gl_detail = {"gl_detail", "0", NULL, CVAR_ARCHIVE};
cvar_t r_shadows = {"r_shadows", "0", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH}; cvar_t r_shadows = {"r_shadows", "0", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH};
cvar_t r_shadow_realtime_world = {"r_shadow_realtime_world", "0", NULL, CVAR_CHEAT};
cvar_t r_noaliasshadows = {"r_noaliasshadows", "0", NULL, CVAR_ARCHIVE}; cvar_t r_noaliasshadows = {"r_noaliasshadows", "0", NULL, CVAR_ARCHIVE};
cvar_t gl_maxshadowlights = {"gl_maxshadowlights", "2", NULL, CVAR_ARCHIVE}; cvar_t gl_maxshadowlights = {"gl_maxshadowlights", "2", NULL, CVAR_ARCHIVE};
cvar_t gl_bump = {"gl_bump", "0", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH}; cvar_t gl_bump = {"gl_bump", "0", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH};
@ -156,7 +157,7 @@ cvar_t gl_ati_truform = {"gl_ati_truform", "0"};
cvar_t gl_ati_truform_type = {"gl_ati_truform_type", "1"}; cvar_t gl_ati_truform_type = {"gl_ati_truform_type", "1"};
cvar_t gl_ati_truform_tesselation = {"gl_ati_truform_tesselation", "3"}; cvar_t gl_ati_truform_tesselation = {"gl_ati_truform_tesselation", "3"};
cvar_t gl_lateswap = {"gl_lateswap", "1"}; cvar_t gl_lateswap = {"gl_lateswap", "0"};
cvar_t scr_sshot_type = {"scr_sshot_type", "jpg"}; cvar_t scr_sshot_type = {"scr_sshot_type", "jpg"};
@ -253,6 +254,8 @@ void GLRenderer_Init(void)
Cvar_Register (&r_lightmap, GLRENDEREROPTIONS); Cvar_Register (&r_lightmap, GLRENDEREROPTIONS);
Cvar_Register (&r_norefresh, GLRENDEREROPTIONS); Cvar_Register (&r_norefresh, GLRENDEREROPTIONS);
Cvar_Register (&r_shadow_realtime_world, GLRENDEREROPTIONS);
Cvar_Register (&gl_clear, GLRENDEREROPTIONS); Cvar_Register (&gl_clear, GLRENDEREROPTIONS);
Cvar_Register (&gl_cull, GLRENDEREROPTIONS); Cvar_Register (&gl_cull, GLRENDEREROPTIONS);

View file

@ -43,23 +43,43 @@ void Skin_Find (player_info_t *sc)
{ {
skin_t *skin; skin_t *skin;
int i; int i;
char name[128], *s; char name[128], *s, *mn;
model_t *model;
mn = Info_ValueForKey (sc->userinfo, "model");
while(s = strchr(mn, '/'))
*mn = '\0';
if (allskins[0]) if (allskins[0])
strcpy (name, allskins); s = allskins;
else else
{ {
s = Info_ValueForKey (sc->userinfo, "skin"); s = Info_ValueForKey (sc->userinfo, "skin");
if (s && s[0]) if (!s[0])
strcpy (name, s); s = baseskin.string;
else
strcpy (name, baseskin.string);
} }
if (strstr (name, "..") || *name == '.') if (*mn)
strcpy (name, "base"); mn = va("%s/%s", mn, s);
COM_StripExtension (name, name); if (strstr (mn, "..") || *mn == '.')
mn = "base";
COM_StripExtension (mn, name);
s = strchr(name, '/');
if (s)
{
*s = '\0';
model = Mod_ForName(va("models/players/%s.mdl", name), false);
if (model->type == mod_dummy)
model = NULL;
*s = '/';
}
else
model = NULL;
sc->model = model;
for (i=0 ; i<numskins ; i++) for (i=0 ; i<numskins ; i++)
{ {

View file

@ -1231,6 +1231,9 @@ void V_RenderPlayerViews(int plnum)
SCR_VRectForPlayer(&r_refdef.vrect, plnum); SCR_VRectForPlayer(&r_refdef.vrect, plnum);
view_message = &view_frame->playerstate[cl.playernum[plnum]]; view_message = &view_frame->playerstate[cl.playernum[plnum]];
if (cls.netcon)
view_message->weaponframe = cl.stats[0][STAT_WEAPONFRAME];
cl.simangles[plnum][ROLL] = 0; // FIXME @@@ cl.simangles[plnum][ROLL] = 0; // FIXME @@@

View file

@ -348,7 +348,7 @@ typedef struct q2miptex_s
#define MAX_Q2MAP_AREAS 256 #define MAX_Q2MAP_AREAS 256
#define MAX_Q2MAP_AREAPORTALS 1024 #define MAX_Q2MAP_AREAPORTALS 1024
#define MAX_Q2MAP_PLANES 0x00030000 #define MAX_Q2MAP_PLANES 0x00040000
#define MAX_Q2MAP_NODES 65536 #define MAX_Q2MAP_NODES 65536
#define MAX_Q2MAP_BRUSHSIDES 0x40000 #define MAX_Q2MAP_BRUSHSIDES 0x40000
#define MAX_Q2MAP_LEAFS 65536 #define MAX_Q2MAP_LEAFS 65536

View file

@ -681,6 +681,7 @@ void MSG_WriteString (sizebuf_t *sb, char *s)
} }
int sizeofcoord=2; int sizeofcoord=2;
int sizeofangle=1;
float MSG_FromCoord(coorddata c, int bytes) float MSG_FromCoord(coorddata c, int bytes)
{ {
switch(bytes) switch(bytes)
@ -719,16 +720,19 @@ void MSG_WriteCoord (sizebuf_t *sb, float f)
SZ_Write (sb, (void*)&i, sizeofcoord); SZ_Write (sb, (void*)&i, sizeofcoord);
} }
void MSG_WriteAngle (sizebuf_t *sb, float f)
{
MSG_WriteByte (sb, (int)(f*256/360) & 255);
}
void MSG_WriteAngle16 (sizebuf_t *sb, float f) void MSG_WriteAngle16 (sizebuf_t *sb, float f)
{ {
MSG_WriteShort (sb, (int)(f*65536/360) & 65535); MSG_WriteShort (sb, (int)(f*65536/360) & 65535);
} }
void MSG_WriteAngle (sizebuf_t *sb, float f)
{
if (sizeofangle==2)
MSG_WriteAngle16(sb, f);
else
MSG_WriteByte (sb, (int)(f*256/360) & 255);
}
void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
{ {
int bits; int bits;
@ -990,9 +994,9 @@ float MSG_ReadCoord (void)
void MSG_ReadPos (vec3_t pos) void MSG_ReadPos (vec3_t pos)
{ {
pos[0] = MSG_ReadShort() * (1.0/8); pos[0] = MSG_ReadCoord();
pos[1] = MSG_ReadShort() * (1.0/8); pos[1] = MSG_ReadCoord();
pos[2] = MSG_ReadShort() * (1.0/8); pos[2] = MSG_ReadCoord();
} }
#define Q2NUMVERTEXNORMALS 162 #define Q2NUMVERTEXNORMALS 162
@ -1035,15 +1039,17 @@ void MSG_WriteDir (sizebuf_t *sb, vec3_t dir)
} }
MSG_WriteByte (sb, best); MSG_WriteByte (sb, best);
} }
float MSG_ReadAngle (void)
{
return MSG_ReadChar() * (360.0/256);
}
float MSG_ReadAngle16 (void) float MSG_ReadAngle16 (void)
{ {
return MSG_ReadShort() * (360.0/65536); return MSG_ReadShort() * (360.0/65536);
} }
float MSG_ReadAngle (void)
{
if (sizeofangle==2)
return MSG_ReadAngle16();
return MSG_ReadChar() * (360.0/256);
}
void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move) void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move)
{ {
@ -2200,7 +2206,7 @@ void COM_WriteFile (char *filename, void *data, int len)
f = fopen (name, "wb"); f = fopen (name, "wb");
if (!f) if (!f)
{ {
Con_Printf("Error opening %s\n", filename); Con_Printf("Error opening %s for writing\n", filename);
return; return;
} }
} }
@ -2301,17 +2307,11 @@ int FS_RebuildOSFSHash(char *filename, int filesize, void *data)
return true; return true;
} }
void FS_RebuildFSHash(void) void FS_FlushFSHash(void)
{ {
if (filesystemhash.numbuckets)
{
int i; int i;
searchpath_t *search;
if (!filesystemhash.numbuckets)
{
filesystemhash.numbuckets = 1024;
filesystemhash.bucket = BZ_Malloc(Hash_BytesForBuckets(filesystemhash.numbuckets));
}
else
{
bucket_t *bucket, *next; bucket_t *bucket, *next;
for (i = 0; i < filesystemhash.numbuckets; i++) for (i = 0; i < filesystemhash.numbuckets; i++)
@ -2327,6 +2327,23 @@ void FS_RebuildFSHash(void)
} }
} }
} }
com_fschanged = true;
}
void FS_RebuildFSHash(void)
{
int i;
searchpath_t *search;
if (!filesystemhash.numbuckets)
{
filesystemhash.numbuckets = 1024;
filesystemhash.bucket = BZ_Malloc(Hash_BytesForBuckets(filesystemhash.numbuckets));
}
else
{
FS_FlushFSHash();
}
Hash_InitTable(&filesystemhash, filesystemhash.numbuckets, filesystemhash.bucket); Hash_InitTable(&filesystemhash, filesystemhash.numbuckets, filesystemhash.bucket);
fs_hash_dups = 0; fs_hash_dups = 0;
@ -3952,6 +3969,8 @@ void COM_Gamedir (char *dir)
cl.gamedirchanged = true; cl.gamedirchanged = true;
#endif #endif
FS_FlushFSHash();
// //
// free up any current game dir info // free up any current game dir info
// //

View file

@ -112,6 +112,7 @@ typedef union { //note: reading from packets can be misaligned
float f; float f;
} coorddata; } coorddata;
extern int sizeofcoord; 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);

View file

@ -34,7 +34,7 @@ void Cache_FreeLow (int new_low_hunk);
void Cache_FreeHigh (int new_high_hunk); void Cache_FreeHigh (int new_high_hunk);
#ifdef _DEBUG #ifdef _DEBUG
#define MEMDEBUG 8192 //Debugging adds sentinels (the number is the size - I have the ram) //#define MEMDEBUG 8192 //Debugging adds sentinels (the number is the size - I have the ram)
#endif #endif
#ifndef MEMDEBUG #ifndef MEMDEBUG

View file

@ -351,7 +351,7 @@ static void R_GAliasAddDlights(mesh_t *mesh, vec3_t org, vec3_t angles)
AngleVectors(angles, axis[0], axis[1], axis[2]); AngleVectors(angles, axis[0], axis[1], axis[2]);
for (l=0 ; l<MAX_DLIGHTS ; l++) for (l=0 ; l<MAX_DLIGHTS ; l++)
{ {
if (cl_dlights[l].die >= cl.time) if (cl_dlights[l].radius)
{ {
VectorSubtract (cl_dlights[l].origin, VectorSubtract (cl_dlights[l].origin,
org, org,
@ -623,7 +623,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, entity_
galiascolourmapped_t *cm; galiascolourmapped_t *cm;
cc = (tc<<4)|bc; cc = (tc<<4)|bc;
if (!strstr(modelname, "player")) if (!strstr(modelname, "progs/player.mdl"))
skinname = modelname; skinname = modelname;
else else
{ {
@ -661,18 +661,18 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, entity_
cm->texnum.fullbright = 0; cm->texnum.fullbright = 0;
cm->texnum.base = 0; cm->texnum.base = 0;
cm->texnum.bump = texnums[cm->skinnum].bump; //can't colour bumpmapping cm->texnum.bump = texnums[cm->skinnum].bump; //can't colour bumpmapping
if (skins->ofstexels) if (skinname!=modelname && e->scoreboard && e->scoreboard->skin)
{
original = (qbyte *)skins + skins->ofstexels;
inwidth = skins->skinwidth;
inheight = skins->skinheight;
}
else if (skinname!=modelname && e->scoreboard && e->scoreboard->skin)
{ {
original = Skin_Cache8(e->scoreboard->skin); original = Skin_Cache8(e->scoreboard->skin);
inwidth = e->scoreboard->skin->width; inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height; inheight = e->scoreboard->skin->height;
} }
else if (skins->ofstexels)
{
original = (qbyte *)skins + skins->ofstexels;
inwidth = skins->skinwidth;
inheight = skins->skinheight;
}
else else
{ {
original = NULL; original = NULL;
@ -971,7 +971,7 @@ void GL_DrawAliasMesh (mesh_t *mesh, int texnum)
void R_DrawGAliasModel (entity_t *e) void R_DrawGAliasModel (entity_t *e)
{ {
model_t *clmodel = e->model; model_t *clmodel;
vec3_t mins, maxs; vec3_t mins, maxs;
vec3_t dist; vec3_t dist;
vec_t add; vec_t add;
@ -989,6 +989,18 @@ void R_DrawGAliasModel (entity_t *e)
if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1) if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1)
return; return;
{
extern int cl_playerindex;
if (e->scoreboard && e->model == cl.model_precache[cl_playerindex])
{
clmodel = e->scoreboard->model;
if (!clmodel || clmodel->type != mod_alias)
clmodel = e->model;
}
else
clmodel = e->model;
}
VectorAdd (e->origin, clmodel->mins, mins); VectorAdd (e->origin, clmodel->mins, mins);
VectorAdd (e->origin, clmodel->maxs, maxs); VectorAdd (e->origin, clmodel->maxs, maxs);
@ -1012,7 +1024,7 @@ void R_DrawGAliasModel (entity_t *e)
{ {
for (i=0 ; i<MAX_DLIGHTS ; i++) for (i=0 ; i<MAX_DLIGHTS ; i++)
{ {
if (cl_dlights[i].die >= cl.time) if (cl_dlights[i].radius)
{ {
VectorSubtract (e->origin, VectorSubtract (e->origin,
cl_dlights[i].origin, cl_dlights[i].origin,
@ -1452,7 +1464,7 @@ void R_DrawGAliasModelLighting (entity_t *e)
for (i=0 ; i<MAX_DLIGHTS ; i++) for (i=0 ; i<MAX_DLIGHTS ; i++)
{ {
if (cl_dlights[i].die >= cl.time) if (cl_dlights[i].radius)
{ {
VectorSubtract (e->origin, VectorSubtract (e->origin,
cl_dlights[i].origin, cl_dlights[i].origin,

View file

@ -61,12 +61,10 @@ void GL_BindType (int type, int texnum)
void GL_TexEnv( GLenum mode ) void GL_TexEnv( GLenum mode )
{ {
static int lastmodes[MAX_TEXTURE_UNITS] = { -1, -1 }; if ( mode != gl_state.texenvmode[gl_state.currenttmu] )
if ( mode != lastmodes[gl_state.currenttmu] )
{ {
qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode ); qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode );
lastmodes[gl_state.currenttmu] = mode; gl_state.texenvmode[gl_state.currenttmu] = mode;
} }
} }

View file

@ -420,8 +420,15 @@ void GLMod_Think (void)
if (relitsurface >= lightmodel->numsurfaces) if (relitsurface >= lightmodel->numsurfaces)
{ {
char filename[MAX_QPATH]; char filename[MAX_QPATH];
char *f;
Con_Printf("Finished lighting level\n"); Con_Printf("Finished lighting level\n");
strcpy(filename, lightmodel->name);
f = COM_SkipPath(filename);
*f = '\0';
Sys_mkdir(va("%s/%s", com_gamedir, filename));
if (lightmodel->deluxdata) if (lightmodel->deluxdata)
{ {
COM_StripExtension(lightmodel->name, filename); COM_StripExtension(lightmodel->name, filename);

View file

@ -19,6 +19,7 @@ extern cvar_t gl_part_flame;
extern cvar_t gl_part_flame; extern cvar_t gl_part_flame;
extern cvar_t gl_maxshadowlights; extern cvar_t gl_maxshadowlights;
extern cvar_t r_shadow_realtime_world;
extern int detailtexture; extern int detailtexture;
//end header confict //end header confict
@ -40,6 +41,13 @@ int ppl_specular_fragmentprogram;
//#define glBegin glEnd //#define glBegin glEnd
typedef struct shadowmesh_s {
int numindicies;
int *indicies;
vec3_t *verts;
} shadowmesh_t;
#define Q2RF_WEAPONMODEL 4 // only draw through eyes #define Q2RF_WEAPONMODEL 4 // only draw through eyes
struct { struct {
@ -837,7 +845,60 @@ void PPL_LoadSpecularFragmentProgram(void)
"MUL_SAT ocol.rgb, diff, lm;\n" "MUL_SAT ocol.rgb, diff, lm;\n"
//that's all folks. //that's all folks.
"END"; "END";
/*
//okay, the NV fallback
char *nvfp = "!!FP1.0\n"
"PARAM half = { 0.5, 0.5, 0.5, 0.5 };\n"
"PARAM negone = { -1,-1,-1,-1 };\n"
"ATTRIB tm_tc = fragment.texcoord[0];\n"
"ATTRIB lm_tc = fragment.texcoord[1];\n"
"ATTRIB cm_tc = fragment.texcoord[2];\n"
"TEMP diff, spec, nm, ld, cm, gm, lm, dm;\n"
"TEX nm.rgb, tm_tc, f[TEX1], 2D;\n" //normalmap
"TEX ld.rgb, lm_tc, f[TEX3], 2D;\n" //
"TEX dm.rgb, tm_tc, f[TEX0], 2D;\n" //deluxmap
"TEX gm.rgb, tm_tc, f[TEX4], 2D;\n" //glossmap
"TEX lm.rgb, lm_tc, f[TEX2], 2D;\n" //lightmap
"TEX cm.rgb, cm_tc, f[TEX5], CUBE;\n" //cubemap
//textures loaded - get diffuse
"MAD nm.rgb, nm, 2, negone;\n"
"MAD ld.rgb, ld, 2, negone;\n"
"DP3 diff.rgb, nm, ld;\n"
"MUL diff.rgb, diff, dm;\n"
//diff now contains the entire diffuse part of the equation.
//l 19
"MAD cm.rgb, cm, 2, negone;\n"
"DP3 spec.rgb, nm, cm;\n"
"MUL spec.rgb, spec, spec;\n"
"MUL spec.rgb, spec, spec;\n"
"MUL spec.rgb, spec, spec;\n"
"MUL spec.rgb, spec, gm;\n"
//that's the specular part done.
//we have diffuse and specular - wahoo
//combine then halve.
"ADD diff.rgb, diff, spec;\n"
//"MUL diff.rgb, diff, half;\n"
//multiply by inverse lm and output the result.
// "SUB lm.rgb, 1, lm;\n"
"MUL_SAT o[COLR].rgb, diff, lm;\n"
""
"END";
*/
ppl_specular_fragmentprogram = 0; ppl_specular_fragmentprogram = 0;
for (i = 0; i < MAXARRAYVERTS; i++) for (i = 0; i < MAXARRAYVERTS; i++)
@ -1755,6 +1816,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light)
{ {
GL_TexEnv(GL_MODULATE); GL_TexEnv(GL_MODULATE);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
GL_SelectTexture(GL_TEXTURE1_ARB); GL_SelectTexture(GL_TEXTURE1_ARB);
GL_TexEnv(GL_MODULATE); GL_TexEnv(GL_MODULATE);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
@ -1763,6 +1825,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light)
GL_SelectTexture(GL_TEXTURE0_ARB); GL_SelectTexture(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); glTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw);
glDisable(GL_TEXTURE_2D);
} }
for (; s; s=s->texturechain) for (; s; s=s->texturechain)
@ -2669,6 +2732,14 @@ void PPL_RecursiveWorldNode (dlight_t *dl)
float *v1, *v2; float *v1, *v2;
vec3_t v3, v4; vec3_t v3, v4;
if (dl->worldshadowmesh)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(vec3_t), dl->worldshadowmesh->verts);
glDrawElements(GL_TRIANGLES, dl->worldshadowmesh->numindicies, GL_UNSIGNED_INT, dl->worldshadowmesh->indicies);
return;
}
lightradius = dl->radius; lightradius = dl->radius;
lightorg[0] = dl->origin[0]+0.5; lightorg[0] = dl->origin[0]+0.5;
@ -2989,7 +3060,7 @@ void PPL_UpdateNodeShadowFrames(qbyte *lvis)
} }
} }
} }
/*
#if 1 //DP's stolen code #if 1 //DP's stolen code
static void GL_Scissor (int x, int y, int width, int height) static void GL_Scissor (int x, int y, int width, int height)
{ {
@ -3048,7 +3119,10 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
v[1] = (i & 2) ? mins[1] : maxs[1]; v[1] = (i & 2) ? mins[1] : maxs[1];
v[2] = (i & 4) ? mins[2] : maxs[2]; v[2] = (i & 4) ? mins[2] : maxs[2];
v[3] = 1.0f; v[3] = 1.0f;
GL_TransformToScreen(v, v2); ML_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, vid.width/vid.height, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
// GL_TransformToScreen(v, v2);
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]); //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
x = v2[0]; x = v2[0];
y = v2[1]; y = v2[1];
@ -3115,7 +3189,10 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_refdef.vieworg[1]; v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_refdef.vieworg[1];
v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_refdef.vieworg[2]; v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_refdef.vieworg[2];
v[3] = 1.0f; v[3] = 1.0f;
GL_TransformToScreen(v, v2); ML_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, vid.width/vid.height, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
// GL_TransformToScreen(v, v2);
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]); //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
x = v2[0]; x = v2[0];
y = v2[1]; y = v2[1];
@ -3143,6 +3220,8 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
v[2] = (i & 4) ? mins[2] : maxs[2]; v[2] = (i & 4) ? mins[2] : maxs[2];
v[3] = 1.0f; v[3] = 1.0f;
GL_TransformToScreen(v, v2); GL_TransformToScreen(v, v2);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]); //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
if (v2[2] > 0) if (v2[2] > 0)
{ {
@ -3174,7 +3253,7 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
return false; return false;
} }
#endif #endif
*/
void CL_NewDlight (int key, float x, float y, float z, float radius, float time, void CL_NewDlight (int key, float x, float y, float z, float radius, float time,
int type); int type);
//generates stencil shadows of the world geometry. //generates stencil shadows of the world geometry.
@ -3205,8 +3284,8 @@ void PPL_AddLight(dlight_t *dl)
if (R_CullBox(mins, maxs)) if (R_CullBox(mins, maxs))
return; return;
// if (PPL_ScissorForBox(mins, maxs)) if (PPL_ScissorForBox(mins, maxs))
// return; //was culled. return; //was culled.
if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3) if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
i = cl.worldmodel->funcs.LeafForPoint(r_refdef.vieworg, cl.worldmodel); i = cl.worldmodel->funcs.LeafForPoint(r_refdef.vieworg, cl.worldmodel);
@ -3222,7 +3301,7 @@ void PPL_AddLight(dlight_t *dl)
if (!PPL_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect. if (!PPL_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
return; return;
// glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
glDisable(GL_BLEND); glDisable(GL_BLEND);
@ -3410,12 +3489,16 @@ void PPL_DrawWorld (void)
{ {
for (l = cl_dlights, i=0 ; i<MAX_DLIGHTS ; i++, l++) for (l = cl_dlights, i=0 ; i<MAX_DLIGHTS ; i++, l++)
{ {
if (l->die < cl.time || !l->radius || l->noppl) if (!l->radius || l->noppl)
continue; continue;
if (l->color[0]<0) if (l->color[0]<0)
continue; //quick check for darklight continue; //quick check for darklight
if (!maxshadowlights--)
break; if (l->isstatic)
{
if (!r_shadow_realtime_world.value)
continue;
}
mins[0] = l->origin[0] - l->radius; mins[0] = l->origin[0] - l->radius;
mins[1] = l->origin[1] - l->radius; mins[1] = l->origin[1] - l->radius;
@ -3428,16 +3511,24 @@ void PPL_DrawWorld (void)
if (R_CullSphere(l->origin, l->radius)) if (R_CullSphere(l->origin, l->radius))
continue; continue;
if (!maxshadowlights--)
break;
if(!l->isstatic)
{
l->color[0]*=2.5; l->color[0]*=2.5;
l->color[1]*=2.5; l->color[1]*=2.5;
l->color[2]*=2.5; l->color[2]*=2.5;
}
TRACE(("dbg: calling PPL_AddLight\n")); TRACE(("dbg: calling PPL_AddLight\n"));
PPL_AddLight(l); PPL_AddLight(l);
if(!l->isstatic)
{
l->color[0]/=2.5; l->color[0]/=2.5;
l->color[1]/=2.5; l->color[1]/=2.5;
l->color[2]/=2.5; l->color[2]/=2.5;
} }
}
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
} }

View file

@ -157,7 +157,7 @@ void R_RenderDlights (void)
l = cl_dlights; l = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, l++) for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
{ {
if (l->die < cl.time || !l->radius) if (!l->radius || l->noflash)
continue; continue;
R_RenderDlight (l); R_RenderDlight (l);
} }
@ -349,7 +349,7 @@ void GLR_PushDlights (void)
l = cl_dlights; l = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, l++) for (i=0 ; i<MAX_DLIGHTS ; i++, l++)
{ {
if (l->die < cl.time || !l->radius) if (!l->radius || l->nodynamic)
continue; continue;
cl.worldmodel->funcs.MarkLights( l, 1<<i, cl.worldmodel->nodes ); cl.worldmodel->funcs.MarkLights( l, 1<<i, cl.worldmodel->nodes );
} }

View file

@ -827,6 +827,67 @@ void R_TranslatePlayerSkin (int playernum)
} }
} }
void R_LoadRTLights(void)
{
dlight_t *dl;
char fname[MAX_QPATH];
char *file;
char *end;
vec3_t org;
float radius;
vec3_t rgb;
COM_StripExtension(cl.worldmodel->name, fname);
strncat(fname, ".rtlights", MAX_QPATH-1);
file = COM_LoadTempFile(fname);
if (!file)
return;
while(1)
{
end = strchr(file, '\n');
if (!end)
end = file + strlen(file);
if (end == file)
break;
*end = '\0';
file = COM_Parse(file);
org[0] = atof(com_token);
file = COM_Parse(file);
org[1] = atof(com_token);
file = COM_Parse(file);
org[2] = atof(com_token);
file = COM_Parse(file);
radius = atof(com_token);
file = COM_Parse(file);
rgb[0] = atof(com_token);
file = COM_Parse(file);
rgb[1] = atof(com_token);
file = COM_Parse(file);
rgb[2] = atof(com_token);
if (!file)
break;
dl = CL_AllocDlight(0);
VectorCopy(org, dl->origin);
dl->radius = radius;
VectorCopy(rgb, dl->color);
dl->die = cl.time + 0x7fffffff;
dl->isstatic = true;
dl->nodynamic = true;
dl->noflash = true;
file = end+1;
}
}
/* /*
=============== ===============
R_NewMap R_NewMap
@ -899,6 +960,12 @@ TRACE(("dbg: GLR_NewMap: ui\n"));
UI_Reset(); UI_Reset();
TRACE(("dbg: GLR_NewMap: tp\n")); TRACE(("dbg: GLR_NewMap: tp\n"));
TP_NewMap(); TP_NewMap();
if (r_shadows.value)
{
R_LoadRTLights();
}
} }
void GLR_PreNewMap(void) void GLR_PreNewMap(void)

View file

@ -198,7 +198,10 @@ void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...)
Q_vsnprintf (string,sizeof(string)-1, error,argptr); Q_vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr); va_end (argptr);
{
void SV_EndRedirect (void);
SV_EndRedirect(); SV_EndRedirect();
}
// PR_PrintStatement (pr_statements + pr_xstatement); // PR_PrintStatement (pr_statements + pr_xstatement);
PR_StackTrace (progfuncs); PR_StackTrace (progfuncs);

View file

@ -3306,6 +3306,7 @@ reloop:
if (def_ret.temp->used && ao != &def_ret) if (def_ret.temp->used && ao != &def_ret)
QCC_PR_ParseWarning(0, "RETURN VALUE ALREADY IN USE"); QCC_PR_ParseWarning(0, "RETURN VALUE ALREADY IN USE");
def_parms[0].type = type_float;
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], ao, &def_parms[0], NULL)); QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_STORE_F], ao, &def_parms[0], NULL));
if (QCC_PR_Check("=")) if (QCC_PR_Check("="))
@ -4646,6 +4647,7 @@ void QCC_PR_ParseStatement (void)
} }
else else
{ {
// QCC_PR_ParseWarning(0, "using the else");
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2)); QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2));
patch1->b = &statements[numstatements] - patch1; patch1->b = &statements[numstatements] - patch1;
QCC_PR_ParseStatement (); QCC_PR_ParseStatement ();
@ -4675,6 +4677,13 @@ void QCC_PR_ParseStatement (void)
e = QCC_PR_Expression (TOP_PRIORITY); e = QCC_PR_Expression (TOP_PRIORITY);
conditional = false; conditional = false;
if (e == &def_ret)
{ //copy it out, so our hack just below doesn't crash us
if (e->type->type == ev_vector)
e = QCC_PR_Statement(pr_opcodes+OP_STORE_V, QCC_GetTemp(type_vector), e, NULL);
else
e = QCC_PR_Statement(pr_opcodes+OP_STORE_F, QCC_GetTemp(type_float), e, NULL);
}
et = e->temp; et = e->temp;
e->temp = NULL; //so noone frees it until we finish this loop e->temp = NULL; //so noone frees it until we finish this loop
@ -4745,11 +4754,18 @@ void QCC_PR_ParseStatement (void)
oldst = numstatements; oldst = numstatements;
QCC_PR_ParseStatement (); QCC_PR_ParseStatement ();
/* if (oldst != numstatements && QCC_PR_) //this is so that a missing goto at the end of your switch doesn't end up in the jumptable again
if (oldst == numstatements || (QCC_AStatementJumpsTo(numstatements-1, oldst, numstatements-1)))
{ {
}
else*/
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2)); //the P1 statement/the theyforgotthebreak statement. QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_GOTO], 0, 0, &patch2)); //the P1 statement/the theyforgotthebreak statement.
// QCC_PR_ParseWarning(0, "emitted goto");
}
else
{
patch2 = NULL;
// QCC_PR_ParseWarning(0, "No goto");
}
if (hcstyle) if (hcstyle)
patch1->b = &statements[numstatements] - patch1; //the goto start part patch1->b = &statements[numstatements] - patch1; //the goto start part
else else
@ -4850,6 +4866,7 @@ void QCC_PR_ParseStatement (void)
patch3 = &statements[numstatements]; patch3 = &statements[numstatements];
if (patch2)
patch2->a = patch3 - patch2; //set P1 jump patch2->a = patch3 - patch2; //set P1 jump
if (breaks != num_breaks) if (breaks != num_breaks)
@ -5493,10 +5510,13 @@ void QCC_CheckForDeadAndMissingReturns(int first, int last, int rettype)
if (rettype != ev_void) if (rettype != ev_void)
if (statements[last-1].op != OP_RETURN) if (statements[last-1].op != OP_RETURN)
{
if (statements[last-1].op != OP_GOTO || (signed)statements[last-1].a > 0)
{ {
QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name ); QCC_PR_ParseWarning(WARN_MISSINGRETURN, "%s: not all control paths return a value", pr_scope->name );
return; return;
} }
}
for (st = first; st < last; st++) for (st = first; st < last; st++)
{ {
@ -5578,7 +5598,7 @@ int QCC_AStatementJumpsTo(int targ, int first, int last)
{ {
if (pr_opcodes[statements[st].op].type_a == NULL) if (pr_opcodes[statements[st].op].type_a == NULL)
{ {
if (st + (signed)statements[st].a == targ) if (st + (signed)statements[st].a == targ && statements[st].a)
{ {
return true; return true;
} }

View file

@ -404,6 +404,12 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
multicasttype=MULTICAST_PHS; multicasttype=MULTICAST_PHS;
break; break;
case 74: //TE_FLAMEJET
protocollen = sizeofcoord*6 +sizeof(qbyte)*3;
multicastpos = 2;
multicasttype=MULTICAST_PVS;
break;
case 76: case 76:
protocollen = sizeofcoord*9+sizeof(qbyte)*2; protocollen = sizeofcoord*9+sizeof(qbyte)*2;
multicastpos = 2; multicastpos = 2;

View file

@ -6210,6 +6210,7 @@ void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
chain = (edict_t *) *prinst->parms->sv_edicts; chain = (edict_t *) *prinst->parms->sv_edicts;
f = G_INT(OFS_PARM0)+prinst->fieldadjust; f = G_INT(OFS_PARM0)+prinst->fieldadjust;
f += prinst->parms->edictsize/4;
s = PR_GetStringOfs(prinst, OFS_PARM1); s = PR_GetStringOfs(prinst, OFS_PARM1);
for (i = 1; i < *prinst->parms->sv_num_edicts; i++) for (i = 1; i < *prinst->parms->sv_num_edicts; i++)
@ -6217,7 +6218,7 @@ void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent = EDICT_NUM(prinst, i); ent = EDICT_NUM(prinst, i);
if (ent->isfree) if (ent->isfree)
continue; continue;
t = *(string_t *)&((float*)&ent->v)[f] + prinst->stringtable; t = *(string_t *)&((float*)ent)[f] + prinst->stringtable;
if (!t) if (!t)
continue; continue;
if (strcmp(t, s)) if (strcmp(t, s))

View file

@ -545,6 +545,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
else else
sizeofcoord = 2; sizeofcoord = 2;
sizeofangle = 1;
VoteFlushAll(); VoteFlushAll();
#ifndef SERVERONLY #ifndef SERVERONLY
D_FlushCaches(); D_FlushCaches();