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();
if (bits & U_EFFECTS)
to->effects = MSG_ReadByte();
to->effects = (to->effects&0xff00)|MSG_ReadByte();
if (bits & U_ORIGIN1)
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();
}
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);
#ifdef HALFLIFEMODELS
if (to->frame != from->frame)
{
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
}
#endif
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].framechange = cl.time; //marked for hl models
#endif
cl.lerpents[to->number].lerptime = -10;
cl.lerpents[to->number].lerprate = 0;
@ -797,6 +804,7 @@ void DP5_ParseDelta(entity_state_t *s)
num = s->number;
*s = defaultstate;
s->trans = 255;
s->scale = 16;
s->number = num;
// s->active = true;
}
@ -936,6 +944,9 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
remove = !!(read&0x8000);
read&=~0x8000;
if (read >= MAX_EDICTS)
Host_EndGame("Too many entities.\n");
from = &defaultstate;
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->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];
pack->num_entities++;
@ -1114,6 +1130,12 @@ void CLNQ_ParseEntity(unsigned int bits)
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.
base = &cl_baselines[num];
@ -1553,6 +1575,8 @@ void CL_LinkPacketEntities (void)
ent->flags = s1->flags;
if (s1->effects & NQEF_ADDATIVE)
ent->flags |= Q2RF_ADDATIVE;
if (s1->effects & EF_NODEPTHTEST)
ent->flags |= RF_NODEPTHTEST;
// set colormap
if (s1->colormap && (s1->colormap <= MAX_CLIENTS)
@ -2146,6 +2170,15 @@ guess_pm_type:
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);
}
@ -2308,8 +2341,8 @@ void CL_LinkPlayers (void)
ent->model = cl.model_precache[state->modelindex];
ent->skinnum = state->skinnum;
ent->frame1time = cl.time - cl.lerpents[j].framechange;
ent->frame2time = cl.time - cl.lerpents[j].oldframechange;
ent->frame1time = cl.time - cl.lerpplayers[j].framechange;
ent->frame2time = cl.time - cl.lerpplayers[j].oldframechange;
ent->frame = state->frame;
ent->oldframe = state->oldframe;

View file

@ -573,6 +573,13 @@ void CL_CheckForResend (void)
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
if (connect_type || ((connect_tries&3)==3))
{
@ -833,6 +840,9 @@ void CL_ClearState (void)
Media_PlayFilm("");
}
if (cl.lerpents)
BZ_Free(cl.lerpents);
// wipe the entire cl structure
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.
{
Con_Printf ("d\n");
if (cls.demoplayback != DPB_NONE)
{
Con_Printf("Disconnect\n");
@ -2967,6 +2978,7 @@ void Host_Init (quakeparms_t *parms)
Cbuf_AddText ("exec hexen.rc\n", RESTRICT_LOCAL);
else
{ //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 config.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_KEEPINFO 16
#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.
@ -13,14 +14,17 @@ enum {
MT_MASTERHTTP, //an http/ftp based master server
MT_BCASTQW, //-1status
MT_BCASTQ2, //-1status
MT_BCASTQ3,
MT_BCASTNQ, //see code
MT_BCASTDP,
MT_SINGLEQW, //-1status
MT_SINGLEQ2, //-1status
MT_SINGLEQ3,
MT_SINGLENQ, //see code.
MT_SINGLEDP,
MT_MASTERQW, //c\n\0
MT_MASTERQ2, //query
MT_MASTERQ3,
MT_MASTERDP //-1getservers %s 3 empty full\x0A
};

View file

@ -589,6 +589,9 @@ void Model_NextDownload (void)
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())
return;
if (!Wad_NextDownload()) //world is required to be loaded.
@ -738,11 +741,11 @@ void CL_RequestNextDownload (void)
{
if (cl.downloadlist)
{
if (!COM_FCheckExists (cl.downloadlist->name))
if (!COM_FCheckExists (cl.downloadlist->localname))
CL_SendDownloadRequest(cl.downloadlist->name, cl.downloadlist->localname);
else
{
Con_Printf("Already have %s\n", cl.downloadlist->name);
Con_Printf("Already have %s\n", cl.downloadlist->localname);
CL_DisenqueDownload(cl.downloadlist->name);
}
return;

View file

@ -27,8 +27,6 @@ extern frame_t *view_frame;
#define MAX_PARSE_ENTITIES 1024
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;
@ -105,7 +103,6 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
{
int i, x, zd, zu;
trace_t trace;
int headnode;
float *angles;
entity_state_t *ent;
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];
if (!cmodel)
continue;
headnode = cmodel->hulls[0].firstclipnode;
angles = ent->angles;
}
else
@ -142,15 +138,15 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
bmins[2] = -zd;
bmaxs[2] = zu;
headnode = CM_HeadnodeForBox (bmins, bmaxs);
cmodel = CM_TempBoxModel (bmins, bmaxs);
angles = vec3_origin; // boxes don't rotate
}
if (tr->allsolid)
return;
trace = CM_TransformedBoxTrace (start, end,
mins, maxs, headnode, MASK_PLAYERSOLID,
trace = CM_TransformedBoxTrace (cmodel, start, end,
mins, maxs, MASK_PLAYERSOLID,
ent->origin, angles);
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;
// 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)
t.ent = (struct edict_s *)1;
@ -209,7 +205,7 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
model_t *cmodel;
int contents;
contents = CM_PointContents (point, 0);
contents = CM_PointContents (cl.worldmodel, point);
for (i=0 ; i<cl.q2frame.num_entities ; i++)
{
@ -223,7 +219,7 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
if (!cmodel)
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;
@ -347,7 +343,7 @@ void CL_NudgePosition (void)
vec3_t base;
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;
VectorCopy (pmove.origin, base);
@ -357,7 +353,7 @@ void CL_NudgePosition (void)
{
pmove.origin[0] = base[0] + x * 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;
}
}

View file

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

View file

@ -5,6 +5,202 @@
#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
#include "glquake.h"//hack
#else
@ -269,25 +465,8 @@ int VMEnumMods(char *match, int size, void *args)
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 {
q3refEntityType_t reType;
refEntityType_t reType;
int renderfx;
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));
ent.lerpfrac = q3->backlerp;
ent.alpha = 1;
ent.scale = 1;
switch(q3->reType)
{
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;
}
ent.scale = q3->radius;
ent.rtype = q3->reType;
ent.rotation = q3->rotation;
if (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)
ent.flags |= Q2RF_VIEWERMODEL;
VectorCopy(q3->origin, ent.origin);
VectorCopy(q3->oldorigin, ent.oldorigin);
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[2] = tr[2];
org[0] = tr[3];
ang[3] = tr[4];
ang[4] = tr[5];
ang[5] = tr[6];
org[1] = tr[7];
ang[6] = tr[8];
ang[7] = tr[9];
ang[8] = tr[10];
@ -526,15 +679,51 @@ void VQ3_RenderView(const q3refdef_t *ref)
#ifndef Q3CLIENT
typedef struct {
int handle;
int modificationCount;
float value;
int integer;
char string[256];
} vmcvar_t;
#endif
void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font)
{
char *in;
int i;
char name[MAX_QPATH];
#define readInt() LittleLong(*((int*)in)++)
#define readFloat() LittleFloat(*((float*)in)++)
_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
static
@ -555,13 +744,17 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
switch((ui_builtinnum_t)fn)
{
case UI_SYSERROR:
Sys_Error("%s", VM_POINTER(arg[0]));
case UI_ERROR:
Con_Printf("%s", VM_POINTER(arg[0]));
break;
case UI_PRINT:
Con_Printf("%s", VM_POINTER(arg[0]));
break;
case UI_MILLISECONDS:
VM_LONG(ret) = Sys_Milliseconds();
break;
case UI_CVAR_SET:
{
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
}
break;
case UI_CVAR_GET_VALUE:
case UI_CVAR_VARIABLEVALUE:
{
cvar_t *var;
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;
}
break;
case UI_CVAR_GET_STRING:
case UI_CVAR_VARIABLESTRINGBUFFER:
{
cvar_t *var;
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;
case UI_CVAR_SET_VALUE:
case UI_CVAR_SETVALUE:
Cvar_SetValue(Cvar_FindVar(VM_POINTER(arg[0])), VM_FLOAT(arg[1]));
break;
@ -616,7 +809,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
}
break;
case UI_CBUF_ADD_COMMAND:
case UI_CMD_EXECUTETEXT:
if (!strncmp(VM_POINTER(arg[1]), "ping ", 5))
{
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);
break;
case UI_FS_OPEN: //fopen
case UI_FS_FOPENFILE: //fopen
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
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;
case UI_FS_WRITE: //fwrite
break;
case UI_FS_CLOSE: //fclose
case UI_FS_FCLOSEFILE: //fclose
VMUI_fclose(VM_LONG(arg[0]), 0);
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)
break; //out of bounds.
{
@ -687,11 +880,14 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
}
break;
case UI_PRECACHE_MODEL: //precache model
VM_LONG(ret) = (int)Mod_ForName(VM_POINTER(arg[0]), false);
case UI_R_REGISTERMODEL: //precache model
{
char *name = VM_POINTER(arg[0]);
VM_LONG(ret) = (int)Mod_ForName(name, false);
}
break;
case UI_PRECACHE_SKIN:
case UI_R_REGISTERSKIN:
{
char *buf;
char *skinname = VM_POINTER(arg[0]);
@ -701,26 +897,30 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
}
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)
VM_LONG(ret) = 0;
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;
case UI_SCENE_CLEAR: //clear scene
case UI_R_CLEARSCENE: //clear scene
cl_numvisedicts=0;
break;
case UI_SCENE_ADD_ENTITY: //add ent to scene
case UI_R_ADDREFENTITYTOSCENE: //add ent to scene
VQ3_AddEntity(VM_POINTER(arg[0]));
break;
case UI_SCENE_ADD_LIGHT: //add light to scene.
case UI_R_ADDLIGHTTOSCENE: //add light to scene.
break;
case UI_SCENE_RENDER: //render scene
case UI_R_RENDERSCENE: //render scene
VQ3_RenderView(VM_POINTER(arg[0]));
break;
case UI_DRAW_COLOUR: //setcolour float*
case UI_R_SETCOLOR: //setcolour float*
if (Draw_ImageColours)
{
float *fl =VM_POINTER(arg[0]);
@ -731,19 +931,23 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
}
break;
case UI_DRAW_IMAGE:
case UI_R_DRAWSTRETCHPIC:
// qglDisable(GL_ALPHA_TEST);
// qglEnable(GL_BLEND);
// GL_TexEnv(GL_MODULATE);
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;
case UI_LERP_TAG: //Lerp tag...
case UI_CM_LERPTAG: //Lerp tag...
// tag, model, startFrame, endFrame, frac, tagName
if ((int)arg[0] + sizeof(float)*12 >= mask || VM_POINTER(arg[0]) < offset)
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]));
break;
case UI_SOUND_PRECACHE:
case UI_S_REGISTERSOUND:
{
sfx_t *sfx;
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;
}
break;
case UI_SOUND_PLAY:
if (VM_LONG(arg[0]) != -1)
case UI_S_STARTLOCALSOUND:
if (VM_LONG(arg[0]) != -1 && arg[0])
S_LocalSound(VM_LONG(arg[0])+(char *)offset);
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)
break; //out of bounds.
Q_strncpyz(VM_POINTER(arg[1]), Key_KeynumToString(VM_LONG(arg[0])), VM_LONG(arg[2]));
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)
break; //out of bounds.
@ -789,22 +993,20 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
}
break;
case 37:
break;
case 38:
break;
case UI_KEY_CLEARALL:
case UI_KEY_CLEARSTATES:
Key_ClearStates();
break;
case UI_KEY_GETDEST:
VM_LONG(ret) = keycatcher;
case UI_KEY_GETCATCHER:
if (key_dest == key_console)
VM_LONG(ret) = keycatcher | 1;
else
VM_LONG(ret) = keycatcher;
break;
case UI_KEY_SETDEST:
case UI_KEY_SETCATCHER:
keycatcher = VM_LONG(arg[0]);
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)
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);
break;
case UI_GET_CLIENT_STATE: //get client state
case UI_GETCLIENTSTATE: //get client state
//fixme: we need to fill in a structure.
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)
{
VM_LONG(ret) = 0;
break; //out of bounds.
}
switch(VM_LONG(arg[0]))
{
case 0:
Q_strncpyz(VM_POINTER(arg[1]), cl.serverinfo, VM_LONG(arg[2]));
break;
default:
*(char *)VM_POINTER(arg[1]) = 0;
}
Q_strncpyz(VM_POINTER(arg[1]), CG_GetConfigString(VM_LONG(arg[0])), VM_LONG(arg[2]));
break;
case UI_MS_GETSERVERCOUNT: //these four are master server polling.
case UI_LAN_GETPINGQUEUECOUNT: //these four are master server polling.
{
int 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)++;
}
break;
case UI_CLEAR_PINGS: //clear ping
case UI_LAN_CLEARPING: //clear ping
//void (int pingnum)
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
ui_pings[VM_LONG(arg[0])].type = NA_INVALID;
break;
case UI_GET_PINGADDRESS:
case UI_LAN_GETPING:
//void (int pingnum, char *buffer, int buflen, int *ping)
if ((int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
@ -876,7 +1071,7 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
strcpy(buf, "");
}
break;
case UI_GET_PINGINFO:
case UI_LAN_GETPINGINFO:
//void (int pingnum, char *buffer, int buflen, )
if ((int)arg[1] + VM_LONG(arg[2]) >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
@ -945,36 +1140,34 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
}
break;
case UI_MEM_AVAILABLE:
case UI_MEMORY_REMAINING:
VM_LONG(ret) = Hunk_LowMemAvailable();
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)
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;
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)
break; //out of bounds.
{
cvar_t *cvar;
cvar = Cvar_Get("cl_cdkey", "", 0, "Quake3 auth");
Cvar_Set(cvar, VM_POINTER(arg[0]));
}
break;
case UI_REGISTERFRONT: //register font
if (!Draw_SafeCachePic)
VM_LONG(ret) = 0;
else
VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0]));
break;
case UI_GET_REALTIME:
case UI_REAL_TIME:
VM_FLOAT(ret) = realtime;
break;
case UI_LAN_GET_COUNT: //LAN Get server count
case UI_LAN_GETSERVERCOUNT: //LAN Get server count
//int (int source)
VM_LONG(ret) = Master_TotalCount();
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)
if ((int)arg[2] + VM_LONG(arg[3]) >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds.
@ -995,14 +1188,23 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
strcpy(buf, "");
}
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;
case UI_VERIFYCDKEY:
case UI_VERIFY_CDKEY:
VM_LONG(ret) = true;
break;
case UI_SOMETHINGTODOWITHPUNKBUSTER:
case UI_SET_PBCLSTATUS:
break;
// standard Q3
@ -1011,10 +1213,10 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
break; //out of bounds.
memset(VM_POINTER(arg[0]), arg[1], arg[2]);
break;
case UI_MEMMOVE:
case UI_MEMCPY:
if ((int)arg[0] + arg[2] >= mask || VM_POINTER(arg[0]) < offset)
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;
case UI_STRNCPY:
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);
}
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:
Sys_Error("Q3UI: Not implemented system trap: %d\n", fn);
Con_Printf("Q3UI: Not implemented system trap: %d\n", fn);
return 0;
}
return ret;
@ -1212,7 +1432,7 @@ void UI_DrawMenu(void)
{
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)
key_dest = key_game;
}
@ -1257,7 +1477,7 @@ int UI_MenuState(void)
}
if (!uivm)
return false;
if (VM_Call(uivm, UI_FULLSCREEN))
if (VM_Call(uivm, UI_IS_FULLSCREEN))
return 2;
else if (keycatcher&2)
return 3;
@ -1272,16 +1492,16 @@ qboolean UI_KeyPress(int key, qboolean down)
// qboolean result;
if (!uivm)
return false;
if (key_dest == key_menu)
return false;
// if (key_dest == key_menu)
// return false;
if (!(keycatcher&2))
{
if (key == K_ESCAPE && down)
{
if (cls.state)
return VM_Call(uivm, 7, 2)>0;
return VM_Call(uivm, UI_SET_ACTIVE_MENU, 2)>0;
else
return VM_Call(uivm, 7, 1)>0;
return VM_Call(uivm, UI_SET_ACTIVE_MENU, 1)>0;
}
return false;
}
@ -1293,7 +1513,7 @@ qboolean UI_KeyPress(int key, qboolean 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();
return true;
@ -1318,8 +1538,8 @@ void UI_MousePosition(int xpos, int ypos)
ypos = vid.height;
ox=0;oy=0;
//force a cap
VM_Call(uivm, 4, -32767, -32767);
VM_Call(uivm, 4, (xpos-ox)*640/vid.width, (ypos-oy)*480/vid.height);
VM_Call(uivm, UI_MOUSE_DELTA, -32767, -32767);
VM_Call(uivm, UI_MOUSE_DELTA, (xpos-ox)*640/vid.width, (ypos-oy)*480/vid.height);
ox = xpos;
oy = ypos;
@ -1352,7 +1572,7 @@ void UI_Start (void)
apiversion = VM_Call(uivm, UI_GETAPIVERSION, UI_API_VERSION);
if (apiversion == UI_API_VERSION)
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);
VM_Destroy(uivm);
@ -1362,9 +1582,11 @@ void UI_Start (void)
}
VM_Call(uivm, UI_INIT);
VM_Call(uivm, 4, -32767, -32767);
VM_Call(uivm, UI_MOUSE_DELTA, -32767, -32767);
ox = 0;
oy = 0;
VM_Call(uivm, UI_SET_ACTIVE_MENU, 1);
}
}
@ -1376,9 +1598,9 @@ void UI_Restart_f(void)
if (uivm)
{
if (cls.state)
VM_Call(uivm, 7, 2);
VM_Call(uivm, UI_SET_ACTIVE_MENU, 2);
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 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
char downloadtempname[MAX_OSPATH];
char downloadname[MAX_OSPATH];
int downloadnumber;
dltype_t downloadtype;
int downloadpercent;
int downloadchunknum;
int downloadnumber; //file number
dltype_t downloadtype; //of type
// demo loop control
int demonum; // -1 = don't play demos
@ -437,7 +439,9 @@ typedef struct
// sentcmds[cl.netchan.outgoing_sequence & UPDATE_MASK] = cmd
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
int stats[MAX_SPLITS][MAX_CL_STATS]; // health, etc
@ -772,7 +776,7 @@ void CL_LinkProjectiles (void);
//clq3_parse.c
//
#ifdef Q3CLIENT
void CLQ3_SendClientCommand(const char *fmt, ...);
void VARGS CLQ3_SendClientCommand(const char *fmt, ...);
void CLQ3_SendConnectPacket(netadr_t to);
void CLQ3_SendCmd(usercmd_t *cmd);
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_Restart_f(void);
char *CG_GetConfigString(int num);
#endif
//

View file

@ -1645,6 +1645,119 @@ void BoostGamma(qbyte *rgba, int width, int height)
#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
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.
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--)
{
if (i == 1)

View file

@ -1223,9 +1223,14 @@ void Key_Event (int key, qboolean down)
#ifdef CSQC_DAT
//yes, csqc is allowed to steal the escape key.
if (key != '`' && key != '~')
if (key_dest == key_game)
{
if (CSQC_KeyPress(key, down)) //give csqc a chance to handle it.
return;
if (CG_KeyPress(key, down))
return;
}
#endif
//
@ -1234,7 +1239,7 @@ void Key_Event (int key, qboolean down)
if (key == K_ESCAPE)
{
#ifdef TEXTEDITOR
if (key_dest != key_editor)
if (key_dest == key_game)
#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.
@ -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 (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.
return;

View file

@ -1,7 +1,7 @@
#include "quakedef.h"
#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 DPF_HAVEAVERSION 1 //any old version
@ -13,7 +13,7 @@ extern char com_basedir[];
char *downloadablelist[256] = {
"http://127.0.0.1/downloadables.txt"
ROOTDOWNLOADABLESSOURCE
}; //note: these are allocated for the life of the exe
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)
{
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]))
{ //done downloading
FILE *f;
char basename[64];
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++;
if (downloadablelist[info->parsedsourcenum])
{
sprintf(basename, "../dlinfo_%i.inf", info->parsedsourcenum);
if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, NULL))
sprintf(basename, "dlinfo_%i.inf", info->parsedsourcenum);
if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, dlnotification))
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_hidedead = {"sb_hidedead", "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_hidequakeworld = {"sb_hidequakeworld", "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_hidedead, grp);
Cvar_Register(&sb_hidequake2, grp);
Cvar_Register(&sb_hidequake3, grp);
Cvar_Register(&sb_hidenetquake, 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
if (server->special & SS_QUAKE2)
return true;
#ifdef Q2CLIENT
if (sb_hidequake3.value)
#endif
if (server->special & SS_QUAKE3)
return true;
#ifdef NQPROT
if (sb_hidenetquake.value)
#endif
if (server->special & (SS_NETQUAKE|SS_DARKPLACES))
return true;
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;
if (sb_hideempty.value)
if (!server->players)
@ -368,6 +375,8 @@ void M_DrawServerList(void)
colour = COLOR_RED;
else if (server->special & SS_QUAKE2)
colour = COLOR_YELLOW;
else if (server->special & SS_QUAKE3)
colour = COLOR_BLUE;
else if (server->special & SS_NETQUAKE)
colour = COLOR_MAGENTA;
else
@ -474,7 +483,7 @@ void M_DrawSources (void)
}
}
#define NUMSLISTOPTIONS (7+7+4)
#define NUMSLISTOPTIONS (8+7+4)
struct {
char *title;
cvar_t *cvar;
@ -485,6 +494,7 @@ void M_DrawSources (void)
{"Hide Full", &sb_hidefull},
{"Hide Dead", &sb_hidedead},
{"Hide Quake 2", &sb_hidequake2},
{"Hide Quake 3", &sb_hidequake3},
{"Hide Quake 1", &sb_hidenetquake},
{"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_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_Think) (void);
@ -178,8 +176,6 @@ typedef struct {
void *(*Mod_Extradata) (struct model_s *mod); // handles caching
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_Think) (void);
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;
else if (!strcmp(com_token, "single:q2"))
servertype = MT_SINGLEQ2;
else if (!strcmp(com_token, "single:q3"))
servertype = MT_SINGLEQ3;
else if (!strcmp(com_token, "single:dp"))
servertype = MT_SINGLEDP;
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;
else if (!strcmp(com_token, "master:q2"))
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.
servertype = MT_MASTERQW;
@ -599,6 +603,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = MT_BCASTQW;
else if (!strcmp(com_token, "bcast:q2"))
servertype = MT_BCASTQ2;
else if (!strcmp(com_token, "bcast:q3"))
servertype = MT_BCASTQ3;
else if (!strcmp(com_token, "bcast:nq"))
servertype = MT_BCASTNQ;
else if (!strcmp(com_token, "bcast:dp"))
@ -610,6 +616,8 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
servertype = -MT_SINGLEQW;
else if (!strcmp(com_token, "favorite:q2"))
servertype = -MT_SINGLEQ2;
else if (!strcmp(com_token, "favorite:q3"))
servertype = -MT_SINGLEQ3;
else if (!strcmp(com_token, "favorite:nq"))
servertype = -MT_SINGLENQ;
else if (!strcmp(com_token, "favorite"))
@ -755,44 +763,51 @@ int NET_CheckPollSockets(void)
if (*(int *)net_message.data == -1)
{
int c;
#ifdef Q2CLIENT
char *s;
#endif
MSG_BeginReading ();
MSG_ReadLong (); // skip the -1
#ifdef Q2CLIENT
c = msg_readcount;
s = MSG_ReadStringLine(); //peek for q2 messages.
#ifdef Q2CLIENT
if (!strcmp(s, "print"))
{
CL_ReadServerInfo(MSG_ReadString(), MT_SINGLEQ2, false);
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);
continue;
}
else if (!strncmp(s, "getserversResponse\\", 19)) //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...
if (!strncmp(s, "servers", 6)) //parse a bit more...
{
msg_readcount = c+7;
CL_MasterListParse(SS_QUAKE2, false);
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);
continue;
}
msg_readcount = c;
#endif
c = MSG_ReadByte ();
@ -970,6 +985,19 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles)
return;
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
case MT_BCASTQ2:
case MT_SINGLEQ2:
@ -1050,6 +1078,9 @@ void MasterInfo_WriteServers(void)
case MT_MASTERQ2:
typename = "master:q2";
break;
case MT_MASTERQ3:
typename = "master:q3";
break;
case MT_MASTERDP:
typename = "master:dp";
break;
@ -1059,6 +1090,9 @@ void MasterInfo_WriteServers(void)
case MT_BCASTQ2:
typename = "bcast:q2";
break;
case MT_BCASTQ3:
typename = "bcast:q3";
break;
case MT_BCASTNQ:
typename = "bcast:nq";
break;
@ -1068,6 +1102,9 @@ void MasterInfo_WriteServers(void)
case MT_SINGLEQ2:
typename = "single:q2";
break;
case MT_SINGLEQ3:
typename = "single:q3";
break;
case MT_SINGLENQ:
typename = "single:nq";
break;
@ -1088,7 +1125,9 @@ void MasterInfo_WriteServers(void)
{
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);
else if (server->special & SS_NETQUAKE)
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("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)
@ -1158,7 +1203,9 @@ void Master_QueryServer(serverinfo_t *server)
char data[2048];
server->sends--;
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);
else if (server->special & SS_NETQUAKE)
{
@ -1300,6 +1347,11 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite)
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->adr = net_from;
@ -1322,6 +1374,8 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite)
nl++;
}
name = Info_ValueForKey(msg, "hostname");
if (!*name)
name = Info_ValueForKey(msg, "sv_hostname");
Q_strncpyz(info->name, name, sizeof(info->name));
info->special = info->special & (SS_FAVORITE | SS_KEEPINFO); //favorite is never cleared
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))
info->special |= SS_FTESERVER;
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)
info->special |= SS_QUAKE2;
else if (servertype == MT_SINGLEQ3)
info->special |= SS_QUAKE3;
else if (servertype == MT_SINGLENQ)
info->special |= SS_NETQUAKE;
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->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->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)
{
moveclip_t clip;
@ -1455,7 +1454,7 @@ static int CS_PointContents(vec3_t org)
{
if (!cl.worldmodel)
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)
{

View file

@ -1528,7 +1528,7 @@ glEnable(GL_DEPTH_TEST);
else
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)
{
@ -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)
{
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)
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)
{
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)
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)
{
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)
{
@ -4192,6 +4192,8 @@ void P_DrawParticles (void)
if (qglPolygonOffset)
qglPolygonOffset(-1, 0);
qglEnable(GL_POLYGON_OFFSET_FILL);
qglEnable(GL_BLEND);
qglDisable(GL_ALPHA_TEST);
qglBegin(GL_QUADS);
if (r_drawflat.value == 2)
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;
} 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
{
@ -77,6 +89,9 @@ typedef struct entity_s
int flags;
refEntityType_t rtype;
float rotation;
#ifdef Q3SHADERS
struct shader_s *forcedshader;
#endif
@ -263,9 +278,7 @@ struct model_s *GLMod_FindName (char *name);
void *GLMod_Extradata (struct model_s *mod); // handles caching
void GLMod_TouchModel (char *name);
struct mleaf_s *GLMod_PointInLeaf (float *p, struct model_s *model);
qbyte *GLMod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
qbyte *GLMod_LeafnumPVS (int leafnum, struct model_s *model, qbyte *buffer);
struct mleaf_s *GLMod_PointInLeaf (struct model_s *model, float *p);
void GLMod_Think (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_TouchModel (char *name);
struct mleaf_s *SWMod_PointInLeaf (float *p, struct model_s *model);
qbyte *SWMod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
struct mleaf_s *SWMod_PointInLeaf (struct model_s *model, float *p);
void SWMod_Think (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"};
extern cvar_t gl_dither;
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_detailscale = {"gl_detailscale", "5"};
@ -276,6 +278,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_motionblurscale, GLRENDEREROPTIONS);
Cvar_Register (&gl_max_size, GLRENDEREROPTIONS);
Cvar_Register (&gl_maxdist, GLRENDEREROPTIONS);
Cvar_Register (&gl_mindist, GLRENDEREROPTIONS);
Cvar_Register (&vid_conwidth, 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_bias, GRAPHICALNICETIES);
Cvar_Register (&gl_bloom, GRAPHICALNICETIES);
Cvar_Register (&gl_contrast, GLRENDEREROPTIONS);
#ifdef R_XFLIP
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_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_Think) (void);
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_TouchModel,
SWMod_PointInLeaf,
SWMod_LeafPVS,
SWMod_NowLoadExternal,
SWMod_Think,
#elif defined(RGLQUAKE)
@ -705,8 +706,6 @@ rendererinfo_t dedicatedrendererinfo = {
GLMod_Extradata,
GLMod_TouchModel,
GLMod_PointInLeaf,
GLMod_LeafPVS,
GLMod_NowLoadExternal,
GLMod_Think,
#else
@ -803,8 +802,6 @@ rendererinfo_t softwarerendererinfo = {
SWMod_Extradata,
SWMod_TouchModel,
SWMod_PointInLeaf,
SWMod_LeafPVS,
SWMod_NowLoadExternal,
SWMod_Think,
@ -902,8 +899,6 @@ rendererinfo_t openglrendererinfo = {
GLMod_Extradata,
GLMod_TouchModel,
GLMod_PointInLeaf,
GLMod_LeafPVS,
GLMod_NowLoadExternal,
GLMod_Think,
@ -1283,8 +1278,6 @@ void R_SetRenderer(int wanted)
Mod_Extradata = ri->Mod_Extradata;
Mod_TouchModel = ri->Mod_TouchModel;
Mod_PointInLeaf = ri->Mod_PointInLeaf;
Mod_Q1LeafPVS = ri->Mod_Q1LeafPVS;
Mod_NowLoadExternal = ri->Mod_NowLoadExternal;
Mod_GetTag = ri->Mod_GetTag;

View file

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

View file

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

View file

@ -462,7 +462,7 @@ qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha)//r
//extern model_t *loadmodel;
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;
char key[128];
@ -478,13 +478,13 @@ void Mod_ParseInfoFromEntityLump(const char *data) //actually, this should be in
if (!data)
return;
if (!(data=COM_ParseToken(data))) //read the map info.
if (!(data=COM_Parse(data))) //read the map info.
return; // error
if (com_token[0] != '{')
return; // error
while (1)
{
if (!(data=COM_ParseToken(data)))
if (!(data=COM_Parse(data)))
return; // error
if (com_token[0] == '}')
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.
else
strcpy(key, com_token);
if (!((data=COM_ParseToken(data))))
if (!((data=COM_Parse(data))))
return; // error
if (!strcmp("wad", key)) // for HalfLife maps
{

View file

@ -94,6 +94,6 @@ void SwapPic (qpic_t *pic);
void Mod_ParseWadsFromEntityLump(char *data);
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);
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 MD2MODELS //quake2 alias models
#define MD3MODELS //quake3 alias models
#define MD5MODELS //doom3 models
#define ZYMOTICMODELS //zymotic skeletal models.
// #define MD5MODELS //doom3 models
// #define ZYMOTICMODELS //zymotic skeletal models.
#define HUFFNETWORK //huffman network compression
#define HALFLIFEMODELS //halflife model support (experimental)
// #define DOOMWADS //doom wad/map/sprite support
//#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet)
#define Q2BSPS //quake 2 bsp support
#define Q3BSPS //quake 3 bsp support
#define TERRAIN //heightmap support
#define SV_MASTER //starts up a master server
#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.
@ -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 TEXTEDITOR
#define PPL //per pixel lighting (stencil shadowing)
#define DDS //a sort of image file format.
#define PLUGINS
@ -184,9 +186,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef RUNTIMELIGHTING
#undef PLUGINS //we don't have any server side stuff.
#undef Q3SHADERS
#undef TERRAIN
#endif
#ifdef CLIENTONLY //remove optional server componants that make no sence on a client only build.
#undef Q2SERVER
#undef Q3SERVER
#undef WEBSERVER
#endif
@ -198,6 +202,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef Q3BSPS
#undef R_XFLIP
#undef RUNTIMELIGHTING
#undef TERRAIN
#undef Q3CLIENT
#endif
#endif
@ -207,6 +213,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if !defined(Q3BSPS)
#undef Q3SHADERS
#undef Q3CLIENT //reconsider this (later)
#undef Q3SERVER //reconsider this (later)
#endif
#ifndef Q3CLIENT
@ -215,7 +222,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define VM_CG
#endif
#if defined(VM_UI) || defined(VM_CG) || defined(PLUGINS)
#if defined(VM_UI) || defined(VM_CG) || defined(Q3SERVER) || defined(PLUGINS)
#define VM_ANY
#endif
@ -312,7 +319,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// 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_MODELS 512 // these are sent over the net as bytes
#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);
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);
return;
}
@ -1849,7 +1849,7 @@ const char *If_Token(const char *func, const char **end)
while(*func <= ' ' && *func)
func++;
s = COM_ParseToken(func);
s = COM_ParseToken(func, NULL);
if (*com_token == '(')
{
@ -1884,7 +1884,7 @@ const char *If_Token(const char *func, const char **end)
}
else if (!strcmp(com_token, "defined")) //functions
{
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
var = Cvar_FindVar(com_token);
*end = s;
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.
{
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
#ifndef SERVERONLY
if (qrenderer == QR_NONE)
s2 = "";
@ -1926,10 +1926,10 @@ const char *If_Token(const char *func, const char **end)
*end = s;
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
if (!strcmp(com_token, "=")) //comparisions
{
func=COM_ParseToken(s);
func=COM_ParseToken(s, NULL);
if (*com_token == '=') //lol. "=" == "=="
return retfloat(!strcmp(s2, If_Token(func, end)));
else
@ -1939,7 +1939,7 @@ const char *If_Token(const char *func, const char **end)
return retfloat(!strcmp(s2, If_Token(s, end)));
if (!strcmp(com_token, "!"))
{
func=COM_ParseToken(s);
func=COM_ParseToken(s, NULL);
if (*com_token == '=')
{
s = If_Token(func, end);
@ -1957,7 +1957,7 @@ const char *If_Token(const char *func, const char **end)
}
if (!strcmp(com_token, ">"))
{
func=COM_ParseToken(s);
func=COM_ParseToken(s, NULL);
if (*com_token == '=')
return retfloat(atof(s2)>=atof(If_Token(func, end)));
else if (*com_token == '<')//vb?
@ -1977,7 +1977,7 @@ const char *If_Token(const char *func, const char **end)
}
if (!strcmp(com_token, "<"))
{
func=COM_ParseToken(s);
func=COM_ParseToken(s, NULL);
if (*com_token == '=')
return retfloat(atof(s2)<=atof(If_Token(func, end)));
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)));
if (!strcmp(com_token, "&")) //and
{
func=COM_ParseToken(s);
func=COM_ParseToken(s, NULL);
if (*com_token == '&')
return retfloat(*s2&&*If_Token(s, end));
else
@ -2006,7 +2006,7 @@ const char *If_Token(const char *func, const char **end)
}
if (!strcmp(com_token, "|")) //or
{
func=COM_ParseToken(s);
func=COM_ParseToken(s, NULL);
if (*com_token == '|')
{
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_ParseCString (char *data);
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);
@ -259,6 +259,7 @@ char *VARGS va(char *format, ...);
//============================================================================
extern int com_file_copyprotected;
extern int com_filesize;
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_CreatePath (char *path);
void COM_Gamedir (char *dir);
void FS_ForceToPure(char *str, char *crcs, int seed);
char *COM_GetPathInfo (int i, int *crc);
char *COM_NextPath (char *prevpath);
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);
extern struct cvar_s registered;
extern qboolean standard_quake, rogue, hipnotic;
extern qboolean standard_quake; //fixme: remove
#define MAX_INFO_KEY 64
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);
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];
@ -270,9 +271,6 @@ q2mapsurface_t *map_surfaces;
int numplanes;
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
mleaf_t map_leafs[MAX_MAP_LEAFS];
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 r_subdivisions = {"r_subdivisions", "2"};
int CM_NumInlineModels (void);
int CM_NumInlineModels (model_t *model);
q2cmodel_t *CM_InlineModel (char *name);
void CM_InitBoxHull (void);
void FloodAreaConnections (void);
@ -1451,12 +1449,10 @@ void CMod_LoadNodes (lump_t *l)
if (count > MAX_MAP_NODES)
Host_Error ("Map has too many nodes");
out = map_nodes;
numnodes = count;
out = Hunk_Alloc(sizeof(mnode_t)*count);
loadmodel->nodes = out;
loadmodel->numnodes = numnodes;
loadmodel->numnodes = count;
for (i=0 ; i<count ; i++, out++, in++)
{
@ -1481,7 +1477,7 @@ void CMod_LoadNodes (lump_t *l)
if (child < 0)
out->children[j] = (mnode_t *)(map_leafs + -1-child);
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))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
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)
Host_Error("Too many nodes on map");
numnodes = count;
loadmodel->nodes = out;
loadmodel->numnodes = count;
@ -3238,7 +3232,7 @@ void CMQ3_CalcPHS (void)
vcount = 0;
for (i=0 ; i<numclusters ; i++)
{
scan = CM_ClusterPVS ( i, NULL );
scan = CM_ClusterPVS (sv.worldmodel, i, NULL);
for (j=0 ; j<numclusters ; j++)
{
if ( scan[j>>3] & (1<<(j&7)) )
@ -3282,14 +3276,9 @@ void CMQ3_CalcPHS (void)
, 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);
}
int CM_ModelPointLeafnum (vec3_t p, model_t *mdl)
{
return CM_PointLeafnum(p);
return CM_ClusterPVS(model, CM_LeafCluster(model, leafnum), buffer);
}
#ifndef SERVERONLY
@ -3420,9 +3409,9 @@ void SWR_Q2BSP_StainNode (mnode_t *node, float *parms)
#endif
void Q2BSP_FatPVS (vec3_t org, qboolean add);
qboolean Q2BSP_EdictInFatPVS(edict_t *ent);
void Q2BSP_FindTouchedLeafs(edict_t *ent);
void Q2BSP_FatPVS (model_t *mod, vec3_t org, qboolean add);
qboolean Q2BSP_EdictInFatPVS(model_t *mod, 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 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
numplanes = 0;
numnodes = 0;
numleafs = 0;
numcmodels = 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.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
#if defined(RGLQUAKE)
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;
#endif
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
#ifndef SERVERONLY
//light grid info
@ -3675,8 +3664,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.StainNode = NULL;
loadmodel->funcs.MarkLights = NULL;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
break;
#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.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
break;
#endif
#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.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafForPoint = CM_ModelPointLeafnum;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
break;
#endif
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;
@ -3858,41 +3850,41 @@ q2cmodel_t *CM_InlineModel (char *name)
return &map_cmodels[num];
}
int CM_NumClusters (void)
int CM_NumClusters (model_t *model)
{
return numclusters;
}
int CM_ClusterSize (void)
int CM_ClusterSize (model_t *model)
{
return map_q3pvs->rowsize ? map_q3pvs->rowsize : MAX_MAP_LEAFS / 8;
}
int CM_NumInlineModels (void)
int CM_NumInlineModels (model_t *model)
{
return numcmodels;
}
char *CM_EntityString (void)
char *CM_EntityString (model_t *model)
{
return map_entitystring;
}
int CM_LeafContents (int leafnum)
int CM_LeafContents (model_t *model, int leafnum)
{
if (leafnum < 0 || leafnum >= numleafs)
Host_Error ("CM_LeafContents: bad number");
return map_leafs[leafnum].contents;
}
int CM_LeafCluster (int leafnum)
int CM_LeafCluster (model_t *model, int leafnum)
{
if (leafnum < 0 || leafnum >= numleafs)
Host_Error ("CM_LeafCluster: bad number");
return map_leafs[leafnum].cluster;
}
int CM_LeafArea (int leafnum)
int CM_LeafArea (model_t *model, int leafnum)
{
if (leafnum < 0 || leafnum >= numleafs)
Host_Error ("CM_LeafArea: bad number");
@ -3932,15 +3924,14 @@ void CM_InitBoxHull (void)
box_model.funcs.MarkLights = Q2BSP_MarkLights;
#endif
box_model.funcs.LeafPVS = CM_LeafnumPVS;
box_model.funcs.LeafForPoint = CM_ModelPointLeafnum;
box_model.funcs.LeafnumForPoint = CM_PointLeafnum;
box_model.hulls[0].available = true;
Q2BSP_SetHullFuncs(&box_model.hulls[0]);
box_headnode = numnodes;
box_model.nodes = Hunk_Alloc(sizeof(mnode_t)*6);
box_planes = &map_planes[numplanes];
if (numnodes+6 > MAX_MAP_NODES
|| numbrushes+1 > MAX_Q2MAP_BRUSHES
if (numbrushes+1 > MAX_Q2MAP_BRUSHES
|| numleafbrushes+1 > MAX_Q2MAP_LEAFBRUSHES
|| numbrushsides+6 > MAX_Q2MAP_BRUSHSIDES
|| numplanes+12 > MAX_Q2MAP_PLANES)
@ -3968,7 +3959,7 @@ void CM_InitBoxHull (void)
s->surface = &nullsurface;
// nodes
c = &map_nodes[box_headnode+i];
c = &box_model.nodes[i];
c->plane = map_planes + (numplanes+i*2);
c->childnum[side] = -1 - emptyleaf;
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.
===================
*/
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[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[10].dist = mins[2];
box_planes[11].dist = -mins[2];
return box_headnode;
}
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;
}
@ -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;
mnode_t *node;
@ -4038,7 +4027,7 @@ int CM_PointLeafnum_r (vec3_t p, int num)
while (num >= 0)
{
node = map_nodes + num;
node = mod->nodes + num;
plane = node->plane;
if (plane->type < 3)
@ -4056,11 +4045,11 @@ int CM_PointLeafnum_r (vec3_t p, int num)
return -1 - num;
}
int CM_PointLeafnum (vec3_t p)
int CM_PointLeafnum (model_t *mod, vec3_t p)
{
if (!numplanes)
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;
int leaf_topnode;
void CM_BoxLeafnums_r (int nodenum)
void CM_BoxLeafnums_r (model_t *mod, int nodenum)
{
mplane_t *plane;
mnode_t *node;
@ -4094,7 +4083,7 @@ void CM_BoxLeafnums_r (int nodenum)
return;
}
node = &map_nodes[nodenum];
node = &mod->nodes[nodenum];
plane = node->plane;
// s = BoxOnPlaneSide (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
if (leaf_topnode == -1)
leaf_topnode = nodenum;
CM_BoxLeafnums_r (node->childnum[0]);
CM_BoxLeafnums_r (mod, node->childnum[0]);
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_count = 0;
@ -4123,7 +4112,7 @@ int CM_BoxLeafnums_headnode (vec3_t mins, vec3_t maxs, int *list, int listsize,
leaf_topnode = -1;
CM_BoxLeafnums_r (headnode);
CM_BoxLeafnums_r (mod, headnode);
if (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;
}
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,
listsize, map_cmodels[0].headnode, topnode);
return CM_BoxLeafnums_headnode (mod, mins, maxs, list,
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)
int CM_PointContents (vec3_t p, int headnode)
int CM_PointContents (model_t *mod, vec3_t p)
{
int i, j, contents;
mleaf_t *leaf;
q2cbrush_t *brush;
q2cbrushside_t *brushside;
if (!numnodes) // map not loaded
if (!mod) // map not loaded
return 0;
i = CM_PointLeafnum_r (p, headnode);
i = CM_PointLeafnum_r (mod, p, mod->hulls[0].firstclipnode);
if (!mapisq3)
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
==================
*/
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 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);
}
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;
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
// and the offset for the size of the box
//
node = map_nodes + num;
node = mod->nodes + num;
plane = node->plane;
if (plane->type < 3)
@ -4781,12 +4770,12 @@ return;
// see which sides we need to consider
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;
}
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;
}
@ -4822,7 +4811,7 @@ return;
for (i=0 ; i<3 ; 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
@ -4835,7 +4824,7 @@ return;
for (i=0 ; i<3 ; 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
==================
*/
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,
int headnode, int brushmask)
int brushmask)
{
int i;
#if ADJ
@ -4868,7 +4857,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
trace_trace.fraction = 1;
trace_trace.surface = &(nullsurface.c);
if (!numnodes) // map not loaded
if (!mod) // map not loaded
return trace_trace;
trace_contents = brushmask;
@ -4921,7 +4910,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
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++)
{
CM_TestInLeaf (leafs[i]);
@ -4970,7 +4959,7 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end,
//
// 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)
{
@ -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)
{
*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;
}
@ -5010,9 +4999,9 @@ rotating entities
#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,
int headnode, int brushmask,
int brushmask,
vec3_t origin, vec3_t angles)
{
trace_t trace;
@ -5027,7 +5016,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
VectorSubtract (end, origin, end_l);
// rotate start and end into the models frame of reference
if (headnode != box_headnode &&
if (mod != &box_model &&
(angles[0] || angles[1] || angles[2]) )
rotated = true;
else
@ -5049,7 +5038,7 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end,
}
// 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)
{
@ -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)
buffer = pvsrow;
@ -5220,7 +5209,7 @@ qbyte *CM_ClusterPVS (int cluster, qbyte *buffer)
return buffer;
}
qbyte *CM_ClusterPHS (int cluster)
qbyte *CM_ClusterPHS (model_t *mod, int cluster)
{
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)
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
=================
*/
int CM_WriteAreaBits (qbyte *buffer, int area)
int CM_WriteAreaBits (model_t *mod, qbyte *buffer, int area)
{
int i;
int floodnum;
@ -5406,7 +5395,7 @@ int CM_WriteAreaBits (qbyte *buffer, int area)
{
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);
}
}
@ -5459,7 +5448,7 @@ Returns true if any leaf under headnode has a cluster that
is potentially visible
=============
*/
qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits)
qboolean CM_HeadnodeVisible (model_t *mod, int nodenum, qbyte *visbits)
{
int leafnum;
int cluster;
@ -5476,13 +5465,13 @@ qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits)
return false;
}
node = &map_nodes[nodenum];
if (CM_HeadnodeVisible(node->childnum[0], visbits))
node = &mod->nodes[nodenum];
if (CM_HeadnodeVisible(mod, node->childnum[0], visbits))
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)
{
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)
return true;
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;
pc = CM_PointContents (p, hull->firstclipnode);
pc = CM_PointContents (mod, p);
if (pc & (Q2CONTENTS_SOLID|Q2CONTENTS_WINDOW))
ret |= FTECONTENTS_SOLID;
if (pc & Q2CONTENTS_LAVA)
@ -5510,7 +5499,7 @@ int Q2BSP_HullPointContents(hull_t *hull, vec3_t p)
}
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);
Matrix4_Multiply(proj, modelview, tempm);
Matrix4x4_Invert_Simple(proj, tempm);
Matrix4x4_Invert_Simple((void*)proj, (void*)tempm);
{
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));
}
}
/*
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)
{
// Cmd_AddCommand("testvm", VM_Test_f);
Cvar_Register(&plug_sbar, "plugins");
Cvar_Register(&plug_loaddefault, "plugins");
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 (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)
{
pmove.onladder = true;

View file

@ -85,17 +85,14 @@ hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs)
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;
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
if (hull != &box_hull &&
(angles[0] || angles[1] || angles[2]) )
if (angles[0] || angles[1] || angles[2])
{
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);
}
return hull->funcs.HullPointContents(hull, p_l);
return mod->funcs.PointContents(mod, p_l);
}
/*
==================
PM_PointContents
@ -116,19 +114,21 @@ PM_PointContents
*/
int PM_PointContents (vec3_t p)
{
hull_t *hull;
int num;
int pc;
physent_t *pe;
model_t *pm;
hull = &pmove.physents[0].model->hulls[0];
pc = hull->funcs.HullPointContents(hull, p);
pm = pmove.physents[0].model;
pc = pm->funcs.PointContents(pm, p);
//we need this for e2m2 - waterjumping on to plats wouldn't work otherwise.
for (num = 1; num < pmove.numphysent; num++)
{
if (pmove.physents[num].model)
pc |= PM_TransformedHullPointContents(&pmove.physents[num].model->hulls[0], p, pmove.physents[num].origin, pmove.physents[num].angles);
pe = &pmove.physents[num];
pm = pe->model;
if (pm)
pc |= PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles);
}
return pc;
@ -218,13 +218,13 @@ PM_TestPlayerPosition
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)
{
int i;
physent_t *pe;
vec3_t mins, maxs;
hull_t *hull;
trace_t trace;
for (i=0 ; i< pmove.numphysent ; i++)
{
@ -233,28 +233,36 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
// get the clipping hull
if (pe->model)
{
/*
#ifdef Q2BSPS
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)
return false;
continue;
}
#endif
hull = &pe->model->hulls[pmove.hullnum];
#endif*/
/* hull = &pe->model->hulls[pmove.hullnum];
if (!hull->available || !hull->planes || !hull->clipnodes)
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
{
VectorSubtract (pe->mins, player_maxs, mins);
VectorSubtract (pe->maxs, player_mins, maxs);
hull = PM_HullForBox (mins, maxs);
}
VectorSubtract(pos, pe->origin, mins);
if (PM_TransformedHullPointContents (hull, pos, pe->origin, pe->angles) & FTECONTENTS_SOLID)
return false;
if (Q1BSP_HullPointContents(hull, mins) & FTECONTENTS_SOLID)
return false;
// if (PM_TransformedHullPointContents (hull, pos, pe->origin, pe->angles) & FTECONTENTS_SOLID)
// return false;
}
}
return true;

View file

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

View file

@ -1,5 +1,6 @@
#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)
{
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)
@ -823,7 +829,7 @@ extern int fatbytes;
extern qbyte fatpvs[(MAX_MAP_LEAFS+1)/4];
//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;
qbyte *pvs;
@ -837,7 +843,7 @@ void SV_Q1BSP_AddToFatPVS (vec3_t org, mnode_t *node)
{
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++)
fatpvs[i] |= pvs[i];
}
@ -852,7 +858,7 @@ void SV_Q1BSP_AddToFatPVS (vec3_t org, mnode_t *node)
node = node->children[1];
else
{ // go down both
SV_Q1BSP_AddToFatPVS (org, node->children[0]);
SV_Q1BSP_AddToFatPVS (mod, org, node->children[0]);
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.
=============
*/
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)
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;
@ -935,18 +941,158 @@ void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node)
if (sides & 2)
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;
if (ent->v->modelindex)
Q1BSP_RFindTouchedLeafs (ent, sv.worldmodel->nodes);
Q1BSP_RFindTouchedLeafs (ent, mod->nodes);
}
#endif
/*
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->bp += 15*4;
if(qvm->bp!=qvm->max_bp)
Sys_Error("VM run time error: freed too much stack\n");
// if(qvm->bp!=qvm->max_bp)
// Sys_Error("VM run time error: freed too much stack\n");
param = qvm->sp[0];
POP(1);
return param;

View file

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

View file

@ -48,6 +48,7 @@ void Plug_DrawReloadImages(void);
//these things are specific to FTE QuakeWorld
void UI_Init (void);
void UI_Restart_f(void);
void UI_Stop (void);
qboolean UI_Q2LayoutChanged(void);
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
CFG=gas2masm - Win32 Release
CFG=gas2masm - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
@ -13,11 +13,10 @@ CFG=gas2masm - Win32 Release
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "gas2masm.mak" CFG="gas2masm - Win32 Release"
!MESSAGE NMAKE /f "gas2masm.mak" CFG="gas2masm - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "gas2masm - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "gas2masm - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
@ -27,33 +26,6 @@ CFG=gas2masm - Win32 Release
# PROP Scc_LocalPath ""
CPP=cl.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_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
@ -75,12 +47,8 @@ BSC32=bscmake.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 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
# Name "gas2masm - Win32 Release"
# Name "gas2masm - Win32 Debug"
# Begin Group "Source Files"

View file

@ -210,7 +210,6 @@ void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
}
#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)
{
galiasinfo_t *mod = Mod_Extradata(model);
@ -1800,7 +1799,7 @@ void R_DrawGAliasModel (entity_t *e)
mb.shader = currententity->forcedshader;
mb.fog = fog;
mb.mesh = &mesh;
mb.infokey = currententity->keynum;
mb.infokey = -1;//currententity->keynum;
mb.dlightbits = 0;
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.fog = fog;
mb.mesh = &mesh;
mb.infokey = currententity->keynum;
mb.infokey = -1;//currententity->keynum;
mb.dlightbits = 0;
R_IBrokeTheArrays();
@ -2420,12 +2419,12 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum,
while(f)
{
f = COM_ParseToken(f);
f = COM_ParseToken(f,NULL);
if (!f)
return;
if (!strcmp(com_token, "replace"))
{
f = COM_ParseToken(f);
f = COM_ParseToken(f, NULL);
len = strlen(com_token);
@ -2436,7 +2435,7 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum,
//found it
{
surfname+=len;
f = COM_ParseToken(f);
f = COM_ParseToken(f, NULL);
p = com_token;
while(*p) //copy the replacement
*out++ = *p++;
@ -2460,7 +2459,7 @@ void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum,
if (!strcmp(com_token, surfname))
{
f++;
COM_ParseToken(f);
COM_ParseToken(f, NULL);
strcpy(out, com_token);
return;
}
@ -2680,22 +2679,27 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
}
}
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);
//but only preload it if we have no replacement.
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);
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);
}
}
else
texnums = Hunk_Alloc(sizeof(*texnums));
outskin->texnums=1;
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)
return false;
if (frame1 < 0 || frame1 >= inf->numtagframes)
if (frame1 < 0)
return false;
if (frame1 >= inf->numtagframes)
frame1 = inf->numtagframes - 1;
if (frame2 < 0 || frame2 >= inf->numtagframes)
frame2 = frame1;
tagnum--; //tagnum 0 is 'use my angles/org'

View file

@ -16,6 +16,11 @@ typedef struct {
} gl_state_t;
gl_state_t gl_state;
void GL_SetShaderState2D(qboolean is2d)
{
gl_state.in2d = is2d;
}
extern int *lightmap_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
@ -1032,11 +1063,11 @@ R_VertexTCBase
void R_VertexTCBase ( int tcgen, int unit )
{
int i;
vec3_t t, n;
// vec3_t t, n;
float *outCoords;
vec3_t transform;
mat3_t inverse_axis;
mat3_t axis;
// vec3_t transform;
// mat3_t inverse_axis;
// mat3_t axis;
outCoords = tUnitCoordsArray[unit][0];
qglTexCoordPointer( 2, GL_FLOAT, 0, outCoords );
@ -1050,6 +1081,11 @@ void R_VertexTCBase ( int tcgen, int unit )
}
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 )
{
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[1] = t[1]*n[2] - n[1];
}
*/
}
else if ( tcgen == TC_GEN_VECTOR )
{
@ -1117,16 +1154,19 @@ R_ShaderpassTex
*/
int R_ShaderpassTex ( shaderpass_t *pass )
{
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_LIGHTMAP) && r_lmtex >= 0 )
if (pass->flags & (SHADER_PASS_ANIMMAP|SHADER_PASS_LIGHTMAP|SHADER_PASS_DELUXMAP))
{
return lightmap_textures[r_lmtex];
}
else if ( (pass->flags & SHADER_PASS_DELUXMAP) && r_lmtex >= 0 )
{
return deluxmap_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_LIGHTMAP) && r_lmtex >= 0 )
{
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;
@ -1718,6 +1758,11 @@ void R_SetShaderpassState ( shaderpass_t *pass, qboolean mtex )
qglDepthMask ( GL_FALSE );
}
}
else
{
qglDepthFunc ( GL_ALWAYS );
qglDepthMask ( GL_FALSE );
}
}
/*

View file

@ -65,6 +65,7 @@ extern cvar_t gl_load24bit;
#ifdef Q3SHADERS
extern cvar_t gl_blend2d;
shader_t *shader_console;
#endif
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_RenderMeshBuffer ( &mb, false );
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
@ -1697,6 +1754,17 @@ void GLDraw_ConsoleBackground (int lines)
conback->height>>=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)
{
qglColor3f (1,1,1);
@ -1829,6 +1897,14 @@ void GLDraw_FadeScreen (void)
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);
}
@ -1926,6 +2002,8 @@ Setup as if the screen was 320*200
*/
void GL_Set2D (void)
{
GL_SetShaderState2D(true);
qglViewport (glx, gly, glwidth, glheight);
qglMatrixMode(GL_PROJECTION);
@ -1971,8 +2049,17 @@ void GL_Set2D (void)
{
int newtex = 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;
}
else
#endif
if (!*gl_conback.string || !(newtex=Mod_LoadHiResTexture(gl_conback.string, "conbacks", false, true, true)))
{
conback = default_conback;
}
else
{
conback = custom_conback;
@ -2004,6 +2091,8 @@ void GL_Set2D (void)
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);
frac = outwidth*fracstep;
j=outwidth-4;
while (j&3)
j=outwidth-1;
while ((j+1)&3)
{
out[j] = inrow[frac>>16];
frac -= fracstep;

View file

@ -81,15 +81,10 @@ void GLMod_LoadDoomSprite (model_t *mod);
#define MAX_MOD_KNOWN 2048
#ifndef SWQUAKE
qbyte mod_novis[MAX_MAP_LEAFS/8];
model_t mod_known[MAX_MOD_KNOWN];
int mod_numknown;
#else
extern qbyte mod_novis[MAX_MAP_LEAFS/8];
extern model_t mod_known[MAX_MOD_KNOWN];
extern int mod_numknown;
#endif
@ -206,7 +201,7 @@ Mod_Init
void GLMod_Init (void)
{
mod_numknown = 0;
memset (mod_novis, 0xff, sizeof(mod_novis));
Q1BSP_Init();
Cmd_AddRemCommand("mod_texturelist", GLMod_TextureList_f);
Cmd_AddRemCommand("mod_usetexture", GLMod_BlockTextureColour_f);
@ -215,7 +210,6 @@ void GLMod_Init (void)
void GLMod_Shutdown (void)
{
mod_numknown = 0;
memset (mod_novis, 0xff, sizeof(mod_novis));
Cmd_RemoveCommand("mod_texturelist");
Cmd_RemoveCommand("mod_usetexture");
@ -252,10 +246,7 @@ void *GLMod_Extradata (model_t *mod)
Mod_PointInLeaf
===============
*/
#ifdef Q2BSPS
int CM_PointLeafnum (vec3_t p);
#endif
mleaf_t *GLMod_PointInLeaf (vec3_t p, model_t *model)
mleaf_t *GLMod_PointInLeaf (model_t *model, vec3_t p)
{
mnode_t *node;
float d;
@ -270,7 +261,7 @@ mleaf_t *GLMod_PointInLeaf (vec3_t p, model_t *model)
#ifdef Q2BSPS
if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3)
{
return model->leafs + CM_PointLeafnum(p);
return model->leafs + CM_PointLeafnum(model, p);
}
#endif
if (model->fromgame == fg_doom)
@ -294,103 +285,6 @@ mleaf_t *GLMod_PointInLeaf (vec3_t p, model_t *model)
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
@ -690,17 +584,22 @@ couldntload:
GLMod_LoadMD5MeshModel (mod, buf);
break;
}
else if (!strcmp(com_token, "EXTERNALANIM"))
if (!strcmp(com_token, "EXTERNALANIM"))
{
GLMod_LoadCompositeAnim (mod, buf);
break;
}
else
#endif
#ifdef TERRAIN
if (!strcmp(com_token, "terrain"))
{
Con_Printf("Unrecognised model format %i\n", LittleLong(*(unsigned *)buf));
goto couldntload;
GL_LoadHeightmapModel(mod, buf);
break;
}
#endif
Con_Printf("Unrecognised model format %i\n", LittleLong(*(unsigned *)buf));
goto couldntload;
}
P_DefaultTrail(mod);
@ -740,14 +639,14 @@ qbyte *mod_base;
#endif
char *advtexturedesc;
const char *mapsection;
const char *defaultsection;
char *mapsection;
char *defaultsection;
static const char *GLMod_TD_LeaveSection(const char *file)
static char *GLMod_TD_LeaveSection(char *file)
{ //recursive routine to find the next }
while(file)
{
file = COM_ParseToken(file);
file = COM_Parse(file);
if (*com_token == '{')
file = GLMod_TD_LeaveSection(file);
else if (*com_token == '}')
@ -756,7 +655,7 @@ static const char *GLMod_TD_LeaveSection(const char *file)
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.
while(file)
{
@ -766,10 +665,10 @@ static const char *GLMod_TD_Section(const char *file, const char *sectionname)
return NULL;
file++;
}
file = COM_ParseToken(file);
file = COM_Parse(file);
if (!stricmp(com_token, sectionname))
{
file = COM_ParseToken(file);
file = COM_Parse(file);
if (*com_token != '{')
return NULL;
return file;
@ -799,7 +698,7 @@ void GLMod_InitTextureDescs(char *mapname)
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 flatname[MAX_QPATH] = "";
@ -812,7 +711,7 @@ void GLMod_LoadAdvancedTextureSection(const char *section, char *name, int *base
while(section)
{
section = COM_ParseToken(section);
section = COM_Parse(section);
if (*com_token == '}')
break;
@ -827,34 +726,34 @@ void GLMod_LoadAdvancedTextureSection(const char *section, char *name, int *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));
}
else if (!stricmp(com_token, "flatmap") || !stricmp(com_token, "flat")
|| !stricmp(com_token, "diffusemap") || !stricmp(com_token, "diffuse"))
{
section = COM_ParseToken(section);
section = COM_Parse(section);
Q_strncpyz(flatname, com_token, sizeof(flatname));
}
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));
}
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));
}
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));
}
else if (!stricmp(com_token, "luma") || !stricmp(com_token, "glow")
|| !stricmp(com_token, "ambient") || !stricmp(com_token, "ambientmap"))
{
section = COM_ParseToken(section);
section = COM_Parse(section);
Q_strncpyz(lumaname, com_token, sizeof(lumaname));
}
else
@ -978,7 +877,9 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
mt->offsets[j] = LittleLong (mt->offsets[j]);
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;
tx = Hunk_AllocName (sizeof(texture_t)/* +pixels*/, loadname );
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_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);
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);
}
Q1BSP_SetModelFuncs(mod);
mod->funcs.LightPointValues = GLQ1BSP_LightPointValues;
mod->funcs.StainNode = Q1BSP_StainNode;
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

View file

@ -30,22 +30,25 @@ struct edict_s;
typedef struct {
// 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;
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 (*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);
qboolean (*EdictInFatPVS) (struct edict_s *edict);
void (*FindTouchedLeafs_Q1) (struct edict_s *ent); //edict system as opposed to q2 game dll system.
void (*FatPVS) (struct model_s *model, vec3_t org, qboolean add);
qboolean (*EdictInFatPVS) (struct model_s *model, struct edict_s *edict);
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 (*StainNode) (struct mnode_s *node, float *parms);
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
qbyte *(*LeafPVS) (int num, struct model_s *model, qbyte *buffer);
int (*LeafForPoint) (vec3_t point, struct model_s *model);
qbyte *(*LeafPVS) (struct model_s *model, int num, qbyte *buffer);
int (*LeafnumForPoint) (struct model_s *model, vec3_t point);
} bspfuncs_t;
typedef int index_t;
@ -102,7 +105,9 @@ m*_t structures are in-memory
#define EF_BLUE 64
#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_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_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);
qboolean Q1BSP_EdictInFatPVS(struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct edict_s *ent);
void Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct edict_s *ent);
void Q1BSP_FindTouchedLeafs(struct model_s *mod, struct edict_s *ent);
/*
==============================================================================
@ -660,7 +668,7 @@ typedef struct {
// 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)
#define EF_ROCKET 1 // leave a trail
@ -776,7 +784,7 @@ typedef struct model_s
q3lightgridinfo_t *lightgrid;
char *entities;
struct terrain_s *terrain;
void *terrain;
unsigned checksum;
unsigned checksum2;
@ -827,26 +835,27 @@ qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
void CM_Init(void);
qboolean CM_SetAreaPortalState (int portalnum, qboolean open);
qboolean CM_HeadnodeVisible (int nodenum, qbyte *visbits);
qboolean VARGS CM_AreasConnected (int area1, int area2);
int CM_NumClusters (void);
int CM_ClusterSize (void);
int CM_LeafContents (int leafnum);
int CM_LeafCluster (int leafnum);
int CM_LeafArea (int leafnum);
int CM_WriteAreaBits (qbyte *buffer, int area);
int CM_PointLeafnum (vec3_t p);
qbyte *CM_ClusterPVS (int cluster, qbyte *buffer);
qbyte *CM_ClusterPHS (int cluster);
int CM_BoxLeafnums (vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
int CM_PointContents (vec3_t p, int headnode);
struct trace_s CM_BoxTrace (vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int headnode, int brushmask);
int CM_HeadnodeForBox (vec3_t mins, vec3_t maxs);
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);
qboolean CM_SetAreaPortalState (struct model_s *mod, int portalnum, qboolean open);
qboolean CM_HeadnodeVisible (struct model_s *mod, int nodenum, qbyte *visbits);
qboolean VARGS CM_AreasConnected (struct model_s *mod, int area1, int area2);
int CM_NumClusters (struct model_s *mod);
int CM_ClusterSize (struct model_s *mod);
int CM_LeafContents (struct model_s *mod, int leafnum);
int CM_LeafCluster (struct model_s *mod, int leafnum);
int CM_LeafArea (struct model_s *mod, int leafnum);
int CM_WriteAreaBits (struct model_s *mod, qbyte *buffer, int area);
int CM_PointLeafnum (struct model_s *mod, vec3_t p);
qbyte *CM_ClusterPVS (struct model_s *mod, int cluster, qbyte *buffer);
qbyte *CM_ClusterPHS (struct model_s *mod, int cluster);
int CM_BoxLeafnums (struct model_s *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
int CM_PointContents (struct model_s *mod, vec3_t p);
int CM_TransformedPointContents (struct model_s *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles);
struct trace_s CM_BoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask);
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);
void Mod_ParseInfoFromEntityLump(const char *data);
void Mod_ParseInfoFromEntityLump(char *data);
void VARGS CMQ2_SetAreaPortalState (int portalnum, qboolean open);
#endif

View file

@ -1905,6 +1905,8 @@ void PPL_BaseEntTextures(void)
if (!PPL_ShouldDraw())
continue;
if (currententity->rtype)
continue;
if (currententity->flags & Q2RF_BEAM)
{
R_DrawBeam(currententity);
@ -4364,13 +4366,13 @@ qboolean PPL_AddLight(dlight_t *dl)
else
{
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
i = r_viewleaf - cl.worldmodel->leafs;
leaf = cl.worldmodel->funcs.LeafForPoint(dl->origin, cl.worldmodel);
lvis = cl.worldmodel->funcs.LeafPVS(leaf, cl.worldmodel, lvisb);
vvis = cl.worldmodel->funcs.LeafPVS(i, cl.worldmodel, vvisb);
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb);
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.
// return;

View file

@ -24,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef RGLQUAKE
#include "glquake.h"
#ifdef Q3SHADERS
#include "shader.h"
#endif
void R_RenderBrushPoly (msurface_t *fa);
#define PROJECTION_DISTANCE 200
@ -34,8 +38,6 @@ extern int gl_canstencil;
PFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
PFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
extern struct mleaf_s *GLMod_PointInLeaf (float *p, struct model_s *model);
#define Q2RF_WEAPONMODEL 4 // only draw through eyes
#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_dither = {"gl_dither", "1"};
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_motionblurscale;
@ -151,10 +156,12 @@ int scenepp_ww_parm_texture1i;
int scenepp_ww_parm_texture2i;
int scenepp_ww_parm_ampscalef;
int scenepp_bloom_program;
// 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
// processing shaders
void GL_InitSceneProcessingShaders (void)
void GL_InitSceneProcessingShaders_WaterWarp (void)
{
char *genericvert = "\
varying vec2 v_texCoord0;\
@ -219,6 +226,40 @@ void GL_InitSceneProcessingShaders (void)
if (qglGetError())
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_AMP_TEX_SIZE 64
@ -468,40 +509,98 @@ void R_DrawSpriteModel (entity_t *e)
vec3_t forward, right, up;
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
// polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = currententity->model->cache.data;
psprite = e->model->cache.data;
// frame = 0x05b94140;
if (psprite->type == SPR_ORIENTED)
{ // bullet marks on walls
AngleVectors (currententity->angles, forward, right, up);
}
else if (psprite->type == SPR_FACING_UPRIGHT)
switch(psprite->type)
{
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;
right[0] = e->origin[1] - r_origin[1];
right[1] = -(e->origin[0] - r_origin[0]);
right[2] = 0;
VectorNormalize (right);
}
else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT)
{
break;
case SPR_VP_PARALLEL_UPRIGHT:
up[0] = 0;up[1] = 0;up[2]=1;
VectorCopy (vright, right);
}
else
{ // normal sprite
break;
default:
case SPR_VP_PARALLEL:
//normal sprite
VectorCopy(vup, up);
VectorCopy(vright, right);
break;
}
up[0]*=currententity->scale;
up[1]*=currententity->scale;
up[2]*=currententity->scale;
right[0]*=currententity->scale;
right[1]*=currententity->scale;
right[2]*=currententity->scale;
up[0]*=e->scale;
up[1]*=e->scale;
up[2]*=e->scale;
right[0]*=e->scale;
right[1]*=e->scale;
right[2]*=e->scale;
qglColor4f (1,1,1, e->alpha);
@ -566,6 +665,7 @@ void R_DrawSpriteModel (entity_t *e)
qglDisable(GL_BLEND);
qglDisable (GL_ALPHA_TEST);
qglEnable(GL_DEPTH_TEST);
if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us!
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -762,6 +862,25 @@ void GLR_DrawEntitiesOnList (void)
{
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 (currententity->flags & Q2RF_WEAPONMODEL)
@ -776,7 +895,16 @@ void GLR_DrawEntitiesOnList (void)
if (!Cam_DrawPlayer(0, currententity->keynum-1))
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)
{
R_DrawBeam(currententity);
@ -801,7 +929,7 @@ void GLR_DrawEntitiesOnList (void)
switch (currententity->model->type)
{
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);
break;
@ -812,12 +940,19 @@ void GLR_DrawEntitiesOnList (void)
#endif
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);
break;
case mod_sprite:
RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
break;
#ifdef TERRAIN
case mod_heightmap:
GL_DrawHeightmapModel(currententity);
break;
#endif
default:
break;
@ -1175,7 +1310,7 @@ void GLR_SetupFrame (void)
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
leaf = GLMod_PointInLeaf (r_origin, cl.worldmodel);
leaf = GLMod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcluster = r_viewcluster2 = leaf->cluster;
// check above and below so crossing solid water doesn't draw wrong
@ -1185,7 +1320,7 @@ void GLR_SetupFrame (void)
VectorCopy (r_origin, temp);
temp[2] -= 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel);
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster;
@ -1196,7 +1331,7 @@ void GLR_SetupFrame (void)
VectorCopy (r_origin, temp);
temp[2] += 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel);
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster;
@ -1210,7 +1345,7 @@ void GLR_SetupFrame (void)
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
r_viewleaf = GLMod_PointInLeaf (r_origin, cl.worldmodel);
r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin);
if (!r_viewleaf)
{
@ -1219,7 +1354,7 @@ void GLR_SetupFrame (void)
{ //look down a bit
VectorCopy (r_origin, temp);
temp[2] -= 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel);
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA)
r_viewleaf2 = leaf;
else
@ -1230,7 +1365,7 @@ void GLR_SetupFrame (void)
VectorCopy (r_origin, temp);
temp[2] += 16;
leaf = GLMod_PointInLeaf (temp, cl.worldmodel);
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents == Q1CONTENTS_EMPTY)
r_viewleaf2 = leaf;
else
@ -1393,11 +1528,11 @@ void R_SetupGL (void)
// 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;
// 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
{
GL_InfinatePerspective(r_refdef.fov_y, screenaspect, 4);
GL_InfinatePerspective(r_refdef.fov_y, screenaspect, gl_mindist.value);
}
}
else
@ -2088,6 +2223,8 @@ void GLR_RenderView (void)
*/
r_alpha_surfaces = NULL;
GL_SetShaderState2D(false);
// render normal view
R_RenderScene ();
GLR_DrawViewModel ();
@ -2119,7 +2256,7 @@ void GLR_RenderView (void)
// SCENE POST PROCESSING
// we check if we need to use any shaders - currently it's just waterwarp
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 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
// the size determined by the edge texture, after which black bits will be shown.
// 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())
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_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

View file

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

View file

@ -73,7 +73,7 @@ qbyte FloatToByte( float x )
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
@ -974,6 +974,8 @@ static void Shader_MakeCache ( char *path )
if ( !token[0] || ptr - buf >= size )
break;
COM_CleanUpPath(token);
t = NULL;
Shader_GetPathAndOffset ( token, &t, &i );
if ( t ) {
@ -1921,6 +1923,8 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*))
COM_StripExtension ( name, shortname );
COM_CleanUpPath(shortname);
// test if already loaded
for (i = 0; i < MAX_SHADERS; i++)
{

View file

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

View file

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

View file

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

View file

@ -156,14 +156,13 @@ void LightLoadEntities(char *entstring)
{
int cont;
vec3_t v;
hull_t *hull = &lightmodel->hulls[0];
v[0] = mapent->origin[0];
v[1] = mapent->origin[1];
cont=0;
for (i = 0; i < 256; i+=16)
{
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))
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
{ //write it
IWebFWrite(con->buffer, con->chunked, 1, con->file);
IWebFWrite(con->buffer, con->bufferused, 1, con->file);
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 *gf;
@ -403,7 +402,7 @@ IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb");
return ret;
}
if (file_from_pak==2)
if (com_file_copyprotected)
{
char *buffer;
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])
{
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
ip[0] = atoi(com_token);
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
if (*com_token != ',')
return false;
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
ip[1] = atoi(com_token);
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
if (*com_token != ',')
return false;
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
ip[2] = atoi(com_token);
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
if (*com_token != ',')
return false;
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
ip[3] = atoi(com_token);
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
if (*com_token != ',')
return false;
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
port[0] = atoi(com_token);
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
if (*com_token != ',')
return false;
s = COM_ParseToken(s);
s = COM_ParseToken(s, NULL);
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");
strncpy(QCC_copyright, msg, sizeof(QCC_copyright)-1);
}
else if (!strncmp(directive, "forcecrc", 8))
{
ForcedCRC = atoi(msg);
}
else if (!QC_strcasecmp(qcc_token, "TARGET"))
{
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
VectorAdd (ent->v->origin, ent->v->view_ofs, org);
leaf = sv.worldmodel->funcs.LeafForPoint(org, sv.worldmodel);
checkpvs = sv.worldmodel->funcs.LeafPVS (leaf, sv.worldmodel, checkpvsbuffer);
leaf = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org);
checkpvs = sv.worldmodel->funcs.LeafPVS (sv.worldmodel, leaf, checkpvsbuffer);
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
self = PROG_TO_EDICT(prinst, pr_global_struct->self);
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)) ) )
{
c_notvis++;
@ -2959,6 +2959,7 @@ void PF_stuffcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals)
cl = &svs.clients[entnum-1];
if (strcmp(str, "disconnect\n") == 0)
{
// so long and thanks for all the fish
@ -6119,7 +6120,11 @@ lh_extension_t QSG_Extensions[] = {
{"DP_QUAKE3_MODEL"},
{"DP_REGISTERCVAR", 1, NULL, {"registercvar"}},
{"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_DROPCLIENT"},
{"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_SETCOLOR"},
@ -9533,6 +9538,8 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldfloat(style);
fieldfloat(pflags);
fieldfloat(clientcolors);
//UDC_EXTEFFECT... yuckie
PR_RegisterFieldVar(svprogfuncs, ev_float, "fieldcolor", (int)&((entvars_t*)0)->seefcolour, -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 style;
float pflags;
float clientcolors;
//EXT_DIMENSION_VISIBLE
float dimension_see;

View file

@ -105,6 +105,7 @@ extern progsnum_t svmainprogs;
extern progsnum_t clmainprogs;
#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 Q3EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q3serverEntity_t,area)
extern func_t SpectatorConnect;
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;
int version;
char modellist[MAX_QPATH][MAX_MODELS];
char soundlist[MAX_QPATH][MAX_SOUNDS];
int current_skill;
int clnum;
@ -591,6 +594,42 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
PR_RegisterFields();
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);
fseek(f, 0, SEEK_END);
filelen = ftell(f);
@ -617,6 +656,9 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
{
ent = EDICT_NUM(svprogfuncs, i+1);
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)
@ -758,6 +800,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
// write the light styles
fprintf (f, "%i\n",MAX_LIGHTSTYLES);
for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
{
if (sv.lightstyles[i])
@ -766,6 +809,23 @@ void SV_SaveLevelCache(qboolean dontharmgame)
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);
fprintf(f, "%s\n", s);
svprogfuncs->parms->memfree(s);

View file

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

View file

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

View file

@ -47,7 +47,7 @@ qbyte fatpvs[(MAX_MAP_LEAFS+1)/4];
#ifdef Q2BSPS
void SV_Q2BSP_FatPVS (vec3_t org)
void SV_Q2BSP_FatPVS (model_t *mod, vec3_t org)
{
int leafs[64];
int i, j, count;
@ -61,20 +61,20 @@ void SV_Q2BSP_FatPVS (vec3_t org)
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)
Sys_Error ("SV_Q2FatPVS: count < 1");
if (sv.worldmodel->fromgame == fg_quake3)
longs = CM_ClusterSize();
longs = CM_ClusterSize(mod);
else
longs = (CM_NumClusters()+31)>>5;
longs = (CM_NumClusters(mod)+31)>>5;
// convert leafs to clusters
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);
@ -86,7 +86,7 @@ void SV_Q2BSP_FatPVS (vec3_t org)
break;
if (j != i)
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++)
((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 )
bits |= U_FRAME;
if ( (to->effects&255) != (from->effects&255) )
if ( (to->effects&0x00ff) != (from->effects&0x00ff) )
bits |= U_EFFECTS;
if ( (to->effects&0xff00) != (from->effects&0xff00) )
evenmorebits |= U_EFFECTS16;
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)
MSG_WriteByte (msg, to->skinnum);
if (bits & U_EFFECTS)
MSG_WriteByte (msg, to->effects);
MSG_WriteByte (msg, to->effects&0x00ff);
if (bits & U_ORIGIN1)
MSG_WriteCoord (msg, to->origin[0]);
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->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++)
{
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 (!isbot || progstype == PROG_QW) //unless they're NQ bots...
continue;
@ -1803,13 +1808,8 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size
continue;
// ignore if not touching a PV leaf
for (i=0 ; i < ent->num_leafs ; i++)
if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
break;
if (i == ent->num_leafs)
{
continue; // not visible
}
if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent))
continue;
if (!((int)clent->v->dimension_see & ((int)ent->v->dimension_seen | (int)ent->v->dimension_ghost)))
continue; //not in this dimension - sorry...
@ -2194,29 +2194,29 @@ qboolean SV_GibFilter(edict_t *ent)
#ifdef Q2BSPS
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;
leafnum = CM_PointLeafnum (org);
clientarea = CM_LeafArea (leafnum);
leafnum = CM_PointLeafnum (mod, org);
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;
if (!CM_AreasConnected (clientarea, ent->areanum))
if (!CM_AreasConnected (mod, clientarea, ent->areanum))
{ // doors can legally straddle two areas, so
// we may need to check another one
if (!ent->areanum2
|| !CM_AreasConnected (clientarea, ent->areanum2))
|| !CM_AreasConnected (mod, clientarea, ent->areanum2))
return false; // blocked by a door
}
if (ent->num_leafs == -1)
{ // too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->headnode, fatpvs))
if (!CM_HeadnodeVisible (mod, ent->headnode, fatpvs))
return false;
}
else
@ -2274,14 +2274,14 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
clent = client->edict;
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
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
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)
{
@ -2492,12 +2492,12 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
{
p = EDICT_NUM(svprogfuncs, p->v->tag_entity);
}
if (!sv.worldmodel->funcs.EdictInFatPVS(p))
if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, p))
continue;
}
else
{
if (!sv.worldmodel->funcs.EdictInFatPVS(ent))
if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent))
continue;
}
}
@ -2698,7 +2698,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
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;

View file

@ -373,7 +373,7 @@ void SV_CalcPHS (void)
vcount = 0;
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);
if (i == 0)
continue;
@ -665,6 +665,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
sv.worldmodel = Mod_ForName (sv.modelname, true);
if (sv.worldmodel->needload)
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;
#ifndef SERVERONLY
@ -1057,7 +1059,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
else
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
SV_FindModelNumbers ();
@ -1131,6 +1134,43 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
current_loading_size+=10;
SCR_BeginLoadingPlaque();
#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

View file

@ -390,33 +390,47 @@ void SV_DropClient (client_t *drop)
#ifdef SVCHAT
SV_WipeChat(drop);
#endif
#ifdef Q2SERVER
if (ge && drop->protocol == SCP_QUAKE2)
ge->ClientDisconnect(drop->q2edict);
#endif
if (svprogfuncs)
switch(svs.gametype)
{
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);
}
}
#ifdef Q3SERVER
case GT_QUAKE3:
SVQ3_DropClient(drop);
break;
#endif
if (drop->spawninfo)
Z_Free(drop->spawninfo);
drop->spawninfo = NULL;
#ifdef Q2SERVER
case GT_QUAKE2:
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)
@ -3508,17 +3522,18 @@ void SV_ExtractFromUserinfo (client_t *cl)
{
int top = atoi(Info_ValueForKey(cl->userinfo, "topcolor"));
int bottom = atoi(Info_ValueForKey(cl->userinfo, "bottomcolor"));
int playercolor;
top &= 15;
if (top > 13)
top = 13;
bottom &= 15;
if (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, cl-svs.clients);
MSG_WriteByte (&sv.nqreliable_datagram, playercolor);
MSG_WriteByte (&sv.nqreliable_datagram, cl->playercolor);
}
#endif
}

View file

@ -141,6 +141,24 @@ qboolean SV_RunThink (edict_t *ent)
{
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
{
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)
{
leafnum = CM_PointLeafnum (origin);
area1 = CM_LeafArea (leafnum);
leafnum = CM_PointLeafnum (sv.worldmodel, origin);
area1 = CM_LeafArea (sv.worldmodel, leafnum);
}
else
{
@ -493,17 +493,17 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
case MULTICAST_PHS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PHS:
leafnum = CM_PointLeafnum (origin);
cluster = CM_LeafCluster (leafnum);
mask = CM_ClusterPHS (cluster);
leafnum = CM_PointLeafnum (sv.worldmodel, origin);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
mask = CM_ClusterPHS (sv.worldmodel, cluster);
break;
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
leafnum = CM_PointLeafnum (origin);
cluster = CM_LeafCluster (leafnum);
mask = CM_ClusterPVS (cluster, NULL);
leafnum = CM_PointLeafnum (sv.worldmodel, origin);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
mask = CM_ClusterPVS (sv.worldmodel, cluster, NULL);
break;
default:
@ -532,13 +532,13 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
{
#ifdef Q2SERVER
if (ge)
leafnum = CM_PointLeafnum (client->q2edict->s.origin);
leafnum = CM_PointLeafnum (sv.worldmodel, client->q2edict->s.origin);
else
#endif
leafnum = CM_PointLeafnum (client->edict->v->origin);
cluster = CM_LeafCluster (leafnum);
area2 = CM_LeafArea (leafnum);
if (!CM_AreasConnected (area1, area2))
leafnum = CM_PointLeafnum (sv.worldmodel, client->edict->v->origin);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area2 = CM_LeafArea (sv.worldmodel, leafnum);
if (!CM_AreasConnected (sv.worldmodel, area1, area2))
continue;
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
continue;
@ -588,11 +588,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
else
#endif
{
leaf = Mod_PointInLeaf (origin, sv.worldmodel);
if (!leaf)
leafnum = 0;
else
leafnum = leaf - sv.worldmodel->leafs;
leafnum = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, origin);
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))
continue;
leaf = Mod_PointInLeaf (client->edict->v->origin, sv.worldmodel);
if (leaf)
leafnum = sv.worldmodel->funcs.LeafnumForPoint (sv.worldmodel, client->edict->v->origin);
{
// -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)) ) )
{
// Con_Printf ("supressed multicast\n");
@ -1459,13 +1454,56 @@ void SV_UpdateToReliableMessages (void)
int i, j;
client_t *client, *sp;
edict_t *ent;
char *name;
// 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++)
{
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 && 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)
{

View file

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

View file

@ -57,7 +57,7 @@ void Mod_Init (void)
Mod_LeafForPoint
===============
*/
int Mod_LeafForPoint (vec3_t p, model_t *model)
int Mod_LeafForPoint (model_t *model, vec3_t p)
{
mnode_t *node;
float d;
@ -65,7 +65,7 @@ int Mod_LeafForPoint (vec3_t p, model_t *model)
#ifdef Q2BSPS
if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3)
{
return CM_PointLeafnum(p);
return CM_PointLeafnum(model, p);
}
#endif
if (!model || !model->nodes)
@ -92,9 +92,9 @@ int Mod_LeafForPoint (vec3_t p, model_t *model)
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->funcs.FatPVS = Q1BSP_FatPVS;
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;
Q1BSP_SetModelFuncs(mod);
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++)
org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
leafnum = CM_PointLeafnum (org);
clientarea = CM_LeafArea (leafnum);
clientcluster = CM_LeafCluster (leafnum);
leafnum = CM_PointLeafnum (sv.worldmodel, org);
clientarea = CM_LeafArea (sv.worldmodel, leafnum);
clientcluster = CM_LeafCluster (sv.worldmodel, leafnum);
// calculate the visible areas
areabytes = CM_WriteAreaBits (areabits, clientarea);
areabytes = CM_WriteAreaBits (sv.worldmodel, areabits, clientarea);
// grab the current player_state_t
frame->ps = clent->client->ps;
SV_Q2BSP_FatPVS (org);
clientphs = CM_ClusterPHS (clientcluster);
sv.worldmodel->funcs.FatPVS(sv.worldmodel, org, false);
clientphs = CM_ClusterPHS (sv.worldmodel, clientcluster);
// build up the list of visible entities
frame->num_entities = 0;
@ -674,11 +674,11 @@ void SV_BuildClientFrame (client_t *client)
if (ent != clent)
{
// check area
if (!CM_AreasConnected (clientarea, ent->areanum))
if (!CM_AreasConnected (sv.worldmodel, clientarea, ent->areanum))
{ // doors can legally straddle two areas, so
// we may need to check another one
if (!ent->areanum2
|| !CM_AreasConnected (clientarea, ent->areanum2))
|| !CM_AreasConnected (sv.worldmodel, clientarea, ent->areanum2))
continue; // blocked by a door
}
@ -698,7 +698,7 @@ void SV_BuildClientFrame (client_t *client)
if (ent->num_clusters == -1)
{ // too many leafs for individual check, go by headnode
if (!CM_HeadnodeVisible (ent->headnode, bitvector))
if (!CM_HeadnodeVisible (sv.worldmodel, ent->headnode, bitvector))
continue;
c_fullsend++;
}

View file

@ -343,17 +343,17 @@ static qboolean VARGS PFQ2_inPVS (vec3_t p1, vec3_t p2)
int area1, area2;
qbyte *mask;
leafnum = CM_PointLeafnum (p1);
cluster = CM_LeafCluster (leafnum);
area1 = CM_LeafArea (leafnum);
mask = CM_ClusterPVS (cluster, NULL);
leafnum = CM_PointLeafnum (sv.worldmodel, p1);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area1 = CM_LeafArea (sv.worldmodel, leafnum);
mask = CM_ClusterPVS (sv.worldmodel, cluster, NULL);
leafnum = CM_PointLeafnum (p2);
cluster = CM_LeafCluster (leafnum);
area2 = CM_LeafArea (leafnum);
leafnum = CM_PointLeafnum (sv.worldmodel, p2);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area2 = CM_LeafArea (sv.worldmodel, leafnum);
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
return false;
if (!CM_AreasConnected (area1, area2))
if (!CM_AreasConnected (sv.worldmodel, area1, area2))
return false; // a door blocks sight
return true;
}
@ -373,22 +373,27 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2)
int area1, area2;
qbyte *mask;
leafnum = CM_PointLeafnum (p1);
cluster = CM_LeafCluster (leafnum);
area1 = CM_LeafArea (leafnum);
mask = CM_ClusterPHS (cluster);
leafnum = CM_PointLeafnum (sv.worldmodel, p1);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area1 = CM_LeafArea (sv.worldmodel, leafnum);
mask = CM_ClusterPHS (sv.worldmodel, cluster);
leafnum = CM_PointLeafnum (p2);
cluster = CM_LeafCluster (leafnum);
area2 = CM_LeafArea (leafnum);
leafnum = CM_PointLeafnum (sv.worldmodel, p2);
cluster = CM_LeafCluster (sv.worldmodel, leafnum);
area2 = CM_LeafArea (sv.worldmodel, leafnum);
if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) )
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 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_ATTENUATION (1<<1) // a byte
@ -682,7 +687,7 @@ qboolean SVQ2_InitGameProgs(void)
import.DebugGraph = Q2SCR_DebugGraph;
import.SetAreaPortalState = CMQ2_SetAreaPortalState;
import.AreasConnected = CM_AreasConnected;
import.AreasConnected = PFQ2_AreasConnected;
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
void Q2BSP_FindTouchedLeafs(edict_t *ent)
void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent)
{
#define MAX_TOTAL_ENT_LEAFS 128
int leafs[MAX_TOTAL_ENT_LEAFS];
@ -310,14 +310,14 @@ void Q2BSP_FindTouchedLeafs(edict_t *ent)
ent->areanum2 = 0;
//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);
// set areas
for (i=0 ; i<num_leafs ; i++)
{
clusters[i] = CM_LeafCluster (leafs[i]);
area = CM_LeafArea (leafs[i]);
clusters[i] = CM_LeafCluster (model, leafs[i]);
area = CM_LeafArea (model, leafs[i]);
if (area)
{ // doors may legally straggle two areas,
// 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
sv.worldmodel->funcs.FindTouchedLeafs_Q1(ent);
sv.worldmodel->funcs.FindTouchedLeafs_Q1(sv.worldmodel, ent);
/*
#ifdef Q2BSPS
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;
//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);
// set areas
for (i=0 ; i<num_leafs ; i++)
{
clusters[i] = CM_LeafCluster (leafs[i]);
area = CM_LeafArea (leafs[i]);
clusters[i] = CM_LeafCluster (sv.worldmodel, leafs[i]);
area = CM_LeafArea (sv.worldmodel, leafs[i]);
if (area)
{ // doors may legally straggle two areas,
// but nothing should evern need more than that
@ -887,7 +887,7 @@ SV_PointContents
*/
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));
trace->fraction = 1;
trace->allsolid = true;
VectorCopy (end, trace->endpos);
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
VectorCopy (end_l, trace->endpos);
result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
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)
{
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);
}
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.
================
*/
int SV_HeadnodeForEntity (edict_t *ent)
static model_t *SV_ModelForEntity (edict_t *ent)
{
model_t *model;
@ -1293,16 +1293,16 @@ int SV_HeadnodeForEntity (edict_t *ent)
if (!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
return CM_HeadnodeForBox (ent->v->mins, ent->v->maxs);
return CM_TempBoxModel (ent->v->mins, ent->v->maxs);
}
#ifdef Q2SERVER
int SVQ2_HeadnodeForEntity (q2edict_t *ent)
static model_t *SVQ2_ModelForEntity (q2edict_t *ent)
{
model_t *model;
@ -1314,12 +1314,12 @@ int SVQ2_HeadnodeForEntity (q2edict_t *ent)
if (!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
return CM_HeadnodeForBox (ent->mins, ent->maxs);
return CM_TempBoxModel (ent->mins, ent->maxs);
}
#endif
/*
@ -1433,7 +1433,7 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask )
int i, num;
q2edict_t *touchlist[MAX_EDICTS], *touch;
trace_t trace;
int headnode;
model_t *model;
float *angles;
num = SVQ2_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist
@ -1463,18 +1463,18 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask )
continue;
// might intersect, so do an exact clip
headnode = SVQ2_HeadnodeForEntity (touch);
model = SVQ2_ModelForEntity (touch);
angles = touch->s.angles;
if (touch->solid != Q2SOLID_BSP)
angles = vec3_origin; // boxes don't rotate
if (touch->svflags & SVF_MONSTER)
trace = CM_TransformedBoxTrace (clip->start, clip->end,
clip->mins2, clip->maxs2, headnode, contentsmask,
trace = CM_TransformedBoxTrace (model, clip->start, clip->end,
clip->mins2, clip->maxs2, contentsmask,
touch->s.origin, angles);
else
trace = CM_TransformedBoxTrace (clip->start, clip->end,
clip->mins, clip->maxs, headnode, contentsmask,
trace = CM_TransformedBoxTrace (model, clip->start, clip->end,
clip->mins, clip->maxs, contentsmask,
touch->s.origin, angles);
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)
clip.trace.fraction = 0;
if (!clip.trace.ent)
return clip.trace;
return clip.trace;
}
#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 ) );
// 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;
if (clip.trace.fraction == 0)

View file

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

View file

@ -580,12 +580,12 @@ void SWR_MarkLeaves (void)
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
if (r_viewcluster2 != r_viewcluster)
{
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;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
@ -619,7 +619,7 @@ void SWR_MarkLeaves (void)
r_visframecount++;
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++)
{

View file

@ -531,7 +531,7 @@ r_refdef.viewangles[2]= 0;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
leaf = SWMod_PointInLeaf (r_origin, cl.worldmodel);
leaf = SWMod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcluster = r_viewcluster2 = leaf->cluster;
// 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);
temp[2] -= 16;
leaf = SWMod_PointInLeaf (temp, cl.worldmodel);
leaf = SWMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster;
@ -552,7 +552,7 @@ r_refdef.viewangles[2]= 0;
VectorCopy (r_origin, temp);
temp[2] += 16;
leaf = SWMod_PointInLeaf (temp, cl.worldmodel);
leaf = SWMod_PointInLeaf (cl.worldmodel, temp);
if ( !(leaf->contents & Q2CONTENTS_SOLID) &&
(leaf->cluster != r_viewcluster2) )
r_viewcluster2 = leaf->cluster;
@ -563,7 +563,7 @@ r_refdef.viewangles[2]= 0;
{
// current 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;

View file

@ -98,7 +98,7 @@ void *SWMod_Extradata (model_t *mod)
Mod_PointInLeaf
===============
*/
int SWMod_LeafForPoint (vec3_t p, model_t *model)
static int SWMod_LeafForPoint (model_t *model, vec3_t p)
{
mnode_t *node;
float d;
@ -107,7 +107,7 @@ int SWMod_LeafForPoint (vec3_t p, model_t *model)
#ifdef Q2BSPS
if (model->fromgame == fg_quake2 || model->fromgame == fg_quake3)
{
return CM_PointLeafnum(p);
return CM_PointLeafnum(cl.worldmodel, p);
}
#endif
@ -130,9 +130,9 @@ int SWMod_LeafForPoint (vec3_t p, model_t *model)
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
===================
*/
qbyte *SWMod_DecompressVis (qbyte *in, model_t *model, qbyte *decompressed)
static qbyte *SWMod_DecompressVis (model_t *model, qbyte *in, qbyte *decompressed)
{
int c;
qbyte *out;
@ -184,7 +184,7 @@ qbyte *SWMod_DecompressVis (qbyte *in, model_t *model, qbyte *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];
@ -193,12 +193,7 @@ qbyte *SWMod_LeafPVS (mleaf_t *leaf, model_t *model, qbyte *buffer)
if (!buffer)
buffer = decompressed;
return SWMod_DecompressVis (leaf->compressed_vis, model, buffer);
}
qbyte *SWMod_LeafnumPVS (int ln, model_t *model, qbyte *buffer)
{
return SWMod_LeafPVS(model->leafs + ln, model, buffer);
return SWMod_DecompressVis (model, leaf->compressed_vis, buffer);
}
/*
@ -1867,11 +1862,6 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs);
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 SWR_Q1BSP_StainNode (mnode_t *node, float *parms);
@ -1960,18 +1950,11 @@ void SWMod_LoadBrushModel (model_t *mod, void *buffer)
crouchhullfile=NULL;
}
#ifndef CLIENTONLY
mod->funcs.FatPVS = Q1BSP_FatPVS;
mod->funcs.EdictInFatPVS = Q1BSP_EdictInFatPVS;
mod->funcs.FindTouchedLeafs_Q1 = Q1BSP_FindTouchedLeafs;
#endif
Q1BSP_SetModelFuncs(mod);
mod->funcs.LightPointValues = SWQ1BSP_LightPointValues;
mod->funcs.StainNode = SWR_Q1BSP_StainNode;
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
#ifndef SERVERONLY