I need to commit more often...

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@316 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2004-10-10 06:32:29 +00:00
parent 738993eba9
commit ea5c476ced
40 changed files with 1493 additions and 311 deletions

View file

@ -105,6 +105,8 @@ qboolean Cam_DrawViewModel(int pnum)
// returns true if we should draw this player, we don't if we are chase camming
qboolean Cam_DrawPlayer(int pnum, int playernum)
{
if (playernum == cl.playernum[pnum])
return false;
if (cl.spectator && autocam[pnum] && locked[pnum] && cl_chasecam.value &&
spec_track[pnum] == playernum)
return false;

View file

@ -780,6 +780,49 @@ entity_state_t *CL_FindPacketEntity(int num)
}
#endif
void CL_RotateAroundTag(entity_t *ent, int num)
{
entity_state_t *ps;
float *org=NULL, *ang=NULL;
ps = CL_FindPacketEntity(cl.lerpents[num].tagent);
if (ps)
{
org = ps->origin;
ang = ps->angles;
}
else
{
extern int parsecountmod;
if (cl.lerpents[num].tagent <= MAX_CLIENTS && cl.lerpents[num].tagent > 0)
{
if (cl.lerpents[num].tagent-1 == cl.playernum[0])
{
org = cl.simorg[0];
ang = cl.simangles[0];
}
else
{
org = cl.frames[parsecountmod].playerstate[cl.lerpents[num].tagent-1].origin;
ang = cl.frames[parsecountmod].playerstate[cl.lerpents[num].tagent-1].viewangles;
}
}
}
if (org)
VectorAdd(ent->origin, org, ent->origin);
if (ang)
{
if (ps)
ent->angles[0]+=ang[0];
else
ent->angles[0]+=-ang[0]/3;
ent->angles[1]+=ang[1];
ent->angles[2]+=ang[2];
}
ent->keynum = cl.lerpents[num].tagent;
}
/*
===============
CL_LinkPacketEntities
@ -1002,6 +1045,11 @@ void CL_LinkPacketEntities (void)
}
}
if (cl.lerpents[s1->number].tagent)
{ //ent is attached to a tag, rotate this ent accordingly.
CL_RotateAroundTag(ent, s1->number);
}
// add automatic particle trails
if (!model || (!(model->flags&~EF_ROTATE) && model->particletrail<0))
continue;
@ -1299,7 +1347,7 @@ void CL_ParsePlayerinfo (void)
state->hullnum = 1;
state->scale = 1;
state->trans = 100;
state->trans = 1;
state->fatness = 0;
state->pm_type = PM_NORMAL;
@ -1383,7 +1431,7 @@ void CL_ParsePlayerinfo (void)
state->hullnum = 1;
state->scale = 1;
state->trans = 100;
state->trans = 1;
state->fatness = 0;
if (cls.z_ext & Z_EXT_PM_TYPE)
@ -1396,7 +1444,7 @@ void CL_ParsePlayerinfo (void)
#endif
#ifdef PEXT_TRANS
if (flags & PF_TRANS_Z && cls.fteprotocolextensions & PEXT_TRANS)
state->trans = (float)MSG_ReadByte() / 2.55;
state->trans = (float)MSG_ReadByte() / 255;
#endif
#ifdef PEXT_FATNESS
if (flags & PF_FATNESS_Z && cls.fteprotocolextensions & PEXT_FATNESS)
@ -1458,7 +1506,7 @@ void CL_ParsePlayerinfo (void)
#endif
#ifdef PEXT_TRANS
if (flags & PF_TRANS_NOZ && cls.fteprotocolextensions & PEXT_TRANS)
state->trans = (float)MSG_ReadByte() / 2.55;
state->trans = (float)MSG_ReadByte() / 255;
#endif
#ifdef PEXT_FATNESS
if (flags & PF_FATNESS_NOZ && cls.fteprotocolextensions & PEXT_FATNESS)
@ -1559,6 +1607,15 @@ void CL_AddVWeapModel(entity_t *player, int model)
newent->frame = player->frame;
}
void CL_ParseAttachment(void)
{
int e = (unsigned short)MSG_ReadShort();
int o = (unsigned short)MSG_ReadShort();
int i = (unsigned short)MSG_ReadShort();
cl.lerpents[e].tagent = o;
cl.lerpents[e].tagindex = i;
}
/*
=============
CL_LinkPlayers

View file

@ -153,7 +153,11 @@ qbyte *host_colormap;
cvar_t host_speeds = {"host_speeds","0"}; // set for running times
cvar_t show_fps = {"show_fps","0"}; // set for running times
#ifdef CRAZYDEBUGGING
cvar_t developer = {"developer","1"};
#else
cvar_t developer = {"developer","0"};
#endif
int fps_count;
@ -316,6 +320,7 @@ void CL_SendConnectPacket (
fteprotextsupported |= PEXT_256PACKETENTITIES;
// fteprotextsupported |= PEXT_64PLAYERS;
fteprotextsupported |= PEXT_SHOWPIC;
fteprotextsupported |= PEXT_SETATTACHMENT;
fteprotextsupported &= ftepext;

View file

@ -519,6 +519,8 @@ to start a download from the server.
*/
qboolean CL_CheckOrDownloadFile (char *filename, int nodelay)
{
downloadlist_t *failed;
if (strstr (filename, ".."))
{
Con_TPrintf (TL_NORELATIVEPATHS);
@ -541,18 +543,17 @@ qboolean CL_CheckOrDownloadFile (char *filename, int nodelay)
if (cl.faileddownloads)
{
downloadlist_t *failed;
for (failed = cl.faileddownloads; failed; failed = failed->next) //yeah, so it failed... Ignore it.
{
if (!strcmp(failed->name, filename))
return true;
}
}
for (failed = cl.downloadlist; failed; failed = failed->next) //It's already on our list. Ignore it.
{
if (!strcmp(failed->name, filename))
return true;
}
for (failed = cl.downloadlist; failed; failed = failed->next) //It's already on our list. Ignore it.
{
if (!strcmp(failed->name, filename))
return true;
}
if ((!requiredownloads.value && !nodelay) || nodelay==-1)
@ -3677,6 +3678,10 @@ void CL_ParseServerMessage (void)
case svc_updatepic:
SCR_ShowPic_Update();
break;
case svc_setattachment:
CL_ParseAttachment();
break;
}
}
}

View file

@ -387,6 +387,7 @@ static void SP_RecalcXY ( float *xx, float *yy, int origin )
}
void SCR_ShowPics_Draw(void)
{
downloadlist_t *failed;
float x, y;
showpic_t *sp;
qpic_t *p;
@ -395,9 +396,18 @@ void SCR_ShowPics_Draw(void)
x = sp->x;
y = sp->y;
SP_RecalcXY(&x, &y, sp->zone);
p = Draw_SafeCachePic(sp->picname);
if (!*sp->picname)
continue;
for (failed = cl.faileddownloads; failed; failed = failed->next)
{ //don't try displaying ones that we know to have failed.
if (!strcmp(failed->name, sp->picname))
break;
}
if (failed)
continue;
p = Draw_SafeCachePic(sp->picname);
if (!p)
continue;
Draw_Pic(x, y, p);
@ -675,6 +685,49 @@ void SCR_CalcRefdef (void)
scr_vrect = r_refdef.vrect;
}
void SCR_CrosshairPosition(int pnum, int *x, int *y)
{
extern cvar_t cl_crossx, cl_crossy, crosshaircorrect;
vrect_t rect;
SCR_VRectForPlayer(&rect, pnum);
if (cl.worldmodel && crosshaircorrect.value)
{
trace_t tr;
vec3_t end;
vec3_t start;
vec3_t right, up, fwds;
AngleVectors(cl.viewangles[pnum], fwds, right, up);
VectorMA(cl.simorg[pnum], 100000, fwds, end);
memset(&tr, 0, sizeof(tr));
tr.fraction = 1;
cl.worldmodel->hulls->funcs.RecursiveHullCheck (cl.worldmodel->hulls, 0, 0, 1, cl.simorg[pnum], end, &tr);
if (tr.fraction == 1)
{
*x = rect.x + rect.width/2 + cl_crossx.value;
*y = rect.y + rect.height/2 + cl_crossy.value;
return;
}
else
{
VectorCopy(cl.simorg[pnum], start);
start[2] -= cl.viewheight[pnum]/4;
ML_Project(tr.endpos, end, cl.viewangles[pnum], start, (float)rect.width/rect.height);
*x = rect.x+rect.width*end[0];
*y = rect.y+rect.height*end[1];
return;
}
}
else
{
*x = rect.x + rect.width/2 + cl_crossx.value;
*y = rect.y + rect.height/2 + cl_crossy.value;
return;
}
}
/*
=================
@ -817,6 +870,12 @@ void SCR_DrawFPS (void)
sprintf(st, "%3.1f FPS", lastfps);
x = vid.width - strlen(st) * 8 - 8;
y = vid.height - sb_lines - 8;
// Draw_TileClear(x, y, strlen(st) * 8, 8);
Draw_String(x, y, st);
sprintf(st, "%3.1f UPS", Length(cl.simvel[0]));
x = vid.width - strlen(st) * 8 - 8;
y = vid.height - sb_lines - 16;
// Draw_TileClear(x, y, strlen(st) * 8, 8);
Draw_String(x, y, st);
}

View file

@ -169,6 +169,7 @@ sfx_t *cl_sfx_ric3;
sfx_t *cl_sfx_r_exp3;
cvar_t cl_expsprite = {"cl_expsprite", "0"};
cvar_t cl_truelightning = {"cl_truelightning", "0", NULL, CVAR_SEMICHEAT};
/*
=================
@ -186,6 +187,7 @@ void CL_InitTEnts (void)
cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav");
Cvar_Register (&cl_expsprite, "Temporary entity control");
Cvar_Register (&cl_truelightning, "Temporary entity control");
}
#ifdef Q2CLIENT
@ -1667,6 +1669,8 @@ void CL_UpdateBeams (void)
float yaw, pitch;
float forward, offset;
extern cvar_t cl_truelightning;
// update lightning
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
{
@ -1683,12 +1687,13 @@ void CL_UpdateBeams (void)
//rotate the end point to face in the view direction. This gives a smoother shafting. turning looks great.
VectorSubtract (b->end, b->start, dist);
d = VectorNormalize(dist);
AngleVectors (cl.simangles[0], b->end, dist, org);
VectorMA(b->start, d, b->end, b->end);
// b->start[2] -= cl.viewheight; // adjust for view height?
if (cl_truelightning.value)
{
VectorSubtract (b->end, b->start, dist);
d = VectorNormalize(dist);
AngleVectors (cl.simangles[0], b->end, dist, org);
VectorMA(b->start, d, b->end, b->end);
}
}
else if (b->flags & STREAM_ATTACHED)
{

View file

@ -356,8 +356,10 @@ typedef struct {
float lerprate; //inverse rate...
vec3_t origin;
vec3_t angles;
int frame;
trailstate_t trailstate; //when to next throw out a trail
unsigned short frame;
unsigned short tagent;
unsigned short tagindex;
} lerpents_t;
//
// the client_state_t structure is wiped completely at every

View file

@ -445,6 +445,11 @@ void Con_Init (void)
{
con_debuglog = COM_CheckParm("-condebug");
#ifdef CRAZYDEBUGGING
con_debuglog = true;
TRACE(("dbg: Con_Init: con_debuglog forced\n"));
#endif
con = &con_main;
con->linewidth = -1;
Con_CheckResize ();
@ -1037,7 +1042,7 @@ void Con_DrawConsole (int lines, qboolean noback)
int row;
unsigned char dlbar[1024];
char *progresstext;
int progresspercent;
float progresspercent;
#ifdef RUNTIMELIGHTING
extern model_t *lightmodel;
@ -1110,7 +1115,7 @@ void Con_DrawConsole (int lines, qboolean noback)
if (relitsurface < lightmodel->numsurfaces)
{
progresstext = "light";
progresspercent = (relitsurface*100) / lightmodel->numsurfaces;
progresspercent = (relitsurface*100.0f) / lightmodel->numsurfaces;
}
}
#endif
@ -1140,7 +1145,7 @@ void Con_DrawConsole (int lines, qboolean noback)
if (progresspercent == 0)
n = 0;
else
n = y * (float)progresspercent / 100;
n = y * progresspercent / 100;
x = i;
for (j = 0; j < y; j++)
@ -1153,7 +1158,7 @@ void Con_DrawConsole (int lines, qboolean noback)
dlbar[i++] = '\x82';
dlbar[i] = 0;
sprintf(dlbar + strlen(dlbar), " %02d%%", progresspercent);
sprintf(dlbar + strlen(dlbar), " %02d%%", (int)progresspercent);
// draw it
y = con->vislines-22 + 8;

View file

@ -1481,22 +1481,39 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height)
{
qbyte *data;
if ((data = ReadTargaFile(buf, len, width, height, false)))
{
TRACE(("dbg: Read32BitImageFile: tga\n"));
return data;
}
#ifdef AVAIL_PNGLIB
if ((buf[0] == 137 && buf[1] == 'P' && buf[2] == 'N' && buf[3] == 'G') && (data = ReadPNGFile(buf, com_filesize, width, height)))
{
TRACE(("dbg: Read32BitImageFile: png\n"));
return data;
}
#endif
#ifdef AVAIL_JPEGLIB
//jpeg jfif only.
if ((buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff && buf[3] == 0xe0) && (data = ReadJPEGFile(buf, com_filesize, width, height)))
{
TRACE(("dbg: Read32BitImageFile: jpeg\n"));
return data;
}
#endif
if ((data = ReadPCXFile(buf, com_filesize, width, height)))
{
TRACE(("dbg: Read32BitImageFile: pcx\n"));
return data;
}
if ((buf[0] == 'B' && buf[1] == 'M') && (data = ReadBMPFile(buf, com_filesize, width, height)))
{
TRACE(("dbg: Read32BitImageFile: bitmap\n"));
return data;
}
TRACE(("dbg: Read32BitImageFile: life sucks\n"));
return NULL;
}
@ -1573,12 +1590,14 @@ int Mod_LoadHiResTexture(char *name, qboolean mipmap, qboolean alpha, qboolean c
}
else
_snprintf(fname, sizeof(fname)-1, path[i], nicename, extensions[e]);
TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname));
if ((buf = COM_LoadFile (fname, 5)))
{
if ((data = Read32BitImageFile(buf, com_filesize, &image_width, &image_height)))
{
if (colouradjust)
BoostGamma(data, image_width, image_height);
TRACE(("dbg: Mod_LoadHiResTexture: %s loaded\n", name));
len = GL_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alpha);
BZ_Free(data);
@ -1631,6 +1650,8 @@ int Mod_LoadBumpmapTexture(char *name)
int i, e;
TRACE(("dbg: Mod_LoadBumpmapTexture: texture %s\n", name));
COM_StripExtension(name, nicename);
if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists.
@ -1662,10 +1683,14 @@ int Mod_LoadBumpmapTexture(char *name)
}
else
_snprintf(fname, sizeof(fname)-1, path[i], nicename, extensions[e]);
TRACE(("dbg: Mod_LoadBumpmapTexture: opening %s\n", fname));
if ((buf = COM_LoadFile (fname, 5)))
{
if ((data = ReadTargaFile(buf, com_filesize, &image_width, &image_height, 2))) //Only load a greyscale image.
{
TRACE(("dbg: Mod_LoadBumpmapTexture: tga %s loaded\n", name));
len = GL_LoadTexture8Bump(name, image_width, image_height, data, true);
BZ_Free(data);
}

View file

@ -75,6 +75,7 @@ cvar_t r_numedges = {"r_numedges", "0"};
cvar_t r_aliastransbase = {"r_aliastransbase", "200"};
cvar_t r_aliastransadj = {"r_aliastransadj", "100"};
cvar_t d_smooth = {"d_smooth", "0"};
cvar_t gl_skyboxdist = {"gl_skyboxdist", "2300"};
extern cvar_t r_dodgytgafiles;
@ -214,6 +215,8 @@ void R_BulletenForce_f (void);
rendererstate_t currentrendererstate;
cvar_t gl_skyboxname = {"r_skybox", ""};
cvar_t r_fastsky = {"r_fastsky", "0"};
cvar_t r_fastskycolour = {"r_fastskycolour", "0"};
#if defined(RGLQUAKE)
cvar_t gl_ztrick = {"gl_ztrick","1"};
@ -302,6 +305,8 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_ati_truform, GRAPHICALNICETIES);
Cvar_Register (&gl_ati_truform_type, GRAPHICALNICETIES);
Cvar_Register (&gl_ati_truform_tesselation, GRAPHICALNICETIES);
Cvar_Register (&gl_skyboxdist, GLRENDEREROPTIONS);
}
#endif
#if defined(SWQUAKE)
@ -490,6 +495,9 @@ void Renderer_Init(void)
Cvar_Register (&r_nolerp, GRAPHICALNICETIES);
Cvar_Register (&r_nolightdir, GRAPHICALNICETIES);
Cvar_Register (&r_fastsky, GRAPHICALNICETIES);
Cvar_Register (&r_fastskycolour, GRAPHICALNICETIES);
//bulletens
Cvar_Register(&bul_nowater, BULLETENVARS);
Cvar_Register(&bul_rippleamount, BULLETENVARS);
@ -1023,12 +1031,19 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
return false;
if (R_DeInit)
{
TRACE(("dbg: R_ApplyRenderer: R_DeInit\n"));
R_DeInit();
SCR_DeInit();
}
if (VID_DeInit)
{
TRACE(("dbg: R_ApplyRenderer: VID_DeInit\n"));
VID_DeInit();
}
TRACE(("dbg: R_ApplyRenderer: SCR_DeInit\n"));
SCR_DeInit();
IN_Shutdown();
@ -1048,6 +1063,8 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
Hunk_FreeToLowMark(host_hunklevel); //is this a good idea?
TRACE(("dbg: R_ApplyRenderer: old renderer closed\n"));
gl_skyboxname.modified = true;
if (qrenderer) //graphics stuff only when not dedicated
@ -1112,28 +1129,38 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
if (vid.fullbright < 2)
vid.fullbright = 0; //transparent colour doesn't count.
TRACE(("dbg: R_ApplyRenderer: Palette loaded\n"));
if (!VID_Init(newr, host_basepal))
{
R_SetRenderer(QR_NONE);
return false;
}
TRACE(("dbg: R_ApplyRenderer: vid applied\n"));
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
GLV_UpdatePalette();
#endif
TRACE(("dbg: R_ApplyRenderer: done palette\n"));
v_oldgammavalue = -1; //force the gamma to be reset
W_LoadWadFile("gfx.wad");
TRACE(("dbg: R_ApplyRenderer: wad loaded\n"));
Draw_Init();
TRACE(("dbg: R_ApplyRenderer: draw inited\n"));
R_Init();
TRACE(("dbg: R_ApplyRenderer: renderer inited\n"));
SCR_Init();
TRACE(("dbg: R_ApplyRenderer: screen inited\n"));
Sbar_Flush();
IN_Init();
}
else
{
TRACE(("dbg: R_ApplyRenderer: isDedicated = true\n"));
isDedicated = true;
if (cls.state)
{
@ -1145,16 +1172,19 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
Sys_InitTerminal();
Con_PrintToSys();
}
TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
Mod_Init();
TRACE(("dbg: R_ApplyRenderer: initing bulletein boards\n"));
WipeBulletenTextures();
// host_hunklevel = Hunk_LowMark();
if (R_PreNewMap)
if (cl.worldmodel)
{
TRACE(("dbg: R_ApplyRenderer: R_PreNewMap (how handy)\n"));
R_PreNewMap();
}
if (sv.worldmodel)
{
@ -1163,11 +1193,14 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
q2edict_t *q2ent;
#endif
TRACE(("dbg: R_ApplyRenderer: reloading server map\n"));
sv.worldmodel = Mod_ForName (sv.modelname, false);
TRACE(("dbg: R_ApplyRenderer: loaded\n"));
if (sv.worldmodel->needload)
{
SV_Error("Bsp went missing on render restart\n");
}
TRACE(("dbg: R_ApplyRenderer: doing that funky phs thang\n"));
SV_CalcPHS ();
for (i = 0; i < MAX_MODELS; i++)
@ -1177,7 +1210,7 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
else
sv.models[i] = NULL;
}
TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
SV_ClearWorld ();
if (svprogfuncs)
@ -1220,7 +1253,9 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
}
#endif
}
Plug_ResChanged();
TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
if (cl.worldmodel)
{
int staticmodelindex[MAX_STATIC_ENTITIES];
@ -1235,13 +1270,14 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
cl.worldmodel = NULL;
cl_numvisedicts=0;
TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
for (i=1 ; i<MAX_MODELS ; i++)
{
if (!cl.model_name[i][0])
break;
cl.model_precache[i] = NULL;
TRACE(("dbg: R_ApplyRenderer: reloading model %s\n", cl.model_name[i]));
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
if (!cl.model_precache[i])
@ -1259,7 +1295,7 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
}
loadmodel = cl.worldmodel = cl.model_precache[1];
TRACE(("dbg: R_ApplyRenderer: done the models\n"));
if (loadmodel->needload)
{
CL_Disconnect ();
@ -1268,9 +1304,11 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
return true;
}
TRACE(("dbg: R_ApplyRenderer: checking any wad textures\n"));
Mod_NowLoadExternal();
TRACE(("dbg: R_ApplyRenderer: R_NewMap\n"));
R_NewMap();
TRACE(("dbg: R_ApplyRenderer: efrags\n"));
for (i = 0; i < cl.num_statics; i++) //make the static entities reappear.
{
cl_static_entities[i].model = cl.model_precache[staticmodelindex[i]];
@ -1317,6 +1355,8 @@ void R_RestartRenderer_f (void)
rendererstate_t newr;
memset(&newr, 0, sizeof(newr));
TRACE(("dbg: R_RestartRenderer_f\n"));
Media_CaptureDemoEnd();
Cvar_ApplyLatches(CVAR_RENDERERLATCH);
@ -1386,20 +1426,31 @@ void R_RestartRenderer_f (void)
#error "no default renderer"
#endif
TRACE(("dbg: R_RestartRenderer_f renderer %i\n", newr.renderer));
memcpy(&oldr, &currentrendererstate, sizeof(rendererstate_t));
if (!R_ApplyRenderer(&newr))
{
TRACE(("dbg: R_RestartRenderer_f failed\n"));
if (R_ApplyRenderer(&oldr))
{
TRACE(("dbg: R_RestartRenderer_f old restored\n"));
Con_Printf("^1Video mode switch failed. Old mode restored.\n"); //go back to the old mode, the new one failed.
}
else
{
newr.renderer = QR_NONE;
if (R_ApplyRenderer(&newr))
{
TRACE(("dbg: R_RestartRenderer_f going to dedicated\n"));
Con_Printf("^1Video mode switch failed. Old mode wasn't supported either. Console forced.\nChange vid_mode to a compatable mode, and then use the setrenderer command.\n");
}
else
Sys_Error("Couldn't fall back to previous renderer\n");
}
}
TRACE(("dbg: R_RestartRenderer_f success\n"));
}
void R_SetRenderer_f (void)

View file

@ -74,9 +74,11 @@ cvar_t v_idlescale = {"v_idlescale", "0", NULL};
cvar_t crosshair = {"crosshair", "0", NULL, CVAR_ARCHIVE};
cvar_t crosshaircolor = {"crosshaircolor", "79", NULL, CVAR_ARCHIVE};
cvar_t crosshairsize = {"crosshairsize", "8", NULL, CVAR_ARCHIVE};
cvar_t cl_crossx = {"cl_crossx", "0", NULL, CVAR_ARCHIVE};
cvar_t cl_crossy = {"cl_crossy", "0", NULL, CVAR_ARCHIVE};
cvar_t crosshaircorrect = {"crosshaircorrect", "0", NULL, CVAR_SEMICHEAT};
cvar_t gl_cshiftpercent = {"gl_cshiftpercent", "100"};
@ -1440,6 +1442,8 @@ void V_Init (void)
Cvar_Register (&crosshaircolor, VIEWVARS);
Cvar_Register (&crosshair, VIEWVARS);
Cvar_Register (&crosshairsize, VIEWVARS);
Cvar_Register (&crosshaircorrect, VIEWVARS);
Cvar_Register (&cl_crossx, VIEWVARS);
Cvar_Register (&cl_crossy, VIEWVARS);
Cvar_Register (&gl_cshiftpercent, VIEWVARS);

View file

@ -700,6 +700,99 @@ static char *Macro_TF_Skin (void)
}
//Spike: added these:
static char *Macro_ConnectionType (void)
{
if (!cls.state)
return "disconnected";
if (cl.spectator)
return "spectator";
return "connected";
}
static char *Macro_demoplayback (void)
{
switch (cls.demoplayback)
{
case DPB_NONE:
return "0";
case DPB_QUAKEWORLD:
return "qwdplayback";
case DPB_MVD:
return "mvdplayback";
case DPB_NETQUAKE:
return "demplayback";
case DPB_QUAKE2:
return "dm2playback";
//gcc will warn if we add annother playback and forget here, otherwise I'd use a default.
}
return "1"; //unknown.
}
/*
$droploc
Tells location of the dropped flag.
Note: This will tell only if you have dropped the flag (CTF/TF).
$droptime
Tells how many seconds gone of dropped flag.
$ledpoint
This reports the type of the pointed object as a LED according to the
following rules:
If teammate then green.
If enemy then red.
If powerup then yellow.
if item then blue.
$ledstatus
This checks your current status (health, armor and best weapon) and
reports a LED according to the following rules:
if all of the above is ok then green.
if there is one thing low then yellow.
if there are two or over things low then red.
$matchname
you can use to get the name of the match
manually (echo $matchname).
Example: a matchname might be
"[clan]quaker - [4on4_myclan_vs_someclan] - [dm3]" or whatever.
$matchstatus
("disconnected", "standby" or "normal"). This can be
used for detecting prewar/prematch on ktpro/oztf servers.
$matchtype
duel,2on2,4on4,ffa,etc...
$mp3info
Evaluates to "author - title".
Examples:
if you bind space "say listening to $mp3info"
then hitting space will say something like
"listening to disturbed - rise".
bind x "if disturbed isin $mp3info then say dde music is cool"
$need
What you need.
Note: you have to set this with tp_need* variables.
$point
Name of object you are looking at.
$pointatloc
Name of object and location of object you are looking at.
$pointloc
Location of object you are looking at.
$triggermatch
$triggermatch is the last chat message that exec'd a msg_trigger.
*/
//Spike: added end.
static void TP_InitMacros(void)
{
Cmd_AddMacro("qt", Macro_Quote);
@ -727,6 +820,24 @@ static void TP_InitMacros(void)
Cmd_AddMacro("took", Macro_Took);
Cmd_AddMacro("tf_skin", Macro_TF_Skin);
//ones added by Spike, for fuhquake compatability
Cmd_AddMacro("connectiontype", Macro_ConnectionType);
Cmd_AddMacro("demoplayback", Macro_demoplayback);
/*
$droploc
$droptime
$ledpoint
$ledstatus
$matchname
$matchstatus
$matchtype
$mp3info
$need
$point
$pointatloc
$pointloc
$triggermatch
*/
}
#define MAX_MACRO_STRING 1024

View file

@ -100,6 +100,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define IN_XFLIP //allow input to be flipped horizontally.
#define TEXTEDITOR
#define PLUGINS
// #define VOICECHAT //experimental
//these things were moved to plugins.
@ -153,6 +155,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef EMAILCLIENT
#undef TEXTEDITOR
#undef RUNTIMELIGHTING
#undef PLUGINS //we don't have any server side stuff.
#endif
#ifdef CLIENTONLY //remove optional server componants that make no sence on a client only build.
#undef Q2SERVER

View file

@ -326,7 +326,7 @@ void Cvar_ApplyLatches(int latchflag)
cvar_t *var;
int mask = ~0;
if (latchflag == CVAR_SERVEROVERRIDE)
if (latchflag == CVAR_SERVEROVERRIDE) //these ones are cleared
mask = ~CVAR_SERVEROVERRIDE;
for (grp=cvar_groups ; grp ; grp=grp->next)
@ -483,6 +483,8 @@ void Cvar_LockFromServer(cvar_t *var, char *str)
{
char *oldlatch;
Con_DPrintf("Server taking control of cvar %s\n", var->name);
var->flags |= CVAR_SERVEROVERRIDE;
oldlatch = var->latched_string;

View file

@ -90,8 +90,8 @@ typedef struct cvar_group_s
#define CVAR_POINTER 32 // q2 style. May be converted to q1 if needed. These are often specified on the command line and then converted into q1 when registered properly.
#define CVAR_NOTFROMSERVER 64
#define CVAR_USERCREATED 128 //write a 'set' or 'seta' in front of the var name.
#define CVAR_CHEAT 256 //latch from 0 unless cheats are enabled.
#define CVAR_SEMICHEAT 512 //if strict ruleset, force to 0.
#define CVAR_CHEAT 256 //latch to the default, unless cheats are enabled.
#define CVAR_SEMICHEAT 512 //if strict ruleset, force to 0/blank.
#define CVAR_RENDERERLATCH 1024
#define CVAR_SERVEROVERRIDE 2048 //

View file

@ -713,3 +713,183 @@ void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
}
}
#endif
//This function is GL stylie (use as 2nd arg to ML_MultMatrix4).
float *ML_RotationMatrix(float a, float x, float y, float z)
{
static float ret[16];
float c = cos(a* M_PI / 180.0);
float s = sin(a* M_PI / 180.0);
ret[0] = x*x*(1-c)+c;
ret[4] = x*y*(1-c)-z*s;
ret[8] = x*z*(1-c)+y*s;
ret[12] = 0;
ret[1] = y*x*(1-c)+z*s;
ret[5] = y*y*(1-c)+c;
ret[9] = y*z*(1-c)-x*s;
ret[13] = 0;
ret[2] = x*z*(1-c)-y*s;
ret[6] = y*z*(1-c)+x*s;
ret[10] = z*z*(1-c)+c;
ret[14] = 0;
ret[3] = 0;
ret[7] = 0;
ret[11] = 0;
ret[15] = 1;
return ret;
}
//This function is GL stylie (use as 2nd arg to ML_MultMatrix4).
float *ML_TranslationMatrix(float x, float y, float z)
{
static float ret[16];
ret[0] = 1;
ret[4] = 0;
ret[8] = 0;
ret[12] = x;
ret[1] = 0;
ret[5] = 1;
ret[9] = 0;
ret[13] = y;
ret[2] = 0;
ret[6] = 0;
ret[10] = 1;
ret[14] = z;
ret[3] = 0;
ret[7] = 0;
ret[11] = 0;
ret[15] = 1;
return ret;
}
//be aware that this generates two sorts of matricies depending on order of a+b
void ML_MultMatrix4(float *a, float *b, float *out)
{
out[0] = a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3];
out[1] = a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3];
out[2] = a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3];
out[3] = a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3];
out[4] = a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7];
out[5] = a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7];
out[6] = a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7];
out[7] = a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7];
out[8] = a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11];
out[9] = a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11];
out[10] = a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11];
out[11] = a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11];
out[12] = a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15];
out[13] = a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15];
out[14] = a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15];
out[15] = a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15];
}
//transform 4d vector by a 4d matrix.
void ML_MatrixTransform4 (float *matrix, float *vector, float *product)
{
product[0] = matrix[0]*vector[0] + matrix[4]*vector[1] + matrix[8]*vector[2] + matrix[12]*vector[3];
product[1] = matrix[1]*vector[0] + matrix[5]*vector[1] + matrix[9]*vector[2] + matrix[13]*vector[3];
product[2] = matrix[2]*vector[0] + matrix[6]*vector[1] + matrix[10]*vector[2] + matrix[14]*vector[3];
product[3] = matrix[3]*vector[0] + matrix[7]*vector[1] + matrix[11]*vector[2] + matrix[15]*vector[3];
}
//returns fractions of screen.
//uses GL style rotations and translations and stuff.
void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy)
{
float modelview[16];
float proj[16];
{
float tempmat[16];
//load identity.
memset(modelview, 0, sizeof(modelview));
#if FULLYGL
modelview[0] = 1;
modelview[5] = 1;
modelview[10] = 1;
modelview[15] = 1;
ML_MultMatrix4(modelview, ML_RotationMatrix(-90, 1, 0, 0), tempmat); // put Z going up
ML_MultMatrix4(tempmat, ML_RotationMatrix(90, 0, 0, 1), modelview); // put Z going up
#else
//use the lame wierd and crazy identity matrix..
modelview[2] = -1;
modelview[4] = -1;
modelview[9] = 1;
modelview[15] = 1;
#endif
//figure out the current modelview matrix
//I would if some of these, but then I'd still need a couple of copys
ML_MultMatrix4(modelview, ML_RotationMatrix(-viewangles[2], 1, 0, 0), tempmat); // put Z going up
ML_MultMatrix4(tempmat, ML_RotationMatrix(-viewangles[0], 0, 1, 0), modelview); // put Z going up
ML_MultMatrix4(modelview, ML_RotationMatrix(-viewangles[1], 0, 0, 1), tempmat); // put Z going up
ML_MultMatrix4(tempmat, ML_TranslationMatrix(-vieworg[0], -vieworg[1], -vieworg[2]), modelview); // put Z going up
}
{
float xmin, xmax, ymin, ymax;
float nudge = 1;
//proj
ymax = 4 * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmin = ymin * wdivh;
xmax = ymax * wdivh;
proj[0] = (2*4) / (xmax - xmin);
proj[4] = 0;
proj[8] = (xmax + xmin) / (xmax - xmin);
proj[12] = 0;
proj[1] = 0;
proj[5] = (2*4) / (ymax - ymin);
proj[9] = (ymax + ymin) / (ymax - ymin);
proj[13] = 0;
proj[2] = 0;
proj[6] = 0;
proj[10] = -1 * nudge;
proj[14] = -2*4 * nudge;
proj[3] = 0;
proj[7] = 0;
proj[11] = -1;
proj[15] = 0;
}
//we've got our two matricies now.
{
float v[4], tempv[4];
v[0] = in[0];
v[1] = in[1];
v[2] = in[2];
v[3] = 1;
ML_MatrixTransform4(modelview, v, tempv);
ML_MatrixTransform4(proj, tempv, v);
v[0] /= v[3];
v[1] /= v[3];
v[2] /= v[3];
out[0] = (1+v[0])/2;
out[1] = (1+v[1])/2;
out[2] = (1+v[2])/2;
}
}

View file

@ -6,12 +6,16 @@
#ifdef PLUGINS
#include "glquake.h"
typedef struct plugin_s {
char *name;
vm_t *vm;
int tick;
int executestring;
int menufunction;
int sbarlevel[3]; //0 - main sbar, 1 - supplementry sbar sections (make sure these can be switched off), 2 - overlays (scoreboard). menus kill all.
int reschange;
struct plugin_s *next;
} plugin_t;
@ -169,6 +173,9 @@ plugin_t *Plug_Load(char *file)
argarray = (int)"Plug_GetEngineFunction";
VM_Call(newplug->vm, 0, Plug_FindBuiltin(NULL, ~0, &argarray));
if (newplug->reschange)
VM_Call(newplug->vm, newplug->reschange, vid.width, vid.height);
}
else
{
@ -209,11 +216,79 @@ int Plug_ExportToEngine(void *offset, unsigned int mask, const long *arg)
currentplug->executestring = arg[1];
else if (!strcmp(name, "MenuEvent"))
currentplug->menufunction = arg[1];
else if (!strcmp(name, "UpdateVideo"))
currentplug->reschange = arg[1];
else
return 0;
return 1;
}
//void(char *buffer, int buffersize)
typedef struct {
//Make SURE that the engine has resolved all cvar pointers into globals before this happens.
plugin_t *plugin;
cvar_t *var;
} plugincvararray_t;
int plugincvararraylen;
plugincvararray_t *plugincvararray;
//qhandle_t Cvar_Register (char *name, char *defaultval, int flags, char *grouphint);
int Plug_Cvar_Register(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]);
char *defaultvalue = VM_POINTER(arg[1]);
unsigned int flags = VM_LONG(arg[2]);
char *groupname = VM_POINTER(arg[3]);
cvar_t *var;
int i;
var = Cvar_Get(name, defaultvalue, flags&1, groupname);
for (i = 0; i < plugincvararraylen; i++)
{
if (!plugincvararray[i].var)
{ //hmm... a gap...
plugincvararray[i].plugin = currentplug;
plugincvararray[i].var = var;
return i;
}
}
plugincvararray = BZ_Realloc(plugincvararray, (plugincvararraylen+1)*sizeof(plugincvararray_t));
plugincvararray[plugincvararraylen].plugin = currentplug;
plugincvararray[plugincvararraylen].var = var;
plugincvararraylen++;
return plugincvararraylen-1;
}
//int Cvar_Update, (qhandle_t handle, int modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
int Plug_Cvar_Update(void *offset, unsigned int mask, const long *arg)
{
int handle;
int modcount;
char *stringv; //255 bytes long.
float *floatv;
cvar_t *var;
handle = VM_LONG(arg[0]);
if (handle < 0 || handle >= plugincvararraylen)
return 0;
if (plugincvararray[handle].plugin != currentplug)
return 0; //I'm not letting you know what annother plugin has registered.
if (VM_OOB(arg[2], 256) || VM_OOB(arg[3], 4)) //Oi, plugin - you screwed up
return 0;
modcount = VM_LONG(arg[1]);
stringv = VM_POINTER(arg[2]);
floatv = VM_POINTER(arg[3]);
var = plugincvararray[handle].var;
strcpy(stringv, var->string);
*floatv = var->value;
return var->modified;
}
//void Cmd_Args(char *buffer, int buffersize)
int Plug_Cmd_Args(void *offset, unsigned int mask, const long *arg)
{
char *buffer = (char*)VM_POINTER(arg[0]);
@ -224,7 +299,7 @@ int Plug_Cmd_Args(void *offset, unsigned int mask, const long *arg)
strcpy(buffer, args);
return 1;
}
//void(int num, char *buffer, int buffersize)
//void Cmd_Argv(int num, char *buffer, int buffersize)
int Plug_Cmd_Argv(void *offset, unsigned int mask, const long *arg)
{
char *buffer = (char*)VM_POINTER(arg[1]);
@ -235,7 +310,7 @@ int Plug_Cmd_Argv(void *offset, unsigned int mask, const long *arg)
strcpy(buffer, args);
return 1;
}
//int(void)
//int Cmd_Argc(void)
int Plug_Cmd_Argc(void *offset, unsigned int mask, const long *arg)
{
return Cmd_Argc();
@ -245,39 +320,221 @@ int Plug_Menu_Control(void *offset, unsigned int mask, const long *arg)
{
switch(VM_LONG(arg[0]))
{
case 0: //weather it's us or not.
return currentplug == menuplug && m_state == m_plugin;
case 1: //weather a menu is active
return key_dest == key_menu;
case 2: //give us menu control
case 0: //take away all menus
case 1:
if (menuplug)
{
plugin_t *oldplug = currentplug;
currentplug = menuplug;
Plug_Menu_Event(3, 0);
menuplug = NULL;
currentplug = oldplug;
key_dest = key_game;
}
if (VM_LONG(arg[0]) != 1)
return 1;
//give us menu control
menuplug = currentplug;
key_dest = key_menu;
m_state = m_plugin;
return 1;
case 2: //weather it's us or not.
return currentplug == menuplug && m_state == m_plugin;
case 3: //weather a menu is active
return key_dest == key_menu;
default:
return 0;
}
}
int Plug_Draw_Character(void *offset, unsigned int mask, const long *arg)
{
Draw_Character(arg[0], arg[1], (unsigned int)arg[2]);
return 0;
}
int Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg)
{
return 0;
}
//hrm.... FIXME!
int Plug_Draw_ColourP(void *offset, unsigned int mask, const long *arg)
{
extern unsigned char vid_curpal[256*3];
qbyte *pal = vid_curpal + VM_LONG(arg[0])*3;
if (arg[0]<0 || arg[0]>255)
return false;
switch(qrenderer)
{
case QR_OPENGL:
glColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f);
break;
case QR_SOFTWARE:
SWDraw_ImageColours(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f, 1);
break;
default:
return 0;
}
return 1;
}
int Plug_Draw_Colour3f(void *offset, unsigned int mask, const long *arg)
{
switch(qrenderer)
{
case QR_OPENGL:
glColor3f(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]));
break;
case QR_SOFTWARE:
SWDraw_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), 1);
break;
default:
return 0;
}
return 1;
}
int Plug_Draw_Colour4f(void *offset, unsigned int mask, const long *arg)
{
switch(qrenderer)
{
case QR_OPENGL:
glColor4f(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]));
break;
case QR_SOFTWARE:
SWDraw_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]));
break;
default:
return 0;
}
return 1;
}
int Plug_Key_GetKeyCode(void *offset, unsigned int mask, const long *arg)
{
int modifier;
return Key_StringToKeynum(VM_POINTER(arg[0]), &modifier);
}
//void Cvar_SetString (char *name, char *value);
int Plug_Cvar_SetString(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]),
*value = VM_POINTER(arg[1]);
cvar_t *var = Cvar_Get(name, value, 0, "Plugin vars");
if (var)
{
Cvar_Set(var, value);
return 1;
}
return 0;
}
//void Cvar_SetFloat (char *name, float value);
int Plug_Cvar_SetFloat(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]);
float value = VM_FLOAT(arg[1]);
cvar_t *var = Cvar_Get(name, "", 0, "Plugin vars"); //"" because I'm lazy
if (var)
{
Cvar_SetValue(var, value);
return 1;
}
return 0;
}
//void Cvar_GetFloat (char *name);
int Plug_Cvar_GetFloat(void *offset, unsigned int mask, const long *arg)
{
char *name = VM_POINTER(arg[0]);
float value = VM_FLOAT(arg[1]);
int ret;
cvar_t *var = Cvar_Get(name, "", 0, "Plugin vars");
if (var)
{
VM_FLOAT(ret) = var->value;
}
else
VM_FLOAT(ret) = 0;
return ret;
}
//qboolean Cvar_GetString (char *name, char *retstring, int sizeofretstring);
int Plug_Cvar_GetString(void *offset, unsigned int mask, const long *arg)
{
char *name, *ret;
int retsize;
cvar_t *var;
if (VM_OOB(arg[1], arg[2]))
{
return false;
}
name = VM_POINTER(arg[0]);
ret = VM_POINTER(arg[1]);
retsize = VM_LONG(arg[2]);
var = Cvar_Get(name, "", 0, "Plugin vars");
if (strlen(var->name)+1 > retsize)
return false;
strcpy(ret, var->string);
return true;
}
//void Cmd_AddText (char *text, qboolean insert); //abort the entire engine.
int Plug_Cmd_AddText(void *offset, unsigned int mask, const long *arg)
{
if (VM_LONG(arg[1]))
Cbuf_InsertText(VM_POINTER(arg[0]), RESTRICT_LOCAL);
else
Cbuf_AddText(VM_POINTER(arg[0]), RESTRICT_LOCAL);
return 1;
}
void Plug_Init(void)
{
Plug_RegisterBuiltin("Plug_GetEngineFunction", Plug_FindBuiltin, 0);//plugin wishes to find a builtin number.
Plug_RegisterBuiltin("Plug_ExportToEngine", Plug_ExportToEngine, 0); //plugin has a call back that we might be interested in.
Plug_RegisterBuiltin("Con_Print", Plug_Con_Print, 0); //printf is not possible - qvm floats are never doubles, vararg floats in a cdecl call are always converted to doubles.
Plug_RegisterBuiltin("Sys_Error", Plug_Sys_Error, 0);
Plug_RegisterBuiltin("Com_Error", Plug_Sys_Error, 0); //make zquake programmers happy.
Plug_RegisterBuiltin("Plug_GetEngineFunction", Plug_FindBuiltin, 0);//plugin wishes to find a builtin number.
Plug_RegisterBuiltin("Plug_ExportToEngine", Plug_ExportToEngine, 0); //plugin has a call back that we might be interested in.
Plug_RegisterBuiltin("Con_Print", Plug_Con_Print, 0); //printf is not possible - qvm floats are never doubles, vararg floats in a cdecl call are always converted to doubles.
Plug_RegisterBuiltin("Sys_Error", Plug_Sys_Error, 0);
Plug_RegisterBuiltin("Com_Error", Plug_Sys_Error, 0); //make zquake programmers happy.
Plug_RegisterBuiltin("Cmd_Args", Plug_Cmd_Args, 0);
Plug_RegisterBuiltin("Cmd_Argc", Plug_Cmd_Argc, 0);
Plug_RegisterBuiltin("Cmd_Argv", Plug_Cmd_Argv, 0);
Plug_RegisterBuiltin("Cmd_Args", Plug_Cmd_Args, 0);
Plug_RegisterBuiltin("Cmd_Argc", Plug_Cmd_Argc, 0);
Plug_RegisterBuiltin("Cmd_Argv", Plug_Cmd_Argv, 0);
Plug_RegisterBuiltin("Cmd_AddText", Plug_Cmd_AddText, 0);
Plug_RegisterBuiltin("Menu_Control", Plug_Menu_Control, 0);
Plug_RegisterBuiltin("Menu_Control", Plug_Menu_Control, 0);
Plug_RegisterBuiltin("Cvar_Register", Plug_Cvar_Register, 0);
Plug_RegisterBuiltin("Cvar_SetString", Plug_Cvar_SetString, 0);
Plug_RegisterBuiltin("Cvar_SetFloat", Plug_Cvar_SetFloat, 0);
Plug_RegisterBuiltin("Cvar_GetString", Plug_Cvar_GetString, 0);
Plug_RegisterBuiltin("Cvar_GetFloat", Plug_Cvar_GetFloat, 0);
Plug_RegisterBuiltin("Draw_Character", Plug_Draw_Character, 0);
Plug_RegisterBuiltin("Draw_Fill", Plug_Draw_Fill, 0);
Plug_RegisterBuiltin("Draw_Colourp", Plug_Draw_ColourP, 0);
Plug_RegisterBuiltin("Draw_Colour3f", Plug_Draw_Colour3f, 0);
Plug_RegisterBuiltin("Draw_Colour4f", Plug_Draw_Colour4f, 0);
Plug_RegisterBuiltin("Key_GetKeyCode", Plug_Key_GetKeyCode, 0);
#ifdef _WIN32
COM_EnumerateFiles("plugins/*x86.dll", Plug_Emumerated, "x86.dll");
COM_EnumerateFiles("plugins/*x86.dll", Plug_Emumerated, "x86.dll");
#elif defined(__linux__)
COM_EnumerateFiles("plugins/*x86.so", Plug_Emumerated, "x86.so");
COM_EnumerateFiles("plugins/*x86.so", Plug_Emumerated, "x86.so");
#endif
COM_EnumerateFiles("plugins/*.qvm", Plug_Emumerated, ".qvm");
COM_EnumerateFiles("plugins/*.qvm", Plug_Emumerated, ".qvm");
}
void Plug_Tick(void)
@ -293,6 +550,17 @@ void Plug_Tick(void)
}
}
void Plug_ResChanged(void)
{
plugin_t *oldplug = currentplug;
for (currentplug = plugs; currentplug; currentplug = currentplug->next)
{
if (currentplug->reschange)
VM_Call(currentplug->vm, currentplug->reschange, vid.width, vid.height);
}
currentplug = oldplug;
}
qboolean Plugin_ExecuteString(void)
{
plugin_t *plug;

View file

@ -54,6 +54,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PEXT_256PACKETENTITIES 0x01000000 //Client can recieve 256 packet entities.
//#define PEXT_64PLAYERS 0x02000000 //Client is able to cope with 64 players. Wow.
#define PEXT_SHOWPIC 0x04000000
#define PEXT_SETATTACHMENT 0x08000000 //md3 tags (needs networking, they need to lerp).
@ -224,6 +225,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svc_movepic 71
#define svc_updatepic 72
#define svc_setattachment 73
#define svc_invalid 256

View file

@ -573,7 +573,7 @@ static void inline QVM_Return(qvm_t *vm, long size)
if(vm->bp>vm->len_ds+vm->len_ss/2)
Sys_Error("VM run time error: freed too much stack\n");
if(fp[1]>vm->len_cs)
if(fp[1]>vm->len_cs*2)
if (vm->cs+fp[1]) //this being false causes the program to quit.
Sys_Error("VM run time error: program returned to hyperspace\n");
if(fp[1]<0)

View file

@ -19,6 +19,7 @@ typedef struct vm_s vm_t;
#define VM_LONG(x) (*(long*)&(x))
#define VM_FLOAT(x) (*(float*)&(x))
#define VM_POINTER(x) ((x)?(void*)((char *)offset+((x)%mask)):NULL)
#define VM_OOB(p,l) (p + l >= mask || VM_POINTER(p) < offset)
// ------------------------- * interface * -------------------------
void VM_PrintInfo(vm_t *vm);

View file

@ -34,7 +34,7 @@ void Cache_FreeLow (int new_low_hunk);
void Cache_FreeHigh (int new_high_hunk);
#ifdef _DEBUG
#define MEMDEBUG 8192 //Debugging adds sentinels (the number is the size - I have the ram)
//#define MEMDEBUG 8192 //Debugging adds sentinels (the number is the size - I have the ram)
#endif
#ifndef MEMDEBUG
@ -331,11 +331,11 @@ void Zone_Print_f(void)
int allocated = 0;
int blocks = 0;
int futurehide = false;
int i;
int minsize = 0;
qbyte *sent;
zone_t *zone;
#if MEMDEBUG > 0
int i;
qbyte *sent;
qboolean testsent = false;
if (*Cmd_Argv(1) == 't')
{
@ -736,8 +736,24 @@ void Hunk_Check (void)
{
if (h->sentinal != HUNK_SENTINAL)
Sys_Error ("Hunk_Check: trahsed sentinal");
if (h->size < 16 || h->size + (qbyte *)h - hunk_base > hunk_size)
if (h->size < 16+MEMDEBUG*2 || h->size + (qbyte *)h - hunk_base > hunk_size)
Sys_Error ("Hunk_Check: bad size");
#if MEMDEBUG > 0
{
qbyte *present;
qbyte *postsent;
int i;
present = (qbyte *)(h+1);
postsent = (qbyte *)h + h->size-MEMDEBUG;
for (i = 0; i < MEMDEBUG; i++)
{
if (present[i] != sentinalkey)
*(int*)0 = -3;
if (postsent[i] != sentinalkey)
*(int*)0 = -3;
}
}
#endif
h = (hunk_t *)((qbyte *)h+h->size);
}
}
@ -797,7 +813,22 @@ void Hunk_Print (qboolean all)
Sys_Error ("Hunk_Check: trahsed sentinal");
if (h->size < 16 || h->size + (qbyte *)h - hunk_base > hunk_size)
Sys_Error ("Hunk_Check: bad size");
#if MEMDEBUG > 0
{
qbyte *present;
qbyte *postsent;
int i;
present = (qbyte *)(h+1);
postsent = (qbyte *)h + h->size-MEMDEBUG;
for (i = 0; i < MEMDEBUG; i++)
{
if (present[i] != sentinalkey)
*(int*)0 = -3;
if (postsent[i] != sentinalkey)
*(int*)0 = -3;
}
}
#endif
next = (hunk_t *)((qbyte *)h+h->size);
count++;
totalblocks++;
@ -846,7 +877,7 @@ void *Hunk_AllocName (int size, char *name)
if (size < 0)
Sys_Error ("Hunk_Alloc: bad size: %i", size);
size = sizeof(hunk_t) + ((size+15)&~15);
size = sizeof(hunk_t) + MEMDEBUG*2 + ((size+15)&~15);
#ifndef _WIN32
if (hunk_size - hunk_low_used - hunk_high_used < size)
@ -874,13 +905,18 @@ void *Hunk_AllocName (int size, char *name)
Cache_FreeLow (hunk_low_used);
memset (h, 0, size);
memset (h, 0, size-MEMDEBUG);
#if MEMDEBUG>0
memset ((h+1), sentinalkey, MEMDEBUG);
memset ((qbyte *)h+size-MEMDEBUG, sentinalkey, MEMDEBUG);
#endif
h->size = size;
h->sentinal = HUNK_SENTINAL;
Q_strncpyz (h->name, COM_SkipPath(name), sizeof(h->name));
return (void *)(h+1);
return (void *)((char *)(h+1)+MEMDEBUG);
}
/*

View file

@ -87,7 +87,7 @@ BSC32=bscmake.exe
# 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:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ws32_2.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../fteqw.exe" /pdbtype:sept
# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../fteqw.exe" /pdbtype:sept
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"

View file

@ -1925,6 +1925,7 @@ void GL_LoadQ1Model (model_t *mod, void *buffer)
// move the complete, relocatable alias model to the cache
//
hunkend = Hunk_LowMark ();
Hunk_Alloc(0);
hunktotal = hunkend - hunkstart;
Cache_Alloc (&mod->cache, hunktotal, loadname);

View file

@ -47,7 +47,7 @@ extern qbyte gammatable[256];
unsigned char *d_15to8table;
qboolean inited15to8;
extern cvar_t crosshair, cl_crossx, cl_crossy, crosshaircolor;
extern cvar_t crosshair, cl_crossx, cl_crossy, crosshaircolor, crosshairsize;
static int filmtexture;
@ -641,6 +641,8 @@ void GLDraw_ReInit (void)
int maxtexsize;
gltexture_t *glt;
TRACE(("dbg: GLDraw_ReInit: Closing old\n"));
while(gltextures)
{
glt = gltextures;
@ -661,6 +663,7 @@ void GLDraw_ReInit (void)
currenttexture=0;
glmenu_numcachepics=0;
// GL_FlushSkinCache();
TRACE(("dbg: GLDraw_ReInit: GL_GAliasFlushSkinCache\n"));
GL_GAliasFlushSkinCache();
memset(scrap_allocated, 0, sizeof(scrap_allocated));
@ -680,7 +683,7 @@ void GLDraw_ReInit (void)
//required to hold the image after scaling has occured
sizeofuploadmemorybuffer = maxtexsize*maxtexsize*4;
TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
uploadmemorybuffer = BZ_Realloc(uploadmemorybuffer, sizeofuploadmemorybuffer);
uploadmemorybufferintermediate = BZ_Realloc(uploadmemorybufferintermediate, sizeofuploadmemorybufferintermediate);
@ -697,6 +700,7 @@ void GLDraw_ReInit (void)
}
// now turn them into textures
TRACE(("dbg: GLDraw_ReInit: looking for conchars\n"));
if (!(char_texture=Mod_LoadReplacementTexture("gfx/conchars.lmp", false, true))) //no high res
{
if (!draw_chars) //or low res.
@ -756,13 +760,28 @@ void GLDraw_ReInit (void)
}
default_char_texture=char_texture;
TRACE(("dbg: GLDraw_ReInit: loaded charset\n"));
gl_font.modified = true;
gl_smoothfont.modified = 1;
TRACE(("dbg: GLDraw_ReInit: GL_BeginRendering\n"));
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
SCR_DrawLoading ();
TRACE(("dbg: GLDraw_ReInit: SCR_DrawLoading\n"));
GL_Set2D();
glClear(GL_COLOR_BUFFER_BIT);
{
qpic_t *pic = Draw_SafeCachePic ("loading");
if (pic)
Draw_Pic ( (vid.width - pic->width)/2,
(vid.height - 48 - pic->height)/2, pic);
}
TRACE(("dbg: GLDraw_ReInit: GL_EndRendering\n"));
GL_EndRendering ();
//now emit the conchars picture as if from a wad.
@ -777,6 +796,7 @@ void GLDraw_ReInit (void)
gl->th = 1;
glmenu_numcachepics++;
TRACE(("dbg: GLDraw_ReInit: W_SafeGetLumpName\n"));
tinyfont = W_SafeGetLumpName ("tinyfont");
if (tinyfont)
{
@ -794,6 +814,7 @@ void GLDraw_ReInit (void)
gl->th = 1;
glmenu_numcachepics++;
}
TRACE(("dbg: GLDraw_ReInit: gfx/menu/bigfont\n"));
bigfont = (qpic_t *)COM_LoadMallocFile ("gfx/menu/bigfont.lmp");
if (bigfont)
{
@ -815,6 +836,7 @@ void GLDraw_ReInit (void)
}
TRACE(("dbg: GLDraw_ReInit: gfx/conchars2.lmp\n"));
if (!(char_tex2=Mod_LoadReplacementTexture("gfx/conchars2.lmp", false, true)))
{
if (!draw_chars)
@ -829,12 +851,14 @@ void GLDraw_ReInit (void)
start = Hunk_LowMark ();
conback = default_conback;
TRACE(("dbg: GLDraw_ReInit: COM_FDepthFile(\"gfx/conback.lmp\", false)\n"));
if (COM_FDepthFile("gfx/conback.lmp", false) <= COM_FDepthFile("gfx/menu/conback.lmp", false))
cb = (qpic_t *)COM_LoadHunkFile ("gfx/conback.lmp");
else
cb = (qpic_t *)COM_LoadHunkFile ("gfx/menu/conback.lmp");
if (cb)
{
TRACE(("dbg: GLDraw_ReInit: conback opened\n"));
SwapPic (cb);
if (draw_chars)
@ -856,6 +880,7 @@ void GLDraw_ReInit (void)
// scale console to vid size
dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback");
TRACE(("dbg: GLDraw_ReInit: conback loading\n");
for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth)
{
src = cb->data + cb->width * (y*cb->height/vid.conheight);
@ -889,6 +914,7 @@ void GLDraw_ReInit (void)
ncdata = NULL;
}
TRACE(("dbg: GLDraw_ReInit: conback loaded\n"));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -941,6 +967,7 @@ void GLDraw_ReInit (void)
//
// get the other pics we need
//
TRACE(("dbg: GLDraw_ReInit: Draw_SafePicFromWad\n"));
draw_disc = Draw_SafePicFromWad ("disc");
draw_backtile = Draw_SafePicFromWad ("backtile");
if (!draw_backtile)
@ -951,6 +978,7 @@ void GLDraw_ReInit (void)
inited15to8 = false;
TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n"));
PPL_LoadSpecularFragmentProgram();
}
@ -982,8 +1010,10 @@ void GLDraw_DeInit (void)
Cmd_RemoveCommand("gl_texturemode");
draw_disc = NULL;
BZ_Free(uploadmemorybuffer); //free the mem
BZ_Free(uploadmemorybufferintermediate);
if (uploadmemorybuffer)
BZ_Free(uploadmemorybuffer); //free the mem
if (uploadmemorybufferintermediate)
BZ_Free(uploadmemorybufferintermediate);
uploadmemorybuffer = NULL; //make sure we know it's free
uploadmemorybufferintermediate = NULL;
sizeofuploadmemorybuffer = 0; //and give a nice safe sys_error if we try using it.
@ -1128,16 +1158,16 @@ void GLDraw_Crosshair(void)
{
int x, y;
int sc;
vrect_t rect;
float x1, x2, y1, y2;
float size;
if (crosshair.value == 1)
{
for (sc = 0; sc < cl.splitclients; sc++)
{
SCR_VRectForPlayer(&rect, sc);
GLDraw_Character (rect.x + rect.width/2-4 + cl_crossx.value,
rect.y + rect.height/2-4 + cl_crossy.value,
'+');
SCR_CrosshairPosition(sc, &x, &y);
GLDraw_Character (x-4, y-4, '+');
}
return;
}
@ -1183,19 +1213,22 @@ void GLDraw_Crosshair(void)
for (sc = 0; sc < cl.splitclients; sc++)
{
SCR_VRectForPlayer(&rect, sc);
SCR_CrosshairPosition(sc, &x, &y);
x = rect.x + rect.width/2 - 3 + cl_crossx.value;
y = rect.y + rect.height/2 - 3 + cl_crossy.value;
size = crosshairsize.value;
x1 = x - size;
x2 = x + size;
y1 = y - size;
y2 = y + size;
glBegin (GL_QUADS);
glTexCoord2f (0, 0);
glVertex2f (x - 4, y - 4);
glVertex2f (x1, y1);
glTexCoord2f (1, 0);
glVertex2f (x+12, y-4);
glVertex2f (x2, y1);
glTexCoord2f (1, 1);
glVertex2f (x+12, y+12);
glVertex2f (x2, y2);
glTexCoord2f (0, 1);
glVertex2f (x - 4, y+12);
glVertex2f (x1, y2);
glEnd ();
}
@ -2191,6 +2224,9 @@ qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsi
return true;
}
qboolean supported_GL_ARB_texture_non_power_of_two;
qboolean supported_GL_SGIS_generate_mipmap;
/*
===============
GL_Upload32
@ -2203,14 +2239,27 @@ void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean m
unsigned *scaled = (unsigned *)uploadmemorybuffer;
int scaled_width, scaled_height;
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
TRACE(("dbg: GL_Upload32: %s %i %i\n", name, width, height));
if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
{
TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n"));
scaled_width = width;
scaled_height = height;
}
else
{
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
}
TRACE(("dbg: GL_Upload32: %f\n", gl_picmip.value));
scaled_width >>= (int)gl_picmip.value;
scaled_height >>= (int)gl_picmip.value;
TRACE(("dbg: GL_Upload32: %f\n", gl_max_size.value));
if (gl_max_size.value)
{
if (scaled_width > gl_max_size.value)
@ -2219,6 +2268,13 @@ void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean m
scaled_height = gl_max_size.value;
}
if (scaled_width < 1)
scaled_width = 1;
if (scaled_height < 1)
scaled_height = 1;
TRACE(("dbg: GL_Upload32: %i %i\n", scaled_width, scaled_height));
if (scaled_width * scaled_height > sizeofuploadmemorybuffer/4)
Sys_Error ("GL_LoadTexture: too big");
@ -2240,10 +2296,17 @@ void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean m
#else
texels += scaled_width * scaled_height;
if (supported_GL_SGIS_generate_mipmap&&mipmap)
{
TRACE(("dbg: GL_Upload32: GL_SGIS_generate_mipmap\n"));
glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
}
if (scaled_width == width && scaled_height == height)
{
if (!mipmap)
if (!mipmap||supported_GL_SGIS_generate_mipmap) //gotta love this with NPOT textures... :)
{
TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n"));
glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
goto done;
}
@ -2252,10 +2315,12 @@ texels += scaled_width * scaled_height;
else
GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
TRACE(("dbg: GL_Upload32: recaled\n"));
glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
if (mipmap)
if (mipmap && !supported_GL_SGIS_generate_mipmap)
{
miplevel = 0;
TRACE(("dbg: GL_Upload32: mips\n"));
while (scaled_width > 1 || scaled_height > 1)
{
GL_MipMap ((qbyte *)scaled, scaled_width, scaled_height);
@ -2321,7 +2386,9 @@ texels += scaled_width * scaled_height;
}
}
}
done: ;
done:
if (supported_GL_SGIS_generate_mipmap&&mipmap)
glTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
#endif
@ -2343,10 +2410,19 @@ void GL_Upload8Grey (unsigned char*data, int width, int height, qboolean mipmap
unsigned char *scaled = uploadmemorybuffer;
int scaled_width, scaled_height;
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
{
TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n"));
scaled_width = width;
scaled_height = height;
}
else
{
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
}
scaled_width >>= (int)gl_picmip.value;
scaled_height >>= (int)gl_picmip.value;
@ -2359,23 +2435,16 @@ void GL_Upload8Grey (unsigned char*data, int width, int height, qboolean mipmap
scaled_height = gl_max_size.value;
}
if (scaled_width < 1)
scaled_width = 1;
if (scaled_height < 1)
scaled_height = 1;
if (scaled_width * scaled_height > sizeofuploadmemorybuffer/4)
Sys_Error ("GL_LoadTexture: too big");
samples = 1;//alpha ? gl_alpha_format : gl_solid_format;
#if 0
if (mipmap)
gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
else if (scaled_width == width && scaled_height == height)
glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
else
{
gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled);
glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
}
#else
texels += scaled_width * scaled_height;
if (scaled_width == width && scaled_height == height)
@ -2410,8 +2479,6 @@ texels += scaled_width * scaled_height;
}
}
done: ;
#endif
if (mipmap)
{
@ -2554,13 +2621,24 @@ void GL_UploadBump(qbyte *data, int width, int height, qboolean mipmap) {
int scaled_width, scaled_height;
qbyte *nmap;
TRACE(("dbg: GL_UploadBump entered: %i %i\n", width, height));
s = width*height;
//Resize to power of 2 and maximum texture size
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
{
TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n"));
scaled_width = width;
scaled_height = height;
}
else
{
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
}
scaled_width >>= (int)gl_picmip.value;
scaled_height >>= (int)gl_picmip.value;
@ -2573,6 +2651,11 @@ void GL_UploadBump(qbyte *data, int width, int height, qboolean mipmap) {
scaled_height = gl_max_size.value;
}
if (scaled_width < 1)
scaled_width = 1;
if (scaled_height < 1)
scaled_height = 1;
if (scaled_width * scaled_height > sizeofuploadmemorybuffer/4)
Sys_Error ("GL_LoadTexture: too big");
@ -2637,6 +2720,7 @@ void GL_UploadBump(qbyte *data, int width, int height, qboolean mipmap) {
// if (gl_texturefilteranisotropic)
// glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_texureanisotropylevel);
TRACE(("dbg: GL_UploadBump: escaped %i %i\n", width, height));
}
@ -2669,10 +2753,19 @@ void GL_Upload8_EXT (qbyte *data, int width, int height, qboolean mipmap, qbool
if (alpha && noalpha)
alpha = false;
}
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
if (supported_GL_ARB_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
{
TRACE(("dbg: GL_Upload32: GL_ARB_texture_non_power_of_two\n"));
scaled_width = width;
scaled_height = height;
}
else
{
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
}
scaled_width >>= (int)gl_picmip.value;
scaled_height >>= (int)gl_picmip.value;
@ -2685,6 +2778,11 @@ void GL_Upload8_EXT (qbyte *data, int width, int height, qboolean mipmap, qbool
scaled_height = gl_max_size.value;
}
if (scaled_width < 1)
scaled_width = 1;
if (scaled_height < 1)
scaled_height = 1;
if (scaled_width * scaled_height > sizeofuploadmemorybufferintermediate/4)
Sys_Error ("GL_LoadTexture: too big");
@ -2932,9 +3030,15 @@ int GL_LoadTexture (char *identifier, int width, int height, qbyte *data, qboole
{
glt = GL_MatchTexture(identifier, 8, width, height);
if (glt)
{
TRACE(("dbg: GL_LoadTexture: duplicate %s\n", identifier));
return glt->texnum;
}
}
TRACE(("dbg: GL_LoadTexture: new %s\n", identifier));
glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t));
glt->next = gltextures;
gltextures = glt;
@ -3170,9 +3274,14 @@ int GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char
{
glt = GL_MatchTexture(identifier, 8, width, height);
if (glt)
{
TRACE(("dbg: GL_LoadTexture8Bump: duplicated %s\n", identifier));
return glt->texnum;
}
}
TRACE(("dbg: GL_LoadTexture8Bump: new %s\n", identifier));
glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t));
glt->next = gltextures;
gltextures = glt;

View file

@ -865,11 +865,13 @@ void GLR_NewMap (void)
r_viewcluster = -1;
r_oldviewcluster = 0;
r_viewcluster2 = -1;
TRACE(("dbg: GLR_NewMap: clear particles\n"));
R_ClearParticles ();
TRACE(("dbg: GLR_NewMap: wiping them stains (getting the cloth out)\n"));
GLR_WipeStains();
TRACE(("dbg: GLR_NewMap: building lightmaps\n"));
GL_BuildLightmaps ();
TRACE(("dbg: GLR_NewMap: figuring out skys and mirrors\n"));
// identify sky texture
if (cl.worldmodel->fromgame != fg_quake2 && cl.worldmodel->fromgame != fg_quake3)
{
@ -886,13 +888,13 @@ void GLR_NewMap (void)
mirrortexturenum = i;
cl.worldmodel->textures[i]->texturechain = NULL;
}
TRACE(("dbg: GLR_NewMap: that skybox thang\n"));
//#ifdef QUAKE2
R_LoadSkys ();
//#endif
TRACE(("dbg: GLR_NewMap: ui\n"));
UI_Reset();
TRACE(("dbg: GLR_NewMap: tp\n"));
TP_NewMap();
}

View file

@ -93,6 +93,9 @@ void GLSCR_UpdateScreen (void)
vid.recalc_refdef = true;
Con_CheckResize();
Plug_ResChanged();
GL_Set2D();
}
vid.numpages = 2 + gl_triplebuffer.value;

View file

@ -180,6 +180,14 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglBindProgramARB = NULL;
qglGenProgramsARB = NULL;
supported_GL_ARB_texture_non_power_of_two = false;
supported_GL_SGIS_generate_mipmap = false;
if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two"))
supported_GL_ARB_texture_non_power_of_two = true;
if (strstr(gl_extensions, "GL_SGIS_generate_mipmap"))
supported_GL_SGIS_generate_mipmap = true;
if (strstr(gl_extensions, "GL_ARB_multitexture") && !COM_CheckParm("-noamtex"))
{ //ARB multitexture is the popular choice.
Con_SafePrintf("ARB Multitexture extensions found. Use -noamtex to disable.\n");

View file

@ -36,6 +36,9 @@ msurface_t *warpface;
extern cvar_t gl_skyboxname;
extern cvar_t gl_waterripples;
extern cvar_t gl_skyboxdist;
extern cvar_t r_fastsky;
extern cvar_t r_fastskycolour;
char loadedskybox[256];
void R_DrawSkyBox (msurface_t *s);
@ -381,14 +384,35 @@ void R_DrawSkyChain (msurface_t *s)
{
msurface_t *fa;
GL_DisableMultitexture();
if (r_fastsky.value) //this is for visability only... we'd otherwise not stoop this low (and this IS low)
{
int fc;
qbyte *pal;
extern unsigned char vid_curpal[256*3];
fc = r_fastskycolour.value;
if (fc > 255)
fc = 255;
if (fc < 0)
fc = 0;
pal = vid_curpal+fc*3;
glDisable(GL_TEXTURE_2D);
glColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f);
for (fa=s ; fa ; fa=fa->texturechain)
EmitSkyPolys (fa);
glColor3f(1, 1, 1);
glEnable(GL_TEXTURE_2D);
return;
}
if (usingskybox)
{
R_DrawSkyBoxChain(s);
return;
}
GL_DisableMultitexture();
// used when gl_texsort is on
GL_Bind(solidskytexture);
speedscale = cl.gametime;
@ -778,10 +802,14 @@ void MakeSkyVec (float s, float t, int axis)
{
vec3_t v, b;
int j, k;
float skydist = gl_skyboxdist.value;
b[0] = s*2300;
b[1] = t*2300;
b[2] = 2300;
if (r_shadows.value) //because r_shadows comes with an infinate depth perspective.
skydist*=20; //so we can put the distance at whatever distance needed.
b[0] = s*skydist;
b[1] = t*skydist;
b[2] = skydist;
for (j=0 ; j<3 ; j++)
{

View file

@ -229,6 +229,9 @@ extern qboolean gl_mtexable;
void GL_DisableMultitexture(void);
void GL_EnableMultitexture(void);
extern qboolean supported_GL_SGIS_generate_mipmap;
extern qboolean supported_GL_ARB_texture_non_power_of_two;
//
// gl_warp.c
//

View file

@ -5047,69 +5047,63 @@ typedef struct lh_extension_s {
lh_extension_t QSG_Extensions[] = {
{"QW_ENGINE"}, //warning: interpretation of .skin on players can be dodgy, as can some other QW features that differ from NQ.
{"DP_HALFLIFE_MAP_CVAR"},
{"FTE_MULTIPROGS"}, //multiprogs functions are available.
{"FTE_SOLID_LADDER"}, //part of a worthy hl implementation. Allows a simple trigger to remove effects of gravity (solid 20)
{"FRIK_FILE", 11, NULL, {"stof", "fopen","fclose","fgets","fputs","strlen","strcat","substring","stov","strzone","strunzone"}},
{"DP_REGISTERCVAR", 1, NULL, {"registercvar"}},
{"DP_QC_SINCOSSQRTPOW", 4, NULL, {"sin", "cos", "sqrt", "pow"}},
{"DP_TE_BLOOD", 1, NULL, {"te_blood"}},
{"QSG_CVARSTRING", 1, NULL, {"cvar_string"}},
{"DP_QC_CVAR_STRING", 1, NULL, {"dp_cvar_string"}}, //448 builtin.
#ifndef NOMEDIA
{"FTE_MEDIA_AVI"}, //playfilm supports avi files.
{"FTE_MEDIA_ROQ"}, //playfilm command supports q3 roq files
{"FTE_MEDIA_CIN"}, //playfilm command supports q2 cin files.
#endif
{"QWE_MVD_RECORD"}, //Quakeworld extended get the credit for this one. (mvdsv)
{"FTE_MVD_PLAYBACK"},
{"DP_SPRITE32"}, //hmm... is it legal to advertise this one?
{"DP_QC_TRACE_MOVETYPES"}, //this one is just a lame excuse to add annother extension...
{"DP_QC_TRACEBOX", 1, NULL, {"tracebox"}},
{"DP_MOVETYPEBOUNCEMISSILE"}, //I added the code with hexen2 support.
{"DP_SV_NODRAWTOCLIENT"}, //I prefer my older system. Guess I might as well remove that older system at some point.
{"DP_SV_DRAWONLYTOCLIENT"},
{"DP_EF_FULLBRIGHT"}, //Rerouted to hexen2 support.
{"DP_EF_BLUE"}, //hah!! This is QuakeWorld!!!
{"DP_EF_BLUE"}, //hah!! This is QuakeWorld!!!
{"DP_EF_FULLBRIGHT"}, //Rerouted to hexen2 support.
{"DP_EF_RED"},
{"DP_QC_MINMAXBOUND", 3, NULL, {"min", "max", "bound"}},
{"DP_QC_RANDOMVEC", 1, NULL, {"randomvec"}},
{"DP_EXTRA_TEMPSTRING"}, //ftos returns 16 temp buffers.
{"DP_HALFLIFE_MAP_CVAR"},
{"DP_MOVETYPEBOUNCEMISSILE"}, //I added the code for hexen2 support.
{"DP_MOVETYPEFOLLOW"},
{"DP_QC_COPYENTITY", 1, NULL, {"copyentity"}},
{"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system.
{"DP_QC_VECTORVECTORS", 1, NULL, {"vectorvectors"}},
{"DP_QC_FINDFLOAT", 1, NULL, {"findfloat"}},
{"DP_QC_CVAR_STRING", 1, NULL, {"dp_cvar_string"}}, //448 builtin.
{"DP_QC_ETOS", 1, NULL, {"etos"}},
{"DP_QC_FINDCHAIN", 1, NULL, {"findchain"}},
{"DP_QC_FINDCHAINFLOAT", 1, NULL, {"findchainfloat"}},
{"TEI_MD3_MODEL"},
// {"TQ_RAILTRAIL"}, //client supports it, server can't filter it, but can currently send it.
{"DP_QC_FINDFLOAT", 1, NULL, {"findfloat"}},
// {"DP_QC_FS_SEARCH", 4, NULL, {"search_begin", "search_end", "search_getsize", "search_getfilename"}},
{"DP_QC_MINMAXBOUND", 3, NULL, {"min", "max", "bound"}},
{"DP_QC_RANDOMVEC", 1, NULL, {"randomvec"}},
{"DP_QC_SINCOSSQRTPOW", 4, NULL, {"sin", "cos", "sqrt", "pow"}},
{"DP_QC_TRACEBOX", 1, NULL, {"tracebox"}},
{"DP_QC_TRACE_MOVETYPES"}, //this one is just a lame excuse to add annother extension...
{"DP_QC_VECTORVECTORS", 1, NULL, {"vectorvectors"}},
{"DP_QUAKE2_MODEL"},
{"DP_QUAKE3_MODEL"},
{"DP_QC_ETOS", 1, NULL, {"etos"}},
{"DP_REGISTERCVAR", 1, NULL, {"registercvar"}},
{"DP_SPRITE32"}, //hmm... is it legal to advertise this one?
{"DP_SV_DRAWONLYTOCLIENT"},
{"DP_SV_NODRAWTOCLIENT"}, //I prefer my older system. Guess I might as well remove that older system at some point.
{"DP_SV_PLAYERPHYSICS"},
{"DP_EXTRA_TEMPSTRING"}, //ftos returns 16 temp buffers.
{"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, { "te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion",
"te_wizspike", "te_knightspike", "te_lavasplash", "te_teleport", "te_explosion2",
"te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}}, //should we include QW ones?...
{"ZQ_MOVETYPE_NOCLIP"},
{"ZQ_MOVETYPE_FLY"},
{"ZQ_MOVETYPE_NONE"},
{"DP_SV_SETCOLOR"},
{"DP_TE_BLOOD", 1, NULL, {"te_blood"}},
{"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, { "te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash", "te_teleport", "te_explosion2", "te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}}, //should we include QW ones?...
{"EXT_DIMENSION_VISIBILITY"},
{"EXT_DIMENSION_PHYSICS"},
{"EXT_DIMENSION_GHOST"},
{"EXT_BITSHIFT", 1, NULL, {"bitshift"}},
{"FRIK_FILE", 11, NULL, {"stof", "fopen","fclose","fgets","fputs","strlen","strcat","substring","stov","strzone","strunzone"}},
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
#ifndef NOMEDIA
{"FTE_MEDIA_AVI"}, //playfilm supports avi files.
{"FTE_MEDIA_CIN"}, //playfilm command supports q2 cin files.
{"FTE_MEDIA_ROQ"}, //playfilm command supports q3 roq files
#endif
{"FTE_MULTIPROGS"}, //multiprogs functions are available.
{"FTE_MULTITHREADED", 3, NULL, {"sleep", "fork", "abort"}},
{"FTE_MVD_PLAYBACK"},
#ifdef SVCHAT
{"FTE_NPCCHAT", 1, NULL, {"chat"}}, //server looks at chat files. It automagically branches through calling qc functions as requested.
#endif
{"DP_SV_SETCOLOR"}
{"FTE_SOLID_LADDER"}, //part of a worthy hl implementation. Allows a simple trigger to remove effects of gravity (solid 20)
{"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system.
{"QSG_CVARSTRING", 1, NULL, {"cvar_string"}},
{"QW_ENGINE"}, //warning: interpretation of .skin on players can be dodgy, as can some other QW features that differ from NQ.
{"QWE_MVD_RECORD"}, //Quakeworld extended get the credit for this one. (mvdsv)
{"TEI_MD3_MODEL"},
// {"TQ_RAILTRAIL"}, //client supports it, server can't filter it, but can currently send it.
{"ZQ_MOVETYPE_FLY"},
{"ZQ_MOVETYPE_NOCLIP"},
{"ZQ_MOVETYPE_NONE"},
};
//some of these are overkill yes, but they are all derived from the fteextensions flags and document the underlaying protocol available.
@ -5772,7 +5766,7 @@ void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals)
ent = EDICT_NUM(svprogfuncs, i);
if (ent->isfree)
continue;
t = *(string_t *)&((float*)&ent->v)[f];
t = *(string_t *)&((float*)&ent->v)[f] + prinst->stringtable;
if (!t)
continue;
if (strcmp(t, s))
@ -6902,6 +6896,72 @@ void PF_ChangePic(progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
}
//DP_QC_FS_SEARCH
void PF_Search_Begin(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_INT(OFS_RETURN) = 0;
}
void PF_Search_End(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_INT(OFS_RETURN) = 0;
}
void PF_Search_GetSize(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_INT(OFS_RETURN) = 0;
}
void PF_SearchGetFileName(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_INT(OFS_RETURN) = 0;
}
void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *e = G_EDICT(prinst, OFS_PARM0);
edict_t *tagentity = G_EDICT(prinst, OFS_PARM1);
char *tagname = PR_GetStringOfs(prinst, OFS_PARM2);
eval_t *te;
eval_t *ti;
// int i, modelindex;
// model_t *model;
te = prinst->GetEdictFieldValue(prinst, e, "tag_entity", NULL);
ti = prinst->GetEdictFieldValue(prinst, e, "tag_index", NULL);
e->tagent = tagentity->entnum;
e->tagindex = 0;
if (tagentity != sv.edicts && tagname && tagname[0])
{
/* modelindex = (int)tagentity->v->modelindex;
if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.modeltags[modelindex]))
{
if (v->_float == 0 && model->alias.aliasnum_tags)
for (i = 0;i < model->alias.aliasnum_tags;i++)
if (!strcmp(tagname, model->alias.aliasdata_tags[i].name))
v->_float = i + 1;
if (v->_float == 0)
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name);
}
else
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity));
*/
}
//fix me, move to somewhere nicer.
MSG_WriteByte(&sv.multicast, svc_setattachment);
MSG_WriteShort(&sv.multicast, e->entnum);
MSG_WriteShort(&sv.multicast, e->tagent);
MSG_WriteShort(&sv.multicast, e->tagindex);
SV_MulticastProtExt(vec3_origin, MULTICAST_ALL_R, 0xffffffff, PEXT_SETATTACHMENT, 0);
if (te)
te->edict = EDICT_TO_PROG(prinst,EDICT_NUM(prinst, e->tagent));
if (ti)
te->_float = e->tagindex;
}
BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
@ -7195,6 +7255,13 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"clientcommand", PF_clientcommand, 0, 0, 0, 440},// #440 void(entity e, string s) clientcommand (KRIMZON_SV_PARSECLIENTCOMMAND)
{"tokenize", PF_Tokenize, 0, 0, 0, 441},// #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND)
{"argv", PF_ArgV, 0, 0, 0, 442},// #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND
{"setattachment", PF_setattachment, 0, 0, 0, 443},// #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS)
{"search_begin", PF_Search_Begin, 0, 0, 0, 444},
{"search_end", PF_Search_End, 0, 0, 0, 445},
{"search_getsize", PF_Search_GetSize, 0, 0, 0, 446},
{"search_getfilename", PF_SearchGetFileName,0, 0, 0, 447},
//DP_QC_CVAR_STRING
{"dp_cvar_string", PF_cvar_string, 0, 0, 0, 448},// #448 string(float n) cvar_string
//end other peoples extras
@ -7333,6 +7400,8 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any
PR_EnableEBFSBuiltin("calltimeofday", 0)!= 102 ||
PR_EnableEBFSBuiltin("forcedemoframe", 0)!= 103)
Con_Printf("Failed to register all MVDSV builtins\n");
else
Con_Printf("Be aware that MVDSV does not follow standards. Please encourage your mod developers to not require pr_imitatemvdsv to be set.\n");
}
}
@ -7475,6 +7544,7 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldfloat(gravity); //standard extension
fieldfloat(maxspeed); //standard extension
fieldfloat(items2); //standard nq
fieldvector(punchangle);//standard nq
fieldfloat(scale);
//fieldfloat(transparency);
fieldfloat(alpha);
@ -7502,8 +7572,9 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
//hexen 2 stuff
fieldfloat(playerclass);
fieldfloat(hull);
fieldfloat(hasted);
//stats - only a couple...
//stats - only a couple... (optimise me...)
fieldfloat(level);
fieldfloat(intelligence);
fieldfloat(experience);
@ -7537,7 +7608,6 @@ void PR_RegisterFields(void) //it's just easier to do it this way.
fieldstring(puzzle_inv7);
fieldstring(puzzle_inv8);
fieldfloat(hasted);
fieldfloat(inventory);
fieldfloat(cnt_torch);
fieldfloat(cnt_h_boost);

View file

@ -227,6 +227,7 @@ typedef struct entvars_s
float gravity;
float maxspeed;
float items2;
vec3_t punchangle;
float scale;
float alpha;
float fatness;
@ -257,6 +258,7 @@ typedef struct entvars_s
float seefsizez;
float seefoffset;
//hexen2 stuff
float playerclass; //hexen2 requirements
float hull;
float drawflags;
@ -264,9 +266,12 @@ typedef struct entvars_s
int movechain;
func_t chainmoved;
float light_level;
float abslight;
float light_level;//hexen2's grabbing light level from client
float abslight; //hexen2's force a lightlevel
float hasted; //hexen2 uses this AS WELL as maxspeed
//FIXME: remove these, use evalc_ts
float level;
float intelligence;
float experience;
@ -300,7 +305,6 @@ typedef struct entvars_s
string_t puzzle_inv7;
string_t puzzle_inv8;
float hasted;
float inventory;
float cnt_torch;
float cnt_h_boost;

View file

@ -78,6 +78,9 @@ typedef struct edict_s
entity_state_t baseline;
unsigned short tagent;
unsigned short tagindex;
entvars_t v; // C exported fields from progs
// other fields from progs come immediately after
} edict_t;

View file

@ -654,7 +654,7 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
if (ent->spectator == 2 && ent->weaponframe)
pflags |= PF_WEAPONFRAME;
if (!ent->isself)
if (!ent->isself || ent->fteext & PEXT_SPLITSCREEN)
{
#ifdef PEXT_SCALE //this is graphics, not physics
if (ent->fteext & PEXT_SCALE)
@ -872,14 +872,14 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
#define EFQW_DARKFIELD 512
#define EFQW_LIGHT 1024
void SV_RemoveEffect(client_t *to, edict_t *ent, int seefno)
void SV_RemoveEffect(client_t *to, edict_t *ent, int seefmask)
{
specialenteffects_t *prev = NULL;
specialenteffects_t *ef;
int en = NUM_FOR_EDICT(svprogfuncs, ent);
for (ef = to->enteffects; ef; ef = ef->next)
{
if (ef->entnum == en && ef->efnum == seefno)
if (ef->entnum == en && ef->efnum & seefmask)
{
if (prev)
prev->next = ef->next;
@ -887,9 +887,30 @@ void SV_RemoveEffect(client_t *to, edict_t *ent, int seefno)
to->enteffects = ef->next;
Z_Free(ef);
ClientReliableWrite_Begin(to, svc_temp_entity, 4);
ClientReliableWrite_Byte(to, TE_SEEF_BRIGHTFIELD+seefno);
ClientReliableWrite_Short(to, en|0x8000);
if (ef->efnum & seefmask & 1>>SEEF_BRIGHTFIELD)
{
ClientReliableWrite_Begin(to, svc_temp_entity, 4);
ClientReliableWrite_Byte(to, TE_SEEF_BRIGHTFIELD);
ClientReliableWrite_Short(to, en|0x8000);
}
if (ef->efnum & seefmask & 1>>SEEF_DARKLIGHT)
{
ClientReliableWrite_Begin(to, svc_temp_entity, 4);
ClientReliableWrite_Byte(to, SEEF_DARKLIGHT);
ClientReliableWrite_Short(to, en|0x8000);
}
if (ef->efnum & seefmask & 1>>SEEF_DARKFIELD)
{
ClientReliableWrite_Begin(to, svc_temp_entity, 4);
ClientReliableWrite_Byte(to, SEEF_DARKFIELD);
ClientReliableWrite_Short(to, en|0x8000);
}
if (ef->efnum & seefmask & 1>>SEEF_LIGHT)
{
ClientReliableWrite_Begin(to, svc_temp_entity, 4);
ClientReliableWrite_Byte(to, SEEF_LIGHT);
ClientReliableWrite_Short(to, en|0x8000);
}
return;
}
prev = ef;
@ -904,7 +925,7 @@ void SV_AddEffect(client_t *to, edict_t *ent, int seefno)
for (ef = to->enteffects; ef; ef = ef->next)
{
if (ef->entnum == en && ef->efnum == seefno)
if (ef->entnum == en && ef->efnum == 1<<seefno)
{
if (ef->colour != ent->v.seefcolour || ef->offset != ent->v.seefoffset || ef->size[0] != ent->v.seefsizex || ef->size[1] != ent->v.seefsizey || ef->size[2] != ent->v.seefsizez || ef->die < sv.time)
{
@ -925,7 +946,7 @@ void SV_AddEffect(client_t *to, edict_t *ent, int seefno)
ef->die = sv.time + 10;
ef->next = to->enteffects;
to->enteffects = ef;
ef->efnum = seefno;
ef->efnum = 1<<seefno;
ef->entnum = en;
ef->colour = ent->v.seefcolour;
ef->offset = ent->v.seefoffset;
@ -958,63 +979,65 @@ void SV_AddEffect(client_t *to, edict_t *ent, int seefno)
void SV_SendExtraEntEffects(client_t *to, edict_t *ent)
{
if (!pr_udc_exteffect_enabled)
return;
if (to->fteprotocolextensions & PEXT_SEEF1)
int removeeffects = 0;
if (pr_udc_exteffect_enabled)
{
if (progstype != PROG_QW)
if (to->fteprotocolextensions & PEXT_SEEF1)
{
if ((int)ent->v.effects & (EF_BRIGHTFIELD|EFNQ_DARKLIGHT|EFNQ_DARKFIELD|EFNQ_LIGHT) || to->enteffects)
if (progstype != PROG_QW)
{
if ((int)ent->v.effects & EF_BRIGHTFIELD)
SV_AddEffect(to, ent, SEEF_BRIGHTFIELD);
else
SV_RemoveEffect(to, ent, SEEF_BRIGHTFIELD);
if ((int)ent->v.effects & (EF_BRIGHTFIELD|EFNQ_DARKLIGHT|EFNQ_DARKFIELD|EFNQ_LIGHT) || to->enteffects)
{
if ((int)ent->v.effects & EF_BRIGHTFIELD)
SV_AddEffect(to, ent, SEEF_BRIGHTFIELD);
else
removeeffects |= 1<<SEEF_BRIGHTFIELD;
if ((int)ent->v.effects & EFNQ_DARKLIGHT)
SV_AddEffect(to, ent, SEEF_DARKLIGHT);
else
SV_RemoveEffect(to, ent, SEEF_DARKLIGHT);
if ((int)ent->v.effects & EFNQ_DARKLIGHT)
SV_AddEffect(to, ent, SEEF_DARKLIGHT);
else
removeeffects |= 1<<SEEF_DARKLIGHT;
if ((int)ent->v.effects & EFNQ_DARKFIELD)
SV_AddEffect(to, ent, SEEF_DARKFIELD);
else
SV_RemoveEffect(to, ent, SEEF_DARKFIELD);
if ((int)ent->v.effects & EFNQ_DARKFIELD)
SV_AddEffect(to, ent, SEEF_DARKFIELD);
else
removeeffects |= 1<<SEEF_DARKFIELD;
if ((int)ent->v.effects & EFNQ_LIGHT)
SV_AddEffect(to, ent, SEEF_LIGHT);
else
SV_RemoveEffect(to, ent, SEEF_LIGHT);
if ((int)ent->v.effects & EFNQ_LIGHT)
SV_AddEffect(to, ent, SEEF_LIGHT);
else
removeeffects |= 1<<SEEF_LIGHT;
}
}
}
else
{
if ((int)ent->v.effects & (EF_BRIGHTFIELD|EFQW_DARKLIGHT|EFQW_DARKFIELD|EFQW_LIGHT) || to->enteffects)
else
{
if ((int)ent->v.effects & EF_BRIGHTFIELD)
SV_AddEffect(to, ent, SEEF_BRIGHTFIELD);
else
SV_RemoveEffect(to, ent, SEEF_BRIGHTFIELD);
if ((int)ent->v.effects & (EF_BRIGHTFIELD|EFQW_DARKLIGHT|EFQW_DARKFIELD|EFQW_LIGHT) || to->enteffects)
{
if ((int)ent->v.effects & EF_BRIGHTFIELD)
SV_AddEffect(to, ent, SEEF_BRIGHTFIELD);
else
removeeffects |= 1<<SEEF_BRIGHTFIELD;
if ((int)ent->v.effects & EFQW_DARKLIGHT)
SV_AddEffect(to, ent, SEEF_DARKLIGHT);
else
SV_RemoveEffect(to, ent, SEEF_DARKLIGHT);
if ((int)ent->v.effects & EFQW_DARKLIGHT)
SV_AddEffect(to, ent, SEEF_DARKLIGHT);
else
removeeffects |= 1<<SEEF_DARKLIGHT;
if ((int)ent->v.effects & EFQW_DARKFIELD)
SV_AddEffect(to, ent, SEEF_DARKFIELD);
else
SV_RemoveEffect(to, ent, SEEF_DARKFIELD);
if ((int)ent->v.effects & EFQW_DARKFIELD)
SV_AddEffect(to, ent, SEEF_DARKFIELD);
else
removeeffects |= 1<<SEEF_DARKFIELD;
if ((int)ent->v.effects & EFQW_LIGHT)
SV_AddEffect(to, ent, SEEF_LIGHT);
else
SV_RemoveEffect(to, ent, SEEF_LIGHT);
if ((int)ent->v.effects & EFQW_LIGHT)
SV_AddEffect(to, ent, SEEF_LIGHT);
else
removeeffects |= 1<<SEEF_LIGHT;
}
}
if (to->enteffects)
SV_RemoveEffect(to, ent, removeeffects);
}
}
}
/*
=============
@ -1868,8 +1891,22 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
if (!ignorepvs)
{
if (!sv.worldmodel->funcs.EdictInFatPVS(ent))
continue;
if (ent->tagent)
{
edict_t *p = ent;
int c = 10;
while(p->tagent&&c-->0)
{
p = EDICT_NUM(svprogfuncs, p->tagent);
}
if (!sv.worldmodel->funcs.EdictInFatPVS(p))
continue;
}
else
{
if (!sv.worldmodel->funcs.EdictInFatPVS(ent))
continue;
}
/*
#ifdef Q2BSPS
if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3)

View file

@ -2991,6 +2991,7 @@ void SV_InitLocal (void)
svs.fteprotocolextensions |= PEXT_256PACKETENTITIES;
// svs.fteprotocolextensions |= PEXT_64PLAYERS;
svs.fteprotocolextensions |= PEXT_SHOWPIC;
svs.fteprotocolextensions |= PEXT_SETATTACHMENT;
// if (svs.protocolextensions)
// Info_SetValueForStarKey (svs.info, "*"DISTRIBUTION"_ext", va("%x", svs.protocolextensions), MAX_SERVERINFO_STRING);

View file

@ -83,6 +83,7 @@ void SV_CheckAllEnts (void)
continue;
if (check->v.movetype == MOVETYPE_PUSH
|| check->v.movetype == MOVETYPE_NONE
|| check->v.movetype == MOVETYPE_FOLLOW
|| check->v.movetype == MOVETYPE_NOCLIP)
continue;
@ -665,6 +666,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove)
continue;
if (check->v.movetype == MOVETYPE_PUSH
|| check->v.movetype == MOVETYPE_NONE
|| check->v.movetype == MOVETYPE_FOLLOW
|| check->v.movetype == MOVETYPE_NOCLIP)
continue;
@ -856,6 +858,51 @@ void SV_Physics_None (edict_t *ent)
SV_RunThink (ent);
}
/*
=============
SV_Physics_Follow
Entities that are "stuck" to another entity
=============
*/
void SV_Physics_Follow (edict_t *ent)
{
vec3_t vf, vr, vu, angles, v;
edict_t *e;
// regular thinking
if (!SV_RunThink (ent))
return;
// LordHavoc: implemented rotation on MOVETYPE_FOLLOW objects
e = PROG_TO_EDICT(svprogfuncs, ent->v.aiment);
if (e->v.angles[0] == ent->v.punchangle[0] && e->v.angles[1] == ent->v.punchangle[1] && e->v.angles[2] == ent->v.punchangle[2])
{
// quick case for no rotation
VectorAdd(e->v.origin, ent->v.view_ofs, ent->v.origin);
}
else
{
angles[0] = -ent->v.punchangle[0];
angles[1] = ent->v.punchangle[1];
angles[2] = ent->v.punchangle[2];
AngleVectors (angles, vf, vr, vu);
v[0] = ent->v.view_ofs[0] * vf[0] + ent->v.view_ofs[1] * vr[0] + ent->v.view_ofs[2] * vu[0];
v[1] = ent->v.view_ofs[0] * vf[1] + ent->v.view_ofs[1] * vr[1] + ent->v.view_ofs[2] * vu[1];
v[2] = ent->v.view_ofs[0] * vf[2] + ent->v.view_ofs[1] * vr[2] + ent->v.view_ofs[2] * vu[2];
angles[0] = -e->v.angles[0];
angles[1] = e->v.angles[1];
angles[2] = e->v.angles[2];
AngleVectors (angles, vf, vr, vu);
ent->v.origin[0] = v[0] * vf[0] + v[1] * vf[1] + v[2] * vf[2] + e->v.origin[0];
ent->v.origin[1] = v[0] * vr[0] + v[1] * vr[1] + v[2] * vr[2] + e->v.origin[1];
ent->v.origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->v.origin[2];
}
VectorAdd (e->v.angles, ent->v.v_angle, ent->v.angles);
SV_LinkEdict (ent, true);
}
/*
=============
SV_Physics_Noclip
@ -1439,7 +1486,7 @@ From normal Quake in an attempt to fix physics in QuakeRally
void SV_Physics_Client (edict_t *ent, int num)
{
qboolean readyforjump;
float oldvel;
// float oldvel;
if ( svs.clients[num-1].state < cs_spawned )
return; // unconnected slot
@ -1477,27 +1524,31 @@ void SV_Physics_Client (edict_t *ent, int num)
break;
case MOVETYPE_WALK:
oldvel = ent->v.velocity[0];
// oldvel = ent->v.velocity[0];
if (!SV_RunThink (ent))
return;
if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
SV_AddGravity (ent, ent->v.gravity);
if (fabs(oldvel - ent->v.velocity[0])> 100)
Con_Printf("grav: %f -> %f\n", oldvel, ent->v.velocity[0]);
// if (fabs(oldvel - ent->v.velocity[0])> 100)
// Con_Printf("grav: %f -> %f\n", oldvel, ent->v.velocity[0]);
SV_CheckStuck (ent);
if (fabs(oldvel - ent->v.velocity[0])> 100)
Con_Printf("stuck: %f -> %f\n", oldvel, ent->v.velocity[0]);
// if (fabs(oldvel - ent->v.velocity[0])> 100)
// Con_Printf("stuck: %f -> %f\n", oldvel, ent->v.velocity[0]);
SV_WalkMove (ent);
if (fabs(oldvel - ent->v.velocity[0])> 100)
Con_Printf("walk: %f -> %f\n", oldvel, ent->v.velocity[0]);
// if (fabs(oldvel - ent->v.velocity[0])> 100)
// Con_Printf("walk: %f -> %f\n", oldvel, ent->v.velocity[0]);
break;
case MOVETYPE_FOLLOW:
SV_Physics_Follow (ent);
break;
case MOVETYPE_TOSS:
case MOVETYPE_BOUNCE:
SV_Physics_Toss (ent);
@ -1570,6 +1621,9 @@ void SV_RunEntity (edict_t *ent)
case MOVETYPE_PUSHPULL:
SV_Physics_Step (ent);
break;
case MOVETYPE_FOLLOW:
SV_Physics_Follow (ent);
break;
case MOVETYPE_TOSS:
case MOVETYPE_BOUNCE:
case MOVETYPE_BOUNCEMISSILE:
@ -1589,7 +1643,7 @@ void SV_RunEntity (edict_t *ent)
break;
default:
SV_Error ("SV_Physics: bad movetype %i on %s", (int)ent->v.movetype, ent->v.classname);
SV_Error ("SV_Physics: bad movetype %i on %s", (int)ent->v.movetype, svprogfuncs->stringtable + ent->v.classname);
}
if (ent2 != sv.edicts)

View file

@ -585,6 +585,9 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
if (client->state != cs_spawned)
continue;
if (client->controller)
continue; //FIXME: send if at least one of the players is near enough.
if (client->fteprotocolextensions & without)
{
// Con_Printf ("Version supressed multicast - without pext\n");

View file

@ -768,8 +768,16 @@ void SV_PreSpawn_f (void)
break;
ent = EDICT_NUM(svprogfuncs, buf - bufs - sv.numextrastatics);
state = &ent->baseline;
if (ent->tagent)
{
MSG_WriteByte(&host_client->netchan.message, svc_setattachment);
MSG_WriteShort(&host_client->netchan.message, ent->entnum);
MSG_WriteShort(&host_client->netchan.message, ent->tagent);
MSG_WriteShort(&host_client->netchan.message, ent->tagindex);
}
state = &ent->baseline;
if (!state->number || !state->modelindex)
{ //ent doesn't have a baseline
buf++;
@ -1130,6 +1138,7 @@ void SV_Begin_f (void)
SV_PreRunCmd();
{
usercmd_t cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.msec = 0;
#define ANGLE2SHORT(x) (x) * (65536/360.0)
cmd.angles[0] = ANGLE2SHORT(split->edict->v.v_angle[0]);
@ -3911,8 +3920,19 @@ haveannothergo:
if (newcmd.impulse)// && SV_FiltureImpulse(newcmd.impulse, host_client->trustlevel))
sv_player->v.impulse = newcmd.impulse;
sv_player->v.button0 = newcmd.buttons & 1;
sv_player->v.button2 = (newcmd.buttons & 2)>>1;
sv_player->v.button2 = (newcmd.buttons >> 1) & 1;
if (pr_allowbutton1.value) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows.
sv_player->v.button1 = ((newcmd.buttons >> 2) & 1);
// DP_INPUTBUTTONS
sv_player->v.button3 = ((newcmd.buttons >> 2) & 1);
sv_player->v.button4 = ((newcmd.buttons >> 3) & 1);
sv_player->v.button5 = ((newcmd.buttons >> 4) & 1);
sv_player->v.button6 = ((newcmd.buttons >> 5) & 1);
sv_player->v.button7 = ((newcmd.buttons >> 6) & 1);
sv_player->v.button8 = ((newcmd.buttons >> 7) & 1);
cl->lastcmd = newcmd;
cl->lastcmd.buttons = 0; // avoid multiple fires on lag

View file

@ -198,6 +198,7 @@ void D_DrawSurfaces (void)
vec3_t world_transformed_modelorg;
vec3_t local_modelorg;
extern int r_dosirds;
extern cvar_t r_fastsky, r_fastskycolour;
currententity = &r_worldentity;
TransformVector (modelorg, transformed_modelorg);
@ -253,17 +254,24 @@ void D_DrawSurfaces (void)
{
if (r_worldentity.model->fromgame == fg_halflife)
continue;
if (!r_skymade)
if (r_fastsky.value)
{
R_MakeSky ();
D_DrawSolidSurface (s, (int)r_fastskycolour.value & 0xFF);
}
if (r_pixbytes == 4)
D_DrawSkyScans32 (s->spans);
else if (r_pixbytes == 2)
D_DrawSkyScans16 (s->spans);
else
D_DrawSkyScans8 (s->spans);
{
if (!r_skymade)
{
R_MakeSky ();
}
if (r_pixbytes == 4)
D_DrawSkyScans32 (s->spans);
else if (r_pixbytes == 2)
D_DrawSkyScans16 (s->spans);
else
D_DrawSkyScans8 (s->spans);
}
D_DrawZSpans (s->spans);
}
else if (s->flags & SURF_DRAWSKYBOX)

View file

@ -760,70 +760,74 @@ void SWDraw_Crosshair(void)
qbyte c = (qbyte)crosshaircolor.value;
qbyte c2 = (qbyte)crosshaircolor.value;
x = scr_vrect.x + scr_vrect.width/2 + cl_crossx.value;
y = scr_vrect.y + scr_vrect.height/2 + cl_crossy.value;
int sc;
#define Pix(xp,yp,c) SWDraw_Pixel(x+xp, y+yp, c)
switch((int)crosshair.value)
for (sc = 0; sc < cl.splitclients; sc++)
{
case 0:
if (*crosshair.string>='a' && *crosshair.string<='z')
SCR_CrosshairPosition(sc, &x, &y);
#define Pix(xp,yp,c) SWDraw_Pixel(x+xp, y+yp, c)
switch((int)crosshair.value)
{
static qbyte *crosshairfile;
static int crosshairfilesize;
static char cachedcrosshairfile[64];
int fx, fy;
qbyte *f;
if (!strncmp(cachedcrosshairfile, crosshair.string, sizeof(cachedcrosshairfile)))
case 0:
if (*crosshair.string>='a' && *crosshair.string<='z')
{
if (crosshairfile)
Z_Free(crosshairfile);
crosshairfile = COM_LoadFile(va("%s.csh", crosshair.string), 0);
crosshairfilesize = com_filesize;
Q_strncpyz(cachedcrosshairfile, crosshair.string, sizeof(cachedcrosshairfile));
}
static qbyte *crosshairfile;
static int crosshairfilesize;
static char cachedcrosshairfile[64];
int fx, fy;
qbyte *f;
f = crosshairfile;
if (!f)
return;
for (fy = 0; fy < 8; fy++)
{
for (fx = 0; fx < 8; )
if (!strncmp(cachedcrosshairfile, crosshair.string, sizeof(cachedcrosshairfile)))
{
if (f - crosshairfile > crosshairfilesize)
{
Con_Printf("Crosshair file has overrun");
fy=10;
break;
}
if (*f == 'x')
{
Pix(fx-3, fy-3, c);
fx++;
}
else if (*f == 'X')
{
Pix(fx-3, fy-3, c2);
fx++;
}
else if (*f == '0' || *f == 'o' || *f == 'O')
fx++;
if (crosshairfile)
Z_Free(crosshairfile);
crosshairfile = COM_LoadFile(va("%s.csh", crosshair.string), 0);
crosshairfilesize = com_filesize;
Q_strncpyz(cachedcrosshairfile, crosshair.string, sizeof(cachedcrosshairfile));
}
f++;
f = crosshairfile;
if (!f)
return;
for (fy = 0; fy < 8; fy++)
{
for (fx = 0; fx < 8; )
{
if (f - crosshairfile > crosshairfilesize)
{
Con_Printf("Crosshair file has overrun");
fy=10;
break;
}
if (*f == 'x')
{
Pix(fx-3, fy-3, c);
fx++;
}
else if (*f == 'X')
{
Pix(fx-3, fy-3, c2);
fx++;
}
else if (*f == '0' || *f == 'o' || *f == 'O')
fx++;
f++;
}
}
}
break;
default:
case 1:
Draw_Character (
scr_vrect.x + scr_vrect.width/2-4 + cl_crossx.value,
scr_vrect.y + scr_vrect.height/2-4 + cl_crossy.value,
'+');
break;
#include "crosshairs.dat"
}
break;
default:
case 1:
Draw_Character (
scr_vrect.x + scr_vrect.width/2-4 + cl_crossx.value,
scr_vrect.y + scr_vrect.height/2-4 + cl_crossy.value,
'+');
break;
#include "crosshairs.dat"
}
}