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();
if (!cdValid)
{
#ifndef NOMEDIA
Media_FakeTrack(track, looping);
#endif
return;
}
}
@ -143,9 +140,6 @@ void CDAudio_Play(int track, qboolean looping)
if (track < 1 || track > maxTrack)
{
#ifndef NOMEDIA
Media_FakeTrack(track, looping);
#endif
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
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[2] = 32;
vectoangles(vec, v);
VectorAngles(vec, NULL, v);
// v[0] = -v[0];
VectorCopy (v, pmove.angles);
VectorNormalize(vec);
@ -409,7 +409,7 @@ void Cam_SelfTrack(int pnum)
VectorCopy(desired_position[pnum], r_refdef.vieworg);
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];
}
}
@ -509,7 +509,7 @@ void Cam_Track(int pnum, usercmd_t *cmd)
VectorCopy(desired_position[pnum], self->origin);
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];
}

View file

@ -568,8 +568,8 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
mod = &box_model;
else
mod = cl.model_precache[modhandle+1];
if (mod)
pc = cl.worldmodel->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
if (mod && !mod->needload)
pc = mod->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
else
pc = 1;//FTECONTENTS_SOLID;
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);
#else
{
#ifdef _MSC_VER
#pragma message("FIXME: G3 CGame requires TransformedNativeTrace!")
#ifdef warningmsg
#pragma warningmsg("FIXME: G3 CGame requires TransformedNativeTrace!")
#endif
memset(&tr, 0, sizeof(tr));
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:
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:
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:
pe->DelinkTrailstate(VM_POINTER(arg[0]));
break;

View file

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

View file

@ -85,8 +85,8 @@ qboolean CL_FilterModelindex(int modelindex, int frame)
void CL_FreeDlights(void)
{
#ifdef _MSC_VER
#pragma message("not freeing shadowmeshes")
#ifdef warningmsg
#pragma warningmsg("not freeing shadowmeshes")
#endif
rtlights_max = cl_maxdlights = 0;
BZ_Free(cl_dlights);
@ -103,12 +103,12 @@ static void CL_ClearDlight(dlight_t *dl, int key)
{
void *sm;
texid_t st;
st = dl->stexture;
TEXASSIGNF(st, dl->stexture);
sm = dl->worldshadowmesh;
memset (dl, 0, sizeof(*dl));
dl->rebuildcache = true;
dl->worldshadowmesh = sm;
dl->stexture = st;
TEXASSIGNF(dl->stexture, st);
dl->axis[0][0] = 1;
dl->axis[1][1] = 1;
dl->axis[2][2] = 1;
@ -305,7 +305,7 @@ CL_ParseDelta
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)
{
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
for (i=0 ; i<16 ; i++)
if (bits&(1<<i))
bitcounts[i]++;
// for (i=0 ; i<16 ; i++)
// if (bits&(1<<i))
// bitcounts[i]++;
#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)))
@ -757,6 +757,7 @@ void DP5_ParseDelta(entity_state_t *s)
if (bits & E5_FLAGS)
{
int i = MSG_ReadByte();
s->dpflags = i;
s->flags = 0;
if (i & RENDER_VIEWMODEL)
s->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK;
@ -1422,7 +1423,7 @@ void CLQ1_AddShadow(entity_t *ent)
"alphagen vertex\n"
"}\n"
"}\n");
s->defaulttextures.base = balltexture;
TEXASSIGN(s->defaulttextures.base, balltexture);
tx = ent->model->maxs[0] - ent->model->mins[0];
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"
"surfaceparm nodlight\n"
"{\n"
"map $whitetexture\n"
"map $whiteimage\n"
"rgbgen entity\n"
"alphagen entity\n"
"blendfunc src_alpha one\n"
@ -1548,7 +1549,7 @@ void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects
"noshadows\n"
"surfaceparm nodlight\n"
"{\n"
"map $whitetexture\n"
"map $whiteimage\n"
"rgbgen entity\n"
"alphagen entity\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.
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;
VectorCopy(le->neworigin, le->oldorigin);
VectorCopy(le->newangle, le->oldangle);
VectorCopy(snew->origin, le->neworigin);
VectorCopy(snew->angles, le->newangle);
}
@ -1932,7 +1933,6 @@ void CL_LinkPacketEntities (void)
float servertime;
CL_CalcClientTime();
if (cls.protocol == CP_QUAKEWORLD && (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV))
{
servertime = cl.servertime;
@ -1955,7 +1955,10 @@ void CL_LinkPacketEntities (void)
i = servertime*20;
if (flickertime != i)
{
flickertime = i;
flicker = rand();
}
autorotate = anglemod(100*servertime);
@ -2088,6 +2091,8 @@ void CL_LinkPacketEntities (void)
ent->flags |= Q2RF_ADDITIVE;
if (state->effects & EF_NODEPTHTEST)
ent->flags |= RF_NODEPTHTEST;
if (state->effects & DPEF_NOSHADOW)
ent->flags |= RF_NOSHADOW;
if (state->trans != 0xff)
ent->flags |= Q2RF_TRANSLUCENT;
@ -2154,7 +2159,7 @@ void CL_LinkPacketEntities (void)
#endif
// rotate binary objects locally
if (model && model->flags & EF_ROTATE)
if (model && model->flags & MF_ROTATE)
{
angles[0] = 0;
angles[1] = autorotate;
@ -2192,10 +2197,10 @@ void CL_LinkPacketEntities (void)
CLQ1_AddPowerupShell(ent, false, state->effects);
// 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;
if (!cls.allow_anyparticles && !(model->flags & ~EF_ROTATE))
if (!cls.allow_anyparticles && !(model->flags & ~MF_ROTATE))
continue;
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)
pe->ParticleTrailIndex(old_origin, ent->origin, model->traildefaultindex, 0, &(le->trailstate));
@ -2237,28 +2242,29 @@ void CL_LinkPacketEntities (void)
dclr[1] = 0.10;
dclr[2] = 0;
if (model->flags & EF_ROCKET)
if (model->flags & MF_ROCKET)
{
#ifdef _MSC_VER
#pragma message("Replace this flag on load for hexen2 models")
#ifdef warningmsg
#pragma warningmsg("Replace this flag on load for hexen2 models")
#endif
if (strncmp(model->name, "models/sflesh", 13))
{ //hmm. hexen spider gibs...
rad = 200;
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);
}
else if (model->flags & EFH2_ACIDBALL)
else if (model->flags & MFH2_ACIDBALL)
{
rad = 120 - (rand() % 20);
dclr[0] = 0.1;
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...
dclr[0] = -dclr[0];
@ -2273,7 +2279,7 @@ void CL_LinkPacketEntities (void)
memcpy(dl->axis, ent->axis, sizeof(dl->axis));
VectorCopy (ent->origin, dl->origin);
dl->die = (float)cl.time;
if (model->flags & EF_ROCKET)
if (model->flags & MF_ROCKET)
dl->origin[2] += 1; // is this even necessary
dl->radius = rad * r_rocketlight.value;
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
// from the last level
//
if (++cl.movemessages <= 2)
if (++cl.movemessages <= 2 || cls.state == ca_connected)
{
MSG_WriteByte (buf, clc_nop);
return;
}
MSG_WriteByte (buf, clc_move);
@ -1018,9 +1021,9 @@ void CL_AllowIndependantSendCmd(qboolean allow)
if (allowindepphys != allow && runningindepphys)
{
if (allow)
Sys_UnlockMutex(&indeplock);
Sys_UnlockMutex(indeplock);
else
Sys_LockMutex(&indeplock);
Sys_LockMutex(indeplock);
allowindepphys = allow;
}
}
@ -1043,11 +1046,11 @@ int CL_IndepPhysicsThread(void *param)
spare = 15;
time -= spare/1000.0f;
Sys_LockMutex(&indeplock);
Sys_LockMutex(indeplock);
if (cls.state)
CL_SendCmd(time - lasttime, false);
lasttime = time;
Sys_UnlockMutex(&indeplock);
Sys_UnlockMutex(indeplock);
}
fps = cl_netfps.value;
@ -1225,6 +1228,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf)
int checksumIndex, firstsize, plnum;
int clientcount, lost;
int curframe = cls.netchan.outgoing_sequence & UPDATE_MASK;
int st = buf->cursize;
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;
if (cl.sendprespawn)
buf->cursize = 0; //tastyspleen.net is alergic.
buf->cursize = st; //tastyspleen.net is alergic.
return dontdrop;
}
@ -1413,6 +1417,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
return; // sendcmds come from the demo
}
memset(&buf, 0, sizeof(buf));
buf.maxsize = sizeof(data);
buf.cursize = 0;
buf.data = data;
@ -1451,7 +1456,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
if (!runningindepphys)
{
// 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.
if (cls.netchan.remote_address.type == NA_IRC)
@ -1513,7 +1518,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
// if (skipcmd)
// 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
#ifdef NQPROT
@ -1527,14 +1532,14 @@ void CL_SendCmd (double frametime, qboolean mainloop)
next = clientcmdlist->next;
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;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, clientcmdlist->command);
}
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_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 cl_packagedownloads = CVAR("cl_packagedownloads", "1");
cvar_t cl_splitscreen = CVAR("cl_splitscreen", "0");
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_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_solid_players = CVAR("cl_solid_players", "1");
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 cl_antibunch = CVAR("cl_antibunch", "0");
cvar_t r_drawflame = CVAR("r_drawflame", "1");
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_gunanglez = SCVAR("cl_gunanglez", "0");
cvar_t allow_download_csprogs = SCVARF("allow_download_csprogs", "1", CVAR_NOTFROMSERVER);
cvar_t allow_download_redirection = SCVARF("allow_download_redirection", "0", CVAR_NOTFROMSERVER);
cvar_t requiredownloads = SCVARF("requiredownloads","1", CVAR_ARCHIVE);
cvar_t cl_download_csprogs = CVARFD("cl_download_csprogs", "1", CVAR_NOTFROMSERVER, "Download updated client gamecode if available.");
cvar_t cl_download_redirection = CVARFD("cl_download_redirection", "0", CVAR_NOTFROMSERVER, "Follow download redirection to download packages instead of individual files.");
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_item_bobbing = SCVAR("cl_model_bobbing", "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 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);
@ -636,6 +634,9 @@ char *CL_TryingToConnect(void)
return cls.servername;
}
int SV_NewChallenge (void);
client_t *SVC_DirectConnect(void);
/*
=================
CL_CheckForResend
@ -670,12 +671,26 @@ void CL_CheckForResend (void)
break;
#endif
default:
cl.movemessages = 0;
if (!strcmp(cl_loopbackprotocol.string, "qw"))
cls.protocol = CP_QUAKEWORLD;
else if (!strcmp(cl_loopbackprotocol.string, "nq"))
{
cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_ID;
}
else if (!strcmp(cl_loopbackprotocol.string, "q3"))
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)
cls.protocol = CP_QUAKEWORLD;
else
@ -695,8 +710,15 @@ void CL_CheckForResend (void)
}
NET_AdrToString(data, sizeof(data), adr);
//by NQ, we mean to try using the DP protocol extensions to the underlying NQ protocol
CL_ConnectToDarkPlaces("", adr);
if (cls.protocol_nq == CPNQ_ID)
{
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
CL_SendConnectPacket (svs.fteprotocolextensions, svs.fteprotocolextensions2, false);
@ -1458,6 +1480,41 @@ void CL_Color_f (void)
#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)
{
@ -1477,10 +1534,7 @@ void CL_CheckServerInfo(void)
cls.allow_skyboxes=false;
cls.allow_mirrors=false;
cls.allow_luma=false;
cls.allow_bump=false;
#ifdef FISH
cls.allow_fish=false;
#endif
cls.allow_postproc=false;
cls.allow_fbskins = 1;
// cls.allow_fbskins = 0;
// cls.allow_overbrightlight;
@ -1503,13 +1557,9 @@ void CL_CheckServerInfo(void)
if (cl.spectator || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_lmgamma")))
cls.allow_lightmapgamma=true;
s = Info_ValueForKey(cl.serverinfo, "allow_bump");
if (cl.spectator || cls.demoplayback || atoi(s) || !*s) //admin doesn't care.
cls.allow_bump=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, "allow_fish");
if (cl.spectator || cls.demoplayback || !*s || atoi(s))
cls.allow_postproc=true;
s = Info_ValueForKey(cl.serverinfo, "fbskins");
if (*s)
@ -1579,12 +1629,8 @@ void CL_CheckServerInfo(void)
//16
if (allowed & 32)
cls.allow_luma = true;
if (allowed & 64)
cls.allow_bump = true;
#ifdef FISH
if (allowed & 128)
cls.allow_fish = true;
#endif
cls.allow_postproc = true;
if (allowed & 256)
cls.allow_lightmapgamma = true;
if (allowed & 512)
@ -1613,6 +1659,17 @@ void CL_CheckServerInfo(void)
if (oldstate != cl.matchstate)
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);
Validation_Apply_Ruleset();
@ -2362,7 +2419,7 @@ void CL_ConnectionlessPacket (void)
CL_ParseEstablished();
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.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_ID;
@ -2503,6 +2560,7 @@ void CLNQ_ConnectionlessPacket(void)
{
char *s;
int length;
unsigned short port;
MSG_BeginReading (msg_nullnetprim);
length = LongSwap(MSG_ReadLong ());
@ -2521,8 +2579,11 @@ void CLNQ_ConnectionlessPacket(void)
Con_TPrintf (TLC_DUPCONNECTION);
return;
}
port = htons((unsigned short)MSG_ReadLong());
//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;
if (MSG_ReadByte() == 1) //a proquake server adds a little extra info
@ -2581,38 +2642,6 @@ void CL_ReadPackets (void)
// while (NET_GetPacket ())
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())
break;
@ -2844,7 +2873,7 @@ void CL_DownloadSize_f(void)
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);
CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags);
@ -3069,7 +3098,6 @@ void CL_Init (void)
Cvar_Register (&rcon_password, cl_controlgroup);
Cvar_Register (&rcon_address, cl_controlgroup);
Cvar_Register (&entlatency, cl_predictiongroup);
Cvar_Register (&cl_predict_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 (&allow_download_csprogs, cl_controlgroup);
Cvar_Register (&allow_download_redirection, cl_controlgroup);
Cvar_Register (&cl_download_csprogs, cl_controlgroup);
Cvar_Register (&cl_download_redirection, cl_controlgroup);
//
// info mirrors
@ -3113,7 +3141,7 @@ void CL_Init (void)
Cvar_Register (&model, cl_controlgroup);
Cvar_Register (&team, cl_controlgroup);
Cvar_Register (&topcolor, cl_controlgroup);
Cvar_Register (&bottomcolor, cl_controlgroup);
Cvar_Register (&bottomcolor, cl_controlgroup);
Cvar_Register (&rate, cl_controlgroup);
Cvar_Register (&drate, cl_controlgroup);
Cvar_Register (&msg, cl_controlgroup);
@ -3138,12 +3166,12 @@ void CL_Init (void)
Cvar_Register (&host_mapname, "Scripting");
Cvar_Register (&cl_packagedownloads, cl_controlgroup);
#ifndef SERVERONLY
Cvar_Register (&cl_loopbackprotocol, cl_controlgroup);
#endif
Cvar_Register (&cl_countpendingpl, cl_controlgroup);
Cvar_Register (&cl_threadedphysics, cl_controlgroup);
Cvar_Register (&cl_antibunch, "evil hacks");
Cvar_Register (&hud_tracking_show, "statusbar");
Cvar_Register (&cl_download_mapsrc, cl_controlgroup);
@ -3560,6 +3588,7 @@ double Host_Frame (double time)
// fetch results from server
CL_ReadPackets ();
CL_CalcClientTime();
// send intentions now
// resend a connection request if necessary

View file

@ -343,6 +343,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
return false;
}
/*reject if it already failed*/
if (!(flags & DLLF_IGNOREFAILED))
{
#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.
{
if (!strcmp(dl->rname, filename))
@ -398,7 +400,9 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
| PEXT_PK3DOWNLOADS
#endif
)))
{
CL_SendClientCommand(true, "dlsize \"%s\"", dl->rname);
}
if (flags & DLLF_VERBOSE)
Con_Printf("Enqued download of \"%s\"\n", filename);
@ -406,8 +410,8 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
return true;
}
#ifdef _MSC_VER
#pragma message("fix this")
#ifdef warningmsg
#pragma warningmsg("fix this")
#endif
int downloadsize;
void CL_GetDownloadSizes(unsigned int *filecount, unsigned int *totalsize, qboolean *somesizesunknown)
@ -528,7 +532,17 @@ void CL_DownloadFinished(void)
{
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))
{
@ -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();
CL_CheckServerInfo();
}
else if (!strcmp(filename, "gfx/palette.lmp"))
{
Cbuf_AddText("vid_restart\n", RESTRICT_LOCAL);
@ -614,6 +631,23 @@ qboolean CL_CheckFile(char *filename)
}
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
@ -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)
{ //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)
localname = filename;
#ifndef CLIENTONLY
/*no downloading if we're the one we'd be downloading from*/
if (sv.state)
return true;
#endif
if (!(flags & DLLF_OVERWRITE) && CL_CheckFile(localname))
return true;
if (!(flags & DLLF_OVERWRITE))
{
if (CL_CheckDLFile(localname))
return true;
}
//ZOID - can't download when recording
if (cls.demorecording)
@ -886,7 +935,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
extern model_t *loadmodel;
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 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");
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);
if (allow_download_csprogs.ival)
if (cl_download_csprogs.ival)
{
char *str = va("csprogsvers/%x.dat", chksum);
if (CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED))
@ -934,7 +983,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
{
char *s;
qboolean anycsqc;
#if 0//ndef FTE_DEBUG
#ifdef _DEBUG
anycsqc = true;
#else
anycsqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc"));
@ -1187,12 +1236,12 @@ void Sound_CheckDownloads (void)
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
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);
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);
CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED);
@ -1221,9 +1270,11 @@ void CL_RequestNextDownload (void)
{
int stage;
/*already downloading*/
if (cls.downloadmethod)
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.downloadlist)
{
@ -1233,16 +1284,25 @@ void CL_RequestNextDownload (void)
//download required downloads first
for (dl = cl.downloadlist; dl; dl = dl->next)
{
if (dl->flags & DLLF_REQUIRED)
if (dl->flags & DLLF_NONGAME)
break;
}
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;
/*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 ((fl & DLLF_OVERWRITE) || !COM_FCheckExists (dl->localname))
if ((fl & DLLF_OVERWRITE) || !CL_CheckFile (dl->localname))
{
CL_SendDownloadStartRequest(dl->rname, dl->localname);
return;
@ -1283,10 +1343,8 @@ void CL_RequestNextDownload (void)
return;
cl.sendprespawn = false;
#ifdef _MSC_VER
//FIXME: timedemo timer should start here.
#else
#warning timedemo timer should start here
#ifdef warningmsg
#pragma warningmsg("timedemo timer should start here")
#endif
if (!cl.worldmodel || cl.worldmodel->needload)
@ -1342,8 +1400,24 @@ void CL_SendDownloadReq(sizebuf_t *msg)
if (cls.downloadmethod == DL_QWCHUNKS)
{
extern int download_file_number;
extern cvar_t drate;
static float lasttime;
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();
if (i >= 0)
@ -1424,6 +1498,12 @@ downloadlist_t *CL_DownloadFailed(char *name)
{
VFS_CLOSE(cls.downloadqw);
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");
}
*cls.downloadlocalname = 0;
@ -1449,11 +1529,14 @@ downloadlist_t *CL_DownloadFailed(char *name)
float downloadstarttime;
#ifdef PEXT_CHUNKEDDOWNLOADS
#define MAXBLOCKS 64 //must be power of 2
#define MAXBLOCKS 512 //must be power of 2
#define DLBLOCKSIZE 1024
int downloadsize;
int receivedbytes;
int recievedblock[MAXBLOCKS];
struct
{
int chunkno;
} dlblock[MAXBLOCKS];
int firstblock;
int blockcycle;
int download_file_number;
@ -1468,7 +1551,7 @@ void CL_ParseChunkedDownload(void)
qbyte *svname;
//qbyte osname[MAX_OSPATH]; //unreferenced
int totalsize;
int chunknum;
int chunknum, ridx;
char data[DLBLOCKSIZE];
chunknum = MSG_ReadLong();
@ -1527,7 +1610,12 @@ void CL_ParseChunkedDownload(void)
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);
cls.downloadqw = FS_OpenVFS (va("qw/%s", cls.downloadtempname), "wb", FS_ROOT);
@ -1548,7 +1636,8 @@ void CL_ParseChunkedDownload(void)
firstblock = 0;
receivedbytes = 0;
blockcycle = -1; //so it requests 0 first. :)
memset(recievedblock, 0, sizeof(recievedblock));
for (chunknum = 0; chunknum < MAXBLOCKS; chunknum++)
dlblock[chunknum].chunkno = ~0u;
return;
}
@ -1563,31 +1652,21 @@ void CL_ParseChunkedDownload(void)
{ //err, yeah, when playing demos we don't actually pay any attention to this.
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;
}
dlblock[ridx].chunkno = ~0;
// Con_Printf("usable\n", chunknum);
receivedbytes+=DLBLOCKSIZE;
recievedblock[chunknum&(MAXBLOCKS-1)] = true;
while(recievedblock[firstblock&(MAXBLOCKS-1)])
{
recievedblock[firstblock&(MAXBLOCKS-1)] = false;
firstblock++;
}
VFS_SEEK(cls.downloadqw, chunknum*DLBLOCKSIZE);
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 i;
int b;
int ridx;
if (cls.downloadmethod != DL_QWCHUNKS)
{
@ -1619,18 +1698,17 @@ int CL_RequestADownloadChunk(void)
return -1;
}
blockcycle++;
for (i = 0; i < MAXBLOCKS; i++)
{
b = ((i+blockcycle)&(MAXBLOCKS-1))
+ firstblock;
if (!recievedblock[b&(MAXBLOCKS-1)]) //don't ask for ones we've already got.
blockcycle++;
ridx = blockcycle&(MAXBLOCKS-1);
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;
// Con_Printf("Requesting block %i\n", b);
return b;
dlblock[ridx].chunkno = firstblock++;
}
return dlblock[ridx].chunkno;
}
// 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;
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)
{
//darkplaces5
@ -2502,7 +2598,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
}
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
{
@ -2545,7 +2641,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
}
strcpy (cl.model_name[nummodels], str);
if (*str != '*') //not inline models!
CL_CheckOrEnqueDownloadFile(str, NULL, 0);
CL_CheckOrEnqueDownloadFile(str, NULL, ((nummodels==1)?DLLF_REQUIRED:0));
Mod_TouchModel (str);
}
@ -2562,10 +2658,8 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
}
strcpy (cl.sound_name[numsounds], str);
#ifdef _MSC_VER
#pragma message("CLNQ_ParseServerData: no sound autodownloads")
#endif
//CL_CheckOrEnqueDownloadFile(str, NULL, 0);
if (*str != '*') //not inline models!
CL_CheckOrEnqueDownloadFile(va("sound/%s", str), NULL, 0);
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);
}
}
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))
{
int i;

View file

@ -665,15 +665,35 @@ void CL_CalcClientTime(void)
}
else
{
want = cl.oldgametime + (realtime - cl.gametimemark);
if (want>cl.servertime)
cl.servertime = want;
oldst = cl.servertime;
cl.servertime += host_frametime;
if (cl.servertime > cl.gametime)
{
cl.servertime = cl.gametime;
// Con_Printf("clamped to new time\n");
}
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)
{
int i;
@ -682,6 +702,7 @@ void CL_CalcClientTime(void)
cl.players[i].entertime += cl.servertime;
}
}
return;
}
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]))
return;
CL_CalcClientTime();
if (cl.intermission && cl.intermission != 3 && cls.protocol == CP_QUAKEWORLD)
{
cl.crouch[pnum] = 0;
@ -885,7 +904,7 @@ fixedorg:
cl.onground[pnum] = pmove.onground;
if (to->senttime >= cl.time)
if (to->senttime >= realtime)
break;
from = to;
}
@ -895,7 +914,7 @@ fixedorg:
from = to;
to = &ind;
to->cmd[pnum] = independantphysics[pnum];
to->senttime = cl.time;
to->senttime = realtime;
CL_PredictUsercmd (pnum, &from->playerstate[cl.playernum[pnum]]
, &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
@ -918,7 +937,7 @@ fixedorg:
f = 0;
else
{
f = (cl.time - from->senttime) / (to->senttime - from->senttime);
f = (realtime - from->senttime) / (to->senttime - from->senttime);
if (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 crosshair;
extern cvar_t scr_consize;
cvar_t scr_neticontimeout = CVAR("scr_neticontimeout", "0.3");
qboolean scr_initialized; // ready to draw
@ -238,6 +239,7 @@ void CLSCR_Init(void)
Cvar_Register(&show_speed, cl_screengroup);
Cvar_Register(&show_speed_x, 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;
vrect_t rect;
SCR_VRectForPlayer(&rect, pnum);
rect = r_refdef.vrect;
if (cl.worldmodel && crosshaircorrect.ival)
{
@ -1136,7 +1138,7 @@ SCR_DrawNet
*/
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;
if (cls.demoplayback || !scr_net)
return;
@ -1776,8 +1778,8 @@ qboolean SCR_ScreenShot (char *filename)
ext = COM_FileExtension(filename);
buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight);
#ifdef _MSC_VER
#pragma message("Need to ensure that the various image writing routines can cope with ((width|height)&3")
#ifdef warningmsg
#pragma warningmsg("Need to ensure that the various image writing routines can cope with ((width|height)&3")
#endif
if (!buffer)

View file

@ -175,6 +175,7 @@ typedef struct
{
int entity;
short tag;
qbyte active;
qbyte flags;
qbyte type;
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++)
if (b->entity == entity && b->tag == tag)
{
b->active = true;
return b;
}
}
@ -578,8 +580,9 @@ beam_t *CL_NewBeam (int entity, int tag)
// find a free beam
for (i=0, b=cl_beams; i < beams_running; i++, b++)
{
if (!b->model)
if (!b->active)
{
b->active = true;
return b;
}
}
@ -587,6 +590,7 @@ beam_t *CL_NewBeam (int entity, int tag)
if (i == beams_running && i != MAX_BEAMS)
{
beams_running++;
cl_beams[i].active = true;
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;
vec3_t impact, normal;
vec3_t extra;
char *mname;
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.
{
// 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);
return;
}
default:
m = Mod_ForName("progs/bolt.mdl", false);
mname = "progs/bolt.mdl";
btype = rtfte_lightning1;
etype = ptfte_lightning1_end;
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.
{
case 5:
m = Mod_ForName("progs/beam.mdl", false); //remember to precache!
mname = "progs/beam.mdl"; //remember to precache!
btype = P_FindParticleType("te_beam");
etype = P_FindParticleType("te_beam_end");
}
else
{
m = Mod_ForName("progs/bolt2.mdl", false);
mname = "progs/bolt2.mdl";
btype = rtfte_lightning2;
etype = ptfte_lightning2_end;
}
break;
case 2:
m = Mod_ForName("progs/bolt3.mdl", false);
mname = "progs/bolt3.mdl";
btype = rtfte_lightning3;
etype = ptfte_lightning3_end;
break;
#ifdef Q2CLIENT
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");
etype = P_FindParticleType("te_parasite_attack_end");
break;
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");
etype = P_FindParticleType("te_grapple_cable_end");
break;
#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);
// 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->model = m;
b->particleeffect = btype;
b->tag = -1;
b->flags |= /*STREAM_ATTACHED|*/1;
b->endtime = cl.time + 0.2;
b->alpha = 1;
b->particleeffect = btype;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
@ -765,6 +776,7 @@ void CL_ParseStream (int type)
b->tag = tag;
b->flags = flags;
b->model = NULL;
b->particleeffect = -1;
b->endtime = cl.time + duration;
b->alpha = 1;
b->skin = skin;
@ -1282,8 +1294,8 @@ void CL_ParseTEnt (void)
pos2[1] = MSG_ReadCoord ();
pos2[2] = MSG_ReadCoord ();
if (P_ParticleTrail(pos, pos2, rtqw_railtrail, NULL))
if (P_ParticleTrail(pos, pos2, rtq2_railtrail, NULL))
if (P_ParticleTrail(pos, pos2, rtqw_railtrail, 0, NULL))
if (P_ParticleTrail(pos, pos2, rtq2_railtrail, 0, NULL))
P_ParticleTrailIndex(pos, pos2, 208, 8, NULL);
break;
@ -1421,7 +1433,7 @@ void CL_ParseTEnt (void)
// stain (Hopefully this is close to how DP does it)
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);
break;
@ -1439,7 +1451,7 @@ void CL_ParseTEnt (void)
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);
break;
@ -1634,7 +1646,7 @@ void CL_ParseCustomTEnt(void)
{
MSG_ReadPos (pos);
MSG_ReadPos (pos2);
failed = P_ParticleTrail(pos, pos2, t->particleeffecttype, NULL);
failed = P_ParticleTrail(pos, pos2, t->particleeffecttype, 0, NULL);
}
else
{
@ -1736,8 +1748,8 @@ void CLDP_ParseTrailParticles(void)
ts = NULL;
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
if (P_ParticleTrail(start, end, effectindex, ts))
P_ParticleTrail(start, end, rt_blood, ts);
if (P_ParticleTrail(start, end, effectindex, entityindex, ts))
P_ParticleTrail(start, end, rt_blood, entityindex, ts);
}
void CLDP_ParsePointParticles(qboolean compact)
@ -2111,7 +2123,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_RAILTRAIL: // railgun effect
MSG_ReadPos (pos);
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);
Q2S_StartSound (pos, 0, 0, S_PrecacheSound ("weapons/railgf1a.wav"), 1, ATTN_NORM, 0);
break;
@ -2321,7 +2333,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_BUBBLETRAIL:
MSG_ReadPos (pos);
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);
break;
@ -2496,7 +2508,7 @@ void CLQ2_ParseTEnt (void)
case Q2TE_DEBUGTRAIL:
MSG_ReadPos (pos);
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);
break;
@ -2800,7 +2812,7 @@ void CL_UpdateBeams (void)
// update lightning
for (bnum=0, b=cl_beams; bnum < beams_running; bnum++, b++)
{
if (!b->model)
if (!b->active)
continue;
if (b->endtime < cl.time)
@ -2809,7 +2821,7 @@ void CL_UpdateBeams (void)
{ /*don't let lightning decay while paused*/
P_DelinkTrailstate(&b->trailstate);
P_DelinkTrailstate(&b->emitstate);
b->model = NULL;
b->active = false;
continue;
}
}
@ -2851,7 +2863,7 @@ void CL_UpdateBeams (void)
VectorSubtract (playerbeam_end[j], vieworg, org);
len = VectorLength(org);
org[2] -= 22; // adjust for view height
vectoangles (org, ang);
VectorAngles (org, NULL, ang);
// lerp pitch
ang[0] = -ang[0];
@ -2926,9 +2938,11 @@ void CL_UpdateBeams (void)
pitch += 360;
}
if (ruleset_allow_particle_lightning.ival)
if (b->particleeffect >= 0 && !P_ParticleTrail(b->start, b->end, b->particleeffect, &b->trailstate))
if (ruleset_allow_particle_lightning.ival || !b->model)
if (b->particleeffect >= 0 && !P_ParticleTrail(b->start, b->end, b->particleeffect, b->entity, &b->trailstate))
continue;
if (!b->model)
continue;
// add new entities for the lightning
VectorCopy (b->start, org);

View file

@ -261,6 +261,11 @@ typedef struct dlight_s
float minlight; // don't add when contributing less
float color[3];
float channelfade[3];
float ambientscale;
float diffusescale;
float specularscale;
float corona;
float coronascale;
unsigned int flags;
@ -411,11 +416,8 @@ typedef struct
qboolean allow_mirrors;
qboolean allow_watervis;
qboolean allow_luma;
qboolean allow_bump;
float allow_fbskins; //fraction of allowance
#ifdef FISH
qboolean allow_fish;
#endif
qboolean allow_postproc;
qboolean allow_cheats;
qboolean allow_semicheats; //defaults to true, but this allows a server to enforce a strict ruleset (smackdown type rules).
float maxfps; //server capped
@ -436,11 +438,12 @@ typedef struct downloadlist_s {
char localname[128];
unsigned int size;
unsigned int flags;
#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_OVERWRITE 4 //overwrite it even if it already exists
#define DLLF_SIZEUNKNOWN 8
#define DLLF_IGNOREFAILED 16
#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_OVERWRITE 4 //overwrite it even if it already exists
#define DLLF_SIZEUNKNOWN 8 //download's size isn't known
#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;
} downloadlist_t;
@ -487,6 +490,9 @@ typedef struct
qboolean allowsendpacket;
char serverinfo[MAX_SERVERINFO_STRING];
char serverpaknames[1024];
char serverpakcrcs[1024];
qboolean serverpakschanged;
int parsecount; // server message counter
int oldparsecount;
@ -1094,7 +1100,7 @@ void Cam_TrackPlayer(int pnum, char *cmdname, char *plrarg);
void Cam_Lock(int pnum, int playernum);
void CL_InitCam(void);
void QDECL vectoangles(vec3_t vec, vec3_t ang);
void QDECL vectoangles(vec3_t fwd, vec3_t ang);
//
//zqtp.c
@ -1237,7 +1243,7 @@ void Media_Init(void);
qboolean Media_PlayFilm(char *name);
typedef struct cin_s cin_t;
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);
qboolean Media_FakeTrack(int i, qboolean loop);

View file

@ -1007,6 +1007,11 @@ void CLQ2_ParseFrame (void)
cl.q2frame.deltaframe = MSG_ReadLong ();
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 ();
for (j=0 ; j<i ; j++)
@ -1579,8 +1584,8 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
{
if (effects & Q2EF_ROCKET)
{
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_rocket, &cent->trailstate))
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_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, ent.keynum, &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);
@ -1597,7 +1602,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
}
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);
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)
{
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_gib, &cent->trailstate))
if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_blood, &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, ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xe8, 8, &cent->trailstate);
}
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, rt_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, ent.keynum, &cent->trailstate))
P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 4, 8, &cent->trailstate);
}
else if (effects & Q2EF_FLIES)
@ -1651,13 +1656,13 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
}
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);
V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.05, 0.05);
}
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);
V_AddLight (ent.keynum, ent.origin, 225, 0.05, 0.05, 0.2);
}
@ -1665,7 +1670,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
//ROGUE
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);
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)
{
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);
V_AddLight (ent.keynum, ent.origin, 200, -0.2, -0.2, -0.2);
}
@ -1697,13 +1702,13 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
// RAFAEL
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);
}
// RAFAEL
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);
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)
{
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);
}

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);
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_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_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);
@ -2168,7 +2168,7 @@ typedef struct {
} 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_max;
@ -2216,7 +2216,7 @@ texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize)
if (!qglCompressedTexImage2DARB)
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);
datasize = fmtheader.dwPitchOrLinearSize;
@ -2233,12 +2233,12 @@ texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize)
h = 1;
qglCompressedTexImage2DARB(GL_TEXTURE_2D, mipnum, intfmt, w, h, 0, datasize, buffer);
if (qglGetError())
Con_Printf("Incompatible dds file (mip %i)\n", mipnum);
Con_Printf("Incompatible dds file %s (mip %i)\n", iname, mipnum);
buffer += datasize;
datasize/=4;
}
if (qglGetError())
Con_Printf("Incompatible dds file\n");
Con_Printf("Incompatible dds file %s\n", iname);
if (nummips>1)
@ -2355,7 +2355,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
image_width = 0;
image_height = 0;
COM_StripAllExtensions(name, nicename, sizeof(nicename));
COM_StripExtension(name, nicename, sizeof(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)))
{
#ifdef DDS
tex = GL_LoadTextureDDS(buf, com_filesize);
tex = GL_LoadTextureDDS(fname, buf, com_filesize);
if (TEXVALID(tex))
{
BZ_Free(buf);
@ -2494,7 +2494,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
if ((buf = COM_LoadFile (fname, 5)))
{
extern cvar_t vid_hardwaregamma;
tex = r_nulltex;
TEXASSIGNF(tex, r_nulltex);
if (com_filesize >= 8)
{
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.
{
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);
}
else

View file

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

View file

@ -2083,7 +2083,9 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
switch (bulk->variant)
{
case -1: // end of menu
default:
bulk = NULL;
control = NULL;
continue;
case 0: // white text
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;
case 2: // spacing
spacing = bulk->spacing;
control = NULL;
break;
}
break;
@ -2149,11 +2152,11 @@ int MC_AddBulk(struct menu_s *menu, menubulk_t *bulk, int xstart, int xtextend,
if (bulk->ret)
*bulk->ret = control;
if (MI_Selectable(control) && !selected)
if (control && MI_Selectable(control) && !selected)
selected = control;
if (bulk->tooltip)
if (control && bulk->tooltip)
control->common.tooltip = bulk->tooltip;
if (xleft > 0)
if (control && xleft > 0)
control->common.extracollide = xleft;
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)
{
#ifdef _MSC_VER
#pragma message("NM_PrintColoured: needs reimplementing")
#ifdef warningmsg
#pragma warningmsg("NM_PrintColoured: needs reimplementing")
#endif
/*
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)
{
#ifdef _MSC_VER
#pragma message("NM_PrintHighlighted: needs reimplementing")
#ifdef warningmsg
#pragma warningmsg("NM_PrintHighlighted: needs reimplementing")
#endif
/*
while (*str)
@ -265,8 +265,8 @@ int M_AddColumn (int right, int y, char *text, int maxchars, int colour, int hig
right = left;
#ifdef _MSC_VER
#pragma message("M_AddColumn: needs reimplementing")
#ifdef warningmsg
#pragma warningmsg("M_AddColumn: needs reimplementing")
#endif
/*
if (highlight >= 0)

View file

@ -1755,7 +1755,7 @@ qboolean Media_ShowFilm(void)
}
#if defined(GLQUAKE) || defined(D3DQUAKE)
texid_t Media_UpdateForShader(cin_t *cin)
texid_tf Media_UpdateForShader(cin_t *cin)
{
if (!cin)
return r_nulltex;
@ -1767,7 +1767,7 @@ texid_t Media_UpdateForShader(cin_t *cin)
if (!cin->outunchanged)
{
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);
}

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("Load Locs", tp_loadlocs, 0, "Whether to load teamplay locations from .loc files"),
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_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"),
@ -935,7 +935,7 @@ void M_Menu_Network_f (void)
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;
menu_t *menu;
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_SPACING(4),
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("Download CSQC", allow_download_csprogs, 0, "Whether to allow the client to download CSQC (client-side QuakeC) progs from servers"),
MB_CHECKBOXCVARTIP("Redirect Download", cl_download_redirection, 0, "Whether the client will ignore download redirection 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_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_COMBOCVAR("Split-screen", cl_splitscreen, splitopts, splitvalues, "Enables split screen with a number of clients. This feature requires server support."),
MB_END()

View file

@ -426,7 +426,6 @@ const char *presetexec[] =
"r_nolightdir 1;"
"r_dynamic 0;"
"gl_flashblend 0;"
"gl_bump 0;"
"gl_specular 0;"
"r_loadlit 0;"
"r_fastsky 1;"
@ -466,7 +465,6 @@ const char *presetexec[] =
"r_particlesystem script;"
"r_particledesc \"spikeset tsshaft\";"
#endif
// "gl_bump 1;" // requires restart
"gl_specular 1;"
"r_loadlit 2;"
// "r_fastsky -1;"
@ -699,7 +697,7 @@ void M_Menu_Textures_f (void)
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;
int y;
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("Anisotropy", gl_texture_anisotropic_filtering, anisotropylevels, anisotropyvalues, NULL),
MB_SPACING(4),
MB_CHECKBOXCVAR("Bumpmapping", gl_bump, 0),
MB_CHECKBOXCVAR("Deluxemapping", r_deluxemapping, 0),
MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0),
MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0),
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_FunStringWidth(int x, int y, const void *str, int width);
int r_regsequence;
#ifdef SERVERONLY
#define Mod_Q1LeafPVS Mod_LeafPVS
// qbyte *Mod_LeafPVS (struct mleaf_s *leaf, struct model_s *model, qbyte *buffer);
#endif
typedef union {
unsigned int num;
typedef struct
{
int regsequence;
} texcom_t;
struct texid_s
{
union
{
unsigned int num;
#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
} texid_t;
typedef enum uploadfmt uploadfmt_t;
//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented)
typedef enum backendmode_e
@ -182,12 +205,12 @@ typedef struct rendererinfo_s {
void (*Draw_Init) (void);
void (*Draw_Shutdown) (void);
texid_t (*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_t (*IMG_LoadTexture8Pal32) (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t (*IMG_LoadCompressed) (char *name);
texid_t (*IMG_FindTexture) (char *identifier);
texid_t (*IMG_AllocNewTexture) (int w, int h);
texid_tf (*IMG_LoadTexture) (char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);
texid_tf (*IMG_LoadTexture8Pal24) (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_tf (*IMG_LoadTexture8Pal32) (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_tf (*IMG_LoadCompressed) (char *name);
texid_tf (*IMG_FindTexture) (char *identifier);
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_DestroyTexture) (texid_t tex);
@ -248,6 +271,7 @@ typedef struct rendererinfo_s {
//Uploads all modified lightmaps
void (*BE_UploadAllLightmaps)(void);
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*/
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_LightCullModel rf->BE_LightCullModel
#define BE_SelectEntity rf->BE_SelectEntity
#define BE_SelectDLight rf->BE_SelectDLight
#define BE_GetTempBatch rf->BE_GetTempBatch
#define BE_SubmitBatch rf->BE_SubmitBatch
#define BE_DrawMesh_List rf->BE_DrawMesh_List

View file

@ -591,8 +591,8 @@ void Master_AddMaster (char *address, int type, char *description)
return;
}
#ifdef _MSC_VER
#pragma message("Master_AddMaster: add ipv6. don't care about tcp/irc.")
#ifdef warningmsg
#pragma warningmsg("Master_AddMaster: add ipv6. don't care about tcp/irc.")
#endif
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;
struct sockaddr_qstorage addr;
#ifdef _MSC_VER
#pragma message("NET_SendPollPacket: no support for ipv6")
#ifdef warningmsg
#pragma warningmsg("NET_SendPollPacket: no support for ipv6")
#endif
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 "renderque.h"
#define POLYS
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};
#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
static vecV_t classicverts[BUFFERVERTS];
static union c
@ -93,6 +95,7 @@ static union c
static vec2_t classictexcoords[BUFFERVERTS];
static index_t classicindexes[BUFFERVERTS];
mesh_t classicmesh;
#endif
static shader_t *classicshader;
@ -197,6 +200,7 @@ static qboolean PClassic_InitParticles (void)
particles = (cparticle_t *) BZ_Malloc (r_numparticles * sizeof(cparticle_t));
#ifndef POLYS
for (i = 0; i < BUFFERVERTS; i += 3)
{
classictexcoords[i+1][0] = 1;
@ -210,6 +214,7 @@ static qboolean PClassic_InitParticles (void)
classicmesh.st_array = classictexcoords;
classicmesh.colors4b_array = (byte_vec4_t*)classiccolours;
classicmesh.indexes = classicindexes;
#endif
classicshader = R_RegisterShader("particles_classic",
"{\n"
"nomipmaps\n"
@ -221,7 +226,7 @@ static qboolean PClassic_InitParticles (void)
"}\n"
"}\n"
);
classicshader->defaulttextures.base = particlecqtexture;
TEXASSIGN(classicshader->defaulttextures.base, particlecqtexture);
return true;
}
@ -279,8 +284,13 @@ static void PClassic_DrawParticles(void)
float time2, time3, time1, dvel, frametime, grav;
vec3_t up, right;
float dist, scale, r_partscale=0;
union c usecolours;
unsigned int *palette;
#ifdef POLYS
scenetris_t *scenetri;
#else
union c usecolours;
#endif
static float oldtime;
RSpeedMark();
/*#ifdef D3DQUAKE
@ -302,7 +312,9 @@ static void PClassic_DrawParticles(void)
VectorScale (vup, 1.5, up);
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)
frametime = 0;
time3 = frametime * 15;
@ -311,6 +323,25 @@ static void PClassic_DrawParticles(void)
grav = frametime * 800 * 0.05;
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)
{
kill = active_particles;
@ -339,6 +370,49 @@ static void PClassic_DrawParticles(void)
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)
{
classicmesh.numindexes = classicmesh.numvertexes;
@ -346,11 +420,6 @@ static void PClassic_DrawParticles(void)
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;
if (p->type == pt_fire)
usecolours.b[3] = 255 * (6 - p->ramp) / 6;
@ -365,9 +434,7 @@ static void PClassic_DrawParticles(void)
classiccolours[classicmesh.numvertexes].i = usecolours.i;
VectorMA(p->org, scale, right, classicverts[classicmesh.numvertexes]);
classicmesh.numvertexes++;
#endif
p->org[0] += p->vel[0] * frametime;
p->org[1] += p->vel[1] * frametime;
@ -421,14 +488,14 @@ static void PClassic_DrawParticles(void)
break;
}
}
#ifndef POLYS
if (classicmesh.numvertexes)
{
classicmesh.numindexes = classicmesh.numvertexes;
BE_DrawMesh_Single(classicshader, &classicmesh, NULL, &classicshader->defaulttextures, 0);
classicmesh.numvertexes = 0;
}
#endif
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.
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;

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_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 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){}

View file

@ -246,7 +246,7 @@ typedef struct part_type_s {
vec3_t dl_rgb;
float dl_radius;
float dl_time;
vec3_t dl_decay;
vec4_t dl_decay;
vec3_t stain_rgb;
float stain_radius;
@ -534,7 +534,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
// "polygonoffset\n"
"}\n"
;
break;
@ -549,7 +549,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
// "polygonoffset\n"
"}\n"
;
break;
@ -564,7 +564,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
// "polygonoffset\n"
"}\n"
;
break;
@ -579,7 +579,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
// "polygonoffset\n"
"}\n"
;
break;
@ -594,7 +594,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
// "polygonoffset\n"
"}\n"
;
break;
@ -616,26 +616,26 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
{
/*untextured beams get a single continuous blob*/
ptype->looks.shader = R_RegisterShader(va("beam%s", namepostfix), defaultshader);
tn.base = beamtexture;
TEXASSIGNF(tn.base, beamtexture);
}
else if (ptype->looks.type == PT_SPARKFAN)
{
/*untextured beams get a single continuous blob*/
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)
{
/*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*/
ptype->looks.shader = R_RegisterShader(va("ball%s", namepostfix), defaultshader);
tn.base = balltexture;
TEXASSIGNF(tn.base, balltexture);
}
else
{
/*anything else gets a fuzzy texture*/
ptype->looks.shader = R_RegisterShader(va("default%s", namepostfix), defaultshader);
tn.base = explosiontexture;
TEXASSIGNF(tn.base, explosiontexture);
}
}
else
@ -680,7 +680,52 @@ static void P_ParticleEffect_f(void)
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)
{
Con_Printf("Bad name\n");
@ -811,6 +856,7 @@ static void P_ParticleEffect_f(void)
else if (!strcmp(var, "beamtexstep"))
{
ptype->rotationstartmin = 1/atof(value);
ptype->rotationstartrand = 0;
setbeamlen = true;
}
else if (!strcmp(var, "beamtexspeed"))
@ -1247,6 +1293,25 @@ static void P_ParticleEffect_f(void)
ptype->flags |= PT_NOSPREADFIRST;
else if (!strcmp(var, "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
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;
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)
{
@ -2306,10 +2371,11 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir)
}
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[1] = ptype->dl_decay[1];
dl->channelfade[2] = ptype->dl_decay[2];
dl->decay = ptype->dl_decay[3];
}
if (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)
{
PScript_EffectSpawned(ptype, org, dir);
PScript_EffectSpawned(ptype, org, dir, 0);
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;
float len;
@ -3187,14 +3253,14 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
else
ts = NULL;
PScript_EffectSpawned(ptype, start, vec3_origin);
PScript_EffectSpawned(ptype, start, vec3_origin, dlkey);
if (ptype->assoc>=0)
{
if (ts)
P_ParticleTrail(start, end, ptype->assoc, &(ts->assoc));
P_ParticleTrail(start, end, ptype->assoc, dlkey, &(ts->assoc));
else
P_ParticleTrail(start, end, ptype->assoc, NULL);
P_ParticleTrail(start, end, ptype->assoc, dlkey, NULL);
}
// time limit for trails
@ -3608,14 +3674,14 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
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];
// TODO: fallback particle system won't have a decent trailstate which will mess up
// high fps trails
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)
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];
}
P_ParticleTrailDraw (startpos, end, ptype, tsk);
P_ParticleTrailDraw (startpos, end, ptype, tsk, dlkey);
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].colorrand = crnd;
P_ParticleTrail(start, end, pe_defaulttrail, tsk);
P_ParticleTrail(start, end, pe_defaulttrail, 0, tsk);
}
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)
{
#ifdef _MSC_VER
#pragma message("fixme: no line sparks")
#ifdef warningmsg
#pragma warningmsg("fixme: no line sparks")
#endif
#if 0
particle_t *p;
@ -3810,6 +3876,89 @@ static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *ty
#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)
{
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);
VectorNormalize(v);
CrossProduct(c->dir, v, cr);
VectorNormalize(cr);
ts = c->texture_s*q->angle + particletime*q->rotationspeed;
Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+0]);
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);
VectorNormalize(v);
CrossProduct(b->dir, v, cr); // replace with old p->dir?
VectorNormalize(cr);
ts = b->texture_s*p->angle + particletime*p->rotationspeed;
Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]);
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)
{
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);
void *pdraw, *bdraw;
void (*tdraw)(scenetris_t *t, particle_t *p, plooks_t *type);
vec3_t oldorg;
vec3_t stop, normal;
@ -3987,6 +4218,7 @@ static void PScript_DrawParticleTypes (void)
ramp_t *ramp;
float grav;
vec3_t friction;
scenetris_t *scenetri;
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
//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;
pdraw = NULL;
tdraw = NULL;
// set drawing methods by type and cvars and hope branch
// prediction takes care of the rest
@ -4131,6 +4364,7 @@ static void PScript_DrawParticleTypes (void)
break;
case PT_NORMAL:
pdraw = GL_DrawTexturedParticle;
tdraw = R_AddTexturedParticle;
break;
case PT_SPARK:
pdraw = sparklineparticles;
@ -4140,9 +4374,29 @@ static void PScript_DrawParticleTypes (void)
break;
case PT_TEXTUREDSPARK:
pdraw = sparktexturedparticles;
tdraw = R_AddTSparkParticle;
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)
{
while ((p=type->particles))
@ -4358,7 +4612,7 @@ static void PScript_DrawParticleTypes (void)
if (type->emit >= 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)
{
p->state.nextemit = particletime + type->emittime + frandom()*type->emitrand;
@ -4387,16 +4641,18 @@ static void PScript_DrawParticleTypes (void)
p->vel[2] *= type->clipbounce;
if (!*type->texname && Length(p->vel)<1000*pframetime && type->looks.type == PT_NORMAL)
{
p->die = -1;
continue;
}
}
else
{
p->die = -1;
VectorNormalize(p->vel);
P_RunParticleEffectType(stop, p->vel, type->clipcount/part_type[type->cliptype].count, type->cliptype);
continue;
}
continue;
}
}
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);
}

View file

@ -39,7 +39,7 @@ typedef struct csqctreadstate_s {
struct csqctreadstate_s *next;
} csqctreadstate_t;
static unsigned int csqcchecksum;
static unsigned int csprogs_checksum, csaddon_checksum;
static csqctreadstate_t *csqcthreads;
qboolean csqc_resortfrags;
qboolean csqc_drawsbar;
@ -49,6 +49,7 @@ world_t csqc_world;
static int csqc_lplayernum;
static qboolean csqc_isdarkplaces;
static qboolean csqc_singlecheats; /*single player or cheats active, allowing custom addons*/
static char csqc_printbuffer[8192];
@ -156,6 +157,7 @@ typedef enum
globalfloat(svtime, "time"); /*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(physics_mode, "physics_mode"); /*float 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*/ \
\
@ -266,6 +268,7 @@ static void CSQC_ChangeLocalPlayer(int lplayernum)
static void CSQC_FindGlobals(void)
{
static float csphysicsmode = 0;
#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 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.other = csqcg.other;
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.newmis = (int*)PR_FindGlobal(csqcprogs, "newmis", 0, NULL);
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)
*csqcg.maxclients = cl.allocated_client_slots;
@ -459,27 +469,6 @@ static int csqcentsize;
static char *csqcmapentitydata;
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;
#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;
if (in->xv->skeletonindex)
{
skelobject_t *so;
so = skel_get(csqcprogs, in->xv->skeletonindex, 0);
if (so && so->inuse == 1)
{
out->bonecount = so->numbones;
out->bonestate = so->bonematrix;
}
skel_lookup(csqcprogs, in->xv->skeletonindex, out);
}
}
@ -656,6 +639,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
int ival;
model_t *model;
unsigned int rflags;
unsigned int effects;
ival = in->v->modelindex;
model = CSQC_GetModelForIndex(ival);
@ -665,7 +649,8 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
memset(out, 0, sizeof(*out));
out->model = model;
if (in->xv->renderflags)
rflags = in->xv->renderflags;
if (rflags)
{
rflags = in->xv->renderflags;
if (rflags & CSQCRF_VIEWMODEL)
@ -681,10 +666,13 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
out->flags |= RF_NOSHADOW;
//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;
cs_getframestate(in, rflags, &out->framestate);
@ -901,6 +889,7 @@ static void QCBUILTIN PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_
csqcedict_t *ent;
entity_t rent;
int e;
int maxe;
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);
if (ent->isfree)
@ -1134,7 +1124,7 @@ static void QCBUILTIN PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s
CL_SetUpPlayerPrediction(true);
}
skel_dodelete();
skel_dodelete(csqcprogs);
CL_SwapEntityLists();
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;
break;
#ifdef _MSC_VER
#pragma message("fixme: AFOV not retrievable")
#ifdef warningmsg
#pragma warningmsg("fixme: AFOV not retrievable")
#endif
case VF_AFOV:
*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.
pe->ParticleTrail(start, end, efnum, NULL);
pe->ParticleTrail(start, end, efnum, 0, NULL);
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)
@ -2221,7 +2211,15 @@ static void QCBUILTIN PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s
char adr[MAX_ADR_SIZE];
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"))
{ //using this is pretty acedemic, really. Not particuarly portable.
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);
#ifdef _MSC_VER
#pragma message("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)")
#ifdef warningmsg
#pragma warningmsg("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)")
#endif
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;
}
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)
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)
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 (!(flags & RSES_NOROTATE) && (model->flags & EF_ROTATE))
if (!(flags & RSES_NOROTATE) && (model->flags & MF_ROTATE))
{
ent->v->angles[0] = 0;
ent->v->angles[1] = 100*lerptime;
@ -4445,8 +3968,8 @@ static void QCBUILTIN PF_ReadServerEntityState(progfuncs_t *prinst, struct globa
src = &pack->entities[i];
// CL_LinkPacketEntities
#ifndef _MSC_VER
#warning what to do here?
#ifdef warningmsg
#pragma warningmsg("what to do here?")
#endif
// if (csqcent[src->number])
// 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);
}
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)
{
@ -5215,21 +4743,21 @@ qbyte *CSQC_PRLoadFile (const char *path, void *buffer, int bufsize)
if (!strcmp(path, "csprogs.dat"))
{
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);
if (file)
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) == csqcchecksum)
if (QCRC_Block(file, com_filesize) == csprogs_checksum)
return file;
}
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;
}
}
@ -5238,16 +4766,16 @@ qbyte *CSQC_PRLoadFile (const char *path, void *buffer, int 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 (csqcchecksum)
if (csprogs_checksum)
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) != csqcchecksum)
if (QCRC_Block(file, com_filesize) != csprogs_checksum)
return NULL;
}
else
{
if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csqcchecksum)
if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csprogs_checksum)
return NULL; //not valid
}
@ -5270,21 +4798,21 @@ int CSQC_PRFileSize (const char *path)
if (!strcmp(path, "csprogs.dat"))
{
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);
if (file)
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) == csqcchecksum)
if (QCRC_Block(file, com_filesize) == csprogs_checksum)
return com_filesize+1;
}
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;
}
}
@ -5293,16 +4821,16 @@ int CSQC_PRFileSize (const char *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 (csqcchecksum)
if (csprogs_checksum)
{
if (cls.protocol == CP_NETQUAKE)
{
if (QCRC_Block(file, com_filesize) != csqcchecksum)
if (QCRC_Block(file, com_filesize) != csprogs_checksum)
return -1; //not valid
}
else
{
if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csqcchecksum)
if (LittleLong(Com_BlockChecksum(file, com_filesize)) != csprogs_checksum)
return -1; //not valid
}
}
@ -5329,9 +4857,15 @@ qboolean CSQC_Init (unsigned int checksum)
int i;
string_t *str;
csqcedict_t *worldent;
csqcchecksum = checksum;
qboolean loaded;
csprogs_checksum = checksum;
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...
if (csqcprogs)
@ -5354,7 +4888,7 @@ qboolean CSQC_Init (unsigned int checksum)
}
csqc_deprecated_warned = false;
skel_reset();
skel_reset(csqcprogs);
memset(cl.model_csqcname, 0, sizeof(cl.model_csqcname));
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.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
csqcprogparms.user = &csqc_world;
csqctime = Sys_DoubleTime();
if (!csqcprogs)
@ -5406,26 +4941,31 @@ qboolean CSQC_Init (unsigned int checksum)
csqc_world.worldmodel = cl.worldmodel;
csqc_world.Event_Touch = CSQC_Event_Touch;
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);
CSQC_InitFields(); //let the qclib know the field order that the engine needs.
csqc_isdarkplaces = false;
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 22390, NULL, 0) < 0) //no per-progs builtins.
if (setjmp(csqc_abort))
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) < 0) //no per-progs builtins.
{
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;
CSQC_Shutdown();
return false;
}
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))
{
@ -5433,6 +4973,18 @@ qboolean CSQC_Init (unsigned int checksum)
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);
PF_InitTempStrings(csqcprogs);
@ -5678,7 +5230,7 @@ void CSQC_RegisterCvarsAndThings(void)
Cvar_Register(&cl_csqcdebug, CSQCPROGSGROUP);
Cvar_Register(&cl_nocsqc, CSQCPROGSGROUP);
Cvar_Register(&pr_csqc_coreonerror, CSQCPROGSGROUP);
Cvar_Register(&dpcompat_corruptglobals, CSQCPROGSGROUP);
Cvar_Register(&dpcompat_corruptglobals, "Darkplaces compatibility");
}
void CSQC_CvarChanged(cvar_t *var)
@ -5724,12 +5276,15 @@ qboolean CSQC_DrawView(void)
World_ODE_Frame(&csqc_world, ft, 800);
//World_Physics_Frame(&csqc_world);
World_Physics_Frame(&csqc_world);
}
#else
csqc_world.physicstime = cl.servertime;
#endif
if (csqcg.frametime)
*csqcg.frametime = host_frametime;
DropPunchAngle (0);
if (cl.worldmodel)
R_LessenStains();
@ -5841,8 +5396,8 @@ static void CSQC_GameCommand_f(void)
PR_ExecuteProgram (csqcprogs, csqcg.gamecommand);
}
#ifdef _MSC_VER
#pragma message("do we really need the firstbyte parameter here?")
#ifdef warningmsg
#pragma warningmsg("do we really need the firstbyte parameter here?")
#endif
qboolean CSQC_ParseTempEntity(unsigned char firstbyte)
{

View file

@ -1948,8 +1948,8 @@ qboolean MP_Init (void)
if (mp_time)
*mp_time = Sys_DoubleTime();
#ifdef _MSC_VER
#pragma message("disabled until csqc gets forked or some such")
#ifdef warningmsg
#pragma warningmsg("disabled until csqc gets forked or some such")
#endif
//mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 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.
//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
//#pragma warning( disable : 4244 4127 4201 4214 4514 4305 4115 4018)
/*#pragma warning( disable : 4244) //conversion from const double to float

View file

@ -103,8 +103,8 @@ void R2D_Init(void)
Font_Init();
#ifdef _MSC_VER
#pragma message("Fixme: move conwidth handling into here")
#ifdef warningmsg
#pragma warningmsg("Fixme: move conwidth handling into here")
#endif
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"
"map $whitetexture\n"
"map $whiteimage\n"
"blendfunc gl_dst_color gl_zero\n"
"rgbgen const $r_menutint\n"
"}\n"
@ -407,7 +407,7 @@ void R2D_TransPicTranslate (int x, int y, int width, int height, qbyte *pic, qby
if (!TEXVALID(translate_texture))
{
translate_texture = R_AllocNewTexture(64, 64);
translate_texture = R_AllocNewTexture("***translatedpic***", 64, 64);
translate_shader = R_RegisterShader("translatedpic", "{\n"
"if $nofixed\n"
"[\n"
@ -937,7 +937,7 @@ void R2D_Crosshair_Update(void)
c = c % (sizeof(crosshair_pixels) / (CS_HEIGHT*sizeof(*crosshair_pixels)));
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;
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++)
{
if (!mod->needload)
if (mod->flags & EF_ROCKET)
if (mod->flags & MF_ROCKET)
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++)
{
if (!mod->needload)
if (mod->flags & EF_GRENADE)
if (mod->flags & MF_GRENADE)
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];
if (pe->nonsolid)
continue;
if (pe->model)
if (pe->model && !pe->model->needload)
{
VectorSubtract(start, pe->origin, ts);
VectorSubtract(end, pe->origin, te);
@ -362,86 +362,86 @@ void P_DefaultTrail (model_t *model)
if (model->engineflags & MDLF_NODEFAULTTRAIL)
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);
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);
else if (model->flags & EF_GIB)
else if (model->flags & MF_GIB)
{
model->particletrail = P_FindParticleType("TR_BLOOD");
model->traildefaultindex = 70;
}
else if (model->flags & EF_TRACER)
else if (model->flags & MF_TRACER)
{
model->particletrail = P_FindParticleType("TR_WIZSPIKE");
model->traildefaultindex = 60;
}
else if (model->flags & EF_ZOMGIB)
else if (model->flags & MF_ZOMGIB)
{
model->particletrail = P_FindParticleType("TR_SLIGHTBLOOD");
model->traildefaultindex = 70;
}
else if (model->flags & EF_TRACER2)
else if (model->flags & MF_TRACER2)
{
model->particletrail = P_FindParticleType("TR_KNIGHTSPIKE");
model->traildefaultindex = 238;
}
else if (model->flags & EF_TRACER3)
else if (model->flags & MF_TRACER3)
{
model->particletrail = P_FindParticleType("TR_VORESPIKE");
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->traildefaultindex = 136;
}
else if (model->flags & EFH2_FIREBALL)
else if (model->flags & MFH2_FIREBALL)
{
model->particletrail = P_FindParticleType("tr_fireball");
model->traildefaultindex = 424;
}
else if (model->flags & EFH2_ACIDBALL)
else if (model->flags & MFH2_ACIDBALL)
{
model->particletrail = P_FindParticleType("tr_acidball");
model->traildefaultindex = 440;
}
else if (model->flags & EFH2_ICE)
else if (model->flags & MFH2_ICE)
{
model->particletrail = P_FindParticleType("tr_ice");
model->traildefaultindex = 408;
}
else if (model->flags & EFH2_SPIT)
else if (model->flags & MFH2_SPIT)
{
model->particletrail = P_FindParticleType("tr_spit");
model->traildefaultindex = 260;
}
else if (model->flags & EFH2_SPELL)
else if (model->flags & MFH2_SPELL)
{
model->particletrail = P_FindParticleType("tr_spell");
model->traildefaultindex = 260;
}
else if (model->flags & EFH2_VORP_MISSILE)
else if (model->flags & MFH2_VORP_MISSILE)
{
model->particletrail = P_FindParticleType("tr_vorpmissile");
model->traildefaultindex = 302;
}
else if (model->flags & EFH2_SET_STAFF)
else if (model->flags & MFH2_SET_STAFF)
{
model->particletrail = P_FindParticleType("tr_setstaff");
model->traildefaultindex = 424;
}
else if (model->flags & EFH2_MAGICMISSILE)
else if (model->flags & MFH2_MAGICMISSILE)
{
model->particletrail = P_FindParticleType("tr_magicmissile");
model->traildefaultindex = 149;
}
else if (model->flags & EFH2_BONESHARD)
else if (model->flags & MFH2_BONESHARD)
{
model->particletrail = P_FindParticleType("tr_boneshard");
model->traildefaultindex = 384;
}
else if (model->flags & EFH2_SCARAB)
else if (model->flags & MFH2_SCARAB)
{
model->particletrail = P_FindParticleType("tr_scarab");
model->traildefaultindex = 254;

View file

@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h>
extern cvar_t r_ambient;
extern cvar_t gl_bump;
static vec3_t modelorg; /*set before recursively entering the visible surface finder*/
static qbyte areabits[MAX_Q2MAP_AREAS/8];
@ -1221,7 +1220,7 @@ dynamic:
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if (gl_bump.ival)
if (r_deluxemapping.ival)
{
lightmap[fa->lightmaptexturenum]->deluxmodified = true;
theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange;
@ -1307,7 +1306,7 @@ dynamic:
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if (gl_bump.ival)
if (r_deluxemapping.ival)
{
lightmap[fa->lightmaptexturenum]->deluxmodified = true;
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_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4));
lightmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
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);
memset(lightmap_textures+numlightmaps, 0, sizeof(*lightmap_textures)*(4));
deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4));
deluxmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
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);
memset(deluxmap_textures+numlightmaps, 0, sizeof(*deluxmap_textures)*(4));
numlightmaps+=4;
}
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]->modified = true;
lightmap[texnum]->shader = shader;
lightmap[texnum]->external = true;
// reset stainmap since it now starts at 255
memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps));
//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+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)
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*/
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_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4));
lightmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
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);
memset(lightmap_textures+numlightmaps, 0, sizeof(*lightmap_textures)*(4));
deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4));
deluxmap_textures[numlightmaps+0] = R_AllocNewTexture(LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
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);
memset(deluxmap_textures+numlightmaps, 0, sizeof(*deluxmap_textures)*(4));
numlightmaps+=4;
}
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]->meshchain = NULL;
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;
}
@ -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;
//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+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 (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)
{
int j;
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)+1] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*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)+0] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[2];
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_WIDTH*LMBLOCK_HEIGHT*i))[0];
lightmap[i]->lightmaps[(j<<2)+3] = 255;
}
}
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)+1] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_HEIGHT*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)+0] = (cl.worldmodel->lightdata+3*(j + LMBLOCK_WIDTH*LMBLOCK_HEIGHT*i))[0];
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_WIDTH*LMBLOCK_HEIGHT*i))[2];
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
{
/*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
{
char basename[MAX_QPATH];
//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));
if (!lightmap[i]->external)
@ -2474,10 +2473,18 @@ void Surf_DeInit(void)
if (lightmap_textures)
{
for (i = 0; i < numlightmaps; i++)
{
if (!lightmap[i] || lightmap[i]->external)
{
R_DestroyTexture(lightmap_textures[i]);
R_DestroyTexture(deluxmap_textures[i]);
}
}
BZ_Free(lightmap_textures);
BZ_Free(deluxmap_textures);
}
lightmap_textures=NULL;
deluxmap_textures = NULL;
for (i = 0; i < numlightmaps; i++)
{
@ -2490,7 +2497,6 @@ void Surf_DeInit(void)
if (lightmap)
BZ_Free(lightmap);
lightmap_textures=NULL;
lightmap=NULL;
numlightmaps=0;
}

View file

@ -36,7 +36,6 @@ struct texnums_s;
struct texture_s;
static const texid_t r_nulltex = {0};
#define TEXVALID(t) ((t).num!=0)
#if defined(D3DQUAKE) || defined(ANDROID)
@ -76,6 +75,7 @@ typedef enum {
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
struct dlight_s;
typedef struct entity_s
{
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 flipcull; /*reflected/flipped view, requires inverted culling*/
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;
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_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_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_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_NOALPHA = 1<<3,
IF_NOGAMMA = 1<<4,
IF_NEAREST = 1<<5,
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*/
#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);
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);
#endif
#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_LoadCompressed (char *name);
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_DestroyTexture (texid_t tex);
void D3D_Image_Shutdown(void);
#endif
extern int image_width, image_height;
texid_t R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags);
texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags);
texid_t R_LoadBumpmapTexture(char *name, char *subpath);
texid_tf R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags);
texid_tf R_LoadHiResTexture(char *name, char *subpath, unsigned int flags);
texid_tf R_LoadBumpmapTexture(char *name, char *subpath);
extern texid_t particletexture;
extern texid_t particlecqtexture;
@ -431,6 +436,7 @@ extern cvar_t r_wateralpha;
extern cvar_t r_dynamic;
extern cvar_t r_novis;
extern cvar_t r_netgraph;
extern cvar_t r_deluxemapping;
#ifdef 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_blend2d = CVAR ("gl_blend2d", "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_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t gl_compress = CVARF ("gl_compress", "0",
@ -294,6 +292,7 @@ cvar_t vid_triplebuffer = CVARAF ("vid_triplebuffer", "1",
"gl_triplebuffer", CVAR_ARCHIVE);
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_ARCHIVE);
cvar_t r_shadows = SCVARF ("r_shadows", "0",
@ -355,13 +354,12 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_affinemodels, GLRENDEREROPTIONS);
Cvar_Register (&gl_nohwblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblendscale, GLRENDEREROPTIONS);
Cvar_Register (&gl_nocolors, GLRENDEREROPTIONS);
Cvar_Register (&gl_finish, GLRENDEREROPTIONS);
Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS);
Cvar_Register (&gl_lerpimages, GLRENDEREROPTIONS);
Cvar_Register (&dpcompat_psa_ungroup, GLRENDEREROPTIONS);
Cvar_Register (&r_noportals, GLRENDEREROPTIONS);
Cvar_Register (&r_noaliasshadows, GLRENDEREROPTIONS);
Cvar_Register (&gl_maxshadowlights, GLRENDEREROPTIONS);
@ -381,7 +379,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES);
Cvar_Register (&gl_bump, GRAPHICALNICETIES);
Cvar_Register (&r_deluxemapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
@ -539,6 +536,8 @@ void Renderer_Init(void)
Cvar_Register(&r_stainfadetime, GRAPHICALNICETIES);
Cvar_Register(&r_stainfadeammount, GRAPHICALNICETIES);
Cvar_Register(&r_lightprepass, GRAPHICALNICETIES);
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblendscale, GLRENDEREROPTIONS);
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
Cvar_Register(&scr_fov, SCREENOPTIONS);
@ -773,6 +772,7 @@ rendererinfo_t dedicatedrendererinfo = {
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 "shader.h"
#ifdef _MSC_VER
#pragma message("hipnotic/rogue: Find out")
#endif
#define FINDOUT 1024
extern cvar_t hud_tracking_show;
extern cvar_t com_parseutf8;
@ -539,7 +534,7 @@ void Sbar_ExecuteLayoutString (char *s)
color = 0; // green
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);
continue;

View file

@ -223,9 +223,9 @@ qbyte *Skin_Cache8 (skin_t *skin)
if (skin->failedload)
return NULL;
skin->tex_base = r_nulltex;
skin->tex_lower = r_nulltex;
skin->tex_upper = r_nulltex;
TEXASSIGN(skin->tex_base, r_nulltex);
TEXASSIGN(skin->tex_lower, r_nulltex);
TEXASSIGN(skin->tex_upper, r_nulltex);
out = Cache_Check (&skin->cache);
if (out)
@ -279,13 +279,13 @@ qbyte *Skin_Cache8 (skin_t *skin)
#if defined(GLQUAKE) || defined(D3DQUAKE)
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))
{
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);
skin->tex_lower = R_LoadReplacementTexture(name, "skins", 0);
TEXASSIGN(skin->tex_lower, R_LoadReplacementTexture(name, "skins", 0));
skin->failedload = true;
return NULL;

View file

@ -167,8 +167,8 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
// start = ch->end - scache->length;
// samples = end - start;
#ifdef _MSC_VER
#pragma message("pitch fix needed")
#ifdef warningmsg
#pragma warningmsg("pitch fix needed")
#endif
ch->sfx->decoder->decodemore(ch->sfx,
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?
#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);
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);
}
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);
}
@ -263,7 +264,7 @@ NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window)
return NPERR_INVALID_INSTANCE_ERROR;
//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?
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 context *ctx = obj->ctx;
NPUTF8 *pname;
struct pscript_property *prop;
int prop;
bool success = false;
char *strval;
int intval;
@ -510,7 +511,7 @@ bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
Plug_LockPlugin(ctx, true);
prop = Plug_FindProp(obj->ctx, pname);
if (prop)
if (prop >= 0)
{
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;
NPUTF8 *pname;
NPString str;
struct pscript_property *prop;
int prop;
bool success = false;
pname = browserfuncs->utf8fromidentifier(name);
Plug_LockPlugin(ctx, true);
prop = Plug_FindProp(obj->ctx, pname);
if (prop)
if (prop >= 0)
{
success = true;
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;
void *windowhnd;
int windowleft;
int windowtop;
int windowwidth;
int windowheight;
@ -117,7 +119,7 @@ struct context
char *onend;
char *ondemoend;
void *nppinstance;
void *hostinstance;
int read;
int written;
@ -299,7 +301,6 @@ int Plug_PluginThread(void *ctxptr)
}
Con_Printf("Attempting to download %s\n", c);
VS_DebugLocation(__FILE__, __LINE__, "Queuing Download %s", c);
dl = DL_Create(c);
dl->user_ctx = ctx;
@ -327,7 +328,7 @@ int Plug_PluginThread(void *ctxptr)
ctx->pub.dlsize = total;
ctx->pub.dldone = done;
if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub);
ctx->bfuncs.StatusChanged(ctx->hostinstance);
}
if (!dl->file)
ctx->packagelist = dl->next;
@ -347,28 +348,29 @@ int Plug_PluginThread(void *ctxptr)
Sys_LockMutex(ctx->mutex);
ctx->resetvideo = false;
sys_parentwindow = ctx->windowhnd;
sys_parentleft = ctx->windowleft;
sys_parenttop = ctx->windowtop;
sys_parentwidth = ctx->windowwidth;
sys_parentheight = ctx->windowheight;
VS_DebugLocation(__FILE__, __LINE__, "Host_FinishInit");
Host_FinishInit();
Sys_UnlockMutex(ctx->mutex);
}
if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub);
ctx->bfuncs.StatusChanged(ctx->hostinstance);
VS_DebugLocation(__FILE__, __LINE__, "main loop");
while(host_initialized)
{
Sys_LockMutex(ctx->mutex);
if (ctx->shutdown)
{
ctx->shutdown = false;
VS_DebugLocation(__FILE__, __LINE__, "Sys_Shutdown");
Host_Shutdown(); /*will shut down the host*/
}
else if (ctx->resetvideo)
{
sys_parentwindow = ctx->windowhnd;
sys_parentleft = ctx->windowleft;
sys_parenttop = ctx->windowtop;
sys_parentwidth = ctx->windowwidth;
sys_parentheight = ctx->windowheight;
if (ctx->resetvideo == 2)
@ -410,7 +412,7 @@ int Plug_PluginThread(void *ctxptr)
ctx->pub.running = false;
Sys_UnlockMutex(ctx->mutex);
if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub);
ctx->bfuncs.StatusChanged(ctx->hostinstance);
while(argc-- > 0)
free(argv[argc]);
@ -470,7 +472,7 @@ struct context *Plug_CreateContext(void *sysctx, const struct browserfuncs *func
memcpy(&ctx->bfuncs, funcs, sizeof(ctx->bfuncs));
//link the instance to the context and the context to the instance
ctx->nppinstance = sysctx;
ctx->hostinstance = sysctx;
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
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;
@ -497,11 +499,12 @@ qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int width, int heigh
ctx->windowhnd = whnd;
ctx->resetvideo = 2;
}
if (ctx->windowwidth != width || ctx->windowheight != height)
{
ctx->windowwidth = width;
ctx->windowheight = height;
}
ctx->windowleft = left;
ctx->windowtop = top;
ctx->windowwidth = width;
ctx->windowheight = height;
if (ctx->pub.running && !ctx->resetvideo)
ctx->resetvideo = true;
Plug_LockPlugin(ctx, false);
@ -659,7 +662,7 @@ void LoadSplashImage(struct dl_download *dl)
if (!f)
{
if (ctx->bfuncs.StatusChanged)
ctx->bfuncs.StatusChanged(&ctx->pub);
ctx->bfuncs.StatusChanged(ctx->hostinstance);
return;
}
@ -695,7 +698,7 @@ void LoadSplashImage(struct dl_download *dl)
BZ_Free(image);
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;
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},
{"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},
{"playername", true, &name},
{NULL, true, &skin},
@ -913,68 +917,11 @@ static struct pscript_property pscript_properties[] =
{"map", false, NULL, NULL, pscript_property_map_sets},
{"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}
};
struct pscript_property *Plug_FindProp(struct context *ctx, const char *field)
int Plug_FindProp(struct context *ctx, const char *field)
{
struct pscript_property *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 (!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;
if (field->setstring)
{
@ -1024,9 +972,16 @@ qboolean Plug_SetString(struct context *ctx, struct pscript_property *field, con
return false;
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;
if (field->setint)
{
@ -1050,9 +1005,10 @@ qboolean Plug_SetInteger(struct context *ctx, struct pscript_property *field, in
return false;
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;
if (field->setfloat)
{
@ -1077,8 +1033,12 @@ qboolean Plug_SetFloat(struct context *ctx, struct pscript_property *field, floa
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)
{
*value = field->getstring(ctx);
@ -1090,8 +1050,12 @@ void Plug_GotString(const 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)
{
*value = field->getint(ctx);
@ -1099,8 +1063,12 @@ qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, in
}
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)
{
*value = field->getfloat(ctx);
@ -1161,7 +1129,9 @@ static const struct plugfuncs exportedplugfuncs_1 =
Plug_GetFloat,
Plug_GetSplashBack,
Plug_ReleaseSplashBack
Plug_ReleaseSplashBack,
Plug_SetWString
};
const struct plugfuncs *Plug_GetFuncs(int ver)

View file

@ -26,6 +26,7 @@ struct contextpublic
void *user;
};
/*
#include <windows.h>
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("\n");
}
*/
@ -58,16 +59,16 @@ void Plug_DestroyContext(struct context *ctx);
void Plug_LockPlugin(struct context *ctx, qboolean lockstate);
qboolean Plug_StartContext(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);
qboolean Plug_SetString(struct context *ctx, struct pscript_property *field, const char *value);
qboolean Plug_GetString(struct context *ctx, struct pscript_property *field, const char **value);
int Plug_FindProp(struct context *ctx, const char *field);
qboolean Plug_SetString(struct context *ctx, int field, const char *value);
qboolean Plug_GetString(struct context *ctx, int field, const char **value);
void Plug_GotString(const char *value);
qboolean Plug_SetInteger(struct context *ctx, struct pscript_property *field, int value);
qboolean Plug_GetInteger(struct context *ctx, struct pscript_property *field, int *value);
qboolean Plug_SetFloat(struct context *ctx, struct pscript_property *field, float value);
qboolean Plug_GetFloat(struct context *ctx, struct pscript_property *field, float *value);
qboolean Plug_SetInteger(struct context *ctx, int field, int value);
qboolean Plug_GetInteger(struct context *ctx, int field, int *value);
qboolean Plug_SetFloat(struct context *ctx, int field, float value);
qboolean Plug_GetFloat(struct context *ctx, int field, float *value);
#ifdef _WIN32
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);
qboolean (*StartContext)(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);
qboolean (*SetString)(struct context *ctx, struct pscript_property *field, const char *value);
qboolean (*GetString)(struct context *ctx, struct pscript_property *field, const char **value);
int (*FindProp)(struct context *ctx, const char *field);
qboolean (*SetString)(struct context *ctx, int field, const char *value);
qboolean (*GetString)(struct context *ctx, int field, const char **value);
void (*GotString)(const char *value);
qboolean (*SetInteger)(struct context *ctx, struct pscript_property *field, int value);
qboolean (*GetInteger)(struct context *ctx, struct pscript_property *field, int *value);
qboolean (*SetFloat)(struct context *ctx, struct pscript_property *field, float value);
qboolean (*GetFloat)(struct context *ctx, struct pscript_property *field, float *value);
qboolean (*SetInteger)(struct context *ctx, int field, int value);
qboolean (*GetInteger)(struct context *ctx, int field, int *value);
qboolean (*SetFloat)(struct context *ctx, int field, float value);
qboolean (*GetFloat)(struct context *ctx, int field, float *value);
#ifdef _WIN32
void *(*GetSplashBack)(struct context *ctx, void *hdc, int *width, int *height);/*returns an HBITMAP*/
void (*ReleaseSplashBack)(struct context *ctx, void *bmp);
#endif
qboolean (*SetWString)(struct context *ctx, int field, const wchar_t *value);
};
#define PLUG_APIVER 1
#ifdef __cplusplus
extern "C"
#endif
const struct plugfuncs *Plug_GetFuncs(int ver);

View file

@ -46,6 +46,8 @@ qboolean isDedicated = false;
qboolean debugout;
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_parentheight;
@ -1866,8 +1868,10 @@ qboolean Sys_LockMutex(void *mutex)
return true;
OutputDebugString("Warning: Suspected mutex deadlock\n");
DebugBreak();
#endif
return false;
#else
return WaitForSingleObject(mutex, INFINITE) == WAIT_OBJECT_0;
#endif
}
qboolean Sys_UnlockMutex(void *mutex)

View file

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

View file

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

View file

@ -45,7 +45,7 @@ extern rendererstate_t currentrendererstate;
typedef struct vrect_s
{
int x,y,width,height;
struct vrect_s *pnext;
// struct vrect_s *pnext;
} vrect_t;
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();
#ifdef FISH
void R_RenderView_fisheye(void);
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_viewheight = SCVAR("v_viewheight", "0");
cvar_t v_projectionmode = SCVAR("v_projectionmode", "0");
cvar_t scr_autoid = SCVAR("scr_autoid", "1");
@ -1201,11 +1198,9 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
case 3:
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2
#ifdef FISH
&& ffov.value >= 0
#endif
&& ffov.value >= 0 /*panoramic view always stacks player views*/
)
{ //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->height = vid.height;
vrect->x = 0 + vrect->width*pnum;
@ -1214,6 +1209,7 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
else
#endif
{
//stack them vertically
vrect->width = vid.width;
vrect->height = vid.height/cl.splitclients;
vrect->x = 0;
@ -1341,7 +1337,7 @@ void V_RenderPlayerViews(int plnum)
r_secondaryview = 2;
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. :(
@ -1579,10 +1575,7 @@ void V_Init (void)
}
#endif
#ifdef FISH
Cvar_Register (&ffov, VIEWVARS);
Cvar_Register (&fviews, VIEWVARS);
#endif
BuildGammaTable (1.0, 1.0); // no gamma yet
Cvar_Register (&v_gamma, VIEWVARS);

View file

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