committing for fixes for OMC

some minor changes. Mostly bug fixes and internal reorganisation.
Added code to provide an activex control as part of the npfte.dll plugin. If the dll is registered the regsvr32 way, the plugin can be used with IE as well.
fisheye/panoramic view enable is now controlled by rulesets instead of serverinfo.
server will list all pak files it has loaded. client will probably do the wrong thing and still needs fixing properly.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3909 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2011-10-27 15:46:36 +00:00
parent 50a8624f59
commit 5118de8bdd
49 changed files with 2739 additions and 1827 deletions

View File

@ -129,9 +129,6 @@ void CDAudio_Play(int track, qboolean looping)
CDAudio_GetAudioDiskInfo(); CDAudio_GetAudioDiskInfo();
if (!cdValid) if (!cdValid)
{ {
#ifndef NOMEDIA
Media_FakeTrack(track, looping);
#endif
return; return;
} }
} }
@ -143,9 +140,6 @@ void CDAudio_Play(int track, qboolean looping)
if (track < 1 || track > maxTrack) if (track < 1 || track > maxTrack)
{ {
#ifndef NOMEDIA
Media_FakeTrack(track, looping);
#endif
Con_DPrintf("CDAudio: Bad track number %u.\n", track); Con_DPrintf("CDAudio: Bad track number %u.\n", track);
return; return;
} }

View File

@ -174,7 +174,7 @@ static float Cam_TryFlyby(vec3_t selforigin, vec3_t playerorigin, vec3_t vec, qb
player_maxs[0] = player_maxs[1] = 16; player_maxs[0] = player_maxs[1] = 16;
player_maxs[2] = 32; player_maxs[2] = 32;
vectoangles(vec, v); VectorAngles(vec, NULL, v);
// v[0] = -v[0]; // v[0] = -v[0];
VectorCopy (v, pmove.angles); VectorCopy (v, pmove.angles);
VectorNormalize(vec); VectorNormalize(vec);
@ -409,7 +409,7 @@ void Cam_SelfTrack(int pnum)
VectorCopy(desired_position[pnum], r_refdef.vieworg); VectorCopy(desired_position[pnum], r_refdef.vieworg);
VectorSubtract(cl.simorg[pnum], desired_position[pnum], vec); VectorSubtract(cl.simorg[pnum], desired_position[pnum], vec);
vectoangles(vec, r_refdef.viewangles); VectorAngles(vec, NULL, r_refdef.viewangles);
r_refdef.viewangles[0] = -r_refdef.viewangles[0]; r_refdef.viewangles[0] = -r_refdef.viewangles[0];
} }
} }
@ -509,7 +509,7 @@ void Cam_Track(int pnum, usercmd_t *cmd)
VectorCopy(desired_position[pnum], self->origin); VectorCopy(desired_position[pnum], self->origin);
VectorSubtract(player->origin, desired_position[pnum], vec); VectorSubtract(player->origin, desired_position[pnum], vec);
vectoangles(vec, cl.viewangles[pnum]); VectorAngles(vec, NULL, cl.viewangles[pnum]);
cl.viewangles[pnum][0] = -cl.viewangles[pnum][0]; cl.viewangles[pnum][0] = -cl.viewangles[pnum][0];
} }

View File

@ -568,8 +568,8 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
mod = &box_model; mod = &box_model;
else else
mod = cl.model_precache[modhandle+1]; mod = cl.model_precache[modhandle+1];
if (mod) if (mod && !mod->needload)
pc = cl.worldmodel->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin); pc = mod->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
else else
pc = 1;//FTECONTENTS_SOLID; pc = 1;//FTECONTENTS_SOLID;
VM_LONG(ret) = pc;//Contents_To_Q3(pc); VM_LONG(ret) = pc;//Contents_To_Q3(pc);
@ -648,8 +648,8 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
TransformedNativeTrace(mod, 0, 0, start, end, mins, maxs, brushmask, &tr, origin, angles); TransformedNativeTrace(mod, 0, 0, start, end, mins, maxs, brushmask, &tr, origin, angles);
#else #else
{ {
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("FIXME: G3 CGame requires TransformedNativeTrace!") #pragma warningmsg("FIXME: G3 CGame requires TransformedNativeTrace!")
#endif #endif
memset(&tr, 0, sizeof(tr)); memset(&tr, 0, sizeof(tr));
tr.allsolid = tr.startsolid = true; tr.allsolid = tr.startsolid = true;
@ -1042,7 +1042,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_FTE_SPAWNPARTICLEEFFECT: case CG_FTE_SPAWNPARTICLEEFFECT:
return pe->RunParticleEffectState(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]), VM_LONG(arg[3]), VM_POINTER(arg[4])); return pe->RunParticleEffectState(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]), VM_LONG(arg[3]), VM_POINTER(arg[4]));
case CG_FTE_SPAWNPARTICLETRAIL: case CG_FTE_SPAWNPARTICLETRAIL:
return pe->ParticleTrail(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), VM_POINTER(arg[3])); return pe->ParticleTrail(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0, VM_POINTER(arg[3]));
case CG_FTE_FREEPARTICLESTATE: case CG_FTE_FREEPARTICLESTATE:
pe->DelinkTrailstate(VM_POINTER(arg[0])); pe->DelinkTrailstate(VM_POINTER(arg[0]));
break; break;

View File

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void CL_FinishTimeDemo (void); void CL_FinishTimeDemo (void);
float demtime; float demtime;
int demoframe;
int cls_lastto; int cls_lastto;
int cls_lasttype; int cls_lasttype;
@ -430,12 +431,12 @@ qboolean CL_GetDemoMessage (void)
olddemotime = 0; olddemotime = 0;
return 0; return 0;
} }
if ((cls.timedemo && cls.netchan.last_received == (float)realtime) || (!cls.timedemo && demtime<= cl.gametime && cl.gametime))// > dem_lasttime+demtime) cls.netchan.last_received = realtime;
if ((cls.timedemo && host_framecount == demoframe) || (!cls.timedemo && demtime<= cl.gametime && cl.gametime))// > dem_lasttime+demtime)
{ {
if (demtime <= cl.gametime-1) if (demtime <= cl.gametime-1)
{ {
demtime = cl.gametime; demtime = cl.gametime;
cls.netchan.last_received = realtime;
} }
{ {
@ -457,6 +458,7 @@ qboolean CL_GetDemoMessage (void)
} }
return 0; return 0;
} }
demoframe = host_framecount;
} }
if (readdemobytes(&demopos, &msglength, 4) != 4) if (readdemobytes(&demopos, &msglength, 4) != 4)
{ {
@ -537,13 +539,12 @@ readnext:
// decide if it is time to grab the next message // decide if it is time to grab the next message
if (cls.timedemo) if (cls.timedemo)
{ {
if (cls.state == ca_active) if (cls.state == ca_active || cl.validsequence)
{ {
if (cls.td_lastframe < 0) if (cls.td_lastframe < 0)
cls.td_lastframe = host_framecount; cls.td_lastframe = demotime;
else if (host_framecount == cls.td_lastframe) else if (host_framecount == cls.td_lastframe)
{ {
cls.td_lastframe = host_framecount;
return 0; // already read this frame's message return 0; // already read this frame's message
} }
if (cls.td_startframe == -1) if (cls.td_startframe == -1)
@ -780,6 +781,7 @@ readit:
demo_flushbytes(demopos); demo_flushbytes(demopos);
olddemotime = demotime; olddemotime = demotime;
cls.td_lastframe = host_framecount;
return 1; return 1;
} }
@ -796,7 +798,7 @@ qboolean CL_GetMessage (void)
if (cls.demoplayback != DPB_NONE) if (cls.demoplayback != DPB_NONE)
return CL_GetDemoMessage (); return CL_GetDemoMessage ();
if (!NET_GetPacket (NS_CLIENT)) if (NET_GetPacket (NS_CLIENT, 0) < 0)
return false; return false;
CL_WriteDemoMessage (&net_message); CL_WriteDemoMessage (&net_message);
@ -1418,8 +1420,8 @@ void CL_PlayDemo_f (void)
} }
#ifdef WEBCLIENT #ifdef WEBCLIENT
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("playdemo http://blah is broken right now") #pragma warningmsg("playdemo http://blah is broken right now")
#endif #endif
#if 0 #if 0
if (!strncmp(Cmd_Argv(1), "ftp://", 6) || !strncmp(Cmd_Argv(1), "http://", 7)) if (!strncmp(Cmd_Argv(1), "ftp://", 6) || !strncmp(Cmd_Argv(1), "http://", 7))
@ -1597,8 +1599,8 @@ void CL_Demo_ClientCommand(char *commandtext)
{ {
unsigned char b = 1; unsigned char b = 1;
unsigned short len = LittleShort((unsigned short)(strlen(commandtext) + 4)); unsigned short len = LittleShort((unsigned short)(strlen(commandtext) + 4));
#ifndef _MSC_VER #ifdef warningmsg
#warning "this needs buffering safely" #pragma warningmsg("this needs buffering safely")
#endif #endif
if (cls.demoplayback == DPB_EZTV) if (cls.demoplayback == DPB_EZTV)
{ {

View File

@ -85,8 +85,8 @@ qboolean CL_FilterModelindex(int modelindex, int frame)
void CL_FreeDlights(void) void CL_FreeDlights(void)
{ {
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("not freeing shadowmeshes") #pragma warningmsg("not freeing shadowmeshes")
#endif #endif
rtlights_max = cl_maxdlights = 0; rtlights_max = cl_maxdlights = 0;
BZ_Free(cl_dlights); BZ_Free(cl_dlights);
@ -103,12 +103,12 @@ static void CL_ClearDlight(dlight_t *dl, int key)
{ {
void *sm; void *sm;
texid_t st; texid_t st;
st = dl->stexture; TEXASSIGNF(st, dl->stexture);
sm = dl->worldshadowmesh; sm = dl->worldshadowmesh;
memset (dl, 0, sizeof(*dl)); memset (dl, 0, sizeof(*dl));
dl->rebuildcache = true; dl->rebuildcache = true;
dl->worldshadowmesh = sm; dl->worldshadowmesh = sm;
dl->stexture = st; TEXASSIGNF(dl->stexture, st);
dl->axis[0][0] = 1; dl->axis[0][0] = 1;
dl->axis[1][1] = 1; dl->axis[1][1] = 1;
dl->axis[2][2] = 1; dl->axis[2][2] = 1;
@ -305,7 +305,7 @@ CL_ParseDelta
Can go from either a baseline or a previous packet_entity Can go from either a baseline or a previous packet_entity
================== ==================
*/ */
int bitcounts[32]; /// just for protocol profiling //int bitcounts[32]; /// just for protocol profiling
void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean new) void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean new)
{ {
int i; int i;
@ -326,9 +326,9 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
} }
// count the bits for net profiling // count the bits for net profiling
for (i=0 ; i<16 ; i++) // for (i=0 ; i<16 ; i++)
if (bits&(1<<i)) // if (bits&(1<<i))
bitcounts[i]++; // bitcounts[i]++;
#ifdef PROTOCOLEXTENSIONS #ifdef PROTOCOLEXTENSIONS
if (bits & U_EVENMORE && (cls.fteprotocolextensions & (PEXT_SCALE|PEXT_TRANS|PEXT_FATNESS|PEXT_HEXEN2|PEXT_COLOURMOD|PEXT_DPFLAGS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2))) if (bits & U_EVENMORE && (cls.fteprotocolextensions & (PEXT_SCALE|PEXT_TRANS|PEXT_FATNESS|PEXT_HEXEN2|PEXT_COLOURMOD|PEXT_DPFLAGS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2)))
@ -757,6 +757,7 @@ void DP5_ParseDelta(entity_state_t *s)
if (bits & E5_FLAGS) if (bits & E5_FLAGS)
{ {
int i = MSG_ReadByte(); int i = MSG_ReadByte();
s->dpflags = i;
s->flags = 0; s->flags = 0;
if (i & RENDER_VIEWMODEL) if (i & RENDER_VIEWMODEL)
s->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; s->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK;
@ -1422,7 +1423,7 @@ void CLQ1_AddShadow(entity_t *ent)
"alphagen vertex\n" "alphagen vertex\n"
"}\n" "}\n"
"}\n"); "}\n");
s->defaulttextures.base = balltexture; TEXASSIGN(s->defaulttextures.base, balltexture);
tx = ent->model->maxs[0] - ent->model->mins[0]; tx = ent->model->maxs[0] - ent->model->mins[0];
ty = ent->model->maxs[1] - ent->model->mins[1]; ty = ent->model->maxs[1] - ent->model->mins[1];
@ -1530,7 +1531,7 @@ void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects
"noshadows\n" "noshadows\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $whitetexture\n" "map $whiteimage\n"
"rgbgen entity\n" "rgbgen entity\n"
"alphagen entity\n" "alphagen entity\n"
"blendfunc src_alpha one\n" "blendfunc src_alpha one\n"
@ -1548,7 +1549,7 @@ void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects
"noshadows\n" "noshadows\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $whitetexture\n" "map $whiteimage\n"
"rgbgen entity\n" "rgbgen entity\n"
"alphagen entity\n" "alphagen entity\n"
"blendfunc src_alpha one\n" "blendfunc src_alpha one\n"
@ -1756,12 +1757,12 @@ static void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entit
//ignore the old packet entirely, except for maybe its time. //ignore the old packet entirely, except for maybe its time.
if (!VectorEquals(le->neworigin, snew->origin) || !VectorEquals(le->newangle, snew->angles)) if (!VectorEquals(le->neworigin, snew->origin) || !VectorEquals(le->newangle, snew->angles))
{ {
le->orglerpdeltatime = bound(0, oldpack->servertime - le->orglerpstarttime, 0.1); //clamp to 10 tics per second le->orglerpdeltatime = bound(0, oldpack->servertime - le->orglerpstarttime, 0.11); //clamp to 10 tics per second
le->orglerpstarttime = oldpack->servertime; le->orglerpstarttime = oldpack->servertime;
VectorCopy(le->neworigin, le->oldorigin); VectorCopy(le->neworigin, le->oldorigin);
VectorCopy(le->newangle, le->oldangle); VectorCopy(le->newangle, le->oldangle);
VectorCopy(snew->origin, le->neworigin); VectorCopy(snew->origin, le->neworigin);
VectorCopy(snew->angles, le->newangle); VectorCopy(snew->angles, le->newangle);
} }
@ -1932,7 +1933,6 @@ void CL_LinkPacketEntities (void)
float servertime; float servertime;
CL_CalcClientTime();
if (cls.protocol == CP_QUAKEWORLD && (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)) if (cls.protocol == CP_QUAKEWORLD && (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV))
{ {
servertime = cl.servertime; servertime = cl.servertime;
@ -1955,7 +1955,10 @@ void CL_LinkPacketEntities (void)
i = servertime*20; i = servertime*20;
if (flickertime != i) if (flickertime != i)
{
flickertime = i;
flicker = rand(); flicker = rand();
}
autorotate = anglemod(100*servertime); autorotate = anglemod(100*servertime);
@ -2088,6 +2091,8 @@ void CL_LinkPacketEntities (void)
ent->flags |= Q2RF_ADDITIVE; ent->flags |= Q2RF_ADDITIVE;
if (state->effects & EF_NODEPTHTEST) if (state->effects & EF_NODEPTHTEST)
ent->flags |= RF_NODEPTHTEST; ent->flags |= RF_NODEPTHTEST;
if (state->effects & DPEF_NOSHADOW)
ent->flags |= RF_NOSHADOW;
if (state->trans != 0xff) if (state->trans != 0xff)
ent->flags |= Q2RF_TRANSLUCENT; ent->flags |= Q2RF_TRANSLUCENT;
@ -2154,7 +2159,7 @@ void CL_LinkPacketEntities (void)
#endif #endif
// rotate binary objects locally // rotate binary objects locally
if (model && model->flags & EF_ROTATE) if (model && model->flags & MF_ROTATE)
{ {
angles[0] = 0; angles[0] = 0;
angles[1] = autorotate; angles[1] = autorotate;
@ -2192,10 +2197,10 @@ void CL_LinkPacketEntities (void)
CLQ1_AddPowerupShell(ent, false, state->effects); CLQ1_AddPowerupShell(ent, false, state->effects);
// add automatic particle trails // add automatic particle trails
if (!model || (!(model->flags&~EF_ROTATE) && model->particletrail<0 && model->particleeffect<0)) if (!model || (!(model->flags&~MF_ROTATE) && model->particletrail<0 && model->particleeffect<0))
continue; continue;
if (!cls.allow_anyparticles && !(model->flags & ~EF_ROTATE)) if (!cls.allow_anyparticles && !(model->flags & ~MF_ROTATE))
continue; continue;
if (le->isnew) if (le->isnew)
@ -2215,7 +2220,7 @@ void CL_LinkPacketEntities (void)
} }
} }
if (model->particletrail == P_INVALID || pe->ParticleTrail (old_origin, ent->origin, model->particletrail, &(le->trailstate))) if (model->particletrail == P_INVALID || pe->ParticleTrail (old_origin, ent->origin, model->particletrail, ent->keynum, &(le->trailstate)))
if (model->traildefaultindex >= 0) if (model->traildefaultindex >= 0)
pe->ParticleTrailIndex(old_origin, ent->origin, model->traildefaultindex, 0, &(le->trailstate)); pe->ParticleTrailIndex(old_origin, ent->origin, model->traildefaultindex, 0, &(le->trailstate));
@ -2237,28 +2242,29 @@ void CL_LinkPacketEntities (void)
dclr[1] = 0.10; dclr[1] = 0.10;
dclr[2] = 0; dclr[2] = 0;
if (model->flags & EF_ROCKET) if (model->flags & MF_ROCKET)
{ {
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("Replace this flag on load for hexen2 models") #pragma warningmsg("Replace this flag on load for hexen2 models")
#endif #endif
if (strncmp(model->name, "models/sflesh", 13)) if (strncmp(model->name, "models/sflesh", 13))
{ //hmm. hexen spider gibs... { //hmm. hexen spider gibs...
rad = 200; rad = 200;
dclr[2] = 0.05; dclr[2] = 0.05;
rad += r_lightflicker.value?((flicker + state->number)&31):0;
} }
} }
else if (model->flags & EFH2_FIREBALL) else if (model->flags & MFH2_FIREBALL)
{ {
rad = 120 - (rand() % 20); rad = 120 - (rand() % 20);
} }
else if (model->flags & EFH2_ACIDBALL) else if (model->flags & MFH2_ACIDBALL)
{ {
rad = 120 - (rand() % 20); rad = 120 - (rand() % 20);
dclr[0] = 0.1; dclr[0] = 0.1;
dclr[1] = 0.2; dclr[1] = 0.2;
} }
else if (model->flags & EFH2_SPIT) else if (model->flags & MFH2_SPIT)
{ {
// as far as I can tell this effect inverses the light... // as far as I can tell this effect inverses the light...
dclr[0] = -dclr[0]; dclr[0] = -dclr[0];
@ -2273,7 +2279,7 @@ void CL_LinkPacketEntities (void)
memcpy(dl->axis, ent->axis, sizeof(dl->axis)); memcpy(dl->axis, ent->axis, sizeof(dl->axis));
VectorCopy (ent->origin, dl->origin); VectorCopy (ent->origin, dl->origin);
dl->die = (float)cl.time; dl->die = (float)cl.time;
if (model->flags & EF_ROCKET) if (model->flags & MF_ROCKET)
dl->origin[2] += 1; // is this even necessary dl->origin[2] += 1; // is this even necessary
dl->radius = rad * r_rocketlight.value; dl->radius = rad * r_rocketlight.value;
VectorCopy(dclr, dl->color); VectorCopy(dclr, dl->color);

View File

@ -777,8 +777,11 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
// always dump the first two message, because it may contain leftover inputs // always dump the first two message, because it may contain leftover inputs
// from the last level // from the last level
// //
if (++cl.movemessages <= 2) if (++cl.movemessages <= 2 || cls.state == ca_connected)
{
MSG_WriteByte (buf, clc_nop);
return; return;
}
MSG_WriteByte (buf, clc_move); MSG_WriteByte (buf, clc_move);
@ -1018,9 +1021,9 @@ void CL_AllowIndependantSendCmd(qboolean allow)
if (allowindepphys != allow && runningindepphys) if (allowindepphys != allow && runningindepphys)
{ {
if (allow) if (allow)
Sys_UnlockMutex(&indeplock); Sys_UnlockMutex(indeplock);
else else
Sys_LockMutex(&indeplock); Sys_LockMutex(indeplock);
allowindepphys = allow; allowindepphys = allow;
} }
} }
@ -1043,11 +1046,11 @@ int CL_IndepPhysicsThread(void *param)
spare = 15; spare = 15;
time -= spare/1000.0f; time -= spare/1000.0f;
Sys_LockMutex(&indeplock); Sys_LockMutex(indeplock);
if (cls.state) if (cls.state)
CL_SendCmd(time - lasttime, false); CL_SendCmd(time - lasttime, false);
lasttime = time; lasttime = time;
Sys_UnlockMutex(&indeplock); Sys_UnlockMutex(indeplock);
} }
fps = cl_netfps.value; fps = cl_netfps.value;
@ -1225,6 +1228,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf)
int checksumIndex, firstsize, plnum; int checksumIndex, firstsize, plnum;
int clientcount, lost; int clientcount, lost;
int curframe = cls.netchan.outgoing_sequence & UPDATE_MASK; int curframe = cls.netchan.outgoing_sequence & UPDATE_MASK;
int st = buf->cursize;
seq_hash = cls.netchan.outgoing_sequence; seq_hash = cls.netchan.outgoing_sequence;
@ -1316,7 +1320,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf)
cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1; cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1;
if (cl.sendprespawn) if (cl.sendprespawn)
buf->cursize = 0; //tastyspleen.net is alergic. buf->cursize = st; //tastyspleen.net is alergic.
return dontdrop; return dontdrop;
} }
@ -1413,6 +1417,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
return; // sendcmds come from the demo return; // sendcmds come from the demo
} }
memset(&buf, 0, sizeof(buf));
buf.maxsize = sizeof(data); buf.maxsize = sizeof(data);
buf.cursize = 0; buf.cursize = 0;
buf.data = data; buf.data = data;
@ -1451,7 +1456,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
if (!runningindepphys) if (!runningindepphys)
{ {
// while we're not playing send a slow keepalive fullsend to stop mvdsv from screwing up // while we're not playing send a slow keepalive fullsend to stop mvdsv from screwing up
if (cls.state < ca_active) if (cls.state < ca_active && !cls.downloadmethod)
{ {
#ifdef IRCCONNECT //don't spam irc. #ifdef IRCCONNECT //don't spam irc.
if (cls.netchan.remote_address.type == NA_IRC) if (cls.netchan.remote_address.type == NA_IRC)
@ -1513,7 +1518,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
// if (skipcmd) // if (skipcmd)
// return; // return;
if (!fullsend && cls.state == ca_active) if (!fullsend)
return; // when we're actually playing we try to match netfps exactly to avoid gameplay problems return; // when we're actually playing we try to match netfps exactly to avoid gameplay problems
#ifdef NQPROT #ifdef NQPROT
@ -1527,14 +1532,14 @@ void CL_SendCmd (double frametime, qboolean mainloop)
next = clientcmdlist->next; next = clientcmdlist->next;
if (clientcmdlist->reliable) if (clientcmdlist->reliable)
{ {
if (cls.netchan.message.cursize + 2+strlen(clientcmdlist->command) > cls.netchan.message.maxsize) if (cls.netchan.message.cursize + 2+strlen(clientcmdlist->command)+100 > cls.netchan.message.maxsize)
break; break;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, clientcmdlist->command); MSG_WriteString (&cls.netchan.message, clientcmdlist->command);
} }
else else
{ {
if (buf.cursize + 2+strlen(clientcmdlist->command) <= buf.maxsize) if (buf.cursize + 2+strlen(clientcmdlist->command)+100 <= buf.maxsize)
{ {
MSG_WriteByte (&buf, clc_stringcmd); MSG_WriteByte (&buf, clc_stringcmd);
MSG_WriteString (&buf, clientcmdlist->command); MSG_WriteString (&buf, clientcmdlist->command);

View File

@ -60,6 +60,7 @@ cvar_t cl_defaultport = CVARAF("cl_defaultport", STRINGIFY(PORT_QWSERVER), "por
cvar_t cfg_save_name = CVARF("cfg_save_name", "fte", CVAR_ARCHIVE); cvar_t cfg_save_name = CVARF("cfg_save_name", "fte", CVAR_ARCHIVE);
cvar_t cl_packagedownloads = CVAR("cl_packagedownloads", "1");
cvar_t cl_splitscreen = CVAR("cl_splitscreen", "0"); cvar_t cl_splitscreen = CVAR("cl_splitscreen", "0");
cvar_t lookspring = CVARF("lookspring","0", CVAR_ARCHIVE); cvar_t lookspring = CVARF("lookspring","0", CVAR_ARCHIVE);
@ -73,7 +74,6 @@ cvar_t m_yaw = CVARF("m_yaw","0.022", CVAR_ARCHIVE);
cvar_t m_forward = CVARF("m_forward","1", CVAR_ARCHIVE); cvar_t m_forward = CVARF("m_forward","1", CVAR_ARCHIVE);
cvar_t m_side = CVARF("m_side","0.8", CVAR_ARCHIVE); cvar_t m_side = CVARF("m_side","0.8", CVAR_ARCHIVE);
cvar_t entlatency = CVAR("entlatency", "20");
cvar_t cl_predict_players = CVAR("cl_predict_players", "1"); cvar_t cl_predict_players = CVAR("cl_predict_players", "1");
cvar_t cl_solid_players = CVAR("cl_solid_players", "1"); cvar_t cl_solid_players = CVAR("cl_solid_players", "1");
cvar_t cl_noblink = CVAR("cl_noblink", "0"); cvar_t cl_noblink = CVAR("cl_noblink", "0");
@ -91,8 +91,6 @@ cvar_t cl_threadedphysics = CVAR("cl_threadedphysics", "0");
cvar_t localid = SCVAR("localid", ""); cvar_t localid = SCVAR("localid", "");
cvar_t cl_antibunch = CVAR("cl_antibunch", "0");
cvar_t r_drawflame = CVAR("r_drawflame", "1"); cvar_t r_drawflame = CVAR("r_drawflame", "1");
static qboolean allowremotecmd = true; static qboolean allowremotecmd = true;
@ -138,17 +136,17 @@ cvar_t cl_gunanglex = SCVAR("cl_gunanglex", "0");
cvar_t cl_gunangley = SCVAR("cl_gunangley", "0"); cvar_t cl_gunangley = SCVAR("cl_gunangley", "0");
cvar_t cl_gunanglez = SCVAR("cl_gunanglez", "0"); cvar_t cl_gunanglez = SCVAR("cl_gunanglez", "0");
cvar_t allow_download_csprogs = SCVARF("allow_download_csprogs", "1", CVAR_NOTFROMSERVER); cvar_t cl_download_csprogs = CVARFD("cl_download_csprogs", "1", CVAR_NOTFROMSERVER, "Download updated client gamecode if available.");
cvar_t allow_download_redirection = SCVARF("allow_download_redirection", "0", CVAR_NOTFROMSERVER); cvar_t cl_download_redirection = CVARFD("cl_download_redirection", "0", CVAR_NOTFROMSERVER, "Follow download redirection to download packages instead of individual files.");
cvar_t requiredownloads = SCVARF("requiredownloads","1", CVAR_ARCHIVE); cvar_t cl_download_mapsrc = CVARD("cl_download_mapsrc", "", "Specifies an http location prefix for map downloads. EG: \"http://bigfoot.morphos-team.net/misc/quakemaps/\"");
cvar_t cl_download_packages = CVARFD("cl_download_packages", "1", CVAR_NOTFROMSERVER, "0=Do not download packages simply because the server is using them. 1=Do download, but don't use them by default. 2=Do download and install permanently (use with caution!)");
cvar_t requiredownloads = CVARFD("requiredownloads","1", CVAR_ARCHIVE, "0=join the game before downloads have even finished (might be laggy). 1=wait for all downloads to complete before joining.");
cvar_t cl_muzzleflash = SCVAR("cl_muzzleflash", "1"); cvar_t cl_muzzleflash = SCVAR("cl_muzzleflash", "1");
cvar_t cl_item_bobbing = SCVAR("cl_model_bobbing", "0"); cvar_t cl_item_bobbing = SCVAR("cl_model_bobbing", "0");
cvar_t cl_countpendingpl = SCVAR("cl_countpendingpl", "0"); cvar_t cl_countpendingpl = SCVAR("cl_countpendingpl", "0");
cvar_t cl_download_mapsrc = SCVAR("cl_download_mapsrc", ""); //EG: "http://bigfoot.morphos-team.net/misc/quakemaps/"
cvar_t cl_standardchat = SCVARF("cl_standardchat", "0", CVAR_ARCHIVE); cvar_t cl_standardchat = SCVARF("cl_standardchat", "0", CVAR_ARCHIVE);
cvar_t msg_filter = SCVAR("msg_filter", "0"); //0 for neither, 1 for mm1, 2 for mm2, 3 for both cvar_t msg_filter = SCVAR("msg_filter", "0"); //0 for neither, 1 for mm1, 2 for mm2, 3 for both
cvar_t cl_standardmsg = SCVARF("cl_standardmsg", "0", CVAR_ARCHIVE); cvar_t cl_standardmsg = SCVARF("cl_standardmsg", "0", CVAR_ARCHIVE);
@ -636,6 +634,9 @@ char *CL_TryingToConnect(void)
return cls.servername; return cls.servername;
} }
int SV_NewChallenge (void);
client_t *SVC_DirectConnect(void);
/* /*
================= =================
CL_CheckForResend CL_CheckForResend
@ -670,12 +671,26 @@ void CL_CheckForResend (void)
break; break;
#endif #endif
default: default:
cl.movemessages = 0;
if (!strcmp(cl_loopbackprotocol.string, "qw")) if (!strcmp(cl_loopbackprotocol.string, "qw"))
cls.protocol = CP_QUAKEWORLD; cls.protocol = CP_QUAKEWORLD;
else if (!strcmp(cl_loopbackprotocol.string, "nq")) else if (!strcmp(cl_loopbackprotocol.string, "nq"))
{
cls.protocol = CP_NETQUAKE; cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_ID;
}
else if (!strcmp(cl_loopbackprotocol.string, "q3")) else if (!strcmp(cl_loopbackprotocol.string, "q3"))
cls.protocol = CP_QUAKE3; cls.protocol = CP_QUAKE3;
else if (!strcmp(cl_loopbackprotocol.string, "dp6"))
{
cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_DP7;
}
else if (!strcmp(cl_loopbackprotocol.string, "dp7"))
{
cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_DP7;
}
else if (progstype == PROG_QW) else if (progstype == PROG_QW)
cls.protocol = CP_QUAKEWORLD; cls.protocol = CP_QUAKEWORLD;
else else
@ -695,8 +710,15 @@ void CL_CheckForResend (void)
} }
NET_AdrToString(data, sizeof(data), adr); NET_AdrToString(data, sizeof(data), adr);
//by NQ, we mean to try using the DP protocol extensions to the underlying NQ protocol if (cls.protocol_nq == CPNQ_ID)
CL_ConnectToDarkPlaces("", adr); {
net_from = adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()), false, false);
SVC_DirectConnect();
}
else
CL_ConnectToDarkPlaces("", adr);
} }
else else
CL_SendConnectPacket (svs.fteprotocolextensions, svs.fteprotocolextensions2, false); CL_SendConnectPacket (svs.fteprotocolextensions, svs.fteprotocolextensions2, false);
@ -1458,6 +1480,41 @@ void CL_Color_f (void)
#endif #endif
} }
void FS_GenCachedPakName(char *pname, char *crc, char *local, int llen);
qboolean CL_CheckDLFile(char *filename);
void CL_PakDownloads(int mode)
{
/*
mode=0 no downloads (forced to 1 for pure)
mode=1 archived names so local stuff is not poluted
mode=2 downloaded packages will always be present. Use With Caution.
*/
char local[256];
char *pname;
char *s = cl.serverpakcrcs;
int i;
if (!cl.serverpakschanged || !mode)
return;
Cmd_TokenizeString(cl.serverpaknames, false, false);
for (i = 0; i < Cmd_Argc(); i++)
{
s = COM_Parse(s);
pname = Cmd_Argv(i);
if (mode != 2)
{
/*if we already have such a file, this is a no-op*/
if (CL_CheckDLFile(va("package/%s", pname)))
continue;
FS_GenCachedPakName(pname, com_token, local, sizeof(local));
}
else
Q_strncpyz(local, pname, sizeof(local));
CL_CheckOrEnqueDownloadFile(pname, local, DLLF_NONGAME);
}
}
void CL_CheckServerInfo(void) void CL_CheckServerInfo(void)
{ {
@ -1477,10 +1534,7 @@ void CL_CheckServerInfo(void)
cls.allow_skyboxes=false; cls.allow_skyboxes=false;
cls.allow_mirrors=false; cls.allow_mirrors=false;
cls.allow_luma=false; cls.allow_luma=false;
cls.allow_bump=false; cls.allow_postproc=false;
#ifdef FISH
cls.allow_fish=false;
#endif
cls.allow_fbskins = 1; cls.allow_fbskins = 1;
// cls.allow_fbskins = 0; // cls.allow_fbskins = 0;
// cls.allow_overbrightlight; // cls.allow_overbrightlight;
@ -1503,13 +1557,9 @@ void CL_CheckServerInfo(void)
if (cl.spectator || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_lmgamma"))) if (cl.spectator || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_lmgamma")))
cls.allow_lightmapgamma=true; cls.allow_lightmapgamma=true;
s = Info_ValueForKey(cl.serverinfo, "allow_bump"); s = Info_ValueForKey(cl.serverinfo, "allow_fish");
if (cl.spectator || cls.demoplayback || atoi(s) || !*s) //admin doesn't care. if (cl.spectator || cls.demoplayback || !*s || atoi(s))
cls.allow_bump=true; cls.allow_postproc=true;
#ifdef FISH
if (cl.spectator || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_fish")))
cls.allow_fish=true;
#endif
s = Info_ValueForKey(cl.serverinfo, "fbskins"); s = Info_ValueForKey(cl.serverinfo, "fbskins");
if (*s) if (*s)
@ -1579,12 +1629,8 @@ void CL_CheckServerInfo(void)
//16 //16
if (allowed & 32) if (allowed & 32)
cls.allow_luma = true; cls.allow_luma = true;
if (allowed & 64)
cls.allow_bump = true;
#ifdef FISH
if (allowed & 128) if (allowed & 128)
cls.allow_fish = true; cls.allow_postproc = true;
#endif
if (allowed & 256) if (allowed & 256)
cls.allow_lightmapgamma = true; cls.allow_lightmapgamma = true;
if (allowed & 512) if (allowed & 512)
@ -1613,6 +1659,17 @@ void CL_CheckServerInfo(void)
if (oldstate != cl.matchstate) if (oldstate != cl.matchstate)
cl.matchgametime = 0; cl.matchgametime = 0;
if (atoi(Info_ValueForKey(cl.serverinfo, "sv_pure")))
{
CL_PakDownloads((!cl_packagedownloads.ival)?1:cl_packagedownloads.ival);
FS_ForceToPure(cl.serverpaknames, cl.serverpakcrcs, cls.challenge);
}
else
{
CL_PakDownloads(cl_packagedownloads.ival);
FS_ImpurePacks(cl.serverpaknames, cl.serverpakcrcs);
}
Cvar_ForceCheatVars(cls.allow_semicheats, cls.allow_cheats); Cvar_ForceCheatVars(cls.allow_semicheats, cls.allow_cheats);
Validation_Apply_Ruleset(); Validation_Apply_Ruleset();
@ -2362,7 +2419,7 @@ void CL_ConnectionlessPacket (void)
CL_ParseEstablished(); CL_ParseEstablished();
Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername); Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername);
/*this is a DP server... but we don't know which version*/
cls.netchan.isnqprotocol = true; cls.netchan.isnqprotocol = true;
cls.protocol = CP_NETQUAKE; cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_ID; cls.protocol_nq = CPNQ_ID;
@ -2503,6 +2560,7 @@ void CLNQ_ConnectionlessPacket(void)
{ {
char *s; char *s;
int length; int length;
unsigned short port;
MSG_BeginReading (msg_nullnetprim); MSG_BeginReading (msg_nullnetprim);
length = LongSwap(MSG_ReadLong ()); length = LongSwap(MSG_ReadLong ());
@ -2521,8 +2579,11 @@ void CLNQ_ConnectionlessPacket(void)
Con_TPrintf (TLC_DUPCONNECTION); Con_TPrintf (TLC_DUPCONNECTION);
return; return;
} }
port = htons((unsigned short)MSG_ReadLong());
//this is the port that we're meant to respond to. //this is the port that we're meant to respond to.
net_from.port = htons((short)MSG_ReadLong());
if (port)
net_from.port = port;
cls.protocol_nq = CPNQ_ID; cls.protocol_nq = CPNQ_ID;
if (MSG_ReadByte() == 1) //a proquake server adds a little extra info if (MSG_ReadByte() == 1) //a proquake server adds a little extra info
@ -2581,38 +2642,6 @@ void CL_ReadPackets (void)
// while (NET_GetPacket ()) // while (NET_GetPacket ())
for(;;) for(;;)
{ {
if (cl.oldgametime && cl_antibunch.value)
{
float want;
static float clamp;
want = cl.oldgametime + realtime - cl.gametimemark - clamp;
if (want>cl.time) //don't decrease
{
clamp = 0;
cl.time = want;
}
if (cl.time > cl.gametime)
{
clamp += cl.time - cl.gametime;
cl.time = cl.gametime;
}
if (cl.time < cl.oldgametime)
{
clamp -= cl.time - cl.gametime;
cl.time = cl.oldgametime;
}
if (cl.time < cl.gametime-(1/cl_antibunch.value))
{
// if (cl.gametime - 2 > cl.time)
// cl.gametime = 0;
break;
}
}
if (!CL_GetMessage()) if (!CL_GetMessage())
break; break;
@ -2844,7 +2873,7 @@ void CL_DownloadSize_f(void)
dl = CL_DownloadFailed(rname); dl = CL_DownloadFailed(rname);
if (allow_download_redirection.ival) if (cl_download_redirection.ival)
{ {
Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection); Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection);
CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags); CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags);
@ -3069,7 +3098,6 @@ void CL_Init (void)
Cvar_Register (&rcon_password, cl_controlgroup); Cvar_Register (&rcon_password, cl_controlgroup);
Cvar_Register (&rcon_address, cl_controlgroup); Cvar_Register (&rcon_address, cl_controlgroup);
Cvar_Register (&entlatency, cl_predictiongroup);
Cvar_Register (&cl_predict_players, cl_predictiongroup); Cvar_Register (&cl_predict_players, cl_predictiongroup);
Cvar_Register (&cl_solid_players, cl_predictiongroup); Cvar_Register (&cl_solid_players, cl_predictiongroup);
@ -3100,8 +3128,8 @@ void CL_Init (void)
Cvar_Register (&r_drawflame, "Item effects"); Cvar_Register (&r_drawflame, "Item effects");
Cvar_Register (&allow_download_csprogs, cl_controlgroup); Cvar_Register (&cl_download_csprogs, cl_controlgroup);
Cvar_Register (&allow_download_redirection, cl_controlgroup); Cvar_Register (&cl_download_redirection, cl_controlgroup);
// //
// info mirrors // info mirrors
@ -3113,7 +3141,7 @@ void CL_Init (void)
Cvar_Register (&model, cl_controlgroup); Cvar_Register (&model, cl_controlgroup);
Cvar_Register (&team, cl_controlgroup); Cvar_Register (&team, cl_controlgroup);
Cvar_Register (&topcolor, cl_controlgroup); Cvar_Register (&topcolor, cl_controlgroup);
Cvar_Register (&bottomcolor, cl_controlgroup); Cvar_Register (&bottomcolor, cl_controlgroup);
Cvar_Register (&rate, cl_controlgroup); Cvar_Register (&rate, cl_controlgroup);
Cvar_Register (&drate, cl_controlgroup); Cvar_Register (&drate, cl_controlgroup);
Cvar_Register (&msg, cl_controlgroup); Cvar_Register (&msg, cl_controlgroup);
@ -3138,12 +3166,12 @@ void CL_Init (void)
Cvar_Register (&host_mapname, "Scripting"); Cvar_Register (&host_mapname, "Scripting");
Cvar_Register (&cl_packagedownloads, cl_controlgroup);
#ifndef SERVERONLY #ifndef SERVERONLY
Cvar_Register (&cl_loopbackprotocol, cl_controlgroup); Cvar_Register (&cl_loopbackprotocol, cl_controlgroup);
#endif #endif
Cvar_Register (&cl_countpendingpl, cl_controlgroup); Cvar_Register (&cl_countpendingpl, cl_controlgroup);
Cvar_Register (&cl_threadedphysics, cl_controlgroup); Cvar_Register (&cl_threadedphysics, cl_controlgroup);
Cvar_Register (&cl_antibunch, "evil hacks");
Cvar_Register (&hud_tracking_show, "statusbar"); Cvar_Register (&hud_tracking_show, "statusbar");
Cvar_Register (&cl_download_mapsrc, cl_controlgroup); Cvar_Register (&cl_download_mapsrc, cl_controlgroup);
@ -3560,6 +3588,7 @@ double Host_Frame (double time)
// fetch results from server // fetch results from server
CL_ReadPackets (); CL_ReadPackets ();
CL_CalcClientTime();
// send intentions now // send intentions now
// resend a connection request if necessary // resend a connection request if necessary

View File

@ -343,6 +343,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
return false; return false;
} }
/*reject if it already failed*/
if (!(flags & DLLF_IGNOREFAILED)) if (!(flags & DLLF_IGNOREFAILED))
{ {
#ifdef NQPROT #ifdef NQPROT
@ -362,6 +363,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
} }
} }
/*check for dupes*/
for (dl = cl.downloadlist; dl; dl = dl->next) //It's already on our list. Ignore it. for (dl = cl.downloadlist; dl; dl = dl->next) //It's already on our list. Ignore it.
{ {
if (!strcmp(dl->rname, filename)) if (!strcmp(dl->rname, filename))
@ -398,7 +400,9 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
| PEXT_PK3DOWNLOADS | PEXT_PK3DOWNLOADS
#endif #endif
))) )))
{
CL_SendClientCommand(true, "dlsize \"%s\"", dl->rname); CL_SendClientCommand(true, "dlsize \"%s\"", dl->rname);
}
if (flags & DLLF_VERBOSE) if (flags & DLLF_VERBOSE)
Con_Printf("Enqued download of \"%s\"\n", filename); Con_Printf("Enqued download of \"%s\"\n", filename);
@ -406,8 +410,8 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
return true; return true;
} }
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("fix this") #pragma warningmsg("fix this")
#endif #endif
int downloadsize; int downloadsize;
void CL_GetDownloadSizes(unsigned int *filecount, unsigned int *totalsize, qboolean *somesizesunknown) void CL_GetDownloadSizes(unsigned int *filecount, unsigned int *totalsize, qboolean *somesizesunknown)
@ -528,7 +532,17 @@ void CL_DownloadFinished(void)
{ {
if (strcmp(tempname, filename)) if (strcmp(tempname, filename))
{ {
if (strncmp(tempname,"skins/",6)) if (!strncmp(tempname,"package/",8))
{
if (FS_Rename(tempname+8, filename+8, FS_ROOT))
{
char nativetmp[MAX_OSPATH], nativefinal[MAX_OSPATH];;
FS_NativePath(tempname+8, FS_ROOT, nativetmp, sizeof(nativetmp));
FS_NativePath(filename+8, FS_ROOT, nativefinal, sizeof(nativefinal));
Con_Printf("Couldn't rename %s to %s\n", nativetmp, nativefinal);
}
}
else if (strncmp(tempname,"skins/",6))
{ {
if (FS_Rename(tempname, filename, FS_GAME)) if (FS_Rename(tempname, filename, FS_GAME))
{ {
@ -555,8 +569,11 @@ void CL_DownloadFinished(void)
if (!strcmp(ext, "pk3") || !strcmp(ext, "pak")) if (!strncmp(ext, "pk4", 3) || !strncmp(ext, "pk3", 3) || !strncmp(ext, "pak", 3))
{
FS_ReloadPackFiles(); FS_ReloadPackFiles();
CL_CheckServerInfo();
}
else if (!strcmp(filename, "gfx/palette.lmp")) else if (!strcmp(filename, "gfx/palette.lmp"))
{ {
Cbuf_AddText("vid_restart\n", RESTRICT_LOCAL); Cbuf_AddText("vid_restart\n", RESTRICT_LOCAL);
@ -614,6 +631,23 @@ qboolean CL_CheckFile(char *filename)
} }
return false; return false;
} }
qboolean CL_CheckDLFile(char *filename)
{
if (!strncmp(filename, "package/", 8))
{
vfsfile_t *f;
f = FS_OpenVFS(filename+8, "rb", FS_ROOT);
if (f)
{
VFS_CLOSE(f);
return true;
}
return false;
}
else
return COM_FCheckExists(filename);
}
/* /*
=============== ===============
CL_CheckOrEnqueDownloadFile CL_CheckOrEnqueDownloadFile
@ -624,16 +658,31 @@ Returns true if the file exists, returns false if it triggered a download.
qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags) qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags)
{ //returns false if we don't have the file yet. { //returns false if we don't have the file yet.
if (flags & DLLF_NONGAME)
{
/*pak/pk3 downloads have an explicit leading package/ as an internal/network marker*/
filename = va("package/%s", filename);
localname = va("package/%s", localname);
}
/*files with a leading * should not be downloaded (inline models, sexed sounds, etc)*/
else if (*filename == '*' || !strncmp(filename, "package/", 8))
return true;
if (!localname) if (!localname)
localname = filename; localname = filename;
#ifndef CLIENTONLY #ifndef CLIENTONLY
/*no downloading if we're the one we'd be downloading from*/
if (sv.state) if (sv.state)
return true; return true;
#endif #endif
if (!(flags & DLLF_OVERWRITE) && CL_CheckFile(localname)) if (!(flags & DLLF_OVERWRITE))
return true; {
if (CL_CheckDLFile(localname))
return true;
}
//ZOID - can't download when recording //ZOID - can't download when recording
if (cls.demorecording) if (cls.demorecording)
@ -886,7 +935,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
extern model_t *loadmodel; extern model_t *loadmodel;
int i; int i;
float giveuptime = Sys_DoubleTime()+0.1; //small things get padded into a single frame float giveuptime = Sys_DoubleTime()+0.3; //small things get padded into a single frame
#define atstage() ((cl.contentstage == stage++ && !dontactuallyload)?++cl.contentstage:false) #define atstage() ((cl.contentstage == stage++ && !dontactuallyload)?++cl.contentstage:false)
#define endstage() if (!cls.timedemo && giveuptime<Sys_DoubleTime()) return -1; #define endstage() if (!cls.timedemo && giveuptime<Sys_DoubleTime()) return -1;
@ -903,9 +952,9 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
s = Info_ValueForKey(cl.serverinfo, "*csprogs"); s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s) //only allow csqc if the server says so, and the 'checksum' matches. if (*s) //only allow csqc if the server says so, and the 'checksum' matches.
{ {
extern cvar_t allow_download_csprogs; extern cvar_t cl_download_csprogs;
unsigned int chksum = strtoul(s, NULL, 0); unsigned int chksum = strtoul(s, NULL, 0);
if (allow_download_csprogs.ival) if (cl_download_csprogs.ival)
{ {
char *str = va("csprogsvers/%x.dat", chksum); char *str = va("csprogsvers/%x.dat", chksum);
if (CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED)) if (CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED))
@ -934,7 +983,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
{ {
char *s; char *s;
qboolean anycsqc; qboolean anycsqc;
#if 0//ndef FTE_DEBUG #ifdef _DEBUG
anycsqc = true; anycsqc = true;
#else #else
anycsqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc")); anycsqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc"));
@ -1187,12 +1236,12 @@ void Sound_CheckDownloads (void)
s = Info_ValueForKey(cl.serverinfo, "*csprogs"); s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s) //only allow csqc if the server says so, and the 'checksum' matches. if (*s) //only allow csqc if the server says so, and the 'checksum' matches.
{ {
extern cvar_t allow_download_csprogs, cl_nocsqc; extern cvar_t cl_download_csprogs, cl_nocsqc;
unsigned int chksum = strtoul(s, NULL, 0); unsigned int chksum = strtoul(s, NULL, 0);
if (cl_nocsqc.ival || cls.demoplayback) if (cl_nocsqc.ival || cls.demoplayback)
{ {
} }
else if (allow_download_csprogs.ival) else if (cl_download_csprogs.ival)
{ {
char *str = va("csprogsvers/%x.dat", chksum); char *str = va("csprogsvers/%x.dat", chksum);
CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED); CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED);
@ -1221,9 +1270,11 @@ void CL_RequestNextDownload (void)
{ {
int stage; int stage;
/*already downloading*/
if (cls.downloadmethod) if (cls.downloadmethod)
return; return;
/*request downloads only if we're at the point where we've received a complete list of them*/
if (cl.sendprespawn || cls.state == ca_active) if (cl.sendprespawn || cls.state == ca_active)
if (cl.downloadlist) if (cl.downloadlist)
{ {
@ -1233,16 +1284,25 @@ void CL_RequestNextDownload (void)
//download required downloads first //download required downloads first
for (dl = cl.downloadlist; dl; dl = dl->next) for (dl = cl.downloadlist; dl; dl = dl->next)
{ {
if (dl->flags & DLLF_REQUIRED) if (dl->flags & DLLF_NONGAME)
break; break;
} }
if (!dl) if (!dl)
dl = cl.downloadlist; {
for (dl = cl.downloadlist; dl; dl = dl->next)
{
if (dl->flags & DLLF_REQUIRED)
break;
}
if (!dl)
dl = cl.downloadlist;
}
fl = dl->flags; fl = dl->flags;
/*if we don't require downloads don't queue requests until we're actually on the server, slightly more deterministic*/
if (cls.state == ca_active || requiredownloads.value || (fl & DLLF_REQUIRED)) if (cls.state == ca_active || requiredownloads.value || (fl & DLLF_REQUIRED))
{ {
if ((fl & DLLF_OVERWRITE) || !COM_FCheckExists (dl->localname)) if ((fl & DLLF_OVERWRITE) || !CL_CheckFile (dl->localname))
{ {
CL_SendDownloadStartRequest(dl->rname, dl->localname); CL_SendDownloadStartRequest(dl->rname, dl->localname);
return; return;
@ -1283,10 +1343,8 @@ void CL_RequestNextDownload (void)
return; return;
cl.sendprespawn = false; cl.sendprespawn = false;
#ifdef _MSC_VER #ifdef warningmsg
//FIXME: timedemo timer should start here. #pragma warningmsg("timedemo timer should start here")
#else
#warning timedemo timer should start here
#endif #endif
if (!cl.worldmodel || cl.worldmodel->needload) if (!cl.worldmodel || cl.worldmodel->needload)
@ -1342,8 +1400,24 @@ void CL_SendDownloadReq(sizebuf_t *msg)
if (cls.downloadmethod == DL_QWCHUNKS) if (cls.downloadmethod == DL_QWCHUNKS)
{ {
extern int download_file_number; extern int download_file_number;
extern cvar_t drate;
static float lasttime;
int p; int p;
for (p = 0; p < 8; p++) if (!drate.ival)
p = 64;
else
{
lasttime = fabs(realtime - lasttime);
if (lasttime > 1)
lasttime = 1;
p = lasttime * drate.ival;
if (p > 90)
p = 90;
}
lasttime = realtime;
if (!p)
p = 1;
while (p-->0)
{ {
int i = CL_RequestADownloadChunk(); int i = CL_RequestADownloadChunk();
if (i >= 0) if (i >= 0)
@ -1424,6 +1498,12 @@ downloadlist_t *CL_DownloadFailed(char *name)
{ {
VFS_CLOSE(cls.downloadqw); VFS_CLOSE(cls.downloadqw);
cls.downloadqw = NULL; cls.downloadqw = NULL;
if (!strncmp(cls.downloadtempname, "package/", 8))
FS_Remove(cls.downloadtempname, FS_ROOT);
else if (!strncmp(cls.downloadtempname,"skins/",6))
FS_Remove(va("qw/%s", cls.downloadtempname), FS_ROOT);
else
FS_Remove(cls.downloadtempname, FS_GAME);
CL_SendClientCommand(true, "stopdownload"); CL_SendClientCommand(true, "stopdownload");
} }
*cls.downloadlocalname = 0; *cls.downloadlocalname = 0;
@ -1449,11 +1529,14 @@ downloadlist_t *CL_DownloadFailed(char *name)
float downloadstarttime; float downloadstarttime;
#ifdef PEXT_CHUNKEDDOWNLOADS #ifdef PEXT_CHUNKEDDOWNLOADS
#define MAXBLOCKS 64 //must be power of 2 #define MAXBLOCKS 512 //must be power of 2
#define DLBLOCKSIZE 1024 #define DLBLOCKSIZE 1024
int downloadsize; int downloadsize;
int receivedbytes; int receivedbytes;
int recievedblock[MAXBLOCKS]; struct
{
int chunkno;
} dlblock[MAXBLOCKS];
int firstblock; int firstblock;
int blockcycle; int blockcycle;
int download_file_number; int download_file_number;
@ -1468,7 +1551,7 @@ void CL_ParseChunkedDownload(void)
qbyte *svname; qbyte *svname;
//qbyte osname[MAX_OSPATH]; //unreferenced //qbyte osname[MAX_OSPATH]; //unreferenced
int totalsize; int totalsize;
int chunknum; int chunknum, ridx;
char data[DLBLOCKSIZE]; char data[DLBLOCKSIZE];
chunknum = MSG_ReadLong(); chunknum = MSG_ReadLong();
@ -1527,7 +1610,12 @@ void CL_ParseChunkedDownload(void)
COM_DefaultExtension(cls.downloadtempname, ".tmp"); COM_DefaultExtension(cls.downloadtempname, ".tmp");
*/ */
if (!strncmp(cls.downloadtempname,"skins/",6)) if (!strncmp(cls.downloadtempname, "package/", 8))
{
FS_CreatePath(cls.downloadtempname+8, FS_ROOT);
cls.downloadqw = FS_OpenVFS(cls.downloadtempname + 8, "wb", FS_ROOT);
}
else if (!strncmp(cls.downloadtempname,"skins/",6))
{ {
FS_CreatePath (va("qw/%s", cls.downloadtempname), FS_ROOT); FS_CreatePath (va("qw/%s", cls.downloadtempname), FS_ROOT);
cls.downloadqw = FS_OpenVFS (va("qw/%s", cls.downloadtempname), "wb", FS_ROOT); cls.downloadqw = FS_OpenVFS (va("qw/%s", cls.downloadtempname), "wb", FS_ROOT);
@ -1548,7 +1636,8 @@ void CL_ParseChunkedDownload(void)
firstblock = 0; firstblock = 0;
receivedbytes = 0; receivedbytes = 0;
blockcycle = -1; //so it requests 0 first. :) blockcycle = -1; //so it requests 0 first. :)
memset(recievedblock, 0, sizeof(recievedblock)); for (chunknum = 0; chunknum < MAXBLOCKS; chunknum++)
dlblock[chunknum].chunkno = ~0u;
return; return;
} }
@ -1563,31 +1652,21 @@ void CL_ParseChunkedDownload(void)
{ //err, yeah, when playing demos we don't actually pay any attention to this. { //err, yeah, when playing demos we don't actually pay any attention to this.
return; return;
} }
if (chunknum < firstblock)
{
// Con_Printf("too old\n", chunknum);
return;
}
if (chunknum-firstblock >= MAXBLOCKS)
{
// Con_Printf("^1too new!\n", chunknum);
return;
}
if (recievedblock[chunknum&(MAXBLOCKS-1)]) for (ridx = 0; ridx < MAXBLOCKS; ridx++)
{ {
// Con_Printf("duplicated\n", chunknum); if (dlblock[ridx].chunkno == chunknum)
break;
}
if (ridx == MAXBLOCKS)
{
Con_DPrintf("dupe/invalid chunk received\n", chunknum);
return; return;
} }
dlblock[ridx].chunkno = ~0;
// Con_Printf("usable\n", chunknum); // Con_Printf("usable\n", chunknum);
receivedbytes+=DLBLOCKSIZE; receivedbytes+=DLBLOCKSIZE;
recievedblock[chunknum&(MAXBLOCKS-1)] = true;
while(recievedblock[firstblock&(MAXBLOCKS-1)])
{
recievedblock[firstblock&(MAXBLOCKS-1)] = false;
firstblock++;
}
VFS_SEEK(cls.downloadqw, chunknum*DLBLOCKSIZE); VFS_SEEK(cls.downloadqw, chunknum*DLBLOCKSIZE);
if (downloadsize - chunknum*DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve. if (downloadsize - chunknum*DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve.
@ -1611,7 +1690,7 @@ int CL_CountQueuedDownloads(void)
int CL_RequestADownloadChunk(void) int CL_RequestADownloadChunk(void)
{ {
int i; int i;
int b; int ridx;
if (cls.downloadmethod != DL_QWCHUNKS) if (cls.downloadmethod != DL_QWCHUNKS)
{ {
@ -1619,18 +1698,17 @@ int CL_RequestADownloadChunk(void)
return -1; return -1;
} }
blockcycle++;
for (i = 0; i < MAXBLOCKS; i++) for (i = 0; i < MAXBLOCKS; i++)
{ {
b = ((i+blockcycle)&(MAXBLOCKS-1)) blockcycle++;
+ firstblock; ridx = blockcycle&(MAXBLOCKS-1);
if (!recievedblock[b&(MAXBLOCKS-1)]) //don't ask for ones we've already got. if (dlblock[ridx].chunkno == ~0u)
{ {
if (b >= (downloadsize+DLBLOCKSIZE-1)/DLBLOCKSIZE) //don't ask for blocks that are over the size of the file. if (firstblock >= (downloadsize+DLBLOCKSIZE-1)/DLBLOCKSIZE)
continue; continue;
// Con_Printf("Requesting block %i\n", b); dlblock[ridx].chunkno = firstblock++;
return b;
} }
return dlblock[ridx].chunkno;
} }
// Con_Printf("^1 EOF?\n"); // Con_Printf("^1 EOF?\n");
@ -2465,6 +2543,24 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
cls.protocol_nq = CPNQ_FITZ666; cls.protocol_nq = CPNQ_FITZ666;
Con_DPrintf("FitzQuake 666 protocol\n"); Con_DPrintf("FitzQuake 666 protocol\n");
} }
else if (protover == RMQ_PROTOCOL_VERSION)
{
int fl;
cls.protocol_nq = CPNQ_FITZ666;
Con_DPrintf("RMQ extensions to FitzQuake's protocol\n");
fl = MSG_ReadLong();
if (fl & RMQFL_SHORTANGLE)
netprim.anglesize = 2;
if (fl & RMQFL_FLOATANGLE)
netprim.anglesize = 4;
if (fl & RMQFL_24BITCOORD)
netprim.coordsize = 3;
if (fl & RMQFL_FLOATCOORD)
netprim.coordsize = 4;
if (fl & ~(RMQFL_SHORTANGLE|RMQFL_FLOATANGLE|RMQFL_24BITCOORD|RMQFL_FLOATCOORD))
Con_Printf("WARNING: Server is using unsupported RMQ extensions\n");
}
else if (protover == DP5_PROTOCOL_VERSION) else if (protover == DP5_PROTOCOL_VERSION)
{ {
//darkplaces5 //darkplaces5
@ -2502,7 +2598,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
} }
else if (protover != NQ_PROTOCOL_VERSION) else if (protover != NQ_PROTOCOL_VERSION)
{ {
Host_EndGame ("Server returned version %i, not %i\nYou will need to use a different client.", protover, NQ_PROTOCOL_VERSION); Host_EndGame ("Server is using protocol version %i, which is not supported by this version of " FULLENGINENAME ".", protover);
} }
else else
{ {
@ -2545,7 +2641,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
} }
strcpy (cl.model_name[nummodels], str); strcpy (cl.model_name[nummodels], str);
if (*str != '*') //not inline models! if (*str != '*') //not inline models!
CL_CheckOrEnqueDownloadFile(str, NULL, 0); CL_CheckOrEnqueDownloadFile(str, NULL, ((nummodels==1)?DLLF_REQUIRED:0));
Mod_TouchModel (str); Mod_TouchModel (str);
} }
@ -2562,10 +2658,8 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
} }
strcpy (cl.sound_name[numsounds], str); strcpy (cl.sound_name[numsounds], str);
#ifdef _MSC_VER if (*str != '*') //not inline models!
#pragma message("CLNQ_ParseServerData: no sound autodownloads") CL_CheckOrEnqueDownloadFile(va("sound/%s", str), NULL, 0);
#endif
//CL_CheckOrEnqueDownloadFile(str, NULL, 0);
S_TouchSound (str); S_TouchSound (str);
} }
@ -4705,6 +4799,17 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit); Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit);
} }
} }
else if (!strncmp(stufftext, "//paknames ", 11))
{
Q_strncpyz(cl.serverpaknames, stufftext+11, sizeof(cl.serverpaknames));
cl.serverpakschanged = true;
}
else if (!strncmp(stufftext, "//paks ", 7))
{
Q_strncpyz(cl.serverpakcrcs, stufftext+7, sizeof(cl.serverpakcrcs));
cl.serverpakschanged = true;
CL_CheckServerInfo();
}
else if (!strncmp(stufftext, "//vwep ", 7)) else if (!strncmp(stufftext, "//vwep ", 7))
{ {
int i; int i;

View File

@ -665,15 +665,35 @@ void CL_CalcClientTime(void)
} }
else else
{ {
want = cl.oldgametime + (realtime - cl.gametimemark); oldst = cl.servertime;
if (want>cl.servertime)
cl.servertime = want; cl.servertime += host_frametime;
if (cl.servertime > cl.gametime) if (cl.servertime > cl.gametime)
{
cl.servertime = cl.gametime; cl.servertime = cl.gametime;
// Con_Printf("clamped to new time\n");
}
if (cl.servertime < cl.oldgametime) if (cl.servertime < cl.oldgametime)
cl.servertime = cl.oldgametime; {
if (cl.servertime < cl.oldgametime-0.5)
{
cl.servertime = cl.oldgametime-0.5;
// Con_Printf("clamped to old time\n");
}
else if (cl.servertime < cl.oldgametime-0.3)
{
cl.servertime += 0.02*(cl.oldgametime - cl.servertime);
// Con_Printf("running really slow\n");
}
else
{
cl.servertime += 0.01*(cl.oldgametime - cl.servertime);
// Con_Printf("running slow\n");
}
}
} }
cl.time = cl.servertime;
if (oldst == 0) if (oldst == 0)
{ {
int i; int i;
@ -682,6 +702,7 @@ void CL_CalcClientTime(void)
cl.players[i].entertime += cl.servertime; cl.players[i].entertime += cl.servertime;
} }
} }
return;
} }
if (cls.protocol == CP_NETQUAKE || (cls.demoplayback && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) if (cls.protocol == CP_NETQUAKE || (cls.demoplayback && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV))
@ -755,8 +776,6 @@ void CL_PredictMovePNum (int pnum)
if (cl.paused && !(cls.demoplayback!=DPB_MVD && cls.demoplayback!=DPB_EZTV) && (!cl.spectator || !autocam[pnum])) if (cl.paused && !(cls.demoplayback!=DPB_MVD && cls.demoplayback!=DPB_EZTV) && (!cl.spectator || !autocam[pnum]))
return; return;
CL_CalcClientTime();
if (cl.intermission && cl.intermission != 3 && cls.protocol == CP_QUAKEWORLD) if (cl.intermission && cl.intermission != 3 && cls.protocol == CP_QUAKEWORLD)
{ {
cl.crouch[pnum] = 0; cl.crouch[pnum] = 0;
@ -885,7 +904,7 @@ fixedorg:
cl.onground[pnum] = pmove.onground; cl.onground[pnum] = pmove.onground;
if (to->senttime >= cl.time) if (to->senttime >= realtime)
break; break;
from = to; from = to;
} }
@ -895,7 +914,7 @@ fixedorg:
from = to; from = to;
to = &ind; to = &ind;
to->cmd[pnum] = independantphysics[pnum]; to->cmd[pnum] = independantphysics[pnum];
to->senttime = cl.time; to->senttime = realtime;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]] CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]); , &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
@ -918,7 +937,7 @@ fixedorg:
f = 0; f = 0;
else else
{ {
f = (cl.time - from->senttime) / (to->senttime - from->senttime); f = (realtime - from->senttime) / (to->senttime - from->senttime);
if (f < 0) if (f < 0)
f = 0; f = 0;

View File

@ -183,6 +183,7 @@ extern cvar_t scr_sshot_type;
extern cvar_t scr_sshot_compression; extern cvar_t scr_sshot_compression;
extern cvar_t crosshair; extern cvar_t crosshair;
extern cvar_t scr_consize; extern cvar_t scr_consize;
cvar_t scr_neticontimeout = CVAR("scr_neticontimeout", "0.3");
qboolean scr_initialized; // ready to draw qboolean scr_initialized; // ready to draw
@ -238,6 +239,7 @@ void CLSCR_Init(void)
Cvar_Register(&show_speed, cl_screengroup); Cvar_Register(&show_speed, cl_screengroup);
Cvar_Register(&show_speed_x, cl_screengroup); Cvar_Register(&show_speed_x, cl_screengroup);
Cvar_Register(&show_speed_y, cl_screengroup); Cvar_Register(&show_speed_y, cl_screengroup);
Cvar_Register(&scr_neticontimeout, cl_screengroup);
} }
/* /*
@ -987,7 +989,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
extern cvar_t cl_crossx, cl_crossy, crosshaircorrect, v_viewheight; extern cvar_t cl_crossx, cl_crossy, crosshaircorrect, v_viewheight;
vrect_t rect; vrect_t rect;
SCR_VRectForPlayer(&rect, pnum); rect = r_refdef.vrect;
if (cl.worldmodel && crosshaircorrect.ival) if (cl.worldmodel && crosshaircorrect.ival)
{ {
@ -1136,7 +1138,7 @@ SCR_DrawNet
*/ */
void SCR_DrawNet (void) void SCR_DrawNet (void)
{ {
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < UPDATE_BACKUP-1) if (realtime - cls.netchan.last_received < scr_neticontimeout.value)
return; return;
if (cls.demoplayback || !scr_net) if (cls.demoplayback || !scr_net)
return; return;
@ -1776,8 +1778,8 @@ qboolean SCR_ScreenShot (char *filename)
ext = COM_FileExtension(filename); ext = COM_FileExtension(filename);
buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight); buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight);
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("Need to ensure that the various image writing routines can cope with ((width|height)&3") #pragma warningmsg("Need to ensure that the various image writing routines can cope with ((width|height)&3")
#endif #endif
if (!buffer) if (!buffer)

View File

@ -175,6 +175,7 @@ typedef struct
{ {
int entity; int entity;
short tag; short tag;
qbyte active;
qbyte flags; qbyte flags;
qbyte type; qbyte type;
qbyte skin; qbyte skin;
@ -571,6 +572,7 @@ beam_t *CL_NewBeam (int entity, int tag)
for (i=0, b=cl_beams; i < beams_running; i++, b++) for (i=0, b=cl_beams; i < beams_running; i++, b++)
if (b->entity == entity && b->tag == tag) if (b->entity == entity && b->tag == tag)
{ {
b->active = true;
return b; return b;
} }
} }
@ -578,8 +580,9 @@ beam_t *CL_NewBeam (int entity, int tag)
// find a free beam // find a free beam
for (i=0, b=cl_beams; i < beams_running; i++, b++) for (i=0, b=cl_beams; i < beams_running; i++, b++)
{ {
if (!b->model) if (!b->active)
{ {
b->active = true;
return b; return b;
} }
} }
@ -587,6 +590,7 @@ beam_t *CL_NewBeam (int entity, int tag)
if (i == beams_running && i != MAX_BEAMS) if (i == beams_running && i != MAX_BEAMS)
{ {
beams_running++; beams_running++;
cl_beams[i].active = true;
return &cl_beams[i]; return &cl_beams[i];
} }
@ -603,6 +607,7 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n
int i; int i;
vec3_t impact, normal; vec3_t impact, normal;
vec3_t extra; vec3_t extra;
char *mname;
switch(tent) switch(tent)
{ {
@ -610,12 +615,12 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n
if (ent < 0 && ent >= -512) //a zquake concept. ent between -1 and -maxplayers is to be taken to be a railtrail from a particular player instead of a beam. if (ent < 0 && ent >= -512) //a zquake concept. ent between -1 and -maxplayers is to be taken to be a railtrail from a particular player instead of a beam.
{ {
// TODO: add support for those finnicky colored railtrails... // TODO: add support for those finnicky colored railtrails...
if (P_ParticleTrail(start, end, rtqw_railtrail, NULL)) if (P_ParticleTrail(start, end, rtqw_railtrail, -ent, NULL))
P_ParticleTrailIndex(start, end, 208, 8, NULL); P_ParticleTrailIndex(start, end, 208, 8, NULL);
return; return;
} }
default: default:
m = Mod_ForName("progs/bolt.mdl", false); mname = "progs/bolt.mdl";
btype = rtfte_lightning1; btype = rtfte_lightning1;
etype = ptfte_lightning1_end; etype = ptfte_lightning1_end;
break; break;
@ -623,37 +628,43 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n
if (ent < 0 && ent >= -MAX_CLIENTS) //based on the railgun concept - this adds a rogue style TE_BEAM effect. if (ent < 0 && ent >= -MAX_CLIENTS) //based on the railgun concept - this adds a rogue style TE_BEAM effect.
{ {
case 5: case 5:
m = Mod_ForName("progs/beam.mdl", false); //remember to precache! mname = "progs/beam.mdl"; //remember to precache!
btype = P_FindParticleType("te_beam"); btype = P_FindParticleType("te_beam");
etype = P_FindParticleType("te_beam_end"); etype = P_FindParticleType("te_beam_end");
} }
else else
{ {
m = Mod_ForName("progs/bolt2.mdl", false); mname = "progs/bolt2.mdl";
btype = rtfte_lightning2; btype = rtfte_lightning2;
etype = ptfte_lightning2_end; etype = ptfte_lightning2_end;
} }
break; break;
case 2: case 2:
m = Mod_ForName("progs/bolt3.mdl", false); mname = "progs/bolt3.mdl";
btype = rtfte_lightning3; btype = rtfte_lightning3;
etype = ptfte_lightning3_end; etype = ptfte_lightning3_end;
break; break;
#ifdef Q2CLIENT #ifdef Q2CLIENT
case 3: case 3:
m = Mod_ForName(q2tentmodels[q2cl_mod_parasite_segment].modelname, false); mname = q2tentmodels[q2cl_mod_parasite_segment].modelname;
btype = P_FindParticleType("te_parasite_attack"); btype = P_FindParticleType("te_parasite_attack");
etype = P_FindParticleType("te_parasite_attack_end"); etype = P_FindParticleType("te_parasite_attack_end");
break; break;
case 4: case 4:
m = Mod_ForName(q2tentmodels[q2cl_mod_grapple_cable].modelname, false); mname = q2tentmodels[q2cl_mod_grapple_cable].modelname;
btype = P_FindParticleType("te_grapple_cable"); btype = P_FindParticleType("te_grapple_cable");
etype = P_FindParticleType("te_grapple_cable_end"); etype = P_FindParticleType("te_grapple_cable_end");
break; break;
#endif #endif
} }
if (!m || m->needload) /*don't bother loading the model if we have a particle effect for it instead*/
if (ruleset_allow_particle_lightning.ival && btype >= 0)
m = NULL;
else
m = Mod_ForName(mname, false);
if (m && m->needload)
CL_CheckOrEnqueDownloadFile(m->name, NULL, 0); CL_CheckOrEnqueDownloadFile(m->name, NULL, 0);
// save end position for truelightning // save end position for truelightning
@ -695,11 +706,11 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n
b->entity = ent; b->entity = ent;
b->model = m; b->model = m;
b->particleeffect = btype;
b->tag = -1; b->tag = -1;
b->flags |= /*STREAM_ATTACHED|*/1; b->flags |= /*STREAM_ATTACHED|*/1;
b->endtime = cl.time + 0.2; b->endtime = cl.time + 0.2;
b->alpha = 1; b->alpha = 1;
b->particleeffect = btype;
VectorCopy (start, b->start); VectorCopy (start, b->start);
VectorCopy (end, b->end); VectorCopy (end, b->end);
@ -765,6 +776,7 @@ void CL_ParseStream (int type)
b->tag = tag; b->tag = tag;
b->flags = flags; b->flags = flags;
b->model = NULL; b->model = NULL;
b->particleeffect = -1;
b->endtime = cl.time + duration; b->endtime = cl.time + duration;
b->alpha = 1; b->alpha = 1;
b->skin = skin; b->skin = skin;
@ -1282,8 +1294,8 @@ void CL_ParseTEnt (void)
pos2[1] = MSG_ReadCoord (); pos2[1] = MSG_ReadCoord ();
pos2[2] = MSG_ReadCoord (); pos2[2] = MSG_ReadCoord ();
if (P_ParticleTrail(pos, pos2, rtqw_railtrail, NULL)) if (P_ParticleTrail(pos, pos2, rtqw_railtrail, 0, NULL))
if (P_ParticleTrail(pos, pos2, rtq2_railtrail, NULL)) if (P_ParticleTrail(pos, pos2, rtq2_railtrail, 0, NULL))
P_ParticleTrailIndex(pos, pos2, 208, 8, NULL); P_ParticleTrailIndex(pos, pos2, 208, 8, NULL);
break; break;
@ -1421,7 +1433,7 @@ void CL_ParseTEnt (void)
// stain (Hopefully this is close to how DP does it) // stain (Hopefully this is close to how DP does it)
R_AddStain(pos, -10, -10, -10, 30); R_AddStain(pos, -10, -10, -10, 30);
if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_plasmaburn"), NULL)) if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_plasmaburn"), 0, NULL))
P_ParticleTrailIndex(pos, pos2, 15, 0, NULL); P_ParticleTrailIndex(pos, pos2, 15, 0, NULL);
break; break;
@ -1439,7 +1451,7 @@ void CL_ParseTEnt (void)
MSG_ReadCoord (); MSG_ReadCoord ();
MSG_ReadCoord (); MSG_ReadCoord ();
if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_nexbeam"), NULL)) if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_nexbeam"), 0, NULL))
P_ParticleTrailIndex(pos, pos2, 15, 0, NULL); P_ParticleTrailIndex(pos, pos2, 15, 0, NULL);
break; break;
@ -1634,7 +1646,7 @@ void CL_ParseCustomTEnt(void)
{ {
MSG_ReadPos (pos); MSG_ReadPos (pos);
MSG_ReadPos (pos2); MSG_ReadPos (pos2);
failed = P_ParticleTrail(pos, pos2, t->particleeffecttype, NULL); failed = P_ParticleTrail(pos, pos2, t->particleeffecttype, 0, NULL);
} }
else else
{ {
@ -1736,8 +1748,8 @@ void CLDP_ParseTrailParticles(void)
ts = NULL; ts = NULL;
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex)); effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
if (P_ParticleTrail(start, end, effectindex, ts)) if (P_ParticleTrail(start, end, effectindex, entityindex, ts))
P_ParticleTrail(start, end, rt_blood, ts); P_ParticleTrail(start, end, rt_blood, entityindex, ts);
} }
void CLDP_ParsePointParticles(qboolean compact) void CLDP_ParsePointParticles(qboolean compact)
@ -2111,7 +2123,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_RAILTRAIL: // railgun effect case Q2TE_RAILTRAIL: // railgun effect
MSG_ReadPos (pos); MSG_ReadPos (pos);
MSG_ReadPos (pos2); MSG_ReadPos (pos2);
if (P_ParticleTrail(pos, pos2, rtq2_railtrail, NULL)) if (P_ParticleTrail(pos, pos2, rtq2_railtrail, 0, NULL))
P_ParticleTrailIndex(pos, pos2, 0x74, 8, NULL); P_ParticleTrailIndex(pos, pos2, 0x74, 8, NULL);
Q2S_StartSound (pos, 0, 0, S_PrecacheSound ("weapons/railgf1a.wav"), 1, ATTN_NORM, 0); Q2S_StartSound (pos, 0, 0, S_PrecacheSound ("weapons/railgf1a.wav"), 1, ATTN_NORM, 0);
break; break;
@ -2321,7 +2333,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_BUBBLETRAIL: case Q2TE_BUBBLETRAIL:
MSG_ReadPos (pos); MSG_ReadPos (pos);
MSG_ReadPos (pos2); MSG_ReadPos (pos2);
if (P_ParticleTrail(pos, pos2, rtq2_bubbletrail, NULL)) if (P_ParticleTrail(pos, pos2, rtq2_bubbletrail, 0, NULL))
P_ParticleTrailIndex(pos, pos2, 4, 8, NULL); P_ParticleTrailIndex(pos, pos2, 4, 8, NULL);
break; break;
@ -2496,7 +2508,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_DEBUGTRAIL: case Q2TE_DEBUGTRAIL:
MSG_ReadPos (pos); MSG_ReadPos (pos);
MSG_ReadPos (pos2); MSG_ReadPos (pos2);
if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_debugtrail"), NULL)) if (P_ParticleTrail(pos, pos2, P_FindParticleType("te_debugtrail"), 0, NULL))
P_ParticleTrailIndex(pos, pos2, 116, 8, NULL); P_ParticleTrailIndex(pos, pos2, 116, 8, NULL);
break; break;
@ -2800,7 +2812,7 @@ void CL_UpdateBeams (void)
// update lightning // update lightning
for (bnum=0, b=cl_beams; bnum < beams_running; bnum++, b++) for (bnum=0, b=cl_beams; bnum < beams_running; bnum++, b++)
{ {
if (!b->model) if (!b->active)
continue; continue;
if (b->endtime < cl.time) if (b->endtime < cl.time)
@ -2809,7 +2821,7 @@ void CL_UpdateBeams (void)
{ /*don't let lightning decay while paused*/ { /*don't let lightning decay while paused*/
P_DelinkTrailstate(&b->trailstate); P_DelinkTrailstate(&b->trailstate);
P_DelinkTrailstate(&b->emitstate); P_DelinkTrailstate(&b->emitstate);
b->model = NULL; b->active = false;
continue; continue;
} }
} }
@ -2851,7 +2863,7 @@ void CL_UpdateBeams (void)
VectorSubtract (playerbeam_end[j], vieworg, org); VectorSubtract (playerbeam_end[j], vieworg, org);
len = VectorLength(org); len = VectorLength(org);
org[2] -= 22; // adjust for view height org[2] -= 22; // adjust for view height
vectoangles (org, ang); VectorAngles (org, NULL, ang);
// lerp pitch // lerp pitch
ang[0] = -ang[0]; ang[0] = -ang[0];
@ -2926,9 +2938,11 @@ void CL_UpdateBeams (void)
pitch += 360; pitch += 360;
} }
if (ruleset_allow_particle_lightning.ival) if (ruleset_allow_particle_lightning.ival || !b->model)
if (b->particleeffect >= 0 && !P_ParticleTrail(b->start, b->end, b->particleeffect, &b->trailstate)) if (b->particleeffect >= 0 && !P_ParticleTrail(b->start, b->end, b->particleeffect, b->entity, &b->trailstate))
continue; continue;
if (!b->model)
continue;
// add new entities for the lightning // add new entities for the lightning
VectorCopy (b->start, org); VectorCopy (b->start, org);

View File

@ -261,6 +261,11 @@ typedef struct dlight_s
float minlight; // don't add when contributing less float minlight; // don't add when contributing less
float color[3]; float color[3];
float channelfade[3]; float channelfade[3];
float ambientscale;
float diffusescale;
float specularscale;
float corona;
float coronascale;
unsigned int flags; unsigned int flags;
@ -411,11 +416,8 @@ typedef struct
qboolean allow_mirrors; qboolean allow_mirrors;
qboolean allow_watervis; qboolean allow_watervis;
qboolean allow_luma; qboolean allow_luma;
qboolean allow_bump;
float allow_fbskins; //fraction of allowance float allow_fbskins; //fraction of allowance
#ifdef FISH qboolean allow_postproc;
qboolean allow_fish;
#endif
qboolean allow_cheats; qboolean allow_cheats;
qboolean allow_semicheats; //defaults to true, but this allows a server to enforce a strict ruleset (smackdown type rules). qboolean allow_semicheats; //defaults to true, but this allows a server to enforce a strict ruleset (smackdown type rules).
float maxfps; //server capped float maxfps; //server capped
@ -436,11 +438,12 @@ typedef struct downloadlist_s {
char localname[128]; char localname[128];
unsigned int size; unsigned int size;
unsigned int flags; unsigned int flags;
#define DLLF_VERBOSE 1 //tell the user that its downloading #define DLLF_VERBOSE 1 //tell the user that its downloading
#define DLLF_REQUIRED 2 //means that it won't load models etc until its downloaded (ie: requiredownloads 0 makes no difference) #define DLLF_REQUIRED 2 //means that it won't load models etc until its downloaded (ie: requiredownloads 0 makes no difference)
#define DLLF_OVERWRITE 4 //overwrite it even if it already exists #define DLLF_OVERWRITE 4 //overwrite it even if it already exists
#define DLLF_SIZEUNKNOWN 8 #define DLLF_SIZEUNKNOWN 8 //download's size isn't known
#define DLLF_IGNOREFAILED 16 #define DLLF_IGNOREFAILED 16 //
#define DLLF_NONGAME 32 //means the requested download filename+localname is gamedir explicit (so id1/foo.txt is distinct from qw/foo.txt)
struct downloadlist_s *next; struct downloadlist_s *next;
} downloadlist_t; } downloadlist_t;
@ -487,6 +490,9 @@ typedef struct
qboolean allowsendpacket; qboolean allowsendpacket;
char serverinfo[MAX_SERVERINFO_STRING]; char serverinfo[MAX_SERVERINFO_STRING];
char serverpaknames[1024];
char serverpakcrcs[1024];
qboolean serverpakschanged;
int parsecount; // server message counter int parsecount; // server message counter
int oldparsecount; int oldparsecount;
@ -1094,7 +1100,7 @@ void Cam_TrackPlayer(int pnum, char *cmdname, char *plrarg);
void Cam_Lock(int pnum, int playernum); void Cam_Lock(int pnum, int playernum);
void CL_InitCam(void); void CL_InitCam(void);
void QDECL vectoangles(vec3_t vec, vec3_t ang); void QDECL vectoangles(vec3_t fwd, vec3_t ang);
// //
//zqtp.c //zqtp.c
@ -1237,7 +1243,7 @@ void Media_Init(void);
qboolean Media_PlayFilm(char *name); qboolean Media_PlayFilm(char *name);
typedef struct cin_s cin_t; typedef struct cin_s cin_t;
struct cin_s *Media_StartCin(char *name); struct cin_s *Media_StartCin(char *name);
texid_t Media_UpdateForShader(cin_t *cin); texid_tf Media_UpdateForShader(cin_t *cin);
void Media_ShutdownCin(cin_t *cin); void Media_ShutdownCin(cin_t *cin);
qboolean Media_FakeTrack(int i, qboolean loop); qboolean Media_FakeTrack(int i, qboolean loop);

View File

@ -1007,6 +1007,11 @@ void CLQ2_ParseFrame (void)
cl.q2frame.deltaframe = MSG_ReadLong (); cl.q2frame.deltaframe = MSG_ReadLong ();
cl.q2frame.servertime = cl.q2frame.serverframe*100; cl.q2frame.servertime = cl.q2frame.serverframe*100;
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = cl.q2frame.servertime/1000.f;
cl.gametimemark = realtime;
i = MSG_ReadByte (); i = MSG_ReadByte ();
for (j=0 ; j<i ; j++) for (j=0 ; j<i ; j++)
@ -1579,8 +1584,8 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
{ {
if (effects & Q2EF_ROCKET) if (effects & Q2EF_ROCKET)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_rocket, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_rocket, ent.keynum, &cent->trailstate))
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_rocket, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_rocket, ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xdc, 4, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xdc, 4, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0); V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0);
@ -1597,7 +1602,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
} }
else else
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_blastertrail, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_blastertrail, ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xe0, 1, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xe0, 1, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0); V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0);
} }
@ -1612,14 +1617,14 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
} }
else if (effects & Q2EF_GIB) else if (effects & Q2EF_GIB)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_gib, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_gib, ent.keynum, &cent->trailstate))
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_blood, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_blood, ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xe8, 8, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xe8, 8, &cent->trailstate);
} }
else if (effects & Q2EF_GRENADE) else if (effects & Q2EF_GRENADE)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_grenade, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_grenade, ent.keynum, &cent->trailstate))
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_grenade, &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_grenade, ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 4, 8, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 4, 8, &cent->trailstate);
} }
else if (effects & Q2EF_FLIES) else if (effects & Q2EF_FLIES)
@ -1651,13 +1656,13 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
} }
else if (effects & Q2EF_FLAG1) else if (effects & Q2EF_FLAG1)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_flag1"), &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_flag1"), ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 242, 1, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 242, 1, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.05, 0.05); V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.05, 0.05);
} }
else if (effects & Q2EF_FLAG2) else if (effects & Q2EF_FLAG2)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_flag2"), &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_flag2"), ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 115, 1, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 115, 1, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 225, 0.05, 0.05, 0.2); V_AddLight (ent.keynum, ent.origin, 225, 0.05, 0.05, 0.2);
} }
@ -1665,7 +1670,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
//ROGUE //ROGUE
else if (effects & Q2EF_TAGTRAIL) else if (effects & Q2EF_TAGTRAIL)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_tagtrail"), &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_tagtrail"), ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 220, 1, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 220, 1, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.2, 0.0); V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.2, 0.0);
} }
@ -1688,7 +1693,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
} }
else if (effects & Q2EF_TRACKER) else if (effects & Q2EF_TRACKER)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_tracker"), &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_tracker"), ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0, 1, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0, 1, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 200, -0.2, -0.2, -0.2); V_AddLight (ent.keynum, ent.origin, 200, -0.2, -0.2, -0.2);
} }
@ -1697,13 +1702,13 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
// RAFAEL // RAFAEL
else if (effects & Q2EF_GREENGIB) else if (effects & Q2EF_GREENGIB)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_greengib"), &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_greengib"), ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 219, 8, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 219, 8, &cent->trailstate);
} }
// RAFAEL // RAFAEL
else if (effects & Q2EF_IONRIPPER) else if (effects & Q2EF_IONRIPPER)
{ {
if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_ionripper"), &cent->trailstate)) if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_ionripper"), ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 228, 4, &cent->trailstate); P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 228, 4, &cent->trailstate);
V_AddLight (ent.keynum, ent.origin, 100, 0.2, 0.1, 0.1); V_AddLight (ent.keynum, ent.origin, 100, 0.2, 0.1, 0.1);
} }
@ -1717,7 +1722,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
{ {
if (effects & Q2EF_ANIM_ALLFAST) if (effects & Q2EF_ANIM_ALLFAST)
{ {
P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_blastertrail, &cent->trailstate); P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_blastertrail, ent.keynum, &cent->trailstate);
} }
V_AddLight (ent.keynum, ent.origin, 130, 0.2, 0.1, 0.1); V_AddLight (ent.keynum, ent.origin, 130, 0.2, 0.1, 0.1);
} }

View File

@ -642,7 +642,7 @@ void (PNGAPI *qpng_read_end) PNGARG((png_structp png_ptr, png_infop info_ptr)) P
void (PNGAPI *qpng_read_image) PNGARG((png_structp png_ptr, png_bytepp image)) PSTATIC(png_read_image); void (PNGAPI *qpng_read_image) PNGARG((png_structp png_ptr, png_bytepp image)) PSTATIC(png_read_image);
png_byte (PNGAPI *qpng_get_bit_depth) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_get_bit_depth); png_byte (PNGAPI *qpng_get_bit_depth) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_get_bit_depth);
png_byte (PNGAPI *qpng_get_channels) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_get_channels); png_byte (PNGAPI *qpng_get_channels) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_get_channels);
png_uint_32 (PNGAPI *qpng_get_rowbytes) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_get_rowbytes); png_size_t (PNGAPI *qpng_get_rowbytes) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_get_rowbytes);
void (PNGAPI *qpng_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_update_info); void (PNGAPI *qpng_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_update_info);
void (PNGAPI *qpng_set_strip_16) PNGARG((png_structp png_ptr)) PSTATIC(png_set_strip_16); void (PNGAPI *qpng_set_strip_16) PNGARG((png_structp png_ptr)) PSTATIC(png_set_strip_16);
void (PNGAPI *qpng_set_expand) PNGARG((png_structp png_ptr)) PSTATIC(png_set_expand); void (PNGAPI *qpng_set_expand) PNGARG((png_structp png_ptr)) PSTATIC(png_set_expand);
@ -2168,7 +2168,7 @@ typedef struct {
} ddsheader; } ddsheader;
texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize) texid_tf GL_LoadTextureDDS(char *iname, unsigned char *buffer, int filesize)
{ {
extern int gl_filter_min; extern int gl_filter_min;
extern int gl_filter_max; extern int gl_filter_max;
@ -2216,7 +2216,7 @@ texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize)
if (!qglCompressedTexImage2DARB) if (!qglCompressedTexImage2DARB)
return r_nulltex; return r_nulltex;
texnum = GL_AllocNewTexture(fmtheader.dwWidth, fmtheader.dwHeight); texnum = GL_AllocNewTexture(iname, fmtheader.dwWidth, fmtheader.dwHeight);
GL_MTBind(0, GL_TEXTURE_2D, texnum); GL_MTBind(0, GL_TEXTURE_2D, texnum);
datasize = fmtheader.dwPitchOrLinearSize; datasize = fmtheader.dwPitchOrLinearSize;
@ -2233,12 +2233,12 @@ texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize)
h = 1; h = 1;
qglCompressedTexImage2DARB(GL_TEXTURE_2D, mipnum, intfmt, w, h, 0, datasize, buffer); qglCompressedTexImage2DARB(GL_TEXTURE_2D, mipnum, intfmt, w, h, 0, datasize, buffer);
if (qglGetError()) if (qglGetError())
Con_Printf("Incompatible dds file (mip %i)\n", mipnum); Con_Printf("Incompatible dds file %s (mip %i)\n", iname, mipnum);
buffer += datasize; buffer += datasize;
datasize/=4; datasize/=4;
} }
if (qglGetError()) if (qglGetError())
Con_Printf("Incompatible dds file\n"); Con_Printf("Incompatible dds file %s\n", iname);
if (nummips>1) if (nummips>1)
@ -2355,7 +2355,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
image_width = 0; image_width = 0;
image_height = 0; image_height = 0;
COM_StripAllExtensions(name, nicename, sizeof(nicename)); COM_StripExtension(name, nicename, sizeof(nicename));
while((data = strchr(nicename, '*'))) while((data = strchr(nicename, '*')))
{ {
@ -2421,7 +2421,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
#ifdef DDS #ifdef DDS
tex = GL_LoadTextureDDS(buf, com_filesize); tex = GL_LoadTextureDDS(fname, buf, com_filesize);
if (TEXVALID(tex)) if (TEXVALID(tex))
{ {
BZ_Free(buf); BZ_Free(buf);
@ -2494,7 +2494,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
extern cvar_t vid_hardwaregamma; extern cvar_t vid_hardwaregamma;
tex = r_nulltex; TEXASSIGNF(tex, r_nulltex);
if (com_filesize >= 8) if (com_filesize >= 8)
{ {
image_width = LittleLong(((int*)buf)[0]); image_width = LittleLong(((int*)buf)[0]);
@ -2582,7 +2582,7 @@ texid_t R_LoadBumpmapTexture(char *name, char *subpath)
if ((data = ReadTargaFile(buf, com_filesize, &image_width, &image_height, 2))) //Only load a greyscale image. 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)); TRACE(("dbg: Mod_LoadBumpmapTexture: tga %s loaded\n", name));
tex = R_LoadTexture8Bump(name, image_width, image_height, data, IF_NOALPHA|IF_NOGAMMA); TEXASSIGNF(tex, R_LoadTexture8Bump(name, image_width, image_height, data, IF_NOALPHA|IF_NOGAMMA));
BZ_Free(data); BZ_Free(data);
} }
else else

View File

@ -1317,6 +1317,10 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
if (mousecursor_y >= vid.height) if (mousecursor_y >= vid.height)
mousecursor_y = vid.height - 1; mousecursor_y = vid.height - 1;
mx=my=0; mx=my=0;
#ifdef PEXT_CSQC
CSQC_MousePosition(mousecursor_x, mousecursor_y);
#endif
} }
else else
{ {
@ -1326,13 +1330,6 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
mx = 0; mx = 0;
my = 0; my = 0;
} }
#endif
#ifdef PEXT_CSQC
if (CSQC_MousePosition(mx, my))
{
mx = 0;
my = 0;
}
#endif #endif
} }

View File

@ -2083,7 +2083,9 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
switch (bulk->variant) switch (bulk->variant)
{ {
case -1: // end of menu case -1: // end of menu
default:
bulk = NULL; bulk = NULL;
control = NULL;
continue; continue;
case 0: // white text case 0: // white text
control = (union menuoption_s *)MC_AddWhiteText(menu, x, y, bulk->text, bulk->rightalign); control = (union menuoption_s *)MC_AddWhiteText(menu, x, y, bulk->text, bulk->rightalign);
@ -2093,6 +2095,7 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
break; break;
case 2: // spacing case 2: // spacing
spacing = bulk->spacing; spacing = bulk->spacing;
control = NULL;
break; break;
} }
break; break;
@ -2149,11 +2152,11 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
if (bulk->ret) if (bulk->ret)
*bulk->ret = control; *bulk->ret = control;
if (MI_Selectable(control) && !selected) if (control && MI_Selectable(control) && !selected)
selected = control; selected = control;
if (bulk->tooltip) if (control && bulk->tooltip)
control->common.tooltip = bulk->tooltip; control->common.tooltip = bulk->tooltip;
if (xleft > 0) if (control && xleft > 0)
control->common.extracollide = xleft; control->common.extracollide = xleft;
y += spacing; y += spacing;

View File

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

View File

@ -1755,7 +1755,7 @@ qboolean Media_ShowFilm(void)
} }
#if defined(GLQUAKE) || defined(D3DQUAKE) #if defined(GLQUAKE) || defined(D3DQUAKE)
texid_t Media_UpdateForShader(cin_t *cin) texid_tf Media_UpdateForShader(cin_t *cin)
{ {
if (!cin) if (!cin)
return r_nulltex; return r_nulltex;
@ -1767,7 +1767,7 @@ texid_t Media_UpdateForShader(cin_t *cin)
if (!cin->outunchanged) if (!cin->outunchanged)
{ {
if (!TEXVALID(cin->texture)) if (!TEXVALID(cin->texture))
cin->texture = R_AllocNewTexture(cin->outwidth, cin->outheight); TEXASSIGN(cin->texture, R_AllocNewTexture("***cin***", cin->outwidth, cin->outheight));
R_Upload(cin->texture, "cin", cin->outtype, cin->outdata, cin->outpalette, cin->outwidth, cin->outheight, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); R_Upload(cin->texture, "cin", cin->outtype, cin->outdata, cin->outpalette, cin->outwidth, cin->outheight, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA);
} }

View File

@ -692,7 +692,7 @@ void M_Menu_Teamplay_f (void)
MB_CHECKBOXCVARTIP("Parse Macros", cl_parseSay, 0, "Whether to parse teamplay macros like %l etc."), MB_CHECKBOXCVARTIP("Parse Macros", cl_parseSay, 0, "Whether to parse teamplay macros like %l etc."),
MB_CHECKBOXCVARTIP("Load Locs", tp_loadlocs, 0, "Whether to load teamplay locations from .loc files"), MB_CHECKBOXCVARTIP("Load Locs", tp_loadlocs, 0, "Whether to load teamplay locations from .loc files"),
MB_CHECKBOXCVARTIP("No Blink", cl_noblink, 0, "No blinking characters"), MB_CHECKBOXCVARTIP("No Blink", cl_noblink, 0, "No blinking characters"),
MB_EDITCVARTIP("Sound Trigger", "tp_soundtrigger", "Character that indicates the following text is a wav file.\nExample:\nsay_team ~location.wav$\me: I'm at %l #a"), MB_EDITCVARTIP("Sound Trigger", "tp_soundtrigger", "Character that indicates the following text is a wav file.\nExample:\nsay_team ~location.wav$\\me: I'm at %l #a"),
MB_EDITCVARTIP("Weapon Order", "tp_weapon_order","Weapon preference order:\n8 = Lightning Gun\n7 = Rocket Launcher\n6 = Grenade Launcher\n5 = Super Nailgun\n4 = Nailgun\n3 = Super Shotgun\n2 = Shotgun\n1 = Axe"), MB_EDITCVARTIP("Weapon Order", "tp_weapon_order","Weapon preference order:\n8 = Lightning Gun\n7 = Rocket Launcher\n6 = Grenade Launcher\n5 = Super Nailgun\n4 = Nailgun\n3 = Super Shotgun\n2 = Shotgun\n1 = Axe"),
MB_CHECKBOXCVARTIP("Teamplay Triggers", cl_triggers, 0, "Enable or disable teamplay triggers"), MB_CHECKBOXCVARTIP("Teamplay Triggers", cl_triggers, 0, "Enable or disable teamplay triggers"),
MB_CHECKBOXCVARTIP("Force Triggers", tp_forceTriggers, 0, "Whether to force teamplay triggers in non-teamplay play like in a 1 on 1 situation"), MB_CHECKBOXCVARTIP("Force Triggers", tp_forceTriggers, 0, "Whether to force teamplay triggers in non-teamplay play like in a 1 on 1 situation"),
@ -935,7 +935,7 @@ void M_Menu_Network_f (void)
NULL NULL
}; };
static const char *splitvalues[] = {"0", "1", "2", "3", NULL}; static const char *splitvalues[] = {"0", "1", "2", "3", NULL};
extern cvar_t allow_download_csprogs, allow_download_redirection, requiredownloads, cl_solid_players; extern cvar_t cl_download_csprogs, cl_download_redirection, requiredownloads, cl_solid_players;
extern cvar_t cl_splitscreen, cl_predict_players; extern cvar_t cl_splitscreen, cl_predict_players;
menu_t *menu; menu_t *menu;
int y; int y;
@ -948,10 +948,10 @@ void M_Menu_Network_f (void)
MB_EDITCVARSLIM("Download Rate", "drate", "Maximum bytes per second that the server should send maps and demos to the client"), MB_EDITCVARSLIM("Download Rate", "drate", "Maximum bytes per second that the server should send maps and demos to the client"),
MB_SPACING(4), MB_SPACING(4),
MB_CHECKBOXCVARTIP("Require Download", requiredownloads, 0, "Ignore downloaded content sent to the client and connect immediatly"), MB_CHECKBOXCVARTIP("Require Download", requiredownloads, 0, "Ignore downloaded content sent to the client and connect immediatly"),
MB_CHECKBOXCVARTIP("Redirect Download", allow_download_redirection, 0, "Whether the client will ignore download redirection from servers"), MB_CHECKBOXCVARTIP("Redirect Download", cl_download_redirection, 0, "Whether the client will ignore download redirection from servers"),
MB_CHECKBOXCVARTIP("Download CSQC", allow_download_csprogs, 0, "Whether to allow the client to download CSQC (client-side QuakeC) progs from servers"), MB_CHECKBOXCVARTIP("Download CSQC", cl_download_csprogs, 0, "Whether to allow the client to download CSQC (client-side QuakeC) progs from servers"),
MB_SPACING(4), MB_SPACING(4),
MB_CHECKBOXCVARTIP("Predict Players", cl_predict_players, 0, "Toggle player prediction"), MB_CHECKBOXCVARTIP("Predict Other Players", cl_predict_players, 0, "Toggle player prediction"),
MB_CHECKBOXCVARTIP("Solid Players", cl_solid_players, 0, "When running/clipping into other players, ON make it appear they are solid, OFF will make it appear like running into a marshmellon."), MB_CHECKBOXCVARTIP("Solid Players", cl_solid_players, 0, "When running/clipping into other players, ON make it appear they are solid, OFF will make it appear like running into a marshmellon."),
MB_COMBOCVAR("Split-screen", cl_splitscreen, splitopts, splitvalues, "Enables split screen with a number of clients. This feature requires server support."), MB_COMBOCVAR("Split-screen", cl_splitscreen, splitopts, splitvalues, "Enables split screen with a number of clients. This feature requires server support."),
MB_END() MB_END()

View File

@ -426,7 +426,6 @@ const char *presetexec[] =
"r_nolightdir 1;" "r_nolightdir 1;"
"r_dynamic 0;" "r_dynamic 0;"
"gl_flashblend 0;" "gl_flashblend 0;"
"gl_bump 0;"
"gl_specular 0;" "gl_specular 0;"
"r_loadlit 0;" "r_loadlit 0;"
"r_fastsky 1;" "r_fastsky 1;"
@ -466,7 +465,6 @@ const char *presetexec[] =
"r_particlesystem script;" "r_particlesystem script;"
"r_particledesc \"spikeset tsshaft\";" "r_particledesc \"spikeset tsshaft\";"
#endif #endif
// "gl_bump 1;" // requires restart
"gl_specular 1;" "gl_specular 1;"
"r_loadlit 2;" "r_loadlit 2;"
// "r_fastsky -1;" // "r_fastsky -1;"
@ -699,7 +697,7 @@ void M_Menu_Textures_f (void)
NULL NULL
}; };
extern cvar_t gl_load24bit, gl_specular, gl_bump, gl_detail, gl_compress, gl_picmip, gl_picmip2d, gl_max_size, r_drawflat; extern cvar_t gl_load24bit, gl_specular, gl_detail, gl_compress, gl_picmip, gl_picmip2d, gl_max_size, r_drawflat;
extern cvar_t gl_texture_anisotropic_filtering, gl_texturemode, gl_texturemode2d; extern cvar_t gl_texture_anisotropic_filtering, gl_texturemode, gl_texturemode2d;
int y; int y;
menubulk_t bulk[] = menubulk_t bulk[] =
@ -712,7 +710,7 @@ void M_Menu_Textures_f (void)
MB_COMBOCVAR("2D Filter Mode", gl_texturemode2d, texture2dfilternames, texture2dfiltervalues, "Chooses the texture filtering method used for HUD, menus, and other 2D assets."), MB_COMBOCVAR("2D Filter Mode", gl_texturemode2d, texture2dfilternames, texture2dfiltervalues, "Chooses the texture filtering method used for HUD, menus, and other 2D assets."),
MB_COMBOCVAR("Anisotropy", gl_texture_anisotropic_filtering, anisotropylevels, anisotropyvalues, NULL), MB_COMBOCVAR("Anisotropy", gl_texture_anisotropic_filtering, anisotropylevels, anisotropyvalues, NULL),
MB_SPACING(4), MB_SPACING(4),
MB_CHECKBOXCVAR("Bumpmapping", gl_bump, 0), MB_CHECKBOXCVAR("Deluxemapping", r_deluxemapping, 0),
MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0), MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0),
MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0), MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0),
MB_SPACING(4), MB_SPACING(4),

View File

@ -147,18 +147,41 @@ void Draw_FunString(int x, int y, const void *str);
void Draw_AltFunString(int x, int y, const void *str); void Draw_AltFunString(int x, int y, const void *str);
void Draw_FunStringWidth(int x, int y, const void *str, int width); void Draw_FunStringWidth(int x, int y, const void *str, int width);
int r_regsequence;
#ifdef SERVERONLY #ifdef SERVERONLY
#define Mod_Q1LeafPVS Mod_LeafPVS #define Mod_Q1LeafPVS Mod_LeafPVS
// qbyte *Mod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer); // qbyte *Mod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
#endif #endif
typedef union { typedef struct
unsigned int num; {
int regsequence;
} texcom_t;
struct texid_s
{
union
{
unsigned int num;
#ifdef D3DQUAKE #ifdef D3DQUAKE
void *ptr; void *ptr;
#endif
};
texcom_t *ref;
};
#if 1
typedef struct texid_s texid_t;
#define texid_tf texid_t
#define TEXASSIGN(d,s) d=s
#define TEXASSIGNF(d,s) d=s
#define TEXVALID(t) ((t).ref!=NULL)
#else
typedef struct texid_s texid_t[1];
typedef struct texid_s texid_tf;
#define TEXASSIGN(d,s) memcpy(&d,&s,sizeof(d))
#define TEXASSIGNF(d,s) memcpy(&d,&s,sizeof(d))
#define TEXVALID(t) 1
#endif #endif
} texid_t;
typedef enum uploadfmt uploadfmt_t; typedef enum uploadfmt uploadfmt_t;
//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented) //not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented)
typedef enum backendmode_e typedef enum backendmode_e
@ -182,12 +205,12 @@ typedef struct rendererinfo_s {
void (*Draw_Init) (void); void (*Draw_Init) (void);
void (*Draw_Shutdown) (void); void (*Draw_Shutdown) (void);
texid_t (*IMG_LoadTexture) (char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags); texid_tf (*IMG_LoadTexture) (char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);
texid_t (*IMG_LoadTexture8Pal24) (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags); texid_tf (*IMG_LoadTexture8Pal24) (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_t (*IMG_LoadTexture8Pal32) (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags); texid_tf (*IMG_LoadTexture8Pal32) (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t (*IMG_LoadCompressed) (char *name); texid_tf (*IMG_LoadCompressed) (char *name);
texid_t (*IMG_FindTexture) (char *identifier); texid_tf (*IMG_FindTexture) (char *identifier);
texid_t (*IMG_AllocNewTexture) (int w, int h); texid_tf (*IMG_AllocNewTexture) (char *identifier, int w, int h);
void (*IMG_Upload) (texid_t tex, char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags); void (*IMG_Upload) (texid_t tex, char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags);
void (*IMG_DestroyTexture) (texid_t tex); void (*IMG_DestroyTexture) (texid_t tex);
@ -248,6 +271,7 @@ typedef struct rendererinfo_s {
//Uploads all modified lightmaps //Uploads all modified lightmaps
void (*BE_UploadAllLightmaps)(void); void (*BE_UploadAllLightmaps)(void);
void (*BE_SelectEntity)(struct entity_s *ent); void (*BE_SelectEntity)(struct entity_s *ent);
void (*BE_SelectDLight)(struct dlight_s *dl, vec3_t colour);
/*check to see if an ent should be drawn for the selected light*/ /*check to see if an ent should be drawn for the selected light*/
qboolean (*BE_LightCullModel)(vec3_t org, struct model_s *model); qboolean (*BE_LightCullModel)(vec3_t org, struct model_s *model);
@ -272,6 +296,7 @@ typedef struct rendererinfo_s {
#define BE_UploadAllLightmaps rf->BE_UploadAllLightmaps #define BE_UploadAllLightmaps rf->BE_UploadAllLightmaps
#define BE_LightCullModel rf->BE_LightCullModel #define BE_LightCullModel rf->BE_LightCullModel
#define BE_SelectEntity rf->BE_SelectEntity #define BE_SelectEntity rf->BE_SelectEntity
#define BE_SelectDLight rf->BE_SelectDLight
#define BE_GetTempBatch rf->BE_GetTempBatch #define BE_GetTempBatch rf->BE_GetTempBatch
#define BE_SubmitBatch rf->BE_SubmitBatch #define BE_SubmitBatch rf->BE_SubmitBatch
#define BE_DrawMesh_List rf->BE_DrawMesh_List #define BE_DrawMesh_List rf->BE_DrawMesh_List

View File

@ -591,8 +591,8 @@ void Master_AddMaster (char *address, int type, char *description)
return; return;
} }
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("Master_AddMaster: add ipv6. don't care about tcp/irc.") #pragma warningmsg("Master_AddMaster: add ipv6. don't care about tcp/irc.")
#endif #endif
if (adr.type != NA_IP && adr.type != NA_IPX) if (adr.type != NA_IP && adr.type != NA_IPX)
{ {
@ -797,8 +797,8 @@ void NET_SendPollPacket(int len, void *data, netadr_t to)
int ret; int ret;
struct sockaddr_qstorage addr; struct sockaddr_qstorage addr;
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("NET_SendPollPacket: no support for ipv6") #pragma warningmsg("NET_SendPollPacket: no support for ipv6")
#endif #endif
NetadrToSockadr (&to, &addr); NetadrToSockadr (&to, &addr);

View File

@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "shader.h" #include "shader.h"
#include "renderque.h" #include "renderque.h"
#define POLYS
void D_DrawParticleTrans (vec3_t porg, float palpha, float pscale, unsigned int pcolour, blendmode_t blendmode); void D_DrawParticleTrans (vec3_t porg, float palpha, float pscale, unsigned int pcolour, blendmode_t blendmode);
@ -82,7 +84,7 @@ static int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66};
static int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; static int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3};
#define qpal(q) ((default_quakepal[(q)*3+0]<<0) | (default_quakepal[(q)*3+1]<<8) | (default_quakepal[(q)*3+2]<<16)) #define qpal(q) ((default_quakepal[(q)*3+0]<<0) | (default_quakepal[(q)*3+1]<<8) | (default_quakepal[(q)*3+2]<<16))
#ifndef POLYS
#define BUFFERVERTS 2048*3 #define BUFFERVERTS 2048*3
static vecV_t classicverts[BUFFERVERTS]; static vecV_t classicverts[BUFFERVERTS];
static union c static union c
@ -93,6 +95,7 @@ static union c
static vec2_t classictexcoords[BUFFERVERTS]; static vec2_t classictexcoords[BUFFERVERTS];
static index_t classicindexes[BUFFERVERTS]; static index_t classicindexes[BUFFERVERTS];
mesh_t classicmesh; mesh_t classicmesh;
#endif
static shader_t *classicshader; static shader_t *classicshader;
@ -197,6 +200,7 @@ static qboolean PClassic_InitParticles (void)
particles = (cparticle_t *) BZ_Malloc (r_numparticles * sizeof(cparticle_t)); particles = (cparticle_t *) BZ_Malloc (r_numparticles * sizeof(cparticle_t));
#ifndef POLYS
for (i = 0; i < BUFFERVERTS; i += 3) for (i = 0; i < BUFFERVERTS; i += 3)
{ {
classictexcoords[i+1][0] = 1; classictexcoords[i+1][0] = 1;
@ -210,6 +214,7 @@ static qboolean PClassic_InitParticles (void)
classicmesh.st_array = classictexcoords; classicmesh.st_array = classictexcoords;
classicmesh.colors4b_array = (byte_vec4_t*)classiccolours; classicmesh.colors4b_array = (byte_vec4_t*)classiccolours;
classicmesh.indexes = classicindexes; classicmesh.indexes = classicindexes;
#endif
classicshader = R_RegisterShader("particles_classic", classicshader = R_RegisterShader("particles_classic",
"{\n" "{\n"
"nomipmaps\n" "nomipmaps\n"
@ -221,7 +226,7 @@ static qboolean PClassic_InitParticles (void)
"}\n" "}\n"
"}\n" "}\n"
); );
classicshader->defaulttextures.base = particlecqtexture; TEXASSIGN(classicshader->defaulttextures.base, particlecqtexture);
return true; return true;
} }
@ -279,8 +284,13 @@ static void PClassic_DrawParticles(void)
float time2, time3, time1, dvel, frametime, grav; float time2, time3, time1, dvel, frametime, grav;
vec3_t up, right; vec3_t up, right;
float dist, scale, r_partscale=0; float dist, scale, r_partscale=0;
union c usecolours;
unsigned int *palette; unsigned int *palette;
#ifdef POLYS
scenetris_t *scenetri;
#else
union c usecolours;
#endif
static float oldtime;
RSpeedMark(); RSpeedMark();
/*#ifdef D3DQUAKE /*#ifdef D3DQUAKE
@ -302,7 +312,9 @@ static void PClassic_DrawParticles(void)
VectorScale (vup, 1.5, up); VectorScale (vup, 1.5, up);
VectorScale (vright, 1.5, right); VectorScale (vright, 1.5, right);
frametime = host_frametime; frametime = cl.time - oldtime;
oldtime = cl.time;
frametime = bound(0, frametime, 1);
if (cl.paused || r_secondaryview || r_refdef.recurse) if (cl.paused || r_secondaryview || r_refdef.recurse)
frametime = 0; frametime = 0;
time3 = frametime * 15; time3 = frametime * 15;
@ -311,6 +323,25 @@ static void PClassic_DrawParticles(void)
grav = frametime * 800 * 0.05; grav = frametime * 800 * 0.05;
dvel = 4 * frametime; dvel = 4 * frametime;
#ifdef POLYS
if (cl_numstris && cl_stris[cl_numstris-1].shader == classicshader)
scenetri = &cl_stris[cl_numstris-1];
else
{
if (cl_numstris == cl_maxstris)
{
cl_maxstris+=8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
}
scenetri = &cl_stris[cl_numstris++];
scenetri->shader = classicshader;
scenetri->firstidx = cl_numstrisidx;
scenetri->firstvert = cl_numstrisvert;
scenetri->numvert = 0;
scenetri->numidx = 0;
}
#endif
while(1) while(1)
{ {
kill = active_particles; kill = active_particles;
@ -339,6 +370,49 @@ static void PClassic_DrawParticles(void)
break; break;
} }
// hack a scale up to keep particles from disapearing
dist = (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] - r_origin[1]) * vpn[1] + (p->org[2] - r_origin[2]) * vpn[2];
scale = 1 + dist * r_partscale;
#ifdef POLYS
if (cl_numstrisvert+3 > cl_maxstrisvert)
{
cl_maxstrisvert+=64*3;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
Vector4Set(cl_strisvertc[cl_numstrisvert+0],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+1],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+2],1,1,1,1);
Vector4Set(cl_strisvertc[cl_numstrisvert+0], ((p->rgb&0xff)>>0)/256.0, ((p->rgb&0xff00)>>8)/256.0, ((p->rgb&0xff0000)>>16)/256.0, ((p->type == pt_fire)?((6 - p->ramp) *0.166666):1.0));
Vector4Copy(cl_strisvertc[cl_numstrisvert+0], cl_strisvertc[cl_numstrisvert+1]);
Vector4Copy(cl_strisvertc[cl_numstrisvert+0], cl_strisvertc[cl_numstrisvert+2]);
Vector2Set(cl_strisvertt[cl_numstrisvert+0], 0, 0);
Vector2Set(cl_strisvertt[cl_numstrisvert+1], 1, 0);
Vector2Set(cl_strisvertt[cl_numstrisvert+2], 0, 1);
VectorCopy(p->org, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(p->org, scale, up, cl_strisvertv[cl_numstrisvert+1]);
VectorMA(p->org, scale, right, cl_strisvertv[cl_numstrisvert+2]);
if (cl_numstrisidx+3 > cl_maxstrisidx)
{
cl_maxstrisidx += 64*3;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - scenetri->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - scenetri->firstvert) + 1;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - scenetri->firstvert) + 2;
cl_numstrisvert += 3;
scenetri->numvert += 3;
scenetri->numidx += 3;
#else
if (classicmesh.numvertexes >= BUFFERVERTS-3) if (classicmesh.numvertexes >= BUFFERVERTS-3)
{ {
classicmesh.numindexes = classicmesh.numvertexes; classicmesh.numindexes = classicmesh.numvertexes;
@ -346,11 +420,6 @@ static void PClassic_DrawParticles(void)
classicmesh.numvertexes = 0; classicmesh.numvertexes = 0;
} }
// hack a scale up to keep particles from disapearing
dist = (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] - r_origin[1]) * vpn[1] + (p->org[2] - r_origin[2]) * vpn[2];
scale = 1 + dist * r_partscale;
usecolours.i = p->rgb; usecolours.i = p->rgb;
if (p->type == pt_fire) if (p->type == pt_fire)
usecolours.b[3] = 255 * (6 - p->ramp) / 6; usecolours.b[3] = 255 * (6 - p->ramp) / 6;
@ -365,9 +434,7 @@ static void PClassic_DrawParticles(void)
classiccolours[classicmesh.numvertexes].i = usecolours.i; classiccolours[classicmesh.numvertexes].i = usecolours.i;
VectorMA(p->org, scale, right, classicverts[classicmesh.numvertexes]); VectorMA(p->org, scale, right, classicverts[classicmesh.numvertexes]);
classicmesh.numvertexes++; classicmesh.numvertexes++;
#endif
p->org[0] += p->vel[0] * frametime; p->org[0] += p->vel[0] * frametime;
p->org[1] += p->vel[1] * frametime; p->org[1] += p->vel[1] * frametime;
@ -421,14 +488,14 @@ static void PClassic_DrawParticles(void)
break; break;
} }
} }
#ifndef POLYS
if (classicmesh.numvertexes) if (classicmesh.numvertexes)
{ {
classicmesh.numindexes = classicmesh.numvertexes; classicmesh.numindexes = classicmesh.numvertexes;
BE_DrawMesh_Single(classicshader, &classicmesh, NULL, &classicshader->defaulttextures, 0); BE_DrawMesh_Single(classicshader, &classicmesh, NULL, &classicshader->defaulttextures, 0);
classicmesh.numvertexes = 0; classicmesh.numvertexes = 0;
} }
#endif
RSpeedEnd(RSPEED_PARTICLESDRAW); RSpeedEnd(RSPEED_PARTICLESDRAW);
} }
@ -741,7 +808,7 @@ done:
//builds a trail from here to there. The trail state can be used to remember how far you got last frame. //builds a trail from here to there. The trail state can be used to remember how far you got last frame.
static int PClassic_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) static int PClassic_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlkey, trailstate_t **tsk)
{ {
float leftover; float leftover;

View File

@ -19,7 +19,7 @@ static int PNULL_FindParticleType(char *name)
} }
static int PNULL_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *name){return 1;} static int PNULL_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *name){return 1;}
static int PNULL_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk){return 1;} static int PNULL_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlkey, trailstate_t **tsk){return 1;}
static int PNULL_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk){return 1;} static int PNULL_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk){return 1;}
static void PNULL_RunParticleWeather(vec3_t minb, vec3_t maxb, vec3_t dir, float count, int colour, char *efname){} static void PNULL_RunParticleWeather(vec3_t minb, vec3_t maxb, vec3_t dir, float count, int colour, char *efname){}
static void PNULL_RunParticleCube(vec3_t minb, vec3_t maxb, vec3_t dir, float count, int colour, qboolean gravity, float jitter){} static void PNULL_RunParticleCube(vec3_t minb, vec3_t maxb, vec3_t dir, float count, int colour, qboolean gravity, float jitter){}

View File

@ -246,7 +246,7 @@ typedef struct part_type_s {
vec3_t dl_rgb; vec3_t dl_rgb;
float dl_radius; float dl_radius;
float dl_time; float dl_time;
vec3_t dl_decay; vec4_t dl_decay;
vec3_t stain_rgb; vec3_t stain_rgb;
float stain_radius; float stain_radius;
@ -534,7 +534,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n" "rgbgen vertex\n"
"alphagen vertex\n" "alphagen vertex\n"
"}\n" "}\n"
"polygonoffset\n" // "polygonoffset\n"
"}\n" "}\n"
; ;
break; break;
@ -549,7 +549,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n" "rgbgen vertex\n"
"alphagen vertex\n" "alphagen vertex\n"
"}\n" "}\n"
"polygonoffset\n" // "polygonoffset\n"
"}\n" "}\n"
; ;
break; break;
@ -564,7 +564,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n" "rgbgen vertex\n"
"alphagen vertex\n" "alphagen vertex\n"
"}\n" "}\n"
"polygonoffset\n" // "polygonoffset\n"
"}\n" "}\n"
; ;
break; break;
@ -579,7 +579,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n" "rgbgen vertex\n"
"alphagen vertex\n" "alphagen vertex\n"
"}\n" "}\n"
"polygonoffset\n" // "polygonoffset\n"
"}\n" "}\n"
; ;
break; break;
@ -594,7 +594,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n" "rgbgen vertex\n"
"alphagen vertex\n" "alphagen vertex\n"
"}\n" "}\n"
"polygonoffset\n" // "polygonoffset\n"
"}\n" "}\n"
; ;
break; break;
@ -616,26 +616,26 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
{ {
/*untextured beams get a single continuous blob*/ /*untextured beams get a single continuous blob*/
ptype->looks.shader = R_RegisterShader(va("beam%s", namepostfix), defaultshader); ptype->looks.shader = R_RegisterShader(va("beam%s", namepostfix), defaultshader);
tn.base = beamtexture; TEXASSIGNF(tn.base, beamtexture);
} }
else if (ptype->looks.type == PT_SPARKFAN) else if (ptype->looks.type == PT_SPARKFAN)
{ {
/*untextured beams get a single continuous blob*/ /*untextured beams get a single continuous blob*/
ptype->looks.shader = R_RegisterShader(va("fan%s", namepostfix), defaultshader); ptype->looks.shader = R_RegisterShader(va("fan%s", namepostfix), defaultshader);
tn.base = ptritexture; TEXASSIGNF(tn.base, ptritexture);
} }
else if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball") || ptype->looks.type == PT_TEXTUREDSPARK) else if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball") || ptype->looks.type == PT_TEXTUREDSPARK)
{ {
/*sparks and special names get a nice circular texture. /*sparks and special names get a nice circular texture.
as these are fully default, we can basically discard the texture name in the shader, and get better batching*/ as these are fully default, we can basically discard the texture name in the shader, and get better batching*/
ptype->looks.shader = R_RegisterShader(va("ball%s", namepostfix), defaultshader); ptype->looks.shader = R_RegisterShader(va("ball%s", namepostfix), defaultshader);
tn.base = balltexture; TEXASSIGNF(tn.base, balltexture);
} }
else else
{ {
/*anything else gets a fuzzy texture*/ /*anything else gets a fuzzy texture*/
ptype->looks.shader = R_RegisterShader(va("default%s", namepostfix), defaultshader); ptype->looks.shader = R_RegisterShader(va("default%s", namepostfix), defaultshader);
tn.base = explosiontexture; TEXASSIGNF(tn.base, explosiontexture);
} }
} }
else else
@ -680,7 +680,52 @@ static void P_ParticleEffect_f(void)
return; return;
} }
ptype = P_GetParticleType(Cmd_Argv(1)); var = Cmd_Argv(1);
if (*var == '+')
{
ptype = P_GetParticleType(var+1);
if (ptype->loaded)
{
int i, parenttype;
char newname[256];
for (i = 0; i < 64; i++)
{
parenttype = ptype - part_type;
snprintf(newname, sizeof(newname), "+%i%s", i, var);
ptype = P_GetParticleType(newname);
if (!ptype->loaded)
{
if (part_type[parenttype].assoc != P_INVALID)
Con_Printf("warning: assoc on particle chain %s overridden\n", var+1);
part_type[parenttype].assoc = ptype - part_type;
break;
}
}
if (i == 64)
{
Con_Printf("Too many duplicate names, gave up\n");
return;
}
}
}
else
{
ptype = P_GetParticleType(Cmd_Argv(1));
if (ptype->loaded)
{
assoc = ptype->assoc;
while (assoc != P_INVALID && assoc < FALLBACKBIAS)
{
if (*part_type[assoc].name == '+')
{
part_type[assoc].loaded = false;
assoc = part_type[assoc].assoc;
}
else
break;
}
}
}
if (!ptype) if (!ptype)
{ {
Con_Printf("Bad name\n"); Con_Printf("Bad name\n");
@ -811,6 +856,7 @@ static void P_ParticleEffect_f(void)
else if (!strcmp(var, "beamtexstep")) else if (!strcmp(var, "beamtexstep"))
{ {
ptype->rotationstartmin = 1/atof(value); ptype->rotationstartmin = 1/atof(value);
ptype->rotationstartrand = 0;
setbeamlen = true; setbeamlen = true;
} }
else if (!strcmp(var, "beamtexspeed")) else if (!strcmp(var, "beamtexspeed"))
@ -1247,6 +1293,25 @@ static void P_ParticleEffect_f(void)
ptype->flags |= PT_NOSPREADFIRST; ptype->flags |= PT_NOSPREADFIRST;
else if (!strcmp(var, "nospreadlast")) else if (!strcmp(var, "nospreadlast"))
ptype->flags |= PT_NOSPREADLAST; ptype->flags |= PT_NOSPREADLAST;
else if (!strcmp(var, "lightradius"))
ptype->dl_radius = atof(value);
else if (!strcmp(var, "lightradiusfade"))
ptype->dl_decay[3] = atof(value);
else if (!strcmp(var, "lightrgb"))
{
ptype->dl_rgb[0] = atof(value);
ptype->dl_rgb[1] = atof(Cmd_Argv(2));
ptype->dl_rgb[2] = atof(Cmd_Argv(3));
}
else if (!strcmp(var, "lightrgbfade"))
{
ptype->dl_decay[0] = atof(value);
ptype->dl_decay[1] = atof(Cmd_Argv(2));
ptype->dl_decay[2] = atof(Cmd_Argv(3));
}
else if (!strcmp(var, "lighttime"))
ptype->dl_time = atof(value);
else else
Con_DPrintf("%s is not a recognised particle type field (in %s)\n", var, ptype->name); Con_DPrintf("%s is not a recognised particle type field (in %s)\n", var, ptype->name);
} }
@ -2295,7 +2360,7 @@ static vec2_t avelocities[NUMVERTEXNORMALS];
// float timescale = 0.01; // float timescale = 0.01;
static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir) static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, int dlkey)
{ {
if (*ptype->modelname) if (*ptype->modelname)
{ {
@ -2306,10 +2371,11 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir)
} }
if (ptype->dl_radius) if (ptype->dl_radius)
{ {
dlight_t *dl = CL_NewDlightRGB(0, org, ptype->dl_radius, ptype->dl_time, ptype->dl_rgb[0], ptype->dl_rgb[1], ptype->dl_rgb[2]); dlight_t *dl = CL_NewDlightRGB(dlkey, org, ptype->dl_radius, ptype->dl_time, ptype->dl_rgb[0], ptype->dl_rgb[1], ptype->dl_rgb[2]);
dl->channelfade[0] = ptype->dl_decay[0]; dl->channelfade[0] = ptype->dl_decay[0];
dl->channelfade[1] = ptype->dl_decay[1]; dl->channelfade[1] = ptype->dl_decay[1];
dl->channelfade[2] = ptype->dl_decay[2]; dl->channelfade[2] = ptype->dl_decay[2];
dl->decay = ptype->dl_decay[3];
} }
if (ptype->stain_radius) if (ptype->stain_radius)
R_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius); R_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius);
@ -2378,7 +2444,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
while(ptype) while(ptype)
{ {
PScript_EffectSpawned(ptype, org, dir); PScript_EffectSpawned(ptype, org, dir, 0);
if (ptype->looks.type == PT_DECAL) if (ptype->looks.type == PT_DECAL)
{ {
@ -3139,7 +3205,7 @@ static void PScript_RunParticleWeather(vec3_t minb, vec3_t maxb, vec3_t dir, flo
} }
} }
static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype, trailstate_t **tsk) static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype, trailstate_t **tsk, int dlkey)
{ {
vec3_t vec, vstep, right, up, start; vec3_t vec, vstep, right, up, start;
float len; float len;
@ -3187,14 +3253,14 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
else else
ts = NULL; ts = NULL;
PScript_EffectSpawned(ptype, start, vec3_origin); PScript_EffectSpawned(ptype, start, vec3_origin, dlkey);
if (ptype->assoc>=0) if (ptype->assoc>=0)
{ {
if (ts) if (ts)
P_ParticleTrail(start, end, ptype->assoc, &(ts->assoc)); P_ParticleTrail(start, end, ptype->assoc, dlkey, &(ts->assoc));
else else
P_ParticleTrail(start, end, ptype->assoc, NULL); P_ParticleTrail(start, end, ptype->assoc, dlkey, NULL);
} }
// time limit for trails // time limit for trails
@ -3608,14 +3674,14 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
return; return;
} }
static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailstate_t **tsk) static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlkey, trailstate_t **tsk)
{ {
part_type_t *ptype = &part_type[type]; part_type_t *ptype = &part_type[type];
// TODO: fallback particle system won't have a decent trailstate which will mess up // TODO: fallback particle system won't have a decent trailstate which will mess up
// high fps trails // high fps trails
if (type >= FALLBACKBIAS && fallback) if (type >= FALLBACKBIAS && fallback)
return fallback->ParticleTrail(startpos, end, type-FALLBACKBIAS, NULL); return fallback->ParticleTrail(startpos, end, type-FALLBACKBIAS, dlkey, NULL);
if (type < 0 || type >= numparticletypes) if (type < 0 || type >= numparticletypes)
return 1; //bad value return 1; //bad value
@ -3633,7 +3699,7 @@ static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailst
ptype = &part_type[ptype->inwater]; ptype = &part_type[ptype->inwater];
} }
P_ParticleTrailDraw (startpos, end, ptype, tsk); P_ParticleTrailDraw (startpos, end, ptype, tsk, dlkey);
return 0; return 0;
} }
@ -3641,7 +3707,7 @@ static void PScript_ParticleTrailIndex (vec3_t start, vec3_t end, int color, int
{ {
part_type[pe_defaulttrail].colorindex = color; part_type[pe_defaulttrail].colorindex = color;
part_type[pe_defaulttrail].colorrand = crnd; part_type[pe_defaulttrail].colorrand = crnd;
P_ParticleTrail(start, end, pe_defaulttrail, tsk); P_ParticleTrail(start, end, pe_defaulttrail, 0, tsk);
} }
static vec3_t pright, pup; static vec3_t pright, pup;
@ -3779,8 +3845,8 @@ static void GL_DrawTrifanParticle(int count, particle_t **plist, plooks_t *type)
static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *type) static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *type)
{ {
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("fixme: no line sparks") #pragma warningmsg("fixme: no line sparks")
#endif #endif
#if 0 #if 0
particle_t *p; particle_t *p;
@ -3810,6 +3876,89 @@ static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *ty
#endif #endif
} }
static void R_AddTSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type)
{
vec3_t v, cr, o2;
float scale;
if (cl_numstrisvert+4 > cl_maxstrisvert)
{
cl_maxstrisvert+=64*4;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
if (type->scalefactor == 1)
scale = p->scale*0.25;
else
{
scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
+ (p->org[2] - r_origin[2])*vpn[2];
scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250);
if (scale < 20)
scale = 0.25;
else
scale = 0.25 + scale * 0.001;
}
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+0]);
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+1]);
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+2]);
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+3]);
Vector2Set(cl_strisvertt[cl_numstrisvert+0], p->s1, p->t1);
Vector2Set(cl_strisvertt[cl_numstrisvert+1], p->s1, p->t2);
Vector2Set(cl_strisvertt[cl_numstrisvert+2], p->s2, p->t2);
Vector2Set(cl_strisvertt[cl_numstrisvert+3], p->s2, p->t1);
if (type->stretch)
{
VectorMA(p->org, type->stretch, p->vel, o2);
VectorMA(p->org, -type->stretch, p->vel, v);
VectorSubtract(r_refdef.vieworg, v, v);
}
else
{
VectorMA(p->org, 0.1, p->vel, o2);
VectorSubtract(r_refdef.vieworg, p->org, v);
}
CrossProduct(v, p->vel, cr);
VectorNormalize(cr);
VectorMA(p->org, -p->scale/2, cr, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(p->org, p->scale/2, cr, cl_strisvertv[cl_numstrisvert+1]);
VectorSubtract(r_refdef.vieworg, o2, v);
CrossProduct(v, p->vel, cr);
VectorNormalize(cr);
VectorMA(o2, p->scale/2, cr, cl_strisvertv[cl_numstrisvert+2]);
VectorMA(o2, -p->scale/2, cr, cl_strisvertv[cl_numstrisvert+3]);
if (cl_numstrisidx+6 > cl_maxstrisidx)
{
cl_maxstrisidx += 64*6;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 1;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 2;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 2;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 3;
cl_numstrisvert += 4;
t->numvert += 4;
t->numidx += 6;
}
static void GL_DrawTexturedSparkParticle(int count, particle_t **plist, plooks_t *type) static void GL_DrawTexturedSparkParticle(int count, particle_t **plist, plooks_t *type)
{ {
particle_t *p; particle_t *p;
@ -3902,6 +4051,7 @@ static void GL_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type)
VectorSubtract(r_refdef.vieworg, q->org, v); VectorSubtract(r_refdef.vieworg, q->org, v);
VectorNormalize(v); VectorNormalize(v);
CrossProduct(c->dir, v, cr); CrossProduct(c->dir, v, cr);
VectorNormalize(cr);
ts = c->texture_s*q->angle + particletime*q->rotationspeed; ts = c->texture_s*q->angle + particletime*q->rotationspeed;
Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+0]); Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+0]);
Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+1]); Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+1]);
@ -3913,6 +4063,7 @@ static void GL_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type)
VectorSubtract(r_refdef.vieworg, p->org, v); VectorSubtract(r_refdef.vieworg, p->org, v);
VectorNormalize(v); VectorNormalize(v);
CrossProduct(b->dir, v, cr); // replace with old p->dir? CrossProduct(b->dir, v, cr); // replace with old p->dir?
VectorNormalize(cr);
ts = b->texture_s*p->angle + particletime*p->rotationspeed; ts = b->texture_s*p->angle + particletime*p->rotationspeed;
Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]); Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]);
Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+3]); Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+3]);
@ -3970,6 +4121,85 @@ static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *typ
} }
} }
static void R_AddTexturedParticle(scenetris_t *t, particle_t *p, plooks_t *type)
{
float scale, x, y;
if (cl_numstrisvert+4 > cl_maxstrisvert)
{
cl_maxstrisvert+=64*4;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
if (type->scalefactor == 1)
scale = p->scale*0.25;
else
{
scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
+ (p->org[2] - r_origin[2])*vpn[2];
scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250);
if (scale < 20)
scale = 0.25;
else
scale = 0.25 + scale * 0.001;
}
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+0]);
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+1]);
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+2]);
Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+3]);
Vector2Set(cl_strisvertt[cl_numstrisvert+0], p->s1, p->t1);
Vector2Set(cl_strisvertt[cl_numstrisvert+1], p->s1, p->t2);
Vector2Set(cl_strisvertt[cl_numstrisvert+2], p->s2, p->t2);
Vector2Set(cl_strisvertt[cl_numstrisvert+3], p->s2, p->t1);
if (p->angle)
{
x = sin(p->angle)*scale;
y = cos(p->angle)*scale;
cl_strisvertv[cl_numstrisvert+0][0] = p->org[0] - x*pright[0] - y*pup[0];
cl_strisvertv[cl_numstrisvert+0][1] = p->org[1] - x*pright[1] - y*pup[1];
cl_strisvertv[cl_numstrisvert+0][2] = p->org[2] - x*pright[2] - y*pup[2];
cl_strisvertv[cl_numstrisvert+1][0] = p->org[0] - y*pright[0] + x*pup[0];
cl_strisvertv[cl_numstrisvert+1][1] = p->org[1] - y*pright[1] + x*pup[1];
cl_strisvertv[cl_numstrisvert+1][2] = p->org[2] - y*pright[2] + x*pup[2];
cl_strisvertv[cl_numstrisvert+2][0] = p->org[0] + x*pright[0] + y*pup[0];
cl_strisvertv[cl_numstrisvert+2][1] = p->org[1] + x*pright[1] + y*pup[1];
cl_strisvertv[cl_numstrisvert+2][2] = p->org[2] + x*pright[2] + y*pup[2];
cl_strisvertv[cl_numstrisvert+3][0] = p->org[0] + y*pright[0] - x*pup[0];
cl_strisvertv[cl_numstrisvert+3][1] = p->org[1] + y*pright[1] - x*pup[1];
cl_strisvertv[cl_numstrisvert+3][2] = p->org[2] + y*pright[2] - x*pup[2];
}
else
{
VectorMA(p->org, -scale, pup, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(p->org, -scale, pright, cl_strisvertv[cl_numstrisvert+1]);
VectorMA(p->org, scale, pup, cl_strisvertv[cl_numstrisvert+2]);
VectorMA(p->org, scale, pright, cl_strisvertv[cl_numstrisvert+3]);
}
if (cl_numstrisidx+6 > cl_maxstrisidx)
{
cl_maxstrisidx += 64*6;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 1;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 2;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 2;
cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 3;
cl_numstrisvert += 4;
t->numvert += 4;
t->numidx += 6;
}
static void PScript_DrawParticleTypes (void) static void PScript_DrawParticleTypes (void)
{ {
void (*sparklineparticles)(int count, particle_t **,plooks_t*)=GL_DrawLineSparkParticle; void (*sparklineparticles)(int count, particle_t **,plooks_t*)=GL_DrawLineSparkParticle;
@ -3978,6 +4208,7 @@ static void PScript_DrawParticleTypes (void)
qboolean (*tr) (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal); qboolean (*tr) (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
void *pdraw, *bdraw; void *pdraw, *bdraw;
void (*tdraw)(scenetris_t *t, particle_t *p, plooks_t *type);
vec3_t oldorg; vec3_t oldorg;
vec3_t stop, normal; vec3_t stop, normal;
@ -3987,6 +4218,7 @@ static void PScript_DrawParticleTypes (void)
ramp_t *ramp; ramp_t *ramp;
float grav; float grav;
vec3_t friction; vec3_t friction;
scenetris_t *scenetri;
float dist; float dist;
particle_t *kill_list, *kill_first; //the kill list is to stop particles from being freed and reused whilst still in this loop particle_t *kill_list, *kill_first; //the kill list is to stop particles from being freed and reused whilst still in this loop
//which is bad because beams need to find out when particles died. Reuse can do wierd things. //which is bad because beams need to find out when particles died. Reuse can do wierd things.
@ -4116,6 +4348,7 @@ static void PScript_DrawParticleTypes (void)
bdraw = NULL; bdraw = NULL;
pdraw = NULL; pdraw = NULL;
tdraw = NULL;
// set drawing methods by type and cvars and hope branch // set drawing methods by type and cvars and hope branch
// prediction takes care of the rest // prediction takes care of the rest
@ -4131,6 +4364,7 @@ static void PScript_DrawParticleTypes (void)
break; break;
case PT_NORMAL: case PT_NORMAL:
pdraw = GL_DrawTexturedParticle; pdraw = GL_DrawTexturedParticle;
tdraw = R_AddTexturedParticle;
break; break;
case PT_SPARK: case PT_SPARK:
pdraw = sparklineparticles; pdraw = sparklineparticles;
@ -4140,9 +4374,29 @@ static void PScript_DrawParticleTypes (void)
break; break;
case PT_TEXTUREDSPARK: case PT_TEXTUREDSPARK:
pdraw = sparktexturedparticles; pdraw = sparktexturedparticles;
tdraw = R_AddTSparkParticle;
break; break;
} }
if (!tdraw || type->looks.shader->sort == SHADER_SORT_BLEND)
scenetri = NULL;
else if (cl_numstris && cl_stris[cl_numstris-1].shader == type->looks.shader)
scenetri = &cl_stris[cl_numstris-1];
else
{
if (cl_numstris == cl_maxstris)
{
cl_maxstris+=8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
}
scenetri = &cl_stris[cl_numstris++];
scenetri->shader = type->looks.shader;
scenetri->firstidx = cl_numstrisidx;
scenetri->firstvert = cl_numstrisvert;
scenetri->numvert = 0;
scenetri->numidx = 0;
}
if (!type->die) if (!type->die)
{ {
while ((p=type->particles)) while ((p=type->particles))
@ -4358,7 +4612,7 @@ static void PScript_DrawParticleTypes (void)
if (type->emit >= 0) if (type->emit >= 0)
{ {
if (type->emittime < 0) if (type->emittime < 0)
P_ParticleTrail(oldorg, p->org, type->emit, &p->state.trailstate); P_ParticleTrail(oldorg, p->org, type->emit, 0, &p->state.trailstate);
else if (p->state.nextemit < particletime) else if (p->state.nextemit < particletime)
{ {
p->state.nextemit = particletime + type->emittime + frandom()*type->emitrand; p->state.nextemit = particletime + type->emittime + frandom()*type->emitrand;
@ -4387,16 +4641,18 @@ static void PScript_DrawParticleTypes (void)
p->vel[2] *= type->clipbounce; p->vel[2] *= type->clipbounce;
if (!*type->texname && Length(p->vel)<1000*pframetime && type->looks.type == PT_NORMAL) if (!*type->texname && Length(p->vel)<1000*pframetime && type->looks.type == PT_NORMAL)
{
p->die = -1; p->die = -1;
continue;
}
} }
else else
{ {
p->die = -1; p->die = -1;
VectorNormalize(p->vel); VectorNormalize(p->vel);
P_RunParticleEffectType(stop, p->vel, type->clipcount/part_type[type->cliptype].count, type->cliptype); P_RunParticleEffectType(stop, p->vel, type->clipcount/part_type[type->cliptype].count, type->cliptype);
continue;
} }
continue;
} }
} }
else if (type->stainonimpact && r_bloodstains.ival) else if (type->stainonimpact && r_bloodstains.ival)
@ -4412,7 +4668,11 @@ static void PScript_DrawParticleTypes (void)
} }
} }
if (pdraw) if (scenetri)
{
tdraw(scenetri, p, type->slooks);
}
else if (pdraw)
RQ_AddDistReorder((void*)pdraw, p, type->slooks, p->org); RQ_AddDistReorder((void*)pdraw, p, type->slooks, p->org);
} }

View File

@ -39,7 +39,7 @@ typedef struct csqctreadstate_s {
struct csqctreadstate_s *next; struct csqctreadstate_s *next;
} csqctreadstate_t; } csqctreadstate_t;
static unsigned int csqcchecksum; static unsigned int csprogs_checksum, csaddon_checksum;
static csqctreadstate_t *csqcthreads; static csqctreadstate_t *csqcthreads;
qboolean csqc_resortfrags; qboolean csqc_resortfrags;
qboolean csqc_drawsbar; qboolean csqc_drawsbar;
@ -49,6 +49,7 @@ world_t csqc_world;
static int csqc_lplayernum; static int csqc_lplayernum;
static qboolean csqc_isdarkplaces; static qboolean csqc_isdarkplaces;
static qboolean csqc_singlecheats; /*single player or cheats active, allowing custom addons*/
static char csqc_printbuffer[8192]; static char csqc_printbuffer[8192];
@ -156,6 +157,7 @@ typedef enum
globalfloat(svtime, "time"); /*float Written before entering most qc functions*/ \ globalfloat(svtime, "time"); /*float Written before entering most qc functions*/ \
globalfloat(frametime, "frametime"); /*float Written before entering most qc functions*/ \ globalfloat(frametime, "frametime"); /*float Written before entering most qc functions*/ \
globalfloat(cltime, "cltime"); /*float Written before entering most qc functions*/ \ globalfloat(cltime, "cltime"); /*float Written before entering most qc functions*/ \
globalfloat(physics_mode, "physics_mode"); /*float Written before entering most qc functions*/ \
globalentity(self, "self"); /*entity Written before entering most qc functions*/ \ globalentity(self, "self"); /*entity Written before entering most qc functions*/ \
globalentity(other, "other"); /*entity Written before entering most qc functions*/ \ globalentity(other, "other"); /*entity Written before entering most qc functions*/ \
\ \
@ -266,6 +268,7 @@ static void CSQC_ChangeLocalPlayer(int lplayernum)
static void CSQC_FindGlobals(void) static void CSQC_FindGlobals(void)
{ {
static float csphysicsmode = 0;
#define globalfloat(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL); #define globalfloat(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
#define globalvector(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL); #define globalvector(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
#define globalentity(name,qcname) csqcg.name = (int*)PR_FindGlobal(csqcprogs, qcname, 0, NULL); #define globalentity(name,qcname) csqcg.name = (int*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
@ -290,9 +293,16 @@ static void CSQC_FindGlobals(void)
csqc_world.g.self = csqcg.self; csqc_world.g.self = csqcg.self;
csqc_world.g.other = csqcg.other; csqc_world.g.other = csqcg.other;
csqc_world.g.force_retouch = (float*)PR_FindGlobal(csqcprogs, "force_retouch", 0, NULL); csqc_world.g.force_retouch = (float*)PR_FindGlobal(csqcprogs, "force_retouch", 0, NULL);
csqc_world.g.physics_mode = csqcg.physics_mode;
csqc_world.g.frametime = csqcg.frametime; csqc_world.g.frametime = csqcg.frametime;
csqc_world.g.newmis = (int*)PR_FindGlobal(csqcprogs, "newmis", 0, NULL); csqc_world.g.newmis = (int*)PR_FindGlobal(csqcprogs, "newmis", 0, NULL);
csqc_world.g.time = csqcg.svtime; csqc_world.g.time = csqcg.svtime;
csqc_world.g.v_forward = csqcg.forward;
csqc_world.g.v_right = csqcg.right;
csqc_world.g.v_up = csqcg.up;
if (!csqc_world.g.physics_mode)
csqc_world.g.physics_mode = &csphysicsmode;
if (csqcg.maxclients) if (csqcg.maxclients)
*csqcg.maxclients = cl.allocated_client_slots; *csqcg.maxclients = cl.allocated_client_slots;
@ -459,27 +469,6 @@ static int csqcentsize;
static char *csqcmapentitydata; static char *csqcmapentitydata;
static qboolean csqcmapentitydataloaded; static qboolean csqcmapentitydataloaded;
#define MAX_SKEL_OBJECTS 1024
typedef struct {
int inuse;
model_t *model;
qboolean absolute;
unsigned int numbones;
float *bonematrix;
} skelobject_t;
skelobject_t skelobjects[MAX_SKEL_OBJECTS];
int numskelobjectsused;
skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount);
void skel_dodelete(void);
qboolean csqc_deprecated_warned; qboolean csqc_deprecated_warned;
#define csqc_deprecated(s) do {if (!csqc_deprecated_warned){Con_Printf("csqc warning: %s\n", s); csqc_deprecated_warned = true;}}while(0) #define csqc_deprecated(s) do {if (!csqc_deprecated_warned){Con_Printf("csqc warning: %s\n", s); csqc_deprecated_warned = true;}}while(0)
@ -551,13 +540,7 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t
out->bonestate = NULL; out->bonestate = NULL;
if (in->xv->skeletonindex) if (in->xv->skeletonindex)
{ {
skelobject_t *so; skel_lookup(csqcprogs, in->xv->skeletonindex, out);
so = skel_get(csqcprogs, in->xv->skeletonindex, 0);
if (so && so->inuse == 1)
{
out->bonecount = so->numbones;
out->bonestate = so->bonematrix;
}
} }
} }
@ -656,6 +639,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
int ival; int ival;
model_t *model; model_t *model;
unsigned int rflags; unsigned int rflags;
unsigned int effects;
ival = in->v->modelindex; ival = in->v->modelindex;
model = CSQC_GetModelForIndex(ival); model = CSQC_GetModelForIndex(ival);
@ -665,7 +649,8 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
memset(out, 0, sizeof(*out)); memset(out, 0, sizeof(*out));
out->model = model; out->model = model;
if (in->xv->renderflags) rflags = in->xv->renderflags;
if (rflags)
{ {
rflags = in->xv->renderflags; rflags = in->xv->renderflags;
if (rflags & CSQCRF_VIEWMODEL) if (rflags & CSQCRF_VIEWMODEL)
@ -681,10 +666,13 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
out->flags |= RF_NOSHADOW; out->flags |= RF_NOSHADOW;
//CSQCRF_FRAMETIMESARESTARTTIMES is below //CSQCRF_FRAMETIMESARESTARTTIMES is below
} }
else
rflags = 0;
if ((int)in->v->effects & EF_NODEPTHTEST) effects = in->v->effects;
if (effects & NQEF_ADDITIVE)
out->flags |= Q2RF_ADDITIVE;
if (effects & DPEF_NOSHADOW)
out->flags |= RF_NOSHADOW;
if (effects & EF_NODEPTHTEST)
out->flags |= RF_NODEPTHTEST; out->flags |= RF_NODEPTHTEST;
cs_getframestate(in, rflags, &out->framestate); cs_getframestate(in, rflags, &out->framestate);
@ -901,6 +889,7 @@ static void QCBUILTIN PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_
csqcedict_t *ent; csqcedict_t *ent;
entity_t rent; entity_t rent;
int e; int e;
int maxe;
int oldself = *csqcg.self; int oldself = *csqcg.self;
@ -913,7 +902,8 @@ static void QCBUILTIN PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_
} }
} }
for (e=1; e < *prinst->parms->sv_num_edicts; e++) maxe = *prinst->parms->sv_num_edicts;
for (e=1; e < maxe; e++)
{ {
ent = (void*)EDICT_NUM(prinst, e); ent = (void*)EDICT_NUM(prinst, e);
if (ent->isfree) if (ent->isfree)
@ -1134,7 +1124,7 @@ static void QCBUILTIN PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s
CL_SetUpPlayerPrediction(true); CL_SetUpPlayerPrediction(true);
} }
skel_dodelete(); skel_dodelete(csqcprogs);
CL_SwapEntityLists(); CL_SwapEntityLists();
view_frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; view_frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK];
@ -1173,8 +1163,8 @@ static void QCBUILTIN PF_R_GetViewFlag(progfuncs_t *prinst, struct globalvars_s
*r = r_refdef.fov_y; *r = r_refdef.fov_y;
break; break;
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("fixme: AFOV not retrievable") #pragma warningmsg("fixme: AFOV not retrievable")
#endif #endif
case VF_AFOV: case VF_AFOV:
*r = r_refdef.fov_x; *r = r_refdef.fov_x;
@ -1938,9 +1928,9 @@ static void QCBUILTIN PF_cs_trailparticles (progfuncs_t *prinst, struct globalva
} }
if (!ent->entnum) //world trails are non-state-based. if (!ent->entnum) //world trails are non-state-based.
pe->ParticleTrail(start, end, efnum, NULL); pe->ParticleTrail(start, end, efnum, 0, NULL);
else else
pe->ParticleTrail(start, end, efnum, &ent->trailstate); pe->ParticleTrail(start, end, efnum, -ent->entnum, &ent->trailstate);
} }
static void QCBUILTIN PF_cs_particleeffectnum (progfuncs_t *prinst, struct globalvars_s *pr_globals) static void QCBUILTIN PF_cs_particleeffectnum (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -2221,7 +2211,15 @@ static void QCBUILTIN PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
if (!strcmp(keyname, "ip")) if (!strcmp(keyname, "ip"))
ret = NET_AdrToString(adr, sizeof(adr), cls.netchan.remote_address); {
if (cls.demoplayback)
{
extern char lastdemoname[];
ret = lastdemoname;
}
else
ret = NET_AdrToString(adr, sizeof(adr), cls.netchan.remote_address);
}
else if (!strcmp(keyname, "protocol")) else if (!strcmp(keyname, "protocol"))
{ //using this is pretty acedemic, really. Not particuarly portable. { //using this is pretty acedemic, really. Not particuarly portable.
switch (cls.protocol) switch (cls.protocol)
@ -3332,8 +3330,8 @@ static void QCBUILTIN PF_cs_gettaginfo (progfuncs_t *prinst, struct globalvars_s
cs_getframestate(ent, ent->xv->renderflags, &fstate); cs_getframestate(ent, ent->xv->renderflags, &fstate);
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)") #pragma warningmsg("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)")
#endif #endif
if (!Mod_GetTag(mod, tagnum, &fstate, transforms)) if (!Mod_GetTag(mod, tagnum, &fstate, transforms))
{ {
@ -3442,481 +3440,6 @@ static void QCBUILTIN PF_shaderforname (progfuncs_t *prinst, struct globalvars_s
G_FLOAT(OFS_RETURN) = 0; G_FLOAT(OFS_RETURN) = 0;
} }
void skel_reset(void)
{
while (numskelobjectsused > 0)
{
numskelobjectsused--;
skelobjects[numskelobjectsused].numbones = 0;
skelobjects[numskelobjectsused].inuse = false;
}
}
void skel_dodelete(void)
{
int skelidx;
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{
if (skelobjects[skelidx].inuse == 2)
skelobjects[skelidx].inuse = 0;
}
}
skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount)
{
if (skelidx == 0)
{
//allocation
if (!bonecount)
return NULL;
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{
if (!skelobjects[skelidx].inuse && skelobjects[skelidx].numbones == bonecount)
return &skelobjects[skelidx];
}
for (skelidx = 0; skelidx <= numskelobjectsused; skelidx++)
{
if (!skelobjects[skelidx].inuse && !skelobjects[skelidx].numbones)
{
skelobjects[skelidx].numbones = bonecount;
skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount);
if (skelidx <= numskelobjectsused)
{
numskelobjectsused = skelidx + 1;
skelobjects[skelidx].model = NULL;
skelobjects[skelidx].inuse = 1;
}
return &skelobjects[skelidx];
}
}
return NULL;
}
else
{
skelidx--;
if ((unsigned int)skelidx >= numskelobjectsused)
return NULL;
if (skelobjects[skelidx].inuse != 1)
return NULL;
if (bonecount && skelobjects[skelidx].numbones != bonecount)
return NULL;
return &skelobjects[skelidx];
}
}
//float(float modelindex) skel_create (FTE_CSQC_SKELETONOBJECTS)
static void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int numbones;
skelobject_t *skelobj;
qboolean isabs;
model_t *model;
int midx;
midx = G_FLOAT(OFS_PARM0);
//default to failure
G_FLOAT(OFS_RETURN) = 0;
model = CSQC_GetModelForIndex(midx);
if (!model)
return; //no model set, can't get a skeleton
isabs = false;
numbones = Mod_GetNumBones(model, isabs);
if (!numbones)
{
// isabs = true;
// numbones = Mod_GetNumBones(model, isabs);
// if (!numbones)
return; //this isn't a skeletal model.
}
skelobj = skel_get(prinst, 0, numbones);
if (!skelobj)
return; //couldn't get one, ran out of memory or something?
skelobj->model = model;
skelobj->absolute = isabs;
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
}
//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone) skel_build (FTE_CSQC_SKELETONOBJECTS)
static void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM1);
int midx = G_FLOAT(OFS_PARM2);
float retainfrac = G_FLOAT(OFS_PARM3);
int firstbone = G_FLOAT(OFS_PARM4)-1;
int lastbone = G_FLOAT(OFS_PARM5)-1;
float addition = 1?G_FLOAT(OFS_PARM6):1-retainfrac;
int i, j;
int numbones;
framestate_t fstate;
skelobject_t *skelobj;
model_t *model;
//default to failure
G_FLOAT(OFS_RETURN) = 0;
model = CSQC_GetModelForIndex(midx);
if (!model)
return; //invalid model, can't get a skeleton
cs_getframestate(ent, ent->xv->renderflags, &fstate);
//heh... don't copy.
fstate.bonecount = 0;
fstate.bonestate = NULL;
numbones = Mod_GetNumBones(model, false);
if (!numbones)
{
return; //this isn't a skeletal model.
}
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
return; //couldn't get one, ran out of memory or something?
if (lastbone < 0)
lastbone = numbones;
if (lastbone > numbones)
lastbone = numbones;
if (firstbone < 0)
firstbone = 0;
if (retainfrac == 0 && addition == 1)
{
/*replace everything*/
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, skelobj->bonematrix);
}
else
{
if (retainfrac != 1)
{
//rescale the existing bones
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] *= retainfrac;
}
}
if (addition == 1)
{
//just add
float relationsbuf[MAX_BONES*12];
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, relationsbuf);
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] += relationsbuf[i*12+j];
}
}
else if (addition)
{
//add+scale
float relationsbuf[MAX_BONES*12];
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, relationsbuf);
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] += addition*relationsbuf[i*12+j];
}
}
}
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
}
//float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
static void QCBUILTIN PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = skelobj->numbones;
}
//string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
static void QCBUILTIN PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_INT(OFS_RETURN) = 0;
else
{
RETURN_TSTRING(Mod_GetBoneName(skelobj->model, boneidx));
}
}
//float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
static void QCBUILTIN PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_GetBoneParent(skelobj->model, boneidx);
}
//float(float skel, string tagname) gettagindex (DP_MD3_TAGSINFO)
static void QCBUILTIN PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
char *bname = PR_GetStringOfs(prinst, OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(skelobj->model, bname);
}
static void bonemat_fromqcvectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
{
out[0] = vx[0];
out[1] = -vy[0];
out[2] = vz[0];
out[3] = t[0];
out[4] = vx[1];
out[5] = -vy[1];
out[6] = vz[1];
out[7] = t[1];
out[8] = vx[2];
out[9] = -vy[2];
out[10] = vz[2];
out[11] = t[2];
}
void bonemat_toqcvectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = in[0];
vx[1] = in[4];
vx[2] = in[8];
vy[0] = -in[1];
vy[1] = -in[5];
vy[2] = -in[9];
vz[0] = in[2];
vz[1] = in[6];
vz[2] = in[10];
t [0] = in[3];
t [1] = in[7];
t [2] = in[11];
}
void bonematident_toqcvectors(float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = 1;
vx[1] = 0;
vx[2] = 0;
vy[0] = -0;
vy[1] = -1;
vy[2] = -0;
vz[0] = 0;
vz[1] = 0;
vz[2] = 1;
t [0] = 0;
t [1] = 0;
t [2] = 0;
}
//vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
static void QCBUILTIN PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
skelobject_t *skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || skelobj->absolute || (unsigned int)boneidx >= skelobj->numbones)
bonematident_toqcvectors(csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_RETURN));
else
bonemat_toqcvectors(skelobj->bonematrix+12*boneidx, csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_RETURN));
}
//vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
static void QCBUILTIN PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float workingm[12], tempmatrix[3][4];
int i;
skelobject_t *skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || (unsigned int)boneidx >= skelobj->numbones)
bonematident_toqcvectors(csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_RETURN));
else if (skelobj->absolute)
{
//can just copy it out
bonemat_toqcvectors(skelobj->bonematrix + boneidx*12, csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_RETURN));
}
else
{
//we need to work out the abs position
//testme
//set up an identity matrix
for (i = 0;i < 12;i++)
workingm[i] = 0;
workingm[0] = 1;
workingm[5] = 1;
workingm[10] = 1;
while(boneidx >= 0)
{
//copy out the previous working matrix, so we don't stomp on it
memcpy(tempmatrix, workingm, sizeof(tempmatrix));
R_ConcatTransforms((void*)(skelobj->bonematrix + boneidx*12), (void*)tempmatrix, (void*)workingm);
boneidx = Mod_GetBoneParent(skelobj->model, boneidx+1)-1;
}
bonemat_toqcvectors(workingm, csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_RETURN));
}
}
//void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
static void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
unsigned int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[3];
skelobject_t *skelobj;
float *bone;
if (*prinst->callargc > 5)
{
matrix[0] = G_VECTOR(OFS_PARM3);
matrix[1] = G_VECTOR(OFS_PARM4);
matrix[2] = G_VECTOR(OFS_PARM5);
}
else
{
matrix[0] = csqcg.forward;
matrix[1] = csqcg.right;
matrix[2] = csqcg.up;
}
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || boneidx >= skelobj->numbones)
return;
bone = skelobj->bonematrix+12*boneidx;
bonemat_fromqcvectors(skelobj->bonematrix+12*boneidx, matrix[0], matrix[1], matrix[2], G_VECTOR(OFS_PARM2));
}
//void(float skel, float bonenum, vector org [, vector fwd, vector right, vector up]) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
static void QCBUILTIN PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float temp[3][4];
float mult[3][4];
skelobject_t *skelobj;
if (*prinst->callargc > 5)
bonemat_fromqcvectors((float*)mult, G_VECTOR(OFS_PARM3), G_VECTOR(OFS_PARM4), G_VECTOR(OFS_PARM5), G_VECTOR(OFS_PARM2));
else
bonemat_fromqcvectors((float*)mult, csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_PARM2));
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || boneidx >= skelobj->numbones)
return;
//testme
Vector4Copy(skelobj->bonematrix+12*boneidx+0, temp[0]);
Vector4Copy(skelobj->bonematrix+12*boneidx+4, temp[1]);
Vector4Copy(skelobj->bonematrix+12*boneidx+8, temp[2]);
R_ConcatTransforms(mult, temp, (float(*)[4])(skelobj->bonematrix+12*boneidx));
}
//void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
static void QCBUILTIN PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
unsigned int startbone = G_FLOAT(OFS_PARM1)-1;
unsigned int endbone = G_FLOAT(OFS_PARM2)-1;
float temp[3][4];
float mult[3][4];
skelobject_t *skelobj;
if (*prinst->callargc > 6)
bonemat_fromqcvectors((float*)mult, G_VECTOR(OFS_PARM4), G_VECTOR(OFS_PARM5), G_VECTOR(OFS_PARM6), G_VECTOR(OFS_PARM3));
else
bonemat_fromqcvectors((float*)mult, csqcg.forward, csqcg.right, csqcg.up, G_VECTOR(OFS_PARM3));
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
return;
if (startbone == -1)
startbone = 0;
//testme
while(startbone < endbone && startbone < skelobj->numbones)
{
Vector4Copy(skelobj->bonematrix+12*startbone+0, temp[0]);
Vector4Copy(skelobj->bonematrix+12*startbone+4, temp[1]);
Vector4Copy(skelobj->bonematrix+12*startbone+8, temp[2]);
R_ConcatTransforms(mult, temp, (float(*)[4])(skelobj->bonematrix+12*startbone));
}
}
//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
static void QCBUILTIN PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skeldst = G_FLOAT(OFS_PARM0);
int skelsrc = G_FLOAT(OFS_PARM1);
int startbone = G_FLOAT(OFS_PARM2)-1;
int endbone = G_FLOAT(OFS_PARM3)-1;
skelobject_t *skelobjdst;
skelobject_t *skelobjsrc;
skelobjdst = skel_get(prinst, skeldst, 0);
skelobjsrc = skel_get(prinst, skelsrc, 0);
if (!skelobjdst || !skelobjsrc)
return;
if (skelobjsrc->absolute != skelobjdst->absolute)
return;
if (startbone == -1)
startbone = 0;
//testme
while(startbone < endbone && startbone < skelobjdst->numbones && startbone < skelobjsrc->numbones)
{
Vector4Copy(skelobjsrc->bonematrix+12*startbone+0, skelobjdst->bonematrix+12*startbone+0);
Vector4Copy(skelobjsrc->bonematrix+12*startbone+4, skelobjdst->bonematrix+12*startbone+4);
Vector4Copy(skelobjsrc->bonematrix+12*startbone+8, skelobjdst->bonematrix+12*startbone+8);
}
}
//void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
static void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (skelobj)
skelobj->inuse = 2; //2 means don't reuse yet.
}
@ -4079,7 +3602,7 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src
//use entnum as a test to see if its new (if the old origin isn't usable) //use entnum as a test to see if its new (if the old origin isn't usable)
if (ent->xv->entnum) if (ent->xv->entnum)
{ {
if (model->particletrail == P_INVALID || pe->ParticleTrail (ent->v->origin, src->origin, model->particletrail, &(le->trailstate))) if (model->particletrail == P_INVALID || pe->ParticleTrail (ent->v->origin, src->origin, model->particletrail, src->number, &(le->trailstate)))
if (model->traildefaultindex >= 0) if (model->traildefaultindex >= 0)
pe->ParticleTrailIndex(ent->v->origin, src->origin, model->traildefaultindex, 0, &(le->trailstate)); pe->ParticleTrailIndex(ent->v->origin, src->origin, model->traildefaultindex, 0, &(le->trailstate));
} }
@ -4118,7 +3641,7 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src
if (model) if (model)
{ {
if (!(flags & RSES_NOROTATE) && (model->flags & EF_ROTATE)) if (!(flags & RSES_NOROTATE) && (model->flags & MF_ROTATE))
{ {
ent->v->angles[0] = 0; ent->v->angles[0] = 0;
ent->v->angles[1] = 100*lerptime; ent->v->angles[1] = 100*lerptime;
@ -4445,8 +3968,8 @@ static void QCBUILTIN PF_ReadServerEntityState(progfuncs_t *prinst, struct globa
src = &pack->entities[i]; src = &pack->entities[i];
// CL_LinkPacketEntities // CL_LinkPacketEntities
#ifndef _MSC_VER #ifdef warningmsg
#warning what to do here? #pragma warningmsg("what to do here?")
#endif #endif
// if (csqcent[src->number]) // if (csqcent[src->number])
// continue; //don't add the entity if we have one sent specially via csqc protocols. // continue; //don't add the entity if we have one sent specially via csqc protocols.
@ -5172,6 +4695,11 @@ model_t *CSQC_World_ModelForIndex(world_t *w, int modelindex)
{ {
return CSQC_GetModelForIndex(modelindex); return CSQC_GetModelForIndex(modelindex);
} }
void CSQC_World_GetFrameState(world_t *w, wedict_t *win, framestate_t *out)
{
csqcedict_t *in = (csqcedict_t *)win;
cs_getframestate(in, in->xv->renderflags, out);
}
void CSQC_Shutdown(void) void CSQC_Shutdown(void)
{ {
@ -5215,21 +4743,21 @@ qbyte *CSQC_PRLoadFile (const char *path, void *buffer, int bufsize)
if (!strcmp(path, "csprogs.dat")) if (!strcmp(path, "csprogs.dat"))
{ {
char newname[MAX_QPATH]; char newname[MAX_QPATH];
snprintf(newname, MAX_QPATH, "csprogsvers/%x.dat", csqcchecksum); snprintf(newname, MAX_QPATH, "csprogsvers/%x.dat", csprogs_checksum);
if (csqcchecksum) if (csprogs_checksum)
{ {
file = COM_LoadStackFile(newname, buffer, bufsize); file = COM_LoadStackFile(newname, buffer, bufsize);
if (file) if (file)
{ {
if (cls.protocol == CP_NETQUAKE) if (cls.protocol == CP_NETQUAKE)
{ {
if (QCRC_Block(file, com_filesize) == csqcchecksum) if (QCRC_Block(file, com_filesize) == csprogs_checksum)
return file; return file;
} }
else else
{ {
if (LittleLong(Com_BlockChecksum(file, com_filesize)) == csqcchecksum) //and the user wasn't trying to be cunning. if (LittleLong(Com_BlockChecksum(file, com_filesize)) == csprogs_checksum) //and the user wasn't trying to be cunning.
return file; return file;
} }
} }
@ -5238,16 +4766,16 @@ qbyte *CSQC_PRLoadFile (const char *path, void *buffer, int bufsize)
file = COM_LoadStackFile(path, buffer, bufsize); file = COM_LoadStackFile(path, buffer, bufsize);
if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum
{ {
if (csqcchecksum) if (csprogs_checksum)
{ {
if (cls.protocol == CP_NETQUAKE) if (cls.protocol == CP_NETQUAKE)
{ {
if (QCRC_Block(file, com_filesize) != csqcchecksum) if (QCRC_Block(file, com_filesize) != csprogs_checksum)
return NULL; return NULL;
} }
else else
{ {
if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csqcchecksum) if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csprogs_checksum)
return NULL; //not valid return NULL; //not valid
} }
@ -5270,21 +4798,21 @@ int CSQC_PRFileSize (const char *path)
if (!strcmp(path, "csprogs.dat")) if (!strcmp(path, "csprogs.dat"))
{ {
char newname[MAX_QPATH]; char newname[MAX_QPATH];
snprintf(newname, MAX_QPATH, "csprogsvers/%x.dat", csqcchecksum); snprintf(newname, MAX_QPATH, "csprogsvers/%x.dat", csprogs_checksum);
if (csqcchecksum) if (csprogs_checksum)
{ {
file = COM_LoadTempFile (newname); file = COM_LoadTempFile (newname);
if (file) if (file)
{ {
if (cls.protocol == CP_NETQUAKE) if (cls.protocol == CP_NETQUAKE)
{ {
if (QCRC_Block(file, com_filesize) == csqcchecksum) if (QCRC_Block(file, com_filesize) == csprogs_checksum)
return com_filesize+1; return com_filesize+1;
} }
else else
{ {
if (LittleLong(Com_BlockChecksum(file, com_filesize)) == csqcchecksum) //and the user wasn't trying to be cunning. if (LittleLong(Com_BlockChecksum(file, com_filesize)) == csprogs_checksum) //and the user wasn't trying to be cunning.
return com_filesize+1; return com_filesize+1;
} }
} }
@ -5293,16 +4821,16 @@ int CSQC_PRFileSize (const char *path)
file = COM_LoadTempFile(path); file = COM_LoadTempFile(path);
if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum
{ {
if (csqcchecksum) if (csprogs_checksum)
{ {
if (cls.protocol == CP_NETQUAKE) if (cls.protocol == CP_NETQUAKE)
{ {
if (QCRC_Block(file, com_filesize) != csqcchecksum) if (QCRC_Block(file, com_filesize) != csprogs_checksum)
return -1; //not valid return -1; //not valid
} }
else else
{ {
if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csqcchecksum) if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csprogs_checksum)
return -1; //not valid return -1; //not valid
} }
} }
@ -5329,9 +4857,15 @@ qboolean CSQC_Init (unsigned int checksum)
int i; int i;
string_t *str; string_t *str;
csqcedict_t *worldent; csqcedict_t *worldent;
csqcchecksum = checksum; qboolean loaded;
csprogs_checksum = checksum;
csqc_usinglistener = false; csqc_usinglistener = false;
csqc_singlecheats = false;
#ifndef CLIENTONLY
if ((sv.state == ss_active && sv.allocated_client_slots == 1) || atoi(Info_ValueForKey(cl.serverinfo, "*cheats")))
csqc_singlecheats = true;
#endif
//its already running... //its already running...
if (csqcprogs) if (csqcprogs)
@ -5354,7 +4888,7 @@ qboolean CSQC_Init (unsigned int checksum)
} }
csqc_deprecated_warned = false; csqc_deprecated_warned = false;
skel_reset(); skel_reset(csqcprogs);
memset(cl.model_csqcname, 0, sizeof(cl.model_csqcname)); memset(cl.model_csqcname, 0, sizeof(cl.model_csqcname));
memset(cl.model_csqcprecache, 0, sizeof(cl.model_csqcprecache)); memset(cl.model_csqcprecache, 0, sizeof(cl.model_csqcprecache));
@ -5393,6 +4927,7 @@ qboolean CSQC_Init (unsigned int checksum)
csqcprogparms.sv_num_edicts = &csqc_world.num_edicts; csqcprogparms.sv_num_edicts = &csqc_world.num_edicts;
csqcprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms); csqcprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
csqcprogparms.user = &csqc_world;
csqctime = Sys_DoubleTime(); csqctime = Sys_DoubleTime();
if (!csqcprogs) if (!csqcprogs)
@ -5406,26 +4941,31 @@ qboolean CSQC_Init (unsigned int checksum)
csqc_world.worldmodel = cl.worldmodel; csqc_world.worldmodel = cl.worldmodel;
csqc_world.Event_Touch = CSQC_Event_Touch; csqc_world.Event_Touch = CSQC_Event_Touch;
csqc_world.Event_Think = CSQC_Event_Think; csqc_world.Event_Think = CSQC_Event_Think;
csqc_world.GetCModel = CSQC_World_ModelForIndex; csqc_world.Get_CModel = CSQC_World_ModelForIndex;
csqc_world.Get_FrameState = CSQC_World_GetFrameState;
World_ClearWorld(&csqc_world); World_ClearWorld(&csqc_world);
CSQC_InitFields(); //let the qclib know the field order that the engine needs. CSQC_InitFields(); //let the qclib know the field order that the engine needs.
csqc_isdarkplaces = false; if (setjmp(csqc_abort))
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 22390, NULL, 0) < 0) //no per-progs builtins.
{ {
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) < 0) //no per-progs builtins. CSQC_Shutdown();
{ return false;
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 0, NULL, 0) < 0) //no per-progs builtins. }
{
CSQC_Shutdown();
//failed to load or something
return false;
}
}
else
csqc_isdarkplaces = true;
Con_Printf(CON_WARNING "Running outdated or unknown csprogs.dat version\n"); csqc_isdarkplaces = false;
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 22390, NULL, 0) >= 0)
loaded = true;
else
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) >= 0)
loaded = true;
else if (PR_LoadProgs(csqcprogs, "csprogs.dat", 0, NULL, 0) >= 0)
loaded = true;
else
loaded = false;
if (loaded)
Con_Printf(CON_WARNING "Running outdated or unknown csprogs.dat version\n");
} }
if (setjmp(csqc_abort)) if (setjmp(csqc_abort))
{ {
@ -5433,6 +4973,18 @@ qboolean CSQC_Init (unsigned int checksum)
return false; return false;
} }
if (csqc_singlecheats)
{
if (PR_LoadProgs(csqcprogs, "csaddon.dat", 0, NULL, 0) >= 0)
loaded = true;
}
if (!loaded)
{
CSQC_Shutdown();
return false;
}
PR_AutoCvarSetup(csqcprogs); PR_AutoCvarSetup(csqcprogs);
PF_InitTempStrings(csqcprogs); PF_InitTempStrings(csqcprogs);
@ -5678,7 +5230,7 @@ void CSQC_RegisterCvarsAndThings(void)
Cvar_Register(&cl_csqcdebug, CSQCPROGSGROUP); Cvar_Register(&cl_csqcdebug, CSQCPROGSGROUP);
Cvar_Register(&cl_nocsqc, CSQCPROGSGROUP); Cvar_Register(&cl_nocsqc, CSQCPROGSGROUP);
Cvar_Register(&pr_csqc_coreonerror, CSQCPROGSGROUP); Cvar_Register(&pr_csqc_coreonerror, CSQCPROGSGROUP);
Cvar_Register(&dpcompat_corruptglobals, CSQCPROGSGROUP); Cvar_Register(&dpcompat_corruptglobals, "Darkplaces compatibility");
} }
void CSQC_CvarChanged(cvar_t *var) void CSQC_CvarChanged(cvar_t *var)
@ -5724,12 +5276,15 @@ qboolean CSQC_DrawView(void)
World_ODE_Frame(&csqc_world, ft, 800); World_ODE_Frame(&csqc_world, ft, 800);
//World_Physics_Frame(&csqc_world); World_Physics_Frame(&csqc_world);
} }
#else #else
csqc_world.physicstime = cl.servertime; csqc_world.physicstime = cl.servertime;
#endif #endif
if (csqcg.frametime)
*csqcg.frametime = host_frametime;
DropPunchAngle (0); DropPunchAngle (0);
if (cl.worldmodel) if (cl.worldmodel)
R_LessenStains(); R_LessenStains();
@ -5841,8 +5396,8 @@ static void CSQC_GameCommand_f(void)
PR_ExecuteProgram (csqcprogs, csqcg.gamecommand); PR_ExecuteProgram (csqcprogs, csqcg.gamecommand);
} }
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("do we really need the firstbyte parameter here?") #pragma warningmsg("do we really need the firstbyte parameter here?")
#endif #endif
qboolean CSQC_ParseTempEntity(unsigned char firstbyte) qboolean CSQC_ParseTempEntity(unsigned char firstbyte)
{ {

View File

@ -1948,8 +1948,8 @@ qboolean MP_Init (void)
if (mp_time) if (mp_time)
*mp_time = Sys_DoubleTime(); *mp_time = Sys_DoubleTime();
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("disabled until csqc gets forked or some such") #pragma warningmsg("disabled until csqc gets forked or some such")
#endif #endif
//mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 0, NULL); //mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 0, NULL);
//mp_globs.drawfontscale = (float*)PR_FindGlobal(menuprogs, "drawfontscale", 0, NULL); //mp_globs.drawfontscale = (float*)PR_FindGlobal(menuprogs, "drawfontscale", 0, NULL);

671
engine/client/pr_skelobj.c Normal file
View File

@ -0,0 +1,671 @@
/*
Copyright (C) 2011 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
this file deals with qc builtins to apply custom skeletal blending (skeletal objects extension), as well as the logic required to perform realtime ragdoll, if I ever implement that.
*/
#include "quakedef.h"
#include "pr_common.h"
#define MAX_SKEL_OBJECTS 1024
/*this is the description of the ragdoll, it is how the doll flops around*/
typedef struct doll_s
{
char *name;
struct doll_s *next;
int numbodies;
struct
{
int joint;
char *name;
} body[32];
// struct
// {
// };
} doll_t;
enum
{
BF_ACTIVE, /*used to avoid traces if doll is stationary*/
BF_INSOLID
};
typedef struct {
int jointo; /*multiple of 12*/
int flags;
vec3_t vel;
} body_t;
/*this is the skeletal object*/
typedef struct {
int inuse;
model_t *model;
enum
{
SKOT_HBLEND,
SKOT_ABLEND,
SKOT_ARAG
} type;
unsigned int numbones;
float *bonematrix;
/*
unsigned int numbodies;
body_t *body;
doll_t *doll;
*/
} skelobject_t;
static doll_t *dolllist;
static skelobject_t skelobjects[MAX_SKEL_OBJECTS];
static int numskelobjectsused;
static qboolean pendingkill; /*states that there is a skel waiting to be killed*/
#if 0
doll_t *rag_loaddoll(char *fname)
{
doll_t *d;
void *fptr = NULL;
int fsize;
for (d = dolllist; d; d = d->next)
{
if (!strcmp(d->name, fname))
return d;
}
fsize = FS_LoadFile(fname, &fptr);
if (!fptr)
return NULL;
FS_FreeFile(fptr);
}
void skel_integrate(progfuncs_t *prinst, skelobject_t *sko, float ft)
{
unsigned int p;
trace_t t;
vec3_t npos, opos;
world_t *w = prinst->parms->user;
body_t *b;
float gravity = 800;
for (p = 0, b = sko->body; p < sko->numbodies; p++, b++)
{
/*handle gravity*/
b->vel[2] = b->vel[2] - gravity * ft / 2;
opos[0] = sko->bonematrix[b->jointo + 3 ];
opos[1] = sko->bonematrix[b->jointo + 7 ];
opos[2] = sko->bonematrix[b->jointo + 11];
npos[0] = opos[0] + b->vel[0]*ft;
npos[1] = opos[1] + b->vel[1]*ft;
npos[2] = opos[2] + b->vel[2]*ft;
t = World_Move(w, opos, vec3_origin, vec3_origin, npos, MOVE_NOMONSTERS, w->edicts);
sko->bonematrix[b->jointo + 3 ] = t.endpos[0];
sko->bonematrix[b->jointo + 7 ] = t.endpos[1];
sko->bonematrix[b->jointo + 11] = t.endpos[2];
/*handle gravity again to compensate for framerate*/
b->vel[2] = b->vel[2] - gravity * ft / 2;
}
/*draw points*/
for (p = 0, b = sko->body; p < sko->numbodies; p++, b++)
{
opos[0] = sko->bonematrix[b->jointo + 3 ];
opos[1] = sko->bonematrix[b->jointo + 7 ];
opos[2] = sko->bonematrix[b->jointo + 11];
P_RunParticleEffectTypeString(opos, b->vel, 1, "ragdolltest");
}
}
#endif
/*destroys all skeletons*/
void skel_reset(progfuncs_t *prinst)
{
while (numskelobjectsused > 0)
{
numskelobjectsused--;
skelobjects[numskelobjectsused].numbones = 0;
skelobjects[numskelobjectsused].inuse = false;
}
}
/*deletes any skeletons marked for deletion*/
void skel_dodelete(progfuncs_t *prinst)
{
int skelidx;
if (!pendingkill)
return;
pendingkill = false;
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{
if (skelobjects[skelidx].inuse == 2)
skelobjects[skelidx].inuse = 0;
}
while (numskelobjectsused && !skelobjects[numskelobjectsused-1].inuse)
numskelobjectsused--;
}
skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount)
{
if (skelidx == 0)
{
//allocation
if (!bonecount)
return NULL;
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{
if (!skelobjects[skelidx].inuse && skelobjects[skelidx].numbones == bonecount)
return &skelobjects[skelidx];
}
for (skelidx = 0; skelidx <= numskelobjectsused; skelidx++)
{
if (!skelobjects[skelidx].inuse && !skelobjects[skelidx].numbones)
{
skelobjects[skelidx].numbones = bonecount;
/*so bone matrix list can be mmapped some day*/
skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount);
if (skelidx <= numskelobjectsused)
{
numskelobjectsused = skelidx + 1;
skelobjects[skelidx].model = NULL;
skelobjects[skelidx].inuse = 1;
}
return &skelobjects[skelidx];
}
}
return NULL;
}
else
{
skelidx--;
if ((unsigned int)skelidx >= numskelobjectsused)
return NULL;
if (skelobjects[skelidx].inuse != 1)
return NULL;
if (bonecount && skelobjects[skelidx].numbones != bonecount)
return NULL;
return &skelobjects[skelidx];
}
}
void skel_lookup(progfuncs_t *prinst, int skelidx, framestate_t *out)
{
skelobject_t *sko = skel_get(prinst, skelidx, 0);
if (sko && sko->inuse)
{
out->bonecount = sko->numbones;
out->bonestate = sko->bonematrix;
}
}
//float(float modelindex) skel_create (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int numbones;
skelobject_t *skelobj;
model_t *model;
int midx;
int type;
char *afname;
midx = G_FLOAT(OFS_PARM0);
if (*prinst->callargc > 1)
afname = PR_GetStringOfs(prinst, OFS_PARM1);
else
afname = "";
//default to failure
G_FLOAT(OFS_RETURN) = 0;
model = w->Get_CModel(w, midx);
if (!model)
return; //no model set, can't get a skeleton
type = SKOT_HBLEND;
numbones = Mod_GetNumBones(model, type != SKOT_HBLEND);
if (!numbones)
{
// isabs = true;
// numbones = Mod_GetNumBones(model, isabs);
// if (!numbones)
return; //this isn't a skeletal model.
}
skelobj = skel_get(prinst, 0, numbones);
if (!skelobj)
return; //couldn't get one, ran out of memory or something?
skelobj->model = model;
skelobj->type = type;
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
}
//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone) skel_build (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int skelidx = G_FLOAT(OFS_PARM0);
wedict_t *ent = (wedict_t*)G_EDICT(prinst, OFS_PARM1);
int midx = G_FLOAT(OFS_PARM2);
float retainfrac = G_FLOAT(OFS_PARM3);
int firstbone = G_FLOAT(OFS_PARM4)-1;
int lastbone = G_FLOAT(OFS_PARM5)-1;
float addition = 1?G_FLOAT(OFS_PARM6):1-retainfrac;
int i, j;
int numbones;
framestate_t fstate;
skelobject_t *skelobj;
model_t *model;
//default to failure
G_FLOAT(OFS_RETURN) = 0;
model = w->Get_CModel(w, midx);
if (!model)
return; //invalid model, can't get a skeleton
w->Get_FrameState(w, ent, &fstate);
//heh... don't copy.
fstate.bonecount = 0;
fstate.bonestate = NULL;
numbones = Mod_GetNumBones(model, false);
if (!numbones)
{
return; //this isn't a skeletal model.
}
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
return; //couldn't get one, ran out of memory or something?
if (lastbone < 0)
lastbone = numbones;
if (lastbone > numbones)
lastbone = numbones;
if (firstbone < 0)
firstbone = 0;
if (retainfrac == 0)
{
/*replace everything*/
if (addition == 1)
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, skelobj->bonematrix);
else
{
//scale new
float relationsbuf[MAX_BONES*12];
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, relationsbuf);
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] = addition*relationsbuf[i*12+j];
}
}
}
else
{
if (retainfrac != 1)
{
//rescale the existing bones
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] *= retainfrac;
}
}
if (addition == 1)
{
//just add
float relationsbuf[MAX_BONES*12];
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, relationsbuf);
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] += relationsbuf[i*12+j];
}
}
else if (addition)
{
//add+scale
float relationsbuf[MAX_BONES*12];
Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, relationsbuf);
for (i = firstbone; i < lastbone; i++)
{
for (j = 0; j < 12; j++)
skelobj->bonematrix[i*12+j] += addition*relationsbuf[i*12+j];
}
}
}
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
}
//float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = skelobj->numbones;
}
//string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
void QCBUILTIN PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_INT(OFS_RETURN) = 0;
else
{
RETURN_TSTRING(Mod_GetBoneName(skelobj->model, boneidx));
}
}
//float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_GetBoneParent(skelobj->model, boneidx);
}
//float(float skel, string tagname) skel_find_bone (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
char *bname = PR_GetStringOfs(prinst, OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(skelobj->model, bname);
}
static void bonemat_fromqcvectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
{
out[0] = vx[0];
out[1] = -vy[0];
out[2] = vz[0];
out[3] = t[0];
out[4] = vx[1];
out[5] = -vy[1];
out[6] = vz[1];
out[7] = t[1];
out[8] = vx[2];
out[9] = -vy[2];
out[10] = vz[2];
out[11] = t[2];
}
static void bonemat_toqcvectors(const float *in, float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = in[0];
vx[1] = in[4];
vx[2] = in[8];
vy[0] = -in[1];
vy[1] = -in[5];
vy[2] = -in[9];
vz[0] = in[2];
vz[1] = in[6];
vz[2] = in[10];
t [0] = in[3];
t [1] = in[7];
t [2] = in[11];
}
static void bonematident_toqcvectors(float vx[3], float vy[3], float vz[3], float t[3])
{
vx[0] = 1;
vx[1] = 0;
vx[2] = 0;
vy[0] = -0;
vy[1] = -1;
vy[2] = -0;
vz[0] = 0;
vz[1] = 0;
vz[2] = 1;
t [0] = 0;
t [1] = 0;
t [2] = 0;
}
//vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
void QCBUILTIN PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
skelobject_t *skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || (unsigned int)boneidx >= skelobj->numbones)
bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
else if (skelobj->type!=SKOT_HBLEND)
{
//FIXME
bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
}
else
bonemat_toqcvectors(skelobj->bonematrix+12*boneidx, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
}
//vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
void QCBUILTIN PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float workingm[12], tempmatrix[3][4];
int i;
skelobject_t *skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || (unsigned int)boneidx >= skelobj->numbones)
bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
else if (skelobj->type != SKOT_HBLEND)
{
//can just copy it out
bonemat_toqcvectors(skelobj->bonematrix + boneidx*12, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
}
else
{
//we need to work out the abs position
//testme
//set up an identity matrix
for (i = 0;i < 12;i++)
workingm[i] = 0;
workingm[0] = 1;
workingm[5] = 1;
workingm[10] = 1;
while(boneidx >= 0)
{
//copy out the previous working matrix, so we don't stomp on it
memcpy(tempmatrix, workingm, sizeof(tempmatrix));
R_ConcatTransforms((void*)(skelobj->bonematrix + boneidx*12), (void*)tempmatrix, (void*)workingm);
boneidx = Mod_GetBoneParent(skelobj->model, boneidx+1)-1;
}
bonemat_toqcvectors(workingm, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN));
}
}
//void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int skelidx = G_FLOAT(OFS_PARM0);
unsigned int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[3];
skelobject_t *skelobj;
float *bone;
if (*prinst->callargc > 5)
{
matrix[0] = G_VECTOR(OFS_PARM3);
matrix[1] = G_VECTOR(OFS_PARM4);
matrix[2] = G_VECTOR(OFS_PARM5);
}
else
{
matrix[0] = w->g.v_forward;
matrix[1] = w->g.v_right;
matrix[2] = w->g.v_up;
}
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || boneidx >= skelobj->numbones)
return;
bone = skelobj->bonematrix+12*boneidx;
bonemat_fromqcvectors(skelobj->bonematrix+12*boneidx, matrix[0], matrix[1], matrix[2], G_VECTOR(OFS_PARM2));
}
//void(float skel, float bonenum, vector org [, vector fwd, vector right, vector up]) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
void QCBUILTIN PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float temp[3][4];
float mult[3][4];
skelobject_t *skelobj;
if (*prinst->callargc > 5)
bonemat_fromqcvectors((float*)mult, G_VECTOR(OFS_PARM3), G_VECTOR(OFS_PARM4), G_VECTOR(OFS_PARM5), G_VECTOR(OFS_PARM2));
else
bonemat_fromqcvectors((float*)mult, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_PARM2));
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || boneidx >= skelobj->numbones)
return;
//testme
Vector4Copy(skelobj->bonematrix+12*boneidx+0, temp[0]);
Vector4Copy(skelobj->bonematrix+12*boneidx+4, temp[1]);
Vector4Copy(skelobj->bonematrix+12*boneidx+8, temp[2]);
R_ConcatTransforms(mult, temp, (float(*)[4])(skelobj->bonematrix+12*boneidx));
}
//void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
void QCBUILTIN PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
int skelidx = G_FLOAT(OFS_PARM0);
unsigned int startbone = G_FLOAT(OFS_PARM1)-1;
unsigned int endbone = G_FLOAT(OFS_PARM2)-1;
float temp[3][4];
float mult[3][4];
skelobject_t *skelobj;
if (*prinst->callargc > 6)
bonemat_fromqcvectors((float*)mult, G_VECTOR(OFS_PARM4), G_VECTOR(OFS_PARM5), G_VECTOR(OFS_PARM6), G_VECTOR(OFS_PARM3));
else
bonemat_fromqcvectors((float*)mult, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_PARM3));
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
return;
if (startbone == -1)
startbone = 0;
//testme
while(startbone < endbone && startbone < skelobj->numbones)
{
Vector4Copy(skelobj->bonematrix+12*startbone+0, temp[0]);
Vector4Copy(skelobj->bonematrix+12*startbone+4, temp[1]);
Vector4Copy(skelobj->bonematrix+12*startbone+8, temp[2]);
R_ConcatTransforms(mult, temp, (float(*)[4])(skelobj->bonematrix+12*startbone));
}
}
//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skeldst = G_FLOAT(OFS_PARM0);
int skelsrc = G_FLOAT(OFS_PARM1);
int startbone = G_FLOAT(OFS_PARM2)-1;
int endbone = G_FLOAT(OFS_PARM3)-1;
skelobject_t *skelobjdst;
skelobject_t *skelobjsrc;
skelobjdst = skel_get(prinst, skeldst, 0);
skelobjsrc = skel_get(prinst, skelsrc, 0);
if (!skelobjdst || !skelobjsrc)
return;
if (skelobjsrc->type != skelobjdst->type)
return;
if (startbone == -1)
startbone = 0;
//testme
while(startbone < endbone && startbone < skelobjdst->numbones && startbone < skelobjsrc->numbones)
{
Vector4Copy(skelobjsrc->bonematrix+12*startbone+0, skelobjdst->bonematrix+12*startbone+0);
Vector4Copy(skelobjsrc->bonematrix+12*startbone+4, skelobjdst->bonematrix+12*startbone+4);
Vector4Copy(skelobjsrc->bonematrix+12*startbone+8, skelobjdst->bonematrix+12*startbone+8);
}
}
//void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (skelobj)
{
skelobj->inuse = 2; //2 means don't reuse yet.
pendingkill = true;
}
}

View File

@ -24,6 +24,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "bothdefs.h" //first thing included by ALL files. #include "bothdefs.h" //first thing included by ALL files.
//for msvc #pragma message lines
#if defined(_MSC_VER)
#define MSVC_LINE __FILE__"("STRINGIFY(__LINE__)"):"
#define warningmsg(s) message(MSVC_LINE s)
#elif __GNUC__ >=4
#define warningmsg(s) message(s)
#endif
#ifdef MSVCDISABLEWARNINGS #ifdef MSVCDISABLEWARNINGS
//#pragma warning( disable : 4244 4127 4201 4214 4514 4305 4115 4018) //#pragma warning( disable : 4244 4127 4201 4214 4514 4305 4115 4018)
/*#pragma warning( disable : 4244) //conversion from const double to float /*#pragma warning( disable : 4244) //conversion from const double to float

View File

@ -103,8 +103,8 @@ void R2D_Init(void)
Font_Init(); Font_Init();
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("Fixme: move conwidth handling into here") #pragma warningmsg("Fixme: move conwidth handling into here")
#endif #endif
missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0); missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0);
@ -214,7 +214,7 @@ void R2D_Init(void)
"}\n" "}\n"
"][\n" "][\n"
"{\n" "{\n"
"map $whitetexture\n" "map $whiteimage\n"
"blendfunc gl_dst_color gl_zero\n" "blendfunc gl_dst_color gl_zero\n"
"rgbgen const $r_menutint\n" "rgbgen const $r_menutint\n"
"}\n" "}\n"
@ -407,7 +407,7 @@ void R2D_TransPicTranslate (int x, int y, int width, int height, qbyte *pic, qby
if (!TEXVALID(translate_texture)) if (!TEXVALID(translate_texture))
{ {
translate_texture = R_AllocNewTexture(64, 64); translate_texture = R_AllocNewTexture("***translatedpic***", 64, 64);
translate_shader = R_RegisterShader("translatedpic", "{\n" translate_shader = R_RegisterShader("translatedpic", "{\n"
"if $nofixed\n" "if $nofixed\n"
"[\n" "[\n"
@ -937,7 +937,7 @@ void R2D_Crosshair_Update(void)
c = c % (sizeof(crosshair_pixels) / (CS_HEIGHT*sizeof(*crosshair_pixels))); c = c % (sizeof(crosshair_pixels) / (CS_HEIGHT*sizeof(*crosshair_pixels)));
if (!TEXVALID(ch_int_texture)) if (!TEXVALID(ch_int_texture))
ch_int_texture = R_AllocNewTexture(CS_WIDTH, CS_HEIGHT); ch_int_texture = R_AllocNewTexture("***crosshair***", CS_WIDTH, CS_HEIGHT);
shader_crosshair->defaulttextures.base = ch_int_texture; shader_crosshair->defaulttextures.base = ch_int_texture;
Q_memset(crossdata, 0, sizeof(crossdata)); Q_memset(crossdata, 0, sizeof(crossdata));

View File

@ -38,7 +38,7 @@ void R_Rockettrail_Callback(struct cvar_s *var, char *oldvalue)
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
{ {
if (!mod->needload) if (!mod->needload)
if (mod->flags & EF_ROCKET) if (mod->flags & MF_ROCKET)
P_DefaultTrail(mod); P_DefaultTrail(mod);
} }
} }
@ -56,7 +56,7 @@ void R_Grenadetrail_Callback(struct cvar_s *var, char *oldvalue)
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
{ {
if (!mod->needload) if (!mod->needload)
if (mod->flags & EF_GRENADE) if (mod->flags & MF_GRENADE)
P_DefaultTrail(mod); P_DefaultTrail(mod);
} }
} }
@ -215,7 +215,7 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
pe = &pmove.physents[i]; pe = &pmove.physents[i];
if (pe->nonsolid) if (pe->nonsolid)
continue; continue;
if (pe->model) if (pe->model && !pe->model->needload)
{ {
VectorSubtract(start, pe->origin, ts); VectorSubtract(start, pe->origin, ts);
VectorSubtract(end, pe->origin, te); VectorSubtract(end, pe->origin, te);
@ -362,86 +362,86 @@ void P_DefaultTrail (model_t *model)
if (model->engineflags & MDLF_NODEFAULTTRAIL) if (model->engineflags & MDLF_NODEFAULTTRAIL)
return; return;
if (model->flags & EF_ROCKET) if (model->flags & MF_ROCKET)
P_SelectableTrail(model, &r_rockettrail, P_FindParticleType("TR_ROCKET"), 109, P_FindParticleType("TR_GRENADE"), 6); P_SelectableTrail(model, &r_rockettrail, P_FindParticleType("TR_ROCKET"), 109, P_FindParticleType("TR_GRENADE"), 6);
else if (model->flags & EF_GRENADE) else if (model->flags & MF_GRENADE)
P_SelectableTrail(model, &r_grenadetrail, P_FindParticleType("TR_GRENADE"), 6, P_FindParticleType("TR_ROCKET"), 109); P_SelectableTrail(model, &r_grenadetrail, P_FindParticleType("TR_GRENADE"), 6, P_FindParticleType("TR_ROCKET"), 109);
else if (model->flags & EF_GIB) else if (model->flags & MF_GIB)
{ {
model->particletrail = P_FindParticleType("TR_BLOOD"); model->particletrail = P_FindParticleType("TR_BLOOD");
model->traildefaultindex = 70; model->traildefaultindex = 70;
} }
else if (model->flags & EF_TRACER) else if (model->flags & MF_TRACER)
{ {
model->particletrail = P_FindParticleType("TR_WIZSPIKE"); model->particletrail = P_FindParticleType("TR_WIZSPIKE");
model->traildefaultindex = 60; model->traildefaultindex = 60;
} }
else if (model->flags & EF_ZOMGIB) else if (model->flags & MF_ZOMGIB)
{ {
model->particletrail = P_FindParticleType("TR_SLIGHTBLOOD"); model->particletrail = P_FindParticleType("TR_SLIGHTBLOOD");
model->traildefaultindex = 70; model->traildefaultindex = 70;
} }
else if (model->flags & EF_TRACER2) else if (model->flags & MF_TRACER2)
{ {
model->particletrail = P_FindParticleType("TR_KNIGHTSPIKE"); model->particletrail = P_FindParticleType("TR_KNIGHTSPIKE");
model->traildefaultindex = 238; model->traildefaultindex = 238;
} }
else if (model->flags & EF_TRACER3) else if (model->flags & MF_TRACER3)
{ {
model->particletrail = P_FindParticleType("TR_VORESPIKE"); model->particletrail = P_FindParticleType("TR_VORESPIKE");
model->traildefaultindex = 154; model->traildefaultindex = 154;
} }
else if (model->flags & EFH2_BLOODSHOT) //these are the hexen2 ones. else if (model->flags & MFH2_BLOODSHOT) //these are the hexen2 ones.
{ {
model->particletrail = P_FindParticleType("tr_bloodshot"); model->particletrail = P_FindParticleType("tr_bloodshot");
model->traildefaultindex = 136; model->traildefaultindex = 136;
} }
else if (model->flags & EFH2_FIREBALL) else if (model->flags & MFH2_FIREBALL)
{ {
model->particletrail = P_FindParticleType("tr_fireball"); model->particletrail = P_FindParticleType("tr_fireball");
model->traildefaultindex = 424; model->traildefaultindex = 424;
} }
else if (model->flags & EFH2_ACIDBALL) else if (model->flags & MFH2_ACIDBALL)
{ {
model->particletrail = P_FindParticleType("tr_acidball"); model->particletrail = P_FindParticleType("tr_acidball");
model->traildefaultindex = 440; model->traildefaultindex = 440;
} }
else if (model->flags & EFH2_ICE) else if (model->flags & MFH2_ICE)
{ {
model->particletrail = P_FindParticleType("tr_ice"); model->particletrail = P_FindParticleType("tr_ice");
model->traildefaultindex = 408; model->traildefaultindex = 408;
} }
else if (model->flags & EFH2_SPIT) else if (model->flags & MFH2_SPIT)
{ {
model->particletrail = P_FindParticleType("tr_spit"); model->particletrail = P_FindParticleType("tr_spit");
model->traildefaultindex = 260; model->traildefaultindex = 260;
} }
else if (model->flags & EFH2_SPELL) else if (model->flags & MFH2_SPELL)
{ {
model->particletrail = P_FindParticleType("tr_spell"); model->particletrail = P_FindParticleType("tr_spell");
model->traildefaultindex = 260; model->traildefaultindex = 260;
} }
else if (model->flags & EFH2_VORP_MISSILE) else if (model->flags & MFH2_VORP_MISSILE)
{ {
model->particletrail = P_FindParticleType("tr_vorpmissile"); model->particletrail = P_FindParticleType("tr_vorpmissile");
model->traildefaultindex = 302; model->traildefaultindex = 302;
} }
else if (model->flags & EFH2_SET_STAFF) else if (model->flags & MFH2_SET_STAFF)
{ {
model->particletrail = P_FindParticleType("tr_setstaff"); model->particletrail = P_FindParticleType("tr_setstaff");
model->traildefaultindex = 424; model->traildefaultindex = 424;
} }
else if (model->flags & EFH2_MAGICMISSILE) else if (model->flags & MFH2_MAGICMISSILE)
{ {
model->particletrail = P_FindParticleType("tr_magicmissile"); model->particletrail = P_FindParticleType("tr_magicmissile");
model->traildefaultindex = 149; model->traildefaultindex = 149;
} }
else if (model->flags & EFH2_BONESHARD) else if (model->flags & MFH2_BONESHARD)
{ {
model->particletrail = P_FindParticleType("tr_boneshard"); model->particletrail = P_FindParticleType("tr_boneshard");
model->traildefaultindex = 384; model->traildefaultindex = 384;
} }
else if (model->flags & EFH2_SCARAB) else if (model->flags & MFH2_SCARAB)
{ {
model->particletrail = P_FindParticleType("tr_scarab"); model->particletrail = P_FindParticleType("tr_scarab");
model->traildefaultindex = 254; model->traildefaultindex = 254;

View File

@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h> #include <math.h>
extern cvar_t r_ambient; extern cvar_t r_ambient;
extern cvar_t gl_bump;
static vec3_t modelorg; /*set before recursively entering the visible surface finder*/ static vec3_t modelorg; /*set before recursively entering the visible surface finder*/
static qbyte areabits[MAX_Q2MAP_AREAS/8]; static qbyte areabits[MAX_Q2MAP_AREAS/8];
@ -1221,7 +1220,7 @@ dynamic:
if ((theRect->h + theRect->t) < (fa->light_t + tmax)) if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax; theRect->h = (fa->light_t-theRect->t)+tmax;
if (gl_bump.ival) if (r_deluxemapping.ival)
{ {
lightmap[fa->lightmaptexturenum]->deluxmodified = true; lightmap[fa->lightmaptexturenum]->deluxmodified = true;
theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange; theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange;
@ -1307,7 +1306,7 @@ dynamic:
if ((theRect->h + theRect->t) < (fa->light_t + tmax)) if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax; theRect->h = (fa->light_t-theRect->t)+tmax;
if (gl_bump.ival) if (r_deluxemapping.ival)
{ {
lightmap[fa->lightmaptexturenum]->deluxmodified = true; lightmap[fa->lightmaptexturenum]->deluxmodified = true;
theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange; theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange;
@ -2141,16 +2140,10 @@ static int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
lightmap[numlightmaps+3] = NULL; lightmap[numlightmaps+3] = NULL;
lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4)); lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4));
lightmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT); memset(lightmap_textures+numlightmaps, 0, sizeof(*lightmap_textures)*(4));
lightmap_textures[numlightmaps+1] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
lightmap_textures[numlightmaps+2] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
lightmap_textures[numlightmaps+3] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4)); deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4));
deluxmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT); memset(deluxmap_textures+numlightmaps, 0, sizeof(*deluxmap_textures)*(4));
deluxmap_textures[numlightmaps+1] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
deluxmap_textures[numlightmaps+2] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
deluxmap_textures[numlightmaps+3] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
numlightmaps+=4; numlightmaps+=4;
} }
if (!lightmap[texnum]) if (!lightmap[texnum])
@ -2159,11 +2152,12 @@ static int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
lightmap[texnum]->meshchain = NULL; lightmap[texnum]->meshchain = NULL;
lightmap[texnum]->modified = true; lightmap[texnum]->modified = true;
lightmap[texnum]->shader = shader; lightmap[texnum]->shader = shader;
lightmap[texnum]->external = true;
// reset stainmap since it now starts at 255 // reset stainmap since it now starts at 255
memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps)); memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps));
//clear out the deluxmaps incase there is none on the map. //clear out the deluxmaps incase there is none on the map.
for (j = 0; j < LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3; j+=3) for (j = 0; j < LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3; j+=3)
{ {
lightmap[texnum]->deluxmaps[j+0] = 128; lightmap[texnum]->deluxmaps[j+0] = 128;
lightmap[texnum]->deluxmaps[j+1] = 128; lightmap[texnum]->deluxmaps[j+1] = 128;
@ -2172,7 +2166,11 @@ static int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
} }
if (lightmap[texnum]->external) if (lightmap[texnum]->external)
lightmap_textures[texnum] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT); {
TEXASSIGN(lightmap_textures[texnum], R_AllocNewTexture("***lightmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
TEXASSIGN(deluxmap_textures[texnum], R_AllocNewTexture("***deluxmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
lightmap[texnum]->external = false;
}
/*not required, but using one lightmap per texture can result in better texture unit switching*/ /*not required, but using one lightmap per texture can result in better texture unit switching*/
if (lightmap[texnum]->shader != shader) if (lightmap[texnum]->shader != shader)
@ -2225,16 +2223,10 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
lightmap[numlightmaps+3] = NULL; lightmap[numlightmaps+3] = NULL;
lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4)); lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4));
lightmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT); memset(lightmap_textures+numlightmaps, 0, sizeof(*lightmap_textures)*(4));
lightmap_textures[numlightmaps+1] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
lightmap_textures[numlightmaps+2] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
lightmap_textures[numlightmaps+3] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4)); deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4));
deluxmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT); memset(deluxmap_textures+numlightmaps, 0, sizeof(*deluxmap_textures)*(4));
deluxmap_textures[numlightmaps+1] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
deluxmap_textures[numlightmaps+2] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
deluxmap_textures[numlightmaps+3] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
numlightmaps+=4; numlightmaps+=4;
} }
for (i = texnum; i >= 0; i--) for (i = texnum; i >= 0; i--)
@ -2244,7 +2236,8 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
lightmap[i] = BZ_Malloc(sizeof(*lightmap[i])); lightmap[i] = BZ_Malloc(sizeof(*lightmap[i]));
lightmap[i]->meshchain = NULL; lightmap[i]->meshchain = NULL;
lightmap[i]->modified = true; lightmap[i]->modified = true;
for (l=0 ; l<LMBLOCK_HEIGHT ; l++) lightmap[i]->external = true;
for (l=0 ; l<LMBLOCK_WIDTH ; l++)
{ {
lightmap[i]->allocated[l] = LMBLOCK_HEIGHT; lightmap[i]->allocated[l] = LMBLOCK_HEIGHT;
} }
@ -2254,7 +2247,7 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
lightmap[i]->rectchange.h = LMBLOCK_HEIGHT; lightmap[i]->rectchange.h = LMBLOCK_HEIGHT;
//clear out the deluxmaps incase there is none on the map. //clear out the deluxmaps incase there is none on the map.
for (l = 0; l < LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3; l+=3) for (l = 0; l < LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3; l+=3)
{ {
lightmap[i]->deluxmaps[l+0] = 0; lightmap[i]->deluxmaps[l+0] = 0;
lightmap[i]->deluxmaps[l+1] = 0; lightmap[i]->deluxmaps[l+1] = 0;
@ -2263,26 +2256,32 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
if (cl.worldmodel->lightdata) if (cl.worldmodel->lightdata)
{ {
if (lightmap[i]->external)
{
TEXASSIGN(lightmap_textures[i], R_AllocNewTexture("***lightmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
TEXASSIGN(deluxmap_textures[i], R_AllocNewTexture("***deluxmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
lightmap[i]->external = false;
}
if (lightmap_bytes == 4) if (lightmap_bytes == 4)
{ {
int j; int j;
if (lightmap_bgra) if (lightmap_bgra)
{ {
for (j = 0; j < LMBLOCK_HEIGHT*LMBLOCK_HEIGHT; j++) for (j = 0; j < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; j++)
{ {
lightmap[i]->lightmaps[(j<<2)+0] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i))[2]; lightmap[i]->lightmaps[(j<<2)+0] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[2];
lightmap[i]->lightmaps[(j<<2)+1] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i))[1]; lightmap[i]->lightmaps[(j<<2)+1] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[1];
lightmap[i]->lightmaps[(j<<2)+2] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i))[0]; lightmap[i]->lightmaps[(j<<2)+2] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[0];
lightmap[i]->lightmaps[(j<<2)+3] = 255; lightmap[i]->lightmaps[(j<<2)+3] = 255;
} }
} }
else else
{ {
for (j = 0; j < LMBLOCK_HEIGHT*LMBLOCK_HEIGHT; j++) for (j = 0; j < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; j++)
{ {
lightmap[i]->lightmaps[(j<<2)+0] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i))[0]; lightmap[i]->lightmaps[(j<<2)+0] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[0];
lightmap[i]->lightmaps[(j<<2)+1] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i))[1]; lightmap[i]->lightmaps[(j<<2)+1] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[1];
lightmap[i]->lightmaps[(j<<2)+2] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i))[2]; lightmap[i]->lightmaps[(j<<2)+2] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[2];
lightmap[i]->lightmaps[(j<<2)+3] = 255; lightmap[i]->lightmaps[(j<<2)+3] = 255;
} }
} }
@ -2290,14 +2289,14 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
else else
{ {
/*BUG: assumes RGB. if its BGR then wrong colours, but whys that going to happen*/ /*BUG: assumes RGB. if its BGR then wrong colours, but whys that going to happen*/
memcpy(lightmap[i]->lightmaps, cl.worldmodel->lightdata+3*LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*i, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); memcpy(lightmap[i]->lightmaps, cl.worldmodel->lightdata+3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3);
} }
} }
else else
{ {
char basename[MAX_QPATH]; char basename[MAX_QPATH];
//maybe someone screwed with my lightmap... //maybe someone screwed with my lightmap...
memset(lightmap[i]->lightmaps, 255, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); memset(lightmap[i]->lightmaps, 255, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3);
COM_StripExtension(cl.worldmodel->name, basename, sizeof(basename)); COM_StripExtension(cl.worldmodel->name, basename, sizeof(basename));
if (!lightmap[i]->external) if (!lightmap[i]->external)
@ -2474,10 +2473,18 @@ void Surf_DeInit(void)
if (lightmap_textures) if (lightmap_textures)
{ {
for (i = 0; i < numlightmaps; i++) for (i = 0; i < numlightmaps; i++)
{
if (!lightmap[i] || lightmap[i]->external) if (!lightmap[i] || lightmap[i]->external)
{
R_DestroyTexture(lightmap_textures[i]); R_DestroyTexture(lightmap_textures[i]);
R_DestroyTexture(deluxmap_textures[i]);
}
}
BZ_Free(lightmap_textures); BZ_Free(lightmap_textures);
BZ_Free(deluxmap_textures);
} }
lightmap_textures=NULL;
deluxmap_textures = NULL;
for (i = 0; i < numlightmaps; i++) for (i = 0; i < numlightmaps; i++)
{ {
@ -2490,7 +2497,6 @@ void Surf_DeInit(void)
if (lightmap) if (lightmap)
BZ_Free(lightmap); BZ_Free(lightmap);
lightmap_textures=NULL;
lightmap=NULL; lightmap=NULL;
numlightmaps=0; numlightmaps=0;
} }

View File

@ -36,7 +36,6 @@ struct texnums_s;
struct texture_s; struct texture_s;
static const texid_t r_nulltex = {0}; static const texid_t r_nulltex = {0};
#define TEXVALID(t) ((t).num!=0)
#if defined(D3DQUAKE) || defined(ANDROID) #if defined(D3DQUAKE) || defined(ANDROID)
@ -76,6 +75,7 @@ typedef enum {
RT_MAX_REF_ENTITY_TYPE RT_MAX_REF_ENTITY_TYPE
} refEntityType_t; } refEntityType_t;
struct dlight_s;
typedef struct entity_s typedef struct entity_s
{ {
int keynum; // for matching entities in different frames int keynum; // for matching entities in different frames
@ -166,6 +166,9 @@ typedef struct
qboolean recurse; /*in a mirror/portal/half way through drawing something else*/ qboolean recurse; /*in a mirror/portal/half way through drawing something else*/
qboolean flipcull; /*reflected/flipped view, requires inverted culling*/ qboolean flipcull; /*reflected/flipped view, requires inverted culling*/
qboolean useperspective; /*not orthographic*/ qboolean useperspective; /*not orthographic*/
int postprocshader; /*if set, renders to texture then invokes this shader*/
int postproccube; /*postproc shader wants a cubemap, this is the mask of sides required*/
} refdef_t; } refdef_t;
extern refdef_t r_refdef; extern refdef_t r_refdef;
@ -181,7 +184,7 @@ void BE_GenModelBatches(struct batch_s **batches);
void R_GAlias_DrawBatch(struct batch_s *batch); void R_GAlias_DrawBatch(struct batch_s *batch);
void R_GAlias_GenerateBatches(entity_t *e, struct batch_s **batches); void R_GAlias_GenerateBatches(entity_t *e, struct batch_s **batches);
void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals); void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals);
void R_LightArrays(const entity_t *entity, vecV_t *coords, vec4_t *colours, int vertcount, vec3_t *normals); void R_LightArrays(const entity_t *entity, vecV_t *coords, vec4_t *colours, int vertcount, vec3_t *normals, float scale);
void R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and calls back into it*/ void R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and calls back into it*/
void R_InitSky (struct texnums_s *ret, struct texture_s *mt, qbyte *src); /*generate q1 sky texnums*/ void R_InitSky (struct texnums_s *ret, struct texture_s *mt, qbyte *src); /*generate q1 sky texnums*/
@ -268,6 +271,7 @@ enum imageflags
IF_NOMIPMAP = 1<<2, IF_NOMIPMAP = 1<<2,
IF_NOALPHA = 1<<3, IF_NOALPHA = 1<<3,
IF_NOGAMMA = 1<<4, IF_NOGAMMA = 1<<4,
IF_NEAREST = 1<<5,
IF_SUBDIRONLY = 1<<31 IF_SUBDIRONLY = 1<<31
}; };
@ -303,9 +307,9 @@ enum uploadfmt
/*it seems a little excessive to have to include glquake (and windows headers), just to load some textures/shaders for the backend*/ /*it seems a little excessive to have to include glquake (and windows headers), just to load some textures/shaders for the backend*/
#ifdef GLQUAKE #ifdef GLQUAKE
texid_t GL_AllocNewTexture(int w, int h); texid_tf GL_AllocNewTexture(char *name, int w, int h);
void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags); void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
texid_t GL_LoadTextureFmt (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags); texid_tf GL_LoadTextureFmt (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
void GL_DestroyTexture(texid_t tex); void GL_DestroyTexture(texid_t tex);
#endif #endif
#ifdef D3DQUAKE #ifdef D3DQUAKE
@ -314,15 +318,16 @@ texid_t D3D9_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *
texid_t D3D9_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags); texid_t D3D9_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t D3D9_LoadCompressed (char *name); texid_t D3D9_LoadCompressed (char *name);
texid_t D3D9_FindTexture (char *identifier); texid_t D3D9_FindTexture (char *identifier);
texid_t D3D9_AllocNewTexture(int width, int height); texid_t D3D9_AllocNewTexture(char *ident, int width, int height);
void D3D9_Upload (texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags); void D3D9_Upload (texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
void D3D9_DestroyTexture (texid_t tex); void D3D9_DestroyTexture (texid_t tex);
void D3D_Image_Shutdown(void);
#endif #endif
extern int image_width, image_height; extern int image_width, image_height;
texid_t R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags); texid_tf R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags);
texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags); texid_tf R_LoadHiResTexture(char *name, char *subpath, unsigned int flags);
texid_t R_LoadBumpmapTexture(char *name, char *subpath); texid_tf R_LoadBumpmapTexture(char *name, char *subpath);
extern texid_t particletexture; extern texid_t particletexture;
extern texid_t particlecqtexture; extern texid_t particlecqtexture;
@ -431,6 +436,7 @@ extern cvar_t r_wateralpha;
extern cvar_t r_dynamic; extern cvar_t r_dynamic;
extern cvar_t r_novis; extern cvar_t r_novis;
extern cvar_t r_netgraph; extern cvar_t r_netgraph;
extern cvar_t r_deluxemapping;
#ifdef R_XFLIP #ifdef R_XFLIP
extern cvar_t r_xflip; extern cvar_t r_xflip;

View File

@ -224,8 +224,6 @@ cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1");
cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3"); cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3");
cvar_t gl_blend2d = CVAR ("gl_blend2d", "1"); cvar_t gl_blend2d = CVAR ("gl_blend2d", "1");
cvar_t gl_blendsprites = CVAR ("gl_blendsprites", "1"); cvar_t gl_blendsprites = CVAR ("gl_blendsprites", "1");
cvar_t gl_bump = CVARF ("gl_bump", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t r_deluxemapping = CVARAF ("r_deluxemapping", "0", "r_glsl_deluxemapping", cvar_t r_deluxemapping = CVARAF ("r_deluxemapping", "0", "r_glsl_deluxemapping",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t gl_compress = CVARF ("gl_compress", "0", cvar_t gl_compress = CVARF ("gl_compress", "0",
@ -294,6 +292,7 @@ cvar_t vid_triplebuffer = CVARAF ("vid_triplebuffer", "1",
"gl_triplebuffer", CVAR_ARCHIVE); "gl_triplebuffer", CVAR_ARCHIVE);
cvar_t r_noportals = SCVAR ("r_noportals", "0"); cvar_t r_noportals = SCVAR ("r_noportals", "0");
cvar_t dpcompat_psa_ungroup = SCVAR ("dpcompat_psa_ungroup", "0");
cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t r_shadows = SCVARF ("r_shadows", "0", cvar_t r_shadows = SCVARF ("r_shadows", "0",
@ -355,13 +354,12 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_affinemodels, GLRENDEREROPTIONS); Cvar_Register (&gl_affinemodels, GLRENDEREROPTIONS);
Cvar_Register (&gl_nohwblend, GLRENDEREROPTIONS); Cvar_Register (&gl_nohwblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblendscale, GLRENDEREROPTIONS);
Cvar_Register (&gl_nocolors, GLRENDEREROPTIONS); Cvar_Register (&gl_nocolors, GLRENDEREROPTIONS);
Cvar_Register (&gl_finish, GLRENDEREROPTIONS); Cvar_Register (&gl_finish, GLRENDEREROPTIONS);
Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS); Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS);
Cvar_Register (&gl_lerpimages, GLRENDEREROPTIONS); Cvar_Register (&gl_lerpimages, GLRENDEREROPTIONS);
Cvar_Register (&dpcompat_psa_ungroup, GLRENDEREROPTIONS);
Cvar_Register (&r_noportals, GLRENDEREROPTIONS); Cvar_Register (&r_noportals, GLRENDEREROPTIONS);
Cvar_Register (&r_noaliasshadows, GLRENDEREROPTIONS); Cvar_Register (&r_noaliasshadows, GLRENDEREROPTIONS);
Cvar_Register (&gl_maxshadowlights, GLRENDEREROPTIONS); Cvar_Register (&gl_maxshadowlights, GLRENDEREROPTIONS);
@ -381,7 +379,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES); Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES);
Cvar_Register (&gl_bump, GRAPHICALNICETIES);
Cvar_Register (&r_deluxemapping, GRAPHICALNICETIES); Cvar_Register (&r_deluxemapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
@ -539,6 +536,8 @@ void Renderer_Init(void)
Cvar_Register(&r_stainfadetime, GRAPHICALNICETIES); Cvar_Register(&r_stainfadetime, GRAPHICALNICETIES);
Cvar_Register(&r_stainfadeammount, GRAPHICALNICETIES); Cvar_Register(&r_stainfadeammount, GRAPHICALNICETIES);
Cvar_Register(&r_lightprepass, GRAPHICALNICETIES); Cvar_Register(&r_lightprepass, GRAPHICALNICETIES);
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblendscale, GLRENDEREROPTIONS);
Cvar_Register(&scr_viewsize, SCREENOPTIONS); Cvar_Register(&scr_viewsize, SCREENOPTIONS);
Cvar_Register(&scr_fov, SCREENOPTIONS); Cvar_Register(&scr_fov, SCREENOPTIONS);
@ -773,6 +772,7 @@ rendererinfo_t dedicatedrendererinfo = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
"" ""
}; };
@ -2147,7 +2147,7 @@ void R_InitParticleTexture (void)
} }
} }
particletexture = R_LoadTexture32("", 8, 8, data, IF_NOMIPMAP|IF_NOPICMIP); TEXASSIGN(particletexture, R_LoadTexture32("", 8, 8, data, IF_NOMIPMAP|IF_NOPICMIP));
// //

View File

@ -22,11 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h" #include "quakedef.h"
#include "shader.h" #include "shader.h"
#ifdef _MSC_VER
#pragma message("hipnotic/rogue: Find out")
#endif
#define FINDOUT 1024
extern cvar_t hud_tracking_show; extern cvar_t hud_tracking_show;
extern cvar_t com_parseutf8; extern cvar_t com_parseutf8;
@ -539,7 +534,7 @@ void Sbar_ExecuteLayoutString (char *s)
color = 0; // green color = 0; // green
if (cl.q2frame.playerstate.stats[Q2STAT_FLASHES] & 2) if (cl.q2frame.playerstate.stats[Q2STAT_FLASHES] & 2)
R2D_ScalePic (x, y, FINDOUT, FINDOUT, R2D_SafeCachePic("field_3")); R2D_ScalePic (x, y, 64, 64, R2D_SafeCachePic("field_3"));
SCR_DrawField (x, y, color, width, value); SCR_DrawField (x, y, color, width, value);
continue; continue;

View File

@ -223,9 +223,9 @@ qbyte *Skin_Cache8 (skin_t *skin)
if (skin->failedload) if (skin->failedload)
return NULL; return NULL;
skin->tex_base = r_nulltex; TEXASSIGN(skin->tex_base, r_nulltex);
skin->tex_lower = r_nulltex; TEXASSIGN(skin->tex_lower, r_nulltex);
skin->tex_upper = r_nulltex; TEXASSIGN(skin->tex_upper, r_nulltex);
out = Cache_Check (&skin->cache); out = Cache_Check (&skin->cache);
if (out) if (out)
@ -279,13 +279,13 @@ qbyte *Skin_Cache8 (skin_t *skin)
#if defined(GLQUAKE) || defined(D3DQUAKE) #if defined(GLQUAKE) || defined(D3DQUAKE)
if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D)
{ {
skin->tex_base = R_LoadReplacementTexture(skin->name, "skins", IF_NOALPHA); TEXASSIGN(skin->tex_base, R_LoadReplacementTexture(skin->name, "skins", IF_NOALPHA));
if (TEXVALID(skin->tex_base)) if (TEXVALID(skin->tex_base))
{ {
Q_snprintfz (name, sizeof(name), "%s_shirt", skin->name); Q_snprintfz (name, sizeof(name), "%s_shirt", skin->name);
skin->tex_upper = R_LoadReplacementTexture(name, "skins", 0); TEXASSIGN(skin->tex_upper, R_LoadReplacementTexture(name, "skins", 0));
Q_snprintfz (name, sizeof(name), "%s_pants", skin->name); Q_snprintfz (name, sizeof(name), "%s_pants", skin->name);
skin->tex_lower = R_LoadReplacementTexture(name, "skins", 0); TEXASSIGN(skin->tex_lower, R_LoadReplacementTexture(name, "skins", 0));
skin->failedload = true; skin->failedload = true;
return NULL; return NULL;

View File

@ -167,8 +167,8 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
// start = ch->end - scache->length; // start = ch->end - scache->length;
// samples = end - start; // samples = end - start;
#ifdef _MSC_VER #ifdef warningmsg
#pragma message("pitch fix needed") #pragma warningmsg("pitch fix needed")
#endif #endif
ch->sfx->decoder->decodemore(ch->sfx, ch->sfx->decoder->decodemore(ch->sfx,
end - (ch->end - scache->length) + 1); end - (ch->end - scache->length) + 1);

850
engine/client/sys_axfte.cpp Normal file
View File

@ -0,0 +1,850 @@
#include "quakedef.h"
#ifdef _WIN32
#include "sys_plugfte.h"
#include <objsafe.h> /*IObjectSafety*/
#include <mshtmdid.h> /*DISPID_SECURITYCTX*/
#include <OleCtl.h> /*common dispid values*/
const GUID axfte_iid = {0x7d676c9f, 0xfb84, 0x40b6, {0xb3, 0xff, 0xe1, 0x08, 0x31, 0x55, 0x7e, 0xeb}};
#define axfte_iid_str "7d676c9f-fb84-40b6-b3ff-e10831557eeb"
extern "C" extern HINSTANCE global_hInstance;
#pragma warning(disable:4584) /*shush now*/
class axfte : public IUnknown, public IDispatch, public IClassFactory, public IObjectSafety,
public IOleObject, public IOleInPlaceObjectWindowless, public IViewObject, public IPersistPropertyBag2
{
private:
unsigned int ref;
IUnknown *site;
struct context *plug;
const struct plugfuncs *funcs;
HWND phwnd;
static const struct browserfuncs axbrowserfuncs;
public:
axfte()
{
ref = 0;
site = NULL;
phwnd = NULL;
funcs = Plug_GetFuncs(PLUG_APIVER);
plug = funcs->CreateContext(this, &axbrowserfuncs);
}
~axfte()
{
funcs->DestroyContext(plug);
if (site)
site->Release();
site = NULL;
}
static void statuschanged(void *arg)
{
axfte *fte = (axfte*)arg;
InvalidateRect(NULL, NULL, FALSE);
}
/*IUnknown*/
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject)
{
*ppvObject = NULL;
if (riid == IID_IUnknown)
{
*ppvObject = (IUnknown*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IDispatch)
{
*ppvObject = (IDispatch*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IClassFactory)
{
*ppvObject = (IClassFactory*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IObjectSafety)
{
*ppvObject = (IObjectSafety*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
/* else if (riid == IID_IPersistPropertyBag2)
{
*ppvObject = (IPersistPropertyBag2*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}*/
else if (riid == IID_IOleObject)
{
*ppvObject = (IOleObject*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IOleInPlaceObject)
{
*ppvObject = (IOleInPlaceObject*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IOleInPlaceObjectWindowless)
{
*ppvObject = (IOleInPlaceObjectWindowless*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IOleWindow)
{
*ppvObject = (IOleWindow*)(IOleInPlaceObject*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IOleInPlaceObject)
{
*ppvObject = (IOleInPlaceObject*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
else if (riid == IID_IViewObject)
{
*ppvObject = (IViewObject*)this;
((LPUNKNOWN)*ppvObject)->AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
virtual ULONG STDMETHODCALLTYPE AddRef( void)
{
return ++ref;
}
virtual ULONG STDMETHODCALLTYPE Release( void)
{
if (ref == 1)
{
delete this;
return 0;
}
return --ref;
}
/*IDispatch*/
virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(
/* [out] */ UINT *pctinfo)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
/* [in] */ UINT iTInfo,
/* [in] */ LCID lcid,
/* [out] */ ITypeInfo **ppTInfo)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(
/* [in] */ REFIID riid,
/* [size_is][in] */ LPOLESTR *rgszNames,
/* [in] */ UINT cNames,
/* [in] */ LCID lcid,
/* [size_is][out] */ DISPID *rgDispId)
{
char tmp[1024];
HRESULT ret = S_OK;
int i;
int prop;
for (i = 0; i < cNames; i++)
{
wcstombs(tmp, rgszNames[i], sizeof(tmp));
prop = funcs->FindProp(plug, tmp);
if (prop >= 0)
{
rgDispId[i] = prop;
}
else if (!stricmp(tmp, "unselectable"))
rgDispId[i] = 5001;
else
{
rgDispId[i] = DISPID_UNKNOWN;
ret = DISP_E_UNKNOWNNAME;
}
}
return ret;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS *pDispParams,
/* [out] */ VARIANT *pVarResult,
/* [out] */ EXCEPINFO *pExcepInfo,
/* [out] */ UINT *puArgErr)
{
if(wFlags & DISPATCH_METHOD)
{
MessageBox(NULL, "", "invoke method!", 0);
return DISP_E_MEMBERNOTFOUND;
}
else if (wFlags & DISPATCH_PROPERTYGET)
{
VariantClear(pVarResult);
switch(dispIdMember)
{
case DISPID_READYSTATE:
pVarResult->vt = VT_INT;
pVarResult->intVal = READYSTATE_COMPLETE;
break;
case DISPID_ENABLED:
return DISP_E_MEMBERNOTFOUND;
case DISPID_SECURITYCTX:
return DISP_E_MEMBERNOTFOUND;
default:
if (dispIdMember >= 0 && dispIdMember < 1000)
{
const char *tmpa;
wchar_t tmpw[1024];
if (funcs->GetFloat(plug, dispIdMember, &pVarResult->fltVal))
pVarResult->vt = VT_R4;
else if (funcs->GetInteger(plug, dispIdMember, &pVarResult->intVal))
pVarResult->vt = VT_I4;
else if (funcs->GetString(plug, dispIdMember, &tmpa))
{
mbstowcs(tmpw, tmpa, sizeof(tmpw)/sizeof(tmpw[0]));
funcs->GotString(tmpa);
pVarResult->vt = VT_BSTR;
pVarResult->bstrVal = SysAllocString(tmpw);
}
else
return DISP_E_MEMBERNOTFOUND;
}
else
{
char tmp[1024];
sprintf(tmp, "DISPATCH_PROPERTYGET dispIdMember=%i", dispIdMember);
OutputDebugStringA(tmp);
return DISP_E_MEMBERNOTFOUND;
}
}
}
else if (wFlags & DISPATCH_PROPERTYPUT)
{
if (dispIdMember >= 0 && dispIdMember < 1000)
{
VARIANT *v = &pDispParams->rgvarg[0];
switch(v->vt)
{
case VT_R4:
funcs->SetFloat(plug, dispIdMember, v->fltVal);
break;
case VT_R8:
funcs->SetFloat(plug, dispIdMember, v->dblVal);
break;
case VT_INT:
case VT_I4:
funcs->SetInteger(plug, dispIdMember, v->intVal);
break;
case VT_BSTR:
funcs->SetWString(plug, dispIdMember, v->bstrVal);
break;
default:
return DISP_E_TYPEMISMATCH;
}
return S_OK;
}
else
{
char tmp[1024];
sprintf(tmp, "DISPATCH_PROPERTYPUT dispIdMember=%i", dispIdMember);
OutputDebugStringA(tmp);
return DISP_E_MEMBERNOTFOUND;
}
}
else if (wFlags & DISPATCH_PROPERTYPUTREF)
{
char tmp[1024];
sprintf(tmp, "DISPATCH_PROPERTYPUTREF dispIdMember=%i", dispIdMember);
OutputDebugStringA(tmp);
return DISP_E_MEMBERNOTFOUND;
}
else
return DISP_E_MEMBERNOTFOUND;
return S_OK;
}
/*IClassFactory*/
virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance(
/* [unique][in] */ IUnknown *pUnkOuter,
/* [in] */ REFIID riid,
/* [iid_is][out] */ void **ppvObject)
{
HRESULT res;
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
axfte *newaxfte = new axfte();
res = newaxfte->QueryInterface(riid, ppvObject);
if (!*ppvObject)
delete newaxfte;
return res;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE LockServer(
/* [in] */ BOOL fLock)
{
return S_OK;
}
/*IObjectSafety*/
virtual HRESULT STDMETHODCALLTYPE GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD *pdwSupportedOptions,
/* [out] */ DWORD *pdwEnabledOptions)
{
*pdwSupportedOptions = *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
return S_OK;
}
/*IOleWindow*/
virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(
/* [out] */ HWND *phwnd)
{
*phwnd = NULL;
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(
/* [in] */ BOOL fEnterMode)
{
return E_NOTIMPL;
}
/*IOleInPlaceObject*/
virtual HRESULT STDMETHODCALLTYPE InPlaceDeactivate( void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE UIDeactivate( void)
{
return E_NOTIMPL;
}
virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE SetObjectRects(
/* [in] */ LPCRECT lprcPosRect,
/* [in] */ LPCRECT lprcClipRect)
{
if (phwnd)
funcs->ChangeWindow(plug, phwnd, lprcPosRect->left, lprcPosRect->top, lprcPosRect->right - lprcPosRect->left, lprcPosRect->bottom - lprcPosRect->top);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE ReactivateAndUndo( void)
{
return E_NOTIMPL;
}
/*IOleObject*/
virtual HRESULT STDMETHODCALLTYPE SetClientSite(
/* [unique][in] */ IOleClientSite *pClientSite)
{
IUnknown *osite = site;
site = pClientSite;
if (site)
site->AddRef();
IOleInPlaceSiteWindowless *oipc;
if (site)
if (!FAILED(site->QueryInterface(IID_IOleInPlaceSiteWindowless, (void**)&oipc)))
{
IOleInPlaceFrame *pframe;
IOleInPlaceUIWindow *pdoc;
RECT posrect;
RECT cliprect;
OLEINPLACEFRAMEINFO frameinfo;
memset(&frameinfo, 0, sizeof(frameinfo));
frameinfo.cb = sizeof(frameinfo);
oipc->GetWindowContext(&pframe, &pdoc, &posrect, &cliprect, &frameinfo);
if (pframe) pframe->Release();
if (pdoc) pdoc->Release();
phwnd = frameinfo.hwndFrame;
oipc->Release();
}
if (osite)
osite->Release();
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetClientSite(
/* [out] */ IOleClientSite **ppClientSite)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE SetHostNames(
/* [in] */ LPCOLESTR szContainerApp,
/* [unique][in] */ LPCOLESTR szContainerObj)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Close(
/* [in] */ DWORD dwSaveOption)
{
funcs->SetInteger(plug, funcs->FindProp(plug, "running"), 0);
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE SetMoniker(
/* [in] */ DWORD dwWhichMoniker,
/* [unique][in] */ IMoniker *pmk)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetMoniker(
/* [in] */ DWORD dwAssign,
/* [in] */ DWORD dwWhichMoniker,
/* [out] */ IMoniker **ppmk)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE InitFromData(
/* [unique][in] */ IDataObject *pDataObject,
/* [in] */ BOOL fCreation,
/* [in] */ DWORD dwReserved)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetClipboardData(
/* [in] */ DWORD dwReserved,
/* [out] */ IDataObject **ppDataObject)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE DoVerb(
/* [in] */ LONG iVerb,
/* [unique][in] */ LPMSG lpmsg,
/* [unique][in] */ IOleClientSite *pActiveSite,
/* [in] */ LONG lindex,
/* [in] */ HWND hwndParent,
/* [unique][in] */ LPCRECT lprcPosRect)
{
switch(iVerb)
{
case OLEIVERB_INPLACEACTIVATE:
IOleInPlaceSiteWindowless *oipc;
if (!FAILED(pActiveSite->QueryInterface(IID_IOleInPlaceSiteWindowless, (void**)&oipc)))
{
IOleInPlaceFrame *pframe;
IOleInPlaceUIWindow *pdoc;
RECT posrect;
RECT cliprect;
OLEINPLACEFRAMEINFO frameinfo;
memset(&frameinfo, 0, sizeof(frameinfo));
frameinfo.cb = sizeof(frameinfo);
oipc->GetWindowContext(&pframe, &pdoc, &posrect, &cliprect, &frameinfo);
if (pframe) pframe->Release();
if (pdoc) pdoc->Release();
phwnd = frameinfo.hwndFrame;
funcs->ChangeWindow(plug, frameinfo.hwndFrame, lprcPosRect->left, lprcPosRect->top, lprcPosRect->right - lprcPosRect->left, lprcPosRect->bottom - lprcPosRect->top);
oipc->OnInPlaceActivateEx(NULL, 1);
oipc->Release();
}
break;
}
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE EnumVerbs(
/* [out] */ IEnumOLEVERB **ppEnumOleVerb)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Update( void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE IsUpToDate( void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetUserClassID(
/* [out] */ CLSID *pClsid)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetUserType(
/* [in] */ DWORD dwFormOfType,
/* [out] */ LPOLESTR *pszUserType)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE SetExtent(
/* [in] */ DWORD dwDrawAspect,
/* [in] */ SIZEL *psizel)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetExtent(
/* [in] */ DWORD dwDrawAspect,
/* [out] */ SIZEL *psizel)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Advise(
/* [unique][in] */ IAdviseSink *pAdvSink,
/* [out] */ DWORD *pdwConnection)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Unadvise(
/* [in] */ DWORD dwConnection)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE EnumAdvise(
/* [out] */ IEnumSTATDATA **ppenumAdvise)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetMiscStatus(
/* [in] */ DWORD dwAspect,
/* [out] */ DWORD *pdwStatus)
{
*pdwStatus = OLEMISC_RECOMPOSEONRESIZE;
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE SetColorScheme(
/* [in] */ LOGPALETTE *pLogpal)
{
return E_NOTIMPL;
}
/*IViewObject*/
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Draw(
/* [in] */ DWORD dwDrawAspect,
/* [in] */ LONG lindex,
/* [unique][in] */ void *pvAspect,
/* [unique][in] */ DVTARGETDEVICE *ptd,
/* [in] */ HDC hdcTargetDev,
/* [in] */ HDC hdcDraw,
/* [in] */ LPCRECTL lprcBounds,
/* [unique][in] */ LPCRECTL lprcWBounds,
/* [in] */ BOOL ( STDMETHODCALLTYPE *pfnContinue )(
ULONG_PTR dwContinue),
/* [in] */ ULONG_PTR dwContinue)
{
int width, height;
HBITMAP bmp = (HBITMAP)funcs->GetSplashBack(plug, hdcDraw, &width, &height);
if (bmp)
{
HDC memDC;
RECT irect;
irect.left = lprcBounds->left;
irect.right = lprcBounds->right;
irect.top = lprcBounds->top;
irect.bottom = lprcBounds->bottom;
memDC = CreateCompatibleDC(hdcDraw);
SelectObject(memDC, bmp);
StretchBlt(hdcDraw, irect.left, irect.top, irect.right-irect.left,irect.bottom-irect.top, memDC, 0, 0, width, height, SRCCOPY);
SelectObject(memDC, NULL);
DeleteDC(memDC);
funcs->ReleaseSplashBack(plug, bmp);
}
return S_OK;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetColorSet(
/* [in] */ DWORD dwDrawAspect,
/* [in] */ LONG lindex,
/* [unique][in] */ void *pvAspect,
/* [unique][in] */ DVTARGETDEVICE *ptd,
/* [in] */ HDC hicTargetDev,
/* [out] */ LOGPALETTE **ppColorSet)
{
return E_NOTIMPL;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE Freeze(
/* [in] */ DWORD dwDrawAspect,
/* [in] */ LONG lindex,
/* [unique][in] */ void *pvAspect,
/* [out] */ DWORD *pdwFreeze)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE Unfreeze(
/* [in] */ DWORD dwFreeze)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE SetAdvise(
/* [in] */ DWORD aspects,
/* [in] */ DWORD advf,
/* [unique][in] */ IAdviseSink *pAdvSink)
{
return E_NOTIMPL;
}
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetAdvise(
/* [unique][out] */ DWORD *pAspects,
/* [unique][out] */ DWORD *pAdvf,
/* [out] */ IAdviseSink **ppAdvSink)
{
return E_NOTIMPL;
}
/*IOleInPlaceObjectWindowless*/
virtual HRESULT STDMETHODCALLTYPE OnWindowMessage(
/* [in] */ UINT msg,
/* [in] */ WPARAM wParam,
/* [in] */ LPARAM lParam,
/* [out] */ LRESULT *plResult)
{
switch(msg)
{
case WM_LBUTTONDOWN:
funcs->SetInteger(plug, funcs->FindProp(plug, "running"), 1);
return S_OK;
default:
return E_NOTIMPL;
}
}
virtual HRESULT STDMETHODCALLTYPE GetDropTarget(
/* [out] */ IDropTarget **ppDropTarget)
{
return E_NOTIMPL;
}
/*IPersist*/
virtual HRESULT STDMETHODCALLTYPE GetClassID(
/* [out] */ CLSID *pClassID)
{
return E_NOTIMPL;
}
/*IPersistPropertyBag2*/
virtual HRESULT STDMETHODCALLTYPE InitNew( void)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Load(
/* [in] */ IPropertyBag2 *pPropBag,
/* [in] */ IErrorLog *pErrLog)
{
PROPBAG2 prop[] =
{
{PROPBAG2_TYPE_DATA, VT_BSTR, 0, 0, L"splash", NULL},
{PROPBAG2_TYPE_DATA, VT_BSTR, 0, 0, L"game", NULL},
{PROPBAG2_TYPE_DATA, VT_BSTR, 0, 0, L"dataDownload", NULL}
};
VARIANT val[sizeof(prop)/sizeof(prop[0])];
HRESULT res[sizeof(prop)/sizeof(prop[0])];
memset(val, 0, sizeof(val));
pPropBag->Read(sizeof(prop)/sizeof(prop[0]), prop, NULL, val, res);
funcs->SetWString(plug, funcs->FindProp(plug, "splash"), val[0].bstrVal);
funcs->SetWString(plug, funcs->FindProp(plug, "game"), val[1].bstrVal);
funcs->SetWString(plug, funcs->FindProp(plug, "dataDownload"), val[2].bstrVal);
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE Save(
/* [in] */ IPropertyBag2 *pPropBag,
/* [in] */ BOOL fClearDirty,
/* [in] */ BOOL fSaveAllProperties)
{
/*we don't actually save anything*/
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE IsDirty( void)
{
return E_NOTIMPL;
}
};
const struct browserfuncs axfte::axbrowserfuncs = {NULL, axfte::statuschanged};
extern "C"
{
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
*ppv = NULL;
if (rclsid == axfte_iid)
{
HRESULT res;
axfte *newaxfte = new axfte();
res = newaxfte->QueryInterface(riid, ppv);
if (!*ppv)
delete newaxfte;
return res;
}
return CLASS_E_CLASSNOTAVAILABLE;
}
HRESULT WINAPI DllCanUnloadNow(void)
{
return S_OK;
}
struct
{
char *key;
char *value;
} regkeys[] =
{
{"Software\\Classes\\FTE.FTEPlug\\", "FTEPlug Class"},
{"Software\\Classes\\FTE.FTEPlug\\CurVer\\", "FTE.FTEPlug.1"},
{"Software\\Classes\\FTE.FTEPlug.1\\", "FTEPlug Class"},
{"Software\\Classes\\FTE.FTEPlug.1\\CLSID\\", "{"axfte_iid_str"}"},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\", ""},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\InprocHandler32\\", "ole32.dll"},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\InprocServer32\\", "***DLLNAME***"},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\InprocServer32\\ThreadingModel", "Apartment"},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\Programmable\\", ""},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\VersionIndependentProgID\\", "FTE.FTEPlug"},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\ProgID\\", "FTE.FTEPlug.1.0"},
#ifdef warningmsg
#pragma warningmsg("Hey, moodles, do you want the plugin to register itself as a firefox plugin at the same time as it registers itself for support in IE?")
#endif
/*
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Description", ENGINEWEBSITE},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\GeckoVersion", "1.00"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Path", "***DLLNAME***"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\ProductName", FULLENGINENAME},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Vendor", DISTRIBUTIONLONG},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Version", "***VERSION***"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\MimeTypes\\application/x-fteplugin\\Description", "FTE Game Engine Plugin"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\MimeTypes\\application/x-qtv\\Description", "QuakeTV Stream Information File"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\MimeTypes\\application/x-qtv\\Suffixes", "qtv"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Suffixes\\qtv", ""},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Suffixes\\mvd", ""},
*/
{NULL}
};
HRESULT WINAPI DllRegisterServer(void)
{
char binaryname[1024];
char tmp[1024];
GetModuleFileName(global_hInstance, binaryname, sizeof(binaryname));
HKEY h;
bool allusers = false;
int i;
char *ls;
for (i = 0; regkeys[i].key; i++)
{
ls = strrchr(regkeys[i].key, '\\') + 1;
memcpy(tmp, regkeys[i].key, ls - regkeys[i].key);
tmp[ls - regkeys[i].key] = 0;
if (RegCreateKeyExA(allusers?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER, tmp, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &h, NULL))
continue;
if (!strcmp(regkeys[i].value, "***DLLNAME***"))
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)binaryname, strlen(binaryname));
else if (!strcmp(regkeys[i].value, "***VERSION***"))
{
char *ver = version_string();
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)ver, strlen(ver));
}
else
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)regkeys[i].value, strlen(regkeys[i].value));
RegCloseKey(h);
}
return S_OK;
}
HRESULT WINAPI DllUnregisterServer(void)
{
int i;
bool allusers = false;
char *ls;
char tmp[1024];
HKEY h;
for (i = 0; regkeys[i].key; i++)
{
}
/*go backwards*/
for (i--; i>=0; i--)
{
ls = strrchr(regkeys[i].key, '\\') + 1;
memcpy(tmp, regkeys[i].key, ls - regkeys[i].key);
tmp[ls - regkeys[i].key] = 0;
if (*ls)
{
h = NULL;
if (!RegOpenKeyEx(allusers?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER, tmp, 0, KEY_SET_VALUE, &h))
{
RegDeleteValue(h, ls);
RegCloseKey(h);
}
}
else
RegDeleteKey(allusers?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER, tmp);
}
return S_OK;
}
}//externC
#endif

View File

@ -490,7 +490,9 @@ void *Sys_GetGameAPI(void *parms)
result = getcwd(curpath, sizeof(curpath)); // do something with result? result = getcwd(curpath, sizeof(curpath)); // do something with result?
#warning Search for both gamei386.so and game.so #ifdef warningmsg
#pragma warningmsg("Search for both gamei386.so and game.so")
#endif
Con_DPrintf("Searching for %s but not %s\n", agamename, ggamename); Con_DPrintf("Searching for %s but not %s\n", agamename, ggamename);
searchpath = 0; searchpath = 0;

View File

@ -66,9 +66,10 @@ qboolean NPFTE_BeginDownload(void *ctx, struct pipetype *ftype, char *url)
return NPERR_NO_ERROR==browserfuncs->geturlnotify(ctx, url, NULL, ftype); return NPERR_NO_ERROR==browserfuncs->geturlnotify(ctx, url, NULL, ftype);
} }
void NPFTE_StatusChanged(struct context *ctx) void NPFTE_StatusChanged(void *sysctx)
{ {
struct contextpublic *pub = (struct contextpublic*)ctx; NPP instance = sysctx;
struct contextpublic *pub = instance->pdata;
InvalidateRgn(pub->oldwnd, NULL, FALSE); InvalidateRgn(pub->oldwnd, NULL, FALSE);
} }
@ -263,7 +264,7 @@ NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window)
return NPERR_INVALID_INSTANCE_ERROR; return NPERR_INVALID_INSTANCE_ERROR;
//if the window changed //if the window changed
if (Plug_ChangeWindow(ctx, window->window, window->width, window->height)) if (Plug_ChangeWindow(ctx, window->window, 0, 0, window->width, window->height))
{ {
//we switched window? //we switched window?
if (pub->oldwnd && pub->oldproc) if (pub->oldwnd && pub->oldproc)
@ -501,7 +502,7 @@ bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
struct npscript *obj = (struct npscript *)npobj; struct npscript *obj = (struct npscript *)npobj;
struct context *ctx = obj->ctx; struct context *ctx = obj->ctx;
NPUTF8 *pname; NPUTF8 *pname;
struct pscript_property *prop; int prop;
bool success = false; bool success = false;
char *strval; char *strval;
int intval; int intval;
@ -510,7 +511,7 @@ bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
Plug_LockPlugin(ctx, true); Plug_LockPlugin(ctx, true);
prop = Plug_FindProp(obj->ctx, pname); prop = Plug_FindProp(obj->ctx, pname);
if (prop) if (prop >= 0)
{ {
if (Plug_GetString(ctx, prop, &strval)) if (Plug_GetString(ctx, prop, &strval))
{ {
@ -554,13 +555,13 @@ bool npscript_setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *v
struct context *ctx = obj->ctx; struct context *ctx = obj->ctx;
NPUTF8 *pname; NPUTF8 *pname;
NPString str; NPString str;
struct pscript_property *prop; int prop;
bool success = false; bool success = false;
pname = browserfuncs->utf8fromidentifier(name); pname = browserfuncs->utf8fromidentifier(name);
Plug_LockPlugin(ctx, true); Plug_LockPlugin(ctx, true);
prop = Plug_FindProp(obj->ctx, pname); prop = Plug_FindProp(obj->ctx, pname);
if (prop) if (prop >= 0)
{ {
success = true; success = true;
if (NPVARIANT_IS_STRING(*value)) if (NPVARIANT_IS_STRING(*value))

View File

@ -1,697 +0,0 @@
#include "quakedef.h"
#include "winquake.h"
#define bool int //we ain't c++ (grr microsoft stdbool.h gief!)
#ifdef _WIN32
#ifndef _WINDOWS
#define _WINDOWS //stupid GCC
#endif
#endif
#include "npapi/npupp.h"
#include "sys_plugfte.h"
#define Q_STRINGZ_TO_NPVARIANT(_val, _v) \
NP_BEGIN_MACRO \
NPString str = { _val, strlen(_val) }; \
(_v).type = NPVariantType_String; \
(_v).value.stringValue = str; \
NP_END_MACRO
#undef STRINGZ_TO_NPVARIANT
#define STRINGZ_TO_NPVARIANT Q_STRINGZ_TO_NPVARIANT
#define FIREFOX_BUGS_OVER_25MB
//TODO: player name input (before allowing them to join)
//TODO: fix active gl context (per thread, and we hijacked the browser's thread)
NPNetscapeFuncs *browserfuncs;
#ifdef _WIN32
#ifndef GetWindowLongPtr
#define GetWindowLongPtr GetWindowLong
#endif
#ifndef SetWindowLongPtr
#define SetWindowLongPtr SetWindowLong
#define LONG_PTR LONG
#endif
#endif
qboolean NPFTE_BeginDownload(void *ctx, struct pipetype *ftype, char *url)
{
return NPERR_NO_ERROR==browserfuncs->geturlnotify(ctx, url, NULL, ftype);
}
#ifdef _WIN32
void DrawWndBack(struct context *ctx, HWND hWnd, HDC hdc, PAINTSTRUCT *p)
{
int width, height;
HBITMAP bmp = Plug_GetSplashBack(ctx, hdc, &width, &height);
if (bmp)
{
HDC memDC;
memDC = CreateCompatibleDC(hdc);
SelectObject(memDC, bmp);
StretchBlt(hdc, p->rcPaint.left, p->rcPaint.top, p->rcPaint.right-p->rcPaint.left,p->rcPaint.bottom-p->rcPaint.top, memDC, 0, 0, width, height, SRCCOPY);
SelectObject(memDC, NULL);
DeleteDC(memDC);
Plug_ReleaseSplashBack(ctx, bmp);
}
else
PatBlt(hdc, p->rcPaint.left, p->rcPaint.top, p->rcPaint.right-p->rcPaint.left,p->rcPaint.bottom-p->rcPaint.top,PATCOPY);
}
LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
struct context *ctx;
struct contextpublic *pub;
ctx = (struct context *)GetWindowLongPtr(hWnd, GWL_USERDATA);
if (!ctx)
return DefWindowProc(hWnd, msg, wParam, lParam);
pub = (struct contextpublic*)ctx;
switch(msg)
{
case WM_USER:
/*if the plugin is somewhere in video code, the plugin might depend upon us being able to respond to window messages*/
/* while(ctx->queuedstreams)
{
struct qstream *strm;
strm = ctx->queuedstreams;
ctx->queuedstreams = strm->next;
if (!browserfuncs->geturlnotify(ctx->nppinstance, strm->url, NULL, strm->type))
{
VS_DebugLocation(__FILE__, __LINE__, "Starting Download %s", strm->url);
if (strm->type->wait == WAIT_YES)
ctx->waitingfordatafiles++;
}
free(strm);
}
*/
return TRUE;
case WM_PAINT:
/* if (ctx->waitingfordatafiles)
{
HDC hdc;
PAINTSTRUCT paint;
char *s;
unsigned int progress;
unsigned int total;
bool sizeknown = true;
struct qstream *strm;
progress = 0;
total = 0;
if (Sys_TryLockMutex(ctx->mutex)) //this lock doesn't have to be here
{
for (strm = ctx->activestreams; strm; strm = strm->next)
{
progress += strm->offset;
total += strm->size;
if (!total && progress)
sizeknown = false;
}
Plug_LockPlugin(ctx, false);
}
hdc = BeginPaint(hWnd, &paint);
DrawWndBack(ctx, hWnd, hdc, &paint);
SetBkMode(hdc, TRANSPARENT);
TextOutA(hdc, 0, 0, "Downloading Data, please wait", 16);
if (!progress && !total)
s = "connecting";
else if (sizeknown)
s = va("%i bytes (%i%%)", progress, (int)((100.0f*progress)/total));
else
s = va("%i bytes", progress);
TextOutA(hdc, 0, 32, s, strlen(s));
EndPaint(hWnd, &paint);
return TRUE;
}
else
*/ {
HDC hdc;
PAINTSTRUCT paint;
char *s;
hdc = BeginPaint(hWnd, &paint);
DrawWndBack(ctx, hWnd, hdc, &paint);
SetBkMode(hdc, TRANSPARENT);
if (!pub->running)
{
s = "Click to activate";
TextOutA(hdc, 0, 0, s, strlen(s));
if (pub->availver)
{
s = va("Your plugin may be incompatible");
TextOutA(hdc, 0, 32, s, strlen(s));
s = va("Version %3.2f was requested, you are using version %3.2f", pub->availver, (float)version_number());
TextOutA(hdc, 0, 48, s, strlen(s));
}
}
EndPaint(hWnd, &paint);
return TRUE;
}
break;
case WM_LBUTTONDOWN:
SetActiveWindow(hWnd);
if (!Plug_StartContext(ctx))
Plug_StopContext(NULL);
break;
default:
break;
}
//I would call the previous wndproc... but that crashes firefox
return DefWindowProc(hWnd, msg, wParam, lParam);
}
#endif
static const struct browserfuncs npqtv_browserfuncs =
{
NPFTE_BeginDownload
};
NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance,
uint16 mode, int16 argc, char* argn[],
char* argv[], NPSavedData* saved)
{
int i;
struct context *ctx;
if (!instance || instance->pdata)
{
return NPERR_INVALID_INSTANCE_ERROR;
}
if (mode != NP_EMBED && mode != NP_FULL)
{
return NPERR_INVALID_PLUGIN_ERROR;
}
ctx = Plug_CreateContext(instance, &npqtv_browserfuncs);
instance->pdata = ctx;
if (!ctx)
{
return NPERR_OUT_OF_MEMORY_ERROR;
}
//parse out the properties
for (i = 0; i < argc; i++)
{
Plug_SetString(ctx, Plug_FindProp(ctx, argn[i]), argv[i]);
}
return NPERR_NO_ERROR;
}
NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save)
{
struct context *ctx = instance->pdata;
struct contextpublic *pub = (struct contextpublic *)ctx;
if (!ctx)
return NPERR_INVALID_INSTANCE_ERROR;
#ifdef _WIN32
if (pub->oldwnd)
{
if (pub->oldproc)
SetWindowLongPtr(pub->oldwnd, GWL_WNDPROC, (LONG_PTR)pub->oldproc);
SetWindowLongPtr(pub->oldwnd, GWL_USERDATA, (LONG_PTR)NULL);
}
#endif
Plug_DestroyContext(ctx);
instance->pdata = NULL;
return NPERR_NO_ERROR;
}
NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window)
{
extern cvar_t vid_width;
struct context *ctx = instance->pdata;
struct contextpublic *pub = (struct contextpublic*)ctx;
#ifdef _WIN32
HWND oldwindow;
WNDPROC p;
if (!ctx)
return NPERR_INVALID_INSTANCE_ERROR;
//if the window changed
if (Plug_ChangeWindow(ctx, window->window, window->width, window->height))
{
//we switched window?
if (pub->oldwnd && pub->oldproc)
{
SetWindowLongPtr(pub->oldwnd, GWL_WNDPROC, (LONG_PTR)pub->oldproc);
}
pub->oldproc = NULL;
p = (WNDPROC)GetWindowLongPtr(window->window, GWL_WNDPROC);
if (p != MyPluginWndProc)
pub->oldproc = p;
pub->oldwnd = window->window;
SetWindowLongPtr(window->window, GWL_WNDPROC, (LONG_PTR)MyPluginWndProc);
SetWindowLongPtr(window->window, GWL_USERDATA, (LONG_PTR)ctx);
}
InvalidateRgn(window->window, NULL, FALSE);
#endif
return NPERR_NO_ERROR;
}
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type,
NPStream* stream, NPBool seekable,
uint16* stype)
{
return NPERR_NO_ERROR;
/* struct context *ctx = instance->pdata;
struct qstream *qstr;
stream->pdata = qstr = malloc(sizeof(*qstr) + strlen(stream->url));
memset(qstr, 0, sizeof(*qstr));
strcpy(qstr->url, stream->url);
Plug_LockPlugin(ctx, true);
qstr->next = ctx->activestreams;
if (qstr->next)
qstr->next->prev = qstr;
ctx->activestreams = qstr;
Plug_LockPlugin(ctx, false);
if (!stream->notifyData)
{
//choose source type based on mime type
if (!strncmp(type, "text/x-quaketvident", 5))
stream->notifyData = &QTVFileDescriptor;
else if (!strcmp(type, "application/x-multiviewdemo"))
stream->notifyData = &DemoFileDescriptor;
//well that failed, try choosing based on extension
else if (!strcmp(COM_FileExtension(stream->url), "qtv"))
stream->notifyData = &QTVFileDescriptor;
else
return NPERR_INVALID_PARAM;
}
qstr->type = stream->notifyData;
if (qstr->type->needseeking)
{
*stype = NP_ASFILEONLY; //everything is a download
#ifdef FIREFOX_BUGS_OVER_25MB
*stype = NP_NORMAL;
qstr->pipe = FS_OpenTemp();
#endif
}
else
{
*stype = NP_NORMAL;
qstr->pipe = VFSPIPE_Open();
}
return NPERR_NO_ERROR;*/
}
NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream,
NPReason reason)
{
return NPERR_NO_ERROR;
/* struct context *ctx = instance->pdata;
struct qstream *qstr = stream->pdata;
if (!qstr) //urm, got canceled before it finished downloading?
return NPERR_NO_ERROR;
if (qstr->type->wait == WAIT_YES)
{
ctx->waitingfordatafiles--;
}
if (qstr->next)
qstr->next->prev = qstr->prev;
if (qstr->prev)
qstr->prev->next = qstr->next;
else
ctx->activestreams = qstr->next;
if (qstr->type->wait == WAIT_NONACTIVE)
{
Plug_LockPlugin(ctx, true);
qstr->type->completionfunc(ctx, qstr->pipe, qstr->url);
Plug_LockPlugin(ctx, false);
}
else
{
qstr->next = ctx->donestreams;
ctx->donestreams = qstr;
}
if (qstr && qstr->type && qstr->type->wait)
{
InvalidateRgn(ctx->window.window, NULL, FALSE);
}
return NPERR_NO_ERROR;*/
}
int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream)
{
return 8192;
/* struct qstream *qstr = stream->pdata;
vfsfile_t *pipe = qstr?qstr->pipe:NULL;
if (pipe && pipe->seekingisabadplan)
return 1024*1024 - VFS_GETLEN(pipe);
else
return 8192;*/
}
int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset,
int32 len, void* buffer)
{
return NPERR_NO_ERROR;
/* int bytes = NPP_WriteReady(instance, stream);
struct context *ctx = instance->pdata;
struct qstream *qstr = stream->pdata;
if (qstr && qstr->type && qstr->type->wait)
{
qstr->offset = offset;
qstr->size = stream->end;
InvalidateRgn(ctx->window.window, NULL, FALSE);
}
if (!qstr || !qstr->pipe)
return bytes;
//we're not meant to read more bytes than we said we could read.
if (len > bytes)
len = bytes;
return VFS_WRITE(qstr->pipe, buffer, len);*/
}
void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream,
const char* fname)
{
return;
/* struct qstream *qstr = stream->pdata;
if (!qstr)
return;
if (qstr->pipe)
VFS_CLOSE(qstr->pipe);
qstr->pipe = VFSOS_Open(fname, "rb");
*/
}
void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint)
{
//we don't support printing.
//paper and ink doesn't give a good frame rate.
return;
}
int16 NP_LOADDS NPP_HandleEvent(NPP instance, void* event)
{
// MessageBox(NULL, "NPP_HandleEvent", "npapi", 0);
return NPERR_NO_ERROR;
}
void NP_LOADDS NPP_URLNotify(NPP instance, const char* url,
NPReason reason, void* notifyData)
{
}
struct npscript
{
NPObject obj;
struct context *ctx;
};
NPObject *npscript_allocate(NPP npp, NPClass *aClass)
{
struct npscript_property *prop;
struct npscript *obj;
obj = malloc(sizeof(*obj));
obj->obj._class = aClass;
obj->obj.referenceCount = 1;
obj->ctx = npp->pdata;
return (NPObject*)obj;
}
void npscript_deallocate(NPObject *npobj)
{
free(npobj);
}
void npscript_invalidate(NPObject *npobj)
{
struct npscript *obj = (struct npscript *)npobj;
obj->ctx = NULL;
}
bool npscript_hasMethod(NPObject *npobj, NPIdentifier name)
{
NPUTF8 *mname;
mname = browserfuncs->utf8fromidentifier(name);
return false;
}
bool npscript_invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
return false;
}
bool npscript_invokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
return false;
}
bool npscript_hasProperty(NPObject *npobj, NPIdentifier name)
{
struct npscript *obj = (struct npscript *)npobj;
struct npscript_property *prop;
NPUTF8 *pname;
pname = browserfuncs->utf8fromidentifier(name);
if (Plug_FindProp(obj->ctx, pname))
return true;
return false;
}
bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
{
struct npscript *obj = (struct npscript *)npobj;
struct context *ctx = obj->ctx;
NPUTF8 *pname;
struct pscript_property *prop;
bool success = false;
char *strval;
int intval;
float floatval;
pname = browserfuncs->utf8fromidentifier(name);
Plug_LockPlugin(ctx, true);
prop = Plug_FindProp(obj->ctx, pname);
if (prop)
{
if (Plug_GetString(ctx, prop, &strval))
{
char *ns;
int len;
len = strlen(strval);
ns = browserfuncs->memalloc(len);
if (ns)
{
memcpy(ns, strval, len);
STRINGZ_TO_NPVARIANT(ns, *result);
success = true;
}
Plug_GotString(strval);
}
else if (Plug_GetInteger(ctx, prop, &intval))
{
INT32_TO_NPVARIANT(intval, *result);
success = true;
}
else if (Plug_GetFloat(ctx, prop, &floatval))
{
DOUBLE_TO_NPVARIANT(floatval, *result);
success = true;
}
}
Plug_LockPlugin(ctx, false);
return success;
}
bool npscript_setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
{
struct npscript *obj = (struct npscript *)npobj;
struct context *ctx = obj->ctx;
NPUTF8 *pname;
NPString str;
struct pscript_property *prop;
bool success = false;
pname = browserfuncs->utf8fromidentifier(name);
Plug_LockPlugin(ctx, true);
prop = Plug_FindProp(obj->ctx, pname);
if (prop)
{
success = true;
if (NPVARIANT_IS_STRING(*value))
{
char *t = NULL;
str = NPVARIANT_TO_STRING(*value);
if (str.utf8characters[str.utf8length] != 0)
{
t = malloc(str.utf8length+1);
memcpy(t, str.utf8characters, str.utf8length);
t[str.utf8length] = 0;
str.utf8characters = t;
}
Plug_SetString(ctx, prop, str.utf8characters);
if (t)
free(t);
}
else if (NPVARIANT_IS_INT32(*value))
Plug_SetInteger(ctx, prop, NPVARIANT_TO_INT32(*value));
else if (NPVARIANT_IS_BOOLEAN(*value))
Plug_SetInteger(ctx, prop, NPVARIANT_TO_BOOLEAN(*value));
else if (NPVARIANT_IS_DOUBLE(*value))
Plug_SetFloat(ctx, prop, NPVARIANT_TO_DOUBLE(*value));
else
success = false;
}
Plug_LockPlugin(ctx, false);
return success;
}
bool npscript_removeProperty(NPObject *npobj, NPIdentifier name)
{
return false;
}
bool npscript_enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
{
return false;
}
bool npscript_construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result)
{
return false;
}
NPClass npscript_class =
{
NP_CLASS_STRUCT_VERSION,
npscript_allocate,
npscript_deallocate,
npscript_invalidate,
npscript_hasMethod,
npscript_invoke,
npscript_invokeDefault,
npscript_hasProperty,
npscript_getProperty,
npscript_setProperty,
npscript_removeProperty,
npscript_enumerate,
npscript_construct
};
NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
switch(variable)
{
case NPPVpluginScriptableNPObject:
*(void**)value = browserfuncs->createobject(instance, &npscript_class);
return NPERR_NO_ERROR;
default:
return NPERR_INVALID_PARAM;
}
return NPERR_NO_ERROR;
}
NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value)
{
switch(variable)
{
default:
return NPERR_INVALID_PARAM;
}
return NPERR_NO_ERROR;
}
NPError OSCALL NP_Initialize(NPNetscapeFuncs* pFuncs)
{
browserfuncs = pFuncs;
return NPERR_NO_ERROR;
}
NPError OSCALL NP_Shutdown(void)
{
/* if (contextlist)
{ //the browser isn't meant to call this when there's still instances left...
return NPERR_GENERIC_ERROR;
}
*/
return NPERR_NO_ERROR;
}
NPError OSCALL NP_GetValue(void *instance, NPPVariable variable, void *value)
{
if (value == NULL)
return NPERR_INVALID_PARAM;
switch(variable)
{
case NPPVpluginNameString:
*(char**)value = "QTV Viewer";
break;
case NPPVpluginDescriptionString:
*(char**)value = "QTV Viewer";
break;
default:
return NPERR_INVALID_PARAM;
}
return NPERR_NO_ERROR;
}
NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* pFuncs)
{
if (pFuncs->size < sizeof(NPPluginFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
pFuncs->size = sizeof(NPPluginFuncs);
pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
pFuncs->newp = NPP_New;
pFuncs->destroy = NPP_Destroy;
pFuncs->setwindow = NPP_SetWindow;
pFuncs->newstream = NPP_NewStream;
pFuncs->destroystream = NPP_DestroyStream;
pFuncs->asfile = NPP_StreamAsFile;
pFuncs->writeready = NPP_WriteReady;
pFuncs->write = NPP_Write;
pFuncs->print = NPP_Print;
pFuncs->event = NPP_HandleEvent;
pFuncs->urlnotify = NPP_URLNotify;
pFuncs->javaClass = NULL;
pFuncs->getvalue = NPP_GetValue;
pFuncs->setvalue = NPP_SetValue;
return NPERR_NO_ERROR;
}
char *NP_GetMIMEDescription(void)
{
return "test/x-qtv:qtv:QTV Stream Description";
}

View File

@ -105,6 +105,8 @@ struct context
struct contextpublic pub; struct contextpublic pub;
void *windowhnd; void *windowhnd;
int windowleft;
int windowtop;
int windowwidth; int windowwidth;
int windowheight; int windowheight;
@ -117,7 +119,7 @@ struct context
char *onend; char *onend;
char *ondemoend; char *ondemoend;
void *nppinstance; void *hostinstance;
int read; int read;
int written; int written;
@ -299,7 +301,6 @@ int Plug_PluginThread(void *ctxptr)
} }
Con_Printf("Attempting to download %s\n", c); Con_Printf("Attempting to download %s\n", c);
VS_DebugLocation(__FILE__, __LINE__, "Queuing Download %s", c);
dl = DL_Create(c); dl = DL_Create(c);
dl->user_ctx = ctx; dl->user_ctx = ctx;
@ -327,7 +328,7 @@ int Plug_PluginThread(void *ctxptr)
ctx->pub.dlsize = total; ctx->pub.dlsize = total;
ctx->pub.dldone = done; ctx->pub.dldone = done;
if (ctx->bfuncs.StatusChanged) if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub); ctx->bfuncs.StatusChanged(ctx->hostinstance);
} }
if (!dl->file) if (!dl->file)
ctx->packagelist = dl->next; ctx->packagelist = dl->next;
@ -347,28 +348,29 @@ int Plug_PluginThread(void *ctxptr)
Sys_LockMutex(ctx->mutex); Sys_LockMutex(ctx->mutex);
ctx->resetvideo = false; ctx->resetvideo = false;
sys_parentwindow = ctx->windowhnd; sys_parentwindow = ctx->windowhnd;
sys_parentleft = ctx->windowleft;
sys_parenttop = ctx->windowtop;
sys_parentwidth = ctx->windowwidth; sys_parentwidth = ctx->windowwidth;
sys_parentheight = ctx->windowheight; sys_parentheight = ctx->windowheight;
VS_DebugLocation(__FILE__, __LINE__, "Host_FinishInit");
Host_FinishInit(); Host_FinishInit();
Sys_UnlockMutex(ctx->mutex); Sys_UnlockMutex(ctx->mutex);
} }
if (ctx->bfuncs.StatusChanged) if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub); ctx->bfuncs.StatusChanged(ctx->hostinstance);
VS_DebugLocation(__FILE__, __LINE__, "main loop");
while(host_initialized) while(host_initialized)
{ {
Sys_LockMutex(ctx->mutex); Sys_LockMutex(ctx->mutex);
if (ctx->shutdown) if (ctx->shutdown)
{ {
ctx->shutdown = false; ctx->shutdown = false;
VS_DebugLocation(__FILE__, __LINE__, "Sys_Shutdown");
Host_Shutdown(); /*will shut down the host*/ Host_Shutdown(); /*will shut down the host*/
} }
else if (ctx->resetvideo) else if (ctx->resetvideo)
{ {
sys_parentwindow = ctx->windowhnd; sys_parentwindow = ctx->windowhnd;
sys_parentleft = ctx->windowleft;
sys_parenttop = ctx->windowtop;
sys_parentwidth = ctx->windowwidth; sys_parentwidth = ctx->windowwidth;
sys_parentheight = ctx->windowheight; sys_parentheight = ctx->windowheight;
if (ctx->resetvideo == 2) if (ctx->resetvideo == 2)
@ -410,7 +412,7 @@ int Plug_PluginThread(void *ctxptr)
ctx->pub.running = false; ctx->pub.running = false;
Sys_UnlockMutex(ctx->mutex); Sys_UnlockMutex(ctx->mutex);
if (ctx->bfuncs.StatusChanged) if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub); ctx->bfuncs.StatusChanged(ctx->hostinstance);
while(argc-- > 0) while(argc-- > 0)
free(argv[argc]); free(argv[argc]);
@ -470,7 +472,7 @@ struct context *Plug_CreateContext(void *sysctx, const struct browserfuncs *func
memcpy(&ctx->bfuncs, funcs, sizeof(ctx->bfuncs)); memcpy(&ctx->bfuncs, funcs, sizeof(ctx->bfuncs));
//link the instance to the context and the context to the instance //link the instance to the context and the context to the instance
ctx->nppinstance = sysctx; ctx->hostinstance = sysctx;
ctx->gamename = strdup("q1"); ctx->gamename = strdup("q1");
@ -484,7 +486,7 @@ struct context *Plug_CreateContext(void *sysctx, const struct browserfuncs *func
} }
//change the plugin's parent window, width, and height, returns true if the window handle actually changed, false otherwise //change the plugin's parent window, width, and height, returns true if the window handle actually changed, false otherwise
qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int width, int height) qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int left, int top, int width, int height)
{ {
qboolean result = false; qboolean result = false;
@ -497,11 +499,12 @@ qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int width, int heigh
ctx->windowhnd = whnd; ctx->windowhnd = whnd;
ctx->resetvideo = 2; ctx->resetvideo = 2;
} }
if (ctx->windowwidth != width || ctx->windowheight != height)
{ ctx->windowleft = left;
ctx->windowwidth = width; ctx->windowtop = top;
ctx->windowheight = height; ctx->windowwidth = width;
} ctx->windowheight = height;
if (ctx->pub.running && !ctx->resetvideo) if (ctx->pub.running && !ctx->resetvideo)
ctx->resetvideo = true; ctx->resetvideo = true;
Plug_LockPlugin(ctx, false); Plug_LockPlugin(ctx, false);
@ -659,7 +662,7 @@ void LoadSplashImage(struct dl_download *dl)
if (!f) if (!f)
{ {
if (ctx->bfuncs.StatusChanged) if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub); ctx->bfuncs.StatusChanged(ctx->hostinstance);
return; return;
} }
@ -695,7 +698,7 @@ void LoadSplashImage(struct dl_download *dl)
BZ_Free(image); BZ_Free(image);
if (ctx->bfuncs.StatusChanged) if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub); ctx->bfuncs.StatusChanged(ctx->hostinstance);
} }
} }
@ -887,9 +890,10 @@ char *pscript_property_build_gets(struct context *ctx)
extern cvar_t skin, team, topcolor, bottomcolor, vid_fullscreen, cl_download_mapsrc; extern cvar_t skin, team, topcolor, bottomcolor, vid_fullscreen, cl_download_mapsrc;
static struct pscript_property pscript_properties[] = static struct pscript_property pscript_properties[] =
{ {
{"", false, NULL, pscript_property_curserver_gets, pscript_property_curserver_sets},
{"server", false, NULL, pscript_property_curserver_gets, pscript_property_curserver_sets},
{"running", false, NULL, NULL, NULL, pscript_property_running_getb, pscript_property_running_setb}, {"running", false, NULL, NULL, NULL, pscript_property_running_getb, pscript_property_running_setb},
{"startserver", false, NULL, pscript_property_startserver_gets, pscript_property_startserver_sets}, {"startserver", false, NULL, pscript_property_startserver_gets, pscript_property_startserver_sets},
{"server", false, NULL, pscript_property_curserver_gets, pscript_property_curserver_sets},
{"join", false, NULL, NULL, pscript_property_curserver_sets}, {"join", false, NULL, NULL, pscript_property_curserver_sets},
{"playername", true, &name}, {"playername", true, &name},
{NULL, true, &skin}, {NULL, true, &skin},
@ -913,68 +917,11 @@ static struct pscript_property pscript_properties[] =
{"map", false, NULL, NULL, pscript_property_map_sets}, {"map", false, NULL, NULL, pscript_property_map_sets},
{"build", false, NULL, pscript_property_build_gets}, {"build", false, NULL, pscript_property_build_gets},
/*
else if (!stricmp(argn[i], "connType"))
{
if (ctx->qtvf.connectiontype)
continue;
if (!stricmp(argn[i], "join"))
ctx->qtvf.connectiontype = QTVCT_JOIN;
else if (!stricmp(argn[i], "qtv"))
ctx->qtvf.connectiontype = QTVCT_STREAM;
else if (!stricmp(argn[i], "connect"))
ctx->qtvf.connectiontype = QTVCT_CONNECT;
else if (!stricmp(argn[i], "map"))
ctx->qtvf.connectiontype = QTVCT_MAP;
else if (!stricmp(argn[i], "join"))
ctx->qtvf.connectiontype = QTVCT_JOIN;
else if (!stricmp(argn[i], "observe"))
ctx->qtvf.connectiontype = QTVCT_OBSERVE;
else
ctx->qtvf.connectiontype = QTVCT_NONE;
}
else if (!stricmp(argn[i], "map"))
{
if (ctx->qtvf.connectiontype)
continue;
ctx->qtvf.connectiontype = QTVCT_MAP;
Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server));
}
else if (!stricmp(argn[i], "join"))
{
if (ctx->qtvf.connectiontype)
continue;
ctx->qtvf.connectiontype = QTVCT_JOIN;
Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server));
}
else if (!stricmp(argn[i], "observe"))
{
if (ctx->qtvf.connectiontype)
continue;
ctx->qtvf.connectiontype = QTVCT_OBSERVE;
Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server));
}
else if (!stricmp(argn[i], "password"))
{
ctx->password = strdup(argv[i]);
}
else if (!stricmp(argn[i], "onStart"))
{
ctx->onstart = strdup(argv[i]);
}
else if (!stricmp(argn[i], "onEnd"))
{
ctx->onend = strdup(argv[i]);
}
else if (!stricmp(argn[i], "onDemoEnd"))
{
ctx->ondemoend = strdup(argv[i]);
}
*/
{NULL} {NULL}
}; };
struct pscript_property *Plug_FindProp(struct context *ctx, const char *field) int Plug_FindProp(struct context *ctx, const char *field)
{ {
struct pscript_property *prop; struct pscript_property *prop;
for (prop = pscript_properties; prop->name||prop->cvar; prop++) for (prop = pscript_properties; prop->name||prop->cvar; prop++)
@ -984,17 +931,18 @@ struct pscript_property *Plug_FindProp(struct context *ctx, const char *field)
if (prop->onlyifactive) if (prop->onlyifactive)
{ {
if (!ctx->pub.running) if (!ctx->pub.running)
return NULL; return -1;
} }
return prop; return prop - pscript_properties;
} }
} }
return NULL; return -1;
} }
qboolean Plug_SetString(struct context *ctx, struct pscript_property *field, const char *value) qboolean Plug_SetString(struct context *ctx, int fieldidx, const char *value)
{ {
if (!ctx || !field || !value) struct pscript_property *field = pscript_properties + fieldidx;
if (!ctx || fieldidx < 0 || fieldidx >= sizeof(pscript_properties)/sizeof(pscript_properties[0]) || !value)
return false; return false;
if (field->setstring) if (field->setstring)
{ {
@ -1024,9 +972,16 @@ qboolean Plug_SetString(struct context *ctx, struct pscript_property *field, con
return false; return false;
return true; return true;
} }
qboolean Plug_SetInteger(struct context *ctx, struct pscript_property *field, int value) qboolean Plug_SetWString(struct context *ctx, int fieldidx, const wchar_t *value)
{ {
if (!ctx || !field) char tmp[1024];
wcstombs(tmp, value, sizeof(tmp));
return Plug_SetString(ctx, fieldidx, tmp);
}
qboolean Plug_SetInteger(struct context *ctx, int fieldidx, int value)
{
struct pscript_property *field = pscript_properties + fieldidx;
if (!ctx || fieldidx < 0 || fieldidx >= sizeof(pscript_properties)/sizeof(pscript_properties[0]))
return false; return false;
if (field->setint) if (field->setint)
{ {
@ -1050,9 +1005,10 @@ qboolean Plug_SetInteger(struct context *ctx, struct pscript_property *field, in
return false; return false;
return true; return true;
} }
qboolean Plug_SetFloat(struct context *ctx, struct pscript_property *field, float value) qboolean Plug_SetFloat(struct context *ctx, int fieldidx, float value)
{ {
if (!ctx || !field) struct pscript_property *field = pscript_properties + fieldidx;
if (!ctx || fieldidx < 0 || fieldidx >= sizeof(pscript_properties)/sizeof(pscript_properties[0]))
return false; return false;
if (field->setfloat) if (field->setfloat)
{ {
@ -1077,8 +1033,12 @@ qboolean Plug_SetFloat(struct context *ctx, struct pscript_property *field, floa
return true; return true;
} }
qboolean Plug_GetString(struct context *ctx, struct pscript_property *field, const char **value) qboolean Plug_GetString(struct context *ctx, int fieldidx, const char **value)
{ {
struct pscript_property *field = pscript_properties + fieldidx;
if (!ctx || fieldidx < 0 || fieldidx >= sizeof(pscript_properties)/sizeof(pscript_properties[0]))
return false;
if (field->getstring) if (field->getstring)
{ {
*value = field->getstring(ctx); *value = field->getstring(ctx);
@ -1090,8 +1050,12 @@ void Plug_GotString(const char *value)
{ {
free((char*)value); free((char*)value);
} }
qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, int *value) qboolean Plug_GetInteger(struct context *ctx, int fieldidx, int *value)
{ {
struct pscript_property *field = pscript_properties + fieldidx;
if (!ctx || fieldidx < 0 || fieldidx >= sizeof(pscript_properties)/sizeof(pscript_properties[0]))
return false;
if (field->getint) if (field->getint)
{ {
*value = field->getint(ctx); *value = field->getint(ctx);
@ -1099,8 +1063,12 @@ qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, in
} }
return false; return false;
} }
qboolean Plug_GetFloat(struct context *ctx, struct pscript_property *field, float *value) qboolean Plug_GetFloat(struct context *ctx, int fieldidx, float *value)
{ {
struct pscript_property *field = pscript_properties + fieldidx;
if (!ctx || fieldidx < 0 || fieldidx >= sizeof(pscript_properties)/sizeof(pscript_properties[0]))
return false;
if (field->getfloat) if (field->getfloat)
{ {
*value = field->getfloat(ctx); *value = field->getfloat(ctx);
@ -1161,7 +1129,9 @@ static const struct plugfuncs exportedplugfuncs_1 =
Plug_GetFloat, Plug_GetFloat,
Plug_GetSplashBack, Plug_GetSplashBack,
Plug_ReleaseSplashBack Plug_ReleaseSplashBack,
Plug_SetWString
}; };
const struct plugfuncs *Plug_GetFuncs(int ver) const struct plugfuncs *Plug_GetFuncs(int ver)

View File

@ -26,6 +26,7 @@ struct contextpublic
void *user; void *user;
}; };
/*
#include <windows.h> #include <windows.h>
static void VS_DebugLocation(char *fname, int line, char *fmt, ...) static void VS_DebugLocation(char *fname, int line, char *fmt, ...)
{ {
@ -41,7 +42,7 @@ static void VS_DebugLocation(char *fname, int line, char *fmt, ...)
OutputDebugStringA(buffer); OutputDebugStringA(buffer);
OutputDebugStringA("\n"); OutputDebugStringA("\n");
} }
*/
@ -58,16 +59,16 @@ void Plug_DestroyContext(struct context *ctx);
void Plug_LockPlugin(struct context *ctx, qboolean lockstate); void Plug_LockPlugin(struct context *ctx, qboolean lockstate);
qboolean Plug_StartContext(struct context *ctx); qboolean Plug_StartContext(struct context *ctx);
void Plug_StopContext(struct context *ctx); void Plug_StopContext(struct context *ctx);
qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int width, int height); qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int left, int top, int width, int height);
struct pscript_property *Plug_FindProp(struct context *ctx, const char *field); int Plug_FindProp(struct context *ctx, const char *field);
qboolean Plug_SetString(struct context *ctx, struct pscript_property *field, const char *value); qboolean Plug_SetString(struct context *ctx, int field, const char *value);
qboolean Plug_GetString(struct context *ctx, struct pscript_property *field, const char **value); qboolean Plug_GetString(struct context *ctx, int field, const char **value);
void Plug_GotString(const char *value); void Plug_GotString(const char *value);
qboolean Plug_SetInteger(struct context *ctx, struct pscript_property *field, int value); qboolean Plug_SetInteger(struct context *ctx, int field, int value);
qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, int *value); qboolean Plug_GetInteger(struct context *ctx, int field, int *value);
qboolean Plug_SetFloat(struct context *ctx, struct pscript_property *field, float value); qboolean Plug_SetFloat(struct context *ctx, int field, float value);
qboolean Plug_GetFloat(struct context *ctx, struct pscript_property *field, float *value); qboolean Plug_GetFloat(struct context *ctx, int field, float *value);
#ifdef _WIN32 #ifdef _WIN32
void *Plug_GetSplashBack(struct context *ctx, void *hdc, int *width, int *height);/*returns an HBITMAP*/ void *Plug_GetSplashBack(struct context *ctx, void *hdc, int *width, int *height);/*returns an HBITMAP*/
@ -81,22 +82,27 @@ struct plugfuncs
void (*LockPlugin)(struct context *ctx, qboolean lockstate); void (*LockPlugin)(struct context *ctx, qboolean lockstate);
qboolean (*StartContext)(struct context *ctx); qboolean (*StartContext)(struct context *ctx);
void (*StopContext)(struct context *ctx); void (*StopContext)(struct context *ctx);
qboolean (*ChangeWindow)(struct context *ctx, void *whnd, int width, int height); qboolean (*ChangeWindow)(struct context *ctx, void *whnd, int left, int top, int width, int height);
struct pscript_property *(*FindProp)(struct context *ctx, const char *field); int (*FindProp)(struct context *ctx, const char *field);
qboolean (*SetString)(struct context *ctx, struct pscript_property *field, const char *value); qboolean (*SetString)(struct context *ctx, int field, const char *value);
qboolean (*GetString)(struct context *ctx, struct pscript_property *field, const char **value); qboolean (*GetString)(struct context *ctx, int field, const char **value);
void (*GotString)(const char *value); void (*GotString)(const char *value);
qboolean (*SetInteger)(struct context *ctx, struct pscript_property *field, int value); qboolean (*SetInteger)(struct context *ctx, int field, int value);
qboolean (*GetInteger)(struct context *ctx, struct pscript_property *field, int *value); qboolean (*GetInteger)(struct context *ctx, int field, int *value);
qboolean (*SetFloat)(struct context *ctx, struct pscript_property *field, float value); qboolean (*SetFloat)(struct context *ctx, int field, float value);
qboolean (*GetFloat)(struct context *ctx, struct pscript_property *field, float *value); qboolean (*GetFloat)(struct context *ctx, int field, float *value);
#ifdef _WIN32 #ifdef _WIN32
void *(*GetSplashBack)(struct context *ctx, void *hdc, int *width, int *height);/*returns an HBITMAP*/ void *(*GetSplashBack)(struct context *ctx, void *hdc, int *width, int *height);/*returns an HBITMAP*/
void (*ReleaseSplashBack)(struct context *ctx, void *bmp); void (*ReleaseSplashBack)(struct context *ctx, void *bmp);
#endif #endif
qboolean (*SetWString)(struct context *ctx, int field, const wchar_t *value);
}; };
#define PLUG_APIVER 1 #define PLUG_APIVER 1
#ifdef __cplusplus
extern "C"
#endif
const struct plugfuncs *Plug_GetFuncs(int ver); const struct plugfuncs *Plug_GetFuncs(int ver);

View File

@ -46,6 +46,8 @@ qboolean isDedicated = false;
qboolean debugout; qboolean debugout;
HWND sys_parentwindow; HWND sys_parentwindow;
unsigned int sys_parentleft; //valid if sys_parentwindow is set
unsigned int sys_parenttop;
unsigned int sys_parentwidth; //valid if sys_parentwindow is set unsigned int sys_parentwidth; //valid if sys_parentwindow is set
unsigned int sys_parentheight; unsigned int sys_parentheight;
@ -1866,8 +1868,10 @@ qboolean Sys_LockMutex(void *mutex)
return true; return true;
OutputDebugString("Warning: Suspected mutex deadlock\n"); OutputDebugString("Warning: Suspected mutex deadlock\n");
DebugBreak(); DebugBreak();
#endif return false;
#else
return WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0; return WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0;
#endif
} }
qboolean Sys_UnlockMutex(void *mutex) qboolean Sys_UnlockMutex(void *mutex)

View File

@ -526,7 +526,7 @@ void Editor_Key(int key, int unicode)
case K_F4: case K_F4:
EditorSaveFile(OpenEditorFile); EditorSaveFile(OpenEditorFile);
break; break;
case K_F5: case K_F5: /*stop debugging*/
editormodal = false; editormodal = false;
if (editprogfuncs) if (editprogfuncs)
*editprogfuncs->pr_trace = false; *editprogfuncs->pr_trace = false;
@ -535,16 +535,16 @@ void Editor_Key(int key, int unicode)
if (editprogfuncs) if (editprogfuncs)
PR_StackTrace(editprogfuncs); PR_StackTrace(editprogfuncs);
break; break;
case K_F7: case K_F7: /*save+recompile*/
EditorSaveFile(OpenEditorFile); EditorSaveFile(OpenEditorFile);
if (editprogfuncs) if (editprogfuncs)
Cbuf_AddText("compile\n", RESTRICT_LOCAL); Cbuf_AddText("compile\n", RESTRICT_LOCAL);
break; break;
case K_F8: case K_F8: /*move execution point to here - I hope you move to the same function!*/
executionlinenum = cursorlinenum; executionlinenum = cursorlinenum;
executionblock = cursorblock; executionblock = cursorblock;
break; break;
case K_F9: case K_F9: /*set breakpoint*/
{ {
int f = 0; int f = 0;
if (editprogfuncs) if (editprogfuncs)
@ -570,11 +570,11 @@ void Editor_Key(int key, int unicode)
cursorblock->flags &= ~FB_BREAK; cursorblock->flags &= ~FB_BREAK;
} }
break; break;
case K_F10: case K_F10: //save+apply changes, supposedly
EditorSaveFile(OpenEditorFile); EditorSaveFile(OpenEditorFile);
Cbuf_AddText("applycompile\n", RESTRICT_LOCAL); Cbuf_AddText("applycompile\n", RESTRICT_LOCAL);
break; break;
case K_F11: case K_F11: //single step
editormodal = false; editormodal = false;
break; break;
// case K_STOP: // case K_STOP:

View File

@ -295,8 +295,8 @@ static void Validation_Server(void)
{ {
char adr[MAX_ADR_SIZE]; char adr[MAX_ADR_SIZE];
#ifndef _MSC_VER #ifdef warningmsg
#warning is allowing the user to turn this off practical?.. #pragma warningmsg("is allowing the user to turn this off practical?..")
#endif #endif
if (!allow_f_server.ival) if (!allow_f_server.ival)
return; return;
@ -391,6 +391,8 @@ rulesetrule_t rulesetrules_strict[] = {
{"ruleset_allow_localvolume", "0"}, {"ruleset_allow_localvolume", "0"},
{"tp_disputablemacros", "0"}, {"tp_disputablemacros", "0"},
{"cl_instantrotate", "0"}, {"cl_instantrotate", "0"},
{"v_projectionmode", "0"}, /*no extended fovs*/
{"r_shadow_realtime_world", "0"}, /*static lighting can be used to cast shadows around corners*/
{NULL} {NULL}
}; };
@ -404,6 +406,7 @@ rulesetrule_t rulesetrules_nqr[] = {
{"ruleset_allow_sensative_texture_replacements", "0"}, {"ruleset_allow_sensative_texture_replacements", "0"},
{"ruleset_allow_localvolume", "0"}, {"ruleset_allow_localvolume", "0"},
{"ruleset_allow_shaders", "0"}, {"ruleset_allow_shaders", "0"},
{"v_projectionmode", "0"},
{NULL} {NULL}
}; };
@ -435,11 +438,11 @@ qboolean Validation_GetCurrentRulesetName(char *rsnames, int resultbuflen, qbool
rs = rulesets; rs = rulesets;
*rsnames = '\0'; *rsnames = '\0';
#ifndef _MSC_VER #ifdef warningmsg
#warning "here's a question... Should we latch the ruleset unconditionally, or only when someone actually cares?" #pragma warningmsg("here's a question... Should we latch the ruleset unconditionally, or only when someone actually cares?")
#warning if we do it only when someone checks, we have a lot more checking, otherwise we have a freer tournament if the users choose to play that way #pragma warningmsg("if we do it only when someone checks, we have a lot more checking, otherwise we have a freer tournament if the users choose to play that way")
#warning "I'm going to do it the old-fashioned way" #pragma warningmsg("I'm going to do it the old-fashioned way")
#warning (yes, this is one for molgrum to resolve!) #pragma warningmsg("(yes, this is one for molgrum to resolve!)")
#endif #endif
for (rs = rulesets; rs->rulesetname; rs++) for (rs = rulesets; rs->rulesetname; rs++)
{ {
@ -537,8 +540,8 @@ void Validation_Apply_Ruleset(void)
cvar_t *var; cvar_t *var;
int i; int i;
#ifndef _MSC_VER #ifdef warningmsg
#warning fixme: the following line should not be needed. ensure this is the case #pragma warningmsg("fixme: the following line should not be needed. ensure this is the case")
#endif #endif
Validation_DelatchRulesets(); //make sure there's no old one Validation_DelatchRulesets(); //make sure there's no old one

View File

@ -45,7 +45,7 @@ extern rendererstate_t currentrendererstate;
typedef struct vrect_s typedef struct vrect_s
{ {
int x,y,width,height; int x,y,width,height;
struct vrect_s *pnext; // struct vrect_s *pnext;
} vrect_t; } vrect_t;
typedef struct typedef struct

View File

@ -25,11 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ctype.h> // for isdigit(); #include <ctype.h> // for isdigit();
#ifdef FISH
void R_RenderView_fisheye(void);
cvar_t ffov = SCVAR("ffov", "0"); cvar_t ffov = SCVAR("ffov", "0");
cvar_t fviews = SCVAR("fviews", "6");
#endif
/* /*
@ -96,6 +92,7 @@ cvar_t v_gunkick = SCVAR("v_gunkick", "0");
cvar_t v_gunkick_q2 = SCVAR("v_gunkick_q2", "1"); cvar_t v_gunkick_q2 = SCVAR("v_gunkick_q2", "1");
cvar_t v_viewheight = SCVAR("v_viewheight", "0"); cvar_t v_viewheight = SCVAR("v_viewheight", "0");
cvar_t v_projectionmode = SCVAR("v_projectionmode", "0");
cvar_t scr_autoid = SCVAR("scr_autoid", "1"); cvar_t scr_autoid = SCVAR("scr_autoid", "1");
@ -1201,11 +1198,9 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
case 3: case 3:
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2 if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2
#ifdef FISH && ffov.value >= 0 /*panoramic view always stacks player views*/
&& ffov.value >= 0
#endif
) )
{ //over twice as wide as high, assume duel moniter, horizontal. { //over twice as wide as high, assume dual moniter, horizontal.
vrect->width = vid.width/cl.splitclients; vrect->width = vid.width/cl.splitclients;
vrect->height = vid.height; vrect->height = vid.height;
vrect->x = 0 + vrect->width*pnum; vrect->x = 0 + vrect->width*pnum;
@ -1214,6 +1209,7 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
else else
#endif #endif
{ {
//stack them vertically
vrect->width = vid.width; vrect->width = vid.width;
vrect->height = vid.height/cl.splitclients; vrect->height = vid.height/cl.splitclients;
vrect->x = 0; vrect->x = 0;
@ -1341,7 +1337,7 @@ void V_RenderPlayerViews(int plnum)
r_secondaryview = 2; r_secondaryview = 2;
VectorSubtract(r_refdef.vieworg, desired_position[plnum], dir); VectorSubtract(r_refdef.vieworg, desired_position[plnum], dir);
vectoangles(dir, r_refdef.viewangles); VectorAngles(dir, NULL, r_refdef.viewangles);
r_refdef.viewangles[0] = -r_refdef.viewangles[0]; //flip the pitch. :( r_refdef.viewangles[0] = -r_refdef.viewangles[0]; //flip the pitch. :(
@ -1579,10 +1575,7 @@ void V_Init (void)
} }
#endif #endif
#ifdef FISH
Cvar_Register (&ffov, VIEWVARS); Cvar_Register (&ffov, VIEWVARS);
Cvar_Register (&fviews, VIEWVARS);
#endif
BuildGammaTable (1.0, 1.0); // no gamma yet BuildGammaTable (1.0, 1.0); // no gamma yet
Cvar_Register (&v_gamma, VIEWVARS); Cvar_Register (&v_gamma, VIEWVARS);

View File

@ -51,6 +51,8 @@ extern HINSTANCE global_hInstance;
extern int global_nCmdShow; extern int global_nCmdShow;
extern HWND sys_parentwindow; extern HWND sys_parentwindow;
extern unsigned int sys_parentleft;
extern unsigned int sys_parenttop;
extern unsigned int sys_parentwidth; extern unsigned int sys_parentwidth;
extern unsigned int sys_parentheight; extern unsigned int sys_parentheight;