1
0
Fork 0
forked from fte/fteqw

Rewrote a few bsp tracing stuff (primarily for heightmap things).

Q3 client and server support is in.
heightmaps are in.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1252 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-08-26 22:56:51 +00:00
parent de7be87de0
commit 1130dea569
75 changed files with 3420 additions and 3083 deletions

View file

@ -296,7 +296,7 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
to->skinnum = MSG_ReadByte(); to->skinnum = MSG_ReadByte();
if (bits & U_EFFECTS) if (bits & U_EFFECTS)
to->effects = MSG_ReadByte(); to->effects = (to->effects&0xff00)|MSG_ReadByte();
if (bits & U_ORIGIN1) if (bits & U_ORIGIN1)
to->origin[0] = MSG_ReadCoord (); to->origin[0] = MSG_ReadCoord ();
@ -382,21 +382,28 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
to->lightpflags = MSG_ReadByte(); to->lightpflags = MSG_ReadByte();
} }
if (morebits & U_EFFECTS16)
to->effects = (to->effects&0x00ff)|(MSG_ReadByte()<<8);
if (to->number>=cl.maxlerpents)
{
cl.maxlerpents = to->number+16;
cl.lerpents = BZ_Realloc(cl.lerpents, sizeof(entity_state_t)*cl.maxlerpents);
}
VectorSubtract(to->origin, from->origin, move); VectorSubtract(to->origin, from->origin, move);
#ifdef HALFLIFEMODELS
if (to->frame != from->frame) if (to->frame != from->frame)
{ {
cl.lerpents[to->number].oldframechange = cl.lerpents[to->number].framechange; //marked for hl models cl.lerpents[to->number].oldframechange = cl.lerpents[to->number].framechange; //marked for hl models
cl.lerpents[to->number].framechange = cl.time; //marked for hl models cl.lerpents[to->number].framechange = cl.time; //marked for hl models
} }
#endif
if (to->modelindex != from->modelindex || to->number != from->number || VectorLength(move)>500) //model changed... or entity changed... if (to->modelindex != from->modelindex || to->number != from->number || VectorLength(move)>500) //model changed... or entity changed...
{ {
#ifdef HALFLIFEMODELS
cl.lerpents[to->number].oldframechange = cl.lerpents[to->number].framechange; //marked for hl models cl.lerpents[to->number].oldframechange = cl.lerpents[to->number].framechange; //marked for hl models
cl.lerpents[to->number].framechange = cl.time; //marked for hl models cl.lerpents[to->number].framechange = cl.time; //marked for hl models
#endif
cl.lerpents[to->number].lerptime = -10; cl.lerpents[to->number].lerptime = -10;
cl.lerpents[to->number].lerprate = 0; cl.lerpents[to->number].lerprate = 0;
@ -797,6 +804,7 @@ void DP5_ParseDelta(entity_state_t *s)
num = s->number; num = s->number;
*s = defaultstate; *s = defaultstate;
s->trans = 255; s->trans = 255;
s->scale = 16;
s->number = num; s->number = num;
// s->active = true; // s->active = true;
} }
@ -936,6 +944,9 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
remove = !!(read&0x8000); remove = !!(read&0x8000);
read&=~0x8000; read&=~0x8000;
if (read >= MAX_EDICTS)
Host_EndGame("Too many entities.\n");
from = &defaultstate; from = &defaultstate;
for (oldi=0 ; oldi<oldpack->num_entities ; oldi++) for (oldi=0 ; oldi<oldpack->num_entities ; oldi++)
@ -958,6 +969,11 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
pack->max_entities = pack->num_entities+16; pack->max_entities = pack->num_entities+16;
pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities); pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities);
} }
if (read>=cl.maxlerpents)
{
cl.maxlerpents = read+16;
cl.lerpents = BZ_Realloc(cl.lerpents, sizeof(entity_state_t)*cl.maxlerpents);
}
to = &pack->entities[pack->num_entities]; to = &pack->entities[pack->num_entities];
pack->num_entities++; pack->num_entities++;
@ -1114,6 +1130,12 @@ void CLNQ_ParseEntity(unsigned int bits)
state = &pack->entities[pack->num_entities++]; state = &pack->entities[pack->num_entities++];
} }
if (num>=cl.maxlerpents)
{
cl.maxlerpents = num+16;
cl.lerpents = BZ_Realloc(cl.lerpents, sizeof(entity_state_t)*cl.maxlerpents);
}
from = CL_FindOldPacketEntity(num); //this could be optimised. from = CL_FindOldPacketEntity(num); //this could be optimised.
base = &cl_baselines[num]; base = &cl_baselines[num];
@ -1553,6 +1575,8 @@ void CL_LinkPacketEntities (void)
ent->flags = s1->flags; ent->flags = s1->flags;
if (s1->effects & NQEF_ADDATIVE) if (s1->effects & NQEF_ADDATIVE)
ent->flags |= Q2RF_ADDATIVE; ent->flags |= Q2RF_ADDATIVE;
if (s1->effects & EF_NODEPTHTEST)
ent->flags |= RF_NODEPTHTEST;
// set colormap // set colormap
if (s1->colormap && (s1->colormap <= MAX_CLIENTS) if (s1->colormap && (s1->colormap <= MAX_CLIENTS)
@ -2146,6 +2170,15 @@ guess_pm_type:
state->pm_type = PM_NORMAL; state->pm_type = PM_NORMAL;
} }
if (cl.lerpplayers[num].frame != state->frame)
{
cl.lerpplayers[num].oldframechange = cl.lerpplayers[num].framechange;
cl.lerpplayers[num].framechange = cl.time;
cl.lerpplayers[num].frame = state->frame;
//don't care about position interpolation.
}
TP_ParsePlayerInfo(oldstate, state, info); TP_ParsePlayerInfo(oldstate, state, info);
} }
@ -2308,8 +2341,8 @@ void CL_LinkPlayers (void)
ent->model = cl.model_precache[state->modelindex]; ent->model = cl.model_precache[state->modelindex];
ent->skinnum = state->skinnum; ent->skinnum = state->skinnum;
ent->frame1time = cl.time - cl.lerpents[j].framechange; ent->frame1time = cl.time - cl.lerpplayers[j].framechange;
ent->frame2time = cl.time - cl.lerpents[j].oldframechange; ent->frame2time = cl.time - cl.lerpplayers[j].oldframechange;
ent->frame = state->frame; ent->frame = state->frame;
ent->oldframe = state->oldframe; ent->oldframe = state->oldframe;

View file

@ -573,6 +573,13 @@ void CL_CheckForResend (void)
connect_time = realtime+t2-t1; // for retransmit requests connect_time = realtime+t2-t1; // for retransmit requests
#ifdef Q3CLIENT
//Q3 clients send thier cdkey to the q3 authorize server.
//they send this packet with the challenge.
//and the server will refuse the client if it hasn't sent it.
CLQ3_SendAuthPacket(adr);
#endif
#ifdef NQPROT #ifdef NQPROT
if (connect_type || ((connect_tries&3)==3)) if (connect_type || ((connect_tries&3)==3))
{ {
@ -833,6 +840,9 @@ void CL_ClearState (void)
Media_PlayFilm(""); Media_PlayFilm("");
} }
if (cl.lerpents)
BZ_Free(cl.lerpents);
// wipe the entire cl structure // wipe the entire cl structure
memset (&cl, 0, sizeof(cl)); memset (&cl, 0, sizeof(cl));
@ -1836,6 +1846,7 @@ void CL_ConnectionlessPacket (void)
if (c == 'd') //note - this conflicts with qw masters, our browser uses a different socket. if (c == 'd') //note - this conflicts with qw masters, our browser uses a different socket.
{ {
Con_Printf ("d\n");
if (cls.demoplayback != DPB_NONE) if (cls.demoplayback != DPB_NONE)
{ {
Con_Printf("Disconnect\n"); Con_Printf("Disconnect\n");
@ -2967,6 +2978,7 @@ void Host_Init (quakeparms_t *parms)
Cbuf_AddText ("exec hexen.rc\n", RESTRICT_LOCAL); Cbuf_AddText ("exec hexen.rc\n", RESTRICT_LOCAL);
else else
{ //they didn't give us an rc file! { //they didn't give us an rc file!
Cbuf_AddText ("bind ~ toggleconsole\n", RESTRICT_LOCAL); //we expect default.cfg to not exist. :(
Cbuf_AddText ("exec default.cfg\n", RESTRICT_LOCAL); Cbuf_AddText ("exec default.cfg\n", RESTRICT_LOCAL);
Cbuf_AddText ("exec config.cfg\n", RESTRICT_LOCAL); Cbuf_AddText ("exec config.cfg\n", RESTRICT_LOCAL);
Cbuf_AddText ("exec autoexec.cfg\n", RESTRICT_LOCAL); Cbuf_AddText ("exec autoexec.cfg\n", RESTRICT_LOCAL);

View file

@ -5,6 +5,7 @@
#define SS_FAVORITE 8 //filter all others. #define SS_FAVORITE 8 //filter all others.
#define SS_KEEPINFO 16 #define SS_KEEPINFO 16
#define SS_DARKPLACES 32 #define SS_DARKPLACES 32
#define SS_QUAKE3 64
//despite not supporting nq or q2, we still load them. We just filter them. This is to make sure we properly write the listing files. //despite not supporting nq or q2, we still load them. We just filter them. This is to make sure we properly write the listing files.
@ -13,14 +14,17 @@ enum {
MT_MASTERHTTP, //an http/ftp based master server MT_MASTERHTTP, //an http/ftp based master server
MT_BCASTQW, //-1status MT_BCASTQW, //-1status
MT_BCASTQ2, //-1status MT_BCASTQ2, //-1status
MT_BCASTQ3,
MT_BCASTNQ, //see code MT_BCASTNQ, //see code
MT_BCASTDP, MT_BCASTDP,
MT_SINGLEQW, //-1status MT_SINGLEQW, //-1status
MT_SINGLEQ2, //-1status MT_SINGLEQ2, //-1status
MT_SINGLEQ3,
MT_SINGLENQ, //see code. MT_SINGLENQ, //see code.
MT_SINGLEDP, MT_SINGLEDP,
MT_MASTERQW, //c\n\0 MT_MASTERQW, //c\n\0
MT_MASTERQ2, //query MT_MASTERQ2, //query
MT_MASTERQ3,
MT_MASTERDP //-1getservers %s 3 empty full\x0A MT_MASTERDP //-1getservers %s 3 empty full\x0A
}; };

View file

@ -589,6 +589,9 @@ void Model_NextDownload (void)
cl.worldmodel = cl.model_precache[1]; cl.worldmodel = cl.model_precache[1];
} }
if (cl.worldmodel->type != mod_brush && cl.worldmodel->type != mod_heightmap)
Host_EndGame("Worldmodel must be a bsp of some sort\n");
if (!R_CheckSky()) if (!R_CheckSky())
return; return;
if (!Wad_NextDownload()) //world is required to be loaded. if (!Wad_NextDownload()) //world is required to be loaded.
@ -738,11 +741,11 @@ void CL_RequestNextDownload (void)
{ {
if (cl.downloadlist) if (cl.downloadlist)
{ {
if (!COM_FCheckExists (cl.downloadlist->name)) if (!COM_FCheckExists (cl.downloadlist->localname))
CL_SendDownloadRequest(cl.downloadlist->name, cl.downloadlist->localname); CL_SendDownloadRequest(cl.downloadlist->name, cl.downloadlist->localname);
else else
{ {
Con_Printf("Already have %s\n", cl.downloadlist->name); Con_Printf("Already have %s\n", cl.downloadlist->localname);
CL_DisenqueDownload(cl.downloadlist->name); CL_DisenqueDownload(cl.downloadlist->name);
} }
return; return;

View file

@ -27,8 +27,6 @@ extern frame_t *view_frame;
#define MAX_PARSE_ENTITIES 1024 #define MAX_PARSE_ENTITIES 1024
extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES]; extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles);
extern float pm_airaccelerate; extern float pm_airaccelerate;
@ -105,7 +103,6 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
{ {
int i, x, zd, zu; int i, x, zd, zu;
trace_t trace; trace_t trace;
int headnode;
float *angles; float *angles;
entity_state_t *ent; entity_state_t *ent;
int num; int num;
@ -128,7 +125,6 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
cmodel = cl.model_precache[ent->modelindex]; cmodel = cl.model_precache[ent->modelindex];
if (!cmodel) if (!cmodel)
continue; continue;
headnode = cmodel->hulls[0].firstclipnode;
angles = ent->angles; angles = ent->angles;
} }
else else
@ -142,15 +138,15 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
bmins[2] = -zd; bmins[2] = -zd;
bmaxs[2] = zu; bmaxs[2] = zu;
headnode = CM_HeadnodeForBox (bmins, bmaxs); cmodel = CM_TempBoxModel (bmins, bmaxs);
angles = vec3_origin; // boxes don't rotate angles = vec3_origin; // boxes don't rotate
} }
if (tr->allsolid) if (tr->allsolid)
return; return;
trace = CM_TransformedBoxTrace (start, end, trace = CM_TransformedBoxTrace (cmodel, start, end,
mins, maxs, headnode, MASK_PLAYERSOLID, mins, maxs, MASK_PLAYERSOLID,
ent->origin, angles); ent->origin, angles);
if (trace.allsolid || trace.startsolid || if (trace.allsolid || trace.startsolid ||
@ -182,7 +178,7 @@ q2trace_t VARGS CLQ2_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end
trace_t t; trace_t t;
// check against world // check against world
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID); t = CM_BoxTrace (cl.worldmodel, start, end, mins, maxs, MASK_PLAYERSOLID);
if (t.fraction < 1.0) if (t.fraction < 1.0)
t.ent = (struct edict_s *)1; t.ent = (struct edict_s *)1;
@ -209,7 +205,7 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
model_t *cmodel; model_t *cmodel;
int contents; int contents;
contents = CM_PointContents (point, 0); contents = CM_PointContents (cl.worldmodel, point);
for (i=0 ; i<cl.q2frame.num_entities ; i++) for (i=0 ; i<cl.q2frame.num_entities ; i++)
{ {
@ -223,7 +219,7 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
if (!cmodel) if (!cmodel)
continue; continue;
contents |= CM_TransformedPointContents (point, cmodel->hulls[0].firstclipnode, ent->origin, ent->angles); contents |= CM_TransformedPointContents (cl.worldmodel, point, cmodel->hulls[0].firstclipnode, ent->origin, ent->angles);
} }
return contents; return contents;
@ -347,7 +343,7 @@ void CL_NudgePosition (void)
vec3_t base; vec3_t base;
int x, y; int x, y;
if (cl.worldmodel->hulls->funcs.HullPointContents (cl.worldmodel->hulls, pmove.origin) == FTECONTENTS_EMPTY) if (cl.worldmodel->funcs.PointContents (cl.worldmodel, pmove.origin) == FTECONTENTS_EMPTY)
return; return;
VectorCopy (pmove.origin, base); VectorCopy (pmove.origin, base);
@ -357,7 +353,7 @@ void CL_NudgePosition (void)
{ {
pmove.origin[0] = base[0] + x * 1.0/8; pmove.origin[0] = base[0] + x * 1.0/8;
pmove.origin[1] = base[1] + y * 1.0/8; pmove.origin[1] = base[1] + y * 1.0/8;
if (cl.worldmodel->hulls->funcs.HullPointContents (cl.worldmodel->hulls, pmove.origin) == FTECONTENTS_EMPTY) if (cl.worldmodel->funcs.PointContents (cl.worldmodel, pmove.origin) == FTECONTENTS_EMPTY)
return; return;
} }
} }

View file

@ -792,7 +792,8 @@ void CL_ParseTEnt (void)
P_ParticleExplosion (pos); P_ParticleExplosion (pos);
// light // light
if (r_explosionlight.value) { if (r_explosionlight.value)
{
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);
dl->radius = 150 + bound(0, r_explosionlight.value, 1)*200; dl->radius = 150 + bound(0, r_explosionlight.value, 1)*200;
@ -828,7 +829,8 @@ void CL_ParseTEnt (void)
P_ParticleExplosion (pos); P_ParticleExplosion (pos);
// light // light
if (r_explosionlight.value) { if (r_explosionlight.value)
{
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);
dl->radius = 150 + bound(0, r_explosionlight.value, 1)*200; dl->radius = 150 + bound(0, r_explosionlight.value, 1)*200;
@ -864,7 +866,8 @@ void CL_ParseTEnt (void)
P_ParticleExplosion (pos); P_ParticleExplosion (pos);
// light // light
if (r_explosionlight.value) { if (r_explosionlight.value)
{
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);
dl->radius = 150 + bound(0, r_explosionlight.value, 1)*200; dl->radius = 150 + bound(0, r_explosionlight.value, 1)*200;
@ -890,7 +893,8 @@ void CL_ParseTEnt (void)
P_ParticleExplosion (pos); P_ParticleExplosion (pos);
// light // light
if (r_explosionlight.value) { if (r_explosionlight.value)
{
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);
// no point in doing this the fuh/ez way // no point in doing this the fuh/ez way
@ -1757,7 +1761,8 @@ void CLQ2_ParseTEnt (void)
P_ParticleExplosion (pos); P_ParticleExplosion (pos);
// light // light
if (r_explosionlight.value) { if (r_explosionlight.value)
{
dlight_t *dl; dlight_t *dl;
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);
@ -1843,7 +1848,8 @@ void CLQ2_ParseTEnt (void)
P_ParticleExplosion (pos); P_ParticleExplosion (pos);
// light // light
if (r_explosionlight.value) { if (r_explosionlight.value)
{
dlight_t *dl; dlight_t *dl;
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);

View file

@ -5,6 +5,202 @@
#ifdef VM_UI #ifdef VM_UI
#ifdef Q3CLIENT
#include "clq3defs.h"
#else
typedef struct {
int handle;
int modificationCount;
float value;
int integer;
char string[256];
} vmcvar_t;
#endif
void GLDraw_ShaderImage (int x, int y, int w, int h, float s1, float t1, float s2, float t2, struct shader_s *pic);
#define MAX_TOKENLENGTH 1024
typedef struct pc_token_s
{
int type;
int subtype;
int intvalue;
float floatvalue;
char string[MAX_TOKENLENGTH];
} pc_token_t;
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
#define TT_NUMBER 3 // number
#define TT_NAME 4 // name
#define TT_PUNCTUATION 5 // punctuation
#define SCRIPT_MAXDEPTH 64
#define SCRIPT_DEFINELENGTH 256
typedef struct {
char *filestack[SCRIPT_MAXDEPTH];
char *originalfilestack[SCRIPT_MAXDEPTH];
char filename[MAX_QPATH][SCRIPT_MAXDEPTH];
int stackdepth;
char *defines;
int numdefines;
} script_t;
script_t *scripts;
int maxscripts;
#define Q3SCRIPTPUNCTUATION "(,{})(\':;=!><&|+-"
int Script_Read(int handle, pc_token_t *token)
{
int i;
script_t *sc = scripts+handle-1;
for(;;)
{
if (!sc->stackdepth)
return 0;
sc->filestack[sc->stackdepth-1] = COM_ParseToken(sc->filestack[sc->stackdepth-1], Q3SCRIPTPUNCTUATION);
if (!strcmp(com_token, "#include"))
{
sc->filestack[sc->stackdepth-1] = COM_ParseToken(sc->filestack[sc->stackdepth-1], Q3SCRIPTPUNCTUATION);
if (sc->stackdepth == SCRIPT_MAXDEPTH) //just don't enter it
continue;
if (sc->originalfilestack[sc->stackdepth])
BZ_Free(sc->originalfilestack[sc->stackdepth]);
sc->filestack[sc->stackdepth] = sc->originalfilestack[sc->stackdepth] = COM_LoadMallocFile(com_token);
sc->stackdepth++;
continue;
}
if (!strcmp(com_token, "#define"))
{
sc->numdefines++;
sc->defines = BZ_Realloc(sc->defines, sc->numdefines*SCRIPT_DEFINELENGTH*2);
sc->filestack[sc->stackdepth-1] = COM_ParseToken(sc->filestack[sc->stackdepth-1], Q3SCRIPTPUNCTUATION);
Q_strncpyz(sc->defines+SCRIPT_DEFINELENGTH*2*(sc->numdefines-1), com_token, SCRIPT_DEFINELENGTH);
sc->filestack[sc->stackdepth-1] = COM_ParseToken(sc->filestack[sc->stackdepth-1], Q3SCRIPTPUNCTUATION);
Q_strncpyz(sc->defines+SCRIPT_DEFINELENGTH*2*(sc->numdefines-1)+SCRIPT_DEFINELENGTH, com_token, SCRIPT_DEFINELENGTH);
continue;
}
if (!*com_token)
{
if (sc->stackdepth==0)
return 0;
sc->stackdepth--;
continue;
}
break;
}
for (i = 0; i < sc->numdefines; i++)
{
if (!strcmp(com_token, sc->defines+SCRIPT_DEFINELENGTH*2*i))
{
Q_strncpyz(token->string, sc->defines+SCRIPT_DEFINELENGTH*2*i+SCRIPT_DEFINELENGTH, sizeof(token->string));
break;
}
}
//fill in the token
if (i == sc->numdefines)
Q_strncpyz(token->string, com_token, sizeof(token->string));
token->intvalue = atoi(token->string);
token->floatvalue = atof(token->string);
if (token->floatvalue || *token->string == '0')
{
token->type = TT_NUMBER;
token->subtype = 0;
}
else if (com_tokentype == TTP_STRING)
{
token->type = TT_STRING;
token->subtype = strlen(token->string);
}
else
{
if (token->string[1] == '\0')
{
token->type = TT_PUNCTUATION;
token->subtype = token->string[0];
}
else
{
token->type = TT_NAME;
token->subtype = strlen(token->string);
}
}
// Con_Printf("Found %s (%i, %i)\n", token->string, token->type, token->subtype);
return !!*token->string;
}
int Script_LoadFile(char *filename)
{
int i;
script_t *sc;
for (i = 0; i < maxscripts; i++)
if (!scripts[i].stackdepth)
break;
if (i == maxscripts)
{
maxscripts++;
scripts = BZ_Realloc(scripts, sizeof(script_t)*maxscripts);
}
sc = scripts+i;
memset(sc, 0, sizeof(*sc));
sc->filestack[0] = sc->originalfilestack[0] = COM_LoadMallocFile(filename);
sc->stackdepth = 1;
return i+1;
}
void Script_Free(int handle)
{
int i;
script_t *sc = scripts+handle-1;
if (sc->defines)
BZ_Free(sc->defines);
for (i = 0; i < sc->stackdepth; i++)
BZ_Free(sc->originalfilestack[i]);
}
void Script_Get_File_And_Line(int handle, char *filename, int *line)
{
script_t *sc = scripts+handle-1;
char *src;
char *start;
*line = 0;
if (!sc->stackdepth)
return;
*line = 1;
src = sc->filestack[sc->stackdepth-1];
start = sc->originalfilestack[sc->stackdepth-1];
while(start < src)
{
if (*start == '\n')
(*line)++;
start++;
}
}
#ifdef RGLQUAKE #ifdef RGLQUAKE
#include "glquake.h"//hack #include "glquake.h"//hack
#else #else
@ -269,25 +465,8 @@ int VMEnumMods(char *match, int size, void *args)
return true; return true;
} }
typedef enum {
RT_MODEL,
RT_POLY,
RT_SPRITE,
RT_BEAM,
RT_RAIL_CORE,
RT_RAIL_RINGS,
RT_LIGHTNING,
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
RT_MAX_REF_ENTITY_TYPE
} q3refEntityType_t;
typedef struct q3refEntity_s { typedef struct q3refEntity_s {
q3refEntityType_t reType; refEntityType_t reType;
int renderfx; int renderfx;
struct model_s *hModel; // opaque type outside refresh struct model_s *hModel; // opaque type outside refresh
@ -341,38 +520,9 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
memcpy(ent.axis, q3->axis, sizeof(q3->axis)); memcpy(ent.axis, q3->axis, sizeof(q3->axis));
ent.lerpfrac = q3->backlerp; ent.lerpfrac = q3->backlerp;
ent.alpha = 1; ent.alpha = 1;
ent.scale = 1; ent.scale = q3->radius;
ent.rtype = q3->reType;
switch(q3->reType) ent.rotation = q3->rotation;
{
case RT_MODEL:
// Con_Printf("Model\n");
break;
case RT_POLY:
Con_Printf("Poly\n");
break;
case RT_SPRITE:
Con_Printf("Sprite\n");
break;
case RT_BEAM:
Con_Printf("Beam\n");
break;
case RT_RAIL_CORE:
VectorCopy(q3->oldorigin, ent.oldorigin);
ent.flags |= Q2RF_BEAM;
ent.scale = q3->radius;
break;
case RT_RAIL_RINGS:
Con_Printf("RailRings\n");
break;
case RT_LIGHTNING:
Con_Printf("Lightning\n");
break;
case RT_PORTALSURFACE: // doesn't draw anything, just info for portals
Con_Printf("PortalSurface\n");
return;
}
if (q3->customSkin) if (q3->customSkin)
ent.skinnum = Mod_SkinForName(ent.model, q3->customSkin); ent.skinnum = Mod_SkinForName(ent.model, q3->customSkin);
@ -388,6 +538,7 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
if (q3->renderfx & Q3RF_THIRD_PERSON) if (q3->renderfx & Q3RF_THIRD_PERSON)
ent.flags |= Q2RF_VIEWERMODEL; ent.flags |= Q2RF_VIEWERMODEL;
VectorCopy(q3->origin, ent.origin); VectorCopy(q3->origin, ent.origin);
VectorCopy(q3->oldorigin, ent.oldorigin);
V_AddAxisEntity(&ent); V_AddAxisEntity(&ent);
} }
@ -420,10 +571,12 @@ int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagnam
ang[1] = tr[1]; ang[1] = tr[1];
ang[2] = tr[2]; ang[2] = tr[2];
org[0] = tr[3]; org[0] = tr[3];
ang[3] = tr[4]; ang[3] = tr[4];
ang[4] = tr[5]; ang[4] = tr[5];
ang[5] = tr[6]; ang[5] = tr[6];
org[1] = tr[7]; org[1] = tr[7];
ang[6] = tr[8]; ang[6] = tr[8];
ang[7] = tr[9]; ang[7] = tr[9];
ang[8] = tr[10]; ang[8] = tr[10];
@ -526,15 +679,51 @@ void VQ3_RenderView(const q3refdef_t *ref)
#ifndef Q3CLIENT
typedef struct { void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font)
int handle; {
int modificationCount; char *in;
float value; int i;
int integer; char name[MAX_QPATH];
char string[256]; #define readInt() LittleLong(*((int*)in)++)
} vmcvar_t; #define readFloat() LittleFloat(*((float*)in)++)
#endif
_snprintf(name, sizeof(name), "fonts/fontImage_%i.dat",pointSize);
in = COM_LoadTempFile(name);
if (com_filesize == sizeof(fontInfo_t))
{
for(i=0; i<GLYPHS_PER_FONT; i++)
{
font->glyphs[i].height = readInt();
font->glyphs[i].top = readInt();
font->glyphs[i].bottom = readInt();
font->glyphs[i].pitch = readInt();
font->glyphs[i].xSkip = readInt();
font->glyphs[i].imageWidth = readInt();
font->glyphs[i].imageHeight = readInt();
font->glyphs[i].s = readFloat();
font->glyphs[i].t = readFloat();
font->glyphs[i].s2 = readFloat();
font->glyphs[i].t2 = readFloat();
font->glyphs[i].glyph = readInt();
memcpy(font->glyphs[i].shaderName, in, 32);
in += 32;
}
font->glyphScale = readFloat();
memcpy(font->name, in, MAX_QPATH);
// Com_Memcpy(font, faceData, sizeof(fontInfo_t));
Q_strncpyz(font->name, name, sizeof(font->name));
for (i = GLYPH_START; i < GLYPH_END; i++)
{
font->glyphs[i].glyph = (int)R_RegisterPic(font->glyphs[i].shaderName);
}
}
}
#ifndef _DEBUG #ifndef _DEBUG
static static
@ -555,13 +744,17 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
switch((ui_builtinnum_t)fn) switch((ui_builtinnum_t)fn)
{ {
case UI_SYSERROR: case UI_ERROR:
Sys_Error("%s", VM_POINTER(arg[0])); Con_Printf("%s", VM_POINTER(arg[0]));
break; break;
case UI_PRINT: case UI_PRINT:
Con_Printf("%s", VM_POINTER(arg[0])); Con_Printf("%s", VM_POINTER(arg[0]));
break; break;
case UI_MILLISECONDS:
VM_LONG(ret) = Sys_Milliseconds();
break;
case UI_CVAR_SET: case UI_CVAR_SET:
{ {
cvar_t *var; cvar_t *var;
@ -572,7 +765,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
Cvar_Get(VM_POINTER(arg[0]), VM_POINTER(arg[1]), 0, "UI created"); //create one Cvar_Get(VM_POINTER(arg[0]), VM_POINTER(arg[1]), 0, "UI created"); //create one
} }
break; break;
case UI_CVAR_GET_VALUE: case UI_CVAR_VARIABLEVALUE:
{ {
cvar_t *var; cvar_t *var;
var = Cvar_FindVar(VM_POINTER(arg[0])); var = Cvar_FindVar(VM_POINTER(arg[0]));
@ -582,7 +775,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
VM_FLOAT(ret) = 0; VM_FLOAT(ret) = 0;
} }
break; break;
case UI_CVAR_GET_STRING: case UI_CVAR_VARIABLESTRINGBUFFER:
{ {
cvar_t *var; cvar_t *var;
var = Cvar_FindVar(VM_POINTER(arg[0])); var = Cvar_FindVar(VM_POINTER(arg[0]));
@ -603,7 +796,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case UI_CVAR_SET_VALUE: case UI_CVAR_SETVALUE:
Cvar_SetValue(Cvar_FindVar(VM_POINTER(arg[0])), VM_FLOAT(arg[1])); Cvar_SetValue(Cvar_FindVar(VM_POINTER(arg[0])), VM_FLOAT(arg[1]));
break; break;
@ -616,7 +809,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case UI_CBUF_ADD_COMMAND: case UI_CMD_EXECUTETEXT:
if (!strncmp(VM_POINTER(arg[1]), "ping ", 5)) if (!strncmp(VM_POINTER(arg[1]), "ping ", 5))
{ {
int i; int i;
@ -646,7 +839,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
Cbuf_AddText(VM_POINTER(arg[1]), RESTRICT_SERVER); Cbuf_AddText(VM_POINTER(arg[1]), RESTRICT_SERVER);
break; break;
case UI_FS_OPEN: //fopen case UI_FS_FOPENFILE: //fopen
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset) if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds. break; //out of bounds.
VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0); VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
@ -660,11 +853,11 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
break; break;
case UI_FS_WRITE: //fwrite case UI_FS_WRITE: //fwrite
break; break;
case UI_FS_CLOSE: //fclose case UI_FS_FCLOSEFILE: //fclose
VMUI_fclose(VM_LONG(arg[0]), 0); VMUI_fclose(VM_LONG(arg[0]), 0);
break; break;
case UI_FS_LISTFILES: //fs listing case UI_FS_GETFILELIST: //fs listing
if ((int)arg[2] + arg[3] >= mask || VM_POINTER(arg[2]) < offset) if ((int)arg[2] + arg[3] >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds. break; //out of bounds.
{ {
@ -687,11 +880,14 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case UI_PRECACHE_MODEL: //precache model case UI_R_REGISTERMODEL: //precache model
VM_LONG(ret) = (int)Mod_ForName(VM_POINTER(arg[0]), false); {
char *name = VM_POINTER(arg[0]);
VM_LONG(ret) = (int)Mod_ForName(name, false);
}
break; break;
case UI_PRECACHE_SKIN: case UI_R_REGISTERSKIN:
{ {
char *buf; char *buf;
char *skinname = VM_POINTER(arg[0]); char *skinname = VM_POINTER(arg[0]);
@ -701,26 +897,30 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case UI_DRAW_CACHEPIC: case UI_R_REGISTERFONT: //register font
UI_RegisterFont(VM_POINTER(arg[0]), arg[1], VM_POINTER(arg[2]));
break;
case UI_R_REGISTERSHADERNOMIP:
if (!Draw_SafeCachePic) if (!Draw_SafeCachePic)
VM_LONG(ret) = 0; VM_LONG(ret) = 0;
else else
VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0])); // VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0]));
VM_LONG(ret) = (long)R_RegisterPic(VM_POINTER(arg[0]));
break; break;
case UI_SCENE_CLEAR: //clear scene case UI_R_CLEARSCENE: //clear scene
cl_numvisedicts=0; cl_numvisedicts=0;
break; break;
case UI_SCENE_ADD_ENTITY: //add ent to scene case UI_R_ADDREFENTITYTOSCENE: //add ent to scene
VQ3_AddEntity(VM_POINTER(arg[0])); VQ3_AddEntity(VM_POINTER(arg[0]));
break; break;
case UI_SCENE_ADD_LIGHT: //add light to scene. case UI_R_ADDLIGHTTOSCENE: //add light to scene.
break; break;
case UI_SCENE_RENDER: //render scene case UI_R_RENDERSCENE: //render scene
VQ3_RenderView(VM_POINTER(arg[0])); VQ3_RenderView(VM_POINTER(arg[0]));
break; break;
case UI_DRAW_COLOUR: //setcolour float* case UI_R_SETCOLOR: //setcolour float*
if (Draw_ImageColours) if (Draw_ImageColours)
{ {
float *fl =VM_POINTER(arg[0]); float *fl =VM_POINTER(arg[0]);
@ -731,19 +931,23 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case UI_DRAW_IMAGE: case UI_R_DRAWSTRETCHPIC:
// qglDisable(GL_ALPHA_TEST);
// qglEnable(GL_BLEND);
// GL_TexEnv(GL_MODULATE);
if (Draw_Image) if (Draw_Image)
Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (void *)VM_LONG(arg[8]));
// Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8]));
break; break;
case UI_LERP_TAG: //Lerp tag... case UI_CM_LERPTAG: //Lerp tag...
// tag, model, startFrame, endFrame, frac, tagName // tag, model, startFrame, endFrame, frac, tagName
if ((int)arg[0] + sizeof(float)*12 >= mask || VM_POINTER(arg[0]) < offset) if ((int)arg[0] + sizeof(float)*12 >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds. break; //out of bounds.
VM_LerpTag(VM_POINTER(arg[0]), (model_t*)VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_FLOAT(arg[4]), VM_POINTER(arg[5])); VM_LerpTag(VM_POINTER(arg[0]), (model_t*)VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_FLOAT(arg[4]), VM_POINTER(arg[5]));
break; break;
case UI_SOUND_PRECACHE: case UI_S_REGISTERSOUND:
{ {
sfx_t *sfx; sfx_t *sfx;
sfx = S_PrecacheSound(va("../%s", VM_POINTER(arg[0]))); sfx = S_PrecacheSound(va("../%s", VM_POINTER(arg[0])));
@ -753,19 +957,19 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
VM_LONG(ret) = -1; VM_LONG(ret) = -1;
} }
break; break;
case UI_SOUND_PLAY: case UI_S_STARTLOCALSOUND:
if (VM_LONG(arg[0]) != -1) if (VM_LONG(arg[0]) != -1 && arg[0])
S_LocalSound(VM_LONG(arg[0])+(char *)offset); S_LocalSound(VM_LONG(arg[0])+(char *)offset);
break; break;
case UI_KEY_NAME: case UI_KEY_KEYNUMTOSTRINGBUF:
if (VM_LONG(arg[0]) < 0 || VM_LONG(arg[0]) > 255 || (int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1) if (VM_LONG(arg[0]) < 0 || VM_LONG(arg[0]) > 255 || (int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1)
break; //out of bounds. break; //out of bounds.
Q_strncpyz(VM_POINTER(arg[1]), Key_KeynumToString(VM_LONG(arg[0])), VM_LONG(arg[2])); Q_strncpyz(VM_POINTER(arg[1]), Key_KeynumToString(VM_LONG(arg[0])), VM_LONG(arg[2]));
break; break;
case UI_KEY_GETBINDING: case UI_KEY_GETBINDINGBUF:
if (VM_LONG(arg[0]) < 0 || VM_LONG(arg[0]) > 255 || (int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1) if (VM_LONG(arg[0]) < 0 || VM_LONG(arg[0]) > 255 || (int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1)
break; //out of bounds. break; //out of bounds.
@ -789,22 +993,20 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case 37: case UI_KEY_CLEARSTATES:
break;
case 38:
break;
case UI_KEY_CLEARALL:
Key_ClearStates(); Key_ClearStates();
break; break;
case UI_KEY_GETDEST: case UI_KEY_GETCATCHER:
VM_LONG(ret) = keycatcher; if (key_dest == key_console)
VM_LONG(ret) = keycatcher | 1;
else
VM_LONG(ret) = keycatcher;
break; break;
case UI_KEY_SETDEST: case UI_KEY_SETCATCHER:
keycatcher = VM_LONG(arg[0]); keycatcher = VM_LONG(arg[0]);
break; break;
case UI_GET_VID_CONFIG: //get glconfig case UI_GETGLCONFIG: //get glconfig
if ((int)arg[0] + 11332/*sizeof(glconfig_t)*/ >= mask || VM_POINTER(arg[0]) < offset) if ((int)arg[0] + 11332/*sizeof(glconfig_t)*/ >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds. break; //out of bounds.
@ -816,27 +1018,20 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
memset(VM_POINTER(arg[0]+11316), 0, 11332-11316); memset(VM_POINTER(arg[0]+11316), 0, 11332-11316);
break; break;
case UI_GET_CLIENT_STATE: //get client state case UI_GETCLIENTSTATE: //get client state
//fixme: we need to fill in a structure. //fixme: we need to fill in a structure.
break; break;
case UI_GET_SERVERINFO: case UI_GETCONFIGSTRING:
if (arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1) if (arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset || VM_LONG(arg[2]) < 1)
{ {
VM_LONG(ret) = 0; VM_LONG(ret) = 0;
break; //out of bounds. break; //out of bounds.
} }
switch(VM_LONG(arg[0])) Q_strncpyz(VM_POINTER(arg[1]), CG_GetConfigString(VM_LONG(arg[0])), VM_LONG(arg[2]));
{
case 0:
Q_strncpyz(VM_POINTER(arg[1]), cl.serverinfo, VM_LONG(arg[2]));
break;
default:
*(char *)VM_POINTER(arg[1]) = 0;
}
break; break;
case UI_MS_GETSERVERCOUNT: //these four are master server polling. case UI_LAN_GETPINGQUEUECOUNT: //these four are master server polling.
{ {
int i; int i;
for (i = 0; i < MAX_PINGREQUESTS; i++) for (i = 0; i < MAX_PINGREQUESTS; i++)
@ -844,12 +1039,12 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
VM_LONG(ret)++; VM_LONG(ret)++;
} }
break; break;
case UI_CLEAR_PINGS: //clear ping case UI_LAN_CLEARPING: //clear ping
//void (int pingnum) //void (int pingnum)
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS) if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
ui_pings[VM_LONG(arg[0])].type = NA_INVALID; ui_pings[VM_LONG(arg[0])].type = NA_INVALID;
break; break;
case UI_GET_PINGADDRESS: case UI_LAN_GETPING:
//void (int pingnum, char *buffer, int buflen, int *ping) //void (int pingnum, char *buffer, int buflen, int *ping)
if ((int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset) if ((int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds. break; //out of bounds.
@ -876,7 +1071,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
strcpy(buf, ""); strcpy(buf, "");
} }
break; break;
case UI_GET_PINGINFO: case UI_LAN_GETPINGINFO:
//void (int pingnum, char *buffer, int buflen, ) //void (int pingnum, char *buffer, int buflen, )
if ((int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset) if ((int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds. break; //out of bounds.
@ -945,36 +1140,34 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
} }
break; break;
case UI_MEM_AVAILABLE: case UI_MEMORY_REMAINING:
VM_LONG(ret) = Hunk_LowMemAvailable(); VM_LONG(ret) = Hunk_LowMemAvailable();
break; break;
case UI_CDKEY_GET: //get cd key case UI_GET_CDKEY: //get cd key
if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset) if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds. break; //out of bounds.
strncpy(VM_POINTER(arg[0]), "aaaaaaaaaaaaaaaa", VM_LONG(arg[1])); strncpy(VM_POINTER(arg[0]), Cvar_VariableString("cl_cdkey"), VM_LONG(arg[1]));
break; break;
case UI_CDKEY_SET: //set cd key case UI_SET_CDKEY: //set cd key
if ((int)arg[0] + strlen(VM_POINTER(arg[0])) >= mask || VM_POINTER(arg[0]) < offset) if ((int)arg[0] + strlen(VM_POINTER(arg[0])) >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds. break; //out of bounds.
{
cvar_t *cvar;
cvar = Cvar_Get("cl_cdkey", "", 0, "Quake3 auth");
Cvar_Set(cvar, VM_POINTER(arg[0]));
}
break; break;
case UI_REGISTERFRONT: //register font case UI_REAL_TIME:
if (!Draw_SafeCachePic)
VM_LONG(ret) = 0;
else
VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0]));
break;
case UI_GET_REALTIME:
VM_FLOAT(ret) = realtime; VM_FLOAT(ret) = realtime;
break; break;
case UI_LAN_GET_COUNT: //LAN Get server count case UI_LAN_GETSERVERCOUNT: //LAN Get server count
//int (int source) //int (int source)
VM_LONG(ret) = Master_TotalCount(); VM_LONG(ret) = Master_TotalCount();
break; break;
case UI_LAN_GET_ADDRESS: //LAN get server address case UI_LAN_GETSERVERADDRESSSTRING: //LAN get server address
//void (int source, int svnum, char *buffer, int buflen) //void (int source, int svnum, char *buffer, int buflen)
if ((int)arg[2] + VM_LONG(arg[3]) >= mask || VM_POINTER(arg[2]) < offset) if ((int)arg[2] + VM_LONG(arg[3]) >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds. break; //out of bounds.
@ -995,14 +1188,23 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
strcpy(buf, ""); strcpy(buf, "");
} }
break; break;
case 67: case UI_LAN_LOADCACHEDSERVERS:
break;
case UI_LAN_SAVECACHEDSERVERS:
break;
case UI_LAN_GETSERVERPING:
return 50;
case UI_LAN_GETSERVERINFO:
break;
case UI_LAN_SERVERISVISIBLE:
return 1;
break; break;
case UI_VERIFYCDKEY: case UI_VERIFY_CDKEY:
VM_LONG(ret) = true; VM_LONG(ret) = true;
break; break;
case UI_SOMETHINGTODOWITHPUNKBUSTER: case UI_SET_PBCLSTATUS:
break; break;
// standard Q3 // standard Q3
@ -1011,10 +1213,10 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
break; //out of bounds. break; //out of bounds.
memset(VM_POINTER(arg[0]), arg[1], arg[2]); memset(VM_POINTER(arg[0]), arg[1], arg[2]);
break; break;
case UI_MEMMOVE: case UI_MEMCPY:
if ((int)arg[0] + arg[2] >= mask || VM_POINTER(arg[0]) < offset) if ((int)arg[0] + arg[2] >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds. break; //out of bounds.
memmove(VM_POINTER(arg[0]), VM_POINTER(arg[1]), arg[2]); memcpy(VM_POINTER(arg[0]), VM_POINTER(arg[1]), arg[2]);
break; break;
case UI_STRNCPY: case UI_STRNCPY:
if (arg[0] + arg[2] >= mask || VM_POINTER(arg[0]) < offset) if (arg[0] + arg[2] >= mask || VM_POINTER(arg[0]) < offset)
@ -1147,8 +1349,26 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
return strlen(str); return strlen(str);
} }
case UI_PC_ADD_GLOBAL_DEFINE:
Con_Printf("UI_PC_ADD_GLOBAL_DEFINE not supported\n");
break;
case UI_PC_SOURCE_FILE_AND_LINE:
Script_Get_File_And_Line(arg[0], VM_POINTER(arg[1]), VM_POINTER(arg[2]));
break;
case UI_PC_LOAD_SOURCE:
return Script_LoadFile(VM_POINTER(arg[0]));
case UI_PC_FREE_SOURCE:
Script_Free(arg[0]);
break;
case UI_PC_READ_TOKEN:
//fixme: memory protect.
return Script_Read(arg[0], VM_POINTER(arg[1]));
default: default:
Sys_Error("Q3UI: Not implemented system trap: %d\n", fn); Con_Printf("Q3UI: Not implemented system trap: %d\n", fn);
return 0;
} }
return ret; return ret;
@ -1212,7 +1432,7 @@ void UI_DrawMenu(void)
{ {
if (uivm) if (uivm)
{ {
VM_Call(uivm, UI_DRAWMENU, (int)(realtime * 1000)); VM_Call(uivm, UI_REFRESH, (int)(realtime * 1000));
if (keycatcher&2 && key_dest != key_console) if (keycatcher&2 && key_dest != key_console)
key_dest = key_game; key_dest = key_game;
} }
@ -1257,7 +1477,7 @@ int UI_MenuState(void)
} }
if (!uivm) if (!uivm)
return false; return false;
if (VM_Call(uivm, UI_FULLSCREEN)) if (VM_Call(uivm, UI_IS_FULLSCREEN))
return 2; return 2;
else if (keycatcher&2) else if (keycatcher&2)
return 3; return 3;
@ -1272,16 +1492,16 @@ qboolean UI_KeyPress(int key, qboolean down)
// qboolean result; // qboolean result;
if (!uivm) if (!uivm)
return false; return false;
if (key_dest == key_menu) // if (key_dest == key_menu)
return false; // return false;
if (!(keycatcher&2)) if (!(keycatcher&2))
{ {
if (key == K_ESCAPE && down) if (key == K_ESCAPE && down)
{ {
if (cls.state) if (cls.state)
return VM_Call(uivm, 7, 2)>0; return VM_Call(uivm, UI_SET_ACTIVE_MENU, 2)>0;
else else
return VM_Call(uivm, 7, 1)>0; return VM_Call(uivm, UI_SET_ACTIVE_MENU, 1)>0;
} }
return false; return false;
} }
@ -1293,7 +1513,7 @@ qboolean UI_KeyPress(int key, qboolean down)
/*result = */VM_Call(uivm, UI_KEY_EVENT, key, down); /*result = */VM_Call(uivm, UI_KEY_EVENT, key, down);
if (!keycatcher && !cls.state) if (!keycatcher && !cls.state && key == K_ESCAPE && down)
{ {
M_Menu_Main_f(); M_Menu_Main_f();
return true; return true;
@ -1318,8 +1538,8 @@ void UI_MousePosition(int xpos, int ypos)
ypos = vid.height; ypos = vid.height;
ox=0;oy=0; ox=0;oy=0;
//force a cap //force a cap
VM_Call(uivm, 4, -32767, -32767); VM_Call(uivm, UI_MOUSE_DELTA, -32767, -32767);
VM_Call(uivm, 4, (xpos-ox)*640/vid.width, (ypos-oy)*480/vid.height); VM_Call(uivm, UI_MOUSE_DELTA, (xpos-ox)*640/vid.width, (ypos-oy)*480/vid.height);
ox = xpos; ox = xpos;
oy = ypos; oy = ypos;
@ -1352,7 +1572,7 @@ void UI_Start (void)
apiversion = VM_Call(uivm, UI_GETAPIVERSION, UI_API_VERSION); apiversion = VM_Call(uivm, UI_GETAPIVERSION, UI_API_VERSION);
if (apiversion == UI_API_VERSION) if (apiversion == UI_API_VERSION)
keycatcher = 0; keycatcher = 0;
else if (apiversion != 4) //make sure we can run the thing else if (apiversion != 4 && apiversion != 6) //make sure we can run the thing
{ {
Con_Printf("User-Interface VM uses incompatable API version (%i)\n", apiversion); Con_Printf("User-Interface VM uses incompatable API version (%i)\n", apiversion);
VM_Destroy(uivm); VM_Destroy(uivm);
@ -1362,9 +1582,11 @@ void UI_Start (void)
} }
VM_Call(uivm, UI_INIT); VM_Call(uivm, UI_INIT);
VM_Call(uivm, 4, -32767, -32767); VM_Call(uivm, UI_MOUSE_DELTA, -32767, -32767);
ox = 0; ox = 0;
oy = 0; oy = 0;
VM_Call(uivm, UI_SET_ACTIVE_MENU, 1);
} }
} }
@ -1376,9 +1598,9 @@ void UI_Restart_f(void)
if (uivm) if (uivm)
{ {
if (cls.state) if (cls.state)
VM_Call(uivm, 7, 2); VM_Call(uivm, UI_SET_ACTIVE_MENU, 2);
else else
VM_Call(uivm, 7, 1); VM_Call(uivm, UI_SET_ACTIVE_MENU, 1);
} }
} }

View file

@ -316,13 +316,15 @@ typedef struct
int socketip6; int socketip6;
int socketipx; int socketipx;
enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod; enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod;
FILE *downloadqw; // file transfer from server FILE *downloadqw; // file transfer from server
char downloadtempname[MAX_OSPATH]; char downloadtempname[MAX_OSPATH];
char downloadname[MAX_OSPATH]; char downloadname[MAX_OSPATH];
int downloadnumber;
dltype_t downloadtype;
int downloadpercent; int downloadpercent;
int downloadchunknum;
int downloadnumber; //file number
dltype_t downloadtype; //of type
// demo loop control // demo loop control
int demonum; // -1 = don't play demos int demonum; // -1 = don't play demos
@ -437,7 +439,9 @@ typedef struct
// sentcmds[cl.netchan.outgoing_sequence & UPDATE_MASK] = cmd // sentcmds[cl.netchan.outgoing_sequence & UPDATE_MASK] = cmd
frame_t frames[UPDATE_BACKUP]; frame_t frames[UPDATE_BACKUP];
lerpents_t lerpents[MAX_EDICTS]; lerpents_t *lerpents;
int maxlerpents; //number of slots allocated.
lerpents_t lerpplayers[MAX_CLIENTS];
// information for local display // information for local display
int stats[MAX_SPLITS][MAX_CL_STATS]; // health, etc int stats[MAX_SPLITS][MAX_CL_STATS]; // health, etc
@ -772,7 +776,7 @@ void CL_LinkProjectiles (void);
//clq3_parse.c //clq3_parse.c
// //
#ifdef Q3CLIENT #ifdef Q3CLIENT
void CLQ3_SendClientCommand(const char *fmt, ...); void VARGS CLQ3_SendClientCommand(const char *fmt, ...);
void CLQ3_SendConnectPacket(netadr_t to); void CLQ3_SendConnectPacket(netadr_t to);
void CLQ3_SendCmd(usercmd_t *cmd); void CLQ3_SendCmd(usercmd_t *cmd);
qboolean CLQ3_Netchan_Process(void); qboolean CLQ3_Netchan_Process(void);
@ -781,6 +785,8 @@ qboolean CG_FillQ3Snapshot(int snapnum, struct snapshot_s *snapshot);
void CG_InsertIntoGameState(int num, char *str); void CG_InsertIntoGameState(int num, char *str);
void CG_Restart_f(void); void CG_Restart_f(void);
char *CG_GetConfigString(int num);
#endif #endif
// //

View file

@ -1645,6 +1645,119 @@ void BoostGamma(qbyte *rgba, int width, int height)
#if defined(RGLQUAKE) #if defined(RGLQUAKE)
#ifdef DDS
#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif
typedef struct {
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwFourCC;
unsigned int unk[5];
} ddspixelformat;
typedef struct {
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwHeight;
unsigned int dwWidth;
unsigned int dwPitchOrLinearSize;
unsigned int dwDepth;
unsigned int dwMipMapCount;
unsigned int dwReserved1[11];
ddspixelformat ddpfPixelFormat;
unsigned int ddsCaps[4];
unsigned int dwReserved2;
} ddsheader;
int GL_LoadTextureDDS(unsigned char *buffer, int filesize)
{
extern int gl_filter_min;
extern int gl_filter_max;
int texnum;
int nummips;
int mipnum;
int datasize;
int intfmt;
int pad;
ddsheader fmtheader;
if (*(int*)buffer != *(int*)"DDS ")
return 0;
buffer+=4;
texnum = texture_extension_number;
GL_Bind(texnum);
memcpy(&fmtheader, buffer, sizeof(fmtheader));
if (fmtheader.dwSize != sizeof(fmtheader))
return 0; //corrupt/different version
buffer += fmtheader.dwSize;
nummips = fmtheader.dwMipMapCount;
if (nummips < 1)
nummips = 1;
if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT1")
{
intfmt = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; //alpha or not? Assume yes, and let the drivers decide.
pad = 8;
}
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT3")
{
intfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
pad = 8;
}
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT5")
{
intfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
pad = 8;
}
else
return 0;
if (!qglCompressedTexImage2DARB)
return 0;
datasize = fmtheader.dwPitchOrLinearSize;
for (mipnum = 0; mipnum < nummips; mipnum++)
{
// (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
if (datasize < pad)
datasize = pad;
qglCompressedTexImage2DARB(GL_TEXTURE_2D, mipnum, intfmt, fmtheader.dwWidth>>mipnum, fmtheader.dwHeight>>mipnum, 0, datasize, buffer);
if (qglGetError())
Con_Printf("Incompatable dds file (mip %i)\n", mipnum);
buffer += datasize;
datasize/=4;
}
if (qglGetError())
Con_Printf("Incompatable dds file\n");
if (nummips>1)
{
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
texture_extension_number++;
return texnum;
}
#endif
//returns r8g8b8a8 //returns r8g8b8a8
qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height) qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height)
{ {
@ -1740,6 +1853,24 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al
//should write this nicer. //should write this nicer.
for (; i < sizeof(path)/sizeof(char *); i++) for (; i < sizeof(path)/sizeof(char *); i++)
{ {
#ifdef DDS
if (i == 1)
{
if (!subpath)
continue;
_snprintf(fname, sizeof(fname)-1, path[i], subpath, COM_SkipPath(nicename), ".dds");
}
else
_snprintf(fname, sizeof(fname)-1, path[i], nicename, ".dds");
if ((buf = COM_LoadFile (fname, 5)))
{
len = GL_LoadTextureDDS(buf, com_filesize);
BZ_Free(buf);
if (len)
return len;
}
#endif
for (e = sizeof(extensions)/sizeof(char *)-1; e >=0 ; e--) for (e = sizeof(extensions)/sizeof(char *)-1; e >=0 ; e--)
{ {
if (i == 1) if (i == 1)

View file

@ -1223,9 +1223,14 @@ void Key_Event (int key, qboolean down)
#ifdef CSQC_DAT #ifdef CSQC_DAT
//yes, csqc is allowed to steal the escape key. //yes, csqc is allowed to steal the escape key.
if (key != '`' && key != '~')
if (key_dest == key_game) if (key_dest == key_game)
{
if (CSQC_KeyPress(key, down)) //give csqc a chance to handle it. if (CSQC_KeyPress(key, down)) //give csqc a chance to handle it.
return; return;
if (CG_KeyPress(key, down))
return;
}
#endif #endif
// //
@ -1234,7 +1239,7 @@ void Key_Event (int key, qboolean down)
if (key == K_ESCAPE) if (key == K_ESCAPE)
{ {
#ifdef TEXTEDITOR #ifdef TEXTEDITOR
if (key_dest != key_editor) if (key_dest == key_game)
#endif #endif
{ {
if (UI_KeyPress(key, down)) //Allow the UI to see the escape key. It is possible that a developer may get stuck at a menu. if (UI_KeyPress(key, down)) //Allow the UI to see the escape key. It is possible that a developer may get stuck at a menu.
@ -1329,7 +1334,8 @@ void Key_Event (int key, qboolean down)
// if not a consolekey, send to the interpreter no matter what mode is // if not a consolekey, send to the interpreter no matter what mode is
// //
if (key_dest == key_game || down) if (key != '`' && key != '~')
if (key_dest == key_game || !down)
{ {
if (UI_KeyPress(key, down) && down) //UI is allowed to take these keydowns. Keyups are always maintained. if (UI_KeyPress(key, down) && down) //UI is allowed to take these keydowns. Keyups are always maintained.
return; return;

View file

@ -1,7 +1,7 @@
#include "quakedef.h" #include "quakedef.h"
#ifndef MINIMAL #ifndef MINIMAL
#define ROOTDOWNLOADABLESSOURCE "http://127.0.0.1/downloadables.txt" #define ROOTDOWNLOADABLESSOURCE "http://fteqw.sourceforge.net/downloadables.txt"
#define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed). #define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed).
#define DPF_HAVEAVERSION 1 //any old version #define DPF_HAVEAVERSION 1 //any old version
@ -13,7 +13,7 @@ extern char com_basedir[];
char *downloadablelist[256] = { char *downloadablelist[256] = {
"http://127.0.0.1/downloadables.txt" ROOTDOWNLOADABLESSOURCE
}; //note: these are allocated for the life of the exe }; //note: these are allocated for the life of the exe
int numdownloadablelists = 1; int numdownloadablelists = 1;
@ -179,6 +179,18 @@ void ConcatPackageLists(package_t *l2)
} }
} }
static void dlnotification(char *localfile, qboolean sucess)
{
FILE *f;
COM_FOpenFile(localfile, &f);
if (f)
{
ConcatPackageLists(BuildPackageList(f, 0));
fclose(f);
}
}
void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m) void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
{ {
int pn; int pn;
@ -191,29 +203,15 @@ void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
if (!cls.downloadmethod && (info->parsedsourcenum==-1 || downloadablelist[info->parsedsourcenum])) if (!cls.downloadmethod && (info->parsedsourcenum==-1 || downloadablelist[info->parsedsourcenum]))
{ //done downloading { //done downloading
FILE *f;
char basename[64]; char basename[64];
char *absolutename; char *absolutename;
if (info->parsedsourcenum>=0)
{
sprintf(basename, "../dlinfo_%i.inf", info->parsedsourcenum);
absolutename = va("%s/%s", com_basedir, basename+3);
f = fopen(absolutename, "rb");
if (f)
{
ConcatPackageLists(BuildPackageList(f, 0));
fclose(f);
unlink(absolutename);
}
}
info->parsedsourcenum++; info->parsedsourcenum++;
if (downloadablelist[info->parsedsourcenum]) if (downloadablelist[info->parsedsourcenum])
{ {
sprintf(basename, "../dlinfo_%i.inf", info->parsedsourcenum); sprintf(basename, "dlinfo_%i.inf", info->parsedsourcenum);
if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, NULL)) if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, dlnotification))
Con_Printf("Could not contact server\n"); Con_Printf("Could not contact server\n");
} }
} }

View file

@ -21,6 +21,7 @@ cvar_t sb_hidenotempty = {"sb_hidenotempty", "0", NULL, CVAR_ARCHIVE};
cvar_t sb_hidefull = {"sb_hidefull", "0", NULL, CVAR_ARCHIVE}; cvar_t sb_hidefull = {"sb_hidefull", "0", NULL, CVAR_ARCHIVE};
cvar_t sb_hidedead = {"sb_hidedead", "1", NULL, CVAR_ARCHIVE}; cvar_t sb_hidedead = {"sb_hidedead", "1", NULL, CVAR_ARCHIVE};
cvar_t sb_hidequake2 = {"sb_hidequake2", "1", NULL, CVAR_ARCHIVE}; cvar_t sb_hidequake2 = {"sb_hidequake2", "1", NULL, CVAR_ARCHIVE};
cvar_t sb_hidequake3 = {"sb_hidequake3", "1", NULL, CVAR_ARCHIVE};
cvar_t sb_hidenetquake = {"sb_hidenetquake", "1", NULL, CVAR_ARCHIVE}; cvar_t sb_hidenetquake = {"sb_hidenetquake", "1", NULL, CVAR_ARCHIVE};
cvar_t sb_hidequakeworld = {"sb_hidequakeworld", "0", NULL, CVAR_ARCHIVE}; cvar_t sb_hidequakeworld = {"sb_hidequakeworld", "0", NULL, CVAR_ARCHIVE};
cvar_t sb_maxping = {"sb_maxping", "0", NULL, CVAR_ARCHIVE}; cvar_t sb_maxping = {"sb_maxping", "0", NULL, CVAR_ARCHIVE};
@ -47,6 +48,7 @@ void M_Serverlist_Init(void)
Cvar_Register(&sb_hidefull, grp); Cvar_Register(&sb_hidefull, grp);
Cvar_Register(&sb_hidedead, grp); Cvar_Register(&sb_hidedead, grp);
Cvar_Register(&sb_hidequake2, grp); Cvar_Register(&sb_hidequake2, grp);
Cvar_Register(&sb_hidequake3, grp);
Cvar_Register(&sb_hidenetquake, grp); Cvar_Register(&sb_hidenetquake, grp);
Cvar_Register(&sb_hidequakeworld, grp); Cvar_Register(&sb_hidequakeworld, grp);
@ -112,13 +114,18 @@ qboolean M_IsFiltered(serverinfo_t *server) //figure out if we should filter a s
#endif #endif
if (server->special & SS_QUAKE2) if (server->special & SS_QUAKE2)
return true; return true;
#ifdef Q2CLIENT
if (sb_hidequake3.value)
#endif
if (server->special & SS_QUAKE3)
return true;
#ifdef NQPROT #ifdef NQPROT
if (sb_hidenetquake.value) if (sb_hidenetquake.value)
#endif #endif
if (server->special & (SS_NETQUAKE|SS_DARKPLACES)) if (server->special & (SS_NETQUAKE|SS_DARKPLACES))
return true; return true;
if (sb_hidequakeworld.value) if (sb_hidequakeworld.value)
if (!(server->special & (SS_QUAKE2|SS_NETQUAKE|SS_DARKPLACES))) if (!(server->special & (SS_QUAKE2|SS_QUAKE3|SS_NETQUAKE|SS_DARKPLACES)))
return true; return true;
if (sb_hideempty.value) if (sb_hideempty.value)
if (!server->players) if (!server->players)
@ -368,6 +375,8 @@ void M_DrawServerList(void)
colour = COLOR_RED; colour = COLOR_RED;
else if (server->special & SS_QUAKE2) else if (server->special & SS_QUAKE2)
colour = COLOR_YELLOW; colour = COLOR_YELLOW;
else if (server->special & SS_QUAKE3)
colour = COLOR_BLUE;
else if (server->special & SS_NETQUAKE) else if (server->special & SS_NETQUAKE)
colour = COLOR_MAGENTA; colour = COLOR_MAGENTA;
else else
@ -474,7 +483,7 @@ void M_DrawSources (void)
} }
} }
#define NUMSLISTOPTIONS (7+7+4) #define NUMSLISTOPTIONS (8+7+4)
struct { struct {
char *title; char *title;
cvar_t *cvar; cvar_t *cvar;
@ -485,6 +494,7 @@ void M_DrawSources (void)
{"Hide Full", &sb_hidefull}, {"Hide Full", &sb_hidefull},
{"Hide Dead", &sb_hidedead}, {"Hide Dead", &sb_hidedead},
{"Hide Quake 2", &sb_hidequake2}, {"Hide Quake 2", &sb_hidequake2},
{"Hide Quake 3", &sb_hidequake3},
{"Hide Quake 1", &sb_hidenetquake}, {"Hide Quake 1", &sb_hidenetquake},
{"Hide QuakeWorld", &sb_hidequakeworld}, {"Hide QuakeWorld", &sb_hidequakeworld},

View file

@ -97,8 +97,6 @@ extern struct model_s *FNC(Mod_FindName) (char *name);
extern void *FNC(Mod_Extradata) (struct model_s *mod); // handles caching extern void *FNC(Mod_Extradata) (struct model_s *mod); // handles caching
extern void FNC(Mod_TouchModel) (char *name); extern void FNC(Mod_TouchModel) (char *name);
extern struct mleaf_s *FNC(Mod_PointInLeaf) (float *p, struct model_s *model);
extern qbyte *FNC(Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer); //purly for q1
extern void FNC(Mod_NowLoadExternal) (void); extern void FNC(Mod_NowLoadExternal) (void);
extern void FNC(Mod_Think) (void); extern void FNC(Mod_Think) (void);
@ -178,8 +176,6 @@ typedef struct {
void *(*Mod_Extradata) (struct model_s *mod); // handles caching void *(*Mod_Extradata) (struct model_s *mod); // handles caching
void (*Mod_TouchModel) (char *name); void (*Mod_TouchModel) (char *name);
struct mleaf_s *(*Mod_PointInLeaf) (float *p, struct model_s *model);
qbyte *(*Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
void (*Mod_NowLoadExternal) (void); void (*Mod_NowLoadExternal) (void);
void (*Mod_Think) (void); void (*Mod_Think) (void);
qboolean(*Mod_GetTag) (struct model_s *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result); qboolean(*Mod_GetTag) (struct model_s *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result);

View file

@ -579,6 +579,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = MT_SINGLEQW; servertype = MT_SINGLEQW;
else if (!strcmp(com_token, "single:q2")) else if (!strcmp(com_token, "single:q2"))
servertype = MT_SINGLEQ2; servertype = MT_SINGLEQ2;
else if (!strcmp(com_token, "single:q3"))
servertype = MT_SINGLEQ3;
else if (!strcmp(com_token, "single:dp")) else if (!strcmp(com_token, "single:dp"))
servertype = MT_SINGLEDP; servertype = MT_SINGLEDP;
else if (!strcmp(com_token, "single:nq") || !strcmp(com_token, "single:q1")) else if (!strcmp(com_token, "single:nq") || !strcmp(com_token, "single:q1"))
@ -592,6 +594,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = MT_MASTERQW; servertype = MT_MASTERQW;
else if (!strcmp(com_token, "master:q2")) else if (!strcmp(com_token, "master:q2"))
servertype = MT_MASTERQ2; servertype = MT_MASTERQ2;
else if (!strcmp(com_token, "master:q3"))
servertype = MT_MASTERQ3;
else if (!strcmp(com_token, "master")) //any other sort of master, assume it's a qw master. else if (!strcmp(com_token, "master")) //any other sort of master, assume it's a qw master.
servertype = MT_MASTERQW; servertype = MT_MASTERQW;
@ -599,6 +603,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = MT_BCASTQW; servertype = MT_BCASTQW;
else if (!strcmp(com_token, "bcast:q2")) else if (!strcmp(com_token, "bcast:q2"))
servertype = MT_BCASTQ2; servertype = MT_BCASTQ2;
else if (!strcmp(com_token, "bcast:q3"))
servertype = MT_BCASTQ3;
else if (!strcmp(com_token, "bcast:nq")) else if (!strcmp(com_token, "bcast:nq"))
servertype = MT_BCASTNQ; servertype = MT_BCASTNQ;
else if (!strcmp(com_token, "bcast:dp")) else if (!strcmp(com_token, "bcast:dp"))
@ -610,6 +616,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = -MT_SINGLEQW; servertype = -MT_SINGLEQW;
else if (!strcmp(com_token, "favorite:q2")) else if (!strcmp(com_token, "favorite:q2"))
servertype = -MT_SINGLEQ2; servertype = -MT_SINGLEQ2;
else if (!strcmp(com_token, "favorite:q3"))
servertype = -MT_SINGLEQ3;
else if (!strcmp(com_token, "favorite:nq")) else if (!strcmp(com_token, "favorite:nq"))
servertype = -MT_SINGLENQ; servertype = -MT_SINGLENQ;
else if (!strcmp(com_token, "favorite")) else if (!strcmp(com_token, "favorite"))
@ -755,44 +763,51 @@ int NET_CheckPollSockets(void)
if (*(int *)net_message.data == -1) if (*(int *)net_message.data == -1)
{ {
int c; int c;
#ifdef Q2CLIENT
char *s; char *s;
#endif
MSG_BeginReading (); MSG_BeginReading ();
MSG_ReadLong (); // skip the -1 MSG_ReadLong (); // skip the -1
#ifdef Q2CLIENT
c = msg_readcount; c = msg_readcount;
s = MSG_ReadStringLine(); //peek for q2 messages. s = MSG_ReadStringLine(); //peek for q2 messages.
#ifdef Q2CLIENT
if (!strcmp(s, "print")) if (!strcmp(s, "print"))
{ {
CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEQ2, false); CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEQ2, false);
continue; continue;
} }
else if (!strcmp(s, "info")) //parse a bit more... if (!strcmp(s, "info")) //parse a bit more...
{ {
CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEQ2, false); CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEQ2, false);
continue; continue;
} }
else if (!strncmp(s, "getserversResponse\\", 19)) //parse a bit more... if (!strncmp(s, "servers", 6)) //parse a bit more...
{
msg_readcount = c+18-1;
CL_MasterListParse(SS_DARKPLACES, true);
continue;
}
else if (!strncmp(s, "servers", 6)) //parse a bit more...
{ {
msg_readcount = c+7; msg_readcount = c+7;
CL_MasterListParse(SS_QUAKE2, false); CL_MasterListParse(SS_QUAKE2, false);
continue; continue;
} }
else if (!strcmp(s, "infoResponse")) //parse a bit more... #endif
#ifdef Q3CLIENT
if (!strcmp(s, "statusResponse"))
{
CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEQ3, false);
continue;
}
#endif
if (!strncmp(s, "getserversResponse\\", 19)) //parse a bit more...
{
msg_readcount = c+18-1;
CL_MasterListParse(SS_DARKPLACES, true);
continue;
}
if (!strcmp(s, "infoResponse")) //parse a bit more...
{ {
CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEDP, false); CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEDP, false);
continue; continue;
} }
msg_readcount = c; msg_readcount = c;
#endif
c = MSG_ReadByte (); c = MSG_ReadByte ();
@ -970,6 +985,19 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles)
return; return;
switch(mast->type) switch(mast->type)
{ {
#ifdef Q3CLIENT
case MT_BCASTQ3:
case MT_SINGLEQ3:
NET_SendPollPacket (14, va("%c%c%c%cgetstatus\n", 255, 255, 255, 255), mast->adr);
break;
case MT_MASTERQ3:
{
char *str;
str = va("%c%c%c%cgetservers %u empty full\x0A\n", 255, 255, 255, 255, 68);
NET_SendPollPacket (strlen(str), str, mast->adr);
}
break;
#endif
#ifdef Q2CLIENT #ifdef Q2CLIENT
case MT_BCASTQ2: case MT_BCASTQ2:
case MT_SINGLEQ2: case MT_SINGLEQ2:
@ -1050,6 +1078,9 @@ void MasterInfo_WriteServers(void)
case MT_MASTERQ2: case MT_MASTERQ2:
typename = "master:q2"; typename = "master:q2";
break; break;
case MT_MASTERQ3:
typename = "master:q3";
break;
case MT_MASTERDP: case MT_MASTERDP:
typename = "master:dp"; typename = "master:dp";
break; break;
@ -1059,6 +1090,9 @@ void MasterInfo_WriteServers(void)
case MT_BCASTQ2: case MT_BCASTQ2:
typename = "bcast:q2"; typename = "bcast:q2";
break; break;
case MT_BCASTQ3:
typename = "bcast:q3";
break;
case MT_BCASTNQ: case MT_BCASTNQ:
typename = "bcast:nq"; typename = "bcast:nq";
break; break;
@ -1068,6 +1102,9 @@ void MasterInfo_WriteServers(void)
case MT_SINGLEQ2: case MT_SINGLEQ2:
typename = "single:q2"; typename = "single:q2";
break; break;
case MT_SINGLEQ3:
typename = "single:q3";
break;
case MT_SINGLENQ: case MT_SINGLENQ:
typename = "single:nq"; typename = "single:nq";
break; break;
@ -1088,7 +1125,9 @@ void MasterInfo_WriteServers(void)
{ {
if (server->special & SS_FAVORITE) if (server->special & SS_FAVORITE)
{ {
if (server->special & SS_QUAKE2) if (server->special & SS_QUAKE3)
fprintf(mf, "%s\t%s\t%s\n", NET_AdrToString(server->adr), "favorite:q3", server->name);
else if (server->special & SS_QUAKE2)
fprintf(mf, "%s\t%s\t%s\n", NET_AdrToString(server->adr), "favorite:q2", server->name); fprintf(mf, "%s\t%s\t%s\n", NET_AdrToString(server->adr), "favorite:q2", server->name);
else if (server->special & SS_NETQUAKE) else if (server->special & SS_NETQUAKE)
fprintf(mf, "%s\t%s\t%s\n", NET_AdrToString(server->adr), "favorite:nq", server->name); fprintf(mf, "%s\t%s\t%s\n", NET_AdrToString(server->adr), "favorite:nq", server->name);
@ -1145,6 +1184,12 @@ void MasterInfo_Begin(void)
Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers."); Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers.");
Master_AddMaster("192.246.40.37:27900", MT_MASTERQ2, "id q2 Master."); Master_AddMaster("192.246.40.37:27900", MT_MASTERQ2, "id q2 Master.");
} }
//q3
{
Master_AddMaster("255.255.255.255:27960", MT_BCASTQ3, "Nearby Quake3 UDP servers.");
Master_AddMaster("master.quake3arena.com:27950", MT_MASTERQ3, "Quake3 master server.");
}
} }
for (mast = master; mast; mast=mast->next) for (mast = master; mast; mast=mast->next)
@ -1158,7 +1203,9 @@ void Master_QueryServer(serverinfo_t *server)
char data[2048]; char data[2048];
server->sends--; server->sends--;
server->refreshtime = Sys_DoubleTime(); server->refreshtime = Sys_DoubleTime();
if (server->special & SS_DARKPLACES) if (server->special & SS_QUAKE3)
sprintf(data, "%c%c%c%cgetstatus", 255, 255, 255, 255);
else if (server->special & SS_DARKPLACES)
sprintf(data, "%c%c%c%cgetinfo", 255, 255, 255, 255); sprintf(data, "%c%c%c%cgetinfo", 255, 255, 255, 255);
else if (server->special & SS_NETQUAKE) else if (server->special & SS_NETQUAKE)
{ {
@ -1300,6 +1347,11 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite)
if (!info) //not found... if (!info) //not found...
{ {
if (atoi(Info_ValueForKey(msg, "sv_punkbuster")))
return false; //never add servers that require punkbuster. :(
if (atoi(Info_ValueForKey(msg, "sv_pure")))
return false; //we don't support the filesystem hashing. :(
info = Z_Malloc(sizeof(serverinfo_t)); info = Z_Malloc(sizeof(serverinfo_t));
info->adr = net_from; info->adr = net_from;
@ -1322,6 +1374,8 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite)
nl++; nl++;
} }
name = Info_ValueForKey(msg, "hostname"); name = Info_ValueForKey(msg, "hostname");
if (!*name)
name = Info_ValueForKey(msg, "sv_hostname");
Q_strncpyz(info->name, name, sizeof(info->name)); Q_strncpyz(info->name, name, sizeof(info->name));
info->special = info->special & (SS_FAVORITE | SS_KEEPINFO); //favorite is never cleared info->special = info->special & (SS_FAVORITE | SS_KEEPINFO); //favorite is never cleared
if (!strcmp("FTE", Info_ValueForKey(msg, "*distrib"))) if (!strcmp("FTE", Info_ValueForKey(msg, "*distrib")))
@ -1329,11 +1383,17 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite)
else if (!strncmp("FTE", Info_ValueForKey(msg, "*version"), 3)) else if (!strncmp("FTE", Info_ValueForKey(msg, "*version"), 3))
info->special |= SS_FTESERVER; info->special |= SS_FTESERVER;
if (servertype == MT_SINGLEDP) if (servertype == MT_SINGLEDP)
info->special |= SS_DARKPLACES; {
if (atoi(Info_ValueForKey(msg, "protocol")) > 60)
info->special |= SS_QUAKE3;
else
info->special |= SS_DARKPLACES;
}
else if (servertype == MT_SINGLEQ2) else if (servertype == MT_SINGLEQ2)
info->special |= SS_QUAKE2; info->special |= SS_QUAKE2;
else if (servertype == MT_SINGLEQ3)
info->special |= SS_QUAKE3;
else if (servertype == MT_SINGLENQ) else if (servertype == MT_SINGLENQ)
info->special |= SS_NETQUAKE; info->special |= SS_NETQUAKE;
if (favorite) //was specifically named, not retrieved from a master. if (favorite) //was specifically named, not retrieved from a master.
@ -1353,7 +1413,7 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite)
info->tl = atoi(Info_ValueForKey(msg, "timelimit")); info->tl = atoi(Info_ValueForKey(msg, "timelimit"));
info->fl = atoi(Info_ValueForKey(msg, "fraglimit")); info->fl = atoi(Info_ValueForKey(msg, "fraglimit"));
if (servertype == MT_SINGLEQ2 || servertype == MT_SINGLEDP) if (servertype == MT_SINGLEQ3 || servertype == MT_SINGLEQ2 || servertype == MT_SINGLEDP)
{ {
Q_strncpyz(info->gamedir, Info_ValueForKey(msg, "gamename"), sizeof(info->gamedir)); Q_strncpyz(info->gamedir, Info_ValueForKey(msg, "gamename"), sizeof(info->gamedir));
Q_strncpyz(info->map, Info_ValueForKey(msg, "mapname"), sizeof(info->map)); Q_strncpyz(info->map, Info_ValueForKey(msg, "mapname"), sizeof(info->map));

View file

@ -580,7 +580,6 @@ void CS_ClipToLinks ( areanode_t *node, moveclip_t *clip )
} }
} }
//FIXME: Not fully functional
static trace_t CS_Move(vec3_t v1, vec3_t mins, vec3_t maxs, vec3_t v2, float nomonsters, csqcedict_t *passedict) static trace_t CS_Move(vec3_t v1, vec3_t mins, vec3_t maxs, vec3_t v2, float nomonsters, csqcedict_t *passedict)
{ {
moveclip_t clip; moveclip_t clip;
@ -1455,7 +1454,7 @@ static int CS_PointContents(vec3_t org)
{ {
if (!cl.worldmodel) if (!cl.worldmodel)
return FTECONTENTS_EMPTY; return FTECONTENTS_EMPTY;
return cl.worldmodel->hulls[0].funcs.HullPointContents(&cl.worldmodel->hulls[0], org); return cl.worldmodel->funcs.PointContents(cl.worldmodel, org);
} }
static void PF_cs_pointcontents(progfuncs_t *prinst, struct globalvars_s *pr_globals) static void PF_cs_pointcontents(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {

View file

@ -1528,7 +1528,7 @@ glEnable(GL_DEPTH_TEST);
else else
VectorMA(org, 0.5, st->face->plane->normal, org); VectorMA(org, 0.5, st->face->plane->normal, org);
if (!(cl.worldmodel->hulls->funcs.HullPointContents(cl.worldmodel->hulls, org) & FTECONTENTS_SOLID)) if (!(cl.worldmodel->funcs.PointContents(cl.worldmodel, org) & FTECONTENTS_SOLID))
{ {
if (st->face->flags & SURF_PLANEBACK) if (st->face->flags & SURF_PLANEBACK)
{ {
@ -1854,7 +1854,7 @@ int P_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum,
if (r_part_contentswitch.value && ptype->inwater >= 0) if (r_part_contentswitch.value && ptype->inwater >= 0)
{ {
int cont; int cont;
cont = cl.worldmodel->hulls[0].funcs.HullPointContents(&cl.worldmodel->hulls[0], org); cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, org);
if (cont & FTECONTENTS_WATER) if (cont & FTECONTENTS_WATER)
ptype = &part_type[ptype->inwater]; ptype = &part_type[ptype->inwater];
@ -2918,7 +2918,7 @@ int P_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk)
if (r_part_contentswitch.value && ptype->inwater >= 0) if (r_part_contentswitch.value && ptype->inwater >= 0)
{ {
int cont; int cont;
cont = cl.worldmodel->hulls[0].funcs.HullPointContents(&cl.worldmodel->hulls[0], startpos); cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, startpos);
if (cont & FTECONTENTS_WATER) if (cont & FTECONTENTS_WATER)
ptype = &part_type[ptype->inwater]; ptype = &part_type[ptype->inwater];
@ -2936,7 +2936,7 @@ void CLQ2_BubbleTrail (vec3_t start, vec3_t end)
qboolean Q2TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal) qboolean Q2TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
{ {
vec3_t nul = {0,0,0}; vec3_t nul = {0,0,0};
trace_t trace = CM_BoxTrace(start, end, nul, nul, pmove.physents[0].model->hulls[0].firstclipnode, MASK_SOLID); trace_t trace = CM_BoxTrace(pmove.physents[0].model, start, end, nul, nul, MASK_SOLID);
if (trace.fraction < 1) if (trace.fraction < 1)
{ {
@ -4192,6 +4192,8 @@ void P_DrawParticles (void)
if (qglPolygonOffset) if (qglPolygonOffset)
qglPolygonOffset(-1, 0); qglPolygonOffset(-1, 0);
qglEnable(GL_POLYGON_OFFSET_FILL); qglEnable(GL_POLYGON_OFFSET_FILL);
qglEnable(GL_BLEND);
qglDisable(GL_ALPHA_TEST);
qglBegin(GL_QUADS); qglBegin(GL_QUADS);
if (r_drawflat.value == 2) if (r_drawflat.value == 2)
DrawParticleTypes(GL_DrawSketchParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal); DrawParticleTypes(GL_DrawSketchParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal);

View file

@ -35,6 +35,18 @@ typedef struct efrag_s
struct efrag_s *entnext; struct efrag_s *entnext;
} efrag_t; } efrag_t;
typedef enum {
RT_MODEL,
RT_POLY,
RT_SPRITE,
RT_BEAM,
RT_RAIL_CORE,
RT_RAIL_RINGS,
RT_LIGHTNING,
RT_PORTALSURFACE, // doesn't draw anything, just info for portals
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
typedef struct entity_s typedef struct entity_s
{ {
@ -77,6 +89,9 @@ typedef struct entity_s
int flags; int flags;
refEntityType_t rtype;
float rotation;
#ifdef Q3SHADERS #ifdef Q3SHADERS
struct shader_s *forcedshader; struct shader_s *forcedshader;
#endif #endif
@ -263,9 +278,7 @@ struct model_s *GLMod_FindName (char *name);
void *GLMod_Extradata (struct model_s *mod); // handles caching void *GLMod_Extradata (struct model_s *mod); // handles caching
void GLMod_TouchModel (char *name); void GLMod_TouchModel (char *name);
struct mleaf_s *GLMod_PointInLeaf (float *p, struct model_s *model); struct mleaf_s *GLMod_PointInLeaf (struct model_s *model, float *p);
qbyte *GLMod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
qbyte *GLMod_LeafnumPVS (int leafnum, struct model_s *model, qbyte *buffer);
void GLMod_Think (void); void GLMod_Think (void);
void GLMod_NowLoadExternal(void); void GLMod_NowLoadExternal(void);
@ -282,8 +295,7 @@ struct model_s *SWMod_FindName (char *name);
void *SWMod_Extradata (struct model_s *mod); // handles caching void *SWMod_Extradata (struct model_s *mod); // handles caching
void SWMod_TouchModel (char *name); void SWMod_TouchModel (char *name);
struct mleaf_s *SWMod_PointInLeaf (float *p, struct model_s *model); struct mleaf_s *SWMod_PointInLeaf (struct model_s *model, float *p);
qbyte *SWMod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
void SWMod_Think (void); void SWMod_Think (void);
void SWMod_NowLoadExternal(void); void SWMod_NowLoadExternal(void);

View file

@ -116,6 +116,8 @@ cvar_t gl_compress = {"gl_compress", "0"};
cvar_t gl_savecompressedtex = {"gl_savecompressedtex", "0"}; cvar_t gl_savecompressedtex = {"gl_savecompressedtex", "0"};
extern cvar_t gl_dither; extern cvar_t gl_dither;
extern cvar_t gl_maxdist; extern cvar_t gl_maxdist;
extern cvar_t gl_mindist;
extern cvar_t gl_bloom;
cvar_t gl_detail = {"gl_detail", "0", NULL, CVAR_ARCHIVE}; cvar_t gl_detail = {"gl_detail", "0", NULL, CVAR_ARCHIVE};
cvar_t gl_detailscale = {"gl_detailscale", "5"}; cvar_t gl_detailscale = {"gl_detailscale", "5"};
@ -276,6 +278,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_motionblurscale, GLRENDEREROPTIONS); Cvar_Register (&gl_motionblurscale, GLRENDEREROPTIONS);
Cvar_Register (&gl_max_size, GLRENDEREROPTIONS); Cvar_Register (&gl_max_size, GLRENDEREROPTIONS);
Cvar_Register (&gl_maxdist, GLRENDEREROPTIONS); Cvar_Register (&gl_maxdist, GLRENDEREROPTIONS);
Cvar_Register (&gl_mindist, GLRENDEREROPTIONS);
Cvar_Register (&vid_conwidth, GLRENDEREROPTIONS); Cvar_Register (&vid_conwidth, GLRENDEREROPTIONS);
Cvar_Register (&vid_conheight, GLRENDEREROPTIONS); Cvar_Register (&vid_conheight, GLRENDEREROPTIONS);
@ -289,6 +292,8 @@ void GLRenderer_Init(void)
Cvar_Register (&r_shadow_glsl_offsetmapping_scale, GRAPHICALNICETIES); Cvar_Register (&r_shadow_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_glsl_offsetmapping_bias, GRAPHICALNICETIES); Cvar_Register (&r_shadow_glsl_offsetmapping_bias, GRAPHICALNICETIES);
Cvar_Register (&gl_bloom, GRAPHICALNICETIES);
Cvar_Register (&gl_contrast, GLRENDEREROPTIONS); Cvar_Register (&gl_contrast, GLRENDEREROPTIONS);
#ifdef R_XFLIP #ifdef R_XFLIP
Cvar_Register (&r_xflip, GLRENDEREROPTIONS); Cvar_Register (&r_xflip, GLRENDEREROPTIONS);
@ -594,8 +599,6 @@ struct model_s *(*Mod_FindName) (char *name);
void *(*Mod_Extradata) (struct model_s *mod); // handles caching void *(*Mod_Extradata) (struct model_s *mod); // handles caching
void (*Mod_TouchModel) (char *name); void (*Mod_TouchModel) (char *name);
struct mleaf_s *(*Mod_PointInLeaf) (float *p, struct model_s *model);
qbyte *(*Mod_Q1LeafPVS) (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
void (*Mod_NowLoadExternal) (void); void (*Mod_NowLoadExternal) (void);
void (*Mod_Think) (void); void (*Mod_Think) (void);
qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms); qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
@ -693,8 +696,6 @@ rendererinfo_t dedicatedrendererinfo = {
SWMod_Extradata, SWMod_Extradata,
SWMod_TouchModel, SWMod_TouchModel,
SWMod_PointInLeaf,
SWMod_LeafPVS,
SWMod_NowLoadExternal, SWMod_NowLoadExternal,
SWMod_Think, SWMod_Think,
#elif defined(RGLQUAKE) #elif defined(RGLQUAKE)
@ -705,8 +706,6 @@ rendererinfo_t dedicatedrendererinfo = {
GLMod_Extradata, GLMod_Extradata,
GLMod_TouchModel, GLMod_TouchModel,
GLMod_PointInLeaf,
GLMod_LeafPVS,
GLMod_NowLoadExternal, GLMod_NowLoadExternal,
GLMod_Think, GLMod_Think,
#else #else
@ -803,8 +802,6 @@ rendererinfo_t softwarerendererinfo = {
SWMod_Extradata, SWMod_Extradata,
SWMod_TouchModel, SWMod_TouchModel,
SWMod_PointInLeaf,
SWMod_LeafPVS,
SWMod_NowLoadExternal, SWMod_NowLoadExternal,
SWMod_Think, SWMod_Think,
@ -902,8 +899,6 @@ rendererinfo_t openglrendererinfo = {
GLMod_Extradata, GLMod_Extradata,
GLMod_TouchModel, GLMod_TouchModel,
GLMod_PointInLeaf,
GLMod_LeafPVS,
GLMod_NowLoadExternal, GLMod_NowLoadExternal,
GLMod_Think, GLMod_Think,
@ -1283,8 +1278,6 @@ void R_SetRenderer(int wanted)
Mod_Extradata = ri->Mod_Extradata; Mod_Extradata = ri->Mod_Extradata;
Mod_TouchModel = ri->Mod_TouchModel; Mod_TouchModel = ri->Mod_TouchModel;
Mod_PointInLeaf = ri->Mod_PointInLeaf;
Mod_Q1LeafPVS = ri->Mod_Q1LeafPVS;
Mod_NowLoadExternal = ri->Mod_NowLoadExternal; Mod_NowLoadExternal = ri->Mod_NowLoadExternal;
Mod_GetTag = ri->Mod_GetTag; Mod_GetTag = ri->Mod_GetTag;

View file

@ -1141,10 +1141,10 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc)
// calc ambient sound levels // calc ambient sound levels
if (!cl.worldmodel) if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame != fg_quake)
return; return;
l = Mod_PointInLeaf (listener_origin, cl.worldmodel); l = Q1BSP_LeafForPoint(cl.worldmodel, listener_origin);
if (!l || !ambient_level.value) if (!l || !ambient_level.value)
{ {
for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++) for (ambient_channel = 0 ; ambient_channel< NUM_AMBIENTS ; ambient_channel++)

View file

@ -1,6 +1,10 @@
#include "quakedef.h" #include "quakedef.h"
#include <ctype.h> #include <ctype.h>
#ifdef _WIN32
#include <windows.h>
#endif
typedef struct f_query_s typedef struct f_query_s
{ {
char *query; char *query;

View file

@ -462,7 +462,7 @@ qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha)//r
//extern model_t *loadmodel; //extern model_t *loadmodel;
char wads[4096]; char wads[4096];
void Mod_ParseInfoFromEntityLump(const char *data) //actually, this should be in the model code. void Mod_ParseInfoFromEntityLump(char *data) //actually, this should be in the model code.
{ {
extern model_t *loadmodel; extern model_t *loadmodel;
char key[128]; char key[128];
@ -478,13 +478,13 @@ void Mod_ParseInfoFromEntityLump(const char *data) //actually, this should be in
if (!data) if (!data)
return; return;
if (!(data=COM_ParseToken(data))) //read the map info. if (!(data=COM_Parse(data))) //read the map info.
return; // error return; // error
if (com_token[0] != '{') if (com_token[0] != '{')
return; // error return; // error
while (1) while (1)
{ {
if (!(data=COM_ParseToken(data))) if (!(data=COM_Parse(data)))
return; // error return; // error
if (com_token[0] == '}') if (com_token[0] == '}')
break; // end of worldspawn break; // end of worldspawn
@ -492,7 +492,7 @@ void Mod_ParseInfoFromEntityLump(const char *data) //actually, this should be in
strcpy(key, com_token + 1); //_ vars are for comments/utility stuff that arn't visible to progs. Ignore them. strcpy(key, com_token + 1); //_ vars are for comments/utility stuff that arn't visible to progs. Ignore them.
else else
strcpy(key, com_token); strcpy(key, com_token);
if (!((data=COM_ParseToken(data)))) if (!((data=COM_Parse(data))))
return; // error return; // error
if (!strcmp("wad", key)) // for HalfLife maps if (!strcmp("wad", key)) // for HalfLife maps
{ {

View file

@ -94,6 +94,6 @@ void SwapPic (qpic_t *pic);
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(const char *data); void Mod_ParseInfoFromEntityLump(char *data);
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

@ -99,14 +99,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define SP2MODELS //quake2 sprite models #define SP2MODELS //quake2 sprite models
#define MD2MODELS //quake2 alias models #define MD2MODELS //quake2 alias models
#define MD3MODELS //quake3 alias models #define MD3MODELS //quake3 alias models
#define MD5MODELS //doom3 models // #define MD5MODELS //doom3 models
#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/map/sprite 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
#define TERRAIN //heightmap support
#define SV_MASTER //starts up a master server #define SV_MASTER //starts up a master server
#define SVCHAT //serverside npc chatting. see sv_chat.c #define SVCHAT //serverside npc chatting. see sv_chat.c
#define Q2SERVER //server can run a q2 game dll and switches to q2 network and everything else. #define Q2SERVER //server can run a q2 game dll and switches to q2 network and everything else.
@ -125,6 +126,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define IN_XFLIP //allow input to be flipped horizontally. #define IN_XFLIP //allow input to be flipped horizontally.
#define TEXTEDITOR #define TEXTEDITOR
#define PPL //per pixel lighting (stencil shadowing) #define PPL //per pixel lighting (stencil shadowing)
#define DDS //a sort of image file format.
#define PLUGINS #define PLUGINS
@ -184,9 +186,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef RUNTIMELIGHTING #undef RUNTIMELIGHTING
#undef PLUGINS //we don't have any server side stuff. #undef PLUGINS //we don't have any server side stuff.
#undef Q3SHADERS #undef Q3SHADERS
#undef TERRAIN
#endif #endif
#ifdef CLIENTONLY //remove optional server componants that make no sence on a client only build. #ifdef CLIENTONLY //remove optional server componants that make no sence on a client only build.
#undef Q2SERVER #undef Q2SERVER
#undef Q3SERVER
#undef WEBSERVER #undef WEBSERVER
#endif #endif
@ -198,6 +202,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef Q3BSPS #undef Q3BSPS
#undef R_XFLIP #undef R_XFLIP
#undef RUNTIMELIGHTING #undef RUNTIMELIGHTING
#undef TERRAIN
#undef Q3CLIENT
#endif #endif
#endif #endif
@ -207,6 +213,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if !defined(Q3BSPS) #if !defined(Q3BSPS)
#undef Q3SHADERS #undef Q3SHADERS
#undef Q3CLIENT //reconsider this (later) #undef Q3CLIENT //reconsider this (later)
#undef Q3SERVER //reconsider this (later)
#endif #endif
#ifndef Q3CLIENT #ifndef Q3CLIENT
@ -215,7 +222,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define VM_CG #define VM_CG
#endif #endif
#if defined(VM_UI) || defined(VM_CG) || defined(PLUGINS) #if defined(VM_UI) || defined(VM_CG) || defined(Q3SERVER) || defined(PLUGINS)
#define VM_ANY #define VM_ANY
#endif #endif
@ -312,7 +319,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// //
// per-level limits // per-level limits
// //
#define MAX_EDICTS 2048 // FIXME: ouch! ouch! ouch! #define MAX_EDICTS 32767 // FIXME: ouch! ouch! ouch!
#define MAX_LIGHTSTYLES 64 #define MAX_LIGHTSTYLES 64
#define MAX_MODELS 512 // these are sent over the net as bytes #define MAX_MODELS 512 // these are sent over the net as bytes
#define MAX_SOUNDS 256 // so they cannot be blindly increased #define MAX_SOUNDS 256 // so they cannot be blindly increased

View file

@ -1689,7 +1689,7 @@ void Cmd_ExecuteString (char *text, int level)
Cbuf_InsertText (va("set cmd_argc \"%i\"\n", cmd_argc), execlevel); Cbuf_InsertText (va("set cmd_argc \"%i\"\n", cmd_argc), execlevel);
for (i = 1; i < cmd_argc; i++) for (i = 0; i < cmd_argc; i++)
Cbuf_InsertText (va("set cmd_argv%i \"%s\"\n", i, cmd_argv[i]), execlevel); Cbuf_InsertText (va("set cmd_argv%i \"%s\"\n", i, cmd_argv[i]), execlevel);
return; return;
} }
@ -1849,7 +1849,7 @@ const char *If_Token(const char *func, const char **end)
while(*func <= ' ' && *func) while(*func <= ' ' && *func)
func++; func++;
s = COM_ParseToken(func); s = COM_ParseToken(func, NULL);
if (*com_token == '(') if (*com_token == '(')
{ {
@ -1884,7 +1884,7 @@ const char *If_Token(const char *func, const char **end)
} }
else if (!strcmp(com_token, "defined")) //functions else if (!strcmp(com_token, "defined")) //functions
{ {
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
var = Cvar_FindVar(com_token); var = Cvar_FindVar(com_token);
*end = s; *end = s;
return retstring((var != NULL)?"true":""); return retstring((var != NULL)?"true":"");
@ -1895,7 +1895,7 @@ const char *If_Token(const char *func, const char **end)
} }
else if (!strcmp(com_token, "vid")) //mostly for use with the menu system. else if (!strcmp(com_token, "vid")) //mostly for use with the menu system.
{ {
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
#ifndef SERVERONLY #ifndef SERVERONLY
if (qrenderer == QR_NONE) if (qrenderer == QR_NONE)
s2 = ""; s2 = "";
@ -1926,10 +1926,10 @@ const char *If_Token(const char *func, const char **end)
*end = s; *end = s;
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
if (!strcmp(com_token, "=")) //comparisions if (!strcmp(com_token, "=")) //comparisions
{ {
func=COM_ParseToken(s); func=COM_ParseToken(s, NULL);
if (*com_token == '=') //lol. "=" == "==" if (*com_token == '=') //lol. "=" == "=="
return retfloat(!strcmp(s2, If_Token(func, end))); return retfloat(!strcmp(s2, If_Token(func, end)));
else else
@ -1939,7 +1939,7 @@ const char *If_Token(const char *func, const char **end)
return retfloat(!strcmp(s2, If_Token(s, end))); return retfloat(!strcmp(s2, If_Token(s, end)));
if (!strcmp(com_token, "!")) if (!strcmp(com_token, "!"))
{ {
func=COM_ParseToken(s); func=COM_ParseToken(s, NULL);
if (*com_token == '=') if (*com_token == '=')
{ {
s = If_Token(func, end); s = If_Token(func, end);
@ -1957,7 +1957,7 @@ const char *If_Token(const char *func, const char **end)
} }
if (!strcmp(com_token, ">")) if (!strcmp(com_token, ">"))
{ {
func=COM_ParseToken(s); func=COM_ParseToken(s, NULL);
if (*com_token == '=') if (*com_token == '=')
return retfloat(atof(s2)>=atof(If_Token(func, end))); return retfloat(atof(s2)>=atof(If_Token(func, end)));
else if (*com_token == '<')//vb? else if (*com_token == '<')//vb?
@ -1977,7 +1977,7 @@ const char *If_Token(const char *func, const char **end)
} }
if (!strcmp(com_token, "<")) if (!strcmp(com_token, "<"))
{ {
func=COM_ParseToken(s); func=COM_ParseToken(s, NULL);
if (*com_token == '=') if (*com_token == '=')
return retfloat(atof(s2)<=atof(If_Token(func, end))); return retfloat(atof(s2)<=atof(If_Token(func, end)));
else if (*com_token == '>')//vb? else if (*com_token == '>')//vb?
@ -1998,7 +1998,7 @@ const char *If_Token(const char *func, const char **end)
return retfloat(atof(s2)/atof(If_Token(s, end))); return retfloat(atof(s2)/atof(If_Token(s, end)));
if (!strcmp(com_token, "&")) //and if (!strcmp(com_token, "&")) //and
{ {
func=COM_ParseToken(s); func=COM_ParseToken(s, NULL);
if (*com_token == '&') if (*com_token == '&')
return retfloat(*s2&&*If_Token(s, end)); return retfloat(*s2&&*If_Token(s, end));
else else
@ -2006,7 +2006,7 @@ const char *If_Token(const char *func, const char **end)
} }
if (!strcmp(com_token, "|")) //or if (!strcmp(com_token, "|")) //or
{ {
func=COM_ParseToken(s); func=COM_ParseToken(s, NULL);
if (*com_token == '|') if (*com_token == '|')
{ {
func = If_Token(func, end); func = If_Token(func, end);

File diff suppressed because it is too large Load diff

View file

@ -232,7 +232,7 @@ extern qboolean com_eof;
char *COM_Parse (char *data); char *COM_Parse (char *data);
char *COM_ParseCString (char *data); char *COM_ParseCString (char *data);
char *COM_StringParse (char *data, qboolean expandmacros, qboolean qctokenize); char *COM_StringParse (char *data, qboolean expandmacros, qboolean qctokenize);
const char *COM_ParseToken (const char *data); const char *COM_ParseToken (const char *data, const char *punctuation);
char *COM_TrimString(char *str); char *COM_TrimString(char *str);
@ -259,6 +259,7 @@ char *VARGS va(char *format, ...);
//============================================================================ //============================================================================
extern int com_file_copyprotected;
extern int com_filesize; extern int com_filesize;
struct cache_user_s; struct cache_user_s;
@ -300,6 +301,7 @@ qbyte *COM_LoadMallocFile (char *path);
void COM_LoadCacheFile (char *path, struct cache_user_s *cu); void COM_LoadCacheFile (char *path, struct cache_user_s *cu);
void COM_CreatePath (char *path); void COM_CreatePath (char *path);
void COM_Gamedir (char *dir); void COM_Gamedir (char *dir);
void FS_ForceToPure(char *str, char *crcs, int seed);
char *COM_GetPathInfo (int i, int *crc); char *COM_GetPathInfo (int i, int *crc);
char *COM_NextPath (char *prevpath); char *COM_NextPath (char *prevpath);
void COM_FlushFSCache(void); //a file was written using fopen void COM_FlushFSCache(void); //a file was written using fopen
@ -311,7 +313,7 @@ void COM_FlushTempoaryPacks(void);
void COM_EnumerateFiles (char *match, int (*func)(char *, int, void *), void *parm); void COM_EnumerateFiles (char *match, int (*func)(char *, int, void *), void *parm);
extern struct cvar_s registered; extern struct cvar_s registered;
extern qboolean standard_quake, rogue, hipnotic; extern qboolean standard_quake; //fixme: remove
#define MAX_INFO_KEY 64 #define MAX_INFO_KEY 64
char *Info_ValueForKey (char *s, const char *key); char *Info_ValueForKey (char *s, const char *key);

View file

@ -45,6 +45,7 @@ void SWMod_LoadLighting (lump_t *l);
void Q2BSP_SetHullFuncs(hull_t *hull); void Q2BSP_SetHullFuncs(hull_t *hull);
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace); qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
int Q2BSP_PointContents(model_t *mod, vec3_t p);
qbyte areabits[MAX_Q2MAP_AREAS/8]; qbyte areabits[MAX_Q2MAP_AREAS/8];
@ -270,9 +271,6 @@ q2mapsurface_t *map_surfaces;
int numplanes; int numplanes;
mplane_t map_planes[MAX_Q2MAP_PLANES+6]; // extra for box hull mplane_t map_planes[MAX_Q2MAP_PLANES+6]; // extra for box hull
int numnodes;
mnode_t map_nodes[MAX_MAP_NODES+6]; // extra for box hull
int numleafs = 1; // allow leaf funcs to be called without a map int numleafs = 1; // allow leaf funcs to be called without a map
mleaf_t map_leafs[MAX_MAP_LEAFS]; mleaf_t map_leafs[MAX_MAP_LEAFS];
int emptyleaf; int emptyleaf;
@ -324,7 +322,7 @@ cvar_t map_noCurves = {"map_noCurves", "0", NULL, CVAR_CHEAT};
cvar_t map_autoopenportals = {"map_autoopenportals", "1"}; //1 for lack of mod support. cvar_t map_autoopenportals = {"map_autoopenportals", "1"}; //1 for lack of mod support.
cvar_t r_subdivisions = {"r_subdivisions", "2"}; cvar_t r_subdivisions = {"r_subdivisions", "2"};
int CM_NumInlineModels (void); int CM_NumInlineModels (model_t *model);
q2cmodel_t *CM_InlineModel (char *name); q2cmodel_t *CM_InlineModel (char *name);
void CM_InitBoxHull (void); void CM_InitBoxHull (void);
void FloodAreaConnections (void); void FloodAreaConnections (void);
@ -1451,12 +1449,10 @@ void CMod_LoadNodes (lump_t *l)
if (count > MAX_MAP_NODES) if (count > MAX_MAP_NODES)
Host_Error ("Map has too many nodes"); Host_Error ("Map has too many nodes");
out = map_nodes; out = Hunk_Alloc(sizeof(mnode_t)*count);
numnodes = count;
loadmodel->nodes = out; loadmodel->nodes = out;
loadmodel->numnodes = numnodes; loadmodel->numnodes = count;
for (i=0 ; i<count ; i++, out++, in++) for (i=0 ; i<count ; i++, out++, in++)
{ {
@ -1481,7 +1477,7 @@ void CMod_LoadNodes (lump_t *l)
if (child < 0) if (child < 0)
out->children[j] = (mnode_t *)(map_leafs + -1-child); out->children[j] = (mnode_t *)(map_leafs + -1-child);
else else
out->children[j] = map_nodes + child; out->children[j] = loadmodel->nodes + child;
} }
} }
@ -2749,13 +2745,11 @@ void CModQ3_LoadNodes (lump_t *l)
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
out = map_nodes;//Hunk_AllocName ( count*sizeof(*out), loadname); out = Hunk_AllocName ( count*sizeof(*out), loadname);
if (count > MAX_MAP_NODES) if (count > MAX_MAP_NODES)
Host_Error("Too many nodes on map"); Host_Error("Too many nodes on map");
numnodes = count;
loadmodel->nodes = out; loadmodel->nodes = out;
loadmodel->numnodes = count; loadmodel->numnodes = count;
@ -3238,7 +3232,7 @@ void CMQ3_CalcPHS (void)
vcount = 0; vcount = 0;
for (i=0 ; i<numclusters ; i++) for (i=0 ; i<numclusters ; i++)
{ {
scan = CM_ClusterPVS ( i, NULL ); scan = CM_ClusterPVS (sv.worldmodel, i, NULL);
for (j=0 ; j<numclusters ; j++) for (j=0 ; j<numclusters ; j++)
{ {
if ( scan[j>>3] & (1<<(j&7)) ) if ( scan[j>>3] & (1<<(j&7)) )
@ -3282,14 +3276,9 @@ void CMQ3_CalcPHS (void)
, vcount/numclusters, count/numclusters, numclusters); , vcount/numclusters, count/numclusters, numclusters);
} }
qbyte *CM_LeafnumPVS (int leafnum, model_t *model, qbyte *buffer) qbyte *CM_LeafnumPVS (model_t *model, int leafnum, qbyte *buffer)
{ {
return CM_ClusterPVS(CM_LeafCluster(leafnum), buffer); return CM_ClusterPVS(model, CM_LeafCluster(model, leafnum), buffer);
}
int CM_ModelPointLeafnum (vec3_t p, model_t *mdl)
{
return CM_PointLeafnum(p);
} }
#ifndef SERVERONLY #ifndef SERVERONLY
@ -3420,9 +3409,9 @@ void SWR_Q2BSP_StainNode (mnode_t *node, float *parms)
#endif #endif
void Q2BSP_FatPVS (vec3_t org, qboolean add); void Q2BSP_FatPVS (model_t *mod, vec3_t org, qboolean add);
qboolean Q2BSP_EdictInFatPVS(edict_t *ent); qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent);
void Q2BSP_FindTouchedLeafs(edict_t *ent); void Q2BSP_FindTouchedLeafs(model_t *mod, edict_t *ent);
void GLQ2BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void GLQ2BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void SWQ2BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void SWQ2BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
@ -3444,7 +3433,6 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
// free old stuff // free old stuff
numplanes = 0; numplanes = 0;
numnodes = 0;
numleafs = 0; numleafs = 0;
numcmodels = 0; numcmodels = 0;
numvisibility = 0; numvisibility = 0;
@ -3592,7 +3580,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS; loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
loadmodel->funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs; loadmodel->funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
#if defined(RGLQUAKE) #if defined(RGLQUAKE)
loadmodel->funcs.LightPointValues = GLQ3_LightGrid; loadmodel->funcs.LightPointValues = GLQ3_LightGrid;
@ -3600,6 +3588,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.MarkLights = Q2BSP_MarkLights; loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
#endif #endif
loadmodel->funcs.Trace = CM_Trace; loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
#ifndef SERVERONLY #ifndef SERVERONLY
//light grid info //light grid info
@ -3675,8 +3664,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.StainNode = NULL; loadmodel->funcs.StainNode = NULL;
loadmodel->funcs.MarkLights = NULL; loadmodel->funcs.MarkLights = NULL;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace; loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
break; break;
#if defined(RGLQUAKE) #if defined(RGLQUAKE)
@ -3713,8 +3703,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode; loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights; loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace; loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
break; break;
#endif #endif
#if defined(SWQUAKE) #if defined(SWQUAKE)
@ -3752,8 +3743,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.StainNode = SWR_Q2BSP_StainNode; loadmodel->funcs.StainNode = SWR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights; loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum; loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace; loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
break; break;
#endif #endif
default: default:
@ -3779,7 +3771,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->numsubmodels = CM_NumInlineModels(); loadmodel->numsubmodels = CM_NumInlineModels(loadmodel);
{ {
model_t *mod = loadmodel; model_t *mod = loadmodel;
@ -3858,41 +3850,41 @@ q2cmodel_t *CM_InlineModel (char *name)
return &map_cmodels[num]; return &map_cmodels[num];
} }
int CM_NumClusters (void) int CM_NumClusters (model_t *model)
{ {
return numclusters; return numclusters;
} }
int CM_ClusterSize (void) int CM_ClusterSize (model_t *model)
{ {
return map_q3pvs->rowsize ? map_q3pvs->rowsize : MAX_MAP_LEAFS / 8; return map_q3pvs->rowsize ? map_q3pvs->rowsize : MAX_MAP_LEAFS / 8;
} }
int CM_NumInlineModels (void) int CM_NumInlineModels (model_t *model)
{ {
return numcmodels; return numcmodels;
} }
char *CM_EntityString (void) char *CM_EntityString (model_t *model)
{ {
return map_entitystring; return map_entitystring;
} }
int CM_LeafContents (int leafnum) int CM_LeafContents (model_t *model, int leafnum)
{ {
if (leafnum < 0 || leafnum >= numleafs) if (leafnum < 0 || leafnum >= numleafs)
Host_Error ("CM_LeafContents: bad number"); Host_Error ("CM_LeafContents: bad number");
return map_leafs[leafnum].contents; return map_leafs[leafnum].contents;
} }
int CM_LeafCluster (int leafnum) int CM_LeafCluster (model_t *model, int leafnum)
{ {
if (leafnum < 0 || leafnum >= numleafs) if (leafnum < 0 || leafnum >= numleafs)
Host_Error ("CM_LeafCluster: bad number"); Host_Error ("CM_LeafCluster: bad number");
return map_leafs[leafnum].cluster; return map_leafs[leafnum].cluster;
} }
int CM_LeafArea (int leafnum) int CM_LeafArea (model_t *model, int leafnum)
{ {
if (leafnum < 0 || leafnum >= numleafs) if (leafnum < 0 || leafnum >= numleafs)
Host_Error ("CM_LeafArea: bad number"); Host_Error ("CM_LeafArea: bad number");
@ -3932,15 +3924,14 @@ void CM_InitBoxHull (void)
box_model.funcs.MarkLights = Q2BSP_MarkLights; box_model.funcs.MarkLights = Q2BSP_MarkLights;
#endif #endif
box_model.funcs.LeafPVS = CM_LeafnumPVS; box_model.funcs.LeafPVS = CM_LeafnumPVS;
box_model.funcs.LeafForPoint = CM_ModelPointLeafnum; box_model.funcs.LeafnumForPoint = CM_PointLeafnum;
box_model.hulls[0].available = true; box_model.hulls[0].available = true;
Q2BSP_SetHullFuncs(&box_model.hulls[0]); Q2BSP_SetHullFuncs(&box_model.hulls[0]);
box_headnode = numnodes; box_model.nodes = Hunk_Alloc(sizeof(mnode_t)*6);
box_planes = &map_planes[numplanes]; box_planes = &map_planes[numplanes];
if (numnodes+6 > MAX_MAP_NODES if (numbrushes+1 > MAX_Q2MAP_BRUSHES
|| numbrushes+1 > MAX_Q2MAP_BRUSHES
|| numleafbrushes+1 > MAX_Q2MAP_LEAFBRUSHES || numleafbrushes+1 > MAX_Q2MAP_LEAFBRUSHES
|| numbrushsides+6 > MAX_Q2MAP_BRUSHSIDES || numbrushsides+6 > MAX_Q2MAP_BRUSHSIDES
|| numplanes+12 > MAX_Q2MAP_PLANES) || numplanes+12 > MAX_Q2MAP_PLANES)
@ -3968,7 +3959,7 @@ void CM_InitBoxHull (void)
s->surface = &nullsurface; s->surface = &nullsurface;
// nodes // nodes
c = &map_nodes[box_headnode+i]; c = &box_model.nodes[i];
c->plane = map_planes + (numplanes+i*2); c->plane = map_planes + (numplanes+i*2);
c->childnum[side] = -1 - emptyleaf; c->childnum[side] = -1 - emptyleaf;
if (i != 5) if (i != 5)
@ -4000,7 +3991,7 @@ To keep everything totally uniform, bounding boxes are turned into small
BSP trees instead of being compared directly. BSP trees instead of being compared directly.
=================== ===================
*/ */
int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs) void CM_SetTempboxSize (vec3_t mins, vec3_t maxs)
{ {
box_planes[0].dist = maxs[0]; box_planes[0].dist = maxs[0];
box_planes[1].dist = -maxs[0]; box_planes[1].dist = -maxs[0];
@ -4014,13 +4005,11 @@ int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs)
box_planes[9].dist = -maxs[2]; box_planes[9].dist = -maxs[2];
box_planes[10].dist = mins[2]; box_planes[10].dist = mins[2];
box_planes[11].dist = -mins[2]; box_planes[11].dist = -mins[2];
return box_headnode;
} }
model_t *CM_TempBoxModel(vec3_t mins, vec3_t maxs) model_t *CM_TempBoxModel(vec3_t mins, vec3_t maxs)
{ {
box_model.hulls[0].firstclipnode = CM_HeadnodeForBox(mins, maxs); CM_SetTempboxSize(mins, maxs);
return &box_model; return &box_model;
} }
@ -4030,7 +4019,7 @@ CM_PointLeafnum_r
================== ==================
*/ */
int CM_PointLeafnum_r (vec3_t p, int num) int CM_PointLeafnum_r (model_t *mod, vec3_t p, int num)
{ {
float d; float d;
mnode_t *node; mnode_t *node;
@ -4038,7 +4027,7 @@ int CM_PointLeafnum_r (vec3_t p, int num)
while (num >= 0) while (num >= 0)
{ {
node = map_nodes + num; node = mod->nodes + num;
plane = node->plane; plane = node->plane;
if (plane->type < 3) if (plane->type < 3)
@ -4056,11 +4045,11 @@ int CM_PointLeafnum_r (vec3_t p, int num)
return -1 - num; return -1 - num;
} }
int CM_PointLeafnum (vec3_t p) int CM_PointLeafnum (model_t *mod, vec3_t p)
{ {
if (!numplanes) if (!numplanes)
return 0; // sound may call this without map loaded return 0; // sound may call this without map loaded
return CM_PointLeafnum_r (p, 0); return CM_PointLeafnum_r (mod, p, 0);
} }
/* /*
@ -4075,7 +4064,7 @@ int *leaf_list;
float *leaf_mins, *leaf_maxs; float *leaf_mins, *leaf_maxs;
int leaf_topnode; int leaf_topnode;
void CM_BoxLeafnums_r (int nodenum) void CM_BoxLeafnums_r (model_t *mod, int nodenum)
{ {
mplane_t *plane; mplane_t *plane;
mnode_t *node; mnode_t *node;
@ -4094,7 +4083,7 @@ void CM_BoxLeafnums_r (int nodenum)
return; return;
} }
node = &map_nodes[nodenum]; node = &mod->nodes[nodenum];
plane = node->plane; plane = node->plane;
// s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane); // s = BoxOnPlaneSide (leaf_mins, leaf_maxs, plane);
s = BOX_ON_PLANE_SIDE(leaf_mins, leaf_maxs, plane); s = BOX_ON_PLANE_SIDE(leaf_mins, leaf_maxs, plane);
@ -4106,14 +4095,14 @@ void CM_BoxLeafnums_r (int nodenum)
{ // go down both { // go down both
if (leaf_topnode == -1) if (leaf_topnode == -1)
leaf_topnode = nodenum; leaf_topnode = nodenum;
CM_BoxLeafnums_r (node->childnum[0]); CM_BoxLeafnums_r (mod, node->childnum[0]);
nodenum = node->childnum[1]; nodenum = node->childnum[1];
} }
} }
} }
int CM_BoxLeafnums_headnode (vec3_t mins, vec3_t maxs, int *list, int listsize, int headnode, int *topnode) int CM_BoxLeafnums_headnode (model_t *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int headnode, int *topnode)
{ {
leaf_list = list; leaf_list = list;
leaf_count = 0; leaf_count = 0;
@ -4123,7 +4112,7 @@ int CM_BoxLeafnums_headnode (vec3_t mins, vec3_t maxs, int *list, int listsize,
leaf_topnode = -1; leaf_topnode = -1;
CM_BoxLeafnums_r (headnode); CM_BoxLeafnums_r (mod, headnode);
if (topnode) if (topnode)
*topnode = leaf_topnode; *topnode = leaf_topnode;
@ -4131,10 +4120,10 @@ int CM_BoxLeafnums_headnode (vec3_t mins, vec3_t maxs, int *list, int listsize,
return leaf_count; return leaf_count;
} }
int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode) int CM_BoxLeafnums (model_t *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode)
{ {
return CM_BoxLeafnums_headnode (mins, maxs, list, return CM_BoxLeafnums_headnode (mod, mins, maxs, list,
listsize, map_cmodels[0].headnode, topnode); listsize, mod->hulls[0].firstclipnode, topnode);
} }
@ -4146,17 +4135,17 @@ CM_PointContents
================== ==================
*/ */
#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist) #define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
int CM_PointContents (vec3_t p, int headnode) int CM_PointContents (model_t *mod, vec3_t p)
{ {
int i, j, contents; int i, j, contents;
mleaf_t *leaf; mleaf_t *leaf;
q2cbrush_t *brush; q2cbrush_t *brush;
q2cbrushside_t *brushside; q2cbrushside_t *brushside;
if (!numnodes) // map not loaded if (!mod) // map not loaded
return 0; return 0;
i = CM_PointLeafnum_r (p, headnode); i = CM_PointLeafnum_r (mod, p, mod->hulls[0].firstclipnode);
if (!mapisq3) if (!mapisq3)
return map_leafs[i].contents; //q2 is simple. return map_leafs[i].contents; //q2 is simple.
@ -4200,7 +4189,7 @@ Handles offseting and rotation of the end points for moving and
rotating entities rotating entities
================== ==================
*/ */
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles) int CM_TransformedPointContents (model_t *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles)
{ {
vec3_t p_l; vec3_t p_l;
vec3_t temp; vec3_t temp;
@ -4221,7 +4210,7 @@ int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t a
p_l[2] = DotProduct (temp, up); p_l[2] = DotProduct (temp, up);
} }
return CM_PointContents(p, headnode); return CM_PointContents(mod, p);
} }
@ -4724,7 +4713,7 @@ CM_RecursiveHullCheck
================== ==================
*/ */
void CM_RecursiveHullCheck (int num, float p1f, float p2f, vec3_t p1, vec3_t p2) void CM_RecursiveHullCheck (model_t *mod, int num, float p1f, float p2f, vec3_t p1, vec3_t p2)
{ {
mnode_t *node; mnode_t *node;
mplane_t *plane; mplane_t *plane;
@ -4750,7 +4739,7 @@ void CM_RecursiveHullCheck (int num, float p1f, float p2f, vec3_t p1, vec3_t p2)
// find the point distances to the seperating plane // find the point distances to the seperating plane
// and the offset for the size of the box // and the offset for the size of the box
// //
node = map_nodes + num; node = mod->nodes + num;
plane = node->plane; plane = node->plane;
if (plane->type < 3) if (plane->type < 3)
@ -4781,12 +4770,12 @@ return;
// see which sides we need to consider // see which sides we need to consider
if (t1 >= offset && t2 >= offset) if (t1 >= offset && t2 >= offset)
{ {
CM_RecursiveHullCheck (node->childnum[0], p1f, p2f, p1, p2); CM_RecursiveHullCheck (mod, node->childnum[0], p1f, p2f, p1, p2);
return; return;
} }
if (t1 < -offset && t2 < -offset) if (t1 < -offset && t2 < -offset)
{ {
CM_RecursiveHullCheck (node->childnum[1], p1f, p2f, p1, p2); CM_RecursiveHullCheck (mod, node->childnum[1], p1f, p2f, p1, p2);
return; return;
} }
@ -4822,7 +4811,7 @@ return;
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
mid[i] = p1[i] + frac*(p2[i] - p1[i]); mid[i] = p1[i] + frac*(p2[i] - p1[i]);
CM_RecursiveHullCheck (node->childnum[side], p1f, midf, p1, mid); CM_RecursiveHullCheck (mod, node->childnum[side], p1f, midf, p1, mid);
// go past the node // go past the node
@ -4835,7 +4824,7 @@ return;
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
mid[i] = p1[i] + frac2*(p2[i] - p1[i]); mid[i] = p1[i] + frac2*(p2[i] - p1[i]);
CM_RecursiveHullCheck (node->childnum[side^1], midf, p2f, mid, p2); CM_RecursiveHullCheck (mod, node->childnum[side^1], midf, p2f, mid, p2);
} }
@ -4846,9 +4835,9 @@ return;
CM_BoxTrace CM_BoxTrace
================== ==================
*/ */
trace_t CM_BoxTrace (vec3_t start, vec3_t end, trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs, vec3_t mins, vec3_t maxs,
int headnode, int brushmask) int brushmask)
{ {
int i; int i;
#if ADJ #if ADJ
@ -4868,7 +4857,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
trace_trace.fraction = 1; trace_trace.fraction = 1;
trace_trace.surface = &(nullsurface.c); trace_trace.surface = &(nullsurface.c);
if (!numnodes) // map not loaded if (!mod) // map not loaded
return trace_trace; return trace_trace;
trace_contents = brushmask; trace_contents = brushmask;
@ -4921,7 +4910,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
c2[i] += 1; c2[i] += 1;
} }
numleafs = CM_BoxLeafnums_headnode (c1, c2, leafs, sizeof(leafs)/sizeof(leafs[0]), headnode, &topnode); numleafs = CM_BoxLeafnums_headnode (mod, c1, c2, leafs, sizeof(leafs)/sizeof(leafs[0]), mod->hulls[0].firstclipnode, &topnode);
for (i=0 ; i<numleafs ; i++) for (i=0 ; i<numleafs ; i++)
{ {
CM_TestInLeaf (leafs[i]); CM_TestInLeaf (leafs[i]);
@ -4970,7 +4959,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
// //
// general sweeping through world // general sweeping through world
// //
CM_RecursiveHullCheck (headnode, 0, 1, trace_start, trace_end); CM_RecursiveHullCheck (mod, mod->hulls[0].firstclipnode, 0, 1, trace_start, trace_end);
if (trace_nearfraction == 1) if (trace_nearfraction == 1)
{ {
@ -4993,7 +4982,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace) qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{ {
*trace = CM_BoxTrace(start, end, mins, maxs, model->hulls[0].firstclipnode, MASK_PLAYERSOLID); *trace = CM_BoxTrace(model, start, end, mins, maxs, MASK_PLAYERSOLID);
return trace->fraction != 1; return trace->fraction != 1;
} }
@ -5010,9 +4999,9 @@ rotating entities
#endif #endif
trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, trace_t CM_TransformedBoxTrace (model_t *mod, vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs, vec3_t mins, vec3_t maxs,
int headnode, int brushmask, int brushmask,
vec3_t origin, vec3_t angles) vec3_t origin, vec3_t angles)
{ {
trace_t trace; trace_t trace;
@ -5027,7 +5016,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
VectorSubtract (end, origin, end_l); VectorSubtract (end, origin, end_l);
// rotate start and end into the models frame of reference // rotate start and end into the models frame of reference
if (headnode != box_headnode && if (mod != &box_model &&
(angles[0] || angles[1] || angles[2]) ) (angles[0] || angles[1] || angles[2]) )
rotated = true; rotated = true;
else else
@ -5049,7 +5038,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
} }
// sweep the box through the model // sweep the box through the model
trace = CM_BoxTrace (start_l, end_l, mins, maxs, headnode, brushmask); trace = CM_BoxTrace (mod, start_l, end_l, mins, maxs, brushmask);
if (rotated && trace.fraction != 1.0) if (rotated && trace.fraction != 1.0)
{ {
@ -5195,7 +5184,7 @@ qbyte phsrow[MAX_MAP_LEAFS/8];
qbyte *CM_ClusterPVS (int cluster, qbyte *buffer) qbyte *CM_ClusterPVS (model_t *mod, int cluster, qbyte *buffer)
{ {
if (!buffer) if (!buffer)
buffer = pvsrow; buffer = pvsrow;
@ -5220,7 +5209,7 @@ qbyte *CM_ClusterPVS (int cluster, qbyte *buffer)
return buffer; return buffer;
} }
qbyte *CM_ClusterPHS (int cluster) qbyte *CM_ClusterPHS (model_t *mod, int cluster)
{ {
if (mapisq3) //phs not working yet. if (mapisq3) //phs not working yet.
{ {
@ -5349,7 +5338,7 @@ void CMQ3_SetAreaPortalState (int area1, int area2, qboolean open)
} }
} }
qboolean VARGS CM_AreasConnected (int area1, int area2) qboolean VARGS CM_AreasConnected (model_t *mod, int area1, int area2)
{ {
if (map_noareas.value) if (map_noareas.value)
return true; return true;
@ -5386,7 +5375,7 @@ that area in the same flood as the area parameter
This is used by the client refreshes to cull visibility This is used by the client refreshes to cull visibility
================= =================
*/ */
int CM_WriteAreaBits (qbyte *buffer, int area) int CM_WriteAreaBits (model_t *mod, qbyte *buffer, int area)
{ {
int i; int i;
int floodnum; int floodnum;
@ -5406,7 +5395,7 @@ int CM_WriteAreaBits (qbyte *buffer, int area)
{ {
for (i=0 ; i<numareas ; i++) for (i=0 ; i<numareas ; i++)
{ {
if (!area || CM_AreasConnected ( i, area ) || i == area) if (!area || CM_AreasConnected (mod, i, area ) || i == area)
buffer[i>>3] |= 1<<(i&7); buffer[i>>3] |= 1<<(i&7);
} }
} }
@ -5459,7 +5448,7 @@ Returns true if any leaf under headnode has a cluster that
is potentially visible is potentially visible
============= =============
*/ */
qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits) qboolean CM_HeadnodeVisible (model_t *mod, int nodenum, qbyte *visbits)
{ {
int leafnum; int leafnum;
int cluster; int cluster;
@ -5476,13 +5465,13 @@ qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits)
return false; return false;
} }
node = &map_nodes[nodenum]; node = &mod->nodes[nodenum];
if (CM_HeadnodeVisible(node->childnum[0], visbits)) if (CM_HeadnodeVisible(mod, node->childnum[0], visbits))
return true; return true;
return CM_HeadnodeVisible(node->childnum[1], visbits); return CM_HeadnodeVisible(mod, node->childnum[1], visbits);
} }
/*
qboolean Q2BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) qboolean Q2BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace)
{ {
trace_t ret = CM_BoxTrace(p1, p2, hull->clip_mins, hull->clip_maxs, hull->firstclipnode, MASK_SOLID); trace_t ret = CM_BoxTrace(p1, p2, hull->clip_mins, hull->clip_maxs, hull->firstclipnode, MASK_SOLID);
@ -5490,11 +5479,11 @@ qboolean Q2BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
if (ret.fraction==1) if (ret.fraction==1)
return true; return true;
return false; return false;
} }*/
int Q2BSP_HullPointContents(hull_t *hull, vec3_t p) int Q2BSP_PointContents(model_t *mod, vec3_t p)
{ {
int pc, ret = FTECONTENTS_EMPTY; int pc, ret = FTECONTENTS_EMPTY;
pc = CM_PointContents (p, hull->firstclipnode); pc = CM_PointContents (mod, p);
if (pc & (Q2CONTENTS_SOLID|Q2CONTENTS_WINDOW)) if (pc & (Q2CONTENTS_SOLID|Q2CONTENTS_WINDOW))
ret |= FTECONTENTS_SOLID; ret |= FTECONTENTS_SOLID;
if (pc & Q2CONTENTS_LAVA) if (pc & Q2CONTENTS_LAVA)
@ -5510,7 +5499,7 @@ int Q2BSP_HullPointContents(hull_t *hull, vec3_t p)
} }
void Q2BSP_SetHullFuncs(hull_t *hull) void Q2BSP_SetHullFuncs(hull_t *hull)
{ {
hull->funcs.HullPointContents = Q2BSP_HullPointContents; // hull->funcs.HullPointContents = Q2BSP_HullPointContents;
} }

View file

@ -1007,7 +1007,7 @@ void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, floa
ML_ProjectionMatrix(proj, wdivh, fovy); ML_ProjectionMatrix(proj, wdivh, fovy);
Matrix4_Multiply(proj, modelview, tempm); Matrix4_Multiply(proj, modelview, tempm);
Matrix4x4_Invert_Simple(proj, tempm); Matrix4x4_Invert_Simple((void*)proj, (void*)tempm);
{ {
float v[4], tempv[4]; float v[4], tempv[4];

View file

@ -1158,9 +1158,38 @@ void Plug_Load_f(void)
Con_Printf("Couldn't load plugin %s\n", Cmd_Argv(1)); Con_Printf("Couldn't load plugin %s\n", Cmd_Argv(1));
} }
} }
/*
static long Test_SysCalls_Ex(void *offset, unsigned int mask, int fn, const long *arg)
{
switch(fn)
{
case 1:
Con_Printf("%s", VM_POINTER(arg[0]));
break;
default:
Con_Printf("Can't handle %i\n", fn);
}
return 0;
}
static int EXPORT_FN Test_SysCalls(int arg, ...)
{
return 0;
}
void VM_Test_f(void)
{
vm_t *vm;
vm = VM_Create(NULL, "vm/test", Test_SysCalls, Test_SysCalls_Ex);
if (vm)
{
VM_Call(vm, 0, "");
VM_Destroy(vm);
}
}*/
void Plug_Init(void) void Plug_Init(void)
{ {
// Cmd_AddCommand("testvm", VM_Test_f);
Cvar_Register(&plug_sbar, "plugins"); Cvar_Register(&plug_sbar, "plugins");
Cvar_Register(&plug_loaddefault, "plugins"); Cvar_Register(&plug_loaddefault, "plugins");
Cmd_AddCommand("plug_closeall", Plug_CloseAll_f); Cmd_AddCommand("plug_closeall", Plug_CloseAll_f);

View file

@ -740,7 +740,7 @@ void PM_CategorizePosition (void)
//if we hit a wall when going forwards and we are in a ladder region, then we are on a ladder. //if we hit a wall when going forwards and we are in a ladder region, then we are on a ladder.
if (pmove.physents[0].model->fromgame == fg_quake2) if (pmove.physents[0].model->fromgame == fg_quake2)
{ {
t = CM_BoxTrace(pmove.origin, fwd1, player_mins, player_maxs, pmove.physents[0].model->hulls[0].firstclipnode, MASK_PLAYERSOLID); t = CM_BoxTrace(pmove.physents[0].model, pmove.origin, fwd1, player_mins, player_maxs, MASK_PLAYERSOLID);
if (t.fraction < 1) if (t.fraction < 1)
{ {
pmove.onladder = true; pmove.onladder = true;

View file

@ -85,17 +85,14 @@ hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs)
return &box_hull; return &box_hull;
} }
int PM_TransformedHullPointContents (hull_t *hull, vec3_t p, vec3_t origin, vec3_t angles)
int PM_TransformedModelPointContents (model_t *mod, vec3_t p, vec3_t origin, vec3_t angles)
{ {
vec3_t p_l, forward, up, right, temp; vec3_t p_l, forward, up, right, temp;
VectorSubtract (p, origin, p_l); VectorSubtract (p, origin, p_l);
if (!player_mins[2])
p_l[2] -= hull->clip_mins[2]+0.1;
// rotate start and end into the models frame of reference // rotate start and end into the models frame of reference
if (hull != &box_hull && if (angles[0] || angles[1] || angles[2])
(angles[0] || angles[1] || angles[2]) )
{ {
AngleVectors (angles, forward, right, up); AngleVectors (angles, forward, right, up);
@ -105,9 +102,10 @@ int PM_TransformedHullPointContents (hull_t *hull, vec3_t p, vec3_t origin, vec3
p_l[2] = DotProduct (temp, up); p_l[2] = DotProduct (temp, up);
} }
return hull->funcs.HullPointContents(hull, p_l); return mod->funcs.PointContents(mod, p_l);
} }
/* /*
================== ==================
PM_PointContents PM_PointContents
@ -116,19 +114,21 @@ PM_PointContents
*/ */
int PM_PointContents (vec3_t p) int PM_PointContents (vec3_t p)
{ {
hull_t *hull;
int num; int num;
int pc; int pc;
physent_t *pe;
model_t *pm;
hull = &pmove.physents[0].model->hulls[0]; pm = pmove.physents[0].model;
pc = pm->funcs.PointContents(pm, p);
pc = hull->funcs.HullPointContents(hull, p);
//we need this for e2m2 - waterjumping on to plats wouldn't work otherwise. //we need this for e2m2 - waterjumping on to plats wouldn't work otherwise.
for (num = 1; num < pmove.numphysent; num++) for (num = 1; num < pmove.numphysent; num++)
{ {
if (pmove.physents[num].model) pe = &pmove.physents[num];
pc |= PM_TransformedHullPointContents(&pmove.physents[num].model->hulls[0], p, pmove.physents[num].origin, pmove.physents[num].angles); pm = pe->model;
if (pm)
pc |= PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles);
} }
return pc; return pc;
@ -218,13 +218,13 @@ PM_TestPlayerPosition
Returns false if the given player position is not valid (in solid) Returns false if the given player position is not valid (in solid)
================ ================
*/ */
int CM_TransformedPointContents (vec3_t p, int headnode, vec3_t origin, vec3_t angles);
qboolean PM_TestPlayerPosition (vec3_t pos) qboolean PM_TestPlayerPosition (vec3_t pos)
{ {
int i; int i;
physent_t *pe; physent_t *pe;
vec3_t mins, maxs; vec3_t mins, maxs;
hull_t *hull; hull_t *hull;
trace_t trace;
for (i=0 ; i< pmove.numphysent ; i++) for (i=0 ; i< pmove.numphysent ; i++)
{ {
@ -233,28 +233,36 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
// get the clipping hull // get the clipping hull
if (pe->model) if (pe->model)
{ {
/*
#ifdef Q2BSPS #ifdef Q2BSPS
if (pe->model->fromgame == fg_quake2 || pe->model->fromgame == fg_quake3) if (pe->model->fromgame == fg_quake2 || pe->model->fromgame == fg_quake3)
{ {
trace_t trace = CM_TransformedBoxTrace(pos, pos, player_mins, player_maxs, pe->model->hulls[0].firstclipnode, MASK_PLAYERSOLID, pe->origin, pe->angles); trace_t trace = CM_TransformedBoxTrace(pe->model, pos, pos, player_mins, player_maxs, MASK_PLAYERSOLID, pe->origin, pe->angles);
if (trace.fraction == 0) if (trace.fraction == 0)
return false; return false;
continue; continue;
} }
#endif #endif*/
hull = &pe->model->hulls[pmove.hullnum]; /* hull = &pe->model->hulls[pmove.hullnum];
if (!hull->available || !hull->planes || !hull->clipnodes) if (!hull->available || !hull->planes || !hull->clipnodes)
hull = &pe->model->hulls[1]; hull = &pe->model->hulls[1];
*/
if (pe->model->funcs.Trace(pe->model, 0, 0, pos, pos, player_mins, player_maxs, &trace))
return false; //solid
} }
else else
{ {
VectorSubtract (pe->mins, player_maxs, mins); VectorSubtract (pe->mins, player_maxs, mins);
VectorSubtract (pe->maxs, player_mins, maxs); VectorSubtract (pe->maxs, player_mins, maxs);
hull = PM_HullForBox (mins, maxs); hull = PM_HullForBox (mins, maxs);
} VectorSubtract(pos, pe->origin, mins);
if (PM_TransformedHullPointContents (hull, pos, pe->origin, pe->angles) & FTECONTENTS_SOLID) if (Q1BSP_HullPointContents(hull, mins) & FTECONTENTS_SOLID)
return false; return false;
// if (PM_TransformedHullPointContents (hull, pos, pe->origin, pe->angles) & FTECONTENTS_SOLID)
// return false;
}
} }
return true; return true;

View file

@ -444,6 +444,7 @@ enum clcq2_ops_e
#define U_DPFLAGS (1<<11) #define U_DPFLAGS (1<<11)
#define U_TAGINFO (1<<12) #define U_TAGINFO (1<<12)
#define U_LIGHT (1<<13) #define U_LIGHT (1<<13)
#define U_EFFECTS16 (1<<14)
#define U_FARMORE (1<<15) #define U_FARMORE (1<<15)
@ -854,6 +855,7 @@ typedef struct q1usercmd_s
#define Q2RF_ADDATIVE 0x00080000 #define Q2RF_ADDATIVE 0x00080000
#define RF_NOSHADOW 0x00100000 #define RF_NOSHADOW 0x00100000
#define RF_NODEPTHTEST 0x00200000
// player_state_t->refdef flags // player_state_t->refdef flags
#define Q2RDF_UNDERWATER 1 // warp the screen as apropriate #define Q2RDF_UNDERWATER 1 // warp the screen as apropriate

View file

@ -1,5 +1,6 @@
#include "quakedef.h" #include "quakedef.h"
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer);
/* /*
============================================================================ ============================================================================
@ -204,7 +205,12 @@ int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
void Q1BSP_SetHullFuncs(hull_t *hull) void Q1BSP_SetHullFuncs(hull_t *hull)
{ {
hull->funcs.HullPointContents = Q1BSP_HullPointContents; // hull->funcs.HullPointContents = Q1BSP_HullPointContents;
}
int Q1BSP_PointContents(model_t *model, vec3_t point)
{
return Q1BSP_HullPointContents(&model->hulls[0], point);
} }
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace) qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
@ -823,7 +829,7 @@ extern int fatbytes;
extern qbyte fatpvs[(MAX_MAP_LEAFS+1)/4]; extern qbyte fatpvs[(MAX_MAP_LEAFS+1)/4];
//does the recursive work of Q1BSP_FatPVS //does the recursive work of Q1BSP_FatPVS
void SV_Q1BSP_AddToFatPVS (vec3_t org, mnode_t *node) void SV_Q1BSP_AddToFatPVS (model_t *mod, vec3_t org, mnode_t *node)
{ {
int i; int i;
qbyte *pvs; qbyte *pvs;
@ -837,7 +843,7 @@ void SV_Q1BSP_AddToFatPVS (vec3_t org, mnode_t *node)
{ {
if (node->contents != Q1CONTENTS_SOLID) if (node->contents != Q1CONTENTS_SOLID)
{ {
pvs = Mod_Q1LeafPVS ( (mleaf_t *)node, sv.worldmodel, NULL); pvs = Q1BSP_LeafPVS (mod, (mleaf_t *)node, NULL);
for (i=0 ; i<fatbytes ; i++) for (i=0 ; i<fatbytes ; i++)
fatpvs[i] |= pvs[i]; fatpvs[i] |= pvs[i];
} }
@ -852,7 +858,7 @@ void SV_Q1BSP_AddToFatPVS (vec3_t org, mnode_t *node)
node = node->children[1]; node = node->children[1];
else else
{ // go down both { // go down both
SV_Q1BSP_AddToFatPVS (org, node->children[0]); SV_Q1BSP_AddToFatPVS (mod, org, node->children[0]);
node = node->children[1]; node = node->children[1];
} }
} }
@ -866,15 +872,15 @@ Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
given point. given point.
============= =============
*/ */
void Q1BSP_FatPVS (vec3_t org, qboolean add) void Q1BSP_FatPVS (model_t *mod, vec3_t org, qboolean add)
{ {
fatbytes = (sv.worldmodel->numleafs+31)>>3; fatbytes = (mod->numleafs+31)>>3;
if (!add) if (!add)
Q_memset (fatpvs, 0, fatbytes); Q_memset (fatpvs, 0, fatbytes);
SV_Q1BSP_AddToFatPVS (org, sv.worldmodel->nodes); SV_Q1BSP_AddToFatPVS (mod, org, mod->nodes);
} }
qboolean Q1BSP_EdictInFatPVS(edict_t *ent) qboolean Q1BSP_EdictInFatPVS(model_t *mod, edict_t *ent)
{ {
int i; int i;
@ -935,18 +941,158 @@ void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node)
if (sides & 2) if (sides & 2)
Q1BSP_RFindTouchedLeafs (ent, node->children[1]); Q1BSP_RFindTouchedLeafs (ent, node->children[1]);
} }
void Q1BSP_FindTouchedLeafs(edict_t *ent) void Q1BSP_FindTouchedLeafs(model_t *mod, edict_t *ent)
{ {
ent->num_leafs = 0; ent->num_leafs = 0;
if (ent->v->modelindex) if (ent->v->modelindex)
Q1BSP_RFindTouchedLeafs (ent, sv.worldmodel->nodes); Q1BSP_RFindTouchedLeafs (ent, mod->nodes);
} }
#endif #endif
/* /*
Server only functions Server only functions
============================================================================== ==============================================================================
PVS type stuff
*/ */
/*
===================
Mod_DecompressVis
===================
*/
qbyte *Q1BSP_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed)
{
int c;
qbyte *out;
int row;
row = (model->numleafs+7)>>3;
out = decompressed;
#if 0
memcpy (out, in, row);
#else
if (!in)
{ // no vis info, so make all visible
while (row)
{
*out++ = 0xff;
row--;
}
return decompressed;
}
do
{
if (*in)
{
*out++ = *in++;
continue;
}
c = in[1];
in += 2;
while (c)
{
*out++ = 0;
c--;
}
} while (out - decompressed < row);
#endif
return decompressed;
}
static qbyte mod_novis[MAX_MAP_LEAFS/8];
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer)
{
static qbyte decompressed[MAX_MAP_LEAFS/8];
if (leaf == model->leafs)
return mod_novis;
if (!buffer)
buffer = decompressed;
return Q1BSP_DecompressVis (leaf->compressed_vis, model, buffer);
}
qbyte *Q1BSP_LeafnumPVS (model_t *model, int leafnum, qbyte *buffer)
{
return Q1BSP_LeafPVS(model, model->leafs + leafnum, buffer);
}
//returns the leaf number, which is used as a bit index into the pvs.
int Q1BSP_LeafnumForPoint (model_t *model, vec3_t p)
{
mnode_t *node;
float d;
mplane_t *plane;
if (!model)
{
Sys_Error ("Mod_PointInLeaf: bad model");
}
if (!model->nodes)
return 0;
node = model->nodes;
while (1)
{
if (node->contents < 0)
return (mleaf_t *)node - model->leafs;
plane = node->plane;
d = DotProduct (p,plane->normal) - plane->dist;
if (d > 0)
node = node->children[0];
else
node = node->children[1];
}
return 0; // never reached
}
mleaf_t *Q1BSP_LeafForPoint (model_t *model, vec3_t p)
{
return model->leafs + Q1BSP_LeafnumForPoint(model, p);
}
/*
PVS type stuff
==============================================================================
Init stuff
*/
void Q1BSP_Init(void)
{
memset (mod_novis, 0xff, sizeof(mod_novis));
}
//sets up the functions a server needs.
//fills in bspfuncs_t
void Q1BSP_SetModelFuncs(model_t *mod)
{
#ifndef CLIENTONLY
mod->funcs.FatPVS = Q1BSP_FatPVS;
mod->funcs.EdictInFatPVS = Q1BSP_EdictInFatPVS;
mod->funcs.FindTouchedLeafs_Q1 = Q1BSP_FindTouchedLeafs;
#endif
mod->funcs.LightPointValues = NULL;
mod->funcs.StainNode = NULL;
mod->funcs.MarkLights = NULL;
mod->funcs.LeafnumForPoint = Q1BSP_LeafnumForPoint;
mod->funcs.LeafPVS = Q1BSP_LeafnumPVS;
mod->funcs.Trace = Q1BSP_Trace;
mod->funcs.PointContents = Q1BSP_PointContents;
}

View file

@ -689,8 +689,8 @@ int QVM_Exec(register qvm_t *qvm, int command, int arg0, int arg1, int arg2, int
qvm->pc = oldpc; qvm->pc = oldpc;
qvm->bp += 15*4; qvm->bp += 15*4;
if(qvm->bp!=qvm->max_bp) // if(qvm->bp!=qvm->max_bp)
Sys_Error("VM run time error: freed too much stack\n"); // Sys_Error("VM run time error: freed too much stack\n");
param = qvm->sp[0]; param = qvm->sp[0];
POP(1); POP(1);
return param; return param;

View file

@ -56,8 +56,12 @@ typedef enum {
UI_SHUTDOWN = 2, UI_SHUTDOWN = 2,
UI_KEY_EVENT = 3, UI_KEY_EVENT = 3,
UI_MOUSE_DELTA = 4, UI_MOUSE_DELTA = 4,
UI_DRAWMENU = 5, UI_REFRESH = 5,
UI_FULLSCREEN = 6, UI_IS_FULLSCREEN = 6,
UI_SET_ACTIVE_MENU = 7,
UI_CONSOLE_COMMAND = 8,
UI_DRAW_CONNECT_SCREEN = 9,
UI_HASUNIQUECDKEY = 10,
//return value expected //return value expected
//0 means don't take input //0 means don't take input
//1 means engine should skip map/scrback update, //1 means engine should skip map/scrback update,
@ -73,83 +77,105 @@ typedef enum {
} uiExport_t; } uiExport_t;
typedef enum { typedef enum {
UI_SYSERROR = 0, UI_ERROR = 0,
UI_PRINT = 1, UI_PRINT = 1,
UI_CVAR_SET = 3, UI_MILLISECONDS = 2,
UI_CVAR_GET_VALUE = 4, UI_CVAR_SET = 3,
UI_CVAR_GET_STRING = 5, UI_CVAR_VARIABLEVALUE = 4,
UI_CVAR_SET_VALUE = 6, UI_CVAR_VARIABLESTRINGBUFFER = 5,
UI_CVAR_RESET = 7, //not yet implemented UI_CVAR_SETVALUE = 6,
UI_CVAR_RESET = 7,
UI_CBUF_ADD_COMMAND = 12, UI_CVAR_CREATE = 8,
UI_FS_OPEN = 13, UI_CVAR_INFOSTRINGBUFFER = 9,
UI_FS_READ = 14, UI_ARGC = 10,
UI_FS_WRITE = 15, UI_ARGV = 11,
UI_FS_CLOSE = 16, UI_CMD_EXECUTETEXT = 12,
UI_FS_LISTFILES = 17, UI_FS_FOPENFILE = 13,
UI_FS_READ = 14,
UI_PRECACHE_MODEL = 18, UI_FS_WRITE = 15,
UI_PRECACHE_SKIN = 19, //fte doesn't implement. UI_FS_FCLOSEFILE = 16,
UI_DRAW_CACHEPIC = 20, UI_FS_GETFILELIST = 17,
UI_R_REGISTERMODEL = 18,
UI_SCENE_CLEAR = 21, UI_R_REGISTERSKIN = 19,
UI_SCENE_ADD_ENTITY = 22, UI_R_REGISTERSHADERNOMIP = 20,
UI_SCENE_ADD_LIGHT = 24, //non-functional UI_R_CLEARSCENE = 21,
UI_SCENE_RENDER = 25, UI_R_ADDREFENTITYTOSCENE = 22,
UI_R_ADDPOLYTOSCENE = 23,
UI_DRAW_COLOUR = 26, UI_R_ADDLIGHTTOSCENE = 24,
UI_DRAW_IMAGE = 27, UI_R_RENDERSCENE = 25,
UI_LERP_TAG = 29, //currently non-functional. UI_R_SETCOLOR = 26,
UI_R_DRAWSTRETCHPIC = 27,
UI_SOUND_PRECACHE = 31, UI_UPDATESCREEN = 28,
UI_SOUND_PLAY = 32, UI_CM_LERPTAG = 29,
UI_CM_LOADMODEL = 30,
UI_KEY_NAME = 33, //retrieves text for the name of a key - eg leftarrow UI_S_REGISTERSOUND = 31,
UI_KEY_GETBINDING = 34, UI_S_STARTLOCALSOUND = 32,
UI_KEY_SETBINDING = 35, UI_KEY_KEYNUMTOSTRINGBUF = 33,
UI_KEY_ISDOWN = 36, UI_KEY_GETBINDINGBUF = 34,
UI_KEY_SETBINDING = 35,
UI_KEY_CLEARALL = 39, UI_KEY_ISDOWN = 36,
UI_KEY_GETDEST = 40, UI_KEY_GETOVERSTRIKEMODE = 37,
UI_KEY_SETDEST = 41, UI_KEY_SETOVERSTRIKEMODE = 38,
UI_GET_VID_CONFIG = 43, //very minimal UI_KEY_CLEARSTATES = 39,
UI_GET_CLIENT_STATE = 44, //not going to do anything btw. UI_KEY_GETCATCHER = 40,
UI_GET_SERVERINFO = 45, UI_KEY_SETCATCHER = 41,
UI_GETCLIPBOARDDATA = 42,
//server browser stuph. UI_GETGLCONFIG = 43,
UI_MS_GETSERVERCOUNT = 46, UI_GETCLIENTSTATE = 44,
UI_CLEAR_PINGS = 47, UI_GETCONFIGSTRING = 45,
UI_GET_PINGADDRESS = 48, UI_LAN_GETPINGQUEUECOUNT = 46,
UI_GET_PINGINFO = 49, UI_LAN_CLEARPING = 47,
UI_LAN_GETPING = 48,
UI_CVAR_REGISTER = 50, UI_LAN_GETPINGINFO = 49,
UI_CVAR_UPDATE = 51, UI_CVAR_REGISTER = 50,
UI_MEM_AVAILABLE = 52, UI_CVAR_UPDATE = 51,
UI_MEMORY_REMAINING = 52,
UI_CDKEY_GET = 53, UI_GET_CDKEY = 53,
UI_CDKEY_SET = 54, UI_SET_CDKEY = 54,
UI_R_REGISTERFONT = 55,
UI_REGISTERFRONT = 55, UI_R_MODELBOUNDS = 56,
UI_PC_ADD_GLOBAL_DEFINE = 57,
UI_GET_REALTIME = 62, UI_PC_LOAD_SOURCE = 58,
UI_LAN_GET_COUNT = 65, UI_PC_FREE_SOURCE = 59,
UI_LAN_GET_ADDRESS = 66, UI_PC_READ_TOKEN = 60,
UI_PC_SOURCE_FILE_AND_LINE = 61,
UI_VERIFYCDKEY = 81, UI_S_STOPBACKGROUNDTRACK = 62,
UI_SOMETHINGTODOWITHPUNKBUSTER = 87, UI_S_STARTBACKGROUNDTRACK = 63,
UI_REAL_TIME = 64,
UI_LAN_GETSERVERCOUNT = 65,
UI_LAN_GETSERVERADDRESSSTRING = 66,
UI_MEMSET = 100, UI_LAN_GETSERVERINFO = 67,
UI_MEMMOVE = 101, UI_LAN_MARKSERVERVISIBLE = 68,
UI_STRNCPY = 102, UI_LAN_UPDATEVISIBLEPINGS = 69,
UI_SIN = 103, UI_LAN_RESETPINGS = 70,
UI_COS = 104, UI_LAN_LOADCACHEDSERVERS = 71,
UI_ATAN2 = 105, UI_LAN_SAVECACHEDSERVERS = 72,
UI_SQRT = 106, UI_LAN_ADDSERVER = 73,
UI_FLOOR = 107, UI_LAN_REMOVESERVER = 74,
UI_CEIL = 108, UI_CIN_PLAYCINEMATIC = 75,
UI_CIN_STOPCINEMATIC = 76,
UI_CIN_RUNCINEMATIC = 77,
UI_CIN_DRAWCINEMATIC = 78,
UI_CIN_SETEXTENTS = 79,
UI_R_REMAP_SHADER = 80,
UI_VERIFY_CDKEY = 81,
UI_LAN_SERVERSTATUS = 82,
UI_LAN_GETSERVERPING = 83,
UI_LAN_SERVERISVISIBLE = 84,
UI_LAN_COMPARESERVERS = 85,
// 1.32
UI_FS_SEEK = 86,
UI_SET_PBCLSTATUS = 87,
UI_MEMSET = 100,
UI_MEMCPY,
UI_STRNCPY,
UI_SIN,
UI_COS,
UI_ATAN2,
UI_SQRT,
UI_FLOOR,
UI_CEIL,
UI_CACHE_PIC = 500, UI_CACHE_PIC = 500,

View file

@ -48,6 +48,7 @@ void Plug_DrawReloadImages(void);
//these things are specific to FTE QuakeWorld //these things are specific to FTE QuakeWorld
void UI_Init (void); void UI_Init (void);
void UI_Restart_f(void);
void UI_Stop (void); void UI_Stop (void);
qboolean UI_Q2LayoutChanged(void); qboolean UI_Q2LayoutChanged(void);
void UI_StringChanged(int num); void UI_StringChanged(int num);

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) Console Application" 0x0103 # TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=gas2masm - Win32 Release CFG=gas2masm - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
@ -13,11 +13,10 @@ CFG=gas2masm - Win32 Release
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "gas2masm.mak" CFG="gas2masm - Win32 Release" !MESSAGE NMAKE /f "gas2masm.mak" CFG="gas2masm - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "gas2masm - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "gas2masm - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE "gas2masm - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE !MESSAGE
@ -27,33 +26,6 @@ CFG=gas2masm - Win32 Release
# PROP Scc_LocalPath "" # PROP Scc_LocalPath ""
CPP=cl.exe CPP=cl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "gas2masm - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
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:console /machine:I386
# ADD 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:console /machine:I386
!ELSEIF "$(CFG)" == "gas2masm - Win32 Debug"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1 # PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug" # PROP BASE Output_Dir ".\Debug"
@ -75,12 +47,8 @@ BSC32=bscmake.exe
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:console /debug /machine:I386 # 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:console /debug /machine:I386
# ADD 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:console /debug /machine:I386 # ADD 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:console /debug /machine:I386
!ENDIF
# Begin Target # Begin Target
# Name "gas2masm - Win32 Release"
# Name "gas2masm - Win32 Debug" # Name "gas2masm - Win32 Debug"
# Begin Group "Source Files" # Begin Group "Source Files"

View file

@ -210,7 +210,6 @@ void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
} }
#endif #endif
} }
#include <malloc.h>
qboolean GLMod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace) qboolean GLMod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{ {
galiasinfo_t *mod = Mod_Extradata(model); galiasinfo_t *mod = Mod_Extradata(model);
@ -1800,7 +1799,7 @@ void R_DrawGAliasModel (entity_t *e)
mb.shader = currententity->forcedshader; mb.shader = currententity->forcedshader;
mb.fog = fog; mb.fog = fog;
mb.mesh = &mesh; mb.mesh = &mesh;
mb.infokey = currententity->keynum; mb.infokey = -1;//currententity->keynum;
mb.dlightbits = 0; mb.dlightbits = 0;
R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED | MF_COLORS); R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED | MF_COLORS);
@ -1833,7 +1832,7 @@ void R_DrawGAliasModel (entity_t *e)
mb.shader = skin->shader; mb.shader = skin->shader;
mb.fog = fog; mb.fog = fog;
mb.mesh = &mesh; mb.mesh = &mesh;
mb.infokey = currententity->keynum; mb.infokey = -1;//currententity->keynum;
mb.dlightbits = 0; mb.dlightbits = 0;
R_IBrokeTheArrays(); R_IBrokeTheArrays();
@ -2420,12 +2419,12 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum,
while(f) while(f)
{ {
f = COM_ParseToken(f); f = COM_ParseToken(f,NULL);
if (!f) if (!f)
return; return;
if (!strcmp(com_token, "replace")) if (!strcmp(com_token, "replace"))
{ {
f = COM_ParseToken(f); f = COM_ParseToken(f, NULL);
len = strlen(com_token); len = strlen(com_token);
@ -2436,7 +2435,7 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum,
//found it //found it
{ {
surfname+=len; surfname+=len;
f = COM_ParseToken(f); f = COM_ParseToken(f, NULL);
p = com_token; p = com_token;
while(*p) //copy the replacement while(*p) //copy the replacement
*out++ = *p++; *out++ = *p++;
@ -2460,7 +2459,7 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum,
if (!strcmp(com_token, surfname)) if (!strcmp(com_token, surfname))
{ {
f++; f++;
COM_ParseToken(f); COM_ParseToken(f, NULL);
strcpy(out, com_token); strcpy(out, com_token);
return; return;
} }
@ -2680,22 +2679,27 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
} }
} }
texnums = Hunk_Alloc(sizeof(*texnums)+s); //but only preload it if we have no replacement.
saved = (qbyte*)(texnums+1);
outskin->ofstexels = (qbyte *)(saved) - (qbyte *)outskin;
memcpy(saved, pskintype+1, s);
GLMod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight);
if (!texture) if (!texture)
{ {
sprintf(skinname, "%s_%i", loadname, i); //we're not using 24bits
texnums = Hunk_Alloc(sizeof(*texnums)+s);
saved = (qbyte*)(texnums+1);
outskin->ofstexels = (qbyte *)(saved) - (qbyte *)outskin;
memcpy(saved, pskintype+1, s);
GLMod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight);
//the extra underscore is to stop
sprintf(skinname, "%s__%i", loadname, i);
texture = GL_LoadTexture(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); texture = GL_LoadTexture(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha);
if (r_fb_models.value) if (r_fb_models.value)
{ {
sprintf(skinname, "%s_%i_luma", loadname, i); sprintf(skinname, "%s__%i_luma", loadname, i);
fbtexture = GL_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); fbtexture = GL_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true);
} }
} }
else
texnums = Hunk_Alloc(sizeof(*texnums));
outskin->texnums=1; outskin->texnums=1;
outskin->ofstexnums = (char *)texnums - (char *)outskin; outskin->ofstexnums = (char *)texnums - (char *)outskin;
@ -3396,8 +3400,10 @@ qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2
if (tagnum <= 0 || tagnum > inf->numtags) if (tagnum <= 0 || tagnum > inf->numtags)
return false; return false;
if (frame1 < 0 || frame1 >= inf->numtagframes) if (frame1 < 0)
return false; return false;
if (frame1 >= inf->numtagframes)
frame1 = inf->numtagframes - 1;
if (frame2 < 0 || frame2 >= inf->numtagframes) if (frame2 < 0 || frame2 >= inf->numtagframes)
frame2 = frame1; frame2 = frame1;
tagnum--; //tagnum 0 is 'use my angles/org' tagnum--; //tagnum 0 is 'use my angles/org'

View file

@ -16,6 +16,11 @@ typedef struct {
} gl_state_t; } gl_state_t;
gl_state_t gl_state; gl_state_t gl_state;
void GL_SetShaderState2D(qboolean is2d)
{
gl_state.in2d = is2d;
}
extern int *lightmap_textures; extern int *lightmap_textures;
extern int *deluxmap_textures; extern int *deluxmap_textures;
@ -1024,6 +1029,32 @@ void R_DeformVertices ( meshbuffer_t *mb )
} }
} }
void RB_CalcEnvironmentTexCoords( float *st )
{
int i;
float *v, *normal;
vec3_t viewer, reflected;
float d;
v = vertexArray[0];
normal = normalsArray[0];
for (i = 0 ; i < numVerts ; i++, v += 3, normal += 3, st += 2 )
{
VectorSubtract (r_origin, v, viewer);
VectorNormalizeFast (viewer);
d = DotProduct (normal, viewer);
reflected[0] = normal[0]*2*d - viewer[0];
reflected[1] = normal[1]*2*d - viewer[1];
reflected[2] = normal[2]*2*d - viewer[2];
st[0] = 0.5 + reflected[1] * 0.5;
st[1] = 0.5 - reflected[2] * 0.5;
}
}
/* /*
============== ==============
R_VertexTCBase R_VertexTCBase
@ -1032,11 +1063,11 @@ R_VertexTCBase
void R_VertexTCBase ( int tcgen, int unit ) void R_VertexTCBase ( int tcgen, int unit )
{ {
int i; int i;
vec3_t t, n; // vec3_t t, n;
float *outCoords; float *outCoords;
vec3_t transform; // vec3_t transform;
mat3_t inverse_axis; // mat3_t inverse_axis;
mat3_t axis; // mat3_t axis;
outCoords = tUnitCoordsArray[unit][0]; outCoords = tUnitCoordsArray[unit][0];
qglTexCoordPointer( 2, GL_FLOAT, 0, outCoords ); qglTexCoordPointer( 2, GL_FLOAT, 0, outCoords );
@ -1050,6 +1081,11 @@ void R_VertexTCBase ( int tcgen, int unit )
} }
else if ( tcgen == TC_GEN_ENVIRONMENT ) else if ( tcgen == TC_GEN_ENVIRONMENT )
{ {
RB_CalcEnvironmentTexCoords(outCoords); //use genuine q3 code, to get it totally identical
//plus, it looks like less overhead too
//I guess it depends on the size of the mesh
/*
//the old qfusion code
if ( !currentmodel ) if ( !currentmodel )
{ {
VectorSubtract ( vec3_origin, currententity->origin, transform ); VectorSubtract ( vec3_origin, currententity->origin, transform );
@ -1095,6 +1131,7 @@ void R_VertexTCBase ( int tcgen, int unit )
outCoords[0] = t[0]*n[2] - n[0]; outCoords[0] = t[0]*n[2] - n[0];
outCoords[1] = t[1]*n[2] - n[1]; outCoords[1] = t[1]*n[2] - n[1];
} }
*/
} }
else if ( tcgen == TC_GEN_VECTOR ) else if ( tcgen == TC_GEN_VECTOR )
{ {
@ -1117,16 +1154,19 @@ R_ShaderpassTex
*/ */
int R_ShaderpassTex ( shaderpass_t *pass ) int R_ShaderpassTex ( shaderpass_t *pass )
{ {
if ( pass->flags & SHADER_PASS_ANIMMAP ) { if (pass->flags & (SHADER_PASS_ANIMMAP|SHADER_PASS_LIGHTMAP|SHADER_PASS_DELUXMAP))
return pass->anim_frames[(int)(pass->anim_fps * r_localShaderTime) % pass->anim_numframes];
}
else if ( (pass->flags & SHADER_PASS_LIGHTMAP) && r_lmtex >= 0 )
{ {
return lightmap_textures[r_lmtex]; if ( pass->flags & SHADER_PASS_ANIMMAP ) {
} return pass->anim_frames[(int)(pass->anim_fps * r_localShaderTime) % pass->anim_numframes];
else if ( (pass->flags & SHADER_PASS_DELUXMAP) && r_lmtex >= 0 ) }
{ else if ( (pass->flags & SHADER_PASS_LIGHTMAP) && r_lmtex >= 0 )
return deluxmap_textures[r_lmtex]; {
return lightmap_textures[r_lmtex];
}
else if ( (pass->flags & SHADER_PASS_DELUXMAP) && r_lmtex >= 0 )
{
return deluxmap_textures[r_lmtex];
}
} }
return pass->anim_frames[0] ? pass->anim_frames[0] : 0; return pass->anim_frames[0] ? pass->anim_frames[0] : 0;
@ -1718,6 +1758,11 @@ void R_SetShaderpassState ( shaderpass_t *pass, qboolean mtex )
qglDepthMask ( GL_FALSE ); qglDepthMask ( GL_FALSE );
} }
} }
else
{
qglDepthFunc ( GL_ALWAYS );
qglDepthMask ( GL_FALSE );
}
} }
/* /*

View file

@ -65,6 +65,7 @@ extern cvar_t gl_load24bit;
#ifdef Q3SHADERS #ifdef Q3SHADERS
extern cvar_t gl_blend2d; extern cvar_t gl_blend2d;
shader_t *shader_console;
#endif #endif
extern cvar_t con_ocranaleds; extern cvar_t con_ocranaleds;
@ -1502,6 +1503,62 @@ void GLDraw_ShaderPic (int x, int y, int width, int height, shader_t *pic, float
R_PushMesh(&draw_mesh, mb.shader->features | MF_COLORS | MF_NONBATCHED); R_PushMesh(&draw_mesh, mb.shader->features | MF_COLORS | MF_NONBATCHED);
R_RenderMeshBuffer ( &mb, false ); R_RenderMeshBuffer ( &mb, false );
draw_mesh.colors_array = NULL; draw_mesh.colors_array = NULL;
qglEnable(GL_BLEND);
}
void GLDraw_ShaderImage (int x, int y, int w, int h, float s1, float t1, float s2, float t2, shader_t *pic)
{
meshbuffer_t mb;
if (!pic)
return;
R_IBrokeTheArrays();
mb.entity = &r_worldentity;
mb.shader = pic;
mb.fog = NULL;
mb.mesh = &draw_mesh;
mb.infokey = -1;
mb.dlightbits = 0;
draw_mesh_xyz[0][0] = x;
draw_mesh_xyz[0][1] = y;
draw_mesh_st[0][0] = s1;
draw_mesh_st[0][1] = t1;
draw_mesh_xyz[1][0] = x+w;
draw_mesh_xyz[1][1] = y;
draw_mesh_st[1][0] = s2;
draw_mesh_st[1][1] = t1;
draw_mesh_xyz[2][0] = x+w;
draw_mesh_xyz[2][1] = y+h;
draw_mesh_st[2][0] = s2;
draw_mesh_st[2][1] = t2;
draw_mesh_xyz[3][0] = x;
draw_mesh_xyz[3][1] = y+h;
draw_mesh_st[3][0] = s1;
draw_mesh_st[3][1] = t2;
/* draw_mesh_colors[0][0] = r*255;
draw_mesh_colors[0][1] = g*255;
draw_mesh_colors[0][2] = b*255;
draw_mesh_colors[0][3] = a*255;
((int*)draw_mesh_colors)[1] = ((int*)draw_mesh_colors)[0];
((int*)draw_mesh_colors)[2] = ((int*)draw_mesh_colors)[0];
((int*)draw_mesh_colors)[3] = ((int*)draw_mesh_colors)[0];
*/
draw_mesh.colors_array = draw_mesh_colors;
R_PushMesh(&draw_mesh, mb.shader->features | MF_COLORS | MF_NONBATCHED);
R_RenderMeshBuffer ( &mb, false );
draw_mesh.colors_array = NULL;
qglEnable(GL_BLEND);
} }
#endif #endif
@ -1697,6 +1754,17 @@ void GLDraw_ConsoleBackground (int lines)
conback->height>>=1; conback->height>>=1;
conback->width>>=1; conback->width>>=1;
} }
#ifdef Q3SHADERS
{
if (shader_console)
{
currententity = &r_worldentity;
GLDraw_ShaderPic(0, lines - conback->height, vid.width, vid.height, shader_console, 1, 1, 1, (1.2*lines)/y);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
return;
}
}
#endif
if (lines > y) if (lines > y)
{ {
qglColor3f (1,1,1); qglColor3f (1,1,1);
@ -1829,6 +1897,14 @@ void GLDraw_FadeScreen (void)
void GLDraw_ImageColours(float r, float g, float b, float a) void GLDraw_ImageColours(float r, float g, float b, float a)
{ {
draw_mesh_colors[0][0] = r*255;
draw_mesh_colors[0][1] = g*255;
draw_mesh_colors[0][2] = b*255;
draw_mesh_colors[0][3] = a*255;
((int*)draw_mesh_colors)[1] = ((int*)draw_mesh_colors)[0];
((int*)draw_mesh_colors)[2] = ((int*)draw_mesh_colors)[0];
((int*)draw_mesh_colors)[3] = ((int*)draw_mesh_colors)[0];
qglColor4f(r, g, b, a); qglColor4f(r, g, b, a);
} }
@ -1926,6 +2002,8 @@ Setup as if the screen was 320*200
*/ */
void GL_Set2D (void) void GL_Set2D (void)
{ {
GL_SetShaderState2D(true);
qglViewport (glx, gly, glwidth, glheight); qglViewport (glx, gly, glwidth, glheight);
qglMatrixMode(GL_PROJECTION); qglMatrixMode(GL_PROJECTION);
@ -1971,8 +2049,17 @@ void GL_Set2D (void)
{ {
int newtex = 0; int newtex = 0;
gl_conback.modified = 0; gl_conback.modified = 0;
if (!*gl_conback.string || !(newtex=Mod_LoadHiResTexture(gl_conback.string, "conbacks", false, true, true))) #ifdef Q3SHADERS
if (*gl_conback.string && (shader_console = R_RegisterCustom(gl_conback.string, NULL)))
{
conback = default_conback; conback = default_conback;
}
else
#endif
if (!*gl_conback.string || !(newtex=Mod_LoadHiResTexture(gl_conback.string, "conbacks", false, true, true)))
{
conback = default_conback;
}
else else
{ {
conback = custom_conback; conback = custom_conback;
@ -2004,6 +2091,8 @@ void GL_Set2D (void)
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
} }
} }
r_refdef.time = realtime;
} }
@ -2394,8 +2483,8 @@ void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out,
{ {
inrow = in + inwidth*(i*inheight/outheight); inrow = in + inwidth*(i*inheight/outheight);
frac = outwidth*fracstep; frac = outwidth*fracstep;
j=outwidth-4; j=outwidth-1;
while (j&3) while ((j+1)&3)
{ {
out[j] = inrow[frac>>16]; out[j] = inrow[frac>>16];
frac -= fracstep; frac -= fracstep;

View file

@ -81,15 +81,10 @@ void GLMod_LoadDoomSprite (model_t *mod);
#define MAX_MOD_KNOWN 2048 #define MAX_MOD_KNOWN 2048
#ifndef SWQUAKE #ifndef SWQUAKE
qbyte mod_novis[MAX_MAP_LEAFS/8];
model_t mod_known[MAX_MOD_KNOWN]; model_t mod_known[MAX_MOD_KNOWN];
int mod_numknown; int mod_numknown;
#else #else
extern qbyte mod_novis[MAX_MAP_LEAFS/8];
extern model_t mod_known[MAX_MOD_KNOWN]; extern model_t mod_known[MAX_MOD_KNOWN];
extern int mod_numknown; extern int mod_numknown;
#endif #endif
@ -206,7 +201,7 @@ Mod_Init
void GLMod_Init (void) void GLMod_Init (void)
{ {
mod_numknown = 0; mod_numknown = 0;
memset (mod_novis, 0xff, sizeof(mod_novis)); Q1BSP_Init();
Cmd_AddRemCommand("mod_texturelist", GLMod_TextureList_f); Cmd_AddRemCommand("mod_texturelist", GLMod_TextureList_f);
Cmd_AddRemCommand("mod_usetexture", GLMod_BlockTextureColour_f); Cmd_AddRemCommand("mod_usetexture", GLMod_BlockTextureColour_f);
@ -215,7 +210,6 @@ void GLMod_Init (void)
void GLMod_Shutdown (void) void GLMod_Shutdown (void)
{ {
mod_numknown = 0; mod_numknown = 0;
memset (mod_novis, 0xff, sizeof(mod_novis));
Cmd_RemoveCommand("mod_texturelist"); Cmd_RemoveCommand("mod_texturelist");
Cmd_RemoveCommand("mod_usetexture"); Cmd_RemoveCommand("mod_usetexture");
@ -252,10 +246,7 @@ void *GLMod_Extradata (model_t *mod)
Mod_PointInLeaf Mod_PointInLeaf
=============== ===============
*/ */
#ifdef Q2BSPS mleaf_t *GLMod_PointInLeaf (model_t *model, vec3_t p)
int CM_PointLeafnum (vec3_t p);
#endif
mleaf_t *GLMod_PointInLeaf (vec3_t p, model_t *model)
{ {
mnode_t *node; mnode_t *node;
float d; float d;
@ -270,7 +261,7 @@ mleaf_t *GLMod_PointInLeaf (vec3_t p, model_t *model)
#ifdef Q2BSPS #ifdef Q2BSPS
if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3) if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3)
{ {
return model->leafs + CM_PointLeafnum(p); return model->leafs + CM_PointLeafnum(model, p);
} }
#endif #endif
if (model->fromgame == fg_doom) if (model->fromgame == fg_doom)
@ -294,103 +285,6 @@ mleaf_t *GLMod_PointInLeaf (vec3_t p, model_t *model)
return NULL; // never reached return NULL; // never reached
} }
int GLMod_LeafForPoint (vec3_t p, model_t *model)
{
mnode_t *node;
float d;
mplane_t *plane;
if (!model)
{
Sys_Error ("Mod_PointInLeaf: bad model");
}
if (!model->nodes)
return 0;
node = model->nodes;
while (1)
{
if (node->contents < 0)
return (mleaf_t *)node - model->leafs;
plane = node->plane;
d = DotProduct (p,plane->normal) - plane->dist;
if (d > 0)
node = node->children[0];
else
node = node->children[1];
}
return 0; // never reached
}
/*
===================
Mod_DecompressVis
===================
*/
qbyte *GLMod_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed)
{
int c;
qbyte *out;
int row;
row = (model->numleafs+7)>>3;
out = decompressed;
#if 0
memcpy (out, in, row);
#else
if (!in)
{ // no vis info, so make all visible
while (row)
{
*out++ = 0xff;
row--;
}
return decompressed;
}
do
{
if (*in)
{
*out++ = *in++;
continue;
}
c = in[1];
in += 2;
while (c)
{
*out++ = 0;
c--;
}
} while (out - decompressed < row);
#endif
return decompressed;
}
qbyte *GLMod_LeafPVS (mleaf_t *leaf, model_t *model, qbyte *buffer)
{
static qbyte decompressed[MAX_MAP_LEAFS/8];
if (leaf == model->leafs)
return mod_novis;
if (!buffer)
buffer = decompressed;
return GLMod_DecompressVis (leaf->compressed_vis, model, buffer);
}
qbyte *GLMod_LeafnumPVS (int leafnum, model_t *model, qbyte *buffer)
{
return GLMod_LeafPVS(model->leafs + leafnum, model, buffer);
}
/* /*
=================== ===================
Mod_ClearAll Mod_ClearAll
@ -690,17 +584,22 @@ couldntload:
GLMod_LoadMD5MeshModel (mod, buf); GLMod_LoadMD5MeshModel (mod, buf);
break; break;
} }
else if (!strcmp(com_token, "EXTERNALANIM")) if (!strcmp(com_token, "EXTERNALANIM"))
{ {
GLMod_LoadCompositeAnim (mod, buf); GLMod_LoadCompositeAnim (mod, buf);
break; break;
} }
else
#endif #endif
#ifdef TERRAIN
if (!strcmp(com_token, "terrain"))
{ {
Con_Printf("Unrecognised model format %i\n", LittleLong(*(unsigned *)buf)); GL_LoadHeightmapModel(mod, buf);
goto couldntload; break;
} }
#endif
Con_Printf("Unrecognised model format %i\n", LittleLong(*(unsigned *)buf));
goto couldntload;
} }
P_DefaultTrail(mod); P_DefaultTrail(mod);
@ -740,14 +639,14 @@ qbyte *mod_base;
#endif #endif
char *advtexturedesc; char *advtexturedesc;
const char *mapsection; char *mapsection;
const char *defaultsection; char *defaultsection;
static const char *GLMod_TD_LeaveSection(const char *file) static char *GLMod_TD_LeaveSection(char *file)
{ //recursive routine to find the next } { //recursive routine to find the next }
while(file) while(file)
{ {
file = COM_ParseToken(file); file = COM_Parse(file);
if (*com_token == '{') if (*com_token == '{')
file = GLMod_TD_LeaveSection(file); file = GLMod_TD_LeaveSection(file);
else if (*com_token == '}') else if (*com_token == '}')
@ -756,7 +655,7 @@ static const char *GLMod_TD_LeaveSection(const char *file)
return NULL; return NULL;
} }
static const char *GLMod_TD_Section(const char *file, const char *sectionname) static char *GLMod_TD_Section(char *file, const char *sectionname)
{ //position within the open brace. { //position within the open brace.
while(file) while(file)
{ {
@ -766,10 +665,10 @@ static const char *GLMod_TD_Section(const char *file, const char *sectionname)
return NULL; return NULL;
file++; file++;
} }
file = COM_ParseToken(file); file = COM_Parse(file);
if (!stricmp(com_token, sectionname)) if (!stricmp(com_token, sectionname))
{ {
file = COM_ParseToken(file); file = COM_Parse(file);
if (*com_token != '{') if (*com_token != '{')
return NULL; return NULL;
return file; return file;
@ -799,7 +698,7 @@ void GLMod_InitTextureDescs(char *mapname)
defaultsection = GLMod_TD_Section(advtexturedesc, "default"); defaultsection = GLMod_TD_Section(advtexturedesc, "default");
} }
} }
void GLMod_LoadAdvancedTextureSection(const char *section, char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss void GLMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss
{ {
char stdname[MAX_QPATH] = ""; char stdname[MAX_QPATH] = "";
char flatname[MAX_QPATH] = ""; char flatname[MAX_QPATH] = "";
@ -812,7 +711,7 @@ void GLMod_LoadAdvancedTextureSection(const char *section, char *name, int *base
while(section) while(section)
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
if (*com_token == '}') if (*com_token == '}')
break; break;
@ -827,34 +726,34 @@ void GLMod_LoadAdvancedTextureSection(const char *section, char *name, int *base
if (!stricmp(com_token, "texture") || !stricmp(com_token, "base")) if (!stricmp(com_token, "texture") || !stricmp(com_token, "base"))
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
Q_strncpyz(stdname, com_token, sizeof(stdname)); Q_strncpyz(stdname, com_token, sizeof(stdname));
} }
else if (!stricmp(com_token, "flatmap") || !stricmp(com_token, "flat") else if (!stricmp(com_token, "flatmap") || !stricmp(com_token, "flat")
|| !stricmp(com_token, "diffusemap") || !stricmp(com_token, "diffuse")) || !stricmp(com_token, "diffusemap") || !stricmp(com_token, "diffuse"))
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
Q_strncpyz(flatname, com_token, sizeof(flatname)); Q_strncpyz(flatname, com_token, sizeof(flatname));
} }
else if (!stricmp(com_token, "bumpmap") || !stricmp(com_token, "bump")) else if (!stricmp(com_token, "bumpmap") || !stricmp(com_token, "bump"))
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
Q_strncpyz(bumpname, com_token, sizeof(bumpname)); Q_strncpyz(bumpname, com_token, sizeof(bumpname));
} }
else if (!stricmp(com_token, "normalmap") || !stricmp(com_token, "normal")) else if (!stricmp(com_token, "normalmap") || !stricmp(com_token, "normal"))
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
Q_strncpyz(normname, com_token, sizeof(normname)); Q_strncpyz(normname, com_token, sizeof(normname));
} }
else if (!stricmp(com_token, "glossmap") || !stricmp(com_token, "gloss")) else if (!stricmp(com_token, "glossmap") || !stricmp(com_token, "gloss"))
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
Q_strncpyz(glossname, com_token, sizeof(glossname)); Q_strncpyz(glossname, com_token, sizeof(glossname));
} }
else if (!stricmp(com_token, "luma") || !stricmp(com_token, "glow") else if (!stricmp(com_token, "luma") || !stricmp(com_token, "glow")
|| !stricmp(com_token, "ambient") || !stricmp(com_token, "ambientmap")) || !stricmp(com_token, "ambient") || !stricmp(com_token, "ambientmap"))
{ {
section = COM_ParseToken(section); section = COM_Parse(section);
Q_strncpyz(lumaname, com_token, sizeof(lumaname)); Q_strncpyz(lumaname, com_token, sizeof(lumaname));
} }
else else
@ -978,7 +877,9 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
mt->offsets[j] = LittleLong (mt->offsets[j]); mt->offsets[j] = LittleLong (mt->offsets[j]);
if ( (mt->width & 15) || (mt->height & 15) ) if ( (mt->width & 15) || (mt->height & 15) )
Sys_Error ("Texture %s is not 16 aligned", mt->name); Con_Printf ("Warning: Texture %s is not 16 aligned", mt->name);
if (mt->width < 1 || mt->height < 1)
Con_Printf ("Warning: Texture %s has no size", mt->name);
pixels = mt->width*mt->height/64*85; pixels = mt->width*mt->height/64*85;
tx = Hunk_AllocName (sizeof(texture_t)/* +pixels*/, loadname ); tx = Hunk_AllocName (sizeof(texture_t)/* +pixels*/, loadname );
loadmodel->textures[i] = tx; loadmodel->textures[i] = tx;
@ -2545,9 +2446,6 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms)
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node); void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void Q1BSP_FatPVS (vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct edict_s *ent);
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace); qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
void GLQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void GLQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
@ -2668,19 +2566,10 @@ void GLMod_LoadBrushModel (model_t *mod, void *buffer)
Mod_ParseInfoFromEntityLump(mod_base + header->lumps[LUMP_ENTITIES].fileofs); Mod_ParseInfoFromEntityLump(mod_base + header->lumps[LUMP_ENTITIES].fileofs);
} }
Q1BSP_SetModelFuncs(mod);
mod->funcs.LightPointValues = GLQ1BSP_LightPointValues; mod->funcs.LightPointValues = GLQ1BSP_LightPointValues;
mod->funcs.StainNode = Q1BSP_StainNode; mod->funcs.StainNode = Q1BSP_StainNode;
mod->funcs.MarkLights = Q1BSP_MarkLights; mod->funcs.MarkLights = Q1BSP_MarkLights;
mod->funcs.Trace = Q1BSP_Trace;
mod->funcs.LeafForPoint = GLMod_LeafForPoint;
mod->funcs.LeafPVS = GLMod_LeafnumPVS;
#ifndef CLIENTONLY
mod->funcs.FindTouchedLeafs_Q1 = Q1BSP_FindTouchedLeafs;
mod->funcs.EdictInFatPVS = Q1BSP_EdictInFatPVS;
mod->funcs.FatPVS = Q1BSP_FatPVS;
#endif
mod->numframes = 2; // regular and alternate animation mod->numframes = 2; // regular and alternate animation

View file

@ -30,22 +30,25 @@ struct edict_s;
typedef struct { typedef struct {
// qboolean (*RecursiveHullCheck) (struct hull_s *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace); // qboolean (*RecursiveHullCheck) (struct hull_s *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
int (*HullPointContents) (struct hull_s *hull, vec3_t p); //return FTE contents // int (*HullPointContents) (struct hull_s *hull, vec3_t p); //return FTE contents
int dummy;
} hullfuncs_t; } hullfuncs_t;
typedef struct { typedef struct {
qboolean (*Trace) (struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace); qboolean (*Trace) (struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace);
qboolean (*PointContents) (struct model_s *model, vec3_t p);
qboolean (*BoxContents) (struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs);
void (*FatPVS) (vec3_t org, qboolean add); void (*FatPVS) (struct model_s *model, vec3_t org, qboolean add);
qboolean (*EdictInFatPVS) (struct edict_s *edict); qboolean (*EdictInFatPVS) (struct model_s *model, struct edict_s *edict);
void (*FindTouchedLeafs_Q1) (struct edict_s *ent); //edict system as opposed to q2 game dll system. void (*FindTouchedLeafs_Q1) (struct model_s *model, struct edict_s *ent); //edict system as opposed to q2 game dll system.
void (*LightPointValues) (vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void (*LightPointValues) (vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void (*StainNode) (struct mnode_s *node, float *parms); void (*StainNode) (struct mnode_s *node, float *parms);
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node); void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
qbyte *(*LeafPVS) (int num, struct model_s *model, qbyte *buffer); qbyte *(*LeafPVS) (struct model_s *model, int num, qbyte *buffer);
int (*LeafForPoint) (vec3_t point, struct model_s *model); int (*LeafnumForPoint) (struct model_s *model, vec3_t point);
} bspfuncs_t; } bspfuncs_t;
typedef int index_t; typedef int index_t;
@ -102,7 +105,9 @@ m*_t structures are in-memory
#define EF_BLUE 64 #define EF_BLUE 64
#define EF_RED 128 #define EF_RED 128
#define H2EF_NODRAW 0x80 //this is going to get complicated... #define H2EF_NODRAW 128 //this is going to get complicated...
#define EF_NODEPTHTEST 8192 //shows through walls. :(
/* /*
============================================================================== ==============================================================================
@ -370,11 +375,14 @@ typedef struct hull_s
void Q1BSP_SetHullFuncs(hull_t *hull); void Q1BSP_SetHullFuncs(hull_t *hull);
void Q1BSP_SetModelFuncs(struct model_s *mod);
void Q1BSP_Init(void);
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace); qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace);
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace); qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
void Q1BSP_FatPVS (vec3_t org, qboolean add); void Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct edict_s *ent); qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct edict_s *ent); void Q1BSP_FindTouchedLeafs(struct model_s *mod, struct edict_s *ent);
/* /*
============================================================================== ==============================================================================
@ -660,7 +668,7 @@ typedef struct {
// Whole model // Whole model
// //
typedef enum {mod_brush, mod_sprite, mod_alias, mod_dummy, mod_halflife} modtype_t; typedef enum {mod_brush, mod_sprite, mod_alias, mod_dummy, mod_halflife, mod_heightmap} modtype_t;
typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps) typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps)
#define EF_ROCKET 1 // leave a trail #define EF_ROCKET 1 // leave a trail
@ -776,7 +784,7 @@ typedef struct model_s
q3lightgridinfo_t *lightgrid; q3lightgridinfo_t *lightgrid;
char *entities; char *entities;
struct terrain_s *terrain; void *terrain;
unsigned checksum; unsigned checksum;
unsigned checksum2; unsigned checksum2;
@ -827,26 +835,27 @@ qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
void CM_Init(void); void CM_Init(void);
qboolean CM_SetAreaPortalState (int portalnum, qboolean open); qboolean CM_SetAreaPortalState (struct model_s *mod, int portalnum, qboolean open);
qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits); qboolean CM_HeadnodeVisible (struct model_s *mod, int nodenum, qbyte *visbits);
qboolean VARGS CM_AreasConnected (int area1, int area2); qboolean VARGS CM_AreasConnected (struct model_s *mod, int area1, int area2);
int CM_NumClusters (void); int CM_NumClusters (struct model_s *mod);
int CM_ClusterSize (void); int CM_ClusterSize (struct model_s *mod);
int CM_LeafContents (int leafnum); int CM_LeafContents (struct model_s *mod, int leafnum);
int CM_LeafCluster (int leafnum); int CM_LeafCluster (struct model_s *mod, int leafnum);
int CM_LeafArea (int leafnum); int CM_LeafArea (struct model_s *mod, int leafnum);
int CM_WriteAreaBits (qbyte *buffer, int area); int CM_WriteAreaBits (struct model_s *mod, qbyte *buffer, int area);
int CM_PointLeafnum (vec3_t p); int CM_PointLeafnum (struct model_s *mod, vec3_t p);
qbyte *CM_ClusterPVS (int cluster, qbyte *buffer); qbyte *CM_ClusterPVS (struct model_s *mod, int cluster, qbyte *buffer);
qbyte *CM_ClusterPHS (int cluster); qbyte *CM_ClusterPHS (struct model_s *mod, int cluster);
int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode); int CM_BoxLeafnums (struct model_s *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
int CM_PointContents (vec3_t p, int headnode); int CM_PointContents (struct model_s *mod, vec3_t p);
struct trace_s CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask); int CM_TransformedPointContents (struct model_s *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles);
int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs); struct trace_s CM_BoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask);
struct trace_s CM_TransformedBoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask, vec3_t origin, vec3_t angles); int CM_HeadnodeForBox (struct model_s *mod, vec3_t mins, vec3_t maxs);
struct trace_s CM_TransformedBoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask, vec3_t origin, vec3_t angles);
struct model_s *CM_TempBoxModel(vec3_t mins, vec3_t maxs); struct model_s *CM_TempBoxModel(vec3_t mins, vec3_t maxs);
void Mod_ParseInfoFromEntityLump(const char *data); void Mod_ParseInfoFromEntityLump(char *data);
void VARGS CMQ2_SetAreaPortalState (int portalnum, qboolean open); void VARGS CMQ2_SetAreaPortalState (int portalnum, qboolean open);
#endif #endif

View file

@ -1905,6 +1905,8 @@ void PPL_BaseEntTextures(void)
if (!PPL_ShouldDraw()) if (!PPL_ShouldDraw())
continue; continue;
if (currententity->rtype)
continue;
if (currententity->flags & Q2RF_BEAM) if (currententity->flags & Q2RF_BEAM)
{ {
R_DrawBeam(currententity); R_DrawBeam(currententity);
@ -4364,13 +4366,13 @@ qboolean PPL_AddLight(dlight_t *dl)
else else
{ {
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.LeafnumForPoint(cl.worldmodel, r_refdef.vieworg);
else else
i = r_viewleaf - cl.worldmodel->leafs; i = r_viewleaf - cl.worldmodel->leafs;
leaf = cl.worldmodel->funcs.LeafForPoint(dl->origin, cl.worldmodel); leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(leaf, cl.worldmodel, lvisb); lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb);
vvis = cl.worldmodel->funcs.LeafPVS(i, cl.worldmodel, vvisb); vvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, i, vvisb);
// if (!(lvis[i>>3] & (1<<(i&7)))) //light might not be visible, but it's effects probably should be. // if (!(lvis[i>>3] & (1<<(i&7)))) //light might not be visible, but it's effects probably should be.
// return; // return;

View file

@ -24,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef RGLQUAKE #ifdef RGLQUAKE
#include "glquake.h" #include "glquake.h"
#ifdef Q3SHADERS
#include "shader.h"
#endif
void R_RenderBrushPoly (msurface_t *fa); void R_RenderBrushPoly (msurface_t *fa);
#define PROJECTION_DISTANCE 200 #define PROJECTION_DISTANCE 200
@ -34,8 +38,6 @@ extern int gl_canstencil;
PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB; PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB; PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
extern struct mleaf_s *GLMod_PointInLeaf (float *p, struct model_s *model);
#define Q2RF_WEAPONMODEL 4 // only draw through eyes #define Q2RF_WEAPONMODEL 4 // only draw through eyes
#define Q2RF_DEPTHHACK 16 #define Q2RF_DEPTHHACK 16
@ -123,6 +125,9 @@ cvar_t gl_finish = {"gl_finish","0"};
cvar_t gl_contrast = {"gl_contrast", "1"}; cvar_t gl_contrast = {"gl_contrast", "1"};
cvar_t gl_dither = {"gl_dither", "1"}; cvar_t gl_dither = {"gl_dither", "1"};
cvar_t gl_maxdist = {"gl_maxdist", "8192"}; cvar_t gl_maxdist = {"gl_maxdist", "8192"};
cvar_t gl_mindist = {"gl_mindist", "4", NULL, CVAR_CHEAT}; //by setting to 64 or something, you can use this as a wallhack
cvar_t gl_bloom = {"gl_bloom", "0"};
extern cvar_t gl_motionblur; extern cvar_t gl_motionblur;
extern cvar_t gl_motionblurscale; extern cvar_t gl_motionblurscale;
@ -151,10 +156,12 @@ int scenepp_ww_parm_texture1i;
int scenepp_ww_parm_texture2i; int scenepp_ww_parm_texture2i;
int scenepp_ww_parm_ampscalef; int scenepp_ww_parm_ampscalef;
int scenepp_bloom_program;
// KrimZon - init post processing - called in GL_CheckExtensions, when they're called // KrimZon - init post processing - called in GL_CheckExtensions, when they're called
// I put it here so that only this file need be changed when messing with the post // I put it here so that only this file need be changed when messing with the post
// processing shaders // processing shaders
void GL_InitSceneProcessingShaders (void) void GL_InitSceneProcessingShaders_WaterWarp (void)
{ {
char *genericvert = "\ char *genericvert = "\
varying vec2 v_texCoord0;\ varying vec2 v_texCoord0;\
@ -219,6 +226,40 @@ void GL_InitSceneProcessingShaders (void)
if (qglGetError()) if (qglGetError())
Con_Printf("GL Error initing shader object\n"); Con_Printf("GL Error initing shader object\n");
} }
void GL_InitSceneProcessingShaders_Bloom(void)
{
int texnum;
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 *frag = COM_LoadTempFile("bloom.glsl");
if (!frag)
return;
scenepp_bloom_program = GLSlang_CreateProgram(NULL, genericvert, frag);
if (!scenepp_bloom_program)
return;
texnum = GLSlang_GetUniformLocation(scenepp_bloom_program, "theTexture0");
GLSlang_SetUniform1i(texnum, 0);
}
void GL_InitSceneProcessingShaders (void)
{
GL_InitSceneProcessingShaders_WaterWarp();
GL_InitSceneProcessingShaders_Bloom();
}
#define PP_WARP_TEX_SIZE 64 #define PP_WARP_TEX_SIZE 64
#define PP_AMP_TEX_SIZE 64 #define PP_AMP_TEX_SIZE 64
@ -468,40 +509,98 @@ void R_DrawSpriteModel (entity_t *e)
vec3_t forward, right, up; vec3_t forward, right, up;
msprite_t *psprite; msprite_t *psprite;
#ifdef Q3SHADERS
if (e->forcedshader)
{
meshbuffer_t mb;
mesh_t mesh;
vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}};
vec3_t vertcoords[4];
int indexes[6] = {0, 1, 2, 0, 2, 3};
byte_vec4_t colours[4];
float x, y;
mesh.colors_array = colours;
mesh.indexes = indexes;
mesh.lmst_array = NULL;
mesh.st_array = texcoords;
mesh.normals_array = NULL;
mesh.numvertexes = 4;
mesh.numindexes = 6;
mesh.radius = e->scale;
mesh.xyz_array = vertcoords;
mesh.normals_array = NULL;
#define VectorSet(a,b,c,v) {v[0]=a;v[1]=b;v[2]=c;}
x = cos(e->rotation+225*M_PI/180)*e->scale;
y = sin(e->rotation+225*M_PI/180)*e->scale;
VectorSet (e->origin[0] - y*vright[0] + x*vup[0], e->origin[1] - y*vright[1] + x*vup[1], e->origin[2] - y*vright[2] + x*vup[2], vertcoords[3]);
VectorSet (e->origin[0] - x*vright[0] - y*vup[0], e->origin[1] - x*vright[1] - y*vup[1], e->origin[2] - x*vright[2] - y*vup[2], vertcoords[2]);
VectorSet (e->origin[0] + y*vright[0] - x*vup[0], e->origin[1] + y*vright[1] - x*vup[1], e->origin[2] + y*vright[2] - x*vup[2], vertcoords[1]);
VectorSet (e->origin[0] + x*vright[0] + y*vup[0], e->origin[1] + x*vright[1] + y*vup[1], e->origin[2] + x*vright[2] + y*vup[2], vertcoords[0]);
*(int*)colours[0] = *(int*)colours[1] = *(int*)colours[2] = *(int*)colours[3] =
*(int*)e->shaderRGBA;
R_IBrokeTheArrays();
mb.entity = e;
mb.shader = e->forcedshader;
mb.fog = NULL;//fog;
mb.mesh = &mesh;
mb.infokey = -1;
mb.dlightbits = 0;
R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED);
R_RenderMeshBuffer ( &mb, false );
return;
}
#endif
if (!e->model)
return;
if (e->flags & RF_NODEPTHTEST)
qglDisable(GL_DEPTH_TEST);
// don't even bother culling, because it's just a single // don't even bother culling, because it's just a single
// polygon without a surface cache // polygon without a surface cache
frame = R_GetSpriteFrame (e); frame = R_GetSpriteFrame (e);
psprite = currententity->model->cache.data; psprite = e->model->cache.data;
// frame = 0x05b94140; // frame = 0x05b94140;
if (psprite->type == SPR_ORIENTED) switch(psprite->type)
{ // bullet marks on walls
AngleVectors (currententity->angles, forward, right, up);
}
else if (psprite->type == SPR_FACING_UPRIGHT)
{ {
case SPR_ORIENTED:
// bullet marks on walls
AngleVectors (e->angles, forward, right, up);
break;
case SPR_FACING_UPRIGHT:
up[0] = 0;up[1] = 0;up[2]=1; up[0] = 0;up[1] = 0;up[2]=1;
right[0] = e->origin[1] - r_origin[1]; right[0] = e->origin[1] - r_origin[1];
right[1] = -(e->origin[0] - r_origin[0]); right[1] = -(e->origin[0] - r_origin[0]);
right[2] = 0; right[2] = 0;
VectorNormalize (right); VectorNormalize (right);
} break;
else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) case SPR_VP_PARALLEL_UPRIGHT:
{
up[0] = 0;up[1] = 0;up[2]=1; up[0] = 0;up[1] = 0;up[2]=1;
VectorCopy (vright, right); VectorCopy (vright, right);
} break;
else
{ // normal sprite default:
case SPR_VP_PARALLEL:
//normal sprite
VectorCopy(vup, up); VectorCopy(vup, up);
VectorCopy(vright, right); VectorCopy(vright, right);
break;
} }
up[0]*=currententity->scale; up[0]*=e->scale;
up[1]*=currententity->scale; up[1]*=e->scale;
up[2]*=currententity->scale; up[2]*=e->scale;
right[0]*=currententity->scale; right[0]*=e->scale;
right[1]*=currententity->scale; right[1]*=e->scale;
right[2]*=currententity->scale; right[2]*=e->scale;
qglColor4f (1,1,1, e->alpha); qglColor4f (1,1,1, e->alpha);
@ -566,6 +665,7 @@ void R_DrawSpriteModel (entity_t *e)
qglDisable(GL_BLEND); qglDisable(GL_BLEND);
qglDisable (GL_ALPHA_TEST); qglDisable (GL_ALPHA_TEST);
qglEnable(GL_DEPTH_TEST);
if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us! if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us!
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -762,6 +862,25 @@ void GLR_DrawEntitiesOnList (void)
{ {
currententity = &cl_visedicts[i]; currententity = &cl_visedicts[i];
if (!PPL_ShouldDraw())
continue;
/*
if (r_inmirror)
{
if (currententity->flags & Q2RF_WEAPONMODEL)
continue;
}
else
{
if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1)))
continue;
// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum])
// continue;
if (!Cam_DrawPlayer(0, currententity->keynum-1))
continue;
}*/
/*
if (r_inmirror) if (r_inmirror)
{ {
if (currententity->flags & Q2RF_WEAPONMODEL) if (currententity->flags & Q2RF_WEAPONMODEL)
@ -776,7 +895,16 @@ void GLR_DrawEntitiesOnList (void)
if (!Cam_DrawPlayer(0, currententity->keynum-1)) if (!Cam_DrawPlayer(0, currententity->keynum-1))
continue; continue;
} }
*/
switch (currententity->rtype)
{
case RT_SPRITE:
RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
continue;
case RT_RAIL_CORE:
R_DrawBeam(currententity);
continue;
}
if (currententity->flags & Q2RF_BEAM) if (currententity->flags & Q2RF_BEAM)
{ {
R_DrawBeam(currententity); R_DrawBeam(currententity);
@ -801,7 +929,7 @@ void GLR_DrawEntitiesOnList (void)
switch (currententity->model->type) switch (currententity->model->type)
{ {
case mod_alias: case mod_alias:
if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->fromgame == fg_doom) if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
R_DrawGAliasModel (currententity); R_DrawGAliasModel (currententity);
break; break;
@ -812,12 +940,19 @@ void GLR_DrawEntitiesOnList (void)
#endif #endif
case mod_brush: case mod_brush:
if (cl.worldmodel->fromgame == fg_doom) if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
PPL_BaseBModelTextures (currententity); PPL_BaseBModelTextures (currententity);
break; break;
case mod_sprite: case mod_sprite:
RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin); RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
break;
#ifdef TERRAIN
case mod_heightmap:
GL_DrawHeightmapModel(currententity);
break;
#endif
default: default:
break; break;
@ -1175,7 +1310,7 @@ void GLR_SetupFrame (void)
r_oldviewcluster = r_viewcluster; r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2; r_oldviewcluster2 = r_viewcluster2;
leaf = GLMod_PointInLeaf (r_origin, cl.worldmodel); leaf = GLMod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcluster = r_viewcluster2 = leaf->cluster; r_viewcluster = r_viewcluster2 = leaf->cluster;
// check above and below so crossing solid water doesn't draw wrong // check above and below so crossing solid water doesn't draw wrong
@ -1185,7 +1320,7 @@ void GLR_SetupFrame (void)
VectorCopy (r_origin, temp); VectorCopy (r_origin, temp);
temp[2] -= 16; temp[2] -= 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel); leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) && if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) ) (leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster; r_viewcluster2 = leaf->cluster;
@ -1196,7 +1331,7 @@ void GLR_SetupFrame (void)
VectorCopy (r_origin, temp); VectorCopy (r_origin, temp);
temp[2] += 16; temp[2] += 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel); leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) && if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) ) (leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster; r_viewcluster2 = leaf->cluster;
@ -1210,7 +1345,7 @@ void GLR_SetupFrame (void)
r_oldviewleaf = r_viewleaf; r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2; r_oldviewleaf2 = r_viewleaf2;
r_viewleaf = GLMod_PointInLeaf (r_origin, cl.worldmodel); r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin);
if (!r_viewleaf) if (!r_viewleaf)
{ {
@ -1219,7 +1354,7 @@ void GLR_SetupFrame (void)
{ //look down a bit { //look down a bit
VectorCopy (r_origin, temp); VectorCopy (r_origin, temp);
temp[2] -= 16; temp[2] -= 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel); leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA) if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA)
r_viewleaf2 = leaf; r_viewleaf2 = leaf;
else else
@ -1230,7 +1365,7 @@ void GLR_SetupFrame (void)
VectorCopy (r_origin, temp); VectorCopy (r_origin, temp);
temp[2] += 16; temp[2] += 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel); leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents == Q1CONTENTS_EMPTY) if (leaf->contents == Q1CONTENTS_EMPTY)
r_viewleaf2 = leaf; r_viewleaf2 = leaf;
else else
@ -1393,11 +1528,11 @@ void R_SetupGL (void)
// yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect;
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI;
// MYgluPerspective (yfov, screenaspect, 4, 4096); // MYgluPerspective (yfov, screenaspect, 4, 4096);
MYgluPerspective (r_refdef.fov_y, screenaspect, 4, gl_maxdist.value); MYgluPerspective (r_refdef.fov_y, screenaspect, gl_mindist.value, gl_maxdist.value);
} }
else else
{ {
GL_InfinatePerspective(r_refdef.fov_y, screenaspect, 4); GL_InfinatePerspective(r_refdef.fov_y, screenaspect, gl_mindist.value);
} }
} }
else else
@ -2088,6 +2223,8 @@ void GLR_RenderView (void)
*/ */
r_alpha_surfaces = NULL; r_alpha_surfaces = NULL;
GL_SetShaderState2D(false);
// render normal view // render normal view
R_RenderScene (); R_RenderScene ();
GLR_DrawViewModel (); GLR_DrawViewModel ();
@ -2119,7 +2256,7 @@ void GLR_RenderView (void)
// SCENE POST PROCESSING // SCENE POST PROCESSING
// we check if we need to use any shaders - currently it's just waterwarp // we check if we need to use any shaders - currently it's just waterwarp
if (scenepp_ww_program) if (scenepp_ww_program)
if ((r_waterwarp.value && r_viewleaf && r_viewleaf->contents <= Q1CONTENTS_WATER)) if (((r_waterwarp.value && r_viewleaf && r_viewleaf->contents <= Q1CONTENTS_WATER) || r_waterwarp.value<0))
{ {
float vwidth = 1, vheight = 1; float vwidth = 1, vheight = 1;
float vs, vt; float vs, vt;
@ -2173,7 +2310,14 @@ void GLR_RenderView (void)
// WARNING - waterwarp can change the amplitude, but if it's too big it'll exceed // 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. // the size determined by the edge texture, after which black bits will be shown.
// Suggest clamping to a suitable range. // Suggest clamping to a suitable range.
GLSlang_SetUniform1f(scenepp_ww_parm_ampscalef, (0.005 / 0.625) * vs*r_waterwarp.value); 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()) if (qglGetError())
Con_Printf("GL Error after GLSlang_UseProgram\n"); Con_Printf("GL Error after GLSlang_UseProgram\n");
@ -2303,6 +2447,87 @@ void GLR_RenderView (void)
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} }
/*
if (scenepp_bloom_program && gl_bloom.value)
{
float cs, ct;
int vwidth = 1, vheight = 1;
if (gl_config.arb_texture_non_power_of_two)
{ //we can use any size, supposedly
vwidth = glwidth;
vheight = glheight;
}
else
{ //limit the texture size to square and use padding.
while (vwidth < glwidth)
vwidth *= 2;
while (vheight < glheight)
vheight *= 2;
}
GL_Bind(scenepp_texture);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
cs = (float)glwidth / vwidth;
ct = (float)glheight / vheight;
// go 2d
qglDisable (GL_DEPTH_TEST);
qglDisable (GL_CULL_FACE);
qglDisable (GL_ALPHA_TEST);
qglDisable (GL_BLEND);
qglMatrixMode(GL_PROJECTION);
qglPushMatrix();
qglLoadIdentity ();
qglOrtho (0, glwidth, 0, glheight, -99999, 99999);
qglMatrixMode(GL_MODELVIEW);
qglPushMatrix();
qglLoadIdentity ();
//grab the scene
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
GLSlang_UseProgram(scenepp_bloom_program1);
//regurgitate the scene, but darker
qglBegin(GL_QUADS);
qglTexCoord2f(0, 0);
qglVertex2f(0, 0);
qglTexCoord2f(cs, 0);
qglVertex2f(glwidth, 0);
qglTexCoord2f(cs, ct);
qglVertex2f(glwidth, glheight);
qglTexCoord2f(0, ct);
qglVertex2f(0, glheight);
qglEnd();
GL_Bind(scenepp_texture2);
//grab the dark scene
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0);
GLSlang_UseProgram(scenepp_bloom_program2);
//smear it all over the place, on a +/-8 pixel basis.
//blend with the origional scene in the fragment program too.
GL_MBind(1, scenepp_texture);
qglBegin(GL_QUADS);
qglTexCoord2f(0, 0);
qglVertex2f(0, 0);
qglTexCoord2f(cs, 0);
qglVertex2f(glwidth, 0);
qglTexCoord2f(cs, ct);
qglVertex2f(glwidth, glheight);
qglTexCoord2f(0, ct);
qglVertex2f(0, glheight);
qglEnd();
GL_MBind(0, scenepp_texture);
GLSlang_UseProgram(0);
qglMatrixMode(GL_PROJECTION);
qglPopMatrix();
qglMatrixMode(GL_MODELVIEW);
qglPopMatrix();
}
*/
} }
#endif #endif

View file

@ -3117,10 +3117,9 @@ void R_DrawWorld (void)
VectorCopy (r_refdef.vieworg, modelorg); VectorCopy (r_refdef.vieworg, modelorg);
currententity = &ent; currententity = &ent;
#ifdef TERRAIN
#ifdef TERRAINMAPS if (currentmodel->type == mod_heightmap)
if (ent.model->type == mod_terrain) GL_DrawHeightmapModel(currententity);
DrawTerrain();
else else
#endif #endif
{ {
@ -3136,14 +3135,14 @@ void R_DrawWorld (void)
{ {
int leafnum; int leafnum;
int clientarea; int clientarea;
int CM_WriteAreaBits (qbyte *buffer, int area);
if (cls.protocol == CP_QUAKE2) //we can get server sent info if (cls.protocol == CP_QUAKE2) //we can get server sent info
memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); memcpy(areabits, cl.q2frame.areabits, sizeof(areabits));
else else
{ //generate the info each frame. { //generate the info each frame.
leafnum = CM_PointLeafnum (r_refdef.vieworg); leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg);
clientarea = CM_LeafArea (leafnum); clientarea = CM_LeafArea (cl.worldmodel, leafnum);
CM_WriteAreaBits(areabits, clientarea); CM_WriteAreaBits(cl.worldmodel, areabits, clientarea);
} }
#ifdef Q3BSPS #ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3) if (ent.model->fromgame == fg_quake3)
@ -3219,7 +3218,7 @@ void GLR_MarkLeaves (void)
return; return;
} }
vis = CM_ClusterPVS (r_viewcluster, NULL);//, cl.worldmodel); vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++) for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{ {
cluster = leaf->cluster; cluster = leaf->cluster;
@ -3262,12 +3261,12 @@ void GLR_MarkLeaves (void)
return; return;
} }
vis = CM_ClusterPVS (r_viewcluster, NULL);//, cl.worldmodel); vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
// may have to combine two clusters because of solid water boundaries // may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster) if (r_viewcluster2 != r_viewcluster)
{ {
memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8); memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8);
vis = CM_ClusterPVS (r_viewcluster2, NULL);//, cl.worldmodel); vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL);//, cl.worldmodel);
c = (cl.worldmodel->numleafs+31)/32; c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++) for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i]; ((int *)fatvis)[i] |= ((int *)vis)[i];
@ -3314,8 +3313,8 @@ void GLR_MarkLeaves (void)
else if (r_viewleaf2) else if (r_viewleaf2)
{ {
int c; int c;
GLMod_LeafPVS (r_viewleaf2, cl.worldmodel, fatvis); Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis);
vis = GLMod_LeafPVS (r_viewleaf, cl.worldmodel, NULL); vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
c = (cl.worldmodel->numleafs+31)/32; c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++) for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i]; ((int *)fatvis)[i] |= ((int *)vis)[i];
@ -3323,7 +3322,7 @@ void GLR_MarkLeaves (void)
vis = fatvis; vis = fatvis;
} }
else else
vis = GLMod_LeafPVS (r_viewleaf, cl.worldmodel, NULL); vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
for (i=0 ; i<cl.worldmodel->numleafs ; i++) for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{ {

View file

@ -73,7 +73,7 @@ qbyte FloatToByte( float x )
cvar_t r_detailtextures; cvar_t r_detailtextures;
#define MAX_SHADERS 1024 #define MAX_SHADERS 2048 //fixme: this takes a lot of bss in the r_shaders list
#define MAX_TOKEN_CHARS 1024 #define MAX_TOKEN_CHARS 1024
@ -974,6 +974,8 @@ static void Shader_MakeCache ( char *path )
if ( !token[0] || ptr - buf >= size ) if ( !token[0] || ptr - buf >= size )
break; break;
COM_CleanUpPath(token);
t = NULL; t = NULL;
Shader_GetPathAndOffset ( token, &t, &i ); Shader_GetPathAndOffset ( token, &t, &i );
if ( t ) { if ( t ) {
@ -1921,6 +1923,8 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*))
COM_StripExtension ( name, shortname ); COM_StripExtension ( name, shortname );
COM_CleanUpPath(shortname);
// test if already loaded // test if already loaded
for (i = 0; i < MAX_SHADERS; i++) for (i = 0; i < MAX_SHADERS; i++)
{ {

View file

@ -1083,7 +1083,7 @@ void GLAppActivate(BOOL fActive, BOOL minimize)
if (fActive) if (fActive)
{ {
if (modestate == MS_FULLDIB) if (modestate != MS_WINDOWED)
{ {
IN_ActivateMouse (); IN_ActivateMouse ();
IN_HideMouse (); IN_HideMouse ();
@ -1107,7 +1107,7 @@ void GLAppActivate(BOOL fActive, BOOL minimize)
if (!fActive) if (!fActive)
{ {
if (modestate == MS_FULLDIB) if (modestate != MS_WINDOWED)
{ {
IN_DeactivateMouse (); IN_DeactivateMouse ();
IN_ShowMouse (); IN_ShowMouse ();

View file

@ -198,8 +198,13 @@ void R_DrawSkyChain (msurface_t *s)
{ {
int i; int i;
if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome)
{
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{
skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i];
}
solidskytexture = 1;
}
} }
#endif #endif

View file

@ -4136,8 +4136,6 @@ rendererinfo_t d3drendererinfo = {
GLMod_Extradata, GLMod_Extradata,
GLMod_TouchModel, GLMod_TouchModel,
GLMod_PointInLeaf,
GLMod_LeafPVS,
GLMod_NowLoadExternal, GLMod_NowLoadExternal,
GLMod_Think, GLMod_Think,

View file

@ -156,14 +156,13 @@ void LightLoadEntities(char *entstring)
{ {
int cont; int cont;
vec3_t v; vec3_t v;
hull_t *hull = &lightmodel->hulls[0];
v[0] = mapent->origin[0]; v[0] = mapent->origin[0];
v[1] = mapent->origin[1]; v[1] = mapent->origin[1];
cont=0; cont=0;
for (i = 0; i < 256; i+=16) for (i = 0; i < 256; i+=16)
{ {
v[2] = mapent->origin[2]-i; v[2] = mapent->origin[2]-i;
cont = hull->funcs.HullPointContents (hull, v); cont = lightmodel->funcs.PointContents (lightmodel, v);
if (cont & (FTECONTENTS_LAVA | FTECONTENTS_SLIME | FTECONTENTS_SOLID)) if (cont & (FTECONTENTS_LAVA | FTECONTENTS_SLIME | FTECONTENTS_SOLID))
break; break;
} }

View file

@ -322,7 +322,7 @@ static qboolean HTTP_CL_Run(http_con_t *con)
{ {
if (con->file) //we've got a chunk in the buffer if (con->file) //we've got a chunk in the buffer
{ //write it { //write it
IWebFWrite(con->buffer, con->chunked, 1, con->file); IWebFWrite(con->buffer, con->bufferused, 1, con->file);
con->bufferused = 0; con->bufferused = 0;
} }
} }

View file

@ -376,7 +376,6 @@ void IWebShutdown(void)
{ {
} }
extern int file_from_pak;
IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb"); IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb");
{ {
IWEBFILE *gf; IWEBFILE *gf;
@ -403,7 +402,7 @@ IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb");
return ret; return ret;
} }
if (file_from_pak==2) if (com_file_copyprotected)
{ {
char *buffer; char *buffer;
IWEBFILE *ret; IWEBFILE *ret;
@ -596,42 +595,42 @@ iwboolean IWebAllowUpLoad(char *fname, char *uname) //called for partial write a
iwboolean FTP_StringToAdr (const char *s, qbyte ip[4], qbyte port[2]) iwboolean FTP_StringToAdr (const char *s, qbyte ip[4], qbyte port[2])
{ {
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
ip[0] = atoi(com_token); ip[0] = atoi(com_token);
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
if (*com_token != ',') if (*com_token != ',')
return false; return false;
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
ip[1] = atoi(com_token); ip[1] = atoi(com_token);
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
if (*com_token != ',') if (*com_token != ',')
return false; return false;
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
ip[2] = atoi(com_token); ip[2] = atoi(com_token);
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
if (*com_token != ',') if (*com_token != ',')
return false; return false;
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
ip[3] = atoi(com_token); ip[3] = atoi(com_token);
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
if (*com_token != ',') if (*com_token != ',')
return false; return false;
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
port[0] = atoi(com_token); port[0] = atoi(com_token);
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
if (*com_token != ',') if (*com_token != ',')
return false; return false;
s = COM_ParseToken(s); s = COM_ParseToken(s, NULL);
port[1] = atoi(com_token); port[1] = atoi(com_token);

View file

@ -694,6 +694,10 @@ pbool QCC_PR_Precompiler(void)
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Copyright message is too long\n"); QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Copyright message is too long\n");
strncpy(QCC_copyright, msg, sizeof(QCC_copyright)-1); strncpy(QCC_copyright, msg, sizeof(QCC_copyright)-1);
} }
else if (!strncmp(directive, "forcecrc", 8))
{
ForcedCRC = atoi(msg);
}
else if (!QC_strcasecmp(qcc_token, "TARGET")) else if (!QC_strcasecmp(qcc_token, "TARGET"))
{ {
if (qcc_targetformat == QCF_HEXEN2 && numstatements) if (qcc_targetformat == QCF_HEXEN2 && numstatements)

View file

@ -2872,8 +2872,8 @@ int PF_newcheckclient (progfuncs_t *prinst, int check)
// get the PVS for the entity // get the PVS for the entity
VectorAdd (ent->v->origin, ent->v->view_ofs, org); VectorAdd (ent->v->origin, ent->v->view_ofs, org);
leaf = sv.worldmodel->funcs.LeafForPoint(org, sv.worldmodel); leaf = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org);
checkpvs = sv.worldmodel->funcs.LeafPVS (leaf, sv.worldmodel, checkpvsbuffer); checkpvs = sv.worldmodel->funcs.LeafPVS (sv.worldmodel, leaf, checkpvsbuffer);
return i; return i;
} }
@ -2919,7 +2919,7 @@ void PF_checkclient (progfuncs_t *prinst, struct globalvars_s *pr_globals)
// if current entity can't possibly see the check entity, return 0 // if current entity can't possibly see the check entity, return 0
self = PROG_TO_EDICT(prinst, pr_global_struct->self); self = PROG_TO_EDICT(prinst, pr_global_struct->self);
VectorAdd (self->v->origin, self->v->view_ofs, view); VectorAdd (self->v->origin, self->v->view_ofs, view);
l = sv.worldmodel->funcs.LeafForPoint(view, sv.worldmodel)-1; l = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, view)-1;
if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) ) if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) )
{ {
c_notvis++; c_notvis++;
@ -2959,6 +2959,7 @@ void PF_stuffcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals)
cl = &svs.clients[entnum-1]; cl = &svs.clients[entnum-1];
if (strcmp(str, "disconnect\n") == 0) if (strcmp(str, "disconnect\n") == 0)
{ {
// so long and thanks for all the fish // so long and thanks for all the fish
@ -6119,7 +6120,11 @@ lh_extension_t QSG_Extensions[] = {
{"DP_QUAKE3_MODEL"}, {"DP_QUAKE3_MODEL"},
{"DP_REGISTERCVAR", 1, NULL, {"registercvar"}}, {"DP_REGISTERCVAR", 1, NULL, {"registercvar"}},
{"DP_SPRITE32"}, //hmm... is it legal to advertise this one? {"DP_SPRITE32"}, //hmm... is it legal to advertise this one?
{"DP_SV_BOTCLIENT", 2, NULL, {"spawnclient", "clienttype"}},
{"DP_SV_CLIENTCOLORS"},
{"DP_SV_CLIENTNAME"},
{"DP_SV_DRAWONLYTOCLIENT"}, {"DP_SV_DRAWONLYTOCLIENT"},
{"DP_SV_DROPCLIENT"},
{"DP_SV_NODRAWTOCLIENT"}, //I prefer my older system. Guess I might as well remove that older system at some point. {"DP_SV_NODRAWTOCLIENT"}, //I prefer my older system. Guess I might as well remove that older system at some point.
{"DP_SV_PLAYERPHYSICS"}, {"DP_SV_PLAYERPHYSICS"},
{"DP_SV_SETCOLOR"}, {"DP_SV_SETCOLOR"},
@ -9533,6 +9538,8 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldfloat(style); fieldfloat(style);
fieldfloat(pflags); fieldfloat(pflags);
fieldfloat(clientcolors);
//UDC_EXTEFFECT... yuckie //UDC_EXTEFFECT... yuckie
PR_RegisterFieldVar(svprogfuncs, ev_float, "fieldcolor", (int)&((entvars_t*)0)->seefcolour, -1); PR_RegisterFieldVar(svprogfuncs, ev_float, "fieldcolor", (int)&((entvars_t*)0)->seefcolour, -1);
PR_RegisterFieldVar(svprogfuncs, ev_float, "fieldsizex", (int)&((entvars_t*)0)->seefsizex, -1); PR_RegisterFieldVar(svprogfuncs, ev_float, "fieldsizex", (int)&((entvars_t*)0)->seefsizex, -1);

View file

@ -198,6 +198,7 @@ typedef struct entvars_s
float light_lev; float light_lev;
float style; float style;
float pflags; float pflags;
float clientcolors;
//EXT_DIMENSION_VISIBLE //EXT_DIMENSION_VISIBLE
float dimension_see; float dimension_see;

View file

@ -105,6 +105,7 @@ extern progsnum_t svmainprogs;
extern progsnum_t clmainprogs; extern progsnum_t clmainprogs;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) #define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
#define Q2EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q2edict_t,area) #define Q2EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q2edict_t,area)
#define Q3EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q3serverEntity_t,area)
extern func_t SpectatorConnect; extern func_t SpectatorConnect;
extern func_t SpectatorThink; extern func_t SpectatorThink;

View file

@ -434,7 +434,7 @@ void SV_Loadgame_f(void)
#define CACHEGAME_VERSION 512 #define CACHEGAME_VERSION 513
@ -465,6 +465,9 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
edict_t *ent; edict_t *ent;
int version; int version;
char modellist[MAX_QPATH][MAX_MODELS];
char soundlist[MAX_QPATH][MAX_SOUNDS];
int current_skill; int current_skill;
int clnum; int clnum;
@ -591,6 +594,42 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
PR_RegisterFields(); PR_RegisterFields();
PR_InitEnts(svprogfuncs, sv.max_edicts); PR_InitEnts(svprogfuncs, sv.max_edicts);
sv.model_precache[0] = PR_AddString(svprogfuncs, "", 0);
for (i=1; i < MAX_MODELS; i++)
{
fscanf (f, "%s\n", str);
if (!*str)
break;
sv.model_precache[i] = PR_AddString(svprogfuncs, str, 0);
}
if (i == MAX_MODELS)
{
fscanf (f, "%s\n", str);
if (*str)
SV_Error("Too many model precaches in loadgame cache");
}
for (; i < MAX_SOUNDS; i++)
sv.model_precache[i] = NULL;
// sv.sound_precache[0] = PR_AddString(svprogfuncs, "", 0);
for (i=1; i < MAX_SOUNDS; i++)
{
fscanf (f, "%s\n", str);
if (!*str)
break;
// sv.sound_precache[i] = PR_AddString(svprogfuncs, str, 0);
}
if (i == MAX_SOUNDS)
{
fscanf (f, "%s\n", str);
if (*str)
SV_Error("Too many sound precaches in loadgame cache");
}
for (; i < MAX_SOUNDS; i++)
*sv.sound_precache[i] = 0;
filepos = ftell(f); filepos = ftell(f);
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
filelen = ftell(f); filelen = ftell(f);
@ -617,6 +656,9 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
{ {
ent = EDICT_NUM(svprogfuncs, i+1); ent = EDICT_NUM(svprogfuncs, i+1);
svs.clients[i].edict = ent; svs.clients[i].edict = ent;
svs.clients[i].name = PR_AddString(svprogfuncs, svs.clients[i].namebuf, sizeof(svs.clients[i].namebuf));
svs.clients[i].team = PR_AddString(svprogfuncs, svs.clients[i].teambuf, sizeof(svs.clients[i].teambuf));
} }
if (!ignoreplayers) if (!ignoreplayers)
@ -758,6 +800,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
// write the light styles // write the light styles
fprintf (f, "%i\n",MAX_LIGHTSTYLES);
for (i=0 ; i<MAX_LIGHTSTYLES ; i++) for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
{ {
if (sv.lightstyles[i]) if (sv.lightstyles[i])
@ -766,6 +809,23 @@ void SV_SaveLevelCache(qboolean dontharmgame)
fprintf (f,"m\n"); fprintf (f,"m\n");
} }
for (i=1 ; i<MAX_MODELS ; i++)
{
if (sv.model_precache[i])
fprintf (f, "%s\n", sv.model_precache[i]);
else
break;
}
fprintf (f,"\n");
for (i=1 ; i<MAX_SOUNDS ; i++)
{
if (*sv.sound_precache[i])
fprintf (f, "%s\n", sv.sound_precache[i]);
else
break;
}
fprintf (f,"\n");
s = PR_SaveEnts(svprogfuncs, NULL, &len, 1); s = PR_SaveEnts(svprogfuncs, NULL, &len, 1);
fprintf(f, "%s\n", s); fprintf(f, "%s\n", s);
svprogfuncs->parms->memfree(s); svprogfuncs->parms->memfree(s);

View file

@ -384,6 +384,7 @@ typedef struct client_s
q2edict_t *q2edict; // EDICT_NUM(clientnum+1) q2edict_t *q2edict; // EDICT_NUM(clientnum+1)
#endif #endif
int playercolor;
int playerclass; int playerclass;
char teambuf[32]; char teambuf[32];
char *team; char *team;
@ -498,6 +499,7 @@ typedef struct client_s
SCP_BAD, //don't send (a bot) SCP_BAD, //don't send (a bot)
SCP_QUAKEWORLD, SCP_QUAKEWORLD,
SCP_QUAKE2, SCP_QUAKE2,
SCP_QUAKE3,
SCP_NETQUAKE, SCP_NETQUAKE,
SCP_DARKPLACES6, SCP_DARKPLACES6,
SCP_DARKPLACES7 //extra prediction stuff SCP_DARKPLACES7 //extra prediction stuff

View file

@ -185,7 +185,7 @@ float SV_ChatFunc(const char *func) //parse a condition/function
noted = true; noted = true;
func++; func++;
} }
s = COM_ParseToken(func); s = COM_ParseToken(func, NULL);
if (*com_token == '(') if (*com_token == '(')
{//open bracket {//open bracket
//find correct close //find correct close
@ -203,7 +203,7 @@ float SV_ChatFunc(const char *func) //parse a condition/function
parm++; parm++;
} }
func = strchr(func, '('); func = strchr(func, '(');
s=COM_ParseToken(s+1); s=COM_ParseToken(s+1, NULL);
if (!strncmp(com_token, "&&", 2)) if (!strncmp(com_token, "&&", 2))
result = SV_ChatFunc(func+1) && SV_ChatFunc(s); result = SV_ChatFunc(func+1) && SV_ChatFunc(s);
else if (!strncmp(com_token, "||", 2)) else if (!strncmp(com_token, "||", 2))
@ -223,7 +223,7 @@ float SV_ChatFunc(const char *func) //parse a condition/function
s++; s++;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT); pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
parm = OFS_PARM0; parm = OFS_PARM0;
while((s=COM_ParseToken(os = s))) while((s=COM_ParseToken(os = s, NULL)))
{ {
if (*com_token == ')') if (*com_token == ')')
break; break;

View file

@ -47,7 +47,7 @@ qbyte fatpvs[(MAX_MAP_LEAFS+1)/4];
#ifdef Q2BSPS #ifdef Q2BSPS
void SV_Q2BSP_FatPVS (vec3_t org) void SV_Q2BSP_FatPVS (model_t *mod, vec3_t org)
{ {
int leafs[64]; int leafs[64];
int i, j, count; int i, j, count;
@ -61,20 +61,20 @@ void SV_Q2BSP_FatPVS (vec3_t org)
maxs[i] = org[i] + 8; maxs[i] = org[i] + 8;
} }
count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL); count = CM_BoxLeafnums (mod, mins, maxs, leafs, 64, NULL);
if (count < 1) if (count < 1)
Sys_Error ("SV_Q2FatPVS: count < 1"); Sys_Error ("SV_Q2FatPVS: count < 1");
if (sv.worldmodel->fromgame == fg_quake3) if (sv.worldmodel->fromgame == fg_quake3)
longs = CM_ClusterSize(); longs = CM_ClusterSize(mod);
else else
longs = (CM_NumClusters()+31)>>5; longs = (CM_NumClusters(mod)+31)>>5;
// convert leafs to clusters // convert leafs to clusters
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
leafs[i] = CM_LeafCluster(leafs[i]); leafs[i] = CM_LeafCluster(mod, leafs[i]);
CM_ClusterPVS(leafs[0], fatpvs); CM_ClusterPVS(mod, leafs[0], fatpvs);
// memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2); // memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
@ -86,7 +86,7 @@ void SV_Q2BSP_FatPVS (vec3_t org)
break; break;
if (j != i) if (j != i)
continue; // already have the cluster we want continue; // already have the cluster we want
src = CM_ClusterPVS(leafs[i], NULL); src = CM_ClusterPVS(mod, leafs[i], NULL);
for (j=0 ; j<longs ; j++) for (j=0 ; j<longs ; j++)
((long *)fatpvs)[j] |= ((long *)src)[j]; ((long *)fatpvs)[j] |= ((long *)src)[j];
} }
@ -495,8 +495,10 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
if ( to->frame != from->frame ) if ( to->frame != from->frame )
bits |= U_FRAME; bits |= U_FRAME;
if ( (to->effects&255) != (from->effects&255) ) if ( (to->effects&0x00ff) != (from->effects&0x00ff) )
bits |= U_EFFECTS; bits |= U_EFFECTS;
if ( (to->effects&0xff00) != (from->effects&0xff00) )
evenmorebits |= U_EFFECTS16;
if ( to->modelindex != from->modelindex ) if ( to->modelindex != from->modelindex )
{ {
@ -584,7 +586,7 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
if (bits & U_SKIN) if (bits & U_SKIN)
MSG_WriteByte (msg, to->skinnum); MSG_WriteByte (msg, to->skinnum);
if (bits & U_EFFECTS) if (bits & U_EFFECTS)
MSG_WriteByte (msg, to->effects); MSG_WriteByte (msg, to->effects&0x00ff);
if (bits & U_ORIGIN1) if (bits & U_ORIGIN1)
MSG_WriteCoord (msg, to->origin[0]); MSG_WriteCoord (msg, to->origin[0]);
if (bits & U_ANGLE1) if (bits & U_ANGLE1)
@ -634,6 +636,9 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb
MSG_WriteByte (msg, to->lightstyle); MSG_WriteByte (msg, to->lightstyle);
MSG_WriteByte (msg, to->lightpflags); MSG_WriteByte (msg, to->lightpflags);
} }
if (evenmorebits & U_EFFECTS16)
MSG_WriteByte (msg, (to->effects&0xff00)>>8);
} }
/* /*
@ -1758,7 +1763,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
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++)
{ {
isbot = !cl->state && cl->name[0]; isbot = !cl->state && cl->name[0] || cl->protocol == SCP_BAD;
if (cl->state != cs_spawned) //this includes bots if (cl->state != cs_spawned) //this includes bots
if (!isbot || progstype == PROG_QW) //unless they're NQ bots... if (!isbot || progstype == PROG_QW) //unless they're NQ bots...
continue; continue;
@ -1803,13 +1808,8 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
continue; continue;
// ignore if not touching a PV leaf // ignore if not touching a PV leaf
for (i=0 ; i < ent->num_leafs ; i++) if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent))
if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) )) continue;
break;
if (i == ent->num_leafs)
{
continue; // not visible
}
if (!((int)clent->v->dimension_see & ((int)ent->v->dimension_seen | (int)ent->v->dimension_ghost))) if (!((int)clent->v->dimension_see & ((int)ent->v->dimension_seen | (int)ent->v->dimension_ghost)))
continue; //not in this dimension - sorry... continue; //not in this dimension - sorry...
@ -2194,29 +2194,29 @@ qboolean SV_GibFilter(edict_t *ent)
#ifdef Q2BSPS #ifdef Q2BSPS
static int clientarea; static int clientarea;
void Q2BSP_FatPVS(vec3_t org, qboolean add) void Q2BSP_FatPVS(model_t *mod, vec3_t org, qboolean add)
{ {//fixme: this doesn't add
int leafnum; int leafnum;
leafnum = CM_PointLeafnum (org); leafnum = CM_PointLeafnum (mod, org);
clientarea = CM_LeafArea (leafnum); clientarea = CM_LeafArea (mod, leafnum);
SV_Q2BSP_FatPVS (org); SV_Q2BSP_FatPVS (mod, org);
} }
qboolean Q2BSP_EdictInFatPVS(edict_t *ent) qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent)
{ {
int i,l; int i,l;
if (!CM_AreasConnected (clientarea, ent->areanum)) if (!CM_AreasConnected (mod, clientarea, ent->areanum))
{ // doors can legally straddle two areas, so { // doors can legally straddle two areas, so
// we may need to check another one // we may need to check another one
if (!ent->areanum2 if (!ent->areanum2
|| !CM_AreasConnected (clientarea, ent->areanum2)) || !CM_AreasConnected (mod, clientarea, ent->areanum2))
return false; // blocked by a door return false; // blocked by a door
} }
if (ent->num_leafs == -1) if (ent->num_leafs == -1)
{ // too many leafs for individual check, go by headnode { // too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->headnode, fatpvs)) if (!CM_HeadnodeVisible (mod, ent->headnode, fatpvs))
return false; return false;
} }
else else
@ -2274,14 +2274,14 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
clent = client->edict; clent = client->edict;
VectorAdd (clent->v->origin, clent->v->view_ofs, org); VectorAdd (clent->v->origin, clent->v->view_ofs, org);
sv.worldmodel->funcs.FatPVS(org, false); sv.worldmodel->funcs.FatPVS(sv.worldmodel, org, false);
#ifdef PEXT_VIEW2 #ifdef PEXT_VIEW2
if (clent->v->view2) if (clent->v->view2)
sv.worldmodel->funcs.FatPVS(PROG_TO_EDICT(svprogfuncs, clent->v->view2)->v->origin, true); sv.worldmodel->funcs.FatPVS(sv.worldmodel, PROG_TO_EDICT(svprogfuncs, clent->v->view2)->v->origin, true);
#endif #endif
for (split = client->controlled; split; split = split->controlled) for (split = client->controlled; split; split = split->controlled)
sv.worldmodel->funcs.FatPVS(split->edict->v->origin, true); sv.worldmodel->funcs.FatPVS(sv.worldmodel, split->edict->v->origin, true);
/* /*
if (sv.worldmodel->fromgame == fg_doom) if (sv.worldmodel->fromgame == fg_doom)
{ {
@ -2492,12 +2492,12 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
{ {
p = EDICT_NUM(svprogfuncs, p->v->tag_entity); p = EDICT_NUM(svprogfuncs, p->v->tag_entity);
} }
if (!sv.worldmodel->funcs.EdictInFatPVS(p)) if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, p))
continue; continue;
} }
else else
{ {
if (!sv.worldmodel->funcs.EdictInFatPVS(ent)) if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent))
continue; continue;
} }
} }
@ -2698,7 +2698,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
state->modelindex = 0; state->modelindex = 0;
} }
state->effects &= EF_BRIGHTLIGHT | EF_DIMLIGHT | NQEF_ADDATIVE | EF_RED | EF_BLUE; state->effects &= ~ (QWEF_FLAG1|QWEF_FLAG2);
} }
state->glowsize = ent->v->glow_size*0.25; state->glowsize = ent->v->glow_size*0.25;

View file

@ -373,7 +373,7 @@ void SV_CalcPHS (void)
vcount = 0; vcount = 0;
for (i=0 ; i<num ; i++, scan+=rowbytes) for (i=0 ; i<num ; i++, scan+=rowbytes)
{ {
memcpy (scan, sv.worldmodel->funcs.LeafPVS(i, sv.worldmodel, NULL), memcpy (scan, sv.worldmodel->funcs.LeafPVS(sv.worldmodel, i, NULL),
rowbytes); rowbytes);
if (i == 0) if (i == 0)
continue; continue;
@ -665,6 +665,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
sv.worldmodel = Mod_ForName (sv.modelname, true); sv.worldmodel = Mod_ForName (sv.modelname, true);
if (sv.worldmodel->needload) if (sv.worldmodel->needload)
Sys_Error("%s is missing\n", sv.modelname); Sys_Error("%s is missing\n", sv.modelname);
if (sv.worldmodel->type != mod_brush && sv.worldmodel->type != mod_heightmap)
Sys_Error("%s is not a bsp model\n", sv.modelname);
sv.state = ss_dead; sv.state = ss_dead;
#ifndef SERVERONLY #ifndef SERVERONLY
@ -1057,7 +1059,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
else else
sprintf(sv.mapname, "%s", PR_GetString(svprogfuncs, val->string)); sprintf(sv.mapname, "%s", PR_GetString(svprogfuncs, val->string));
} }
ent->readonly = true; //lock it down! if (Cvar_Get("sv_readonlyworld", "1", 0, "DP compatability")->value)
ent->readonly = true; //lock it down!
// look up some model indexes for specialized message compression // look up some model indexes for specialized message compression
SV_FindModelNumbers (); SV_FindModelNumbers ();
@ -1131,6 +1134,43 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
current_loading_size+=10; current_loading_size+=10;
SCR_BeginLoadingPlaque(); SCR_BeginLoadingPlaque();
#endif #endif
if (svs.gametype == GT_PROGS)
{
for (i = 0; i < MAX_CLIENTS; i++)
{
host_client = &svs.clients[i];
if (host_client->state == cs_connected && host_client->protocol == SCP_BAD)
{
sv_player = host_client->edict;
SV_ExtractFromUserinfo(host_client);
// copy spawn parms out of the client_t
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
{
if (spawnparamglobals[i])
*spawnparamglobals[i] = host_client->spawn_parms[i];
}
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect);
// actually spawn the player
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
// send notification to all clients
host_client->sendinfo = true;
host_client->state = cs_spawned;
SV_UpdateToReliableMessages(); //so that we don't flood too much with 31 bots and one player.
}
}
}
} }
#endif #endif

View file

@ -390,33 +390,47 @@ void SV_DropClient (client_t *drop)
#ifdef SVCHAT #ifdef SVCHAT
SV_WipeChat(drop); SV_WipeChat(drop);
#endif #endif
#ifdef Q2SERVER switch(svs.gametype)
if (ge && drop->protocol == SCP_QUAKE2)
ge->ClientDisconnect(drop->q2edict);
#endif
if (svprogfuncs)
{ {
if (drop->state == cs_spawned) #ifdef Q3SERVER
{ case GT_QUAKE3:
if (!drop->spectator) SVQ3_DropClient(drop);
{ break;
// call the prog function for removing a client #endif
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
}
else if (SpectatorDisconnect)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
}
}
if (drop->spawninfo) #ifdef Q2SERVER
Z_Free(drop->spawninfo); case GT_QUAKE2:
drop->spawninfo = NULL; if (ge)
ge->ClientDisconnect(drop->q2edict);
break;
#endif
case GT_PROGS:
if (svprogfuncs)
{
if (drop->state == cs_spawned)
{
if (!drop->spectator)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
}
else if (SpectatorDisconnect)
{
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
PR_ExecuteProgram (svprogfuncs, SpectatorDisconnect);
}
}
if (drop->spawninfo)
Z_Free(drop->spawninfo);
drop->spawninfo = NULL;
}
break;
} }
if (drop->spectator) if (drop->spectator)
@ -3508,17 +3522,18 @@ void SV_ExtractFromUserinfo (client_t *cl)
{ {
int top = atoi(Info_ValueForKey(cl->userinfo, "topcolor")); int top = atoi(Info_ValueForKey(cl->userinfo, "topcolor"));
int bottom = atoi(Info_ValueForKey(cl->userinfo, "bottomcolor")); int bottom = atoi(Info_ValueForKey(cl->userinfo, "bottomcolor"));
int playercolor;
top &= 15; top &= 15;
if (top > 13) if (top > 13)
top = 13; top = 13;
bottom &= 15; bottom &= 15;
if (bottom > 13) if (bottom > 13)
bottom = 13; bottom = 13;
playercolor = top*16 + bottom; cl->playercolor = top*16 + bottom;
if (svs.gametype == GT_PROGS)
cl->edict->v->clientcolors = cl->playercolor;
MSG_WriteByte (&sv.nqreliable_datagram, svc_updatecolors); MSG_WriteByte (&sv.nqreliable_datagram, svc_updatecolors);
MSG_WriteByte (&sv.nqreliable_datagram, cl-svs.clients); MSG_WriteByte (&sv.nqreliable_datagram, cl-svs.clients);
MSG_WriteByte (&sv.nqreliable_datagram, playercolor); MSG_WriteByte (&sv.nqreliable_datagram, cl->playercolor);
} }
#endif #endif
} }

View file

@ -141,6 +141,24 @@ qboolean SV_RunThink (edict_t *ent)
{ {
float thinktime; float thinktime;
if (sv_nomsec.value>=2) //try and imitate nq as closeley as possible
{
thinktime = ent->v->nextthink;
if (thinktime <= 0 || thinktime > sv.time + host_frametime)
return true;
if (thinktime < sv.time)
thinktime = sv.time; // don't let things stay in the past.
// it is possible to start that way
// by a trigger with a local time.
ent->v->nextthink = 0;
pr_global_struct->time = thinktime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts);
PR_ExecuteProgram (svprogfuncs, ent->v->think);
return !ent->isfree;
}
do do
{ {
thinktime = ent->v->nextthink; thinktime = ent->v->nextthink;

View file

@ -472,8 +472,8 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (to != MULTICAST_ALL_R && to != MULTICAST_ALL) if (to != MULTICAST_ALL_R && to != MULTICAST_ALL)
{ {
leafnum = CM_PointLeafnum (origin); leafnum = CM_PointLeafnum (sv.worldmodel, origin);
area1 = CM_LeafArea (leafnum); area1 = CM_LeafArea (sv.worldmodel, leafnum);
} }
else else
{ {
@ -493,17 +493,17 @@ 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:
leafnum = CM_PointLeafnum (origin); leafnum = CM_PointLeafnum (sv.worldmodel, origin);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
mask = CM_ClusterPHS (cluster); mask = CM_ClusterPHS (sv.worldmodel, cluster);
break; break;
case MULTICAST_PVS_R: case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough reliable = true; // intentional fallthrough
case MULTICAST_PVS: case MULTICAST_PVS:
leafnum = CM_PointLeafnum (origin); leafnum = CM_PointLeafnum (sv.worldmodel, origin);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
mask = CM_ClusterPVS (cluster, NULL); mask = CM_ClusterPVS (sv.worldmodel, cluster, NULL);
break; break;
default: default:
@ -532,13 +532,13 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
{ {
#ifdef Q2SERVER #ifdef Q2SERVER
if (ge) if (ge)
leafnum = CM_PointLeafnum (client->q2edict->s.origin); leafnum = CM_PointLeafnum (sv.worldmodel, client->q2edict->s.origin);
else else
#endif #endif
leafnum = CM_PointLeafnum (client->edict->v->origin); leafnum = CM_PointLeafnum (sv.worldmodel, client->edict->v->origin);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area2 = CM_LeafArea (leafnum); area2 = CM_LeafArea (sv.worldmodel, leafnum);
if (!CM_AreasConnected (area1, area2)) if (!CM_AreasConnected (sv.worldmodel, area1, area2))
continue; continue;
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
continue; continue;
@ -588,11 +588,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
else else
#endif #endif
{ {
leaf = Mod_PointInLeaf (origin, sv.worldmodel); leafnum = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, origin);
if (!leaf)
leafnum = 0;
else
leafnum = leaf - sv.worldmodel->leafs;
reliable = false; reliable = false;
@ -651,11 +647,10 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (!((int)client->edict->v->dimension_see & dimension_mask)) if (!((int)client->edict->v->dimension_see & dimension_mask))
continue; continue;
leaf = Mod_PointInLeaf (client->edict->v->origin, sv.worldmodel); leafnum = sv.worldmodel->funcs.LeafnumForPoint (sv.worldmodel, client->edict->v->origin);
if (leaf)
{ {
// -1 is because pvs rows are 1 based, not 0 based like leafs // -1 is because pvs rows are 1 based, not 0 based like leafs
leafnum = leaf - sv.worldmodel->leafs - 1; // leafnum = leaf - sv.worldmodel->leafs - 1;
if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) ) if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) )
{ {
// Con_Printf ("supressed multicast\n"); // Con_Printf ("supressed multicast\n");
@ -1459,13 +1454,56 @@ void SV_UpdateToReliableMessages (void)
int i, j; int i, j;
client_t *client, *sp; client_t *client, *sp;
edict_t *ent; edict_t *ent;
char *name;
// check for changes to be sent over the reliable streams to all clients // check for changes to be sent over the reliable streams to all clients
for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++) for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
{ {
if (svs.gametype == GT_PROGS && host_client->state == cs_spawned)
{
//DP_SV_CLIENTCOLORS
if (host_client->edict->v->clientcolors != host_client->playercolor)
{
Info_SetValueForKey(host_client->userinfo, "topcolor", va("%i", (int)host_client->edict->v->clientcolors/16), sizeof(host_client->userinfo));
Info_SetValueForKey(host_client->userinfo, "bottomcolor", va("%i", (int)host_client->edict->v->clientcolors&15), sizeof(host_client->userinfo));
{
SV_ExtractFromUserinfo (host_client); //this will take care of nq for us anyway.
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
MSG_WriteByte (&sv.reliable_datagram, i);
MSG_WriteString (&sv.reliable_datagram, "topcolor");
MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(host_client->userinfo, "topcolor"));
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
MSG_WriteByte (&sv.reliable_datagram, i);
MSG_WriteString (&sv.reliable_datagram, "bottomcolor");
MSG_WriteString (&sv.reliable_datagram, Info_ValueForKey(host_client->userinfo, "bottomcolor"));
}
}
name = PR_GetString(svprogfuncs, host_client->edict->v->netname);
if (name != host_client->name)
{
if (strcmp(host_client->name, name))
{
Info_SetValueForKey(host_client->userinfo, "name", name, sizeof(host_client->userinfo));
if (!strcmp(Info_ValueForKey(host_client->userinfo, "name"), name))
{
SV_ExtractFromUserinfo (host_client);
MSG_WriteByte (&sv.reliable_datagram, svc_setinfo);
MSG_WriteByte (&sv.reliable_datagram, i);
MSG_WriteString (&sv.reliable_datagram, "name");
MSG_WriteString (&sv.reliable_datagram, host_client->name);
}
}
host_client->edict->v->netname = host_client->name - svprogfuncs->stringtable;
}
}
if (host_client->state != cs_spawned) if (host_client->state != cs_spawned)
{ {
if (!host_client->state && host_client->name && host_client->name[0]) //if this is a bot if (!host_client->state && host_client->name && host_client->name[0]) //if this is a writebyte bot
{ {
if (host_client->old_frags != (int)host_client->edict->v->frags) if (host_client->old_frags != (int)host_client->edict->v->frags)
{ {

View file

@ -1563,7 +1563,6 @@ qboolean SV_AllowDownload (char *name)
extern cvar_t allow_download_pk3s; extern cvar_t allow_download_pk3s;
extern cvar_t allow_download_wads; extern cvar_t allow_download_wads;
extern cvar_t allow_download_root; extern cvar_t allow_download_root;
// extern int file_from_pak; // ZOID did file come from pak?
//allowed at all? //allowed at all?
if (!allow_download.value) if (!allow_download.value)
@ -1630,7 +1629,6 @@ void SV_BeginDownload_f(void)
{ {
char *name; char *name;
extern cvar_t allow_download_anymap, allow_download_pakcontents; extern cvar_t allow_download_anymap, allow_download_pakcontents;
extern int file_from_pak; // ZOID did file come from pak?
name = Cmd_Argv(1); name = Cmd_Argv(1);
@ -1679,7 +1677,7 @@ void SV_BeginDownload_f(void)
if (!host_client->download if (!host_client->download
// special check for maps, if it came from a pak file, don't allow // special check for maps, if it came from a pak file, don't allow
// download ZOID // download ZOID
|| ((!allow_download_pakcontents.value || (!allow_download_anymap.value && strncmp(name, "maps/", 5) == 0)) && file_from_pak)) || ((!allow_download_pakcontents.value || (!allow_download_anymap.value && strncmp(name, "maps/", 5) == 0)) && com_file_copyprotected))
{ {
if (host_client->download) if (host_client->download)
{ {
@ -2818,6 +2816,8 @@ void Cmd_Observe_f (void)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, SpectatorConnect); PR_ExecuteProgram (svprogfuncs, SpectatorConnect);
} }
else
sv_player->v->movetype = MOVETYPE_NOCLIP;
// send notification to all clients // send notification to all clients
host_client->sendinfo = true; host_client->sendinfo = true;
@ -3653,7 +3653,7 @@ void AddLinksToPmove ( areanode_t *node )
model = sv.models[(int)check->v->modelindex]; model = sv.models[(int)check->v->modelindex];
if (model) if (model)
// test the point // test the point
if ( model->hulls[0].funcs.HullPointContents (&model->hulls[0], sv_player->v->origin) == FTECONTENTS_SOLID ) if ( model->funcs.PointContents (model, sv_player->v->origin) == FTECONTENTS_SOLID )
sv_player->v->fteflags = (int)sv_player->v->fteflags | FF_LADDER; //touch that ladder! sv_player->v->fteflags = (int)sv_player->v->fteflags | FF_LADDER; //touch that ladder!
} }
} }

View file

@ -57,7 +57,7 @@ void Mod_Init (void)
Mod_LeafForPoint Mod_LeafForPoint
=============== ===============
*/ */
int Mod_LeafForPoint (vec3_t p, model_t *model) int Mod_LeafForPoint (model_t *model, vec3_t p)
{ {
mnode_t *node; mnode_t *node;
float d; float d;
@ -65,7 +65,7 @@ int Mod_LeafForPoint (vec3_t p, model_t *model)
#ifdef Q2BSPS #ifdef Q2BSPS
if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3) if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3)
{ {
return CM_PointLeafnum(p); return CM_PointLeafnum(model, p);
} }
#endif #endif
if (!model || !model->nodes) if (!model || !model->nodes)
@ -92,9 +92,9 @@ int Mod_LeafForPoint (vec3_t p, model_t *model)
Mod_PointInLeaf Mod_PointInLeaf
=============== ===============
*/ */
mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model) mleaf_t *Mod_PointInLeaf (model_t *model, vec3_t p)
{ {
return model->leafs + Mod_LeafForPoint(p, model); return model->leafs + Mod_LeafForPoint(model, p);
} }
@ -1287,16 +1287,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
Mod_MakeHull0 (); Mod_MakeHull0 ();
mod->funcs.FatPVS = Q1BSP_FatPVS; Q1BSP_SetModelFuncs(mod);
mod->funcs.EdictInFatPVS = Q1BSP_EdictInFatPVS;
mod->funcs.FindTouchedLeafs_Q1 = Q1BSP_FindTouchedLeafs;
mod->funcs.LightPointValues = NULL;
mod->funcs.StainNode = NULL;
mod->funcs.MarkLights = NULL;
mod->funcs.LeafForPoint = Mod_LeafForPoint;
mod->funcs.LeafPVS = Mod_LeafnumPVS;
mod->funcs.Trace = Q1BSP_Trace;
mod->numframes = 2; // regular and alternate animation mod->numframes = 2; // regular and alternate animation

View file

@ -637,19 +637,19 @@ void SV_BuildClientFrame (client_t *client)
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i]; org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
leafnum = CM_PointLeafnum (org); leafnum = CM_PointLeafnum (sv.worldmodel, org);
clientarea = CM_LeafArea (leafnum); clientarea = CM_LeafArea (sv.worldmodel, leafnum);
clientcluster = CM_LeafCluster (leafnum); clientcluster = CM_LeafCluster (sv.worldmodel, leafnum);
// calculate the visible areas // calculate the visible areas
areabytes = CM_WriteAreaBits (areabits, clientarea); areabytes = CM_WriteAreaBits (sv.worldmodel, areabits, clientarea);
// grab the current player_state_t // grab the current player_state_t
frame->ps = clent->client->ps; frame->ps = clent->client->ps;
SV_Q2BSP_FatPVS (org); sv.worldmodel->funcs.FatPVS(sv.worldmodel, org, false);
clientphs = CM_ClusterPHS (clientcluster); clientphs = CM_ClusterPHS (sv.worldmodel, clientcluster);
// build up the list of visible entities // build up the list of visible entities
frame->num_entities = 0; frame->num_entities = 0;
@ -674,11 +674,11 @@ void SV_BuildClientFrame (client_t *client)
if (ent != clent) if (ent != clent)
{ {
// check area // check area
if (!CM_AreasConnected (clientarea, ent->areanum)) if (!CM_AreasConnected (sv.worldmodel, clientarea, ent->areanum))
{ // doors can legally straddle two areas, so { // doors can legally straddle two areas, so
// we may need to check another one // we may need to check another one
if (!ent->areanum2 if (!ent->areanum2
|| !CM_AreasConnected (clientarea, ent->areanum2)) || !CM_AreasConnected (sv.worldmodel, clientarea, ent->areanum2))
continue; // blocked by a door continue; // blocked by a door
} }
@ -698,7 +698,7 @@ void SV_BuildClientFrame (client_t *client)
if (ent->num_clusters == -1) if (ent->num_clusters == -1)
{ // too many leafs for individual check, go by headnode { // too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->headnode, bitvector)) if (!CM_HeadnodeVisible (sv.worldmodel, ent->headnode, bitvector))
continue; continue;
c_fullsend++; c_fullsend++;
} }

View file

@ -343,17 +343,17 @@ static qboolean VARGS PFQ2_inPVS (vec3_t p1, vec3_t p2)
int area1, area2; int area1, area2;
qbyte *mask; qbyte *mask;
leafnum = CM_PointLeafnum (p1); leafnum = CM_PointLeafnum (sv.worldmodel, p1);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area1 = CM_LeafArea (leafnum); area1 = CM_LeafArea (sv.worldmodel, leafnum);
mask = CM_ClusterPVS (cluster, NULL); mask = CM_ClusterPVS (sv.worldmodel, cluster, NULL);
leafnum = CM_PointLeafnum (p2); leafnum = CM_PointLeafnum (sv.worldmodel, p2);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area2 = CM_LeafArea (leafnum); area2 = CM_LeafArea (sv.worldmodel, leafnum);
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
return false; return false;
if (!CM_AreasConnected (area1, area2)) if (!CM_AreasConnected (sv.worldmodel, area1, area2))
return false; // a door blocks sight return false; // a door blocks sight
return true; return true;
} }
@ -373,22 +373,27 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2)
int area1, area2; int area1, area2;
qbyte *mask; qbyte *mask;
leafnum = CM_PointLeafnum (p1); leafnum = CM_PointLeafnum (sv.worldmodel, p1);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area1 = CM_LeafArea (leafnum); area1 = CM_LeafArea (sv.worldmodel, leafnum);
mask = CM_ClusterPHS (cluster); mask = CM_ClusterPHS (sv.worldmodel, cluster);
leafnum = CM_PointLeafnum (p2); leafnum = CM_PointLeafnum (sv.worldmodel, p2);
cluster = CM_LeafCluster (leafnum); cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area2 = CM_LeafArea (leafnum); area2 = CM_LeafArea (sv.worldmodel, leafnum);
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
return false; // more than one bounce away return false; // more than one bounce away
if (!CM_AreasConnected (area1, area2)) if (!CM_AreasConnected (sv.worldmodel, area1, area2))
return false; // a door blocks hearing return false; // a door blocks hearing
return true; return true;
} }
qboolean VARGS PFQ2_AreasConnected(int area1, int area2)
{
return CM_AreasConnected(sv.worldmodel, area1, area2);
}
#define Q2SND_VOLUME (1<<0) // a byte #define Q2SND_VOLUME (1<<0) // a byte
#define Q2SND_ATTENUATION (1<<1) // a byte #define Q2SND_ATTENUATION (1<<1) // a byte
@ -682,7 +687,7 @@ qboolean SVQ2_InitGameProgs(void)
import.DebugGraph = Q2SCR_DebugGraph; import.DebugGraph = Q2SCR_DebugGraph;
import.SetAreaPortalState = CMQ2_SetAreaPortalState; import.SetAreaPortalState = CMQ2_SetAreaPortalState;
import.AreasConnected = CM_AreasConnected; import.AreasConnected = PFQ2_AreasConnected;
if (sv.worldmodel->fromgame == fg_quake || sv.worldmodel->fromgame == fg_halflife) if (sv.worldmodel->fromgame == fg_quake || sv.worldmodel->fromgame == fg_halflife)
{ {

View file

@ -294,7 +294,7 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node )
} }
#ifdef Q2BSPS #ifdef Q2BSPS
void Q2BSP_FindTouchedLeafs(edict_t *ent) void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent)
{ {
#define MAX_TOTAL_ENT_LEAFS 128 #define MAX_TOTAL_ENT_LEAFS 128
int leafs[MAX_TOTAL_ENT_LEAFS]; int leafs[MAX_TOTAL_ENT_LEAFS];
@ -310,14 +310,14 @@ void Q2BSP_FindTouchedLeafs(edict_t *ent)
ent->areanum2 = 0; ent->areanum2 = 0;
//get all leafs, including solids //get all leafs, including solids
num_leafs = CM_BoxLeafnums (ent->v->absmin, ent->v->absmax, num_leafs = CM_BoxLeafnums (model, ent->v->absmin, ent->v->absmax,
leafs, MAX_TOTAL_ENT_LEAFS, &topnode); leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
// set areas // set areas
for (i=0 ; i<num_leafs ; i++) for (i=0 ; i<num_leafs ; i++)
{ {
clusters[i] = CM_LeafCluster (leafs[i]); clusters[i] = CM_LeafCluster (model, leafs[i]);
area = CM_LeafArea (leafs[i]); area = CM_LeafArea (model, leafs[i]);
if (area) if (area)
{ // doors may legally straggle two areas, { // doors may legally straggle two areas,
// but nothing should evern need more than that // but nothing should evern need more than that
@ -455,7 +455,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
} }
// link to PVS leafs // link to PVS leafs
sv.worldmodel->funcs.FindTouchedLeafs_Q1(ent); sv.worldmodel->funcs.FindTouchedLeafs_Q1(sv.worldmodel, ent);
/* /*
#ifdef Q2BSPS #ifdef Q2BSPS
if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3)
@ -606,14 +606,14 @@ void VARGS SVQ2_LinkEdict(q2edict_t *ent)
ent->areanum2 = 0; ent->areanum2 = 0;
//get all leafs, including solids //get all leafs, including solids
num_leafs = CM_BoxLeafnums (ent->absmin, ent->absmax, num_leafs = CM_BoxLeafnums (sv.worldmodel, ent->absmin, ent->absmax,
leafs, MAX_TOTAL_ENT_LEAFS, &topnode); leafs, MAX_TOTAL_ENT_LEAFS, &topnode);
// set areas // set areas
for (i=0 ; i<num_leafs ; i++) for (i=0 ; i<num_leafs ; i++)
{ {
clusters[i] = CM_LeafCluster (leafs[i]); clusters[i] = CM_LeafCluster (sv.worldmodel, leafs[i]);
area = CM_LeafArea (leafs[i]); area = CM_LeafArea (sv.worldmodel, leafs[i]);
if (area) if (area)
{ // doors may legally straggle two areas, { // doors may legally straggle two areas,
// but nothing should evern need more than that // but nothing should evern need more than that
@ -887,7 +887,7 @@ SV_PointContents
*/ */
int SV_PointContents (vec3_t p) int SV_PointContents (vec3_t p)
{ {
return sv.worldmodel->hulls[0].funcs.HullPointContents(&sv.worldmodel->hulls[0], p); return sv.worldmodel->funcs.PointContents(sv.worldmodel, p);
} }
//=========================================================================== //===========================================================================
@ -983,10 +983,10 @@ qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, v
memset (trace, 0, sizeof(trace_t)); memset (trace, 0, sizeof(trace_t));
trace->fraction = 1; trace->fraction = 1;
trace->allsolid = true; trace->allsolid = true;
VectorCopy (end, trace->endpos);
VectorSubtract (start, origin, start_l); VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l); VectorSubtract (end, origin, end_l);
VectorCopy (end_l, trace->endpos);
result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace); result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
VectorAdd (trace->endpos, origin, trace->endpos); VectorAdd (trace->endpos, origin, trace->endpos);
} }
@ -1024,7 +1024,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max
if (ent->v->solid == SOLID_BSP) if (ent->v->solid == SOLID_BSP)
{ {
model = sv.models[(int)ent->v->modelindex]; model = sv.models[(int)ent->v->modelindex];
if (!model || model->type != mod_brush) if (!model || (model->type != mod_brush && model->type != mod_heightmap))
SV_Error("SOLID_BSP with non bsp model (classname: %s)", svprogfuncs->stringtable + ent->v->classname); SV_Error("SOLID_BSP with non bsp model (classname: %s)", svprogfuncs->stringtable + ent->v->classname);
} }
else else
@ -1281,7 +1281,7 @@ Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull. testing object's origin to get a point to use with the returned hull.
================ ================
*/ */
int SV_HeadnodeForEntity (edict_t *ent) static model_t *SV_ModelForEntity (edict_t *ent)
{ {
model_t *model; model_t *model;
@ -1293,16 +1293,16 @@ int SV_HeadnodeForEntity (edict_t *ent)
if (!model) if (!model)
SV_Error ("MOVETYPE_PUSH with a non bsp model"); SV_Error ("MOVETYPE_PUSH with a non bsp model");
return model->hulls[0].firstclipnode; return model;
} }
// create a temp hull from bounding box sizes // create a temp hull from bounding box sizes
return CM_HeadnodeForBox (ent->v->mins, ent->v->maxs); return CM_TempBoxModel (ent->v->mins, ent->v->maxs);
} }
#ifdef Q2SERVER #ifdef Q2SERVER
int SVQ2_HeadnodeForEntity (q2edict_t *ent) static model_t *SVQ2_ModelForEntity (q2edict_t *ent)
{ {
model_t *model; model_t *model;
@ -1314,12 +1314,12 @@ int SVQ2_HeadnodeForEntity (q2edict_t *ent)
if (!model) if (!model)
SV_Error ("Q2SOLID_BSP with a non bsp model"); SV_Error ("Q2SOLID_BSP with a non bsp model");
return model->hulls[0].firstclipnode; return model;
} }
// create a temp hull from bounding box sizes // create a temp hull from bounding box sizes
return CM_HeadnodeForBox (ent->mins, ent->maxs); return CM_TempBoxModel (ent->mins, ent->maxs);
} }
#endif #endif
/* /*
@ -1433,7 +1433,7 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask )
int i, num; int i, num;
q2edict_t *touchlist[MAX_EDICTS], *touch; q2edict_t *touchlist[MAX_EDICTS], *touch;
trace_t trace; trace_t trace;
int headnode; model_t *model;
float *angles; float *angles;
num = SVQ2_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist num = SVQ2_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist
@ -1463,18 +1463,18 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask )
continue; continue;
// might intersect, so do an exact clip // might intersect, so do an exact clip
headnode = SVQ2_HeadnodeForEntity (touch); model = SVQ2_ModelForEntity (touch);
angles = touch->s.angles; angles = touch->s.angles;
if (touch->solid != Q2SOLID_BSP) if (touch->solid != Q2SOLID_BSP)
angles = vec3_origin; // boxes don't rotate angles = vec3_origin; // boxes don't rotate
if (touch->svflags & SVF_MONSTER) if (touch->svflags & SVF_MONSTER)
trace = CM_TransformedBoxTrace (clip->start, clip->end, trace = CM_TransformedBoxTrace (model, clip->start, clip->end,
clip->mins2, clip->maxs2, headnode, contentsmask, clip->mins2, clip->maxs2, contentsmask,
touch->s.origin, angles); touch->s.origin, angles);
else else
trace = CM_TransformedBoxTrace (clip->start, clip->end, trace = CM_TransformedBoxTrace (model, clip->start, clip->end,
clip->mins, clip->maxs, headnode, contentsmask, clip->mins, clip->maxs, contentsmask,
touch->s.origin, angles); touch->s.origin, angles);
if (trace.allsolid || trace.startsolid || if (trace.allsolid || trace.startsolid ||
@ -1765,6 +1765,9 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
if (clip.trace.startsolid) if (clip.trace.startsolid)
clip.trace.fraction = 0; clip.trace.fraction = 0;
if (!clip.trace.ent)
return clip.trace;
return clip.trace; return clip.trace;
} }
#ifdef Q2SERVER #ifdef Q2SERVER
@ -1775,7 +1778,7 @@ trace_t SVQ2_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type,
memset ( &clip, 0, sizeof ( moveclip_t ) ); memset ( &clip, 0, sizeof ( moveclip_t ) );
// clip to world // clip to world
clip.trace = CM_BoxTrace(start, end, mins, maxs, 0, type);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end ); clip.trace = CM_BoxTrace(sv.worldmodel, start, end, mins, maxs, type);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end );
clip.trace.ent = (edict_t *)ge->edicts; clip.trace.ent = (edict_t *)ge->edicts;
if (clip.trace.fraction == 0) if (clip.trace.fraction == 0)

View file

@ -879,16 +879,16 @@ void R_RenderWorld (void)
{ {
int leafnum; int leafnum;
int clientarea; int clientarea;
int CM_WriteAreaBits (qbyte *buffer, int area);
#ifdef Q2CLIENT #ifdef Q2CLIENT
if (cls.protocol == CP_QUAKE2) if (cls.protocol == CP_QUAKE2)
memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); memcpy(areabits, cl.q2frame.areabits, sizeof(areabits));
else else
#endif #endif
{ {
leafnum = CM_PointLeafnum (r_refdef.vieworg); leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg);
clientarea = CM_LeafArea (leafnum); clientarea = CM_LeafArea (cl.worldmodel, leafnum);
CM_WriteAreaBits(areabits, clientarea); CM_WriteAreaBits(cl.worldmodel, areabits, clientarea);
} }
SWR_RecursiveQ2WorldNode (clmodel->nodes, 15); SWR_RecursiveQ2WorldNode (clmodel->nodes, 15);

View file

@ -580,12 +580,12 @@ void SWR_MarkLeaves (void)
return; return;
} }
vis = CM_ClusterPVS (r_viewcluster, NULL);//, cl.worldmodel); vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);
// may have to combine two clusters because of solid water boundaries // may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster) if (r_viewcluster2 != r_viewcluster)
{ {
memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8); memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8);
vis = CM_ClusterPVS (r_viewcluster2, NULL);//, cl.worldmodel); vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL);//, cl.worldmodel);
c = (cl.worldmodel->numleafs+31)/32; c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++) for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i]; ((int *)fatvis)[i] |= ((int *)vis)[i];
@ -619,7 +619,7 @@ void SWR_MarkLeaves (void)
r_visframecount++; r_visframecount++;
r_oldviewleaf = r_viewleaf; r_oldviewleaf = r_viewleaf;
vis = SWMod_LeafPVS (r_viewleaf, cl.worldmodel, NULL); vis = SWMod_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
for (i=0 ; i<cl.worldmodel->numleafs ; i++) for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{ {

View file

@ -531,7 +531,7 @@ r_refdef.viewangles[2]= 0;
r_oldviewcluster = r_viewcluster; r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2; r_oldviewcluster2 = r_viewcluster2;
leaf = SWMod_PointInLeaf (r_origin, cl.worldmodel); leaf = SWMod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcluster = r_viewcluster2 = leaf->cluster; r_viewcluster = r_viewcluster2 = leaf->cluster;
// check above and below so crossing solid water doesn't draw wrong // check above and below so crossing solid water doesn't draw wrong
@ -541,7 +541,7 @@ r_refdef.viewangles[2]= 0;
VectorCopy (r_origin, temp); VectorCopy (r_origin, temp);
temp[2] -= 16; temp[2] -= 16;
leaf = SWMod_PointInLeaf (temp, cl.worldmodel); leaf = SWMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) && if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) ) (leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster; r_viewcluster2 = leaf->cluster;
@ -552,7 +552,7 @@ r_refdef.viewangles[2]= 0;
VectorCopy (r_origin, temp); VectorCopy (r_origin, temp);
temp[2] += 16; temp[2] += 16;
leaf = SWMod_PointInLeaf (temp, cl.worldmodel); leaf = SWMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) && if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) ) (leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster; r_viewcluster2 = leaf->cluster;
@ -563,7 +563,7 @@ r_refdef.viewangles[2]= 0;
{ {
// current viewleaf // current viewleaf
r_oldviewleaf = r_viewleaf; r_oldviewleaf = r_viewleaf;
r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel); r_viewleaf = SWMod_PointInLeaf (cl.worldmodel, r_origin);
} }
r_dowarpold = r_dowarp; r_dowarpold = r_dowarp;

View file

@ -98,7 +98,7 @@ void *SWMod_Extradata (model_t *mod)
Mod_PointInLeaf Mod_PointInLeaf
=============== ===============
*/ */
int SWMod_LeafForPoint (vec3_t p, model_t *model) static int SWMod_LeafForPoint (model_t *model, vec3_t p)
{ {
mnode_t *node; mnode_t *node;
float d; float d;
@ -107,7 +107,7 @@ int SWMod_LeafForPoint (vec3_t p, model_t *model)
#ifdef Q2BSPS #ifdef Q2BSPS
if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3) if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3)
{ {
return CM_PointLeafnum(p); return CM_PointLeafnum(cl.worldmodel, p);
} }
#endif #endif
@ -130,9 +130,9 @@ int SWMod_LeafForPoint (vec3_t p, model_t *model)
return 0; // never reached return 0; // never reached
} }
mleaf_t *SWMod_PointInLeaf (vec3_t p, model_t *model) mleaf_t *SWMod_PointInLeaf (model_t *model, vec3_t p)
{ {
return model->leafs + SWMod_LeafForPoint(p, model); return model->leafs + SWMod_LeafForPoint(model, p);
} }
@ -141,7 +141,7 @@ mleaf_t *SWMod_PointInLeaf (vec3_t p, model_t *model)
Mod_DecompressVis Mod_DecompressVis
=================== ===================
*/ */
qbyte *SWMod_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed) static qbyte *SWMod_DecompressVis (model_t *model, qbyte *in, qbyte *decompressed)
{ {
int c; int c;
qbyte *out; qbyte *out;
@ -184,7 +184,7 @@ qbyte *SWMod_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed)
return decompressed; return decompressed;
} }
qbyte *SWMod_LeafPVS (mleaf_t *leaf, model_t *model, qbyte *buffer) qbyte *SWMod_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer)
{ {
static qbyte decompressed[MAX_MAP_LEAFS/8]; static qbyte decompressed[MAX_MAP_LEAFS/8];
@ -193,12 +193,7 @@ qbyte *SWMod_LeafPVS (mleaf_t *leaf, model_t *model, qbyte *buffer)
if (!buffer) if (!buffer)
buffer = decompressed; buffer = decompressed;
return SWMod_DecompressVis (leaf->compressed_vis, model, buffer); return SWMod_DecompressVis (model, leaf->compressed_vis, buffer);
}
qbyte *SWMod_LeafnumPVS (int ln, model_t *model, qbyte *buffer)
{
return SWMod_LeafPVS(model->leafs + ln, model, buffer);
} }
/* /*
@ -1867,11 +1862,6 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs);
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node); void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
#ifndef CLIENTONLY
void Q1BSP_FatPVS (vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(edict_t *ent);
void Q1BSP_FindTouchedLeafs(edict_t *ent);
#endif
void SWQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void SWQ1BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void SWR_Q1BSP_StainNode (mnode_t *node, float *parms); void SWR_Q1BSP_StainNode (mnode_t *node, float *parms);
@ -1960,18 +1950,11 @@ void SWMod_LoadBrushModel (model_t *mod, void *buffer)
crouchhullfile=NULL; crouchhullfile=NULL;
} }
#ifndef CLIENTONLY Q1BSP_SetModelFuncs(mod);
mod->funcs.FatPVS = Q1BSP_FatPVS;
mod->funcs.EdictInFatPVS = Q1BSP_EdictInFatPVS;
mod->funcs.FindTouchedLeafs_Q1 = Q1BSP_FindTouchedLeafs;
#endif
mod->funcs.LightPointValues = SWQ1BSP_LightPointValues; mod->funcs.LightPointValues = SWQ1BSP_LightPointValues;
mod->funcs.StainNode = SWR_Q1BSP_StainNode; mod->funcs.StainNode = SWR_Q1BSP_StainNode;
mod->funcs.MarkLights = Q1BSP_MarkLights; mod->funcs.MarkLights = Q1BSP_MarkLights;
mod->funcs.LeafForPoint = SWMod_LeafForPoint;
mod->funcs.LeafPVS = SWMod_LeafnumPVS;
mod->funcs.Trace = Q1BSP_Trace;
//We ONLY do this for the world model //We ONLY do this for the world model
#ifndef SERVERONLY #ifndef SERVERONLY