Android tweeks

memory freeing tweeks
batch data rearranged a little (to try to reduce memory).
RBSP/FBSP fixed. lightstyles now supported.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4059 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-07-05 19:42:36 +00:00
parent 180432523d
commit fe23d72d69
112 changed files with 5444 additions and 2443 deletions

View File

@ -135,7 +135,7 @@ void Cam_Lock(int pnum, int playernum)
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{
memcpy(&cl.stats[pnum], cl.players[playernum].stats, sizeof(cl.stats[pnum]));
memcpy(&cl.playerview[pnum].stats, cl.players[playernum].stats, sizeof(cl.playerview[pnum].stats));
}
Sbar_Changed();
@ -379,18 +379,18 @@ void Cam_SelfTrack(int pnum)
vec3_t forward, right, up;
trace_t tr;
AngleVectors(r_refdef.viewangles, forward, right, up);
VectorMA(cl.simorg[pnum], -128, forward, desired_position[pnum]);
tr = Cam_DoTrace(cl.simorg[pnum], desired_position[pnum]);
VectorMA(cl.playerview[pnum].simorg, -128, forward, desired_position[pnum]);
tr = Cam_DoTrace(cl.playerview[pnum].simorg, desired_position[pnum]);
VectorCopy(tr.endpos, desired_position[pnum]);
}
else
{ //view from a random wall
if (!locked[pnum] || !Cam_IsVisible(cl.simorg[pnum], desired_position[pnum]))
if (!locked[pnum] || !Cam_IsVisible(cl.playerview[pnum].simorg, desired_position[pnum]))
{
if (!locked[pnum] || realtime - cam_lastviewtime[pnum] > 0.1)
{
if (!InitFlyby(pnum, desired_position[pnum], cl.simorg[pnum], cl.simangles[pnum], true))
InitFlyby(pnum, desired_position[pnum], cl.simorg[pnum], cl.simangles[pnum], false);
if (!InitFlyby(pnum, desired_position[pnum], cl.playerview[pnum].simorg, cl.playerview[pnum].simangles, true))
InitFlyby(pnum, desired_position[pnum], cl.playerview[pnum].simorg, cl.playerview[pnum].simangles, false);
cam_lastviewtime[pnum] = realtime;
}
}
@ -408,7 +408,7 @@ void Cam_SelfTrack(int pnum)
// move there locally immediately
VectorCopy(desired_position[pnum], r_refdef.vieworg);
VectorSubtract(cl.simorg[pnum], desired_position[pnum], vec);
VectorSubtract(cl.playerview[pnum].simorg, desired_position[pnum], vec);
VectorAngles(vec, NULL, r_refdef.viewangles);
r_refdef.viewangles[0] = -r_refdef.viewangles[0];
}
@ -474,7 +474,7 @@ void Cam_Track(int pnum, usercmd_t *cmd)
cmd->forwardmove = cmd->sidemove = cmd->upmove = 0;
VectorCopy(player->viewangles, cl.viewangles[pnum]);
VectorCopy(player->viewangles, cl.playerview[pnum].viewangles);
if (memcmp(player->origin, &self->origin, sizeof(player->origin)) != 0)
{
if (!cls.demoplayback)
@ -509,8 +509,8 @@ void Cam_Track(int pnum, usercmd_t *cmd)
VectorCopy(desired_position[pnum], self->origin);
VectorSubtract(player->origin, desired_position[pnum], vec);
VectorAngles(vec, NULL, cl.viewangles[pnum]);
cl.viewangles[pnum][0] = -cl.viewangles[pnum][0];
VectorAngles(vec, NULL, cl.playerview[pnum].viewangles);
cl.playerview[pnum].viewangles[0] = -cl.playerview[pnum].viewangles[0];
}
void Cam_SetAutoTrack(int userid)
@ -575,7 +575,7 @@ void Cam_FinishMove(int pnum, usercmd_t *cmd)
if (autocam[pnum] > CAM_TRACK)
{
Cam_Unlock(pnum);
VectorCopy(cl.viewangles[pnum], cmd->angles);
VectorCopy(cl.playerview[pnum].viewangles, cmd->angles);
return;
}
}

View File

@ -116,7 +116,7 @@ void CL_WriteDemoCmd (usercmd_t *pcmd)
for (i=0 ; i<3 ; i++)
{
fl = LittleFloat (cl.viewangles[0][i]);
fl = LittleFloat (cl.playerview[0].viewangles[i]);
VFS_WRITE (cls.demooutfile, &fl, 4);
}
@ -444,15 +444,15 @@ qboolean CL_GetDemoMessage (void)
for (i=0 ; i<3 ; i++)
{
a1 = cl.viewangles[2][i];
a2 = cl.viewangles[1][i];
a1 = cl.playerview[2].viewangles[i];
a2 = cl.playerview[1].viewangles[i];
if (a1 - a2 > 180)
a1 -= 360;
if (a1 - a2 < -180)
a1 += 360;
cl.simangles[0][i] = a2 + f * (a1 - a2);
cl.playerview[0].simangles[i] = a2 + f * (a1 - a2);
}
VectorCopy(cl.simangles[0], cl.viewangles[0]);
VectorCopy(cl.playerview[0].simangles, cl.playerview[0].viewangles);
}
return 0;
}
@ -464,13 +464,13 @@ qboolean CL_GetDemoMessage (void)
}
if (cls.demoplayback == DPB_NETQUAKE)
{
VectorCopy (cl.viewangles[1], cl.viewangles[2]);
VectorCopy (cl.playerview[1].viewangles, cl.playerview[2].viewangles);
for (i=0 ; i<3 ; i++)
{
readdemobytes(&demopos, &f, 4);
cl.simangles[0][i] = cl.viewangles[1][i] = LittleFloat (f);
cl.playerview[0].simangles[i] = cl.playerview[1].viewangles[i] = LittleFloat (f);
}
VectorCopy (cl.viewangles[1], cl.viewangles[0]);
VectorCopy (cl.playerview[1].viewangles, cl.playerview[0].viewangles);
}
olddemotime = demtime;
@ -678,7 +678,7 @@ readnext:
for (i=0 ; i<3 ; i++)
{
readdemobytes (&demopos, &f, 4);
cl.viewangles[0][i] = LittleFloat (f);
cl.playerview[0].viewangles[i] = LittleFloat (f);
}
goto readnext;
/* }*/
@ -1315,11 +1315,11 @@ void CL_Record_f (void)
for (i = ((cls.fteprotocolextensions&PEXT_HEXEN2)?MAX_QW_STATS:MAX_CL_STATS); i >= 0; i--)
{
if (!cl.stats[0][i])
if (!cl.playerview[0].stats[i])
continue;
MSG_WriteByte (&buf, svc_updatestatlong);
MSG_WriteByte (&buf, i);
MSG_WriteLong (&buf, cl.stats[0][i]);
MSG_WriteLong (&buf, cl.playerview[0].stats[i]);
if (buf.cursize > MAX_QWMSGLEN/2)
{
CL_WriteRecordDemoMessage (&buf, seq++);

View File

@ -510,8 +510,8 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
else if (!olds)
{
/*reset got lost, probably the data will be filled in later - FIXME: we should probably ignore this entity*/
// Con_DPrintf("New entity without reset\n");
memset(news, 0, sizeof(*news));
Con_DPrintf("New entity without reset\n");
*news = nullentitystate;
// *news = *baseline;
}
else
@ -661,6 +661,9 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->lightstyle = MSG_ReadByte();
news->lightpflags = MSG_ReadByte();
}
if (bits & UF_TRAILEFFECT)
news->u.q1.traileffectnum = MSG_ReadShort();
if (bits & UF_COLORMOD)
{
news->colormod[0] = MSG_ReadByte();
@ -673,9 +676,28 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->glowmod[1] = MSG_ReadByte();
news->glowmod[2] = MSG_ReadByte();
}
if (bits & UF_FATNESS)
news->fatness = MSG_ReadByte();
if (bits & UF_MODELINDEX2)
{
if (bits & UF_16BIT)
news->modelindex2 = MSG_ReadShort();
else
news->modelindex2 = MSG_ReadByte();
}
if (bits & UF_GRAVITYDIR)
{
news->u.q1.gravitydir[0] = MSG_ReadByte();
news->u.q1.gravitydir[1] = MSG_ReadByte();
}
}
void CLFTE_ParseBaseline(entity_state_t *es, qboolean numberisimportant)
{
int entnum = 0;
if (numberisimportant)
entnum = MSG_ReadShort();
CLFTE_ReadDelta(entnum, es, &nullentitystate, &nullentitystate);
}
/*
@ -1550,8 +1572,8 @@ void CL_RotateAroundTag(entity_t *ent, int entnum, int parenttagent, int parentt
{
if (parenttagent == cl.playernum[0]+1)
{
org = cl.simorg[0];
ang = cl.simangles[0];
org = cl.playerview[0].simorg;
ang = cl.playerview[0].simangles;
}
else
{
@ -1873,8 +1895,63 @@ void CLQ1_AddVisibleBBoxes(void)
#ifdef CSQC_DAT
case 2:
w = &csqc_world;
return;
break;
#endif
case 3:
{
frame_t *frame;
packet_entities_t *pak;
entity_state_t *state;
model_t *mod;
s = R_RegisterShader("bboxshader",
"{\n"
"polygonoffset\n"
"{\n"
"map $whiteimage\n"
"blendfunc add\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"}\n");
frame = &cl.frames[cl.parsecount & UPDATE_MASK];
pak = &frame->packet_entities;
for (i=0 ; i<pak->num_entities ; i++)
{
state = &pak->entities[i];
if (!state->solid && !state->skinnum)
continue;
if (state->solid == ES_SOLID_BSP)
{ /*bsp model size*/
if (state->modelindex <= 0)
continue;
if (!cl.model_precache[state->modelindex])
continue;
/*this makes non-inline bsp objects non-solid for prediction*/
if ((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->hulls[1].firstclipnode)
{
mod = cl.model_precache[state->modelindex];
VectorAdd(state->origin, mod->mins, min);
VectorAdd(state->origin, mod->maxs, max);
CLQ1_AddCube(s, min, max, 0.1, 0, 0, 1);
}
}
else
{
/*don't bother with angles*/
max[0] = max[1] = 8*(state->solid & 31);
min[0] = min[1] = -max[0];
min[2] = -8*((state->solid>>5) & 31);
max[2] = 8*((state->solid>>10) & 63) - 32;
VectorAdd(state->origin, min, min);
VectorAdd(state->origin, max, max);
CLQ1_AddCube(s, min, max, 0.1, 0, 0, 1);
}
}
}
return;
}
if (!w->progs)
@ -1898,6 +1975,8 @@ void CLQ1_AddVisibleBBoxes(void)
if (r_showbboxes.ival & 4)
{
//shows the hulls instead
/*mins is easy*/
VectorAdd(e->v->origin, e->v->mins, min);
@ -2339,6 +2418,8 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
a1 += 360;
le->angles[i] = a1 + frac * (a2 - a1);
}
VectorCopy(le->origin, le->neworigin);
VectorCopy(le->angles, le->newangle);
le->orglerpdeltatime = 0.1;
le->orglerpstarttime = oldpack->servertime;
}
@ -2533,6 +2614,7 @@ void CL_LinkPacketEntities (void)
vec3_t angles;
static int flickertime;
static int flicker;
int trailef;
pack = cl.currentpackentities;
if (!pack)
@ -2777,7 +2859,7 @@ void CL_LinkPacketEntities (void)
CLQ1_AddPowerupShell(ent, false, state->effects);
// add automatic particle trails
if (!model || (!(model->flags&~MF_ROTATE) && model->particletrail<0 && model->particleeffect<0))
if (!model || (!(model->flags&~MF_ROTATE) && model->particletrail<0 && model->particleeffect<0 && state->u.q1.traileffectnum==0))
continue;
if (!cls.allow_anyparticles && !(model->flags & ~MF_ROTATE))
@ -2801,7 +2883,11 @@ void CL_LinkPacketEntities (void)
}
}
if (model->particletrail == P_INVALID || pe->ParticleTrail (old_origin, ent->origin, model->particletrail, ent->keynum, &(le->trailstate)))
trailef = model->particletrail;
if (state->u.q1.traileffectnum)
trailef = CL_TranslateParticleFromServer(state->u.q1.traileffectnum);
if (trailef == P_INVALID || pe->ParticleTrail (old_origin, ent->origin, trailef, ent->keynum, &(le->trailstate)))
if (model->traildefaultindex >= 0)
pe->ParticleTrailIndex(old_origin, ent->origin, model->traildefaultindex, 0, &(le->trailstate));
@ -3150,6 +3236,10 @@ void CL_ParsePlayerinfo (void)
state->colourmod[1] = 32;
state->colourmod[2] = 32;
state->gravitydir[0] = 0;
state->gravitydir[1] = 0;
state->gravitydir[2] = -1;
state->pm_type = PM_NORMAL;
TP_ParsePlayerInfo(oldstate, state, info);
@ -3160,8 +3250,8 @@ void CL_ParsePlayerinfo (void)
{
if (cl.playernum[i] == num)
{
cl.stats[i][STAT_WEAPONFRAME] = state->weaponframe;
cl.statsf[i][STAT_WEAPONFRAME] = state->weaponframe;
cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe;
cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe;
}
}
@ -3273,6 +3363,10 @@ void CL_ParsePlayerinfo (void)
state->alpha = 255;
state->fatness = 0;
state->gravitydir[0] = 0;
state->gravitydir[1] = 0;
state->gravitydir[2] = -1;
#ifdef PEXT_SCALE
if (flags & PF_SCALE && cls.fteprotocolextensions & PEXT_SCALE)
state->scale = (float)MSG_ReadByte()/50;
@ -3383,8 +3477,8 @@ guess_pm_type:
{
if (cl.playernum[i] == num)
{
cl.stats[i][STAT_WEAPONFRAME] = state->weaponframe;
cl.statsf[i][STAT_WEAPONFRAME] = state->weaponframe;
cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe;
cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe;
}
}
@ -3626,7 +3720,7 @@ void CL_LinkPlayers (void)
VectorCopy(state->origin, org);
for (pnum = 0; pnum < cl.splitclients; pnum++)
if (cl.playernum[pnum] == j)
VectorCopy(cl.simorg[pnum], org);
VectorCopy(cl.playerview[pnum].simorg, org);
if (model)
{
org[2] += model->mins[2];
@ -3710,12 +3804,12 @@ void CL_LinkPlayers (void)
cl_numvisedicts--;
continue;
}
*/ angles[0] = -1*cl.viewangles[pnum][0] / 3;
angles[1] = cl.viewangles[pnum][1];
angles[2] = cl.viewangles[pnum][2];
ent->origin[0] = cl.simorg[pnum][0];
ent->origin[1] = cl.simorg[pnum][1];
ent->origin[2] = cl.simorg[pnum][2]+cl.crouch[pnum];
*/ angles[0] = -1*cl.playerview[pnum].viewangles[0] / 3;
angles[1] = cl.playerview[pnum].viewangles[1];
angles[2] = cl.playerview[pnum].viewangles[2];
ent->origin[0] = cl.playerview[pnum].simorg[0];
ent->origin[1] = cl.playerview[pnum].simorg[1];
ent->origin[2] = cl.playerview[pnum].simorg[2]+cl.crouch[pnum];
break;
}
}
@ -3823,10 +3917,10 @@ void CL_LinkViewModel(void)
if (!r_drawentities.ival)
return;
if ((cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_INVISIBILITY) && r_drawviewmodelinvis.value <= 0)
if ((cl.playerview[r_refdef.currentplayernum].stats[STAT_ITEMS] & IT_INVISIBILITY) && r_drawviewmodelinvis.value <= 0)
return;
if (cl.stats[r_refdef.currentplayernum][STAT_HEALTH] <= 0)
if (cl.playerview[r_refdef.currentplayernum].stats[STAT_HEALTH] <= 0)
return;
if (r_drawviewmodel.value > 0 && r_drawviewmodel.value < 1)
@ -3834,7 +3928,7 @@ void CL_LinkViewModel(void)
else
alpha = 1;
if ((cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_INVISIBILITY)
if ((cl.playerview[r_refdef.currentplayernum].stats[STAT_ITEMS] & IT_INVISIBILITY)
&& r_drawviewmodelinvis.value > 0
&& r_drawviewmodelinvis.value < 1)
alpha *= r_drawviewmodelinvis.value;

View File

@ -33,7 +33,7 @@ cvar_t cl_nodelta = CVAR("cl_nodelta","0");
cvar_t cl_c2spps = CVAR("cl_c2spps", "0");
cvar_t cl_c2sImpulseBackup = SCVAR("cl_c2sImpulseBackup","3");
cvar_t cl_netfps = CVAR("cl_netfps", "100");
cvar_t cl_netfps = CVAR("cl_netfps", "150");
cvar_t cl_sparemsec = CVARC("cl_sparemsec", "10", CL_SpareMsec_Callback);
cvar_t cl_queueimpulses = CVAR("cl_queueimpulses", "0");
cvar_t cl_smartjump = CVAR("cl_smartjump", "1");
@ -274,7 +274,7 @@ void IN_JumpDown (void)
KeyDown(&in_up);
else
#endif
if (condition && cl.stats[pnum][STAT_HEALTH] > 0 && !cls.demoplayback && !cl.spectator &&
if (condition && cl.playerview[pnum].stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.spectator &&
cl.frames[cl.validsequence&UPDATE_MASK].playerstate[cl.playernum[pnum]].messagenum == cl.validsequence && cl.waterlevel[pnum] >= 2 && (!cl.teamfortress || !(in_forward.state[pnum] & 1))
)
KeyDown(&in_up);
@ -322,7 +322,7 @@ void IN_Impulse (void)
if (Cmd_Argc() > 2)
{
items = cl.stats[pnum][STAT_ITEMS];
items = cl.playerview[pnum].stats[STAT_ITEMS];
best = 0;
for (i = Cmd_Argc() - 1; i > 0; i--)
@ -338,31 +338,31 @@ void IN_Impulse (void)
best = 1;
break;
case 2:
if (items & IT_SHOTGUN && cl.stats[pnum][STAT_SHELLS] >= 1)
if (items & IT_SHOTGUN && cl.playerview[pnum].stats[STAT_SHELLS] >= 1)
best = 2;
break;
case 3:
if (items & IT_SUPER_SHOTGUN && cl.stats[pnum][STAT_SHELLS] >= 2)
if (items & IT_SUPER_SHOTGUN && cl.playerview[pnum].stats[STAT_SHELLS] >= 2)
best = 3;
break;
case 4:
if (items & IT_NAILGUN && cl.stats[pnum][STAT_NAILS] >= 1)
if (items & IT_NAILGUN && cl.playerview[pnum].stats[STAT_NAILS] >= 1)
best = 4;
break;
case 5:
if (items & IT_SUPER_NAILGUN && cl.stats[pnum][STAT_NAILS] >= 2)
if (items & IT_SUPER_NAILGUN && cl.playerview[pnum].stats[STAT_NAILS] >= 2)
best = 5;
break;
case 6:
if (items & IT_GRENADE_LAUNCHER && cl.stats[pnum][STAT_ROCKETS] >= 1)
if (items & IT_GRENADE_LAUNCHER && cl.playerview[pnum].stats[STAT_ROCKETS] >= 1)
best = 6;
break;
case 7:
if (items & IT_ROCKET_LAUNCHER && cl.stats[pnum][STAT_ROCKETS] >= 1)
if (items & IT_ROCKET_LAUNCHER && cl.playerview[pnum].stats[STAT_ROCKETS] >= 1)
best = 7;
break;
case 8:
if (items & IT_LIGHTNING && cl.stats[pnum][STAT_CELLS] >= 1)
if (items & IT_LIGHTNING && cl.playerview[pnum].stats[STAT_CELLS] >= 1)
best = 8;
}
}
@ -520,7 +520,7 @@ void CL_AdjustAngles (int pnum, double frametime)
quant *= speed;
in_rotate -= quant;
if (ruleset_allow_frj.ival)
cl.viewanglechange[pnum][YAW] += quant;
cl.playerview[pnum].viewanglechange[YAW] += quant;
}
if (!(in_strafe.state[pnum] & 1))
@ -528,8 +528,8 @@ void CL_AdjustAngles (int pnum, double frametime)
quant = cl_yawspeed.ival;
if (cl.fpd & FPD_LIMIT_YAW || !ruleset_allow_frj.ival)
quant = bound(-900, quant, 900);
cl.viewanglechange[pnum][YAW] -= speed*quant * CL_KeyState (&in_right, pnum);
cl.viewanglechange[pnum][YAW] += speed*quant * CL_KeyState (&in_left, pnum);
cl.playerview[pnum].viewanglechange[YAW] -= speed*quant * CL_KeyState (&in_right, pnum);
cl.playerview[pnum].viewanglechange[YAW] += speed*quant * CL_KeyState (&in_left, pnum);
}
if (in_klook.state[pnum] & 1)
{
@ -537,8 +537,8 @@ void CL_AdjustAngles (int pnum, double frametime)
quant = cl_pitchspeed.ival;
if (cl.fpd & FPD_LIMIT_PITCH || !ruleset_allow_frj.ival)
quant = bound(-700, quant, 700);
cl.viewanglechange[pnum][PITCH] -= speed*quant * CL_KeyState (&in_forward, pnum);
cl.viewanglechange[pnum][PITCH] += speed*quant * CL_KeyState (&in_back, pnum);
cl.playerview[pnum].viewanglechange[PITCH] -= speed*quant * CL_KeyState (&in_forward, pnum);
cl.playerview[pnum].viewanglechange[PITCH] += speed*quant * CL_KeyState (&in_back, pnum);
}
up = CL_KeyState (&in_lookup, pnum);
@ -547,8 +547,8 @@ void CL_AdjustAngles (int pnum, double frametime)
quant = cl_pitchspeed.ival;
if (!ruleset_allow_frj.ival)
quant = bound(-700, quant, 700);
cl.viewanglechange[pnum][PITCH] -= speed*cl_pitchspeed.ival * up;
cl.viewanglechange[pnum][PITCH] += speed*cl_pitchspeed.ival * down;
cl.playerview[pnum].viewanglechange[PITCH] -= speed*cl_pitchspeed.ival * up;
cl.playerview[pnum].viewanglechange[PITCH] += speed*cl_pitchspeed.ival * down;
if (up || down)
V_StopPitchDrift (pnum);
@ -612,7 +612,7 @@ void CL_ClampPitch (int pnum)
static float oldtime;
float timestep = realtime - oldtime;
oldtime = realtime;
#if 0
if (cl.pmovetype[pnum] == PM_WALLWALK)
{
AngleVectors(cl.viewangles[pnum], view[0], view[1], view[2]);
@ -644,11 +644,99 @@ void CL_ClampPitch (int pnum)
return;
}
#endif
#if 1
if (1)
{
float surfm[16], invsurfm[16];
float viewm[16];
vec3_t view[4];
vec3_t surf[3];
vec3_t fwd, up;
vec3_t vang;
void PerpendicularVector( vec3_t dst, const vec3_t src );
cl.viewangles[pnum][PITCH] += cl.viewanglechange[pnum][PITCH];
cl.viewangles[pnum][YAW] += cl.viewanglechange[pnum][YAW];
cl.viewangles[pnum][ROLL] += cl.viewanglechange[pnum][ROLL];
VectorClear(cl.viewanglechange[pnum]);
/*calc current view matrix relative to the surface*/
AngleVectors(cl.playerview[pnum].viewangles, view[0], view[1], view[2]);
VectorNegate(view[1], view[1]);
/*calculate the surface axis with up from the pmove code and right/forwards relative to the player's directions*/
if (!cl.playerview[pnum].gravitydir[0] && !cl.playerview[pnum].gravitydir[1] && !cl.playerview[pnum].gravitydir[2])
{
VectorSet(surf[2], 0, 0, 1);
}
else
{
VectorNegate(cl.playerview[pnum].gravitydir, surf[2]);
}
VectorNormalize(surf[2]);
PerpendicularVector(surf[1], surf[2]);
VectorNormalize(surf[1]);
CrossProduct(surf[2], surf[1], surf[0]);
VectorNegate(surf[0], surf[0]);
VectorNormalize(surf[0]);
Matrix4x4_RM_FromVectors(surfm, surf[0], surf[1], surf[2], vec3_origin);
Matrix3x4_InvertTo4x4_Simple(surfm, invsurfm);
/*calc current view matrix relative to the surface*/
Matrix4x4_RM_FromVectors(viewm, view[0], view[1], view[2], vec3_origin);
Matrix4_Multiply(viewm, invsurfm, mat);
/*convert that back to angles*/
Matrix3x4_RM_ToVectors(mat, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], vang);
vang[PITCH] *= -1;
/*edit it*/
if (vang[PITCH] < -180)
vang[PITCH] += 360;
if (vang[PITCH] > 180)
vang[PITCH] -= 360;
if (vang[ROLL] > 180)
vang[ROLL] -= 360;
vang[PITCH] += cl.playerview[pnum].viewanglechange[PITCH];
vang[YAW] += cl.playerview[pnum].viewanglechange[YAW];
/*keep the player looking relative to their ground (smoothlyish)*/
if (!vang[ROLL])
{
if (!cl.playerview[pnum].viewanglechange[PITCH] && !cl.playerview[pnum].viewanglechange[YAW] && !cl.playerview[pnum].viewanglechange[ROLL])
return;
}
else
{
if (fabs(vang[ROLL]) < host_frametime*180)
vang[ROLL] = 0;
else if (vang[ROLL] > 0)
vang[ROLL] -= host_frametime*180;
else
vang[ROLL] += host_frametime*180;
}
VectorClear(cl.playerview[pnum].viewanglechange);
/*clamp pitch*/
if (vang[PITCH] > cl.maxpitch)
vang[PITCH] = cl.maxpitch;
if (vang[PITCH] < cl.minpitch)
vang[PITCH] = cl.minpitch;
/*turn those angles back to a matrix*/
AngleVectors(vang, view[0], view[1], view[2]);
VectorNegate(view[1], view[1]);
Matrix4x4_RM_FromVectors(mat, view[0], view[1], view[2], vec3_origin);
/*rotate back into world space*/
Matrix4_Multiply(mat, surfm, viewm);
/*and figure out the final result*/
Matrix3x4_RM_ToVectors(viewm, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], cl.playerview[pnum].viewangles);
cl.playerview[pnum].viewangles[PITCH] *= -1;
if (cl.playerview[pnum].viewangles[PITCH] < -180)
cl.playerview[pnum].viewangles[PITCH] += 360;
return;
}
#endif
cl.playerview[pnum].viewangles[PITCH] += cl.playerview[pnum].viewanglechange[PITCH];
cl.playerview[pnum].viewangles[YAW] += cl.playerview[pnum].viewanglechange[YAW];
cl.playerview[pnum].viewangles[ROLL] += cl.playerview[pnum].viewanglechange[ROLL];
VectorClear(cl.playerview[pnum].viewanglechange);
#ifdef Q2CLIENT
if (cls.protocol == CP_QUAKE2)
@ -658,15 +746,15 @@ void CL_ClampPitch (int pnum)
if (pitch > 180)
pitch -= 360;
if (cl.viewangles[pnum][PITCH] + pitch < -360)
cl.viewangles[pnum][PITCH] += 360; // wrapped
if (cl.viewangles[pnum][PITCH] + pitch > 360)
cl.viewangles[pnum][PITCH] -= 360; // wrapped
if (cl.playerview[pnum].viewangles[PITCH] + pitch < -360)
cl.playerview[pnum].viewangles[PITCH] += 360; // wrapped
if (cl.playerview[pnum].viewangles[PITCH] + pitch > 360)
cl.playerview[pnum].viewangles[PITCH] -= 360; // wrapped
if (cl.viewangles[pnum][PITCH] + pitch > cl.maxpitch)
cl.viewangles[pnum][PITCH] = cl.maxpitch - pitch;
if (cl.viewangles[pnum][PITCH] + pitch < cl.minpitch)
cl.viewangles[pnum][PITCH] = cl.minpitch - pitch;
if (cl.playerview[pnum].viewangles[PITCH] + pitch > cl.maxpitch)
cl.playerview[pnum].viewangles[PITCH] = cl.maxpitch - pitch;
if (cl.playerview[pnum].viewangles[PITCH] + pitch < cl.minpitch)
cl.playerview[pnum].viewangles[PITCH] = cl.minpitch - pitch;
}
else
#endif
@ -678,23 +766,23 @@ void CL_ClampPitch (int pnum)
else
#endif
{
if (cl.fixangle[pnum])
if (cl.playerview[pnum].fixangle)
return;
if (cl.viewangles[pnum][PITCH] > cl.maxpitch)
cl.viewangles[pnum][PITCH] = cl.maxpitch;
if (cl.viewangles[pnum][PITCH] < cl.minpitch)
cl.viewangles[pnum][PITCH] = cl.minpitch;
if (cl.playerview[pnum].viewangles[PITCH] > cl.maxpitch)
cl.playerview[pnum].viewangles[PITCH] = cl.maxpitch;
if (cl.playerview[pnum].viewangles[PITCH] < cl.minpitch)
cl.playerview[pnum].viewangles[PITCH] = cl.minpitch;
}
// if (cl.viewangles[pnum][ROLL] > 50)
// cl.viewangles[pnum][ROLL] = 50;
// if (cl.viewangles[pnum][ROLL] < -50)
// cl.viewangles[pnum][ROLL] = -50;
roll = timestep*cl.viewangles[pnum][ROLL]*30;
if ((cl.viewangles[pnum][ROLL]-roll < 0) != (cl.viewangles[pnum][ROLL]<0))
cl.viewangles[pnum][ROLL] = 0;
roll = timestep*cl.playerview[pnum].viewangles[ROLL]*30;
if ((cl.playerview[pnum].viewangles[ROLL]-roll < 0) != (cl.playerview[pnum].viewangles[ROLL]<0))
cl.playerview[pnum].viewangles[ROLL] = 0;
else
cl.viewangles[pnum][ROLL] -= timestep*cl.viewangles[pnum][ROLL]*3;
cl.playerview[pnum].viewangles[ROLL] -= timestep*cl.playerview[pnum].viewangles[ROLL]*3;
}
/*
@ -738,7 +826,7 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum)
cmd->msec = msecs;
for (i=0 ; i<3 ; i++)
cmd->angles[i] = ((int)(cl.viewangles[pnum][i]*65536.0/360)&65535);
cmd->angles[i] = ((int)(cl.playerview[pnum].viewangles[i]*65536.0/360)&65535);
if (in_impulsespending[pnum] && !cl.paused)
{
@ -819,7 +907,7 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso
temp[2] = 1;
VectorCopy(r_origin, cursor_start);
Matrix4x4_CM_UnProject(temp, cursor_end, cl.viewangles[0], cursor_start, r_refdef.fov_x, r_refdef.fov_y);
Matrix4x4_CM_UnProject(temp, cursor_end, cl.playerview[0].viewangles, cursor_start, r_refdef.fov_x, r_refdef.fov_y);
CL_SetSolidEntities();
//don't bother with players, they don't exist in NQ...
@ -859,9 +947,9 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
for (i=0 ; i<3 ; i++)
{
if (cls.protocol_nq == CPNQ_FITZ666 || cls.protocol_nq == CPNQ_PROQUAKE3_4)
MSG_WriteAngle16 (buf, cl.viewangles[pnum][i]);
MSG_WriteAngle16 (buf, cl.playerview[pnum].viewangles[i]);
else
MSG_WriteAngle (buf, cl.viewangles[pnum][i]);
MSG_WriteAngle (buf, cl.playerview[pnum].viewangles[i]);
}
MSG_WriteShort (buf, cmd->forwardmove);
@ -987,7 +1075,7 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
return; //no point.
va_start (argptr, format);
vsnprintf (string,sizeof(string)-1, format,argptr);
Q_vsnprintfz (string,sizeof(string), format,argptr);
va_end (argptr);
@ -1250,7 +1338,7 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf)
else
MSG_WriteLong (buf, cl.q2frame.serverframe);
lightlev = R_LightPoint(cl.simorg[0]);
lightlev = R_LightPoint(cl.playerview[0].simorg);
// msecs = msecs - (double)msecstouse;
@ -1561,7 +1649,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
VectorClear(mousemovements[plnum]);
for (i=0 ; i<3 ; i++)
independantphysics[plnum].angles[i] = ((int)(cl.viewangles[plnum][i]*65536.0/360)&65535);
independantphysics[plnum].angles[i] = ((int)(cl.playerview[plnum].viewangles[i]*65536.0/360)&65535);
if (!independantphysics[plnum].msec)
{
@ -1745,7 +1833,7 @@ static char *VARGS vahunk(char *format, ...)
char *ret;
va_start (argptr, format);
vsnprintf (string,sizeof(string)-1, format,argptr);
Q_vsnprintfz (string,sizeof(string), format,argptr);
va_end (argptr);
ret = Hunk_Alloc(strlen(string)+1);

View File

@ -1119,15 +1119,11 @@ void CL_ClearState (void)
rtlights_first = rtlights_max = RTL_FIRST;
if (cl_baselines)
{
BZ_Free(cl_baselines);
cl_baselines = NULL;
}
cl_baselines_count = 0;
for (i = 0; i < MAX_SPLITS; i++)
{
VectorSet(cl.playerview[i].gravitydir, 0, 0, -1);
cl.viewheight[i] = DEFAULT_VIEWHEIGHT;
}
cl.minpitch = -70;
cl.maxpitch = 80;
@ -1230,34 +1226,7 @@ void CL_Disconnect (void)
cl.worldmodel = NULL;
}
if (cls.downloadmethod <= DL_QWPENDING)
cls.downloadmethod = DL_NONE;
if (cls.downloadqw)
{
VFS_CLOSE(cls.downloadqw);
cls.downloadqw = NULL;
}
if (!cls.downloadmethod)
{
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
}
{
downloadlist_t *next;
while(cl.downloadlist)
{
next = cl.downloadlist->next;
Z_Free(cl.downloadlist);
cl.downloadlist = next;
}
while(cl.faileddownloads)
{
next = cl.faileddownloads->next;
Z_Free(cl.faileddownloads);
cl.faileddownloads = next;
}
}
CL_Parse_Disconnected();
COM_FlushTempoaryPacks();
@ -1294,6 +1263,8 @@ void CL_Disconnect (void)
#endif
Cvar_ForceSet(&cl_servername, "none");
CL_ClearState();
}
#undef serverrunning
@ -3665,9 +3636,9 @@ double Host_Frame (double time)
SCR_UpdateScreen ();
if (cls.state >= ca_active && r_viewleaf)
SNDDMA_SetUnderWater(r_viewleaf->contents <= Q1CONTENTS_WATER);
S_SetUnderWater(r_viewleaf->contents <= Q1CONTENTS_WATER);
else
SNDDMA_SetUnderWater(false);
S_SetUnderWater(false);
}
if (host_speeds.ival)
@ -4015,6 +3986,8 @@ void Host_Shutdown(void)
}
host_initialized = false;
Plug_Shutdown();
//disconnect server/client/etc
CL_Disconnect_f();
//Kill renderer
@ -4037,12 +4010,12 @@ void Host_Shutdown(void)
#else
NET_Shutdown ();
#endif
FS_Shutdown();
Cvar_Shutdown();
Validation_FlushFileList();
Cmd_Shutdown();
Key_Unbindall_f();
Con_Shutdown();
Memory_DeInit();
@ -4051,6 +4024,8 @@ void Host_Shutdown(void)
memset(&svs, 0, sizeof(svs));
#endif
Sys_Shutdown();
FS_Shutdown();
}
#ifdef CLIENTONLY

View File

@ -247,6 +247,41 @@ double parsecounttime;
int cl_spikeindex, cl_playerindex, cl_h_playerindex, cl_flagindex, cl_rocketindex, cl_grenadeindex, cl_gib1index, cl_gib2index, cl_gib3index;
//called after disconnect, purges all memory that was allocated etc
void CL_Parse_Disconnected(void)
{
if (cls.downloadmethod <= DL_QWPENDING)
cls.downloadmethod = DL_NONE;
if (cls.downloadqw)
{
VFS_CLOSE(cls.downloadqw);
cls.downloadqw = NULL;
}
if (!cls.downloadmethod)
{
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
}
{
downloadlist_t *next;
while(cl.downloadlist)
{
next = cl.downloadlist->next;
Z_Free(cl.downloadlist);
cl.downloadlist = next;
}
while(cl.faileddownloads)
{
next = cl.faileddownloads->next;
Z_Free(cl.faileddownloads);
cl.faileddownloads = next;
}
}
CL_ClearParseState();
}
//=============================================================================
int packet_latency[NET_TIMINGS];
@ -2190,6 +2225,20 @@ void CL_ClearParseState(void)
cl_gib1index = -1;
cl_gib2index = -1;
cl_gib3index = -1;
if (cl_baselines)
{
BZ_Free(cl_baselines);
cl_baselines = NULL;
}
cl_baselines_count = 0;
cl_max_static_entities = 0;
if (cl_static_entities)
{
BZ_Free(cl_static_entities);
cl_static_entities = NULL;
}
}
/*
@ -3389,7 +3438,10 @@ void CL_ParseBaseline2 (void)
{
entity_state_t es;
CLQW_ParseDelta(&nullentitystate, &es, (unsigned short)MSG_ReadShort(), true);
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
CLFTE_ParseBaseline(&es, true);
else
CLQW_ParseDelta(&nullentitystate, &es, (unsigned short)MSG_ReadShort(), true);
if (!CL_CheckBaselines(es.number))
Host_EndGame("CL_ParseBaseline2: check baselines failed with size %i", es.number);
memcpy(cl_baselines + es.number, &es, sizeof(es));
@ -3455,7 +3507,10 @@ void CL_ParseStatic (int version)
}
else
{
CLQW_ParseDelta(&nullentitystate, &es, MSG_ReadShort(), true);
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
CLFTE_ParseBaseline(&es, false);
else
CLQW_ParseDelta(&nullentitystate, &es, MSG_ReadShort(), true);
es.number+=MAX_EDICTS;
for (i = 0; i < cl.num_statics; i++)
@ -4041,28 +4096,28 @@ CL_SetStat
static void CL_SetStat_Internal (int pnum, int stat, int value)
{
int j;
if (cl.stats[pnum][stat] != value)
if (cl.playerview[pnum].stats[stat] != value)
Sbar_Changed ();
if (stat == STAT_ITEMS)
{ // set flash times
for (j=0 ; j<32 ; j++)
if ( (value & (1<<j)) && !(cl.stats[pnum][stat] & (1<<j)))
cl.item_gettime[pnum][j] = cl.time;
if ( (value & (1<<j)) && !(cl.playerview[pnum].stats[stat] & (1<<j)))
cl.playerview[pnum].item_gettime[j] = cl.time;
}
if (stat == STAT_WEAPON)
{
if (cl.stats[pnum][stat] != value)
if (cl.playerview[pnum].stats[stat] != value)
{
if (value == 0)
TP_ExecTrigger ("f_reloadstart");
else if (cl.stats[pnum][stat] == 0)
else if (cl.playerview[pnum].stats[stat] == 0)
TP_ExecTrigger ("f_reloadend");
}
}
cl.stats[pnum][stat] = value;
cl.playerview[pnum].stats[stat] = value;
if (pnum == 0)
TP_StatChanged(stat, value);
@ -4108,10 +4163,10 @@ void CL_SetStatFloat (int pnum, int stat, float value)
for (pnum = 0; pnum < cl.splitclients; pnum++)
if (spec_track[pnum] == cls_lastto)
cl.statsf[pnum][stat] = value;
cl.playerview[pnum].statsf[stat] = value;
}
else
cl.statsf[pnum][stat] = value;
cl.playerview[pnum].statsf[stat] = value;
if (stat == STAT_VIEWHEIGHT && cls.z_ext & Z_EXT_VIEWHEIGHT)
cl.viewheight[pnum] = value;
@ -4133,10 +4188,10 @@ void CL_SetStatString (int pnum, int stat, char *value)
}
else
{
if (cl.statsstr[pnum][stat])
Z_Free(cl.statsstr[pnum][stat]);
cl.statsstr[pnum][stat] = Z_Malloc(strlen(value)+1);
strcpy(cl.statsstr[pnum][stat], value);
if (cl.playerview[pnum].statsstr[stat])
Z_Free(cl.playerview[pnum].statsstr[stat]);
cl.playerview[pnum].statsstr[stat] = Z_Malloc(strlen(value)+1);
strcpy(cl.playerview[pnum].statsstr[stat], value);
}
}
/*
@ -4272,7 +4327,7 @@ void CLQ2_ParseMuzzleFlash (void)
break;
case Q2MZ_MACHINEGUN:
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
break;
@ -4288,27 +4343,27 @@ void CLQ2_ParseMuzzleFlash (void)
case Q2MZ_CHAINGUN1:
dl->radius = 200 + (rand()&31);
dl->color[0] = 0.2;dl->color[1] = 0.05;dl->color[2] = 0;
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
break;
case Q2MZ_CHAINGUN2:
dl->radius = 225 + (rand()&31);
dl->color[0] = 0.2;dl->color[1] = 0.1;dl->color[2] = 0;
dl->die = cl.time + 0.1; // long delay
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_AUTO, S_PrecacheSound(soundname), volume, ATTN_NORM, 0.05);
break;
case Q2MZ_CHAINGUN3:
dl->radius = 250 + (rand()&31);
dl->color[0] = 0.2;dl->color[1] = 0.2;dl->color[2] = 0;
dl->die = cl.time + 0.1; // long delay
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_WEAPON, S_PrecacheSound(soundname), volume, ATTN_NORM, 0);
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_AUTO, S_PrecacheSound(soundname), volume, ATTN_NORM, 0.033);
snprintf(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q_snprintfz(soundname, sizeof(soundname), "weapons/machgf%ib.wav", (rand() % 5) + 1);
Q2S_StartSound (NULL, i, CHAN_AUTO, S_PrecacheSound(soundname), volume, ATTN_NORM, 0.066);
break;
@ -5012,6 +5067,8 @@ void CL_ParsePrecache(void)
else
Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS);
break;
case 0x4000:
break;
case 0x8000:
if (i >= 1 && i < MAX_SOUNDS)
{
@ -5027,6 +5084,11 @@ void CL_ParsePrecache(void)
else
Con_Printf("svc_precache: sound index %i outside range %i...%i\n", i, 1, MAX_SOUNDS);
break;
case 0xC000:
if (i >= 1 && i < 1024)
{
}
break;
}
}
@ -5083,7 +5145,7 @@ void CLQW_ParseServerMessage (void)
cl.last_servermessage = realtime;
CL_ClearProjectiles ();
for (i = 0; i < MAX_SPLITS; i++)
cl.fixangle[i] = false;
cl.playerview[i].fixangle = false;
//
// if recording demos, copy the message out
@ -5231,8 +5293,8 @@ void CLQW_ParseServerMessage (void)
#endif
case svcfte_setangledelta:
for (i=0 ; i<3 ; i++)
cl.viewangles[destsplit][i] += MSG_ReadAngle16 ();
VectorCopy (cl.viewangles[destsplit], cl.simangles[destsplit]);
cl.playerview[destsplit].viewangles[i] += MSG_ReadAngle16 ();
VectorCopy (cl.playerview[destsplit].viewangles, cl.playerview[destsplit].simangles);
break;
case svc_setangle:
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
@ -5245,20 +5307,20 @@ void CLQW_ParseServerMessage (void)
{
if (Cam_TrackNum(j) == i)
{
cl.fixangle[j]=true;
VectorCopy(ang, cl.simangles[j]);
VectorCopy(ang, cl.viewangles[j]);
VectorCopy(ang, cl.fixangles[j]);
cl.playerview[j].fixangle=true;
VectorCopy(ang, cl.playerview[j].simangles);
VectorCopy(ang, cl.playerview[j].viewangles);
VectorCopy(ang, cl.playerview[j].fixangles);
}
}
break;
}
cl.fixangle[destsplit]=true;
cl.playerview[destsplit].fixangle=true;
for (i=0 ; i<3 ; i++)
cl.viewangles[destsplit][i] = cl.fixangles[destsplit][i] = MSG_ReadAngle ();
cl.playerview[destsplit].viewangles[i] = cl.playerview[destsplit].fixangles[i] = MSG_ReadAngle ();
VectorCopy (cl.viewangles[destsplit], cl.simangles[destsplit]);
// cl.viewangles[PITCH] = cl.viewangles[ROLL] = 0;
VectorCopy (cl.playerview[destsplit].viewangles, cl.playerview[destsplit].simangles);
// cl.playerview[destsplit].viewangles[PITCH] = cl.viewangles[ROLL] = 0;
break;
case svc_lightstyle:
@ -5372,11 +5434,11 @@ void CLQW_ParseServerMessage (void)
break;
case svc_killedmonster:
cl.stats[destsplit][STAT_MONSTERS]++;
cl.playerview[destsplit].stats[STAT_MONSTERS]++;
break;
case svc_foundsecret:
cl.stats[destsplit][STAT_SECRETS]++;
cl.playerview[destsplit].stats[STAT_SECRETS]++;
break;
case svc_updatestat:
@ -5420,18 +5482,18 @@ void CLQW_ParseServerMessage (void)
cl.completed_time = cl.gametime;
vid.recalc_refdef = true; // go to full screen
for (i=0 ; i<3 ; i++)
cl.simorg[destsplit][i] = MSG_ReadCoord ();
cl.playerview[destsplit].simorg[i] = MSG_ReadCoord ();
for (i=0 ; i<3 ; i++)
cl.simangles[destsplit][i] = MSG_ReadAngle ();
VectorCopy (cl.simangles[destsplit], cl.fixangles[destsplit]);
VectorClear (cl.simvel[destsplit]);
cl.playerview[destsplit].simangles[i] = MSG_ReadAngle ();
VectorCopy (cl.playerview[destsplit].simangles, cl.playerview[destsplit].fixangles);
VectorClear (cl.playerview[destsplit].simvel);
break;
case svc_finale:
if (!cl.intermission)
for (i = 0; i < MAX_SPLITS; i++)
cl.simorg[i][2] += cl.viewheight[i];
VectorCopy (cl.fixangles[destsplit], cl.simangles[destsplit]);
cl.playerview[i].simorg[2] += cl.viewheight[i];
VectorCopy (cl.playerview[destsplit].fixangles, cl.playerview[destsplit].simangles);
cl.intermission = 2;
cl.completed_time = cl.gametime;
@ -5575,13 +5637,13 @@ void CLQW_ParseServerMessage (void)
break;
case svcfte_trailparticles:
CLDP_ParseTrailParticles();
CL_ParseTrailParticles();
break;
case svcfte_pointparticles:
CLDP_ParsePointParticles(false);
CL_ParsePointParticles(false);
break;
case svcfte_pointparticles1:
CLDP_ParsePointParticles(true);
CL_ParsePointParticles(true);
break;
case svcfte_cgamepacket:
@ -6103,9 +6165,9 @@ void CLNQ_ParseServerMessage (void)
break;
case svc_time:
cl.oldfixangle[0] = cl.fixangle[0];
VectorCopy(cl.fixangles[0], cl.oldfixangles[0]);
cl.fixangle[0] = false;
cl.playerview[0].oldfixangle = cl.playerview[0].fixangle;
VectorCopy(cl.playerview[0].fixangles, cl.playerview[0].oldfixangles);
cl.playerview[0].fixangle = false;
cls.netchan.outgoing_sequence++;
cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence-1;
@ -6208,9 +6270,9 @@ void CLNQ_ParseServerMessage (void)
CL_SetStatFloat (0, i, j);
break;
case svc_setangle:
cl.fixangle[0]=true;
cl.playerview[0].fixangle=true;
for (i=0 ; i<3 ; i++)
cl.viewangles[0][i] = cl.fixangles[0][i] = MSG_ReadAngle ();
cl.playerview[0].viewangles[i] = cl.playerview[0].fixangles[i] = MSG_ReadAngle ();
// cl.viewangles[PITCH] = cl.viewangles[ROLL] = 0;
break;
@ -6235,11 +6297,11 @@ void CLNQ_ParseServerMessage (void)
break;
case svc_killedmonster:
cl.stats[0][STAT_MONSTERS]++;
cl.playerview[0].stats[STAT_MONSTERS]++;
break;
case svc_foundsecret:
cl.stats[0][STAT_SECRETS]++;
cl.playerview[0].stats[STAT_SECRETS]++;
break;
case svc_intermission:
@ -6328,13 +6390,13 @@ void CLNQ_ParseServerMessage (void)
break;
case svcdp_trailparticles:
CLDP_ParseTrailParticles();
CL_ParseTrailParticles();
break;
case svcdp_pointparticles:
CLDP_ParsePointParticles(false);
CL_ParsePointParticles(false);
break;
case svcdp_pointparticles1:
CLDP_ParsePointParticles(true);
CL_ParsePointParticles(true);
break;
}

View File

@ -285,7 +285,7 @@ qintptr_t VARGS Plug_CL_GetStats(void *offset, quintptr_t mask, const qintptr_t
max = MAX_CL_STATS;
for (i = 0; i < max; i++)
{ //fill stats with the right player's stats
stats[i] = cl.stats[pnum][i];
stats[i] = cl.playerview[pnum].stats[i];
}
for (; i < pluginstats; i++) //plugin has too many stats (wow)
stats[i] = 0; //fill the rest.

View File

@ -235,6 +235,7 @@ void CLQ2_PredictMovement (void) //q2 doesn't support split clients.
int oldz;
#endif
int i;
int pnum = 0;
if (cls.state != ca_active)
return;
@ -248,7 +249,7 @@ void CLQ2_PredictMovement (void) //q2 doesn't support split clients.
{ // just set angles
for (i=0 ; i<3 ; i++)
{
cl.predicted_angles[i] = cl.viewangles[0][i] + SHORT2ANGLE(cl.q2frame.playerstate.pmove.delta_angles[i]);
cl.predicted_angles[i] = cl.playerview[pnum].viewangles[i] + SHORT2ANGLE(cl.q2frame.playerstate.pmove.delta_angles[i]);
}
return;
}
@ -378,6 +379,7 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
VectorCopy (from->origin, pmove.origin);
VectorCopy (u->angles, pmove.angles);
VectorCopy (from->velocity, pmove.velocity);
VectorCopy (from->gravitydir, pmove.gravitydir);
if (!(pmove.velocity[0] == 0) && !(pmove.velocity[0] != 0))
{
@ -413,6 +415,7 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
VectorCopy (pmove.origin, to->origin);
VectorCopy (pmove.angles, to->viewangles);
VectorCopy (pmove.velocity, to->velocity);
VectorCopy (pmove.gravitydir, to->gravitydir);
to->onground = pmove.onground;
to->weaponframe = from->weaponframe;
@ -432,7 +435,7 @@ void CL_CatagorizePosition (int pnum)
return;
}
VectorClear (pmove.velocity);
VectorCopy (cl.simorg[pnum], pmove.origin);
VectorCopy (cl.playerview[pnum].simorg, pmove.origin);
pmove.numtouch = 0;
PM_CategorizePosition ();
cl.onground[pnum] = pmove.onground;
@ -446,50 +449,50 @@ void CL_CalcCrouch (int pnum, float stepchange)
static float oldz[MAX_SPLITS] = {0}, extracrouch[MAX_SPLITS] = {0}, crouchspeed[MAX_SPLITS] = {100,100};
vec3_t delta;
VectorSubtract(cl.simorg[pnum], oldorigin[pnum], delta);
VectorSubtract(cl.playerview[pnum].simorg, oldorigin[pnum], delta);
teleported = Length(delta)>48;
VectorCopy (cl.simorg[pnum], oldorigin[pnum]);
VectorCopy (cl.playerview[pnum].simorg, oldorigin[pnum]);
if (teleported)
{
// possibly teleported or respawned
oldz[pnum] = cl.simorg[pnum][2];
oldz[pnum] = cl.playerview[pnum].simorg[2];
extracrouch[pnum] = 0;
crouchspeed[pnum] = 100;
cl.crouch[pnum] = 0;
VectorCopy (cl.simorg[pnum], oldorigin[pnum]);
VectorCopy (cl.playerview[pnum].simorg, oldorigin[pnum]);
return;
}
if (cl.onground[pnum] && cl.simorg[pnum][2] - oldz[pnum] > 0)
if (cl.onground[pnum] && cl.playerview[pnum].simorg[2] - oldz[pnum] > 0)
{
if (cl.simorg[pnum][2] - oldz[pnum] > movevars.stepheight+2)
if (cl.playerview[pnum].simorg[2] - oldz[pnum] > movevars.stepheight+2)
{
// if on steep stairs, increase speed
if (crouchspeed[pnum] < 160)
{
extracrouch[pnum] = cl.simorg[pnum][2] - oldz[pnum] - host_frametime * 200 - 15;
extracrouch[pnum] = cl.playerview[pnum].simorg[2] - oldz[pnum] - host_frametime * 200 - 15;
extracrouch[pnum] = min(extracrouch[pnum], 5);
}
crouchspeed[pnum] = 160;
}
oldz[pnum] += host_frametime * crouchspeed[pnum];
if (oldz[pnum] > cl.simorg[pnum][2])
oldz[pnum] = cl.simorg[pnum][2];
if (oldz[pnum] > cl.playerview[pnum].simorg[2])
oldz[pnum] = cl.playerview[pnum].simorg[2];
if (cl.simorg[pnum][2] - oldz[pnum] > 15 + extracrouch[pnum])
oldz[pnum] = cl.simorg[pnum][2] - 15 - extracrouch[pnum];
if (cl.playerview[pnum].simorg[2] - oldz[pnum] > 15 + extracrouch[pnum])
oldz[pnum] = cl.playerview[pnum].simorg[2] - 15 - extracrouch[pnum];
extracrouch[pnum] -= host_frametime * 200;
extracrouch[pnum] = max(extracrouch[pnum], 0);
cl.crouch[pnum] = oldz[pnum] - cl.simorg[pnum][2];
cl.crouch[pnum] = oldz[pnum] - cl.playerview[pnum].simorg[2];
}
else
{
// in air or moving down
oldz[pnum] = cl.simorg[pnum][2];
oldz[pnum] = cl.playerview[pnum].simorg[2];
cl.crouch[pnum] += host_frametime * 150;
if (cl.crouch[pnum] > 0)
cl.crouch[pnum] = 0;
@ -552,11 +555,11 @@ static void CL_LerpMove (int pnum, float msgtime)
VectorCopy (lerp_origin[1], lerp_origin[2]);
VectorCopy (lerp_origin[0], lerp_origin[1]);
VectorCopy (cl.simorg[pnum], lerp_origin[0]);
VectorCopy (cl.playerview[pnum].simorg, lerp_origin[0]);
VectorCopy (lerp_angles[1], lerp_angles[2]);
VectorCopy (lerp_angles[0], lerp_angles[1]);
VectorCopy (cl.simangles[pnum], lerp_angles[0]);
VectorCopy (cl.playerview[pnum].simangles, lerp_angles[0]);
nolerp[1] = nolerp[0];
nolerp[0] = false;
@ -608,9 +611,9 @@ static void CL_LerpMove (int pnum, float msgtime)
for (i=0 ; i<3 ; i++)
{
cl.simorg[pnum][i] = lerp_origin[from][i] +
cl.playerview[pnum].simorg[i] = lerp_origin[from][i] +
frac * (lerp_origin[to][i] - lerp_origin[from][i]);
cl.simangles[pnum][i] = LerpAngles360(lerp_angles[from][i], lerp_angles[to][i], frac);
cl.playerview[pnum].simangles[i] = LerpAngles360(lerp_angles[from][i], lerp_angles[to][i], frac);
}
// LerpVector (lerp_origin[from], lerp_origin[to], frac, cl.simorg);
@ -776,6 +779,7 @@ static void CL_DecodeStateSize(unsigned short solid, int modelindex, vec3_t mins
void CL_PlayerFrameUpdated(player_state_t *plstate, entity_state_t *state, int sequence)
{
/*update the prediction info*/
vec3_t a;
int pmtype, i;
switch(state->u.q1.pmovetype)
{
@ -812,14 +816,19 @@ void CL_PlayerFrameUpdated(player_state_t *plstate, entity_state_t *state, int s
VectorScale(state->u.q1.velocity, 1/8.0, plstate->velocity);
plstate->messagenum = sequence;
a[0] = ((-192-state->u.q1.gravitydir[0])/256.0f) * 360;
a[1] = (state->u.q1.gravitydir[1]/256.0f) * 360;
a[2] = 0;
AngleVectors(a, plstate->gravitydir, NULL, NULL);
cl.players[state->number-1].stats[STAT_WEAPONFRAME] = state->u.q1.weaponframe;
cl.players[state->number-1].statsf[STAT_WEAPONFRAME] = state->u.q1.weaponframe;
for (i = 0; i < cl.splitclients; i++)
{
if (cl.playernum[i] == state->number-1)
{
cl.stats[i][STAT_WEAPONFRAME] = state->u.q1.weaponframe;
cl.statsf[i][STAT_WEAPONFRAME] = state->u.q1.weaponframe;
cl.playerview[i].stats[STAT_WEAPONFRAME] = state->u.q1.weaponframe;
cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->u.q1.weaponframe;
}
}
@ -926,7 +935,7 @@ void CL_PredictMovePNum (int pnum)
if (cls.netchan.outgoing_sequence - cl.ackedinputsequence >= UPDATE_BACKUP-1)
{ //lagging like poo.
if (!cl.intermission) //keep the angles working though.
VectorCopy (cl.viewangles[pnum], cl.simangles[pnum]);
VectorCopy (cl.playerview[pnum].viewangles, cl.playerview[pnum].simangles);
return;
}
@ -935,7 +944,7 @@ void CL_PredictMovePNum (int pnum)
if (!cl.intermission)
{
VectorCopy (cl.viewangles[pnum], cl.simangles[pnum]);
VectorCopy (cl.playerview[pnum].viewangles, cl.playerview[pnum].simangles);
}
vel = from->playerstate[cl.playernum[pnum]].velocity;
@ -968,7 +977,7 @@ void CL_PredictMovePNum (int pnum)
}
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle[pnum] || cl.paused))
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.playerview[pnum].fixangle || cl.paused))
{
if (cl_lerp_players.ival && !cls.demoplayback)
{
@ -978,8 +987,8 @@ void CL_PredictMovePNum (int pnum)
}
fixedorg:
VectorCopy (vel, cl.simvel[pnum]);
VectorCopy (org, cl.simorg[pnum]);
VectorCopy (vel, cl.playerview[pnum].simvel);
VectorCopy (org, cl.playerview[pnum].simorg);
to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK];
@ -1004,7 +1013,7 @@ fixedorg:
lerpents_t *le = &cl.lerpplayers[spec_track[pnum]];
org = le->origin;
vel = vec3_origin;
VectorCopy(le->angles, cl.simangles[pnum]);
VectorCopy(le->angles, cl.playerview[pnum].simangles);
goto fixedorg;
}
@ -1032,7 +1041,7 @@ fixedorg:
lrpv[i] = to->playerstate[spec_track[pnum]].velocity[i] +
f * (from->playerstate[spec_track[pnum]].velocity[i] - to->playerstate[spec_track[pnum]].velocity[i]);
cl.simangles[pnum][i] = LerpAngles16(to->playerstate[spec_track[pnum]].command.angles[i], from->playerstate[spec_track[pnum]].command.angles[i], f)*360.0f/65535;
cl.playerview[pnum].simangles[i] = LerpAngles16(to->playerstate[spec_track[pnum]].command.angles[i], from->playerstate[spec_track[pnum]].command.angles[i], f)*360.0f/65535;
}
org = lrp;
@ -1048,8 +1057,8 @@ fixedorg:
to = &cl.frames[(cls.netchan.outgoing_sequence-1) & UPDATE_MASK];
to->playerstate->pm_type = PM_SPECTATOR;
VectorCopy (cl.simvel[pnum], from->playerstate[cl.playernum[pnum]].velocity);
VectorCopy (cl.simorg[pnum], from->playerstate[cl.playernum[pnum]].origin);
VectorCopy (cl.playerview[pnum].simvel, from->playerstate[cl.playernum[pnum]].velocity);
VectorCopy (cl.playerview[pnum].simorg, from->playerstate[cl.playernum[pnum]].origin);
CL_PredictUsercmd (pnum, cl.playernum[pnum]+1, &from->playerstate[cl.playernum[pnum]], &to->playerstate[cl.playernum[pnum]], &to->cmd[pnum]);
}
@ -1094,8 +1103,8 @@ fixedorg:
if (1)//!independantphysics.msec)
{
VectorCopy (to->playerstate[cl.playernum[pnum]].velocity, cl.simvel[pnum]);
VectorCopy (to->playerstate[cl.playernum[pnum]].origin, cl.simorg[pnum]);
VectorCopy (to->playerstate[cl.playernum[pnum]].velocity, cl.playerview[pnum].simvel);
VectorCopy (to->playerstate[cl.playernum[pnum]].origin, cl.playerview[pnum].simorg);
}
else
{
@ -1115,16 +1124,16 @@ fixedorg:
for (i=0 ; i<3 ; i++)
if ( fabs(org[i] - to->playerstate[cl.playernum[pnum]].origin[i]) > 128)
{ // teleported, so don't lerp
VectorCopy (to->playerstate[cl.playernum[pnum]].velocity, cl.simvel[pnum]);
VectorCopy (to->playerstate[cl.playernum[pnum]].origin, cl.simorg[pnum]);
VectorCopy (to->playerstate[cl.playernum[pnum]].velocity, cl.playerview[pnum].simvel);
VectorCopy (to->playerstate[cl.playernum[pnum]].origin, cl.playerview[pnum].simorg);
goto out;
}
for (i=0 ; i<3 ; i++)
{
cl.simorg[pnum][i] = org[i]
cl.playerview[pnum].simorg[i] = org[i]
+ f*(to->playerstate[cl.playernum[pnum]].origin[i] - org[i]);
cl.simvel[pnum][i] = vel[i]
cl.playerview[pnum].simvel[i] = vel[i]
+ f*(to->playerstate[cl.playernum[pnum]].velocity[i] - vel[i]);
}
CL_CatagorizePosition(pnum);
@ -1137,6 +1146,7 @@ fixedorg:
out:
CL_CalcCrouch (pnum, stepheight);
cl.waterlevel[pnum] = pmove.waterlevel;
VectorCopy(pmove.gravitydir, cl.playerview[pnum].gravitydir);
}
void CL_PredictMove (void)

View File

@ -1021,8 +1021,8 @@ void SCR_CalcRefdef (void)
}
r_refdef.fov_x = scr_fov.value;
if (cl.stats[0][STAT_VIEWZOOM])
r_refdef.fov_x *= cl.stats[0][STAT_VIEWZOOM]/255.0f;
if (cl.playerview[r_refdef.currentplayernum].stats[STAT_VIEWZOOM])
r_refdef.fov_x *= cl.playerview[r_refdef.currentplayernum].stats[STAT_VIEWZOOM]/255.0f;
if (r_refdef.fov_x < 1)
r_refdef.fov_x = 1;
@ -1055,9 +1055,9 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
vec3_t start;
vec3_t right, up, fwds;
AngleVectors(cl.simangles[pnum], fwds, right, up);
AngleVectors(cl.playerview[pnum].simangles, fwds, right, up);
VectorCopy(cl.simorg[pnum], start);
VectorCopy(cl.playerview[pnum].simorg, start);
start[2]+=16;
VectorMA(start, 100000, fwds, end);
@ -1082,7 +1082,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
adj+=v_viewheight.value;
start[2]+=adj;
Matrix4x4_CM_Project(tr.endpos, end, cl.simangles[pnum], start, r_refdef.fov_x, r_refdef.fov_y);
Matrix4x4_CM_Project(tr.endpos, end, cl.playerview[pnum].simangles, start, r_refdef.fov_x, r_refdef.fov_y);
*x = rect.x+rect.width*end[0];
*y = rect.y+rect.height*(1-end[1]);
return;
@ -1349,7 +1349,7 @@ void SCR_DrawUPS (void)
if (track != -1)
vel = cl.frames[cl.validsequence&UPDATE_MASK].playerstate[track].velocity;
else
vel = cl.simvel[0];
vel = cl.playerview[0].simvel;
lastups = sqrt((vel[0]*vel[0]) + (vel[1]*vel[1]));
lastupstime = t;
}

View File

@ -1780,7 +1780,21 @@ void CL_ClearCustomTEnts(void)
customtenttype[i].particleeffecttype = -1;
}
void CLDP_ParseTrailParticles(void)
int CL_TranslateParticleFromServer(int sveffect)
{
if (cl.maxparticleprecaches)
{
/*proper precaches*/
return cl.particle_precache[sveffect].num;
}
else
{
/*server and client must share an identical effectinfo list file (just "effect $name\n" lines)*/
return P_FindParticleType(COM_Effectinfo_ForNumber(sveffect));
}
}
void CL_ParseTrailParticles(void)
{
int entityindex;
int effectindex;
@ -1797,7 +1811,7 @@ void CLDP_ParseTrailParticles(void)
end[1] = MSG_ReadCoord();
end[2] = MSG_ReadCoord();
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
effectindex = CL_TranslateParticleFromServer(effectindex);
if (entityindex && (unsigned int)entityindex < MAX_EDICTS)
ts = &cl.lerpents[entityindex].trailstate;
@ -1808,7 +1822,7 @@ void CLDP_ParseTrailParticles(void)
P_ParticleTrail(start, end, rt_blood, entityindex, ts);
}
void CLDP_ParsePointParticles(qboolean compact)
void CL_ParsePointParticles(qboolean compact)
{
vec3_t org, dir;
unsigned int count, effectindex;
@ -1830,7 +1844,7 @@ void CLDP_ParsePointParticles(qboolean compact)
count = (unsigned short)MSG_ReadShort();
}
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
effectindex = CL_TranslateParticleFromServer(effectindex);
if (P_RunParticleEffectType(org, dir, count, effectindex))
P_RunParticleEffect (org, dir, 15, 15);
@ -2106,6 +2120,10 @@ void CLQ2_ParseTEnt (void)
color = splash_color[r];
P_RunParticleEffect (pos, dir, color, cnt);
if (r == Q2SPLASH_BLUE_WATER || r == Q2SPLASH_BROWN_WATER)
{
P_RunParticleEffectTypeString(pos, dir, 1, "te_watersplash");
}
if (r == Q2SPLASH_SPARKS)
{
r = rand() & 3;
@ -2922,7 +2940,7 @@ void CL_UpdateBeams (void)
vieworg = pl->origin;
}
else
vieworg = cl.simorg[j];
vieworg = cl.playerview[j].simorg;
VectorCopy (vieworg, b->start);
b->start[2] += cl.crouch[j] + bound(-7, v_viewheight.value, 4);
@ -2941,10 +2959,10 @@ void CL_UpdateBeams (void)
ang[0] = -ang[0];
if (ang[0] < -180)
ang[0] += 360;
ang[0] += (cl.simangles[j][0] - ang[0]) * f;
ang[0] += (cl.playerview[j].simangles[0] - ang[0]) * f;
// lerp yaw
delta = cl.simangles[j][1] - ang[1];
delta = cl.playerview[j].simangles[1] - ang[1];
if (delta > 180)
delta -= 360;
if (delta < -180)
@ -2955,7 +2973,7 @@ void CL_UpdateBeams (void)
AngleVectors (ang, fwd, ang, ang);
VectorCopy(fwd, ang);
VectorScale (fwd, len, fwd);
VectorCopy (cl.simorg[j], org);
VectorCopy (cl.playerview[j].simorg, org);
org[2] += 16;
VectorAdd (org, fwd, b->end);

View File

@ -1,12 +1,29 @@
#include "quakedef.h"
#include "glquake.h"
#include "shader.h"
#ifdef _WIN32
#include "winquake.h"
#endif
#ifdef HLCLIENT
extern unsigned int r2d_be_flags;
struct hlcvar_s *QDECL GHL_CVarGetPointer(char *varname);
#define notimp(l) Con_Printf("halflife cl builtin not implemented on line %i\n", l)
#if defined(_MSC_VER)
#if _MSC_VER >= 1300
#define __func__ __FUNCTION__
#else
#define __func__ "unknown"
#endif
#else
//I hope you're c99 and have a __func__
#endif
#define ignore(s) Con_Printf("Fixme: " s "\n")
#define notimpl(l) Con_Printf("halflife cl builtin not implemented on line %i\n", l)
#define notimpf(f) Con_Printf("halflife cl builtin %s not implemented\n", f)
#if HLCLIENT >= 1
#define HLCL_API_VERSION HLCLIENT
@ -16,6 +33,27 @@ struct hlcvar_s *QDECL GHL_CVarGetPointer(char *varname);
void *vgui_panel;
qboolean VGui_Setup(void)
{
void *vguidll;
int (QDECL *init)(void);
dllfunction_t funcs[] =
{
{(void*)&init, "init"},
{NULL}
};
vguidll = Sys_LoadLibrary("vguiwrap", funcs);
if (vguidll)
vgui_panel = init();
return !!vgui_panel;
}
#define HLPIC model_t*
typedef struct
@ -179,7 +217,7 @@ typedef struct
int (QDECL *movetypeisnoclip)(void);
struct hlclent_s *(QDECL *getlocalplayer)(void);
struct hlclent_s *(QDECL *getviewent)(void);
struct hlclent_s *(QDECL *getentidx)(void);
struct hlclent_s *(QDECL *getentidx)(int idx);
float (QDECL *getlocaltime)(void);
void (QDECL *calcshake)(void);
void (QDECL *applyshake)(float *,float *,float);
@ -368,7 +406,7 @@ static mpic_t *getspritepic(HLPIC pic, int frame)
mspriteframe_t *f;
f = getspriteframe(pic, frame);
if (f)
return &f->p;
return f->shader;
return NULL;
}
@ -380,7 +418,7 @@ int QDECL CLGHL_pic_getheight (HLPIC pic, int frame)
if (!pframe)
return 0;
return pframe->p.width;
return pframe->shader->width;
}
int QDECL CLGHL_pic_getwidth (HLPIC pic, int frame)
{
@ -390,7 +428,7 @@ int QDECL CLGHL_pic_getwidth (HLPIC pic, int frame)
if (!pframe)
return 0;
return pframe->p.height;
return pframe->shader->height;
}
void QDECL CLGHL_pic_select (HLPIC pic, int r, int g, int b)
{
@ -432,8 +470,7 @@ void QDECL CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc)
if (!pic)
return;
qglEnable (GL_BLEND);
qglBlendFunc(GL_ONE, GL_ONE);
r2d_be_flags = BEF_FORCEADDITIVE;
//use some kind of alpha
pic->flags |= 1;
@ -453,7 +490,7 @@ void QDECL CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc)
1, 1,
pic);
}
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
r2d_be_flags = 0;
}
void QDECL CLGHL_pic_enablescissor (int x, int y, int width, int height)
{
@ -563,7 +600,7 @@ char *QDECL CLGHL_cvar_getstring (char *name)
void QDECL CLGHL_cmd_register (char *name, xcommand_t func)
{
Cmd_AddRemCommand(name, func);
Cmd_AddCommand(name, func);
}
void QDECL CLGHL_hooknetmsg (char *msgname, void *func)
{
@ -630,7 +667,7 @@ void QDECL CLGHL_startsound_name (char *name, float vol)
Con_Printf ("CLGHL_startsound_name: can't cache %s\n", name);
return;
}
S_StartSound (-1, -1, sfx, vec3_origin, vol, 1);
S_StartSound (-1, -1, sfx, vec3_origin, vol, 1, 0, 0);
}
void QDECL CLGHL_startsound_idx (int idx, float vol)
{
@ -640,7 +677,7 @@ void QDECL CLGHL_startsound_idx (int idx, float vol)
Con_Printf ("CLGHL_startsound_name: index not precached %s\n", name);
return;
}
S_StartSound (-1, -1, sfx, vec3_origin, vol, 1);
S_StartSound (-1, -1, sfx, vec3_origin, vol, 1, 0, 0);
}
void QDECL CLGHL_anglevectors (float *ina, float *outf, float *outr, float *outu)
@ -703,14 +740,14 @@ int QDECL CLGHL_getwindowcentery(void)
}
void QDECL CLGHL_getviewnangles(float*ang)
{
VectorCopy(cl.viewangles[0], ang);
VectorCopy(cl.playerview[0].viewangles, ang);
}
void QDECL CLGHL_setviewnangles(float*ang)
{
VectorCopy(ang, cl.viewangles[0]);
VectorCopy(ang, cl.playerview[0].viewangles);
}
void QDECL CLGHL_getmaxclients(float*ang){notimp(__LINE__);}
void QDECL CLGHL_cvar_setvalue(char *cvarname, char *value){notimp(__LINE__);}
void QDECL CLGHL_getmaxclients(float*ang){notimpf(__func__);}
void QDECL CLGHL_cvar_setvalue(char *cvarname, char *value){notimpf(__func__);}
int QDECL CLGHL_cmd_argc(void)
{
@ -722,10 +759,10 @@ char *QDECL CLGHL_cmd_argv(int i)
}
#define CLGHL_con_printf Con_Printf//void CLGHL_con_printf(char *fmt, ...){notimp(__LINE__);}
#define CLGHL_con_dprintf Con_DPrintf//void CLGHL_con_dprintf(char *fmt, ...){notimp(__LINE__);}
void QDECL CLGHL_con_notificationprintf(int pos, char *fmt, ...){notimp(__LINE__);}
void QDECL CLGHL_con_notificationprintfex(void *info, char *fmt, ...){notimp(__LINE__);}
char *QDECL CLGHL_physkey(char *key){notimp(__LINE__);return NULL;}
char *QDECL CLGHL_serverkey(char *key){notimp(__LINE__);return NULL;}
void QDECL CLGHL_con_notificationprintf(int pos, char *fmt, ...){notimpf(__func__);}
void QDECL CLGHL_con_notificationprintfex(void *info, char *fmt, ...){notimpf(__func__);}
char *QDECL CLGHL_physkey(char *key){notimpf(__func__);return NULL;}
char *QDECL CLGHL_serverkey(char *key){notimpf(__func__);return NULL;}
float QDECL CLGHL_getclientmaxspeed(void)
{
return 320;
@ -751,35 +788,42 @@ int QDECL CLGHL_keyevent(int key, int down)
Con_Printf("CLGHL_keyevent: Unrecognised HL key code\n");
return true; //fixme: check the return type
}
void QDECL CLGHL_getmousepos(int *outx, int *outy){notimp(__LINE__);}
int QDECL CLGHL_movetypeisnoclip(void){notimp(__LINE__);return 0;}
struct hlclent_s *QDECL CLGHL_getlocalplayer(void){notimp(__LINE__);return NULL;}
struct hlclent_s *QDECL CLGHL_getviewent(void){notimp(__LINE__);return NULL;}
struct hlclent_s *QDECL CLGHL_getentidx(void){notimp(__LINE__);return NULL;}
void QDECL CLGHL_getmousepos(int *outx, int *outy){notimpf(__func__);}
int QDECL CLGHL_movetypeisnoclip(void){notimpf(__func__);return 0;}
struct hlclent_s *QDECL CLGHL_getlocalplayer(void){notimpf(__func__);return NULL;}
struct hlclent_s *QDECL CLGHL_getviewent(void){notimpf(__func__);return NULL;}
struct hlclent_s *QDECL CLGHL_getentidx(int idx)
{
notimpf(__func__);return NULL;
}
float QDECL CLGHL_getlocaltime(void){return cl.time;}
void QDECL CLGHL_calcshake(void){notimp(__LINE__);}
void QDECL CLGHL_applyshake(float *origin, float *angles, float factor){notimp(__LINE__);}
int QDECL CLGHL_pointcontents(float *point, float *truecon){notimp(__LINE__);return 0;}
int QDECL CLGHL_entcontents(float *point){notimp(__LINE__);return 0;}
void QDECL CLGHL_traceline(float *start, float *end, int flags, int hull, int forprediction){notimp(__LINE__);}
void QDECL CLGHL_calcshake(void){notimpf(__func__);}
void QDECL CLGHL_applyshake(float *origin, float *angles, float factor){notimpf(__func__);}
int QDECL CLGHL_pointcontents(float *point, float *truecon){notimpf(__func__);return 0;}
int QDECL CLGHL_entcontents(float *point){notimpf(__func__);return 0;}
void QDECL CLGHL_traceline(float *start, float *end, int flags, int hull, int forprediction){notimpf(__func__);}
model_t *QDECL CLGHL_loadmodel(char *modelname, int *mdlindex){notimp(__LINE__);return Mod_ForName(modelname, false);}
int QDECL CLGHL_addrentity(int type, void *ent){notimp(__LINE__);return 0;}
model_t *QDECL CLGHL_loadmodel(char *modelname, int *mdlindex){notimpf(__func__);return Mod_ForName(modelname, false);}
int QDECL CLGHL_addrentity(int type, void *ent){notimpf(__func__);return 0;}
model_t *QDECL CLGHL_modelfrompic(HLPIC pic){notimp(__LINE__);return NULL;}
void QDECL CLGHL_soundatloc(char*sound, float volume, float *org){notimp(__LINE__);}
model_t *QDECL CLGHL_modelfrompic(HLPIC pic){notimpf(__func__);return NULL;}
void QDECL CLGHL_soundatloc(char*sound, float volume, float *org){notimpf(__func__);}
unsigned short QDECL CLGHL_precacheevent(int evtype, char *name){notimp(__LINE__);return 0;}
void QDECL CLGHL_playevent(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2){notimp(__LINE__);}
unsigned short QDECL CLGHL_precacheevent(int evtype, char *name){notimpf(__func__);return 0;}
void QDECL CLGHL_playevent(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2){notimpf(__func__);}
void QDECL CLGHL_weaponanimate(int newsequence, int body)
{
hl_viewmodelsequencetime = cl.time;
hl_viewmodelsequencecur = newsequence;
hl_viewmodelsequencebody = body;
}
float QDECL CLGHL_randfloat(float minv, float maxv){notimp(__LINE__);return minv;}
long QDECL CLGHL_randlong(long minv, long maxv){notimp(__LINE__);return minv;}
void QDECL CLGHL_hookevent(char *name, void (*func)(struct hlevent_s *event)){notimp(__LINE__);}
float QDECL CLGHL_randfloat(float minv, float maxv){notimpf(__func__);return minv;}
long QDECL CLGHL_randlong(long minv, long maxv){notimpf(__func__);return minv;}
void QDECL CLGHL_hookevent(char *name, void (*func)(struct hlevent_s *event))
{
Con_Printf("CLGHL_hookevent: not implemented. %s\n", name);
// notimpf(__func__);
}
int QDECL CLGHL_con_isshown(void)
{
return scr_con_current > 0;
@ -799,12 +843,20 @@ char *QDECL CLGHL_lookupbinding(char *command)
}
char *QDECL CLGHL_getlevelname(void)
{
return cl.levelname;
if (!cl.worldmodel)
return "";
return cl.worldmodel->name;
}
void QDECL CLGHL_getscreenfade(struct hlsfade_s *fade){notimpf(__func__);}
void QDECL CLGHL_setscreenfade(struct hlsfade_s *fade){notimpf(__func__);}
void *QDECL CLGHL_vgui_getpanel(void)
{
return vgui_panel;
}
void QDECL CLGHL_vgui_paintback(int extents[4])
{
notimpf(__func__);
}
void QDECL CLGHL_getscreenfade(struct hlsfade_s *fade){notimp(__LINE__);}
void QDECL CLGHL_setscreenfade(struct hlsfade_s *fade){notimp(__LINE__);}
void *QDECL CLGHL_vgui_getpanel(void){notimp(__LINE__);return NULL;}
void QDECL CLGHL_vgui_paintback(int extents[4]){notimp(__LINE__);}
void *QDECL CLGHL_loadfile(char *path, int alloctype, int *length)
{
@ -815,7 +867,7 @@ void *QDECL CLGHL_loadfile(char *path, int alloctype, int *length)
flen = FS_LoadFile(path, &ptr);
}
else
notimp(__LINE__); //don't leak, just fail
notimpf(__func__); //don't leak, just fail
if (length)
*length = flen;
@ -839,19 +891,19 @@ int QDECL CLGHL_forcedspectator(void)
}
model_t *QDECL CLGHL_loadmapsprite(char *name)
{
notimp(__LINE__);return NULL;
notimpf(__func__);return NULL;
}
void QDECL CLGHL_fs_addgamedir(char *basedir, char *appname){notimp(__LINE__);}
int QDECL CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimp(__LINE__);return false;}
void QDECL CLGHL_fs_addgamedir(char *basedir, char *appname){notimpf(__func__);}
int QDECL CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimpf(__func__);return false;}
char *QDECL CLGHL_player_key(int pnum, char *key){notimp(__LINE__);return NULL;}
void QDECL CLGHL_player_setkey(char *key, char *value){notimp(__LINE__);return;}
char *QDECL CLGHL_player_key(int pnum, char *key){notimpf(__func__);return NULL;}
void QDECL CLGHL_player_setkey(char *key, char *value){notimpf(__func__);return;}
qboolean QDECL CLGHL_getcdkey(int playernum, char key[16]){notimp(__LINE__);return false;}
int QDECL CLGHL_trackerfromplayer(int pslot){notimp(__LINE__);return 0;}
int QDECL CLGHL_playerfromtracker(int tracker){notimp(__LINE__);return 0;}
int QDECL CLGHL_sendcmd_unreliable(char *cmd){notimp(__LINE__);return 0;}
qboolean QDECL CLGHL_getcdkey(int playernum, char key[16]){notimpf(__func__);return false;}
int QDECL CLGHL_trackerfromplayer(int pslot){notimpf(__func__);return 0;}
int QDECL CLGHL_playerfromtracker(int tracker){notimpf(__func__);return 0;}
int QDECL CLGHL_sendcmd_unreliable(char *cmd){notimpf(__func__);return 0;}
void QDECL CLGHL_getsysmousepos(long *xandy)
{
#ifdef _WIN32
@ -887,7 +939,7 @@ int QDECL CLGHL_demo_istimedemo(void)
}
void QDECL CLGHL_demo_writedata(int size, void *data)
{
notimp(__LINE__);
notimpf(__func__);
}
struct hl_demo_api_s hl_demo_api =
@ -1114,15 +1166,19 @@ void CLHL_LoadClientGame(void)
memset(&CLHL_cgamefuncs, 0, sizeof(CLHL_cgamefuncs));
path = NULL;
while((path = COM_NextPath (path)))
clg = Sys_LoadLibrary("C:/Incoming/d/Half-Life/sdks/hlsdk-2.3-p3/hlsdk-2.3-p3/multiplayer/cl_dll/Debug/client", funcs);
if (!clg)
{
if (!path)
return; // couldn't find one anywhere
snprintf (fullname, sizeof(fullname), "%s/%s", path, "cl_dlls/client");
clg = Sys_LoadLibrary(fullname, funcs);
if (clg)
break;
path = NULL;
while((path = COM_NextPath (path)))
{
if (!path)
return; // couldn't find one anywhere
snprintf (fullname, sizeof(fullname), "%s/%s", path, "cl_dlls/client");
clg = Sys_LoadLibrary(fullname, funcs);
if (clg)
break;
}
}
if (!clg)
@ -1149,6 +1205,8 @@ void CLHL_LoadClientGame(void)
CLHL_cgamefuncs.IN_MouseEvent = (void*)Sys_GetAddressForName(clg, "IN_MouseEvent");
#endif
VGui_Setup();
if (CLHL_cgamefuncs.HUD_Init)
CLHL_cgamefuncs.HUD_Init();
if (CLHL_cgamefuncs.HUD_VidInit)
@ -1202,7 +1260,7 @@ int CLHL_DrawHud(void)
state.mousesens = 0;
state.keys = (in_attack.state[0]&3)?1:0;
#endif
state.weapons = cl.stats[0][STAT_ITEMS];
state.weapons = cl.playerview[0].stats[STAT_ITEMS];
state.fov = 90;
V_StopPitchDrift(0);
@ -1226,6 +1284,8 @@ int CLHL_AnimateViewEntity(entity_t *ent)
return true;
}
explosion_t *CL_AllocExplosion (void);
int CLHL_ParseGamePacket(void)
{
int subcode;
@ -1286,7 +1346,7 @@ int CLHL_ParseGamePacket(void)
if (!(flags & 8))
P_RunParticleEffectType(startp, NULL, 1, pt_explosion);
if (!(flags & 4))
S_StartSound(0, 0, S_PrecacheSound("explosion"), startp, 1, 1);
S_StartSound(0, 0, S_PrecacheSound("explosion"), startp, 1, 1, 0, 0);
if (!(flags & 2))
CL_NewDlight(0, startp, 200, 1, 2.0,2.0,2.0);
@ -1409,7 +1469,7 @@ int CLHL_ParseGamePacket(void)
break;
case 37: //svc_roomtype
tempi = MSG_ReadShort();
SNDDMA_SetUnderWater(tempi==14||tempi==15||tempi==16);
S_SetUnderWater(tempi==14||tempi==15||tempi==16);
break;
default:
Con_Printf("Unrecognised gamecode packet %i (%s)\n", subcode, usermsgs[subcode].name);

View File

@ -74,6 +74,7 @@ typedef struct
qboolean jump_held;
int jump_msec; // hack for fixing bunny-hop flickering on non-ZQuake servers
vec3_t szmins, szmaxs;
vec3_t gravitydir;
float lerpstarttime;
int oldframe;
@ -530,20 +531,64 @@ typedef struct
int lerpentssequence;
lerpents_t lerpplayers[MAX_CLIENTS];
// information for local display
int stats[MAX_SPLITS][MAX_CL_STATS]; // health, etc
float statsf[MAX_SPLITS][MAX_CL_STATS]; // health, etc
char *statsstr[MAX_SPLITS][MAX_CL_STATS]; // health, etc
float item_gettime[MAX_SPLITS][32]; // cl.time of aquiring item, for blinking
float faceanimtime[MAX_SPLITS]; // use anim frame if cl.time < this
cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups and content types
// the client maintains its own idea of view angles, which are
// sent to the server each frame. And only reset at level change
// and teleport times
vec3_t viewangles[MAX_SPLITS];
vec3_t viewanglechange[MAX_SPLITS];
//when running splitscreen, we have multiple viewports all active at once
int splitclients; //we are running this many clients split screen.
struct playerview_s
{
// information for local display
int stats[MAX_CL_STATS]; // health, etc
float statsf[MAX_CL_STATS]; // health, etc
char *statsstr[MAX_CL_STATS]; // health, etc
float item_gettime[32]; // cl.time of aquiring item, for blinking
float faceanimtime; // use anim frame if cl.time < this
// the client maintains its own idea of view angles, which are
// sent to the server each frame. And only reset at level change
// and teleport times
vec3_t viewangles;
vec3_t viewanglechange;
vec3_t gravitydir;
// pitch drifting vars
float pitchvel;
qboolean nodrift;
float driftmove;
double laststop;
vec3_t simorg;
vec3_t simvel;
vec3_t simangles;
float rollangle;
qboolean fixangle; //received a fixangle - so disable prediction till the next packet.
qboolean oldfixangle; //received a fixangle - so disable prediction till the next packet.
vec3_t fixangles; //received a fixangle - so disable prediction till the next packet.
vec3_t oldfixangles; //received a fixangle - so disable prediction till the next packet.
} playerview[MAX_SPLITS];
float crouch[MAX_SPLITS]; // local amount for smoothing stepups
qboolean onground[MAX_SPLITS];
float viewheight[MAX_SPLITS];
entity_t viewent[MAX_SPLITS]; // weapon model
float punchangle[MAX_SPLITS]; // temporary view kick from weapon firing
int playernum[MAX_SPLITS];
qboolean nolocalplayer[MAX_SPLITS];
#ifdef PEXT_SETVIEW
int viewentity[MAX_SPLITS];
#endif
int waterlevel[MAX_SPLITS]; //for smartjump
// localized movement vars
float entgravity[MAX_SPLITS];
float maxspeed[MAX_SPLITS];
float bunnyspeedcap;
int pmovetype[MAX_SPLITS];
// the client simulates or interpolates movement to get these values
double time; // this is the time value that the client
@ -558,29 +603,11 @@ typedef struct
float oldgametime; //used as the old time to lerp cl.time from.
float oldgametimemark; //if it's 0, cl.time will casually increase.
vec3_t simorg[MAX_SPLITS];
vec3_t simvel[MAX_SPLITS];
vec3_t simangles[MAX_SPLITS];
float rollangle[MAX_SPLITS];
float minpitch;
float maxpitch;
// pitch drifting vars
float pitchvel[MAX_SPLITS];
qboolean nodrift[MAX_SPLITS];
float driftmove[MAX_SPLITS];
double laststop[MAX_SPLITS];
float crouch[MAX_SPLITS]; // local amount for smoothing stepups
qboolean onground[MAX_SPLITS];
float viewheight[MAX_SPLITS];
qboolean paused; // send over by server
float punchangle[MAX_SPLITS]; // temporar yview kick from weapon firing
int intermission; // don't change view angle, full screen, etc
float completed_time; // latched ffrom time at intermission start
@ -605,6 +632,14 @@ typedef struct
qboolean model_precaches_added;
struct
{
int num;
char *name;
} *particle_precache;
unsigned int maxparticleprecaches;
//used for q2 sky/configstrings
char skyname[MAX_QPATH];
float skyrotate;
@ -614,9 +649,6 @@ typedef struct
vec3_t fog_colour;
char levelname[40]; // for display on solo scoreboard
int playernum[MAX_SPLITS];
qboolean nolocalplayer[MAX_SPLITS];
int splitclients; //we are running this many clients split screen.
// refresh related state
struct model_s *worldmodel; // cl_entitites[0].model
@ -625,8 +657,6 @@ typedef struct
int cdtrack; // cd audio
entity_t viewent[MAX_SPLITS]; // weapon model
// all player information
unsigned int allocated_client_slots;
player_info_t players[MAX_CLIENTS];
@ -635,13 +665,8 @@ typedef struct
downloadlist_t *downloadlist;
downloadlist_t *faileddownloads;
#ifdef PEXT_SETVIEW
int viewentity[MAX_SPLITS];
#endif
qboolean gamedirchanged;
int waterlevel[MAX_SPLITS]; //for smartjump
char q2statusbar[1024];
char q2layout[1024];
int parse_entities;
@ -655,15 +680,6 @@ typedef struct
packet_entities_t *currentpackentities;
float currentpacktime;
// localized movement vars
float entgravity[MAX_SPLITS];
float maxspeed[MAX_SPLITS];
float bunnyspeedcap;
qboolean fixangle[MAX_SPLITS]; //received a fixangle - so disable prediction till the next packet.
qboolean oldfixangle[MAX_SPLITS]; //received a fixangle - so disable prediction till the next packet.
vec3_t fixangles[MAX_SPLITS]; //received a fixangle - so disable prediction till the next packet.
vec3_t oldfixangles[MAX_SPLITS]; //received a fixangle - so disable prediction till the next packet.
int pmovetype[MAX_SPLITS];
int teamplay;
int deathmatch;
@ -941,6 +957,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result);
extern int packet_latency[NET_TIMINGS];
int CL_CalcNet (void);
void CL_ClearParseState(void);
void CL_Parse_Disconnected(void);
void CL_DumpPacket(void);
void CL_ParseEstablished(void);
void CLQW_ParseServerMessage (void);
@ -1003,8 +1020,9 @@ void CL_ParseParticleEffect2 (void);
void CL_ParseParticleEffect3 (void);
void CL_ParseParticleEffect4 (void);
void CLDP_ParseTrailParticles(void);
void CLDP_ParsePointParticles(qboolean compact);
int CL_TranslateParticleFromServer(int sveffect);
void CL_ParseTrailParticles(void);
void CL_ParsePointParticles(qboolean compact);
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, struct model_s *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity); /*called from the particlesystem*/
//
@ -1019,6 +1037,7 @@ void CL_ClearProjectiles (void);
void CL_ParseProjectiles (int modelindex, qboolean nails2);
void CL_ParsePacketEntities (qboolean delta);
void CLFTE_ParseEntities (void);
void CLFTE_ParseBaseline(entity_state_t *es, qboolean numberisimportant);
void CL_SetSolidEntities (void);
void CL_ParsePlayerinfo (void);
void CL_ParseClientPersist(void);
@ -1055,6 +1074,7 @@ char *CG_GetConfigString(int num);
//
#ifdef CSQC_DAT
qboolean CSQC_Inited(void);
void CSQC_RendererRestarted(void);
qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum);
void CSQC_RegisterCvarsAndThings(void);
qboolean CSQC_DrawView(void);
@ -1220,6 +1240,20 @@ void CLQ2_RunMuzzleFlash2 (int ent, int flash_number);
int CLQ2_RegisterTEntModels (void);
#endif
#ifdef HLCLIENT
//networking
void CLHL_LoadClientGame(void);
int CLHL_ParseGamePacket(void);
int CLHL_AnimateViewEntity(entity_t *ent);
//screen
int CLHL_DrawHud(void);
//inputs
int CLHL_GamecodeDoesMouse(void);
int CLHL_MouseEvent(unsigned int buttonmask);
void CLHL_SetMouseActive(int activate);
int CLHL_BuildUserInput(int msecs, usercmd_t *cmd);
#endif
#ifdef NQPROT
void CLNQ_ParseEntity(unsigned int bits);
void NQ_P_ParseParticleEffect (void);

View File

@ -1762,8 +1762,8 @@ void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops)
//generate root matrix..
view = &cl.viewent[0];
VectorCopy(cl.simorg[0], view->origin);
AngleVectors(cl.simangles[0], view->axis[0], view->axis[1], view->axis[2]);
VectorCopy(cl.playerview[0].simorg, view->origin);
AngleVectors(cl.playerview[0].simangles, view->axis[0], view->axis[1], view->axis[2]);
VectorInverse(view->axis[1]);
memset (&gun, 0, sizeof(gun));
@ -1888,8 +1888,8 @@ void CLQ2_CalcViewValues (void)
for (i=0 ; i<3 ; i++)
r_refdef.viewangles[i] += v_gunkick_q2.value * LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
VectorCopy(r_refdef.vieworg, cl.simorg[0]);
VectorCopy(r_refdef.viewangles, cl.simangles[0]);
VectorCopy(r_refdef.vieworg, cl.playerview[0].simorg);
VectorCopy(r_refdef.viewangles, cl.playerview[0].simangles);
// VectorCopy(r_refdef.viewangles, cl.viewangles);
// AngleVectors (r_refdef.viewangles, v_forward, v_right, v_up);

View File

@ -114,7 +114,9 @@ void Con_Destroy (console_t *con)
if (con == &con_main)
{
Con_Finit(con);
/*main console is never destroyed, only cleared (unless shutting down)*/
if (con_initialized)
Con_Finit(con);
return;
}
@ -541,8 +543,8 @@ void Con_Shutdown(void)
{
Con_Destroy(con_main.next);
}
Con_Destroy(&con_main);
con_initialized = false;
Con_Destroy(&con_main);
}
void TTS_SayConString(conchar_t *stringtosay);

View File

@ -251,8 +251,8 @@ void IN_Move (float *movements, int pnum)
V_StopPitchDrift (pnum);
/*handle looks*/
cl.viewanglechange[pnum][YAW] -= m_yaw.value * mouse_x * sensitivity.value;
cl.viewanglechange[pnum][PITCH] += m_pitch.value * mouse_y * sensitivity.value;
cl.playerview[pnum].viewanglechange[YAW] -= m_yaw.value * mouse_x * sensitivity.value;
cl.playerview[pnum].viewanglechange[PITCH] += m_pitch.value * mouse_y * sensitivity.value;
mouse_x = mouse_y = 0.0;
}

View File

@ -290,7 +290,7 @@ Force_CenterView_f
*/
void Force_CenterView_f (void)
{
cl.viewangles[0][PITCH] = 0;
cl.playerview[0].viewangles[PITCH] = 0;
}
/*
@ -1367,10 +1367,10 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
mouse_y *= sensitivity.value*in_sensitivityscale;
}
if (cl.stats[pnum][STAT_VIEWZOOM])
if (cl.playerview[pnum].stats[STAT_VIEWZOOM])
{
mouse_x *= cl.stats[pnum][STAT_VIEWZOOM]/255.0f;
mouse_y *= cl.stats[pnum][STAT_VIEWZOOM]/255.0f;
mouse_x *= cl.playerview[pnum].stats[STAT_VIEWZOOM]/255.0f;
mouse_y *= cl.playerview[pnum].stats[STAT_VIEWZOOM]/255.0f;
}
@ -1389,7 +1389,7 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
{
// if ((int)((cl.viewangles[pnum][PITCH]+89.99)/180) & 1)
// mouse_x *= -1;
cl.viewanglechange[pnum][YAW] -= m_yaw.value * mouse_x;
cl.playerview[pnum].viewanglechange[YAW] -= m_yaw.value * mouse_x;
}
if (in_mlook.state[pnum] & 1)
@ -1397,7 +1397,7 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
if ( (in_mlook.state[pnum] & 1) && !(in_strafe.state[pnum] & 1))
{
cl.viewanglechange[pnum][PITCH] += m_pitch.value * mouse_y;
cl.playerview[pnum].viewanglechange[PITCH] += m_pitch.value * mouse_y;
}
else
{
@ -2150,11 +2150,11 @@ void IN_JoyMove (float *movements, int pnum)
// only absolute control support here (joy_advanced is false)
if (m_pitch.value < 0.0)
{
cl.viewanglechange[pnum][PITCH] -= (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
cl.playerview[pnum].viewanglechange[PITCH] -= (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
}
else
{
cl.viewanglechange[pnum][PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
cl.playerview[pnum].viewanglechange[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
}
V_StopPitchDrift(pnum);
}
@ -2201,11 +2201,11 @@ void IN_JoyMove (float *movements, int pnum)
{
if(dwControlMap[i] == JOY_ABSOLUTE_AXIS)
{
cl.viewanglechange[pnum][YAW] += (fAxisValue * joy_yawsensitivity.value) * aspeed * cl_yawspeed.value;
cl.playerview[pnum].viewanglechange[YAW] += (fAxisValue * joy_yawsensitivity.value) * aspeed * cl_yawspeed.value;
}
else
{
cl.viewanglechange[pnum][YAW] += (fAxisValue * joy_yawsensitivity.value) * speed * 180.0;
cl.playerview[pnum].viewanglechange[YAW] += (fAxisValue * joy_yawsensitivity.value) * speed * 180.0;
}
}
@ -2220,11 +2220,11 @@ void IN_JoyMove (float *movements, int pnum)
// pitch movement detected and pitch movement desired by user
if(dwControlMap[i] == JOY_ABSOLUTE_AXIS)
{
cl.viewanglechange[pnum][PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
cl.playerview[pnum].viewanglechange[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
}
else
{
cl.viewanglechange[pnum][PITCH] += (fAxisValue * joy_pitchsensitivity.value) * speed * 180.0;
cl.playerview[pnum].viewanglechange[PITCH] += (fAxisValue * joy_pitchsensitivity.value) * speed * 180.0;
}
V_StopPitchDrift(pnum);
}

View File

@ -183,6 +183,7 @@ void Key_Init (void);
void Key_WriteBindings (vfsfile_t *f);
void Key_SetBinding (int keynum, int modifier, char *binding, int cmdlevel);
void Key_ClearStates (void);
void Key_Unbindall_f (void); //aka: Key_Shutdown
qboolean Key_GetConsoleSelectionBox(int *sx, int *sy, int *ex, int *ey);
qboolean Key_MouseShouldBeFree(void);

View File

@ -3186,7 +3186,10 @@ typedef struct
void S_MP3_Abort(sfx_t *sfx)
{
mp3decoder_t *dec = sfx->decoder.buf;
sfx->decoder.buf = NULL;
sfx->decoder.abort = NULL;
sfx->decoder.decodedata = NULL;
qacmStreamClose(dec->acm, 0);

View File

@ -192,6 +192,7 @@ typedef struct part_type_s {
float veladd; //scale the incoming velocity by this much
float orgadd; //spawn the particle this far along its velocity direction
float spawnvel, spawnvelvert; //spawn the particle with a velocity based upon its spawn type (generally so it flies outwards)
vec3_t orgbias; //static 3d world-coord bias
float s1, t1, s2, t2; //texture coords
float texsstride; //addition for s for each random slot.
@ -251,6 +252,8 @@ typedef struct part_type_s {
float dl_radius;
float dl_time;
vec4_t dl_decay;
//PT_NODLSHADOW
int dl_cubemapnum;
vec3_t stain_rgb;
float stain_radius;
@ -275,6 +278,9 @@ typedef struct part_type_s {
#define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...)
#define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle
#define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle
#define PT_TROVERWATER 0x200 // don't spawn if underwater
#define PT_TRUNDERWATER 0x400 // don't spawn if overwater
#define PT_NODLSHADOW 0x800 // dlights from this effect don't cast shadows.
unsigned int state;
#define PS_INRUNLIST 0x1 // particle type is currently in execution list
@ -516,7 +522,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
for (i = 0; i < ptype->nummodels; i++)
ptype->models[i].model = NULL;
if (*ptype->texname)
if (*ptype->texname && ptype->looks.blendmode == BM_BLEND)
{
/*try and load the shader, fail if we would need to generate one*/
ptype->looks.shader = R_RegisterCustom(ptype->texname, NULL, NULL);
@ -586,7 +592,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_ZERO GL_ONE_MINUS_SRC_COLOR\n"
"blendfunc GL_ZERO GL_ONE_MINUS_SRC_ALPHA\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
@ -1520,6 +1526,18 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
Q_strncatz(outstr, va("rotationstart %g %g\n", ptype->rotationstartmin*180/M_PI, (ptype->rotationstartmin+ptype->rotationstartrand)*180/M_PI), outstrlen);
Q_strncatz(outstr, va("rotationspeed %g %g\n", ptype->rotationmin*180/M_PI, (ptype->rotationmin+ptype->rotationrand)*180/M_PI), outstrlen);
if (ptype->dl_radius)
{
Q_strncatz(outstr, va("lightradius %g %g\n", ptype->dl_radius), outstrlen);
Q_strncatz(outstr, va("lightradiusfade %g \n", ptype->dl_decay[3]), outstrlen);
Q_strncatz(outstr, va("lightrgb %g %g %g\n", ptype->dl_rgb[0], ptype->dl_rgb[1], ptype->dl_rgb[2]), outstrlen);
Q_strncatz(outstr, va("lightrgbfade %g %g %g\n", ptype->dl_decay[0], ptype->dl_decay[1], ptype->dl_decay[2]), outstrlen);
Q_strncatz(outstr, va("lighttime %g\n", ptype->dl_time), outstrlen);
Q_strncatz(outstr, va("lightshadows %g\n", (ptype->flags & PT_NODLSHADOW)?0.0f:1.0f), outstrlen);
Q_strncatz(outstr, va("lightcubemap %i\n", ptype->dl_cubemapnum), outstrlen);
}
return true;
#if 0
@ -1569,10 +1587,6 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
float clipbounce;
int stainonimpact;
vec3_t dl_rgb;
float dl_radius;
float dl_time;
vec4_t dl_decay;
vec3_t stain_rgb;
float stain_radius;
@ -1600,6 +1614,36 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
return false;
}
static void P_ExportAllEffects_f(void)
{
char effect[8192];
int i;
vfsfile_t *outf;
char fname[64] = "particles/export.cfg";
FS_CreatePath("particles/", FS_GAMEONLY);
outf = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
if (!outf)
{
FS_NativePath(fname, FS_GAMEONLY, effect, sizeof(effect));
Con_Printf("Unable to open file %s\n", effect);
return;
}
for (i = 0; i < numparticletypes; i++)
{
PScript_Query(i, 0, effect, sizeof(effect));
VFS_PUTS(outf, "r_part ");
VFS_PUTS(outf, effect);
VFS_PUTS(outf, "\n{\n");
PScript_Query(i, 1, effect, sizeof(effect));
VFS_PUTS(outf, effect);
VFS_PUTS(outf, "}\n");
}
VFS_CLOSE(outf);
FS_NativePath(fname, FS_GAMEONLY, effect, sizeof(effect));
Con_Printf("Written %s\n", effect);
}
#if _DEBUG
// R_BeamInfo_f - debug junk
static void P_BeamInfo_f (void)
@ -1751,6 +1795,8 @@ static void P_ImportEffectInfo_f(void)
if (ptype)
{
if (ptype->looks.type == PT_CDECAL)
ptype->scale *= 0.25;
FinishParticleType(ptype);
}
@ -1780,7 +1826,7 @@ static void P_ImportEffectInfo_f(void)
ptype->alpharand = 1;
ptype->alphachange = -1;
ptype->die = 9999;
strcpy(ptype->texname, "particles/particlefont.tga");
strcpy(ptype->texname, "particles/particlefont");
ptype->rgb[0] = 1;
ptype->rgb[1] = 1;
ptype->rgb[2] = 1;
@ -1845,17 +1891,19 @@ static void P_ImportEffectInfo_f(void)
{
ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_INVMOD;
ptype->gravity = 800*1;
}
else if (!strcmp(arg[1], "beam"))
{
ptype->looks.type = PT_BEAM;
ptype->looks.blendmode = BM_ADD;
}
// else if (!strcmp(arg[1], "snow"))
// {
// ptype->looks.type = PT_NORMAL;
// ptype->looks.blendmode = BM_BLEND;
// }
else if (!strcmp(arg[1], "snow"))
{
ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_ADD;
//should have some sort of wind/flutter with it
}
else
{
Con_Printf("effectinfo type %s not supported\n", arg[1]);
@ -1878,11 +1926,11 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[0], "size") && args == 3)
{
float s1 = atof(arg[1]), s2 = atof(arg[2]);
ptype->scale = s1;
ptype->scalerand = s2-s1;
ptype->scale = s1 * 4;
ptype->scalerand = (s2-s1) * 4;
}
else if (!strcmp(arg[0], "sizeincrease") && args == 2)
ptype->scaledelta = atof(arg[1]);
ptype->scaledelta = atof(arg[1]) * 4;
else if (!strcmp(arg[0], "color") && args == 3)
{
unsigned int rgb1 = strtoul(arg[1], NULL, 0), rgb2 = strtoul(arg[2], NULL, 0);
@ -1890,7 +1938,8 @@ static void P_ImportEffectInfo_f(void)
for (i = 0; i < 3; i++)
{
ptype->rgb[i] = ((rgb1>>(16-i*8)) & 0xff)/255.0;
ptype->rgbrandsync[i] = (((rgb2>>(16-i*8)) & 0xff) - ((rgb1>>(16-i*8)) & 0xff))/255.0;
ptype->rgbrand[i] = (int)(((rgb2>>(16-i*8)) & 0xff) - ((rgb1>>(16-i*8)) & 0xff))/255.0;
ptype->rgbrandsync[i] = 1;
}
}
else if (!strcmp(arg[0], "alpha") && args == 4)
@ -1908,7 +1957,11 @@ static void P_ImportEffectInfo_f(void)
ptype->spawnvelvert = atof(arg[3]);
}
else if (!strcmp(arg[0], "originoffset") && args == 4)
; /*a 3d world-coord addition*/
{ /*a 3d world-coord addition*/
ptype->orgbias[0] = atof(arg[1]);
ptype->orgbias[1] = atof(arg[2]);
ptype->orgbias[2] = atof(arg[3]);
}
else if (!strcmp(arg[0], "originjitter") && args == 4)
{
ptype->areaspread = (atof(arg[1]) + atof(arg[2]))*0.5;
@ -1928,19 +1981,11 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[0], "liquidfriction") && args == 2)
;
else if (!strcmp(arg[0], "underwater") && args == 1)
;
ptype->flags |= PT_TRUNDERWATER;
else if (!strcmp(arg[0], "notunderwater") && args == 1)
;
ptype->flags |= PT_TROVERWATER;
else if (!strcmp(arg[0], "velocitymultiplier") && args == 2)
ptype->veladd = atof(arg[1]);
else if (!strcmp(arg[0], "lightradius") && args == 2)
;
else if (!strcmp(arg[0], "lightradiusfade") && args == 2)
;
else if (!strcmp(arg[0], "lightcolor") && args == 4)
;
else if (!strcmp(arg[0], "lighttime") && args == 2)
;
else if (!strcmp(arg[0], "trailspacing") && args == 2)
ptype->count = 1 / atof(arg[1]);
else if (!strcmp(arg[0], "time") && args == 3)
@ -1955,15 +2000,47 @@ static void P_ImportEffectInfo_f(void)
}
else if (!strcmp(arg[0], "stretchfactor") && args == 2)
ptype->looks.stretch = atof(arg[1]);
#if 0
else if (!strcmp(arg[0], "blend") && args == 2)
; /*overrides blendmode*/
{
if (!strcmp(arg[1], "invmod"))
ptype->looks.blendmode = BM_INVMOD;
else if (!strcmp(arg[1], "alpha"))
ptype->looks.blendmode = BM_BLEND;
else if (!strcmp(arg[1], "add"))
ptype->looks.blendmode = BM_ADD;
else
Con_Printf("effectinfo 'blend %s' not supported\n", arg[1]);
}
else if (!strcmp(arg[0], "orientation") && args == 2)
; /*overrides type*/
{
// if (!strcmp(arg[1], "billboard"))
// ;
// else if (!strcmp(arg[1], "spark"))
// ;
// else if (!strcmp(arg[1], "oriented"))
// ;
// else if (!strcmp(arg[1], "beam"))
// ;
// else
Con_Printf("effectinfo 'orientation %s' not supported\n", arg[1]);
}
else if (!strcmp(arg[0], "lightradius") && args == 2)
ptype->dl_radius = atof(arg[1]);
else if (!strcmp(arg[0], "lightradiusfade") && args == 2)
ptype->dl_decay[3] = atof(arg[1]);
else if (!strcmp(arg[0], "lightcolor") && args == 4)
{
ptype->dl_rgb[0] = atof(arg[1]);
ptype->dl_rgb[1] = atof(arg[2]);
ptype->dl_rgb[2] = atof(arg[3]);
}
else if (!strcmp(arg[0], "lighttime") && args == 2)
ptype->dl_time = atof(arg[1]);
else if (!strcmp(arg[0], "lightshadow") && args == 2)
;
ptype->flags = (ptype->flags & ~PT_NODLSHADOW) | (!atoi(arg[1])?PT_NODLSHADOW:0);
else if (!strcmp(arg[0], "lightcubemapnum") && args == 2)
;
ptype->dl_cubemapnum = atoi(arg[1]);
#if 0
else if (!strcmp(arg[0], "staincolor") && args == 2)
;
else if (!strcmp(arg[0], "stainalpha") && args == 2)
@ -1986,6 +2063,8 @@ static void P_ImportEffectInfo_f(void)
if (ptype)
{
if (ptype->looks.type == PT_CDECAL)
ptype->scale *= 0.25;
FinishParticleType(ptype);
}
@ -2044,6 +2123,7 @@ static qboolean PScript_InitParticles (void)
Cmd_AddCommand("r_exportbuiltinparticles", P_ExportBuiltinSet_f);
Cmd_AddCommand("r_importeffectinfo", P_ImportEffectInfo_f);
Cmd_AddCommand("r_exportalleffects", P_ExportAllEffects_f);
#if _DEBUG
Cmd_AddCommand("r_partinfo", P_PartInfo_f);
@ -2860,6 +2940,10 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, in
dl->channelfade[1] = ptype->dl_decay[1];
dl->channelfade[2] = ptype->dl_decay[2];
dl->decay = ptype->dl_decay[3];
if (ptype->flags & PT_NODLSHADOW)
dl->flags |= LFLAG_NOSHADOWS;
if (ptype->dl_cubemapnum)
snprintf(dl->cubemapname, sizeof(dl->cubemapname), "cubemaps/%i", ptype->dl_cubemapnum);
}
if (ptype->stain_radius)
R_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius);
@ -2891,7 +2975,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
int cont;
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, org);
if (cont & FTECONTENTS_WATER)
if (cont & FTECONTENTS_FLUID)
ptype = &part_type[ptype->inwater];
}
@ -3388,6 +3472,8 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
p->org[2] -= ptype->orgadd;
}
VectorAdd(p->org, ptype->orgbias, p->org);
p->die = particletime + ptype->die - p->die;
}
@ -3702,6 +3788,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
beamseg_t *b;
beamseg_t *bfirst;
trailstate_t *ts;
int count;
float veladd = -ptype->veladd;
float randvel = ptype->randomvel;
@ -3751,6 +3838,17 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
P_ParticleTrail(start, end, ptype->assoc, dlkey, NULL);
}
if (r_part_contentswitch.ival && (ptype->flags & (PT_TRUNDERWATER | PT_TROVERWATER)) && cl.worldmodel)
{
int cont;
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, startpos);
if ((ptype->flags & PT_TROVERWATER) && (cont & FTECONTENTS_FLUID))
return;
if ((ptype->flags & PT_TRUNDERWATER) && !(cont & FTECONTENTS_FLUID))
return;
}
// time limit for trails
if (ptype->spawntime && ts)
{
@ -3835,7 +3933,17 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
b = bfirst = NULL;
while (len < stop)
if (len < stop)
count = (stop-len) / step;
else
{
count = 0;
step = 0;
VectorClear(vstep);
}
count += ptype->countextra;
while (count-->0)//len < stop)
{
len += step;
@ -4086,6 +4194,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
p->org[1] += vec[1]*ptype->orgadd;
p->org[2] += vec[2]*ptype->orgadd;
}
VectorAdd(p->org, ptype->orgbias, p->org);
}
VectorAdd (start, vstep, start);
@ -4178,12 +4287,12 @@ static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, int dlk
return 1;
// inwater check, switch only once
if (r_part_contentswitch.ival && ptype->inwater >= 0)
if (r_part_contentswitch.ival && ptype->inwater >= 0 && cl.worldmodel)
{
int cont;
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, startpos);
if (cont & FTECONTENTS_WATER)
if (cont & FTECONTENTS_FLUID)
ptype = &part_type[ptype->inwater];
}

View File

@ -205,23 +205,23 @@ static void CSQC_ChangeLocalPlayer(int lplayernum)
if (csqcg.view_angles)
{
csqcg.view_angles[0] = cl.viewangles[csqc_lplayernum][0];
csqcg.view_angles[1] = cl.viewangles[csqc_lplayernum][1];
csqcg.view_angles[2] = cl.viewangles[csqc_lplayernum][2];
csqcg.view_angles[0] = cl.playerview[csqc_lplayernum].viewangles[0];
csqcg.view_angles[1] = cl.playerview[csqc_lplayernum].viewangles[1];
csqcg.view_angles[2] = cl.playerview[csqc_lplayernum].viewangles[2];
}
if (dpcompat_corruptglobals.ival)
{
if (csqcg.pmove_org)
{
csqcg.pmove_org[0] = cl.simorg[csqc_lplayernum][0];
csqcg.pmove_org[1] = cl.simorg[csqc_lplayernum][1];
csqcg.pmove_org[2] = cl.simorg[csqc_lplayernum][2];
csqcg.pmove_org[0] = cl.playerview[csqc_lplayernum].simorg[0];
csqcg.pmove_org[1] = cl.playerview[csqc_lplayernum].simorg[1];
csqcg.pmove_org[2] = cl.playerview[csqc_lplayernum].simorg[2];
}
if (csqcg.input_angles)
{
csqcg.input_angles[0] = cl.viewangles[csqc_lplayernum][0];
csqcg.input_angles[1] = cl.viewangles[csqc_lplayernum][1];
csqcg.input_angles[2] = cl.viewangles[csqc_lplayernum][2];
csqcg.input_angles[0] = cl.playerview[csqc_lplayernum].viewangles[0];
csqcg.input_angles[1] = cl.playerview[csqc_lplayernum].viewangles[1];
csqcg.input_angles[2] = cl.playerview[csqc_lplayernum].viewangles[2];
}
}
}
@ -1197,12 +1197,12 @@ static void QCBUILTIN PF_R_GetViewFlag(progfuncs_t *prinst, struct globalvars_s
break;
case VF_CL_VIEWANGLES_V:
VectorCopy(cl.viewangles[csqc_lplayernum], r);
VectorCopy(cl.playerview[csqc_lplayernum].viewangles, r);
break;
case VF_CL_VIEWANGLES_X:
case VF_CL_VIEWANGLES_Y:
case VF_CL_VIEWANGLES_Z:
*r = cl.viewangles[csqc_lplayernum][parametertype-VF_CL_VIEWANGLES_X];
*r = cl.playerview[csqc_lplayernum].viewangles[parametertype-VF_CL_VIEWANGLES_X];
break;
case VF_CARTESIAN_ANGLES:
@ -1320,12 +1320,12 @@ static void QCBUILTIN PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s
break;
case VF_CL_VIEWANGLES_V:
VectorCopy(p, cl.viewangles[csqc_lplayernum]);
VectorCopy(p, cl.playerview[csqc_lplayernum].viewangles);
break;
case VF_CL_VIEWANGLES_X:
case VF_CL_VIEWANGLES_Y:
case VF_CL_VIEWANGLES_Z:
cl.viewangles[csqc_lplayernum][parametertype-VF_CL_VIEWANGLES_X] = *p;
cl.playerview[csqc_lplayernum].viewangles[parametertype-VF_CL_VIEWANGLES_X] = *p;
break;
case VF_CARTESIAN_ANGLES:
@ -1429,13 +1429,13 @@ static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s
static void QCBUILTIN PF_cs_getstati(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int stnum = G_FLOAT(OFS_PARM0);
G_INT(OFS_RETURN) = cl.stats[csqc_lplayernum][stnum];
G_INT(OFS_RETURN) = cl.playerview[csqc_lplayernum].stats[stnum];
}
static void QCBUILTIN PF_cs_getstatbits(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //convert an int stat into a qc float.
int stnum = G_FLOAT(OFS_PARM0);
int val = cl.stats[csqc_lplayernum][stnum];
int val = cl.playerview[csqc_lplayernum].stats[stnum];
if (*prinst->callargc > 1)
{
int first, count;
@ -1447,23 +1447,23 @@ static void QCBUILTIN PF_cs_getstatbits(progfuncs_t *prinst, struct globalvars_s
G_FLOAT(OFS_RETURN) = (((unsigned int)val)&(((1<<count)-1)<<first))>>first;
}
else
G_FLOAT(OFS_RETURN) = cl.statsf[csqc_lplayernum][stnum];
G_FLOAT(OFS_RETURN) = cl.playerview[csqc_lplayernum].statsf[stnum];
}
static void QCBUILTIN PF_cs_getstats(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int stnum = G_FLOAT(OFS_PARM0);
RETURN_TSTRING(cl.statsstr[csqc_lplayernum][stnum]);
RETURN_TSTRING(cl.playerview[csqc_lplayernum].statsstr[stnum]);
/*
char out[17];
//the network protocol byteswaps
((unsigned int*)out)[0] = LittleLong(cl.stats[csqc_lplayernum][stnum+0]);
((unsigned int*)out)[1] = LittleLong(cl.stats[csqc_lplayernum][stnum+1]);
((unsigned int*)out)[2] = LittleLong(cl.stats[csqc_lplayernum][stnum+2]);
((unsigned int*)out)[3] = LittleLong(cl.stats[csqc_lplayernum][stnum+3]);
((unsigned int*)out)[0] = LittleLong(cl.playerview[csqc_lplayernum].stats[stnum+0]);
((unsigned int*)out)[1] = LittleLong(cl.playerview[csqc_lplayernum].stats[stnum+1]);
((unsigned int*)out)[2] = LittleLong(cl.playerview[csqc_lplayernum].stats[stnum+2]);
((unsigned int*)out)[3] = LittleLong(cl.playerview[csqc_lplayernum].stats[stnum+3]);
((unsigned int*)out)[4] = 0; //make sure it's null terminated
RETURN_TSTRING(out);*/
@ -1913,7 +1913,7 @@ static void QCBUILTIN PF_cs_trailparticles (progfuncs_t *prinst, struct globalva
efnum = G_FLOAT(OFS_PARM1);
ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
efnum = pe->FindParticleType(COM_Effectinfo_ForNumber(efnum));
efnum = CL_TranslateParticleFromServer(efnum);
}
else
{
@ -1951,7 +1951,7 @@ static void QCBUILTIN PF_cs_particleeffectquery (progfuncs_t *prinst, struct glo
if (csqc_isdarkplaces)
{
//keep the effectinfo synced between server and client.
id = COM_Effectinfo_ForName(COM_Effectinfo_ForNumber(id));
id = CL_TranslateParticleFromServer(id);
}
else
id = id - 1;
@ -2098,7 +2098,7 @@ static void QCBUILTIN PF_cs_getinputstate (progfuncs_t *prinst, struct globalvar
{
cmd = &independantphysics[csqc_lplayernum];
for (f=0 ; f<3 ; f++)
cmd->angles[f] = ((int)(cl.viewangles[csqc_lplayernum][f]*65536.0/360)&65535);
cmd->angles[f] = ((int)(cl.playerview[csqc_lplayernum].viewangles[f]*65536.0/360)&65535);
}
else
cmd = &cl.frames[f&UPDATE_MASK].cmd[csqc_lplayernum];
@ -4782,6 +4782,38 @@ void CSQC_Event_Think(world_t *w, wedict_t *s)
PR_ExecuteProgram (w->progs, s->v->think);
}
void CSQC_Event_Sound (wedict_t *wentity, int channel, char *sample, int volume, float attenuation, int pitchadj)
{
int i;
vec3_t origin;
if (wentity->v->solid == SOLID_BSP)
{
for (i=0 ; i<3 ; i++)
origin[i] = wentity->v->origin[i]+0.5*(wentity->v->mins[i]+wentity->v->maxs[i]);
}
else
{
VectorCopy (wentity->v->origin, origin);
}
S_StartSound(NUM_FOR_EDICT(csqcprogs, (edict_t*)wentity), channel, S_PrecacheSound(sample), origin, volume, attenuation, 0, pitchadj);
}
qboolean CSQC_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype)
{
if (ent->xv->contentstransition)
{
void *pr_globals = PR_globals(w->progs, PR_CURRENT);
pr_global_struct->self = EDICT_TO_PROG(w->progs, ent);
pr_global_struct->time = w->physicstime;
G_FLOAT(OFS_PARM0) = oldwatertype;
G_FLOAT(OFS_PARM1) = newwatertype;
PR_ExecuteProgram (w->progs, ent->xv->contentstransition);
return true;
}
return false; //do legacy behaviour
}
model_t *CSQC_World_ModelForIndex(world_t *w, int modelindex)
{
return CSQC_GetModelForIndex(modelindex);
@ -5035,6 +5067,8 @@ qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum)
csqc_world.worldmodel = cl.worldmodel;
csqc_world.Event_Touch = CSQC_Event_Touch;
csqc_world.Event_Think = CSQC_Event_Think;
csqc_world.Event_Sound = CSQC_Event_Sound;
csqc_world.Event_ContentsTransition = CSQC_Event_ContentsTransition;
csqc_world.Get_CModel = CSQC_World_ModelForIndex;
csqc_world.Get_FrameState = CSQC_World_GetFrameState;
csqc_world.defaultgravityscale = 1;
@ -5140,6 +5174,22 @@ qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum)
return true; //success!
}
void CSQC_RendererRestarted(void)
{
int i;
if (!csqcprogs)
return;
csqc_world.worldmodel = cl.worldmodel;
for (i = 0; i < MAX_CSQCMODELS; i++)
{
cl.model_csqcprecache[i] = NULL;
}
//FIXME: registered shaders
}
void CSQC_WorldLoaded(void)
{
csqcedict_t *worldent;
@ -5347,11 +5397,9 @@ void CSQC_CvarChanged(cvar_t *var)
qboolean CSQC_DrawView(void)
{
#ifdef USEODE
int ticlimit = 10;
float ft;
float mintic = 0.01;
#endif
double clframetime = host_frametime;
if (!csqcg.draw_function || !csqcprogs || !cl.worldmodel)
return false;
@ -5361,28 +5409,28 @@ qboolean CSQC_DrawView(void)
if (csqcg.frametime)
*csqcg.frametime = host_frametime;
#ifdef USEODE
while(1)
{
ft = cl.servertime - csqc_world.physicstime;
if (ft < mintic)
host_frametime = cl.servertime - csqc_world.physicstime;
if (host_frametime < mintic)
break;
if (!--ticlimit)
{
csqc_world.physicstime = cl.servertime;
break;
}
if (ft > mintic)
ft = mintic;
csqc_world.physicstime += ft;
if (host_frametime > mintic)
host_frametime = mintic;
csqc_world.physicstime += host_frametime;
World_ODE_Frame(&csqc_world, ft, 800);
#ifdef USEODE
World_ODE_Frame(&csqc_world, host_frametime, 800);
#endif
World_Physics_Frame(&csqc_world);
}
#else
csqc_world.physicstime = cl.servertime;
#endif
host_frametime = clframetime;
if (csqcg.frametime)
*csqcg.frametime = host_frametime;

View File

@ -183,6 +183,11 @@ extern "C" {
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifdef USE_MSVCRT_DEBUG
#define USE_MSVCRT_DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#endif
#ifdef _WIN32
#if (_MSC_VER >= 1400)

View File

@ -81,6 +81,19 @@ qbyte GetPaletteIndex(int red, int green, int blue)
}
}
void R2D_Shutdown(void)
{
Cvar_Unhook(&gl_font);
Cvar_Unhook(&vid_conautoscale);
Cvar_Unhook(&gl_screenangle);
Cvar_Unhook(&vid_conheight);
Cvar_Unhook(&vid_conwidth);
Cvar_Unhook(&crosshair);
Cvar_Unhook(&crosshairimage);
Cvar_Unhook(&crosshaircolor);
}
/*
Iniitalise the 2d rendering functions (including font).
Image loading code must be ready for use at this point.

View File

@ -90,7 +90,10 @@ qboolean Mod_LoadMap_Proc(model_t *model, char *data)
return false;
b[surf].meshes = 1;
b[surf].mesh = (mesh_t**)&m[surf];
b[surf].lightmap = -1;
b[surf].lightmap[0] = -1;
b[surf].lightmap[1] = -1;
b[surf].lightmap[2] = -1;
b[surf].lightmap[3] = -1;
data = COM_ParseOut(data, token, sizeof(token));
b[surf].shader = R_RegisterShader_Vertex(token);

View File

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "glquake.h"
#include "shader.h"
#include "renderque.h"
#include "com_mesh.h"
#include <math.h>
extern cvar_t r_ambient;
@ -36,9 +37,6 @@ model_t *currentmodel;
int lightmap_bytes; // 1, 3 or 4
qboolean lightmap_bgra;
texid_t *lightmap_textures;
texid_t *deluxmap_textures;
#define MAX_LIGHTMAP_SIZE LMBLOCK_WIDTH
vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE];
@ -85,6 +83,7 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
int lim;
mtexinfo_t *tex;
stmap *stainbase;
lightmapinfo_t *lm;
lim = 255 - (r_stains.value*255);
@ -92,15 +91,16 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
change = stainbase[(s)*3+x] + amm*parms[4+x]; \
stainbase[(s)*3+x] = bound(lim, change, 255);
if (surf->lightmaptexturenum < 0)
if (surf->lightmaptexturenums[0] < 0)
return;
lm = lightmap[surf->lightmaptexturenums[0]];
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
tex = surf->texinfo;
stainbase = lightmap[surf->lightmaptexturenum]->stainmaps;
stainbase += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * 3;
stainbase = lm->stainmaps;
stainbase += (surf->light_t[0] * lm->width + surf->light_s[0]) * 3;
rad = *parms;
dist = DotProduct ((parms+1), surf->plane->normal) - surf->plane->dist;
@ -145,7 +145,7 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
surf->stained = true;
}
}
stainbase += 3*LMBLOCK_WIDTH;
stainbase += 3*lm->width;
}
if (surf->stained)
@ -245,7 +245,7 @@ void Surf_WipeStains(void)
{
if (!lightmap[i])
break;
memset(lightmap[i]->stainmaps, 255, sizeof(lightmap[i]->stainmaps));
memset(lightmap[i]->stainmaps, 255, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3*sizeof(stmap));
}
}
@ -260,6 +260,7 @@ void Surf_LessenStains(void)
int stride;
int ammount;
int limit;
lightmapinfo_t *lm;
static float time;
@ -279,15 +280,17 @@ void Surf_LessenStains(void)
{
if (surf->stained)
{
lm = lightmap[surf->lightmaptexturenums[0]];
surf->cached_dlight=-1;//nice hack here...
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
stain = lightmap[surf->lightmaptexturenum]->stainmaps;
stain += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * 3;
stain = lm->stainmaps;
stain += (surf->light_t[0] * lm->width + surf->light_s[0]) * 3;
stride = (LMBLOCK_WIDTH-smax)*3;
stride = (lm->width-smax)*3;
surf->stained = false;
@ -1164,9 +1167,10 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
int maps;
glRect_t *theRect;
int smax, tmax;
lightmapinfo_t *lm;
//surfaces without lightmaps
if (fa->lightmaptexturenum<0)
if (fa->lightmaptexturenums[0]<0)
return;
// check for lightmap modification
@ -1192,58 +1196,60 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
dynamic:
RSpeedRemark();
lightmap[fa->lightmaptexturenum]->modified = true;
lm = lightmap[fa->lightmaptexturenums[0]];
lm->modified = true;
smax = (fa->extents[0]>>4)+1;
tmax = (fa->extents[1]>>4)+1;
theRect = &lightmap[fa->lightmaptexturenum]->rectchange;
if (fa->light_t < theRect->t) {
theRect = &lm->rectchange;
if (fa->light_t[0] < theRect->t) {
if (theRect->h)
theRect->h += theRect->t - fa->light_t;
theRect->t = fa->light_t;
theRect->h += theRect->t - fa->light_t[0];
theRect->t = fa->light_t[0];
}
if (fa->light_s < theRect->l) {
if (fa->light_s[0] < theRect->l) {
if (theRect->w)
theRect->w += theRect->l - fa->light_s;
theRect->l = fa->light_s;
theRect->w += theRect->l - fa->light_s[0];
theRect->l = fa->light_s[0];
}
if ((theRect->w + theRect->l) < (fa->light_s + smax))
theRect->w = (fa->light_s-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if ((theRect->w + theRect->l) < (fa->light_s[0] + smax))
theRect->w = (fa->light_s[0]-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t[0] + tmax))
theRect->h = (fa->light_t[0]-theRect->t)+tmax;
if (r_deluxemapping.ival)
{
lightmap[fa->lightmaptexturenum]->deluxmodified = true;
theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange;
if (fa->light_t < theRect->t) {
lm->deluxmodified = true;
theRect = &lm->deluxrectchange;
if (fa->light_t[0] < theRect->t) {
if (theRect->h)
theRect->h += theRect->t - fa->light_t;
theRect->t = fa->light_t;
theRect->h += theRect->t - fa->light_t[0];
theRect->t = fa->light_t[0];
}
if (fa->light_s < theRect->l) {
if (fa->light_s[0] < theRect->l) {
if (theRect->w)
theRect->w += theRect->l - fa->light_s;
theRect->l = fa->light_s;
theRect->w += theRect->l - fa->light_s[0];
theRect->l = fa->light_s[0];
}
if ((theRect->w + theRect->l) < (fa->light_s + smax))
theRect->w = (fa->light_s-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if ((theRect->w + theRect->l) < (fa->light_s[0] + smax))
theRect->w = (fa->light_s[0]-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t[0] + tmax))
theRect->h = (fa->light_t[0]-theRect->t)+tmax;
luxbase = lightmap[fa->lightmaptexturenum]->deluxmaps;
luxbase += fa->light_t * LMBLOCK_WIDTH * 3 + fa->light_s * 3;
luxbase = lm->deluxmaps;
luxbase += fa->light_t[0] * lm->width * 3 + fa->light_s[0] * 3;
}
else
luxbase = NULL;
base = lightmap[fa->lightmaptexturenum]->lightmaps;
base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
stainbase = lightmap[fa->lightmaptexturenum]->stainmaps;
stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3;
base = lm->lightmaps;
base += fa->light_t[0] * lm->width * lightmap_bytes + fa->light_s[0] * lightmap_bytes;
stainbase = lm->stainmaps;
stainbase += (fa->light_t[0] * lm->width + fa->light_s[0]) * 3;
Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, r_ambient.value*255);
RSpeedEnd(RSPEED_DYNAMIC);
@ -1256,12 +1262,13 @@ void Surf_RenderAmbientLightmaps (msurface_t *fa, int ambient)
stmap *stainbase;
glRect_t *theRect;
int smax, tmax;
lightmapinfo_t *lm;
if (!fa->mesh)
return;
//surfaces without lightmaps
if (fa->lightmaptexturenum<0)
if (fa->lightmaptexturenums[0]<0)
return;
if (fa->cached_light[0] != ambient || fa->cached_colour[0] != 0xff)
@ -1274,58 +1281,64 @@ void Surf_RenderAmbientLightmaps (msurface_t *fa, int ambient)
dynamic:
RSpeedRemark();
lightmap[fa->lightmaptexturenum]->modified = true;
lm = lightmap[fa->lightmaptexturenums[0]];
lm->modified = true;
smax = (fa->extents[0]>>4)+1;
tmax = (fa->extents[1]>>4)+1;
theRect = &lightmap[fa->lightmaptexturenum]->rectchange;
if (fa->light_t < theRect->t) {
theRect = &lm->rectchange;
if (fa->light_t[0] < theRect->t)
{
if (theRect->h)
theRect->h += theRect->t - fa->light_t;
theRect->t = fa->light_t;
theRect->h += theRect->t - fa->light_t[0];
theRect->t = fa->light_t[0];
}
if (fa->light_s < theRect->l) {
if (fa->light_s[0] < theRect->l)
{
if (theRect->w)
theRect->w += theRect->l - fa->light_s;
theRect->l = fa->light_s;
theRect->w += theRect->l - fa->light_s[0];
theRect->l = fa->light_s[0];
}
if ((theRect->w + theRect->l) < (fa->light_s + smax))
theRect->w = (fa->light_s-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if ((theRect->w + theRect->l) < (fa->light_s[0] + smax))
theRect->w = (fa->light_s[0]-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t[0] + tmax))
theRect->h = (fa->light_t[0]-theRect->t)+tmax;
if (r_deluxemapping.ival)
{
lightmap[fa->lightmaptexturenum]->deluxmodified = true;
theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange;
if (fa->light_t < theRect->t) {
lm->deluxmodified = true;
theRect = &lm->deluxrectchange;
if (fa->light_t[0] < theRect->t)
{
if (theRect->h)
theRect->h += theRect->t - fa->light_t;
theRect->t = fa->light_t;
theRect->h += theRect->t - fa->light_t[0];
theRect->t = fa->light_t[0];
}
if (fa->light_s < theRect->l) {
if (fa->light_s[0] < theRect->l)
{
if (theRect->w)
theRect->w += theRect->l - fa->light_s;
theRect->l = fa->light_s;
theRect->w += theRect->l - fa->light_s[0];
theRect->l = fa->light_s[0];
}
if ((theRect->w + theRect->l) < (fa->light_s + smax))
theRect->w = (fa->light_s-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t + tmax))
theRect->h = (fa->light_t-theRect->t)+tmax;
if ((theRect->w + theRect->l) < (fa->light_s[0] + smax))
theRect->w = (fa->light_s[0]-theRect->l)+smax;
if ((theRect->h + theRect->t) < (fa->light_t[0] + tmax))
theRect->h = (fa->light_t[0]-theRect->t)+tmax;
luxbase = lightmap[fa->lightmaptexturenum]->deluxmaps;
luxbase += fa->light_t * LMBLOCK_WIDTH * 3 + fa->light_s * 3;
luxbase = lm->deluxmaps;
luxbase += fa->light_t[0] * lm->width * 3 + fa->light_s[0] * 3;
}
else
luxbase = NULL;
base = lightmap[fa->lightmaptexturenum]->lightmaps;
base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
stainbase = lightmap[fa->lightmaptexturenum]->stainmaps;
stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3;
base = lm->lightmaps;
base += fa->light_t[0] * lm->width * lightmap_bytes + fa->light_s[0] * lightmap_bytes;
stainbase = lm->stainmaps;
stainbase += (fa->light_t[0] * lm->width + fa->light_s[0]) * 3;
Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, -1-ambient);
RSpeedEnd(RSPEED_DYNAMIC);
@ -1516,11 +1529,10 @@ static void Surf_OrthoRecursiveWorldNode (mnode_t *node, unsigned int clipflags)
{
//when rendering as ortho the front and back sides are technically equal. the only culling comes from frustum culling.
int c, side, clipped;
mplane_t *plane, *clipplane;
int c, clipped;
mplane_t *clipplane;
msurface_t *surf, **mark;
mleaf_t *pleaf;
double dot;
if (node->contents == Q1CONTENTS_SOLID)
return; // solid
@ -1528,7 +1540,7 @@ static void Surf_OrthoRecursiveWorldNode (mnode_t *node, unsigned int clipflags)
if (node->visframe != r_visframecount)
return;
for (c = 0, clipplane = frustum; c < FRUSTUMPLANES; c++, clipplane++)
for (c = 0, clipplane = frustum; c < 4; c++, clipplane++)
{
if (!(clipflags & (1 << c)))
continue; // don't need to clip against it
@ -1887,7 +1899,7 @@ static void Surf_CleanChains(void)
void Surf_SetupFrame(void)
{
mleaf_t *leaf;
vec3_t temp;
vec3_t temp, pvsorg;
R_AnimateLight();
r_framecount++;
@ -1948,19 +1960,23 @@ void Surf_SetupFrame(void)
}
else
{
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
if (r_refdef.recurse)
r_viewleaf = RMod_PointInLeaf (cl.worldmodel, r_refdef.pvsorigin);
{
VectorCopy(r_refdef.pvsorigin, pvsorg);
}
else
r_viewleaf = RMod_PointInLeaf (cl.worldmodel, r_origin);
{
VectorCopy(r_origin, pvsorg);
}
r_viewleaf = RMod_PointInLeaf (cl.worldmodel, pvsorg);
if (!r_viewleaf)
{
}
else if (r_viewleaf->contents == Q1CONTENTS_EMPTY)
{ //look down a bit
VectorCopy (r_origin, temp);
VectorCopy (pvsorg, temp);
temp[2] -= 16;
leaf = RMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA)
@ -1971,7 +1987,7 @@ void Surf_SetupFrame(void)
else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA)
{ //in water, look up a bit.
VectorCopy (r_origin, temp);
VectorCopy (pvsorg, temp);
temp[2] += 16;
leaf = RMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents == Q1CONTENTS_EMPTY)
@ -2263,8 +2279,6 @@ void Surf_DrawWorld (void)
}
}
/*
=============================================================================
@ -2272,7 +2286,7 @@ void Surf_DrawWorld (void)
=============================================================================
*/
#ifdef TERRAIN
// returns a texture number and the position inside it
int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
{
@ -2290,22 +2304,21 @@ int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
lightmap[numlightmaps+2] = NULL;
lightmap[numlightmaps+3] = NULL;
lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4));
memset(lightmap_textures+numlightmaps, 0, sizeof(*lightmap_textures)*(4));
// lightmap_textures = BZ_Realloc(lightmap_textures, sizeof(*lightmap_textures)*(numlightmaps+4));
// memset(lightmap_textures+numlightmaps, 0, sizeof(*lightmap_textures)*(4));
deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4));
memset(deluxmap_textures+numlightmaps, 0, sizeof(*deluxmap_textures)*(4));
// deluxmap_textures = BZ_Realloc(deluxmap_textures, sizeof(*deluxmap_textures)*(numlightmaps+4));
// memset(deluxmap_textures+numlightmaps, 0, sizeof(*deluxmap_textures)*(4));
numlightmaps+=4;
}
if (!lightmap[texnum])
{
lightmap[texnum] = Z_Malloc(sizeof(*lightmap[texnum]));
lightmap[texnum]->meshchain = NULL;
lightmap[texnum]->modified = true;
lightmap[texnum]->shader = shader;
// 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));
memset(lightmap[texnum]->stainmaps, 255, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3*sizeof(stmap));
//clear out the deluxmaps incase there is none on the map.
for (j = 0; j < LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3; j+=3)
@ -2317,13 +2330,13 @@ int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
}
/*not required, but using one lightmap per texture can result in better texture unit switching*/
if (lightmap[texnum]->shader != shader)
continue;
// if (lightmap[texnum]->shader != shader)
// continue;
if (lightmap[texnum]->external)
{
TEXASSIGN(lightmap_textures[texnum], R_AllocNewTexture("***lightmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
TEXASSIGN(deluxmap_textures[texnum], R_AllocNewTexture("***deluxmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
TEXASSIGN(lightmap[texnum]->lightmap_texture, R_AllocNewTexture("***lightmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
TEXASSIGN(lightmap[texnum]->deluxmap_texture, R_AllocNewTexture("***deluxmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT));
lightmap[texnum]->external = false;
}
@ -2359,6 +2372,9 @@ int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
Sys_Error ("AllocBlock: full");
return 0;
}
#endif
#if 0
//quake3 maps have their lightmaps in gl style already.
//rather than forgetting that and redoing it, let's just keep the data.
@ -2385,7 +2401,6 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
if (!lightmap[i])
{
lightmap[i] = BZ_Malloc(sizeof(*lightmap[i]));
lightmap[i]->meshchain = NULL;
lightmap[i]->modified = true;
lightmap[i]->external = true;
for (l=0 ; l<LMBLOCK_WIDTH ; l++)
@ -2463,6 +2478,7 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
}
return texnum;
}
#endif
unsigned int Surf_CalcMemSize(msurface_t *surf)
{
@ -2478,6 +2494,7 @@ unsigned int Surf_CalcMemSize(msurface_t *surf)
(sizeof(vecV_t)+sizeof(vec2_t)*2+sizeof(vec3_t)*3+sizeof(vec4_t))*surf->numedges;
}
#if 0
/*
================
BuildSurfaceDisplayList
@ -2581,13 +2598,15 @@ void Surf_BuildSurfaceDisplayList (model_t *model, msurface_t *fa, void **mem)
mesh->colors4f_array[i][3] = 1;
}
}
#endif
#if 0
/*
========================
GL_CreateSurfaceLightmap
========================
*/
static void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift)
void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift)
{
int smax, tmax;
qbyte *base, *luxbase; stmap *stainbase;
@ -2634,6 +2653,7 @@ static void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift)
Surf_BuildLightMap (surf, base, luxbase, stainbase, shift, r_ambient.value*255);
}
#endif
@ -2641,26 +2661,15 @@ void Surf_DeInit(void)
{
int i;
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++)
{
if (!lightmap[i])
break;
if (lightmap[i]->external)
{
R_DestroyTexture(lightmap[i]->lightmap_texture);
R_DestroyTexture(lightmap[i]->deluxmap_texture);
}
BZ_Free(lightmap[i]);
lightmap[i] = NULL;
}
@ -2670,6 +2679,8 @@ void Surf_DeInit(void)
lightmap=NULL;
numlightmaps=0;
Alias_Shutdown();
}
void Surf_Clear(model_t *mod)
@ -2679,16 +2690,6 @@ void Surf_Clear(model_t *mod)
int i;
if (mod->fromgame == fg_doom3)
return;/*they're on the hunk*/
for (i = 0; i < SHADER_SORT_COUNT; i++)
{
while ((b = mod->batches[i]))
{
mod->batches[i] = b->next;
BZ_Free(b->mesh);
Z_Free(b);
}
}
while(mod->vbos)
{
vbo = mod->vbos;
@ -2758,7 +2759,7 @@ Groups surfaces into their respective batches (based on the lightmap number).
*/
void Surf_BuildLightmaps (void)
{
int i, j, t;
int i, j, k, t;
model_t *m;
int shift;
msurface_t *surf;
@ -2784,6 +2785,154 @@ void Surf_BuildLightmaps (void)
if (cl.worldmodel->fromgame == fg_doom)
return; //no lightmaps.
numlightmaps = 0;
for (j=1 ; j<MAX_MODELS ; j++)
{
m = cl.model_precache[j];
if (!m)
break;
if (m->type != mod_brush)
continue;
if (!m->lightmaps.count)
continue;
if (m->needload)
continue;
currentmodel = m;
shift = Surf_LightmapShift(currentmodel);
i = numlightmaps + m->lightmaps.count;
lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(i));
while(i > numlightmaps)
{
i--;
lightmap[i] = Z_Malloc(sizeof(*lightmap[i]) + (sizeof(qbyte)*8 + sizeof(stmap)*3)*m->lightmaps.width*m->lightmaps.height);
lightmap[i]->width = m->lightmaps.width;
lightmap[i]->height = m->lightmaps.height;
lightmap[i]->lightmaps = (qbyte*)(lightmap[i]+1);
lightmap[i]->deluxmaps = (qbyte*)(lightmap[i]->lightmaps+4*lightmap[i]->width*lightmap[i]->height);
lightmap[i]->stainmaps = (stmap*)(lightmap[i]->deluxmaps+4*lightmap[i]->width*lightmap[i]->height);
lightmap[i]->modified = true;
// lightmap[i]->shader = NULL;
lightmap[i]->external = false;
// reset stainmap since it now starts at 255
memset(lightmap[i]->stainmaps, 255, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3*sizeof(stmap));
//clear out the deluxmaps incase there is none on the map.
for (k = 0; k < lightmap[i]->width*lightmap[i]->height*3; k+=3)
{
lightmap[i]->deluxmaps[k+0] = 128;
lightmap[i]->deluxmaps[k+1] = 128;
lightmap[i]->deluxmaps[k+2] = 255;
}
TEXASSIGN(lightmap[i]->lightmap_texture, R_AllocNewTexture("***lightmap***", lightmap[i]->width, lightmap[i]->height));
TEXASSIGN(lightmap[i]->deluxmap_texture, R_AllocNewTexture("***deluxmap***", lightmap[i]->width, lightmap[i]->height));
}
//fixup batch lightmaps
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
for (i = 0; i < MAXLIGHTMAPS; i++)
{
if (batch->lightmap[i] < 0)
continue;
batch->lightmap[i] = batch->lightmap[i] - m->lightmaps.first + numlightmaps;
}
}
/*particle emision based upon texture. this is lazy code*/
if (m == cl.worldmodel)
{
for (t = m->numtextures-1; t >= 0; t--)
{
ptype = P_FindParticleType(va("tex_%s", m->textures[t]->name));
if (ptype != P_INVALID)
{
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
if (surf->texinfo->texture == m->textures[t])
P_EmitSkyEffectTris(m, surf, ptype);
}
}
}
}
if (m->fromgame == fg_quake3)
{
int j;
unsigned char *src;
unsigned char *dst;
for (i = 0; i < m->lightmaps.count; i++)
{
dst = lightmap[numlightmaps+i]->lightmaps;
src = m->lightdata + i*m->lightmaps.width*m->lightmaps.height*3;
if (lightmap_bytes == 4)
{
if (lightmap_bgra)
{
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
{
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = 255;
}
}
else
{
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
{
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = 255;
}
}
}
}
}
else
{
int j;
lightmapinfo_t *lm;
//fixup surface lightmaps, and paint
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
for (j = 0; j < 4; j++)
{
if (surf->lightmaptexturenums[j] < m->lightmaps.first)
{
surf->lightmaptexturenums[j] = -1;
continue;
}
surf->lightmaptexturenums[j] = surf->lightmaptexturenums[0] - m->lightmaps.first + numlightmaps;
lm = lightmap[surf->lightmaptexturenums[j]];
Surf_BuildLightMap (surf,
lm->lightmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * lightmap_bytes,
lm->deluxmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * 3,
lm->stainmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * 3,
shift, r_ambient.value*255);
}
}
}
m->lightmaps.first = numlightmaps;
numlightmaps += m->lightmaps.count;
}
#if 0
for (j=1 ; j<MAX_MODELS ; j++)
{
m = cl.model_precache[j];
@ -2883,6 +3032,7 @@ void Surf_BuildLightmaps (void)
}
}
}
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
@ -2907,7 +3057,7 @@ void Surf_BuildLightmaps (void)
batch->meshes = 0;
}
}
#endif
BE_UploadAllLightmaps();
}
#endif

View File

@ -163,11 +163,14 @@ typedef struct
vrect_t pxrect; /*vrect, but in pixels rather than virtual coords*/
qboolean externalview; /*draw external models and not viewmodels*/
qboolean recurse; /*in a mirror/portal/half way through drawing something else*/
qboolean forcevis; /*if true, vis comes from the forcedvis field instead of recalculated*/
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*/
qbyte *forcedvis;
} refdef_t;
extern refdef_t r_refdef;
@ -210,22 +213,26 @@ typedef struct glRect_s {
typedef unsigned char stmap;
struct mesh_s;
typedef struct {
struct mesh_s *meshchain;
texid_t lightmap_texture;
texid_t deluxmap_texture;
qboolean modified;
qboolean deluxmodified;
qboolean external;
int width;
int height;
glRect_t rectchange;
glRect_t deluxrectchange;
#ifdef TERRAIN
int allocated[LMBLOCK_WIDTH];
qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage.
stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed.
shader_t *shader;
#endif
qbyte *lightmaps;//[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
qbyte *deluxmaps;//[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage.
stmap *stainmaps;//[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed.
} lightmapinfo_t;
extern lightmapinfo_t **lightmap;
extern int numlightmaps;
extern texid_t *lightmap_textures;
extern texid_t *deluxmap_textures;
//extern texid_t *lightmap_textures;
//extern texid_t *deluxmap_textures;
extern int lightmap_bytes; // 1, 3, or 4
extern qboolean lightmap_bgra; /*true=bgra, false=rgba*/
#endif
@ -299,6 +306,15 @@ 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);
texid_t D3D11_LoadTexture (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags);
texid_t D3D11_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags);
texid_t D3D11_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags);
texid_t D3D11_LoadCompressed (char *name);
texid_t D3D11_FindTexture (char *identifier);
texid_t D3D11_AllocNewTexture(char *ident, int width, int height);
void D3D11_Upload (texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags);
void D3D11_DestroyTexture (texid_t tex);
#endif
extern int image_width, image_height;

View File

@ -213,6 +213,9 @@ extern cvar_t r_waterwarp;
cvar_t r_polygonoffset_submodel_factor = SCVAR("r_polygonoffset_submodel_factor", "0.05");
cvar_t r_polygonoffset_submodel_offset = SCVAR("r_polygonoffset_submodel_offset", "25");
cvar_t r_polygonoffset_stencil_factor = SCVAR("r_polygonoffset_stencil_factor", "0.01");
cvar_t r_polygonoffset_stencil_offset = SCVAR("r_polygonoffset_stencil_offset", "1");
rendererstate_t currentrendererstate;
#if defined(GLQUAKE)
@ -457,9 +460,10 @@ void R_InitTextures (void)
{
int x,y, m;
qbyte *dest;
static char r_notexture_mip_mem[(sizeof(texture_t) + 16*16+8*8+4*4+2*2)];
// create a simple checkerboard texture for the default
r_notexture_mip = Z_Malloc (sizeof(texture_t) + 16*16+8*8+4*4+2*2);
r_notexture_mip = (texture_t*)r_notexture_mip_mem;
r_notexture_mip->width = r_notexture_mip->height = 16;
r_notexture_mip->offsets[0] = sizeof(texture_t);
@ -649,6 +653,8 @@ void Renderer_Init(void)
Cvar_Register (&r_showbboxes, GLRENDEREROPTIONS);
Cvar_Register (&r_polygonoffset_submodel_factor, GLRENDEREROPTIONS);
Cvar_Register (&r_polygonoffset_submodel_offset, GLRENDEREROPTIONS);
Cvar_Register (&r_polygonoffset_stencil_factor, GLRENDEREROPTIONS);
Cvar_Register (&r_polygonoffset_stencil_offset, GLRENDEREROPTIONS);
// misc
Cvar_Register(&con_ocranaleds, "Console controls");
@ -939,6 +945,11 @@ void R_ShutdownRenderer(void)
COM_FlushTempoaryPacks();
W_Shutdown();
if (host_basepal)
BZ_Free(host_basepal);
host_basepal = NULL;
S_Shutdown();
}
@ -1296,6 +1307,10 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
}
Skin_FlushPlayers();
#ifdef CSQC_DAT
CSQC_RendererRestarted();
#endif
}
else
{
@ -1829,35 +1844,47 @@ qbyte *R_MarkLeaves_Q2 (void)
int c;
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2)
return vis;
if (r_refdef.forcevis)
{
vis = r_refdef.forcedvis;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
r_oldviewcluster = 0;
r_oldviewcluster2 = 0;
}
else
{
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2)
return vis;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
if (r_novis.ival == 2)
return vis;
if (r_novis.ival || r_viewcluster == -1 || !cl.worldmodel->vis)
{
// mark everything
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
cl.worldmodel->leafs[i].visframe = r_visframecount;
for (i=0 ; i<cl.worldmodel->numnodes ; i++)
cl.worldmodel->nodes[i].visframe = r_visframecount;
return vis;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, curframevis, sizeof(curframevis));
// may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster)
{
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL, sizeof(curframevis));
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)curframevis)[i] |= ((int *)vis)[i];
vis = curframevis;
}
}
if (r_novis.ival == 2)
return vis;
r_visframecount++;
if (r_novis.ival || r_viewcluster == -1 || !cl.worldmodel->vis)
{
// mark everything
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
cl.worldmodel->leafs[i].visframe = r_visframecount;
for (i=0 ; i<cl.worldmodel->numnodes ; i++)
cl.worldmodel->nodes[i].visframe = r_visframecount;
return vis;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, curframevis, sizeof(curframevis));
// may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster)
{
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL, sizeof(curframevis));
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)curframevis)[i] |= ((int *)vis)[i];
vis = curframevis;
}
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
@ -1922,35 +1949,45 @@ qbyte *R_MarkLeaves_Q1 (void)
int i;
qbyte solid[4096];
if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.ival) || r_novis.ival & 2)
return vis;
r_visframecount++;
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
if (r_novis.ival)
if (r_refdef.forcevis)
{
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf)
{
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis, sizeof(fatvis));
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL, 0);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = r_refdef.forcedvis;
vis = fatvis;
r_oldviewleaf = NULL;
r_oldviewleaf2 = NULL;
}
else
{
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, fatvis, sizeof(fatvis));
if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.ival) || r_novis.ival & 2)
return vis;
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
if (r_novis.ival)
{
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf)
{
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis, sizeof(fatvis));
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL, 0);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
else
{
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, fatvis, sizeof(fatvis));
}
}
r_visframecount++;
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{
if (vis[i>>3] & (1<<(i&7)))

View File

@ -406,7 +406,7 @@ void Sbar_ExecuteLayoutString (char *s)
s = COM_Parse (s);
time = atoi(com_token);
// DrawAltString (x+32, y, ci->name);
Draw_AltFunString (x+32, y, cl.players[value].name);
Draw_FunString (x+32, y+8, "Score: ");
Draw_AltFunString (x+32+7*8, y+8, va("%i", score));
Draw_FunString (x+32, y+16, va("Ping: %i", ping));
@ -685,7 +685,7 @@ void Sbar_Hexen2InvLeft_f(void)
if (sb_hexen2_cur_item[pnum] < 0)
sb_hexen2_cur_item[pnum] = 14;
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
if (cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
break;
}
}
@ -707,7 +707,7 @@ void Sbar_Hexen2InvRight_f(void)
if (sb_hexen2_cur_item[pnum] > 14)
sb_hexen2_cur_item[pnum] = 0;
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
if (cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
break;
}
}
@ -1432,11 +1432,12 @@ void Sbar_CoopScoreboard (void)
char str[80];
int minutes, seconds, tens, units;
int l;
int pnum = 0; //doesn't matter, should all be the same
sprintf (str,"Monsters:%3i /%3i", cl.stats[0][STAT_MONSTERS], cl.stats[0][STAT_TOTALMONSTERS]);
sprintf (str,"Monsters:%3i /%3i", cl.playerview[pnum].stats[STAT_MONSTERS], cl.playerview[pnum].stats[STAT_TOTALMONSTERS]);
Sbar_DrawString (8, 4, str);
sprintf (str,"Secrets :%3i /%3i", cl.stats[0][STAT_SECRETS], cl.stats[0][STAT_TOTALSECRETS]);
sprintf (str,"Secrets :%3i /%3i", cl.playerview[pnum].stats[STAT_SECRETS], cl.playerview[pnum].stats[STAT_TOTALSECRETS]);
Sbar_DrawString (8, 12, str);
// time
@ -1477,7 +1478,7 @@ void Sbar_DrawInventory (int pnum)
{
if (sbar_rogue)
{
if ( cl.stats[pnum][STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
if ( cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
Sbar_DrawPic (0, -24, 320, 24, rsb_invbar[0]);
else
Sbar_DrawPic (0, -24, 320, 24, rsb_invbar[1]);
@ -1488,15 +1489,15 @@ void Sbar_DrawInventory (int pnum)
// weapons
for (i=0 ; i<7 ; i++)
{
if (cl.stats[pnum][STAT_ITEMS] & (IT_SHOTGUN<<i) )
if (cl.playerview[pnum].stats[STAT_ITEMS] & (IT_SHOTGUN<<i) )
{
time = cl.item_gettime[pnum][i];
time = cl.playerview[pnum].item_gettime[i];
flashon = (int)((cl.time - time)*10);
if (flashon < 0)
flashon = 0;
if (flashon >= 10)
{
if ( cl.stats[pnum][STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
if ( cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN<<i) )
flashon = 1;
else
flashon = 0;
@ -1522,11 +1523,11 @@ void Sbar_DrawInventory (int pnum)
if (sbar_rogue)
{
// check for powered up weapon.
if ( cl.stats[pnum][STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
if ( cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
{
for (i=0;i<5;i++)
{
if (cl.stats[pnum][STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
if (cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i))
{
if (headsup)
{
@ -1551,7 +1552,7 @@ void Sbar_DrawInventory (int pnum)
}
for (i=0 ; i<4 ; i++)
{
snprintf (num, sizeof(num), "%3i",cl.stats[pnum][STAT_SHELLS+i] );
snprintf (num, sizeof(num), "%3i",cl.playerview[pnum].stats[STAT_SHELLS+i] );
numc[0] = CON_WHITEMASK|0xe000|((num[0]!=' ')?(num[0] + 18-'0'):' ');
numc[1] = CON_WHITEMASK|0xe000|((num[1]!=' ')?(num[1] + 18-'0'):' ');
numc[2] = CON_WHITEMASK|0xe000|((num[2]!=' ')?(num[2] + 18-'0'):' ');
@ -1570,9 +1571,9 @@ void Sbar_DrawInventory (int pnum)
// items
for (i=0 ; i<6 ; i++)
{
if (cl.stats[pnum][STAT_ITEMS] & (1<<(17+i)))
if (cl.playerview[pnum].stats[STAT_ITEMS] & (1<<(17+i)))
{
time = cl.item_gettime[pnum][17+i];
time = cl.playerview[pnum].item_gettime[17+i];
if (time && time > cl.time - 2 && flashon )
{ // flash frame
sb_updates = 0;
@ -1589,9 +1590,9 @@ void Sbar_DrawInventory (int pnum)
// new rogue items
for (i=0 ; i<2 ; i++)
{
if (cl.stats[pnum][STAT_ITEMS] & (1<<(29+i)))
if (cl.playerview[pnum].stats[STAT_ITEMS] & (1<<(29+i)))
{
time = cl.item_gettime[pnum][29+i];
time = cl.playerview[pnum].item_gettime[29+i];
if (time && time > cl.time - 2 && flashon )
{ // flash frame
@ -1612,9 +1613,9 @@ void Sbar_DrawInventory (int pnum)
// sigils
for (i=0 ; i<4 ; i++)
{
if (cl.stats[pnum][STAT_ITEMS] & (1<<(28+i)))
if (cl.playerview[pnum].stats[STAT_ITEMS] & (1<<(28+i)))
{
time = cl.item_gettime[pnum][28+i];
time = cl.playerview[pnum].item_gettime[28+i];
if (time && time > cl.time - 2 && flashon )
{ // flash frame
sb_updates = 0;
@ -1704,37 +1705,37 @@ void Sbar_DrawFace (int pnum)
{
int f, anim;
if ( (cl.stats[pnum][STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) )
if ( (cl.playerview[pnum].stats[STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) )
== (IT_INVISIBILITY | IT_INVULNERABILITY) )
{
Sbar_DrawPic (112, 0, 24, 24, sb_face_invis_invuln);
return;
}
if (cl.stats[pnum][STAT_ITEMS] & IT_QUAD)
if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_QUAD)
{
Sbar_DrawPic (112, 0, 24, 24, sb_face_quad );
return;
}
if (cl.stats[pnum][STAT_ITEMS] & IT_INVISIBILITY)
if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_INVISIBILITY)
{
Sbar_DrawPic (112, 0, 24, 24, sb_face_invis );
return;
}
if (cl.stats[pnum][STAT_ITEMS] & IT_INVULNERABILITY)
if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_INVULNERABILITY)
{
Sbar_DrawPic (112, 0, 24, 24, sb_face_invuln);
return;
}
if (cl.stats[pnum][STAT_HEALTH] >= 100)
if (cl.playerview[pnum].stats[STAT_HEALTH] >= 100)
f = 4;
else
f = cl.stats[pnum][STAT_HEALTH] / 20;
f = cl.playerview[pnum].stats[STAT_HEALTH] / 20;
if (f < 0)
f=0;
if (cl.time <= cl.faceanimtime[pnum])
if (cl.time <= cl.playerview[pnum].faceanimtime)
{
anim = 1;
sb_updates = 0; // make sure the anim gets drawn over
@ -1755,7 +1756,7 @@ void Sbar_DrawNormal (int pnum)
Sbar_DrawPic (0, 0, 320, 24, sb_sbar);
// armor
if (cl.stats[pnum][STAT_ITEMS] & IT_INVULNERABILITY)
if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_INVULNERABILITY)
{
Sbar_DrawNum (24, 0, 666, 3, 1);
Sbar_DrawPic (0, 0, 24, 24, draw_disc);
@ -1764,24 +1765,24 @@ void Sbar_DrawNormal (int pnum)
{
if (sbar_rogue)
{
Sbar_DrawNum (24, 0, cl.stats[pnum][STAT_ARMOR], 3,
cl.stats[pnum][STAT_ARMOR] <= 25);
if (cl.stats[pnum][STAT_ITEMS] & RIT_ARMOR3)
Sbar_DrawNum (24, 0, cl.playerview[pnum].stats[STAT_ARMOR], 3,
cl.playerview[pnum].stats[STAT_ARMOR] <= 25);
if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_ARMOR3)
Sbar_DrawPic (0, 0, 24, 24, sb_armor[2]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_ARMOR2)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_ARMOR2)
Sbar_DrawPic (0, 0, 24, 24, sb_armor[1]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_ARMOR1)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_ARMOR1)
Sbar_DrawPic (0, 0, 24, 24, sb_armor[0]);
}
else
{
Sbar_DrawNum (24, 0, cl.stats[pnum][STAT_ARMOR], 3,
cl.stats[pnum][STAT_ARMOR] <= 25);
if (cl.stats[pnum][STAT_ITEMS] & IT_ARMOR3)
Sbar_DrawNum (24, 0, cl.playerview[pnum].stats[STAT_ARMOR], 3,
cl.playerview[pnum].stats[STAT_ARMOR] <= 25);
if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_ARMOR3)
Sbar_DrawPic (0, 0, 24, 24, sb_armor[2]);
else if (cl.stats[pnum][STAT_ITEMS] & IT_ARMOR2)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_ARMOR2)
Sbar_DrawPic (0, 0, 24, 24, sb_armor[1]);
else if (cl.stats[pnum][STAT_ITEMS] & IT_ARMOR1)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_ARMOR1)
Sbar_DrawPic (0, 0, 24, 24, sb_armor[0]);
}
}
@ -1790,41 +1791,41 @@ void Sbar_DrawNormal (int pnum)
Sbar_DrawFace (pnum);
// health
Sbar_DrawNum (136, 0, cl.stats[pnum][STAT_HEALTH], 3
, cl.stats[pnum][STAT_HEALTH] <= 25);
Sbar_DrawNum (136, 0, cl.playerview[pnum].stats[STAT_HEALTH], 3
, cl.playerview[pnum].stats[STAT_HEALTH] <= 25);
// ammo icon
if (sbar_rogue)
{
if (cl.stats[pnum][STAT_ITEMS] & RIT_SHELLS)
if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_SHELLS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[0]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_NAILS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_NAILS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[1]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_ROCKETS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_ROCKETS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[2]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_CELLS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_CELLS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[3]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_LAVA_NAILS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_LAVA_NAILS)
Sbar_DrawPic (224, 0, 24, 24, rsb_ammo[0]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_PLASMA_AMMO)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_PLASMA_AMMO)
Sbar_DrawPic (224, 0, 24, 24, rsb_ammo[1]);
else if (cl.stats[pnum][STAT_ITEMS] & RIT_MULTI_ROCKETS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & RIT_MULTI_ROCKETS)
Sbar_DrawPic (224, 0, 24, 24, rsb_ammo[2]);
}
else
{
if (cl.stats[pnum][STAT_ITEMS] & IT_SHELLS)
if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_SHELLS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[0]);
else if (cl.stats[pnum][STAT_ITEMS] & IT_NAILS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_NAILS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[1]);
else if (cl.stats[pnum][STAT_ITEMS] & IT_ROCKETS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_ROCKETS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[2]);
else if (cl.stats[pnum][STAT_ITEMS] & IT_CELLS)
else if (cl.playerview[pnum].stats[STAT_ITEMS] & IT_CELLS)
Sbar_DrawPic (224, 0, 24, 24, sb_ammo[3]);
}
Sbar_DrawNum (248, 0, cl.stats[pnum][STAT_AMMO], 3
, cl.stats[pnum][STAT_AMMO] <= 10);
Sbar_DrawNum (248, 0, cl.playerview[pnum].stats[STAT_AMMO], 3
, cl.playerview[pnum].stats[STAT_AMMO] <= 10);
}
qboolean Sbar_ShouldDraw (void)
@ -1874,7 +1875,7 @@ void Sbar_DrawScoreboard (void)
for (pnum = 0; pnum < cl.splitclients; pnum++)
{
if (cl.stats[pnum][STAT_HEALTH] <= 0)
if (cl.playerview[pnum].stats[STAT_HEALTH] <= 0)
deadcount++;
}
@ -1901,7 +1902,7 @@ void Sbar_Hexen2DrawItem(int pnum, int x, int y, int itemnum)
int num;
Sbar_DrawPic(x, y, 29, 28, R2D_SafeCachePic(va("gfx/arti%02d.lmp", itemnum)));
num = cl.stats[pnum][STAT_H2_CNT_TORCH+itemnum];
num = cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+itemnum];
if(num > 0)
{
if (num >= 10)
@ -1920,7 +1921,7 @@ void Sbar_Hexen2DrawInventory(int pnum)
/*always select an artifact that we actually have whether we are drawing the full bar or not.*/
for (i = 0; i < 15; i++)
{
if (cl.stats[pnum][STAT_H2_CNT_TORCH+(i+sb_hexen2_cur_item[pnum])%15])
if (cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+(i+sb_hexen2_cur_item[pnum])%15])
{
sb_hexen2_cur_item[pnum] = (sb_hexen2_cur_item[pnum] + i)%15;
break;
@ -1931,10 +1932,10 @@ void Sbar_Hexen2DrawInventory(int pnum)
return;
for (i = sb_hexen2_cur_item[pnum]; i < 15; i++)
if (sb_hexen2_cur_item[pnum] == i || cl.stats[pnum][STAT_H2_CNT_TORCH+i] > 0)
if (sb_hexen2_cur_item[pnum] == i || cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+i] > 0)
activeright++;
for (i = sb_hexen2_cur_item[pnum]-1; i >= 0; i--)
if (sb_hexen2_cur_item[pnum] == i || cl.stats[pnum][STAT_H2_CNT_TORCH+i] > 0)
if (sb_hexen2_cur_item[pnum] == i || cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+i] > 0)
activeleft++;
if (activeleft > 3 + (activeright<=3?(4-activeright):0))
@ -1942,7 +1943,7 @@ void Sbar_Hexen2DrawInventory(int pnum)
x=320/2-114 + (activeleft-1)*33;
for (i = sb_hexen2_cur_item[pnum]-1; x>=320/2-114; i--)
{
if (!cl.stats[pnum][STAT_H2_CNT_TORCH+i])
if (!cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+i])
continue;
if (i == sb_hexen2_cur_item[pnum])
@ -1954,7 +1955,7 @@ void Sbar_Hexen2DrawInventory(int pnum)
x=320/2-114 + activeleft*33;
for (i = sb_hexen2_cur_item[pnum]; i < 15 && x < 320/2-114+7*33; i++)
{
if (i != sb_hexen2_cur_item[pnum] && !cl.stats[pnum][STAT_H2_CNT_TORCH+i])
if (i != sb_hexen2_cur_item[pnum] && !cl.playerview[pnum].stats[STAT_H2_CNT_TORCH+i])
continue;
if (i == sb_hexen2_cur_item[pnum])
Sbar_DrawPic(x+9, y-12, 11, 11, R2D_SafeCachePic("gfx/artisel.lmp"));
@ -1985,7 +1986,7 @@ void Sbar_Hexen2DrawExtra (int pnum)
Con_Printf("Objectives:\n");
for (i = 0; i < 64; i++)
{
if (cl.stats[pnum][STAT_H2_OBJECTIVE1 + i/32] & (1<<(i&31)))
if (cl.playerview[pnum].stats[STAT_H2_OBJECTIVE1 + i/32] & (1<<(i&31)))
Con_Printf("%s\n", T_GetInfoString(i));
}
sb_hexen2_infoplaque[pnum] = false;
@ -2011,44 +2012,44 @@ void Sbar_Hexen2DrawExtra (int pnum)
Sbar_DrawTinyString (11, 48, pclassname[pclass]);
Sbar_DrawTinyString (11, 58, va("int"));
Sbar_DrawTinyString (33, 58, va("%02d", cl.stats[pnum][STAT_H2_INTELLIGENCE]));
Sbar_DrawTinyString (33, 58, va("%02d", cl.playerview[pnum].stats[STAT_H2_INTELLIGENCE]));
Sbar_DrawTinyString (11, 64, va("wis"));
Sbar_DrawTinyString (33, 64, va("%02d", cl.stats[pnum][STAT_H2_WISDOM]));
Sbar_DrawTinyString (33, 64, va("%02d", cl.playerview[pnum].stats[STAT_H2_WISDOM]));
Sbar_DrawTinyString (11, 70, va("dex"));
Sbar_DrawTinyString (33, 70, va("%02d", cl.stats[pnum][STAT_H2_DEXTERITY]));
Sbar_DrawTinyString (33, 70, va("%02d", cl.playerview[pnum].stats[STAT_H2_DEXTERITY]));
Sbar_DrawTinyString (58, 58, va("str"));
Sbar_DrawTinyString (80, 58, va("%02d", cl.stats[pnum][STAT_H2_STRENGTH]));
Sbar_DrawTinyString (80, 58, va("%02d", cl.playerview[pnum].stats[STAT_H2_STRENGTH]));
Sbar_DrawTinyString (58, 64, va("lvl"));
Sbar_DrawTinyString (80, 64, va("%02d", cl.stats[pnum][STAT_H2_LEVEL]));
Sbar_DrawTinyString (80, 64, va("%02d", cl.playerview[pnum].stats[STAT_H2_LEVEL]));
Sbar_DrawTinyString (58, 70, va("exp"));
Sbar_DrawTinyString (80, 70, va("%06d", cl.stats[pnum][STAT_H2_EXPERIENCE]));
Sbar_DrawTinyString (80, 70, va("%06d", cl.playerview[pnum].stats[STAT_H2_EXPERIENCE]));
Sbar_DrawTinyString (11, 79, va("abilities"));
if (cl.stats[pnum][STAT_H2_FLAGS] & (1<<22))
if (cl.playerview[pnum].stats[STAT_H2_FLAGS] & (1<<22))
Sbar_DrawTinyString (8, 89, T_GetString(400 + 2*(pclass-1) + 0));
if (cl.stats[pnum][STAT_H2_FLAGS] & (1<<23))
if (cl.playerview[pnum].stats[STAT_H2_FLAGS] & (1<<23))
Sbar_DrawTinyString (8, 96, T_GetString(400 + 2*(pclass-1) + 1));
for (i = 0; i < 4; i++)
{
if (cl.stats[pnum][STAT_H2_ARMOUR1+i] > 0)
if (cl.playerview[pnum].stats[STAT_H2_ARMOUR1+i] > 0)
{
Sbar_DrawPic (164+i*40, 115, 28, 19, R2D_SafeCachePic(va("gfx/armor%d.lmp", i+1)));
Sbar_DrawTinyString (168+i*40, 136, va("+%d", cl.stats[pnum][STAT_H2_ARMOUR1+i]));
Sbar_DrawTinyString (168+i*40, 136, va("+%d", cl.playerview[pnum].stats[STAT_H2_ARMOUR1+i]));
}
}
for (i = 0; i < 4; i++)
{
if (cl.stats[pnum][STAT_H2_FLIGHT_T+i] > 0)
if (cl.playerview[pnum].stats[STAT_H2_FLIGHT_T+i] > 0)
{
Sbar_DrawPic (ringpos[i], 119, 32, 22, R2D_SafeCachePic(va("gfx/ring_f.lmp")));
val = cl.stats[pnum][STAT_H2_FLIGHT_T+i];
val = cl.playerview[pnum].stats[STAT_H2_FLIGHT_T+i];
if (val > 100)
val = 100;
if (val < 0)
@ -2061,9 +2062,9 @@ void Sbar_Hexen2DrawExtra (int pnum)
slot = 0;
for (i = 0; i < 8; i++)
{
if (cl.statsstr[pnum][STAT_H2_PUZZLE1+i])
if (cl.playerview[pnum].statsstr[STAT_H2_PUZZLE1+i])
{
Sbar_DrawPic (194+(slot%4)*31, slot<4?51:82, 26, 26, R2D_SafeCachePic(va("gfx/puzzle/%s.lmp", cl.statsstr[pnum][STAT_H2_PUZZLE1+i])));
Sbar_DrawPic (194+(slot%4)*31, slot<4?51:82, 26, 26, R2D_SafeCachePic(va("gfx/puzzle/%s.lmp", cl.playerview[pnum].statsstr[STAT_H2_PUZZLE1+i])));
slot++;
}
}
@ -2095,10 +2096,10 @@ int Sbar_Hexen2ArmourValue(int pnum)
classno--;
for (i = 0; i < 4; i++)
{
if (cl.stats[pnum][STAT_H2_ARMOUR1+i])
if (cl.playerview[pnum].stats[STAT_H2_ARMOUR1+i])
{
ac += acv[classno][i];
ac += cl.stats[pnum][STAT_H2_ARMOUR1+i]/5.0;
ac += cl.playerview[pnum].stats[STAT_H2_ARMOUR1+i]/5.0;
}
}
}
@ -2116,8 +2117,8 @@ void Sbar_Hexen2DrawBasic(int pnum)
Sbar_DrawPic(269, -23, 51, 23, R2D_SafeCachePic("gfx/topbumpr.lmp"));
//mana1
maxval = cl.stats[pnum][STAT_H2_MAXMANA];
val = cl.stats[pnum][STAT_H2_BLUEMANA];
maxval = cl.playerview[pnum].stats[STAT_H2_MAXMANA];
val = cl.playerview[pnum].stats[STAT_H2_BLUEMANA];
val = bound(0, val, maxval);
Sbar_DrawTinyString(201, 22, va("%03d", val));
if(val)
@ -2127,8 +2128,8 @@ void Sbar_Hexen2DrawBasic(int pnum)
}
//mana2
maxval = cl.stats[pnum][STAT_H2_MAXMANA];
val = cl.stats[pnum][STAT_H2_GREENMANA];
maxval = cl.playerview[pnum].stats[STAT_H2_MAXMANA];
val = cl.playerview[pnum].stats[STAT_H2_GREENMANA];
val = bound(0, val, maxval);
Sbar_DrawTinyString(243, 22, va("%03d", val));
if(val)
@ -2139,7 +2140,7 @@ void Sbar_Hexen2DrawBasic(int pnum)
//health
val = cl.stats[pnum][STAT_HEALTH];
val = cl.playerview[pnum].stats[STAT_HEALTH];
if (val < -99)
val = -99;
Sbar_Hexen2DrawNum(58, 14, val, 3);
@ -2149,7 +2150,7 @@ void Sbar_Hexen2DrawBasic(int pnum)
Sbar_Hexen2DrawNum(105, 14, val, 2);
// SetChainPosition(cl.v.health, cl.v.max_health);
chainpos = (195.0f*cl.stats[pnum][STAT_HEALTH]) / cl.stats[pnum][STAT_H2_MAXHEALTH];
chainpos = (195.0f*cl.playerview[pnum].stats[STAT_HEALTH]) / cl.playerview[pnum].stats[STAT_H2_MAXHEALTH];
if (chainpos < 0)
chainpos = 0;
Sbar_DrawPic(45+((int)chainpos&7), 38, 222, 5, R2D_SafeCachePic("gfx/hpchain.lmp"));
@ -2168,10 +2169,10 @@ void Sbar_Hexen2DrawMinimal(int pnum)
Sbar_DrawPic(3, y, 31, 17, R2D_SafeCachePic("gfx/bmmana.lmp"));
Sbar_DrawPic(3, y+18, 31, 17, R2D_SafeCachePic("gfx/gmmana.lmp"));
Sbar_DrawTinyString(10, y+6, va("%03d", cl.stats[pnum][STAT_H2_BLUEMANA]));
Sbar_DrawTinyString(10, y+18+6, va("%03d", cl.stats[pnum][STAT_H2_GREENMANA]));
Sbar_DrawTinyString(10, y+6, va("%03d", cl.playerview[pnum].stats[STAT_H2_BLUEMANA]));
Sbar_DrawTinyString(10, y+18+6, va("%03d", cl.playerview[pnum].stats[STAT_H2_GREENMANA]));
Sbar_Hexen2DrawNum(38, y+18, cl.stats[pnum][STAT_HEALTH], 3);
Sbar_Hexen2DrawNum(38, y+18, cl.playerview[pnum].stats[STAT_HEALTH], 3);
}
@ -2420,14 +2421,14 @@ void Sbar_Draw (void)
if (sbarfailed) //files failed to load.
{
if (cl.stats[pnum][STAT_HEALTH] <= 0) //when dead, show nothing
if (cl.playerview[pnum].stats[STAT_HEALTH] <= 0) //when dead, show nothing
continue;
// if (scr_viewsize.value != 120)
// Cvar_Set(&scr_viewsize, "120");
Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH]));
Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR]));
Sbar_DrawString (0, -8, va("Health: %i", cl.playerview[pnum].stats[STAT_HEALTH]));
Sbar_DrawString (0, -16, va(" Armor: %i", cl.playerview[pnum].stats[STAT_ARMOR]));
Sbar_Voice(-24);
continue;
@ -2457,7 +2458,7 @@ void Sbar_Draw (void)
}
else
{
if (sb_showscores || sb_showteamscores || cl.stats[pnum][STAT_HEALTH] <= 0)
if (sb_showscores || sb_showteamscores || cl.playerview[pnum].stats[STAT_HEALTH] <= 0)
Sbar_SoloScoreboard ();
// else if (cls.gamemode != GAME_DEATHMATCH)
// Sbar_CoopScoreboard ();
@ -2472,7 +2473,7 @@ void Sbar_Draw (void)
}
}
}
else if (sb_showscores || sb_showteamscores || (cl.stats[pnum][STAT_HEALTH] <= 0 && cl.splitclients == 1))
else if (sb_showscores || sb_showteamscores || (cl.playerview[pnum].stats[STAT_HEALTH] <= 0 && cl.splitclients == 1))
{
if (!pnum)
{
@ -3216,6 +3217,7 @@ void Sbar_CoopIntermission (void)
mpic_t *pic;
int dig;
int num;
int pnum = 0; //should be the same for all players.
sbar_rect.width = vid.width;
sbar_rect.height = vid.height;
@ -3240,13 +3242,13 @@ void Sbar_CoopIntermission (void)
R2D_ScalePic ((sbar_rect.width - 320)/2 + 266,(sbar_rect.height - 200)/2 + 64, 16, 24, sb_nums[0][num%10]);
//it is assumed that secrits/monsters are going to be constant for any player...
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 104, cl.stats[0][STAT_SECRETS], 3, 0);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 104, cl.playerview[pnum].stats[STAT_SECRETS], 3, 0);
R2D_ScalePic ((sbar_rect.width - 320)/2 + 232,(sbar_rect.height - 200)/2 + 104, 16, 24, sb_slash);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 240, (sbar_rect.height - 200)/2 + 104, cl.stats[0][STAT_TOTALSECRETS], 3, 0);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 240, (sbar_rect.height - 200)/2 + 104, cl.playerview[pnum].stats[STAT_TOTALSECRETS], 3, 0);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 144, cl.stats[0][STAT_MONSTERS], 3, 0);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 144, cl.playerview[pnum].stats[STAT_MONSTERS], 3, 0);
R2D_ScalePic ((sbar_rect.width - 320)/2 + 232,(sbar_rect.height - 200)/2 + 144, 16, 24, sb_slash);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 240, (sbar_rect.height - 200)/2 + 144, cl.stats[0][STAT_TOTALMONSTERS], 3, 0);
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 240, (sbar_rect.height - 200)/2 + 144, cl.playerview[pnum].stats[STAT_TOTALMONSTERS], 3, 0);
}
/*
==================

View File

@ -658,7 +658,7 @@ static int OpenAL_InitCard(soundcardinfo_t *sc, int cardnum)
sc->GetDMAPos = OpenAL_GetDMAPos;
sc->ChannelUpdate = OpenAL_ChannelUpdate;
snprintf(sc->name, sizeof(sc->name), "OpenAL device");
Q_snprintfz(sc->name, sizeof(sc->name), "OpenAL device");
sc->openal = 1;
sc->inactive_sound = true;

View File

@ -275,7 +275,7 @@ typedef struct {
GUID SubFormat;
} QWAVEFORMATEX;
const static GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010,
const static GUID QKSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010,
{0x80,
0x00,
0x00,
@ -574,7 +574,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
{
format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
format.Format.cbSize = 22;
memcpy(&format.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
memcpy(&format.SubFormat, &QKSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
format.dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
sc->sn.numchannels = 8;
@ -583,7 +583,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
{
format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
format.Format.cbSize = 22;
memcpy(&format.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
memcpy(&format.SubFormat, &QKSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
format.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
sc->sn.numchannels = 6;
@ -592,7 +592,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum)
{
format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
format.Format.cbSize = 22;
memcpy(&format.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
memcpy(&format.SubFormat, &QKSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID));
format.dwChannelMask = KSAUDIO_SPEAKER_QUAD;
sc->sn.numchannels = 4;

View File

@ -30,6 +30,7 @@ static void S_StopAllSounds_f (void);
static void S_UpdateCard(soundcardinfo_t *sc);
static void S_ClearBuffer (soundcardinfo_t *sc);
static sfx_t *S_FindName (char *name);
// =======================================================================
// Internal sound data & structures
@ -883,7 +884,7 @@ void S_Startup (void)
CL_InitTEntSounds();
}
void SNDDMA_SetUnderWater(qboolean underwater)
void S_SetUnderWater(qboolean underwater)
{
soundcardinfo_t *sc;
@ -895,6 +896,8 @@ void SNDDMA_SetUnderWater(qboolean underwater)
//so that the video code can call it directly without flushing the models it's just loaded.
void S_DoRestart (void)
{
int i;
S_StopAllSounds (true);
S_Shutdown();
@ -907,6 +910,14 @@ void S_DoRestart (void)
ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav");
S_StopAllSounds (true);
for (i=1 ; i<MAX_SOUNDS ; i++)
{
if (!cl.sound_name[i][0])
break;
cl.sound_precache[i] = S_FindName (cl.sound_name[i]);
}
}
void S_Restart_f (void)
@ -1207,7 +1218,7 @@ S_FindName
also touches it
==================
*/
sfx_t *S_FindName (char *name)
static sfx_t *S_FindName (char *name)
{
int i;
sfx_t *sfx;

View File

@ -598,7 +598,7 @@ qboolean ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth, int i
#define DSPK_BASE 170.0
#define DSPK_EXP 0.0433
/*
sfxcache_t *S_LoadDoomSpeakerSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
{
sfxcache_t *sc;
@ -674,20 +674,20 @@ sfxcache_t *S_LoadDoomSpeakerSound (sfx_t *s, qbyte *data, int datalen, int snds
return sc;
}
sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
*/
qboolean S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
{
// format data from Unofficial Doom Specs v1.6
unsigned short *dataus;
int samples, rate;
if (datalen < 8)
return NULL;
return false;
dataus = (unsigned short*)data;
if (LittleShort(dataus[0]) != 3)
return NULL;
return false;
rate = LittleShort(dataus[1]);
samples = LittleShort(dataus[2]);
@ -696,13 +696,11 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
datalen -= 8;
if (datalen != samples)
return NULL;
return false;
COM_CharBias(data, datalen);
ResampleSfx (s, rate, 1, 1, samples, -1, data);
return Cache_Check(&s->cache);
return ResampleSfx (s, rate, 1, 1, samples, -1, data);
}
#endif
@ -739,7 +737,7 @@ S_LoadSound_t AudioInputPlugins[10] =
S_LoadWavSound,
#ifdef DOOMWADS
S_LoadDoomSound,
S_LoadDoomSpeakerSound,
// S_LoadDoomSpeakerSound,
#endif
};
@ -784,7 +782,7 @@ qboolean S_LoadSound (sfx_t *s)
FILE *f;
#ifndef _WIN32 //convert from windows to a suitable alternative.
char unixname[128];
snprintf(unixname, sizeof(unixname), "/mnt/%c/%s", name[0]-'A'+'a', name+3);
Q_snprintfz(unixname, sizeof(unixname), "/mnt/%c/%s", name[0]-'A'+'a', name+3);
name = unixname;
while (*name)
{

View File

@ -228,33 +228,24 @@ sfxcache_t *OV_DecodeSome(struct sfx_s *sfx, struct sfxcache_s *buf, int start,
}
void OV_CancelDecoder(sfx_t *s)
{
/*
sfxcache_t *src, *dest;
ovdecoderbuffer_t *dec;
dec = s->decoder->buf;
dec = s->decoder.buf;
s->decoder.buf = NULL;
s->decoder.abort = NULL;
s->decoder.decodedata = NULL;
p_ov_clear (&dec->vf); //close the decoder
//copy to new buffer
src = s->cache.data;
s->cache.fake = false;
s->cache.data = NULL;
dest = Cache_Alloc(&s->cache, dec->mediaaswavpos, s->name);
memcpy(dest, src, dec->mediaaswavpos);
BZ_Free(src);
if (dec->tempbuffer)
{
BZ_Free(dec->tempbuffer);
dec->tempbufferbytes = NULL;
dec->tempbufferbytes = 0;
}
Z_Free(s->decoder);
s->decoder = NULL;
*/
BZ_Free(dec->decodedbuffer);
dec->decodedbuffer = NULL;
//and it's now indistinguisable from a wav
BZ_Free(dec);
}
static size_t VARGS read_func (void *ptr, size_t size, size_t nmemb, void *datasource)

View File

@ -39,7 +39,6 @@ typedef struct
} portable_samplegroup_t;
typedef struct {
int decodedlen;
struct sfxcache_s *(*decodedata) (struct sfx_s *sfx, struct sfxcache_s *buf, int start, int length); //retrurn true when done.
void (*abort) (struct sfx_s *sfx); //it's not playing elsewhere. free entirly
void *buf;
@ -176,6 +175,7 @@ void SND_ResampleStream (void *in, int inrate, int inwidth, int inchannels, int
// restart entire sound subsystem (doesn't flush old sounds, so make sure that happens)
void S_DoRestart (void);
void S_SetUnderWater(qboolean underwater);
void S_Restart_f (void);

View File

@ -19,6 +19,7 @@ qboolean isDedicated = false;
#endif
void *sys_window; /*public so the renderer can attach to the correct place*/
static qboolean sys_running = false;
int sys_glesversion;
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, DISTRIBUTION"Droid", __VA_ARGS__))
@ -48,11 +49,12 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj,
jint width, jint height, jstring japkpath, jstring jusrpath)
jint width, jint height, jint glesversion, jstring japkpath, jstring jusrpath)
{
char *tmp;
vid.pixelwidth = width;
vid.pixelheight = height;
sys_glesversion = glesversion;
if (sys_running)
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
else

View File

@ -36,6 +36,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <process.h>
#endif
#ifdef GLQUAKE
#define PRINTGLARRAYS
#endif
#ifdef _DEBUG
#if _MSC_VER >= 1300
#define CATCHCRASH
@ -53,6 +57,8 @@ unsigned int sys_parenttop;
unsigned int sys_parentwidth; //valid if sys_parentwindow is set
unsigned int sys_parentheight;
extern int fs_switchgame;
#ifdef RESTARTTEST
jmp_buf restart_jmpbuf;
@ -362,7 +368,7 @@ typedef BOOL (WINAPI *MINIDUMPWRITEDUMP) (
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
#if 0
#ifdef PRINTGLARRAYS
#include "glquake.h"
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
@ -390,7 +396,7 @@ DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exception
HMODULE hKernel;
BOOL (WINAPI *pIsDebuggerPresent)(void);
#if 0
#ifdef PRINTGLARRAYS
int rval;
void *ptr;
int i;
@ -805,6 +811,14 @@ void Sys_Shutdown(void)
VirtualFree(host_parms.membase, 0, MEM_RELEASE);
host_parms.membase = 0;
}
if (tevent)
CloseHandle (tevent);
tevent = NULL;
if (qwclsemaphore)
CloseHandle (qwclsemaphore);
qwclsemaphore = NULL;
}
@ -844,6 +858,39 @@ void VARGS Sys_Error (const char *error, ...)
#endif
}
static wchar_t dequake(conchar_t chr)
{
chr &= CON_CHARMASK;
/*only this range are quake chars*/
if (chr >= 0xe000 && chr < 0xe100)
{
chr &= 0xff;
if (chr >= 146 && chr < 156)
chr = chr - 146 + '0';
if (chr >= 0x12 && chr <= 0x1b)
chr = chr - 0x12 + '0';
if (chr == 143)
chr = '.';
if (chr == 128 || chr == 129 || chr == 130 || chr == 157 || chr == 158 || chr == 159)
chr = '-';
if (chr >= 128)
chr -= 128;
if (chr == 16)
chr = '[';
if (chr == 17)
chr = ']';
if (chr == 0x1c)
chr = 249;
}
/*this range contains pictograms*/
if (chr >= 0xe100 && chr < 0xe200)
{
chr = '?';
}
return chr;
}
void VARGS Sys_Printf (char *fmt, ...)
{
va_list argptr;
@ -859,7 +906,19 @@ void VARGS Sys_Printf (char *fmt, ...)
#ifdef _DEBUG
if (debugout)
OutputDebugString(text); //msvc debug output
{
//msvc debug output
conchar_t msg[1024], *end;
wchar_t wide[1024];
int i;
end = COM_ParseFunString(CON_WHITEMASK, text, msg, sizeof(msg), false);
for (i = 0; msg+i < end; i++)
{
wide[i] = dequake(msg[i] & CON_CHARMASK);
}
wide[i] = 0;
OutputDebugStringW(wide);
}
#endif
if (houtput)
WriteFile (houtput, text, strlen(text), &dummy, NULL);
@ -872,17 +931,13 @@ void Sys_Quit (void)
Host_Shutdown ();
if (tevent)
CloseHandle (tevent);
if (qwclsemaphore)
CloseHandle (qwclsemaphore);
SetHookState(false);
#else
SV_Shutdown();
#endif
TL_Shutdown();
#ifdef RESTARTTEST
longjmp(restart_jmpbuf, 1);
#endif
@ -894,6 +949,12 @@ void Sys_Quit (void)
longjmp (host_abort, 1);
}
#else
#ifdef USE_MSVCRT_DEBUG
if (_CrtDumpMemoryLeaks())
OutputDebugStringA("Leaks detected\n");
#endif
exit(1);
#endif
}
@ -1398,6 +1459,10 @@ HWND hwnd_dialog;
#include "ntverp.h"
#endif
#if defined(__MINGW64_VERSION_MAJOR) && (__MINGW64_VERSION_MAJOR >= 3)
#define SHARD_APPIDINFOLINK SHARD_APPIDINFOLINK
#endif
#ifndef SHARD_APPIDINFOLINK
// SDK version 7600 = v7.0a & v7.1
@ -1747,7 +1812,6 @@ void Win7_TaskListInit(void)
}
#endif
/*
#ifdef _MSC_VER
#include <signal.h>
@ -1773,7 +1837,6 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (hPrevInstance)
return 0;
#ifndef MINGW
#if _MSC_VER > 1200
Win7_Init();
@ -2018,6 +2081,20 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
Sys_Error("wut?");
#endif
}
#ifndef SERVERONLY
if (fs_switchgame != -1)
{
SetHookState(false);
Host_Shutdown ();
COM_InitArgv (parms.argc, parms.argv);
if (!Sys_Startup_CheckMem(&parms))
return 0;
Host_Init (&parms);
}
#endif
}
}
#ifdef CATCHCRASH

View File

@ -165,7 +165,7 @@ float V_CalcBob (int pnum, qboolean queryold)
// bob is proportional to simulated velocity in the xy plane
// (don't count Z, or jumping messes it up)
bob[pnum] = sqrt(cl.simvel[pnum][0]*cl.simvel[pnum][0] + cl.simvel[pnum][1]*cl.simvel[pnum][1]) * cl_bob.value;
bob[pnum] = sqrt(cl.playerview[pnum].simvel[0]*cl.playerview[pnum].simvel[0] + cl.playerview[pnum].simvel[1]*cl.playerview[pnum].simvel[1]) * cl_bob.value;
bob[pnum] = bob[pnum]*0.3 + bob[pnum]*0.7*sin(cycle);
if (bob[pnum] > 4)
bob[pnum] = 4;
@ -186,24 +186,24 @@ cvar_t v_centerspeed = SCVAR("v_centerspeed","500");
void V_StartPitchDrift (int pnum)
{
#if 1
if (cl.laststop[pnum] == cl.time)
if (cl.playerview[pnum].laststop == cl.time)
{
return; // something else is keeping it from drifting
}
#endif
if (cl.nodrift || !cl.pitchvel)
if (cl.playerview[pnum].nodrift || !cl.playerview[pnum].pitchvel)
{
cl.pitchvel[pnum] = v_centerspeed.value;
cl.nodrift[pnum] = false;
cl.driftmove[pnum] = 0;
cl.playerview[pnum].pitchvel = v_centerspeed.value;
cl.playerview[pnum].nodrift = false;
cl.playerview[pnum].driftmove = 0;
}
}
void V_StopPitchDrift (int pnum)
{
cl.laststop[pnum] = cl.time;
cl.nodrift[pnum] = true;
cl.pitchvel[pnum] = 0;
cl.playerview[pnum].laststop = cl.time;
cl.playerview[pnum].nodrift = true;
cl.playerview[pnum].pitchvel = 0;
}
/*
@ -225,36 +225,36 @@ void V_DriftPitch (int pnum)
if (!cl.onground || cls.demoplayback )
{
cl.driftmove[pnum] = 0;
cl.pitchvel[pnum] = 0;
cl.playerview[pnum].driftmove = 0;
cl.playerview[pnum].pitchvel = 0;
return;
}
// don't count small mouse motion
if (cl.nodrift[pnum])
if (cl.playerview[pnum].nodrift)
{
if ( fabs(cl.frames[(cls.netchan.outgoing_sequence-1)&UPDATE_MASK].cmd[pnum].forwardmove) < 200)
cl.driftmove[pnum] = 0;
cl.playerview[pnum].driftmove = 0;
else
cl.driftmove[pnum] += host_frametime;
cl.playerview[pnum].driftmove += host_frametime;
if ( cl.driftmove[pnum] > v_centermove.value)
if ( cl.playerview[pnum].driftmove > v_centermove.value)
{
V_StartPitchDrift (pnum);
}
return;
}
delta = 0 - cl.viewangles[pnum][PITCH];
delta = 0 - cl.playerview[pnum].viewangles[PITCH];
if (!delta)
{
cl.pitchvel[pnum] = 0;
cl.playerview[pnum].pitchvel = 0;
return;
}
move = host_frametime * cl.pitchvel[pnum];
cl.pitchvel[pnum] += host_frametime * v_centerspeed.value;
move = host_frametime * cl.playerview[pnum].pitchvel;
cl.playerview[pnum].pitchvel += host_frametime * v_centerspeed.value;
//Con_Printf ("move: %f (%f)\n", move, host_frametime);
@ -262,19 +262,19 @@ void V_DriftPitch (int pnum)
{
if (move > delta)
{
cl.pitchvel[pnum] = 0;
cl.playerview[pnum].pitchvel = 0;
move = delta;
}
cl.viewangles[pnum][PITCH] += move;
cl.playerview[pnum].viewangles[PITCH] += move;
}
else if (delta < 0)
{
if (move > -delta)
{
cl.pitchvel[pnum] = 0;
cl.playerview[pnum].pitchvel = 0;
move = -delta;
}
cl.viewangles[pnum][PITCH] -= move;
cl.playerview[pnum].viewangles[PITCH] -= move;
}
}
@ -395,7 +395,7 @@ void V_ParseDamage (int pnum)
if (v_damagecshift.value >= 0)
count *= v_damagecshift.value;
cl.faceanimtime[pnum] = cl.time + 0.2; // but sbar face into pain frame
cl.playerview[pnum].faceanimtime = cl.time + 0.2; // but sbar face into pain frame
cl.cshifts[CSHIFT_DAMAGE].percent += 3*count;
if (cl.cshifts[CSHIFT_DAMAGE].percent < 0)
@ -425,10 +425,10 @@ void V_ParseDamage (int pnum)
//
// calculate view angle kicks
//
VectorSubtract (from, cl.simorg[pnum], from);
VectorSubtract (from, cl.playerview[pnum].simorg, from);
VectorNormalize (from);
AngleVectors (cl.simangles[pnum], forward, right, up);
AngleVectors (cl.playerview[pnum].simangles, forward, right, up);
side = DotProduct (from, right);
v_dmg_roll[pnum] = count*side*v_kickroll.value;
@ -588,7 +588,7 @@ void V_CalcPowerupCshift (void)
//we only have one palette, so combine the mask
for (s = 0; s < cl.splitclients; s++)
im |= cl.stats[s][STAT_ITEMS];
im |= cl.playerview[s].stats[STAT_ITEMS];
if (im & IT_QUAD)
{
@ -879,18 +879,18 @@ void V_BoundOffsets (int pnum)
// absolutely bound refresh reletive to entity clipping hull
// so the view can never be inside a solid wall
if (r_refdef.vieworg[0] < cl.simorg[pnum][0] - 14)
r_refdef.vieworg[0] = cl.simorg[pnum][0] - 14;
else if (r_refdef.vieworg[0] > cl.simorg[pnum][0] + 14)
r_refdef.vieworg[0] = cl.simorg[pnum][0] + 14;
if (r_refdef.vieworg[1] < cl.simorg[pnum][1] - 14)
r_refdef.vieworg[1] = cl.simorg[pnum][1] - 14;
else if (r_refdef.vieworg[1] > cl.simorg[pnum][1] + 14)
r_refdef.vieworg[1] = cl.simorg[pnum][1] + 14;
if (r_refdef.vieworg[2] < cl.simorg[pnum][2] - 22)
r_refdef.vieworg[2] = cl.simorg[pnum][2] - 22;
else if (r_refdef.vieworg[2] > cl.simorg[pnum][2] + 30)
r_refdef.vieworg[2] = cl.simorg[pnum][2] + 30;
if (r_refdef.vieworg[0] < cl.playerview[pnum].simorg[0] - 14)
r_refdef.vieworg[0] = cl.playerview[pnum].simorg[0] - 14;
else if (r_refdef.vieworg[0] > cl.playerview[pnum].simorg[0] + 14)
r_refdef.vieworg[0] = cl.playerview[pnum].simorg[0] + 14;
if (r_refdef.vieworg[1] < cl.playerview[pnum].simorg[1] - 14)
r_refdef.vieworg[1] = cl.playerview[pnum].simorg[1] - 14;
else if (r_refdef.vieworg[1] > cl.playerview[pnum].simorg[1] + 14)
r_refdef.vieworg[1] = cl.playerview[pnum].simorg[1] + 14;
if (r_refdef.vieworg[2] < cl.playerview[pnum].simorg[2] - 22)
r_refdef.vieworg[2] = cl.playerview[pnum].simorg[2] - 22;
else if (r_refdef.vieworg[2] > cl.playerview[pnum].simorg[2] + 30)
r_refdef.vieworg[2] = cl.playerview[pnum].simorg[2] + 30;
}
/*
@ -946,7 +946,7 @@ void V_CalcViewRoll (int pnum)
float side;
float adjspeed;
side = V_CalcRoll (cl.simangles[pnum], cl.simvel[pnum]);
side = V_CalcRoll (cl.playerview[pnum].simangles, cl.playerview[pnum].simvel);
adjspeed = fabs(cl_rollangle.value);
if (adjspeed<1)
@ -954,19 +954,19 @@ void V_CalcViewRoll (int pnum)
if (adjspeed>45)
adjspeed = 45;
adjspeed*=20;
if (side > cl.rollangle[pnum])
if (side > cl.playerview[pnum].rollangle)
{
cl.rollangle[pnum] += host_frametime * adjspeed;
if (cl.rollangle[pnum] > side)
cl.rollangle[pnum] = side;
cl.playerview[pnum].rollangle += host_frametime * adjspeed;
if (cl.playerview[pnum].rollangle > side)
cl.playerview[pnum].rollangle = side;
}
else if (side < cl.rollangle[pnum])
else if (side < cl.playerview[pnum].rollangle)
{
cl.rollangle[pnum] -= host_frametime * adjspeed;
if (cl.rollangle[pnum] < side)
cl.rollangle[pnum] = side;
cl.playerview[pnum].rollangle -= host_frametime * adjspeed;
if (cl.playerview[pnum].rollangle < side)
cl.playerview[pnum].rollangle = side;
}
r_refdef.viewangles[ROLL] += cl.rollangle[pnum];
r_refdef.viewangles[ROLL] += cl.playerview[pnum].rollangle;
if (v_dmg_time[pnum] > 0)
{
@ -992,8 +992,8 @@ void V_CalcIntermissionRefdef (int pnum)
// view is the weapon model
view = &cl.viewent[pnum];
VectorCopy (cl.simorg[pnum], r_refdef.vieworg);
VectorCopy (cl.simangles[pnum], r_refdef.viewangles);
VectorCopy (cl.playerview[pnum].simorg, r_refdef.vieworg);
VectorCopy (cl.playerview[pnum].simangles, r_refdef.viewangles);
view->model = NULL;
// always idle in intermission
@ -1039,7 +1039,7 @@ void V_CalcRefdef (int pnum)
bob = V_CalcBob (pnum, false);
// refresh position from simulated origin
VectorCopy (cl.simorg[pnum], r_refdef.vieworg);
VectorCopy (cl.playerview[pnum].simorg, r_refdef.vieworg);
r_refdef.useperspective = true;
@ -1050,9 +1050,9 @@ void V_CalcRefdef (int pnum)
r_refdef.vieworg[1] += 1.0/16;
r_refdef.vieworg[2] += 1.0/16;
if (cl.fixangle[pnum])
if (cl.playerview[pnum].fixangle)
{
if (cl.oldfixangle[pnum])
if (cl.playerview[pnum].oldfixangle)
{
float frac, move;
if (cl.gametime <= cl.oldgametime)
@ -1064,22 +1064,22 @@ void V_CalcRefdef (int pnum)
}
for (i = 0; i < 3; i++)
{
move = cl.fixangles[pnum][i] - cl.oldfixangles[pnum][i];
move = cl.playerview[pnum].fixangles[i] - cl.playerview[pnum].oldfixangles[i];
if (move >= 180)
move -= 360;
if (move <= -180)
move += 360;
r_refdef.viewangles[i] = cl.oldfixangles[pnum][i] + frac * move;
r_refdef.viewangles[i] = cl.playerview[pnum].oldfixangles[i] + frac * move;
}
}
else
{
VectorCopy (cl.fixangles[pnum], r_refdef.viewangles);
VectorCopy (cl.playerview[pnum].fixangles, r_refdef.viewangles);
}
}
else
{
VectorCopy (cl.simangles[pnum], r_refdef.viewangles);
VectorCopy (cl.playerview[pnum].simangles, r_refdef.viewangles);
}
V_CalcViewRoll (pnum);
V_AddIdle (pnum);
@ -1112,14 +1112,14 @@ void V_CalcRefdef (int pnum)
// set up gun position
V_CalcGunPositionAngle (pnum, bob);
if (cl.stats[pnum][STAT_HEALTH] > 0 && (unsigned int)cl.stats[pnum][STAT_WEAPON] >= MAX_MODELS)
if (cl.playerview[pnum].stats[STAT_HEALTH] > 0 && (unsigned int)cl.playerview[pnum].stats[STAT_WEAPON] >= MAX_MODELS)
view->model = NULL;
else
view->model = cl.model_precache[cl.stats[pnum][STAT_WEAPON]];
view->model = cl.model_precache[cl.playerview[pnum].stats[STAT_WEAPON]];
#ifdef HLCLIENT
if (!CLHL_AnimateViewEntity(view))
#endif
view->framestate.g[FS_REG].frame[0] = cl.stats[pnum][STAT_WEAPONFRAME];
view->framestate.g[FS_REG].frame[0] = cl.playerview[pnum].stats[STAT_WEAPONFRAME];
// set up the refresh position
if (v_gunkick.value)
@ -1241,8 +1241,8 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
}
r_refdef.fov_x = scr_fov.value;
if (cl.stats[pnum][STAT_VIEWZOOM])
r_refdef.fov_x *= cl.stats[pnum][STAT_VIEWZOOM]/255.0f;
if (cl.playerview[pnum].stats[STAT_VIEWZOOM])
r_refdef.fov_x *= cl.playerview[pnum].stats[STAT_VIEWZOOM]/255.0f;
if (vrect->width < (vrect->height*640)/432)
{
@ -1364,7 +1364,7 @@ void V_RenderPlayerViews(int plnum)
for (viewnum = 0; viewnum < SIDEVIEWS; viewnum++)
if (vsec_scalex[viewnum].value>0&&vsec_scaley[viewnum].value>0
&& ((vsec_enabled[viewnum].value && vsec_enabled[viewnum].value != 2 && cls.allow_rearview) //rearview if v2_enabled = 1 and not 2
|| (vsec_enabled[viewnum].value && cl.stats[plnum][STAT_VIEW2]&&viewnum==0))) //v2 enabled if v2_enabled is non-zero
|| (vsec_enabled[viewnum].value && cl.playerview[plnum].stats[STAT_VIEW2]&&viewnum==0))) //v2 enabled if v2_enabled is non-zero
{
vrect_t oldrect;
vec3_t oldangles;
@ -1401,9 +1401,9 @@ void V_RenderPlayerViews(int plnum)
#ifdef PEXT_VIEW2
//secondary view entity.
e=NULL;
if (viewnum==0&&cl.stats[plnum][STAT_VIEW2])
if (viewnum==0&&cl.playerview[plnum].stats[STAT_VIEW2])
{
e = CL_EntityNum (cl.stats[plnum][STAT_VIEW2]);
e = CL_EntityNum (cl.playerview[plnum].stats[STAT_VIEW2]);
}
if (e)
{

View File

@ -59,6 +59,12 @@ void W_CleanupName (const char *in, char *out)
}
void W_Shutdown (void)
{
if (wad_base)
Z_Free(wad_base);
wad_base = NULL;
}
/*
====================
@ -111,7 +117,6 @@ void W_LoadWadFile (char *filename)
}
}
/*
=============
W_GetLumpinfo
@ -380,7 +385,7 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, int *width, int *height, qboolean *us
alpha = 2;
//use malloc here if you want, but you'll have to free it again... NUR!
data = out = Hunk_TempAllocMore(tex->width * tex->height * 4);
data = out = BZ_Malloc(tex->width * tex->height * 4);
if (!data)
return NULL;
@ -467,7 +472,7 @@ qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha)//r
for (j = 0;j < MIPLEVELS;j++)
tex->offsets[j] = LittleLong(tex->offsets[j]);
data = W_ConvertWAD3Texture(tex, width, height, usesalpha); //this will add to the temp
data = W_ConvertWAD3Texture(tex, width, height, usesalpha);
BZ_Free(tex);
return data;
}

View File

@ -98,6 +98,7 @@ extern int wad_numlumps;
extern lumpinfo_t *wad_lumps;
extern qbyte *wad_base;
void W_Shutdown (void);
void W_LoadWadFile (char *filename);
void W_CleanupName (const char *in, char *out);
lumpinfo_t *W_GetLumpinfo (char *name);

View File

@ -317,43 +317,43 @@ static char *Macro_Gamedir (void)
static char *Macro_Health (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_HEALTH]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_HEALTH]);
return macro_buf;
}
static char *Macro_Armor (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_ARMOR]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_ARMOR]);
return macro_buf;
}
static char *Macro_Shells (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_SHELLS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_SHELLS]);
return macro_buf;
}
static char *Macro_Nails (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_NAILS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_NAILS]);
return macro_buf;
}
static char *Macro_Rockets (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_ROCKETS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_ROCKETS]);
return macro_buf;
}
static char *Macro_Cells (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_CELLS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_CELLS]);
return macro_buf;
}
static char *Macro_Ammo (void)
{
sprintf(macro_buf, "%i", cl.stats[SP][STAT_AMMO]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_AMMO]);
return macro_buf;
}
@ -375,7 +375,7 @@ static char *Weapon_NumToString (int wnum)
static char *Macro_Weapon (void)
{
return Weapon_NumToString(cl.stats[SP][STAT_ACTIVEWEAPON]);
return Weapon_NumToString(cl.playerview[SP].stats[STAT_ACTIVEWEAPON]);
}
static char *Macro_DroppedWeapon (void)
@ -386,21 +386,21 @@ static char *Macro_DroppedWeapon (void)
static char *Macro_Weapons (void) {
macro_buf[0] = 0;
if (cl.stats[SP][STAT_ITEMS] & IT_LIGHTNING)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_LIGHTNING)
strcpy(macro_buf, tp_name_lg.string);
if (cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ROCKET_LAUNCHER)
MacroBuf_strcat_with_separator (tp_name_rl.string);
if (cl.stats[SP][STAT_ITEMS] & IT_GRENADE_LAUNCHER)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_GRENADE_LAUNCHER)
MacroBuf_strcat_with_separator (tp_name_gl.string);
if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_NAILGUN)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SUPER_NAILGUN)
MacroBuf_strcat_with_separator (tp_name_sng.string);
if (cl.stats[SP][STAT_ITEMS] & IT_NAILGUN)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_NAILGUN)
MacroBuf_strcat_with_separator (tp_name_ng.string);
if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_SHOTGUN)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SUPER_SHOTGUN)
MacroBuf_strcat_with_separator (tp_name_ssg.string);
if (cl.stats[SP][STAT_ITEMS] & IT_SHOTGUN)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SHOTGUN)
MacroBuf_strcat_with_separator (tp_name_sg.string);
if (cl.stats[SP][STAT_ITEMS] & IT_AXE)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_AXE)
MacroBuf_strcat_with_separator (tp_name_axe.string);
// if (!macro_buf[0])
// strlcpy(macro_buf, tp_name_none.string, sizeof(macro_buf));
@ -418,7 +418,7 @@ static char *Macro_WeaponAndAmmo (void)
static char *Macro_WeaponNum (void)
{
switch (cl.stats[SP][STAT_ACTIVEWEAPON])
switch (cl.playerview[SP].stats[STAT_ACTIVEWEAPON])
{
case IT_AXE: return "1";
case IT_SHOTGUN: return "2";
@ -443,14 +443,14 @@ static int _Macro_BestWeapon (void)
for (i = 0 ; i < strlen(*s) ; i++)
{
switch ((*s)[i]) {
case '1': if (cl.stats[SP][STAT_ITEMS] & IT_AXE) return IT_AXE; break;
case '2': if (cl.stats[SP][STAT_ITEMS] & IT_SHOTGUN) return IT_SHOTGUN; break;
case '3': if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_SHOTGUN) return IT_SUPER_SHOTGUN; break;
case '4': if (cl.stats[SP][STAT_ITEMS] & IT_NAILGUN) return IT_NAILGUN; break;
case '5': if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_NAILGUN) return IT_SUPER_NAILGUN; break;
case '6': if (cl.stats[SP][STAT_ITEMS] & IT_GRENADE_LAUNCHER) return IT_GRENADE_LAUNCHER; break;
case '7': if (cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER) return IT_ROCKET_LAUNCHER; break;
case '8': if (cl.stats[SP][STAT_ITEMS] & IT_LIGHTNING) return IT_LIGHTNING; break;
case '1': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_AXE) return IT_AXE; break;
case '2': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SHOTGUN) return IT_SHOTGUN; break;
case '3': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SUPER_SHOTGUN) return IT_SUPER_SHOTGUN; break;
case '4': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_NAILGUN) return IT_NAILGUN; break;
case '5': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SUPER_NAILGUN) return IT_SUPER_NAILGUN; break;
case '6': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_GRENADE_LAUNCHER) return IT_GRENADE_LAUNCHER; break;
case '7': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ROCKET_LAUNCHER) return IT_ROCKET_LAUNCHER; break;
case '8': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_LIGHTNING) return IT_LIGHTNING; break;
}
}
}
@ -467,19 +467,19 @@ static char *Macro_BestAmmo (void)
switch (_Macro_BestWeapon())
{
case IT_SHOTGUN: case IT_SUPER_SHOTGUN:
sprintf(macro_buf, "%i", cl.stats[0][STAT_SHELLS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_SHELLS]);
return macro_buf;
case IT_NAILGUN: case IT_SUPER_NAILGUN:
sprintf(macro_buf, "%i", cl.stats[0][STAT_NAILS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_NAILS]);
return macro_buf;
case IT_GRENADE_LAUNCHER: case IT_ROCKET_LAUNCHER:
sprintf(macro_buf, "%i", cl.stats[0][STAT_ROCKETS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_ROCKETS]);
return macro_buf;
case IT_LIGHTNING:
sprintf(macro_buf, "%i", cl.stats[0][STAT_CELLS]);
sprintf(macro_buf, "%i", cl.playerview[SP].stats[STAT_CELLS]);
return macro_buf;
default:
@ -498,11 +498,11 @@ static char *Macro_BestWeaponAndAmmo (void)
static char *Macro_ArmorType (void)
{
if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR1)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR1)
return tp_name_armortype_ga.string;
else if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR2)
else if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR2)
return tp_name_armortype_ya.string;
else if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR3)
else if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR3)
return tp_name_armortype_ra.string;
else
return tp_name_none.string; // no armor at all
@ -514,18 +514,18 @@ static char *Macro_Powerups (void)
macro_buf[0] = 0;
if (cl.stats[SP][STAT_ITEMS] & IT_QUAD)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_QUAD)
MacroBuf_strcat_with_separator (tp_name_quad.string);
if (cl.stats[SP][STAT_ITEMS] & IT_INVULNERABILITY)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVULNERABILITY)
MacroBuf_strcat_with_separator (tp_name_pent.string);
if (cl.stats[SP][STAT_ITEMS] & IT_INVISIBILITY)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVISIBILITY)
MacroBuf_strcat_with_separator (tp_name_ring.string);
effects = cl.frames[cl.parsecount&UPDATE_MASK].playerstate[cl.playernum[SP]].effects;
if ( (effects & (QWEF_FLAG1|QWEF_FLAG2)) || // CTF
(cl.teamfortress && cl.stats[SP][STAT_ITEMS] & (IT_KEY1|IT_KEY2)) ) // TF
(cl.teamfortress && cl.playerview[SP].stats[STAT_ITEMS] & (IT_KEY1|IT_KEY2)) ) // TF
MacroBuf_strcat_with_separator (tp_name_flag.string);
return macro_buf;
@ -533,7 +533,7 @@ static char *Macro_Powerups (void)
static char *Macro_Location (void)
{
return TP_LocationName (cl.simorg[SP]);
return TP_LocationName (cl.playerview[SP].simorg);
}
static char *Macro_LastDeath (void)
@ -624,15 +624,15 @@ static char *Macro_Need (void)
macro_buf[0] = 0;
// check armor
if ( ((cl.stats[SP][STAT_ITEMS] & IT_ARMOR1) && cl.stats[SP][STAT_ARMOR] < tp_need_ga.value)
|| ((cl.stats[SP][STAT_ITEMS] & IT_ARMOR2) && cl.stats[SP][STAT_ARMOR] < tp_need_ya.value)
|| ((cl.stats[SP][STAT_ITEMS] & IT_ARMOR3) && cl.stats[SP][STAT_ARMOR] < tp_need_ra.value)
|| (!(cl.stats[SP][STAT_ITEMS] & (IT_ARMOR1|IT_ARMOR2|IT_ARMOR3))
if ( ((cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR1) && cl.playerview[SP].stats[STAT_ARMOR] < tp_need_ga.value)
|| ((cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR2) && cl.playerview[SP].stats[STAT_ARMOR] < tp_need_ya.value)
|| ((cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR3) && cl.playerview[SP].stats[STAT_ARMOR] < tp_need_ra.value)
|| (!(cl.playerview[SP].stats[STAT_ITEMS] & (IT_ARMOR1|IT_ARMOR2|IT_ARMOR3))
&& (tp_need_ga.value || tp_need_ya.value || tp_need_ra.value)))
strcpy (macro_buf, tp_name_armor.string);
// check health
if (tp_need_health.value && cl.stats[SP][STAT_HEALTH] < tp_need_health.value) {
if (tp_need_health.value && cl.playerview[SP].stats[STAT_HEALTH] < tp_need_health.value) {
MacroBuf_strcat_with_separator (tp_name_health.string);
}
@ -640,13 +640,13 @@ static char *Macro_Need (void)
{
// in TF, we have all weapons from the start,
// and ammo is checked differently
if (cl.stats[SP][STAT_ROCKETS] < tp_need_rockets.value)
if (cl.playerview[SP].stats[STAT_ROCKETS] < tp_need_rockets.value)
MacroBuf_strcat_with_separator (tp_name_rockets.string);
if (cl.stats[SP][STAT_SHELLS] < tp_need_shells.value)
if (cl.playerview[SP].stats[STAT_SHELLS] < tp_need_shells.value)
MacroBuf_strcat_with_separator (tp_name_shells.string);
if (cl.stats[SP][STAT_NAILS] < tp_need_nails.value)
if (cl.playerview[SP].stats[STAT_NAILS] < tp_need_nails.value)
MacroBuf_strcat_with_separator (tp_name_nails.string);
if (cl.stats[SP][STAT_CELLS] < tp_need_cells.value)
if (cl.playerview[SP].stats[STAT_CELLS] < tp_need_cells.value)
MacroBuf_strcat_with_separator (tp_name_cells.string);
goto done;
}
@ -655,13 +655,13 @@ static char *Macro_Need (void)
weapon = 0;
for (i=strlen(tp_need_weapon.string)-1 ; i>=0 ; i--) {
switch (tp_need_weapon.string[i]) {
case '2': if (cl.stats[SP][STAT_ITEMS] & IT_SHOTGUN) weapon = 2; break;
case '3': if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_SHOTGUN) weapon = 3; break;
case '4': if (cl.stats[SP][STAT_ITEMS] & IT_NAILGUN) weapon = 4; break;
case '5': if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_NAILGUN) weapon = 5; break;
case '6': if (cl.stats[SP][STAT_ITEMS] & IT_GRENADE_LAUNCHER) weapon = 6; break;
case '7': if (cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER) weapon = 7; break;
case '8': if (cl.stats[SP][STAT_ITEMS] & IT_LIGHTNING) weapon = 8; break;
case '2': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SHOTGUN) weapon = 2; break;
case '3': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SUPER_SHOTGUN) weapon = 3; break;
case '4': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_NAILGUN) weapon = 4; break;
case '5': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_SUPER_NAILGUN) weapon = 5; break;
case '6': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_GRENADE_LAUNCHER) weapon = 6; break;
case '7': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ROCKET_LAUNCHER) weapon = 7; break;
case '8': if (cl.playerview[SP].stats[STAT_ITEMS] & IT_LIGHTNING) weapon = 8; break;
}
if (weapon)
break;
@ -670,15 +670,15 @@ static char *Macro_Need (void)
if (!weapon) {
MacroBuf_strcat_with_separator (tp_name_weapon.string);
} else {
if (tp_need_rl.value && !(cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER)) {
if (tp_need_rl.value && !(cl.playerview[SP].stats[STAT_ITEMS] & IT_ROCKET_LAUNCHER)) {
MacroBuf_strcat_with_separator (tp_name_rl.string);
}
switch (weapon) {
case 2: case 3: if (cl.stats[SP][STAT_SHELLS] < tp_need_shells.value) needammo = tp_name_shells.string; break;
case 4: case 5: if (cl.stats[SP][STAT_NAILS] < tp_need_nails.value) needammo = tp_name_nails.string; break;
case 6: case 7: if (cl.stats[SP][STAT_ROCKETS] < tp_need_rockets.value) needammo = tp_name_rockets.string; break;
case 8: if (cl.stats[SP][STAT_CELLS] < tp_need_cells.value) needammo = tp_name_cells.string; break;
case 2: case 3: if (cl.playerview[SP].stats[STAT_SHELLS] < tp_need_shells.value) needammo = tp_name_shells.string; break;
case 4: case 5: if (cl.playerview[SP].stats[STAT_NAILS] < tp_need_nails.value) needammo = tp_name_nails.string; break;
case 6: case 7: if (cl.playerview[SP].stats[STAT_ROCKETS] < tp_need_rockets.value) needammo = tp_name_rockets.string; break;
case 8: if (cl.playerview[SP].stats[STAT_CELLS] < tp_need_cells.value) needammo = tp_name_cells.string; break;
}
if (needammo) {
MacroBuf_strcat_with_separator (needammo);
@ -1037,16 +1037,16 @@ char *Macro_CombinedHealth(void)
//total health = health+armour*armourfrac
//however,you're dead if health drops below 0 rather than the entire equation.
if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR1)
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR1)
t = 0.3;
else if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR2)
else if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR2)
t = 0.6;
else if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR3)
else if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR3)
t = 0.8;
else
t = 0;
a = cl.stats[SP][STAT_ARMOR];
h = cl.stats[SP][STAT_HEALTH];
a = cl.playerview[SP].stats[STAT_ARMOR];
h = cl.playerview[SP].stats[STAT_HEALTH];
//work out the max useful armour
//this will under-exagurate, due to usage of ceil based on damage
@ -1172,18 +1172,18 @@ static char *TP_ParseMacroString (char *s)
macro_string = Macro_ArmorType();
if (!macro_string[0])
macro_string = "a";
if (cl.stats[SP][STAT_ARMOR] < 30)
Q_snprintfz (mbuf, sizeof(mbuf), "\x10%s:%i\x11", macro_string, cl.stats[SP][STAT_ARMOR]);
if (cl.playerview[SP].stats[STAT_ARMOR] < 30)
Q_snprintfz (mbuf, sizeof(mbuf), "\x10%s:%i\x11", macro_string, cl.playerview[SP].stats[STAT_ARMOR]);
else
Q_snprintfz (mbuf, sizeof(mbuf), "%s:%i", macro_string, cl.stats[SP][STAT_ARMOR]);
Q_snprintfz (mbuf, sizeof(mbuf), "%s:%i", macro_string, cl.playerview[SP].stats[STAT_ARMOR]);
macro_string = mbuf;
break;
case 'h':
if (cl.stats[SP][STAT_HEALTH] >= 50)
Q_snprintfz (macro_buf, sizeof(macro_buf), "%i", cl.stats[SP][STAT_HEALTH]);
if (cl.playerview[SP].stats[STAT_HEALTH] >= 50)
Q_snprintfz (macro_buf, sizeof(macro_buf), "%i", cl.playerview[SP].stats[STAT_HEALTH]);
else
Q_snprintfz (macro_buf, sizeof(macro_buf), "\x10%i\x11", cl.stats[SP][STAT_HEALTH]);
Q_snprintfz (macro_buf, sizeof(macro_buf), "\x10%i\x11", cl.playerview[SP].stats[STAT_HEALTH]);
macro_string = macro_buf;
break;
@ -2609,17 +2609,17 @@ more:
if (vars.stat_framecounts[STAT_ITEMS] == cls.framecount)
{
if (vars.items & ~vars.olditems & IT_LIGHTNING)
ExecTookTrigger (tp_name_lg.string, it_lg, cl.simorg[SP]);
ExecTookTrigger (tp_name_lg.string, it_lg, cl.playerview[SP].simorg);
else if (vars.items & ~vars.olditems & IT_ROCKET_LAUNCHER)
ExecTookTrigger (tp_name_rl.string, it_rl, cl.simorg[SP]);
ExecTookTrigger (tp_name_rl.string, it_rl, cl.playerview[SP].simorg);
else if (vars.items & ~vars.olditems & IT_GRENADE_LAUNCHER)
ExecTookTrigger (tp_name_gl.string, it_gl, cl.simorg[SP]);
ExecTookTrigger (tp_name_gl.string, it_gl, cl.playerview[SP].simorg);
else if (vars.items & ~vars.olditems & IT_SUPER_NAILGUN)
ExecTookTrigger (tp_name_sng.string, it_sng, cl.simorg[SP]);
ExecTookTrigger (tp_name_sng.string, it_sng, cl.playerview[SP].simorg);
else if (vars.items & ~vars.olditems & IT_NAILGUN)
ExecTookTrigger (tp_name_ng.string, it_ng, cl.simorg[SP]);
ExecTookTrigger (tp_name_ng.string, it_ng, cl.playerview[SP].simorg);
else if (vars.items & ~vars.olditems & IT_SUPER_SHOTGUN)
ExecTookTrigger (tp_name_ssg.string, it_ssg, cl.simorg[SP]);
ExecTookTrigger (tp_name_ssg.string, it_ssg, cl.playerview[SP].simorg);
}
}
return;
@ -2634,11 +2634,11 @@ more:
armor_updated = (vars.stat_framecounts[STAT_ARMOR] == cls.framecount);
armortype = FindNearestItem (it_armor, &item);
if (armortype == 1 || (!armortype && armor_updated && cl.stats[SP][STAT_ARMOR] == 100))
if (armortype == 1 || (!armortype && armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 100))
ExecTookTrigger (tp_name_ga.string, it_ga, org);
else if (armortype == 2 || (!armortype && armor_updated && cl.stats[SP][STAT_ARMOR] == 150))
else if (armortype == 2 || (!armortype && armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 150))
ExecTookTrigger (tp_name_ya.string, it_ya, org);
else if (armortype == 3 || (!armortype && armor_updated && cl.stats[SP][STAT_ARMOR] == 200))
else if (armortype == 3 || (!armortype && armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 200))
ExecTookTrigger (tp_name_ra.string, it_ra, org);
return;
}
@ -2833,9 +2833,9 @@ static void TP_FindPoint (void)
if (!cl.validsequence)
goto nothing;
ang[0] = cl.viewangles[0][0]; ang[1] = cl.viewangles[0][1]; ang[2] = 0;
ang[0] = cl.playerview[SP].viewangles[0]; ang[1] = cl.playerview[SP].viewangles[1]; ang[2] = 0;
AngleVectors (ang, visitem.forward, visitem.right, visitem.up);
VectorCopy (cl.simorg[0], visitem.vieworg);
VectorCopy (cl.playerview[SP].simorg, visitem.vieworg);
visitem.vieworg[2] += 22 + (v_viewheight.value ? bound (-7, v_viewheight.value, 4) : 0);
pointflags_dmm = pointflags;
@ -3058,7 +3058,7 @@ void TP_StatChanged (int stat, int value)
else if (vars.health > 0)
{ // We have just died
vars.droppedweapon = cl.stats[SP][STAT_ACTIVEWEAPON];
vars.droppedweapon = cl.playerview[SP].stats[STAT_ACTIVEWEAPON];
vars.deathtrigger_time = realtime;
strcpy (vars.lastdeathloc, Macro_Location());
@ -3069,7 +3069,7 @@ void TP_StatChanged (int stat, int value)
if (!cl.spectator && CountTeammates())
{
if (cl.teamfortress && (cl.stats[SP][STAT_ITEMS] & (IT_KEY1|IT_KEY2))
if (cl.teamfortress && (cl.playerview[SP].stats[STAT_ITEMS] & (IT_KEY1|IT_KEY2))
&& Cmd_AliasExist("f_flagdeath", RESTRICT_LOCAL))
TP_ExecTrigger ("f_flagdeath");
else
@ -3101,9 +3101,9 @@ void TP_StatChanged (int stat, int value)
}
else if (stat == STAT_ACTIVEWEAPON)
{
if (cl.stats[SP][STAT_ACTIVEWEAPON] != vars.activeweapon)
if (cl.playerview[SP].stats[STAT_ACTIVEWEAPON] != vars.activeweapon)
TP_ExecTrigger ("f_weaponchange");
vars.activeweapon = cl.stats[SP][STAT_ACTIVEWEAPON];
vars.activeweapon = cl.playerview[SP].stats[STAT_ACTIVEWEAPON];
}
vars.stat_framecounts[stat] = cls.framecount;

View File

@ -176,8 +176,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define INTERQUAKEMODELS
#define HUFFNETWORK //huffman network compression
// #define DOOMWADS //doom wad/sprite support
// #define MAP_DOOM //doom map support
#define DOOMWADS //doom wad/sprite support
#define MAP_DOOM //doom map support
#define MAP_PROC //doom3/quake4 map support
//#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet)
#define Q2BSPS //quake 2 bsp support
@ -474,7 +474,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// per-level limits
//
#define MAX_EDICTS 32767 // FIXME: ouch! ouch! ouch!
#define MAX_LIGHTSTYLES 255
#define MAX_LIGHTSTYLES 256
#define MAX_STANDARDLIGHTSTYLES 64
#define MAX_MODELS 1024 // these are sent over the net as bytes
#define MAX_SOUNDS 1024 // so they cannot be blindly increased

View File

@ -497,52 +497,56 @@ typedef struct
// a given brush can contribute multiple content bits
// multiple brushes can be in a single leaf
// these definitions also need to be in q_shared.h!
#define FTECONTENTS_EMPTY 0
#define FTECONTENTS_SOLID 1
//2
//4
#define FTECONTENTS_LAVA 8
#define FTECONTENTS_SLIME 16
#define FTECONTENTS_WATER 32
#define FTECONTENTS_EMPTY 0x00000000
#define FTECONTENTS_SOLID 0x00000001
//0x00000002
//0x00000004
#define FTECONTENTS_LAVA 0x00000008
#define FTECONTENTS_SLIME 0x00000010
#define FTECONTENTS_WATER 0x00000020
#define FTECONTENTS_LADDER 0x00004000
#define FTECONTENTS_FLUID (FTECONTENTS_WATER|FTECONTENTS_SLIME|FTECONTENTS_LAVA|FTECONTENTS_SKY) //sky is a fluid for q1 code.
#define FTECONTENTS_PLAYERCLIP 0x00010000
#define FTECONTENTS_MONSTERCLIP 0x00020000
#define FTECONTENTS_BODY 0x02000000
#define FTECONTENTS_CORPSE 0x04000000
#define FTECONTENTS_SKY 0x80000000
// lower bits are stronger, and will eat weaker brushes completely
#define Q2CONTENTS_SOLID FTECONTENTS_SOLID //1
#define Q2CONTENTS_WINDOW 2 // translucent, but not watery
#define Q2CONTENTS_AUX 4
#define Q2CONTENTS_LAVA FTECONTENTS_LAVA //8
#define Q2CONTENTS_SLIME FTECONTENTS_SLIME //16
#define Q2CONTENTS_WATER FTECONTENTS_WATER //32
#define Q2CONTENTS_MIST 64
#define Q2CONTENTS_SOLID FTECONTENTS_SOLID //0x00000001
#define Q2CONTENTS_WINDOW 0x00000002 // translucent, but not watery
#define Q2CONTENTS_AUX 0x00000004
#define Q2CONTENTS_LAVA FTECONTENTS_LAVA //0x00000008
#define Q2CONTENTS_SLIME FTECONTENTS_SLIME //0x00000010
#define Q2CONTENTS_WATER FTECONTENTS_WATER //0x00000020
#define Q2CONTENTS_MIST 0x00000040
//0x00000080
//0x00000100
//0x00000200
//0x00000400
//0x00000800
//0x00001000
//0x00002000
//FTECONTENTS_LADDER //0x00004000
// remaining contents are non-visible, and don't eat brushes
#define Q2CONTENTS_AREAPORTAL 0x8000
#define Q2CONTENTS_PLAYERCLIP 0x10000
#define Q2CONTENTS_MONSTERCLIP 0x20000
#define Q2CONTENTS_AREAPORTAL 0x00008000
#define Q2CONTENTS_PLAYERCLIP FTECONTENTS_PLAYERCLIP //0x00010000
#define Q2CONTENTS_MONSTERCLIP FTECONTENTS_MONSTERCLIP //0x00020000
// currents can be added to any other contents, and may be mixed
#define Q2CONTENTS_CURRENT_0 0x40000
#define Q2CONTENTS_CURRENT_90 0x80000
#define Q2CONTENTS_CURRENT_180 0x100000
#define Q2CONTENTS_CURRENT_270 0x200000
#define Q2CONTENTS_CURRENT_UP 0x400000
#define Q2CONTENTS_CURRENT_DOWN 0x800000
#define Q2CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
#define Q2CONTENTS_MONSTER FTECONTENTS_BODY //0x2000000 // should never be on a brush, only in game
#define Q2CONTENTS_DEADMONSTER 0x4000000
#define Q2CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
#define Q2CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
#define Q2CONTENTS_LADDER 0x20000000
#define Q2CONTENTS_CURRENT_0 0x00040000
#define Q2CONTENTS_CURRENT_90 0x00080000
#define Q2CONTENTS_CURRENT_180 0x00100000
#define Q2CONTENTS_CURRENT_270 0x00200000
#define Q2CONTENTS_CURRENT_UP 0x00400000
#define Q2CONTENTS_CURRENT_DOWN 0x00800000
#define Q2CONTENTS_ORIGIN 0x01000000 // removed before bsping an entity
#define Q2CONTENTS_MONSTER FTECONTENTS_BODY //0x02000000 // should never be on a brush, only in game
#define Q2CONTENTS_DEADMONSTER FTECONTENTS_CORPSE //0x04000000
#define Q2CONTENTS_DETAIL 0x08000000 // brushes to be added after vis leafs
#define Q2CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
#define Q2CONTENTS_LADDER 0x20000000
//0x40000000
//0x80000000
#define Q3CONTENTS_SOLID FTECONTENTS_SOLID //1 // should never be on a brush, only in game
@ -559,10 +563,10 @@ typedef struct
//0x00000800
//0x00001000
//0x00002000
//0x00004000
//FTECONTENTS_LADDER //0x00004000
#define Q3CONTENTS_AREAPORTAL 0x00008000
#define Q3CONTENTS_PLAYERCLIP Q2CONTENTS_PLAYERCLIP //0x00010000
#define Q3CONTENTS_MONSTERCLIP Q2CONTENTS_MONSTERCLIP //0x00020000
#define Q3CONTENTS_PLAYERCLIP FTECONTENTS_PLAYERCLIP //0x00010000
#define Q3CONTENTS_MONSTERCLIP FTECONTENTS_MONSTERCLIP //0x00020000
#define Q3CONTENTS_TELEPORTER 0x00040000
#define Q3CONTENTS_JUMPPAD 0x00080000
#define Q3CONTENTS_CLUSTERPORTAL 0x00100000
@ -571,7 +575,7 @@ typedef struct
#define Q3CONTENTS_MOVER 0x00800000
#define Q3CONTENTS_ORIGIN Q2CONTENTS_ORIGIN //0x01000000
#define Q3CONTENTS_BODY 0x02000000
#define Q3CONTENTS_CORPSE Q2CONTENTS_DEADMONSTER //0x04000000
#define Q3CONTENTS_CORPSE FTECONTENTS_CORPSE //0x04000000
#define Q3CONTENTS_DETAIL Q2CONTENTS_DETAIL //0x08000000
#define Q3CONTENTS_STRUCTURAL 0x10000000
#define Q3CONTENTS_TRANSLUCENT 0x20000000

View File

@ -2846,11 +2846,22 @@ void Cmd_Shutdown(void)
{
cmd_function_t *c;
cmdalias_t *a;
int i;
//make sure we get no other execution
int level;
for (level = 0; level < sizeof(cmd_text)/sizeof(cmd_text[0]); level++)
{
SZ_Clear (&cmd_text[level].buf);
if (cmd_text[level].buf.data)
{
BZ_Free(cmd_text[level].buf.data);
cmd_text[level].buf.data = NULL;
cmd_text[level].buf.maxsize = 0;
}
}
while(cmd_functions)
{
c = cmd_functions;
@ -2864,6 +2875,12 @@ void Cmd_Shutdown(void)
Z_Free(a->value);
Z_Free(a);
}
for (i=0 ; i<cmd_argc ; i++)
Z_Free (cmd_argv[i]);
Z_Free(cmd_args_buf);
cmd_argc = 0;
cmd_args_buf = NULL;
}

View File

@ -55,6 +55,10 @@ void Cbuf_Execute (void);
// Normally called once per frame, but may be explicitly invoked.
// Do not call inside a command function!
void Cbuf_ExecuteLevel(int level);
//executes only a single cbuf level. can be used to restrict cbuf execution to some 'safe' set of commands, so there are no surprise 'map' commands.
//will not magically make all commands safe to exec, but will prevent user commands slipping in too.
//===========================================================================
/*

View File

@ -1434,6 +1434,24 @@ void Alias_FlushCache(void)
meshcache.ent = NULL;
}
void Alias_Shutdown(void)
{
if (meshcache.colours)
BZ_Free(meshcache.colours);
meshcache.colours = NULL;
meshcache.numcolours = 0;
if (meshcache.norm)
BZ_Free(meshcache.norm);
meshcache.norm = NULL;
meshcache.numnorm = 0;
if (meshcache.coords)
BZ_Free(meshcache.coords);
meshcache.coords = NULL;
meshcache.numcoords = 0;
}
qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, entity_t *e, qboolean usebones)
{
extern cvar_t r_nolerp;
@ -1478,7 +1496,6 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
mesh->numindexes = inf->numindexes;
mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array);
mesh->lmst_array = NULL;
mesh->trneighbors = (int *)((char *)inf + inf->ofs_trineighbours);
mesh->colors4f_array = meshcache.colours;
@ -1507,7 +1524,6 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
#ifndef SERVERONLY
mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array);
mesh->lmst_array = NULL;
mesh->trneighbors = (int *)((char *)inf + inf->ofs_trineighbours);
mesh->normals_array = meshcache.norm;
mesh->snormals_array = meshcache.norm+meshcache.numnorm;
@ -1630,7 +1646,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
}
if (r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival)
if (r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival || qrenderer != QR_OPENGL)
{
mesh->xyz2_array = NULL;
mesh->xyz_blendw[0] = 1;
@ -2230,26 +2246,62 @@ static dmdl_t *pq1inmodel;
#define NUMVERTEXNORMALS 162
extern float r_avertexnormals[NUMVERTEXNORMALS][3];
// mdltype 0 = q1, 1 = qtest, 2 = rapo/h2
static void Alias_LoadPose(vecV_t *verts, vec3_t *normals, vec3_t *svec, vec3_t *tvec, dtrivertx_t *pinframe, int *seamremaps, int mdltype)
{
int j;
if (mdltype == 2)
{
for (j = 0; j < galias->numverts; j++)
{
verts[j][0] = pinframe[seamremaps[j]].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[seamremaps[j]].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[seamremaps[j]].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[seamremaps[j]].lightnormalindex], normals[j]);
#endif
}
}
else
{
for (j = 0; j < pq1inmodel->numverts; j++)
{
verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]);
#endif
if (seamremaps[j] != j)
{
VectorCopy(verts[j], verts[seamremaps[j]]);
#ifndef SERVERONLY
VectorCopy(normals[j], normals[seamremaps[j]]);
#endif
}
}
}
}
static void *Alias_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps, int mdltype)
{
galiaspose_t *pose;
galiasgroup_t *frame;
galiasgroup_t *frame = (galiasgroup_t*)((char *)galias + galias->groupofs);
dtrivertx_t *pinframe;
daliasframe_t *frameinfo;
int i, j, k;
int i, k;
daliasgroup_t *ingroup;
daliasinterval_t *intervals;
float sinter;
#ifndef SERVERONLY
vec3_t *normals, *svec, *tvec;
#endif
vecV_t *verts;
int aliasframesize;
int aliasframesize = (mdltype == 1) ? sizeof(daliasframe_t)-16 : sizeof(daliasframe_t);
aliasframesize = (mdltype == 1) ? sizeof(daliasframe_t)-16 : sizeof(daliasframe_t);
frame = (galiasgroup_t*)((char *)galias + galias->groupofs);
#ifdef SERVERONLY
normals = NULL;
svec = NULL;
tvec = NULL;
#endif
for (i = 0; i < pq1inmodel->numframes; i++)
{
@ -2258,7 +2310,11 @@ static void *Alias_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremap
case ALIAS_SINGLE:
frameinfo = (daliasframe_t*)((char *)(pframetype+1)); // qtest aliasframe is a subset
pinframe = (dtrivertx_t*)((char*)frameinfo+aliasframesize);
#ifndef SERVERONLY
pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + (sizeof(vecV_t)+sizeof(vec3_t)*3)*galias->numverts);
#else
pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + (sizeof(vecV_t))*galias->numverts);
#endif
frame->poseofs = (char *)pose - (char *)frame;
frame->numposes = 1;
galias->groups++;
@ -2277,43 +2333,9 @@ static void *Alias_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremap
pose->ofsnormals = (char *)normals - (char *)pose;
pose->ofssvector = (char *)svec - (char *)pose;
pose->ofstvector = (char *)tvec - (char *)pose;
#else
#ifdef warningmsg
#pragma warningmsg("wasted memory")
#endif
#endif
if (mdltype == 2)
{
for (j = 0; j < galias->numverts; j++)
{
verts[j][0] = pinframe[seamremaps[j]].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[seamremaps[j]].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[seamremaps[j]].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[seamremaps[j]].lightnormalindex], normals[j]);
#endif
}
}
else
{
for (j = 0; j < pq1inmodel->numverts; j++)
{
verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]);
#endif
if (seamremaps[j] != j)
{
VectorCopy(verts[j], verts[seamremaps[j]]);
#ifndef SERVERONLY
VectorCopy(normals[j], normals[seamremaps[j]]);
#endif
}
}
}
Alias_LoadPose(verts, normals, svec, tvec, pinframe, seamremaps, mdltype);
// GL_GenerateNormals((float*)verts, (float*)normals, (int *)((char *)galias + galias->ofs_indexes), galias->numindexes/3, galias->numverts);
@ -2367,37 +2389,7 @@ static void *Alias_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremap
Q_strncpyz(frame->name, frameinfo->name, sizeof(frame->name));
}
if (mdltype == 2)
{
for (j = 0; j < galias->numverts; j++)
{
verts[j][0] = pinframe[seamremaps[j]].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[seamremaps[j]].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[seamremaps[j]].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[seamremaps[j]].lightnormalindex], normals[j]);
#endif
}
}
else
{
for (j = 0; j < pq1inmodel->numverts; j++)
{
verts[j][0] = pinframe[j].v[0]*pq1inmodel->scale[0]+pq1inmodel->scale_origin[0];
verts[j][1] = pinframe[j].v[1]*pq1inmodel->scale[1]+pq1inmodel->scale_origin[1];
verts[j][2] = pinframe[j].v[2]*pq1inmodel->scale[2]+pq1inmodel->scale_origin[2];
#ifndef SERVERONLY
VectorCopy(r_avertexnormals[pinframe[j].lightnormalindex], normals[j]);
#endif
if (seamremaps[j] != j)
{
VectorCopy(verts[j], verts[seamremaps[j]]);
#ifndef SERVERONLY
VectorCopy(normals[j], normals[seamremaps[j]]);
#endif
}
}
}
Alias_LoadPose(verts, normals, svec, tvec, pinframe, seamremaps, mdltype);
#ifndef SERVERONLY
verts = (vecV_t*)&tvec[galias->numverts];

View File

@ -131,6 +131,7 @@ void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weight
#endif
qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, entity_t *e, qboolean allowskel);
void Alias_FlushCache(void);
void Alias_Shutdown(void);
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize);

View File

@ -185,6 +185,15 @@ void QDECL Q_strncpyz(char *d, const char *s, int n)
*d='\0';
}
//windows/linux have inconsistant snprintf
//this is an attempt to get them consistant and safe
//size is the total size of the buffer
void VARGS Q_vsnprintfz (char *dest, size_t size, char *fmt, va_list argptr)
{
vsnprintf (dest, size, fmt, argptr);
dest[size-1] = 0;
}
//windows/linux have inconsistant snprintf
//this is an attempt to get them consistant and safe
//size is the total size of the buffer
@ -193,10 +202,8 @@ void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...)
va_list argptr;
va_start (argptr, fmt);
vsnprintf (dest, size, fmt, argptr);
Q_vsnprintfz(dest, size, fmt, argptr);
va_end (argptr);
dest[size-1] = 0;
}
@ -3381,7 +3388,6 @@ void COM_Init (void)
nullentitystate.glowmod[2] = 32;
nullentitystate.trans = 255;
nullentitystate.scale = 16;
nullentitystate.abslight = 255;
nullentitystate.solid = 0;//ES_SOLID_BSP;
}

View File

@ -212,6 +212,7 @@ int wildcmp(const char *wild, const char *string); //1 if match
#define Q_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...) LIKEPRINTF(3);
void VARGS Q_vsnprintfz (char *dest, size_t size, char *fmt, va_list args);
int VARGS Com_sprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
#define Q_strncpyS(d, s, n) do{const char *____in=(s);char *____out=(d);int ____i; for (____i=0;*(____in); ____i++){if (____i == (n))break;*____out++ = *____in++;}if (____i < (n))*____out='\0';}while(0) //only use this when it should be used. If undiciided, use N
@ -339,6 +340,9 @@ FTE_DEPRECATED void COM_CloseFile (FILE *h);
typedef struct vfsfile_s {
#ifdef _DEBUG
char dbgname[MAX_QPATH];
#endif
int (*ReadBytes) (struct vfsfile_s *file, void *buffer, int bytestoread);
int (*WriteBytes) (struct vfsfile_s *file, const void *buffer, int bytestoread);
qboolean (*Seek) (struct vfsfile_s *file, unsigned long pos); //returns false for error
@ -451,6 +455,7 @@ char *version_string(void);
void TL_InitLanguages(void);
void TL_Shutdown(void);
void T_FreeStrings(void);
char *T_GetString(int num);
void T_FreeInfoStrings(void);

View File

@ -21,6 +21,8 @@ int active_fs_cachetype;
static int fs_referencetype;
int fs_finds;
int fs_switchgame = -1;
struct
{
const char *extension;
@ -1397,7 +1399,10 @@ static int FS_AddWildDataFiles (const char *descriptor, int size, void *vparam)
return true;
pak = funcs->OpenNew (vfs, pakfile);
if (!pak)
{
VFS_CLOSE(vfs);
return true;
}
Q_snprintfz (pakfile, sizeof(pakfile), "%s%s/", param->parentdesc, descriptor);
if (*param->puredesc)
@ -1804,10 +1809,10 @@ void COM_Gamedir (const char *dir)
#define Q3CFG "gl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\n"
typedef struct {
const char *protocolname; //sent to the master server when this is the current gamemode.
const char *exename; //used if the exe name contains this
const char *argname; //used if this was used as a parameter.
const char *auniquefile[4]; //used if this file is relative from the gamedir
const char *exename; //used if the exe name contains this
const char *protocolname; //sent to the master server when this is the current gamemode (Typically set for DP compat).
const char *auniquefile[4]; //used if this file is relative from the gamedir. needs just one file
const char *customexec;
@ -1819,32 +1824,36 @@ const gamemode_info_t gamemode_info[] = {
//this is to avoid having too many gamemodes anyway.
//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake
//protocol name(dpmaster) exename cmdline switch identifying file exec dir1 dir2 dir3 dir(fte) full name
{"DarkPlaces-Quake", "q1", "-quake", {"id1/pak0.pak"}, NULL, {"id1", "qw", "fte"}, "Quake"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", {NULL}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"},
{"Darkplaces-Rogue", "rogue", "-rogue", {NULL}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"},
{"Nexuiz", "nexuiz", "-nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "ftedata"}, "Nexuiz"},
{"Xonotic", "xonotic", "-xonotic", {"xonotic.exe"}, NEXCFG, {"data", "ftedata"}, "Xonotic"},
{"Spark", "spark", "-spark", {"base/src/progs.src",
"base/qwprogs.dat",
"base/pak0.pak"}, DMFCFG, {"base", }, "Spark"},
//cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name
{"-quake", "q1", "DarkPlaces-Quake", {"id1/pak0.pak"
"id1/quake.rc"}, NULL, {"id1", "qw", "fte"}, "Quake"},
{"-hipnotic", "hipnotic", "Darkplaces-Hipnotic", {NULL}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"},
{"-rogue", "rogue", "Darkplaces-Rogue", {NULL}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"},
{"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "ftedata"}, "Nexuiz"},
{"-xonotic", "xonotic", "Xonotic", {"xonotic.exe"}, NEXCFG, {"data", "ftedata"}, "Xonotic"},
{"-spark", "spark", "Spark", {"base/src/progs.src",
"base/qwprogs.dat",
"base/pak0.pak"}, DMFCFG, {"base", }, "Spark"},
//supported commercial mods (some are currently only partially supported)
{"FTE-H2MP", "h2mp", "-portals", {"portals/hexen.rc",
"portals/pak3.pak"}, HEX2CFG,{"data1", "portals", "fteh2"}, "Hexen II MP"},
{"FTE-Hexen2", "hexen2", "-hexen2", {"data1/pak0.pak"}, HEX2CFG,{"data1", "fteh2"}, "Hexen II"},
{"FTE-Quake2", "q2", "-q2", {"baseq2/pak0.pak"}, NULL, {"baseq2", "fteq2"}, "Quake II"},
{"FTE-Quake3", "q3", "-q3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "fteq3"}, "Quake III Arena"},
{"-portals", "h2mp", "FTE-H2MP", {"portals/hexen.rc",
"portals/pak3.pak"}, HEX2CFG,{"data1", "portals", "fteh2"}, "Hexen II MP"},
{"-hexen2", "hexen2", "FTE-Hexen2", {"data1/pak0.pak"}, HEX2CFG,{"data1", "fteh2"}, "Hexen II"},
{"-q2", "q2", "FTE-Quake2", {"baseq2/pak0.pak"}, NULL, {"baseq2", "fteq2"}, "Quake II"},
{"-q3", "q3", "FTE-Quake3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "fteq3"}, "Quake III Arena"},
//the rest are not officially supported.
{"FTE-Quake4", "q4", "-q4", {"q4base/pak00.pk4"}, NULL, {"q4base", "fteq4"}, "Quake 4"},
{"FTE-EnemyTerritory", "et", "-et", {"etmain/pak0.pk3"}, NULL, {"etmain", "fteet"}, "Wolfenstein - Enemy Territory"},
//can run in windows, needs
{"-halflife", "hl", "FTE-HalfLife", {"valve/liblist.gam"}, NULL, {"valve", "ftehl"}, "Half-Life"},
{"FTE-JK2", "jk2", "-jk2", {"base/assets0.pk3"}, NULL, {"base", "fte"}, "Jedi Knight II: Jedi Outcast"},
//the rest are not supported in any real way. maps-only mostly, if that
{"-q4", "q4", "FTE-Quake4", {"q4base/pak00.pk4"}, NULL, {"q4base", "fteq4"}, "Quake 4"},
{"-et", "et", "FTE-EnemyTerritory", {"etmain/pak0.pk3"}, NULL, {"etmain", "fteet"}, "Wolfenstein - Enemy Territory"},
{"FTE-HalfLife", "hl", "-halflife", {"valve/liblist.gam"}, NULL, {"valve", "ftehl"}, "Half-Life"},
{"FTE-Doom", "doom", "-doom", {"doom.wad"}, NULL, {"*doom.wad", "ftedoom"}, "Doom"},
{"FTE-Doom2", "doom2", "-doom2", {"doom2.wad"}, NULL, {"*doom2.wad", "ftedoom"}, "Doom2"},
{"-jk2", "jk2", "FTE-JK2", {"base/assets0.pk3"}, NULL, {"base", "fte"}, "Jedi Knight II: Jedi Outcast"},
{"-warsow", "warsow", "FTE-Warsow", {"basewsw/pak0.pk3"}, NULL, {"basewsw", "fte"}, "Warsow"},
{"-doom", "doom", "FTE-Doom", {"doom.wad"}, NULL, {"*doom.wad", "ftedoom"}, "Doom"},
{"-doom2", "doom2", "FTE-Doom2", {"doom2.wad"}, NULL, {"*doom2.wad", "ftedoom"}, "Doom2"},
{NULL}
};
@ -2430,6 +2439,13 @@ void FS_Shutdown(void)
com_fschanged = true;
if (filesystemhash.numbuckets)
{
BZ_Free(filesystemhash.bucket);
filesystemhash.bucket = NULL;
filesystemhash.numbuckets = 0;
}
}
void FS_AddGamePack(const char *pakname)
@ -2560,6 +2576,23 @@ void FS_StartupWithGame(int gamenum)
Cbuf_AddText(gamemode_info[gamenum].customexec, RESTRICT_LOCAL);
}
void FS_ChangeGame_f(void)
{
int i;
char *arg = Cmd_Argv(1);
for (i = 0; gamemode_info[i].argname; i++)
{
if (!stricmp(gamemode_info[i].argname+1, arg))
{
Con_Printf("Switching to %s\n", gamemode_info[i].argname+1);
fs_switchgame = i;
return;
}
}
Con_Printf("Game unknown\n");
}
/*
================
COM_InitFilesystem
@ -2579,6 +2612,9 @@ void COM_InitFilesystem (void)
FS_RegisterDefaultFileSystems();
Cmd_AddCommand("fs_restart", FS_ReloadPackFiles_f);
#ifdef _WIN32
Cmd_AddCommand("fs_changegame", FS_ChangeGame_f);
#endif
//
// -basedir <path>
@ -2635,7 +2671,7 @@ void COM_InitFilesystem (void)
//use the game based on an parameter over all else.
for (i = 0; gamemode_info[i].argname; i++)
{
if (COM_CheckParm(gamemode_info[i].argname))
if ((fs_switchgame != -1 && i == fs_switchgame) || (fs_switchgame == -1 && COM_CheckParm(gamemode_info[i].argname)))
{
gamenum = i;
@ -2675,6 +2711,7 @@ void COM_InitFilesystem (void)
break;
}
}
fs_switchgame = -1;
//still failed? find quake and use that one by default
if (gamenum<0)

View File

@ -340,6 +340,9 @@ vfsfile_t *FSPAK_OpenVFS(void *handle, flocation_t *loc, const char *mode)
vfs->length = loc->len;
vfs->currentpos = vfs->startpos;
#ifdef _DEBUG
Q_strncpyz(vfs->funcs.dbgname, pack->files[loc->index].name, sizeof(vfs->funcs.dbgname));
#endif
vfs->funcs.Close = VFSPAK_Close;
vfs->funcs.GetLen = VFSPAK_GetLen;
vfs->funcs.ReadBytes = VFSPAK_ReadBytes;
@ -388,7 +391,7 @@ void *FSPAK_LoadDoomWadFile (vfsfile_t *packhandle, const char *desc)
{
dwadheader_t header;
int i;
packfile_t *newfiles;
mpackfile_t *newfiles;
int numpackfiles;
pack_t *pack;
dwadfile_t info;
@ -423,7 +426,7 @@ void *FSPAK_LoadDoomWadFile (vfsfile_t *packhandle, const char *desc)
header.dirlen = LittleLong (header.dirlen);
numpackfiles = header.dirlen;
newfiles = (packfile_t*)Z_Malloc (numpackfiles * sizeof(packfile_t));
newfiles = (mpackfile_t*)Z_Malloc (numpackfiles * sizeof(mpackfile_t));
VFS_SEEK(packhandle, header.dirofs);
//doom wads are awkward.

View File

@ -102,6 +102,9 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
file = Z_Malloc(sizeof(vfsstdiofile_t));
file->funcs.Close = VFSSTDIO_Close;
#endif
#ifdef _DEBUG
Q_strncpyz(file->funcs.dbgname, "FSSTDIO_OpenTemp", sizeof(file->funcs.dbgname));
#endif
file->funcs.ReadBytes = VFSSTDIO_ReadBytes;
file->funcs.WriteBytes = VFSSTDIO_WriteBytes;
@ -164,6 +167,9 @@ static vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *
}
file = Z_Malloc(sizeof(vfsstdiofile_t));
#ifdef _DEBUG
Q_strncpyz(file->funcs.dbgname, osname, sizeof(file->funcs.dbgname));
#endif
file->funcs.ReadBytes = strchr(mode, 'r')?VFSSTDIO_ReadBytes:NULL;
file->funcs.WriteBytes = (strchr(mode, 'w')||strchr(mode, 'a'))?VFSSTDIO_WriteBytes:NULL;
file->funcs.Seek = VFSSTDIO_Seek;

View File

@ -165,6 +165,9 @@ vfsfile_t *VFSW32_Open(const char *osname, const char *mode)
}
file = Z_Malloc(sizeof(vfsw32file_t));
#ifdef _DEBUG
Q_strncpyz(file->funcs.dbgname, osname, sizeof(file->funcs.dbgname));
#endif
file->funcs.ReadBytes = read?VFSW32_ReadBytes:NULL;
file->funcs.WriteBytes = (write||append)?VFSW32_WriteBytes:NULL;
file->funcs.Seek = VFSW32_Seek;

View File

@ -653,6 +653,9 @@ vfsfile_t *FSZIP_OpenVFS(void *handle, flocation_t *loc, const char *mode)
vfsz->startpos = zip->files[loc->index].filepos;
vfsz->length = loc->len;
#ifdef _DEBUG
Q_strncpyz(vfsz->funcs.dbgname, zip->files[loc->index].name, sizeof(vfsz->funcs.dbgname));
#endif
vfsz->funcs.Close = VFSZIP_Close;
vfsz->funcs.GetLen = VFSZIP_GetLen;
vfsz->funcs.ReadBytes = VFSZIP_ReadBytes;

View File

@ -42,6 +42,7 @@ unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p);
extern char loadname[32];
extern model_t *loadmodel;
void RMod_Batches_Build(mesh_t *meshlist, model_t *mod, void (*build)(model_t *mod, msurface_t *surf, void *cookie), void *buildcookie);
float RadiusFromBounds (vec3_t mins, vec3_t maxs)
{
int i;
@ -351,7 +352,7 @@ static vecV_t *map_verts; //3points
static int numvertexes;
static vec2_t *map_vertstmexcoords;
static vec2_t *map_vertlstmexcoords;
static vec2_t *map_vertlstmexcoords[4];
static vec4_t *map_colors4f_array;
static vec3_t *map_normals_array;
static vec3_t *map_svector_array;
@ -2062,7 +2063,10 @@ qboolean CModQ3_LoadVertexes (lump_t *l)
tout = Hunk_Alloc ( count*sizeof(*nout) );
map_verts = out;
map_vertstmexcoords = stout;
map_vertlstmexcoords = lmout;
map_vertlstmexcoords[0] = lmout;
map_vertlstmexcoords[1] = lmout;
map_vertlstmexcoords[2] = lmout;
map_vertlstmexcoords[3] = lmout;
map_colors4f_array = cout;
map_normals_array = nout;
map_svector_array = sout;
@ -2098,6 +2102,7 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
int i, count, j;
vec2_t *lmout, *stout;
vec4_t *cout;
int sty;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
@ -2115,14 +2120,15 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
out = Hunk_Alloc ( count*sizeof(*out) );
stout = Hunk_Alloc ( count*sizeof(*stout) );
lmout = Hunk_Alloc ( count*sizeof(*lmout) );
lmout = Hunk_Alloc ( MAXLIGHTMAPS*count*sizeof(*lmout) );
cout = Hunk_Alloc ( count*sizeof(*cout) );
nout = Hunk_Alloc ( count*sizeof(*nout) );
sout = Hunk_Alloc ( count*sizeof(*sout) );
tout = Hunk_Alloc ( count*sizeof(*tout) );
map_verts = out;
map_vertstmexcoords = stout;
map_vertlstmexcoords = lmout;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
map_vertlstmexcoords[sty] = lmout + sty*count;
map_colors4f_array = cout;
map_normals_array = nout;
map_svector_array = sout;
@ -2139,7 +2145,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
for ( j=0 ; j < 2 ; j++)
{
stout[i][j] = LittleFloat ( ((float *)in->texcoords)[j] );
lmout[i][j] = LittleFloat ( ((float *)in->texcoords)[j+2] );
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
map_vertlstmexcoords[sty][i][j] = LittleFloat ( ((float *)in->texcoords)[j+2*(sty+1)] );
}
for ( j=0 ; j < 4 ; j++)
{
@ -2354,22 +2361,54 @@ mfog_t *CM_FogForOrigin(vec3_t org)
index_t tempIndexesArray[MAX_ARRAY_VERTS*6];
//mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf )
mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, int numverts, int firstvert)
void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert)
{
int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p;
mesh_t *mesh;
index_t *indexes;
int patch_cp[2], step[2], size[2], flat[2];
float subdivlevel;
char *allocbuf;
int sz;
patch_cp[0] = patchwidth;
patch_cp[1] = patchheight;
if (patch_cp[0] <= 0 || patch_cp[1] <= 0 )
{
return NULL;
mesh->numindexes = 0;
mesh->numvertexes = 0;
return;
}
subdivlevel = r_subdivisions.value;
if ( subdivlevel < 1 )
subdivlevel = 1;
// find the degree of subdivision in the u and v directions
Patch_GetFlatness ( subdivlevel, map_verts[firstvert], sizeof(vecV_t)/sizeof(vec_t), patch_cp, flat );
// allocate space for mesh
step[0] = (1 << flat[0]);
step[1] = (1 << flat[1]);
size[0] = (patch_cp[0] / 2) * step[0] + 1;
size[1] = (patch_cp[1] / 2) * step[1] + 1;
mesh->numvertexes = size[0] * size[1];
mesh->numindexes = (size[0]-1) * (size[1]-1) * 6;
}
//mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf )
void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert)
{
int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p;
index_t *indexes;
float subdivlevel;
int sty;
patch_cp[0] = patchwidth;
patch_cp[1] = patchheight;
if (patch_cp[0] <= 0 || patch_cp[1] <= 0 )
{
mesh->numindexes = 0;
mesh->numvertexes = 0;
return;
}
subdivlevel = r_subdivisions.value;
@ -2387,34 +2426,19 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
numverts = size[0] * size[1];
if ( numverts < 0 || numverts > MAX_ARRAY_VERTS )
return NULL;
{
mesh->numindexes = 0;
mesh->numvertexes = 0;
return;
}
sz = sizeof(mesh_t) + numverts * (
sizeof(vecV_t)+
sizeof(vec3_t)+
sizeof(vec3_t)+
sizeof(vec3_t)+
sizeof(vec2_t)+
sizeof(vec2_t)+
sizeof(vec4_t));
allocbuf = Hunk_Alloc(sz);
sz-=sizeof(mesh_t);
mesh = (mesh_t *)(allocbuf+sz);
sz-=numverts*sizeof(vecV_t);
mesh->xyz_array = (vecV_t *)(allocbuf+sz);
sz-=numverts*sizeof(vec3_t);
mesh->normals_array = (vec3_t *)(allocbuf+sz);
sz-=numverts*sizeof(vec3_t);
mesh->snormals_array = (vec3_t *)(allocbuf+sz);
sz-=numverts*sizeof(vec3_t);
mesh->tnormals_array = (vec3_t *)(allocbuf+sz);
sz-=numverts*sizeof(vec2_t);
mesh->st_array = (vec2_t *)(allocbuf+sz);
sz-=numverts*sizeof(vec2_t);
mesh->lmst_array = (vec2_t *)(allocbuf+sz);
sz-=numverts*sizeof(vec4_t);
mesh->colors4f_array = (vec4_t *)(allocbuf+sz);
mesh->numvertexes = numverts;
if (mesh->numvertexes != numverts)
{
mesh->numindexes = 0;
mesh->numvertexes = 0;
return;
}
// fill in
@ -2422,7 +2446,11 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
Patch_Evaluate ( map_colors4f_array[firstvert], patch_cp, step, mesh->colors4f_array[0], 4 );
Patch_Evaluate ( map_normals_array[firstvert], patch_cp, step, mesh->normals_array[0], 3 );
Patch_Evaluate ( map_vertstmexcoords[firstvert], patch_cp, step, mesh->st_array[0], 2 );
Patch_Evaluate ( map_vertlstmexcoords[firstvert], patch_cp, step, mesh->lmst_array[0], 2 );
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
{
if (mesh->lmst_array[sty])
Patch_Evaluate ( map_vertlstmexcoords[sty][firstvert], patch_cp, step, mesh->lmst_array[sty][0], 2 );
}
// compute new indexes avoiding adding invalid triangles
numindexes = 0;
@ -2435,9 +2463,10 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
indexes[1] = p + size[0];
indexes[2] = p + 1;
if ( !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
!VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
!VectorEquals(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) ) {
// if ( !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
// !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
// !VectorEquals(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) )
{
indexes += 3;
numindexes += 3;
}
@ -2446,9 +2475,10 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
indexes[1] = p + size[0];
indexes[2] = p + size[0] + 1;
if ( !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
!VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
!VectorEquals(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) ) {
// if ( !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[1]]) &&
// !VectorEquals(mesh->xyz_array[indexes[0]], mesh->xyz_array[indexes[2]]) &&
// !VectorEquals(mesh->xyz_array[indexes[1]], mesh->xyz_array[indexes[2]]) )
{
indexes += 3;
numindexes += 3;
}
@ -2456,12 +2486,224 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
}
// allocate and fill index table
if (mesh->numindexes != numindexes)
Con_Printf("DEBUGY\n");
mesh->numindexes = numindexes;
mesh->indexes = (index_t *)Hunk_Alloc ( numindexes * sizeof(index_t));
memcpy (mesh->indexes, tempIndexesArray, numindexes * sizeof(index_t) );
}
void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, void *cookie)
{
rbspface_t *in = cookie;
int idx = out - loadmodel->surfaces;
int sty;
in += idx;
if (LittleLong(in->facetype) == MST_PATCH)
{
// out->mesh->numindexes = 0;
// out->mesh->numvertexes = 0;
//FIXME
GL_CreateMeshForPatch(loadmodel, out->mesh, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex));
// if (out->mesh)
// {
// Mod_AccumulateMeshTextureVectors(out->mesh);
// Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes);
// }
}
else if (LittleLong(in->facetype) == MST_PLANAR || LittleLong(in->facetype) == MST_TRIANGLE_SOUP)
{
unsigned int fv = LittleLong(in->firstvertex), i;
for (i = 0; i < out->mesh->numvertexes; i++)
{
VectorCopy(map_verts[fv + i], out->mesh->xyz_array[i]);
Vector2Copy(map_vertstmexcoords[fv + i], out->mesh->st_array[i]);
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
{
Vector2Copy(map_vertlstmexcoords[sty][fv + i], out->mesh->lmst_array[sty][i]);
}
Vector4Copy(map_colors4f_array[fv + i], out->mesh->colors4f_array[i]);
VectorCopy(map_normals_array[fv + i], out->mesh->normals_array[i]);
}
fv = LittleLong(in->firstindex);
for (i = 0; i < out->mesh->numindexes; i++)
{
out->mesh->indexes[i] = map_surfindexes[fv + i];
}
/* numindexes = LittleLong(in->num_indexes);
numverts = LittleLong(in->num_vertices);
if (numindexes%3 || numindexes < 0 || numverts < 0)
{
Con_Printf(CON_ERROR "mesh indexes should be multiples of 3\n");
return false;
}
out->mesh = Hunk_Alloc(sizeof(mesh_t));
out->mesh->normals_array= map_normals_array + LittleLong(in->firstvertex);
out->mesh->snormals_array = map_svector_array + LittleLong(in->firstvertex);
out->mesh->tnormals_array = map_tvector_array + LittleLong(in->firstvertex);
out->mesh->colors4f_array = map_colors4f_array + LittleLong(in->firstvertex);
out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex);
out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex);
out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex);
out->mesh->lmst_array = map_vertlstmexcoords + LittleLong(in->firstvertex);
out->mesh->numindexes = numindexes;
out->mesh->numvertexes = numverts;
if (LittleLong(in->facetype) == MST_PLANAR)
if (out->mesh->numindexes == (out->mesh->numvertexes-2)*3)
out->mesh->istrifan = true;
Mod_AccumulateMeshTextureVectors(out->mesh);
*/
}
else
{
/* //flare
int r, g, b;
extern index_t r_quad_indexes[6];
static vec2_t st[4] = {{0,0},{0,1},{1,1},{1,0}};
mesh = out->mesh = (mesh_t *)Hunk_Alloc(sizeof(mesh_t));
mesh->xyz_array = (vecV_t *)Hunk_Alloc(sizeof(vecV_t)*4);
mesh->colors4b_array = (byte_vec4_t *)Hunk_Alloc(sizeof(byte_vec4_t)*4);
mesh->numvertexes = 4;
mesh->indexes = r_quad_indexes;
mesh->st_array = st;
mesh->numindexes = 6;
VectorCopy (in->lightmap_origin, mesh->xyz_array[0]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[1]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[2]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[3]);
r = LittleFloat(in->lightmap_vecs[0][0]) * 255.0f;
r = bound (0, r, 255);
g = LittleFloat(in->lightmap_vecs[0][1]) * 255.0f;
g = bound (0, g, 255);
b = LittleFloat(in->lightmap_vecs[0][2]) * 255.0f;
b = bound (0, b, 255);
mesh->colors4b_array[0][0] = r;
mesh->colors4b_array[0][1] = g;
mesh->colors4b_array[0][2] = b;
mesh->colors4b_array[0][3] = 255;
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[1]);
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[2]);
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[3]);
*/
}
}
void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, void *cookie)
{
q3dface_t *in = cookie;
int idx = out - loadmodel->surfaces;
in += idx;
if (LittleLong(in->facetype) == MST_PATCH)
{
// out->mesh->numindexes = 0;
// out->mesh->numvertexes = 0;
//FIXME
GL_CreateMeshForPatch(loadmodel, out->mesh, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex));
// if (out->mesh)
// {
// Mod_AccumulateMeshTextureVectors(out->mesh);
// Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes);
// }
}
else if (LittleLong(in->facetype) == MST_PLANAR || LittleLong(in->facetype) == MST_TRIANGLE_SOUP)
{
unsigned int fv = LittleLong(in->firstvertex), i;
for (i = 0; i < out->mesh->numvertexes; i++)
{
VectorCopy(map_verts[fv + i], out->mesh->xyz_array[i]);
Vector2Copy(map_vertstmexcoords[fv + i], out->mesh->st_array[i]);
Vector2Copy(map_vertlstmexcoords[0][fv + i], out->mesh->lmst_array[0][i]);
Vector4Copy(map_colors4f_array[fv + i], out->mesh->colors4f_array[i]);
VectorCopy(map_normals_array[fv + i], out->mesh->normals_array[i]);
}
fv = LittleLong(in->firstindex);
for (i = 0; i < out->mesh->numindexes; i++)
{
out->mesh->indexes[i] = map_surfindexes[fv + i];
}
/* numindexes = LittleLong(in->num_indexes);
numverts = LittleLong(in->num_vertices);
if (numindexes%3 || numindexes < 0 || numverts < 0)
{
Con_Printf(CON_ERROR "mesh indexes should be multiples of 3\n");
return false;
}
out->mesh = Hunk_Alloc(sizeof(mesh_t));
out->mesh->normals_array= map_normals_array + LittleLong(in->firstvertex);
out->mesh->snormals_array = map_svector_array + LittleLong(in->firstvertex);
out->mesh->tnormals_array = map_tvector_array + LittleLong(in->firstvertex);
out->mesh->colors4f_array = map_colors4f_array + LittleLong(in->firstvertex);
out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex);
out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex);
out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex);
out->mesh->lmst_array = map_vertlstmexcoords + LittleLong(in->firstvertex);
out->mesh->numindexes = numindexes;
out->mesh->numvertexes = numverts;
if (LittleLong(in->facetype) == MST_PLANAR)
if (out->mesh->numindexes == (out->mesh->numvertexes-2)*3)
out->mesh->istrifan = true;
Mod_AccumulateMeshTextureVectors(out->mesh);
*/
}
else
{
/* //flare
int r, g, b;
extern index_t r_quad_indexes[6];
static vec2_t st[4] = {{0,0},{0,1},{1,1},{1,0}};
mesh = out->mesh = (mesh_t *)Hunk_Alloc(sizeof(mesh_t));
mesh->xyz_array = (vecV_t *)Hunk_Alloc(sizeof(vecV_t)*4);
mesh->colors4b_array = (byte_vec4_t *)Hunk_Alloc(sizeof(byte_vec4_t)*4);
mesh->numvertexes = 4;
mesh->indexes = r_quad_indexes;
mesh->st_array = st;
mesh->numindexes = 6;
VectorCopy (in->lightmap_origin, mesh->xyz_array[0]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[1]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[2]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[3]);
r = LittleFloat(in->lightmap_vecs[0][0]) * 255.0f;
r = bound (0, r, 255);
g = LittleFloat(in->lightmap_vecs[0][1]) * 255.0f;
g = bound (0, g, 255);
b = LittleFloat(in->lightmap_vecs[0][2]) * 255.0f;
b = bound (0, b, 255);
mesh->colors4b_array[0][0] = r;
mesh->colors4b_array[0][1] = g;
mesh->colors4b_array[0][2] = b;
mesh->colors4b_array[0][3] = 255;
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[1]);
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[2]);
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[3]);
*/
}
return mesh;
}
qboolean CModQ3_LoadRFaces (lump_t *l)
@ -2473,8 +2715,8 @@ qboolean CModQ3_LoadRFaces (lump_t *l)
int count;
int surfnum;
int numverts, numindexes;
int fv;
int sty;
mesh_t *mesh;
@ -2487,6 +2729,7 @@ qboolean CModQ3_LoadRFaces (lump_t *l)
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadmodel->name );
pl = Hunk_AllocName (count*sizeof(*pl), loadmodel->name);//create a new array of planes for speed.
mesh = Hunk_AllocName (count*sizeof(*mesh), loadmodel->name);
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
@ -2495,13 +2738,22 @@ qboolean CModQ3_LoadRFaces (lump_t *l)
{
out->plane = pl;
out->texinfo = loadmodel->texinfo + LittleLong(in->shadernum);
out->lightmaptexturenum = LittleLong(in->lightmapnum);
out->light_s = LittleLong(in->lightmap_x);
out->light_t = LittleLong(in->lightmap_y);
out->lightmaptexturenums[0] = LittleLong(in->lightmapnum);
out->light_s[0] = LittleLong(in->lightmap_x);
out->light_t[0] = LittleLong(in->lightmap_y);
out->styles[0] = 255;
for (sty = 1; sty < MAXLIGHTMAPS; sty++)
{
out->styles[sty] = 255;
out->lightmaptexturenums[sty] = -1;
}
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<4;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<4;
out->samples=NULL;
if (loadmodel->lightmaps.count < out->lightmaptexturenums[0]+1)
loadmodel->lightmaps.count = out->lightmaptexturenums[0]+1;
fv = LittleLong(in->firstvertex);
{
vec3_t v[3];
@ -2511,10 +2763,6 @@ qboolean CModQ3_LoadRFaces (lump_t *l)
PlaneFromPoints(v, pl);
CategorizePlane(pl);
}
/*
if (in->fognum!=-1)
continue;
*/
if (map_surfaces[LittleLong(in->shadernum)].c.value == 0 || map_surfaces[LittleLong(in->shadernum)].c.value & Q3CONTENTS_TRANSLUCENT)
//q3dm10's thingie is 0
@ -2543,84 +2791,30 @@ qboolean CModQ3_LoadRFaces (lump_t *l)
if (map_surfaces[LittleLong(in->shadernum)].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP))
{
out->mesh = &nullmesh;
out->mesh = &mesh[surfnum];
out->mesh->numindexes = 0;
out->mesh->numvertexes = 0;
}
else if (LittleLong(in->facetype) == MST_PATCH)
{
out->mesh = GL_CreateMeshForPatch(loadmodel, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex));
if (out->mesh)
{
Mod_AccumulateMeshTextureVectors(out->mesh);
Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes);
}
out->mesh = &mesh[surfnum];
GL_SizePatch(out->mesh, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex));
}
else if (LittleLong(in->facetype) == MST_PLANAR || LittleLong(in->facetype) == MST_TRIANGLE_SOUP)
{
numindexes = LittleLong(in->num_indexes);
numverts = LittleLong(in->num_vertices);
if (numindexes%3 || numindexes < 0 || numverts < 0)
{
Con_Printf(CON_ERROR "mesh indexes should be multiples of 3\n");
return false;
}
out->mesh = Hunk_Alloc(sizeof(mesh_t));
out->mesh->normals_array= map_normals_array + LittleLong(in->firstvertex);
out->mesh->snormals_array = map_svector_array + LittleLong(in->firstvertex);
out->mesh->tnormals_array = map_tvector_array + LittleLong(in->firstvertex);
out->mesh->colors4f_array = map_colors4f_array + LittleLong(in->firstvertex);
out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex);
out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex);
out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex);
out->mesh->lmst_array = map_vertlstmexcoords + LittleLong(in->firstvertex);
out->mesh->numindexes = numindexes;
out->mesh->numvertexes = numverts;
if (LittleLong(in->facetype) == MST_PLANAR)
if (out->mesh->numindexes == (out->mesh->numvertexes-2)*3)
out->mesh->istrifan = true;
out->mesh = &mesh[surfnum];
out->mesh->numindexes = LittleLong(in->num_indexes);
out->mesh->numvertexes = LittleLong(in->num_vertices);
/*
Mod_AccumulateMeshTextureVectors(out->mesh);
*/
}
else
{
//flare
int r, g, b;
extern index_t r_quad_indexes[6];
static vec2_t st[4] = {{0,0},{0,1},{1,1},{1,0}};
mesh = out->mesh = (mesh_t *)Hunk_Alloc(sizeof(mesh_t));
mesh->xyz_array = (vecV_t *)Hunk_Alloc(sizeof(vecV_t)*4);
mesh->colors4b_array = (byte_vec4_t *)Hunk_Alloc(sizeof(byte_vec4_t)*4);
mesh->numvertexes = 4;
mesh->indexes = r_quad_indexes;
mesh->st_array = st;
mesh->numindexes = 6;
VectorCopy (in->lightmap_origin, mesh->xyz_array[0]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[1]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[2]);
VectorCopy (in->lightmap_origin, mesh->xyz_array[3]);
r = LittleFloat(in->lightmap_vecs[0][0]) * 255.0f;
r = bound (0, r, 255);
g = LittleFloat(in->lightmap_vecs[0][1]) * 255.0f;
g = bound (0, g, 255);
b = LittleFloat(in->lightmap_vecs[0][2]) * 255.0f;
b = bound (0, b, 255);
mesh->colors4b_array[0][0] = r;
mesh->colors4b_array[0][1] = g;
mesh->colors4b_array[0][2] = b;
mesh->colors4b_array[0][3] = 255;
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[1]);
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[2]);
Vector4Copy(mesh->colors4b_array[0], mesh->colors4b_array[3]);
out->mesh = &mesh[surfnum];
out->mesh->numindexes = 6;
out->mesh->numvertexes = 4;
}
if (out->mesh->numindexes == 0)
Con_Printf("foo\n");
}
Mod_NormaliseTextureVectors(map_normals_array, map_svector_array, map_tvector_array, numvertexes);
@ -2641,6 +2835,7 @@ qboolean CModRBSP_LoadRFaces (lump_t *l)
int numverts, numindexes;
int fv;
int j;
mesh_t *mesh;
@ -2654,6 +2849,7 @@ qboolean CModRBSP_LoadRFaces (lump_t *l)
count = l->filelen / sizeof(*in);
out = Hunk_AllocName ( count*sizeof(*out), loadmodel->name );
pl = Hunk_AllocName (count*sizeof(*pl), loadmodel->name);//create a new array of planes for speed.
mesh = Hunk_AllocName (count*sizeof(*mesh), loadmodel->name);
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
@ -2663,11 +2859,20 @@ qboolean CModRBSP_LoadRFaces (lump_t *l)
out->plane = pl;
out->texinfo = loadmodel->texinfo + LittleLong(in->shadernum);
in->facetype = LittleLong(in->facetype);
out->lightmaptexturenum = in->lightmapnum[0];
out->light_s = in->lightmap_offs[0][0];
out->light_t = in->lightmap_offs[0][0];
out->extents[0] = (in->lightmap_width-1)<<4;
out->extents[1] = (in->lightmap_height-1)<<4;
for (j = 0; j < 4 && j < MAXLIGHTMAPS; j++)
{
if (in->lightmapnum[j] >= 0 && j)
Con_Printf("lightstyled!\n");
out->lightmaptexturenums[j] = LittleLong(in->lightmapnum[j]);
out->light_s[j] = LittleLong(in->lightmap_offs[0][j]);
out->light_t[j] = LittleLong(in->lightmap_offs[1][j]);
out->styles[j] = in->lm_styles[j];
if (loadmodel->lightmaps.count < out->lightmaptexturenums[j]+1)
loadmodel->lightmaps.count = out->lightmaptexturenums[j]+1;
}
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<4;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<4;
out->samples=NULL;
fv = LittleLong(in->firstvertex);
@ -2679,10 +2884,6 @@ qboolean CModRBSP_LoadRFaces (lump_t *l)
PlaneFromPoints(v, pl);
CategorizePlane(pl);
}
/*
if (in->fognum!=-1)
continue;
*/
if (map_surfaces[in->shadernum].c.value == 0 || map_surfaces[in->shadernum].c.value & Q3CONTENTS_TRANSLUCENT)
//q3dm10's thingie is 0
@ -2710,66 +2911,35 @@ qboolean CModRBSP_LoadRFaces (lump_t *l)
else
out->fog = map_fogs + in->fognum;
#endif
if (map_surfaces[in->shadernum].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP))
{
if (map_surfaces[in->shadernum].c.flags & Q3SURF_SKIP)
Con_Printf("Surface skip\n");
out->mesh = NULL;
}
else if (in->facetype == MST_PATCH)
{
out->mesh = GL_CreateMeshForPatch(loadmodel, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex));
}
else if (in->facetype == MST_PLANAR || in->facetype == MST_TRIANGLE_SOUP)
{
numindexes = LittleLong(in->num_indexes);
numverts = LittleLong(in->num_vertices);
if (numindexes%3)
{
Con_Printf(CON_ERROR "mesh indexes should be multiples of 3\n");
return false;
}
out->mesh = Hunk_Alloc(sizeof(mesh_t) + (sizeof(vec3_t)) * numverts);
out->mesh->normals_array= map_normals_array + LittleLong(in->firstvertex);
out->mesh->colors4f_array = map_colors4f_array + LittleLong(in->firstvertex);
out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex);
out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex);
out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex);
out->mesh->lmst_array = map_vertlstmexcoords + LittleLong(in->firstvertex);
out->mesh->numindexes = numindexes;
out->mesh->numvertexes = numverts;
if (map_surfaces[LittleLong(in->shadernum)].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP))
{
out->mesh = &mesh[surfnum];
out->mesh->numindexes = 0;
out->mesh->numvertexes = 0;
}
else if (LittleLong(in->facetype) == MST_PATCH)
{
out->mesh = &mesh[surfnum];
GL_SizePatch(out->mesh, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex));
}
else if (LittleLong(in->facetype) == MST_PLANAR || LittleLong(in->facetype) == MST_TRIANGLE_SOUP)
{
out->mesh = &mesh[surfnum];
out->mesh->numindexes = LittleLong(in->num_indexes);
out->mesh->numvertexes = LittleLong(in->num_vertices);
/*
Mod_AccumulateMeshTextureVectors(out->mesh);
*/
}
else
{
// int r, g, b;
extern index_t r_quad_indexes[6];
static vec2_t st[4] = {{0,0},{0,1},{1,1},{1,0}};
mesh = out->mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t));
mesh->xyz_array = (vecV_t *)Hunk_Alloc ( sizeof(vecV_t));
mesh->numvertexes = 1;
mesh->indexes = r_quad_indexes;
mesh->st_array = st;
mesh->numindexes = 6;
// VectorCopy ( out->origin, mesh->xyz_array[0] );
/* r = LittleFloat ( in->lightmapVecs[0][0] ) * 255.0f;
r = bound ( 0, r, 255 );
g = LittleFloat ( in->lightmapVecs[0][1] ) * 255.0f;
g = bound ( 0, g, 255 );
b = LittleFloat ( in->lightmapVecs[0][2] ) * 255.0f;
b = bound ( 0, b, 255 );
out->dlightbits = (unsigned int)COLOR_RGB ( r, g, b );
*/ }
out->mesh = &mesh[surfnum];
out->mesh->numindexes = 6;
out->mesh->numvertexes = 4;
}
}
Mod_SortShaders();
return true;
}
#endif
@ -3256,8 +3426,8 @@ qboolean CModRBSP_LoadLightgrid (lump_t *elements, lump_t *indexes)
ecount = elements->filelen / sizeof(*ein);
grid = Hunk_AllocName (sizeof(q3lightgridinfo_t) + ecount*sizeof(*eout) + icount*sizeof(*iout), loadmodel->name );
grid->rbspelements = (rbspgridlight_t*)((char *)grid);
grid->rbspindexes = (unsigned short*)((char *)grid + ecount*sizeof(*eout));
grid->rbspelements = (rbspgridlight_t*)((char *)grid + sizeof(q3lightgridinfo_t));
grid->rbspindexes = (unsigned short*)((char *)grid + sizeof(q3lightgridinfo_t) + ecount*sizeof(*eout));
eout = grid->rbspelements;
iout = grid->rbspindexes;
@ -3570,6 +3740,9 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
qboolean noerrors = true;
int start;
void (*buildmeshes)(model_t *mod, msurface_t *surf, void *cookie) = NULL;
void *buildcookie = NULL;
// free old stuff
numplanes = 0;
numleafs = 0;
@ -3610,6 +3783,17 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
cmod_base = mod_base = (qbyte *)buf;
start = Hunk_LowMark();
if (header.ident == (('F'<<0)+('B'<<8)+('S'<<16)+('P'<<24)))
{
loadmodel->lightmaps.width = 512;
loadmodel->lightmaps.height = 512;
}
else
{
loadmodel->lightmaps.width = 128;
loadmodel->lightmaps.height = 128;
}
switch(header.version)
{
default:
@ -3618,7 +3802,7 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
return NULL;
break;
#if 1
case 1: //rbsp
case 1: //rbsp/fbsp
case Q3BSPVERSION+1: //rtcw
case Q3BSPVERSION:
mapisq3 = true;
@ -3703,10 +3887,17 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
else
map_numfogs = 0;
buildcookie = (void *)(mod_base + header.lumps[Q3LUMP_SURFACES].fileofs);
if (header.version == 1)
{
noerrors = noerrors && CModRBSP_LoadRFaces (&header.lumps[Q3LUMP_SURFACES]);
buildmeshes = CModRBSP_BuildSurfMesh;
}
else
{
noerrors = noerrors && CModQ3_LoadRFaces (&header.lumps[Q3LUMP_SURFACES]);
buildmeshes = CModQ3_BuildSurfMesh;
}
noerrors = noerrors && CModQ3_LoadMarksurfaces (&header.lumps[Q3LUMP_LEAFSURFACES]); //fixme: duplicated loading.
/*make sure all textures have a shader*/
@ -3923,6 +4114,13 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->checksum = loadmodel->checksum2 = *checksum;
loadmodel->nummodelsurfaces = loadmodel->numsurfaces;
memset(&loadmodel->batches, 0, sizeof(loadmodel->batches));
loadmodel->vbos = NULL;
#ifndef SERVERONLY
if (qrenderer != QR_NONE)
RMod_Batches_Build(NULL, loadmodel, buildmeshes, buildcookie);
#endif
loadmodel->numsubmodels = CM_NumInlineModels(loadmodel);
{
@ -3965,6 +4163,13 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
mod->hulls[j].available = false;
}
memset(&mod->batches, 0, sizeof(mod->batches));
mod->vbos = NULL;
#ifndef SERVERONLY
if (qrenderer != QR_NONE)
RMod_Batches_Build(NULL, mod, buildmeshes, buildcookie);
#endif
VectorCopy (bm->maxs, mod->maxs);
VectorCopy (bm->mins, mod->mins);
#ifndef SERVERONLY

View File

@ -418,6 +418,16 @@ int VectorCompare (const vec3_t v1, const vec3_t v2)
return 1;
}
int Vector4Compare (const vec4_t v1, const vec4_t v2)
{
int i;
for (i=0 ; i<4 ; i++)
if (v1[i] != v2[i])
return 0;
return 1;
}
void _VectorMA (const vec3_t veca, const float scale, const vec3_t vecb, vec3_t vecc)
{

View File

@ -190,6 +190,7 @@ void R_ConcatTransforms (matrix3x4 in1, matrix3x4 in2, matrix3x4 out);
void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees);
void RotateLightVector(const vec3_t *axis, const vec3_t origin, const vec3_t lightpoint, vec3_t result);
int VectorCompare (const vec3_t v1, const vec3_t v2);
int Vector4Compare (const vec4_t v1, const vec4_t v2);
void VectorInverse (vec3_t v);
void _VectorMA (const vec3_t veca, const float scale, const vec3_t vecb, vec3_t vecc);
float QDECL VectorNormalize (vec3_t v); // returns vector length

View File

@ -1812,6 +1812,7 @@ void Plug_Close(plugin_t *plug)
Plug_FreeConCommands(plug);
Plug_Client_Close(plug);
Z_Free(plug);
if (currentplug == plug)
currentplug = NULL;
@ -1883,8 +1884,17 @@ void Plug_Shutdown(void)
{
while(plugs)
{
plugs->blockcloses = 0;
Plug_Close(plugs);
}
numplugbuiltins = 0;
BZ_Free(plugbuiltins);
plugbuiltins = NULL;
plugincommandarraylen = 0;
BZ_Free(plugincommandarray);
plugincommandarray = NULL;
}
#endif

View File

@ -372,6 +372,7 @@ void PM_Friction (void)
speed = Length(pmove.velocity);
if (speed < 1)
{
//fixme: gravitydir fix needed
pmove.velocity[0] = 0;
pmove.velocity[1] = 0;
if (pmove.pm_type == PM_FLY)
@ -1122,7 +1123,7 @@ void PM_PlayerMove (float gamespeed)
if (pmove.waterlevel == 2 && pmove.pm_type != PM_FLY)
PM_CheckWaterJump ();
if (pmove.velocity[2] < 0 || pmove.pm_type == PM_DEAD)
if (-DotProduct(pmove.gravitydir, pmove.velocity) < 0 || pmove.pm_type == PM_DEAD)
pmove.waterjumptime = 0;
if (pmove.waterjumptime)
@ -1157,7 +1158,7 @@ void PM_PlayerMove (float gamespeed)
// this is to make sure landing sound is not played twice
// and falling damage is calculated correctly
if (pmove.onground && pmove.velocity[2] < -300
if (pmove.onground && -DotProduct(pmove.gravitydir, pmove.velocity) < -300
&& DotProduct(pmove.velocity, groundplane.normal) < -0.1)
{
PM_ClipVelocity (pmove.velocity, groundplane.normal, pmove.velocity, 1);

View File

@ -3707,6 +3707,7 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_CALLTIMEOFDAY", 1, NULL, {"calltimeofday"}},
{"FTE_CSQC_HALFLIFE_MODELS"}, //hl-specific skeletal model control
{"FTE_CSQC_BASEFRAME"}, //control for all skeletal models
{"FTE_ENT_SKIN_CONTENTS"}, //self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder.
{"FTE_ENT_UNIQUESPAWNID"},
{"FTE_EXTENDEDTEXTCODES"},
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
@ -3731,7 +3732,7 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_QC_PAUSED"},
{"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}},
{"FTE_QC_TRACETRIGGER"},
{"FTE_SOLID_LADDER"}, //part of a worthy hl implementation. Allows a simple trigger to remove effects of gravity (solid 20)
{"FTE_SOLID_LADDER"}, //Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS
#ifdef SQL
// serverside SQL functions for managing an SQL database connection

View File

@ -543,15 +543,15 @@ enum clcq2_ops_e
#define UF_DRAWFLAGS (1u<<19)
#define UF_TAGINFO (1u<<20)
#define UF_LIGHT (1u<<21)
#define UF_EFFECTS2 (1u<<22)
#define UF_TRAILEFFECT (1u<<22)
#define UF_EXTEND3 (1u<<23)
#define UF_COLORMOD (1u<<24)
#define UF_GLOWMOD (1u<<25)
#define UF_FATNESS (1u<<26)
#define UF_MODELINDEX2 (1u<<27)
#define UF_UNUSED4 (1u<<28)
#define UF_UNUSED3 (1u<<29)
#define UF_GRAVITYDIR (1u<<28)
#define UF_EFFECTS2 (1u<<29)
#define UF_UNUSED2 (1u<<30)
#define UF_UNUSED1 (1u<<31)
@ -823,6 +823,8 @@ typedef struct entity_state_s
unsigned short weaponframe;
short movement[3];
short velocity[3]; // 1/8th
unsigned char gravitydir[2]; //pitch/yaw, no roll
unsigned short traileffectnum;
} q1;
} u;
unsigned short modelindex2; //q2/vweps

View File

@ -1832,7 +1832,6 @@ static qbyte mod_novis[MAX_MAP_LEAFS/8];
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer, unsigned int buffersize)
{
static qbyte decompressed[MAX_MAP_LEAFS/8];
if (leaf == model->leafs)

View File

@ -1,8 +1,5 @@
#include "quakedef.h"
#undef malloc
#undef free
static char *defaultlanguagetext =
"STL_LANGUAGENAME \"English\"\n"
"TL_NL \"\\n\"\n"
@ -686,6 +683,26 @@ void TL_WriteTLHeader(void)
}
#endif
void TL_Shutdown(void)
{
int i, j, k;
for (i = 0; i < STL_MAXSTL; i++)
{
for (j = 0; j < MAX_LANGUAGES; j++)
{
if (j)
free(langtext(i, j));
for (k = j+1; k < MAX_LANGUAGES; k++)
{
if (langtext(i, k) == langtext(i, j))
langtext(i, k) = NULL;
}
langtext(i, j) = NULL;
}
}
}
void TL_InitLanguages(void)
{
int i, j;

View File

@ -71,6 +71,7 @@ void Plug_Command_f(void);
int Plug_ConnectionlessClientPacket(char *buffer, int size);
void Plug_DrawReloadImages(void);
void Plug_Init(void);
void Plug_Shutdown(void);
qboolean Plug_Menu_Event(int eventtype, int param);
void Plug_ResChanged(void);
void Plug_SBar(void);

View File

@ -151,6 +151,7 @@ struct world_s
void (*Event_Touch)(struct world_s *w, wedict_t *s, wedict_t *o);
void (*Event_Think)(struct world_s *w, wedict_t *s);
void (*Event_Sound) (wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj);
qboolean (*Event_ContentsTransition) (struct world_s *w, wedict_t *ent, int oldwatertype, int newwatertype);
model_t *(*Get_CModel)(struct world_s *w, int modelindex);
void (*Get_FrameState)(struct world_s *w, wedict_t *s, framestate_t *fstate);

View File

@ -184,11 +184,24 @@ void *VARGS Z_TagMalloc(int size, int tag)
return (void *)(zone + 1);
}
#ifdef USE_MSVCRT_DEBUG
void *ZF_MallocNamed(int size, char *file, int line)
{
return _calloc_dbg(size, 1, _NORMAL_BLOCK, file, line);
}
void *Z_MallocNamed(int size, char *file, int line)
{
void *mem = ZF_MallocNamed(size, file, line);
if (!mem)
Sys_Error("Z_Malloc: Failed on allocation of %i bytes", size);
return mem;
}
#else
void *ZF_Malloc(int size)
{
return calloc(size, 1);
}
void *Z_Malloc(int size)
{
void *mem = ZF_Malloc(size);
@ -197,6 +210,7 @@ void *Z_Malloc(int size)
return mem;
}
#endif
void VARGS Z_TagFree(void *mem)
{
@ -348,6 +362,19 @@ void *Z_Realloc(void *data, int newsize)
}
*/
#ifdef USE_MSVCRT_DEBUG
void *BZF_MallocNamed(int size, char *file, int line) //BZ_MallocNamed but allowed to fail - like straight malloc.
{
void *mem;
mem = _malloc_dbg(size, _NORMAL_BLOCK, file, line);
if (mem)
{
zmemdelta += size;
zmemtotal += size;
}
return mem;
}
#else
void *BZF_Malloc(int size) //BZ_Malloc but allowed to fail - like straight malloc.
{
void *mem;
@ -359,7 +386,18 @@ void *BZF_Malloc(int size) //BZ_Malloc but allowed to fail - like straight mallo
}
return mem;
}
#endif
#ifdef USE_MSVCRT_DEBUG
void *BZ_MallocNamed(int size, char *file, int line) //BZ_MallocNamed but allowed to fail - like straight malloc.
{
void *mem = BZF_MallocNamed(size, file, line);
if (!mem)
Sys_Error("BZ_Malloc: Failed on allocation of %i bytes", size);
return mem;
}
#else
void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rather than sensative data structures.
{
void *mem = BZF_Malloc(size);
@ -368,7 +406,24 @@ void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rath
return mem;
}
#endif
#ifdef USE_MSVCRT_DEBUG
void *BZF_ReallocNamed(void *data, int newsize, char *file, int line)
{
return _realloc_dbg(data, newsize, _NORMAL_BLOCK, file, line);
}
void *BZ_ReallocNamed(void *data, int newsize, char *file, int line)
{
void *mem = BZF_ReallocNamed(data, newsize, file, line);
if (!mem)
Sys_Error("BZ_Realloc: Failed on reallocation of %i bytes", newsize);
return mem;
}
#else
void *BZF_Realloc(void *data, int newsize)
{
return realloc(data, newsize);
@ -383,6 +438,7 @@ void *BZ_Realloc(void *data, int newsize)
return mem;
}
#endif
void BZ_Free(void *data)
{
@ -1776,6 +1832,17 @@ void Hunk_Print_f (void)
Con_Printf("Zone: %i containing %iKB\n", zoneblocks, zoneused/1024);
}
#endif
#ifdef USE_MSVCRT_DEBUG
{
static struct _CrtMemState savedstate;
static qboolean statesaved;
_CrtMemDumpAllObjectsSince(statesaved?&savedstate:NULL);
_CrtMemCheckpoint(&savedstate);
statesaved = true;
}
#endif
}
void Cache_Init(void)
{

View File

@ -89,6 +89,8 @@ void Memory_DeInit(void);
void VARGS Z_Free (void *ptr);
void *Z_Malloc (int size); // returns 0 filled memory
void *ZF_Malloc (int size); // allowed to fail
void *Z_MallocNamed (int size, char *file, int line); // returns 0 filled memory
void *ZF_MallocNamed (int size, char *file, int line); // allowed to fail
//#define Z_Malloc(x) Z_MallocNamed2(x, __FILE__, __LINE__ )
void *VARGS Z_TagMalloc (int size, int tag);
void VARGS Z_TagFree(void *ptr);
@ -99,17 +101,21 @@ void VARGS Z_FreeTags(int tag);
//(this is a nicer name for malloc)
void *BZ_Malloc(int size);
void *BZF_Malloc(int size);
void *BZ_MallocNamed (int size, char *file, int line); // returns 0 filled memory
void *BZF_MallocNamed (int size, char *file, int line); // allowed to fail
void *BZ_Realloc(void *ptr, int size);
void *BZ_ReallocNamed(void *data, int newsize, char *file, int line);
void *BZF_Realloc(void *data, int newsize);
void *BZF_ReallocNamed(void *data, int newsize, char *file, int line);
void BZ_Free(void *ptr);
#ifdef NAMEDMALLOCS
#define BZ_Malloc(size) Z_MallocNamed(size, __FILE__, __LINE__)
#ifdef USE_MSVCRT_DEBUG
#define BZ_Malloc(size) BZ_MallocNamed(size, __FILE__, __LINE__)
#define Z_Malloc(size) Z_MallocNamed(size, __FILE__, __LINE__)
#define BZ_Realloc(ptr, size) BZ_NamedRealloc(ptr, size, __FILE__, __LINE__)
#define BZ_Realloc(ptr, size) BZ_ReallocNamed(ptr, size, __FILE__, __LINE__)
#define BZF_Malloc(size) BZF_MallocNamed(size, __FILE__, __LINE__)
#define ZF_Malloc(size) ZF_MallocNamed(size, __FILE__, __LINE__)
#define BZF_Realloc(ptr, size) BZF_ReallocNamed(ptr, size, __FILE__, __LINE__)
#endif
void *Hunk_Alloc (int size); // returns 0 filled memory

View File

@ -9,6 +9,33 @@
#endif
#include <d3d9.h>
/*
Things to improve:
mmapping:
this code is fairly simple. the caller gives a series of batches/meshes, and this code pushes the data to the gpu in its entirety before moving on to the next batch
for the world, this is fast enough where its pretty much all vboed (except for weird shaders).
but for lightning beams and models etc, we're mmapping new data regions in the dynamic vbo for every single quad.
not just one mmap, but one mmap for every single individual attribute that is submitted
by using a single buffer for all dynamic data, and filling that buffer before flushing anything to the hardware we ought to get higher framerates
especially if this means D3DLOCK_NOOVERWRITE checks etc are not doing weird slow things.
This won't affect the world too much, but should stop everything else destroying the framerate.
long story short, make this batch properly, and use D3DLOCK_DISCARD only.
models:
models should already be in a buffer (with different offsets for different poses). This is a problem with gl too.
hlsl:
we don't really use this as much as we should. Should be possible to use as a fast path to avoid having to do any weird shader/dynamic stuff.
currently used for water(required to mimic software rendering) and sky(because its muuuch faster than a skydome).
hlsl programs ought to have per-hlsl vertex declarations, and only one stream source.
*/
extern LPDIRECT3DDEVICE9 pD3DDev9;
//#define d3dcheck(foo) foo
@ -169,6 +196,17 @@ typedef struct
batch_t *wbatches;
} d3dbackend_t;
typedef struct
{
vecV_t coord;
vec2_t tex;
vec2_t lm;
vec3_t ndir;
vec3_t sdir;
vec3_t tdir;
byte_vec4_t colorsb;
} vbovdata_t;
#define DYNVBUFFSIZE 65536
#define DYNIBUFFSIZE 65536
@ -1052,7 +1090,7 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
(pass->rgbgen == RGB_GEN_ONE_MINUS_VERTEX)) &&
(pass->alphagen == ALPHA_GEN_VERTEX)))
{
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(byte_vec4_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(vbovdata_t)));
}
else
{
@ -1537,9 +1575,9 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
vdec |= D3D_VDEC_ST0<<tmu;
if (shaderstate.batchvbo && pass[passno].tcgen == TC_GEN_BASE && !pass[passno].numtcmods)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vec2_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vbovdata_t)));
else if (shaderstate.batchvbo && pass[passno].tcgen == TC_GEN_LIGHTMAP && !pass[passno].numtcmods)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->lmcoord.d3d.buff, shaderstate.batchvbo->lmcoord.d3d.offs, sizeof(vec2_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.batchvbo->lmcoord[0].d3d.buff, shaderstate.batchvbo->lmcoord[0].d3d.offs, sizeof(vbovdata_t)));
else
{
allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec2_t));
@ -1595,13 +1633,13 @@ static void BE_SubmitMeshChain(int idxfirst)
for (++m; m < shaderstate.nummeshes; m++)
{
mesh = shaderstate.meshlist[m];
/* if (endi == mesh->vbofirstelement)
if (endi == mesh->vbofirstelement)
{
endv = mesh->vbofirstvert+mesh->numvertexes;
endi = mesh->vbofirstelement+mesh->numindexes;
}
else
*/ {
{
break;
}
}
@ -1747,7 +1785,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
if (vdec & D3D_VDEC_COL4B)
{
if (shaderstate.batchvbo)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(byte_vec4_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.batchvbo->colours.d3d.buff, shaderstate.batchvbo->colours.d3d.offs, sizeof(vbovdata_t)));
else
{
int mno,v;
@ -1783,7 +1821,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
if (vdec & D3D_VDEC_ST0)
{
if (shaderstate.batchvbo)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vec2_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.batchvbo->texcoord.d3d.buff, shaderstate.batchvbo->texcoord.d3d.offs, sizeof(vbovdata_t)));
else
{
int mno;
@ -1805,7 +1843,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
if (vdec & D3D_VDEC_ST1)
{
if (shaderstate.batchvbo)
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC1, shaderstate.batchvbo->lmcoord.d3d.buff, shaderstate.batchvbo->lmcoord.d3d.offs, sizeof(vec2_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC1, shaderstate.batchvbo->lmcoord[0].d3d.buff, shaderstate.batchvbo->lmcoord[0].d3d.offs, sizeof(vbovdata_t)));
else
{
int mno;
@ -1829,9 +1867,9 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
{
if (shaderstate.batchvbo)
{
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORM, shaderstate.batchvbo->normals.d3d.buff, shaderstate.batchvbo->normals.d3d.offs, sizeof(vec3_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMS, shaderstate.batchvbo->svector.d3d.buff, shaderstate.batchvbo->svector.d3d.offs, sizeof(vec3_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMT, shaderstate.batchvbo->tvector.d3d.buff, shaderstate.batchvbo->tvector.d3d.offs, sizeof(vec3_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORM, shaderstate.batchvbo->normals.d3d.buff, shaderstate.batchvbo->normals.d3d.offs, sizeof(vbovdata_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMS, shaderstate.batchvbo->svector.d3d.buff, shaderstate.batchvbo->svector.d3d.offs, sizeof(vbovdata_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMT, shaderstate.batchvbo->tvector.d3d.buff, shaderstate.batchvbo->tvector.d3d.offs, sizeof(vbovdata_t)));
}
else
{
@ -1933,7 +1971,7 @@ static void BE_DrawMeshChain_Internal(void)
/*vertex buffers are common to all passes*/
if (shaderstate.batchvbo && !shaderstate.curshader->numdeforms)
{
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, shaderstate.batchvbo->coord.d3d.buff, shaderstate.batchvbo->coord.d3d.offs, sizeof(vecV_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, shaderstate.batchvbo->coord.d3d.buff, shaderstate.batchvbo->coord.d3d.offs, sizeof(vbovdata_t)));
}
else
{
@ -2046,10 +2084,135 @@ void D3DBE_SelectEntity(entity_t *ent)
BE_RotateForEntity(ent, ent->model);
}
#if 1
static void D3DBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch)
{
int maxvboelements;
int maxvboverts;
int vert = 0, idx = 0;
batch_t *batch;
vbo_t *vbo;
int i, j;
mesh_t *m;
IDirect3DVertexBuffer9 *vbuff;
IDirect3DIndexBuffer9 *ebuff;
index_t *vboedata;
vbovdata_t *vbovdata;
vbo = Z_Malloc(sizeof(*vbo));
maxvboverts = 0;
maxvboelements = 0;
for(batch = firstbatch; batch != stopbatch; batch = batch->next)
{
for (i=0 ; i<batch->maxmeshes ; i++)
{
m = batch->mesh[i];
maxvboelements += m->numindexes;
maxvboverts += m->numvertexes;
}
}
IDirect3DDevice9_CreateIndexBuffer(pD3DDev9, sizeof(index_t) * maxvboelements, 0, D3DFMT_QINDEX, D3DPOOL_MANAGED, &ebuff, NULL);
IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, sizeof(*vbovdata) * maxvboverts, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &vbuff, NULL);
vbovdata = NULL;
vbo->coord.d3d.buff = vbuff;
vbo->coord.d3d.offs = (quintptr_t)&vbovdata->coord;
vbo->texcoord.d3d.buff = vbuff;
vbo->texcoord.d3d.offs = (quintptr_t)&vbovdata->tex;
vbo->lmcoord[0].d3d.buff = vbuff;
vbo->lmcoord[0].d3d.offs = (quintptr_t)&vbovdata->lm;
vbo->normals.d3d.buff = vbuff;
vbo->normals.d3d.offs = (quintptr_t)&vbovdata->ndir;
vbo->svector.d3d.buff = vbuff;
vbo->svector.d3d.offs = (quintptr_t)&vbovdata->sdir;
vbo->tvector.d3d.buff = vbuff;
vbo->tvector.d3d.offs = (quintptr_t)&vbovdata->tdir;
vbo->colours.d3d.buff = vbuff;
vbo->colours.d3d.offs = (quintptr_t)&vbovdata->colorsb;
vbo->indicies.d3d.buff = ebuff;
vbo->indicies.d3d.offs = 0;
IDirect3DIndexBuffer9_Lock(ebuff, 0, sizeof(index_t) * maxvboelements, &vboedata, D3DLOCK_DISCARD);
IDirect3DVertexBuffer9_Lock(vbuff, 0, sizeof(*vbovdata) * maxvboverts, &vbovdata, D3DLOCK_DISCARD);
for(batch = firstbatch; batch != stopbatch; batch = batch->next)
{
batch->vbo = vbo;
for (j=0 ; j<batch->maxmeshes ; j++)
{
m = batch->mesh[j];
m->vbofirstvert = vert;
for (i = 0; i < m->numvertexes; i++)
{
VectorCopy(m->xyz_array[i], vbovdata->coord);
vbovdata->coord[3] = 1;
Vector2Copy(m->st_array[i], vbovdata->tex);
Vector2Copy(m->lmst_array[0][i], vbovdata->lm);
VectorCopy(m->normals_array[i], vbovdata->ndir);
VectorCopy(m->snormals_array[i], vbovdata->sdir);
VectorCopy(m->tnormals_array[i], vbovdata->tdir);
Vector4Scale(m->colors4f_array[i], 255, vbovdata->colorsb);
vbovdata++;
}
m->vbofirstelement = idx;
for (i = 0; i < m->numindexes; i++)
{
*vboedata++ = vert + m->indexes[i];
}
idx += m->numindexes;
vert += m->numvertexes;
}
}
IDirect3DIndexBuffer9_Unlock(ebuff);
IDirect3DVertexBuffer9_Unlock(vbuff);
vbo->next = *vbochain;
*vbochain = vbo;
}
void D3DBE_GenBrushModelVBO(model_t *mod)
{
unsigned int vcount;
batch_t *batch, *fbatch;
int sortid;
int i;
fbatch = NULL;
vcount = 0;
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
{
if (!mod->batches[sortid])
continue;
for (fbatch = batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{
//firstmesh got reused as the number of verticies in each batch
if (vcount + batch->firstmesh > MAX_INDICIES)
{
D3DBE_GenBatchVBOs(&mod->vbos, fbatch, batch);
fbatch = batch;
vcount = 0;
}
for (i = 0; i < batch->maxmeshes; i++)
vcount += batch->mesh[i]->numvertexes;
}
D3DBE_GenBatchVBOs(&mod->vbos, fbatch, batch);
}
}
#else
/*Generates an optimised vbo for each of the given model's textures*/
void D3DBE_GenBrushModelVBO(model_t *mod)
{
#if 0
#if 1
unsigned int maxvboverts;
unsigned int maxvboelements;
@ -2101,7 +2264,7 @@ void D3DBE_GenBrushModelVBO(model_t *mod)
maxvboverts += m->numvertexes;
}
#if sizeof_index_t == 2
if (maxvboverts > (1<<(sizeof(index_t)*8))-1)
if (maxvboverts > (1u<<(sizeof(index_t)*8))-1)
continue;
#endif
if (!maxvboverts)
@ -2231,53 +2394,58 @@ void D3DBE_GenBrushModelVBO(model_t *mod)
}
#endif
}
#endif
/*Wipes a vbo*/
void D3DBE_ClearVBO(vbo_t *vbo)
{
IDirect3DVertexBuffer9 *vbuff = vbo->vertdata;
IDirect3DVertexBuffer9 *vbuff = vbo->coord.d3d.buff;
IDirect3DIndexBuffer9 *ebuff = vbo->indicies.d3d.buff;
if (vbuff)
IDirect3DVertexBuffer9_Release(vbuff);
if (ebuff)
IDirect3DIndexBuffer9_Release(ebuff);
vbo->vertdata = NULL;
vbo->coord.d3d.buff = NULL;
vbo->indicies.d3d.buff = NULL;
free(vbo);
}
/*upload all lightmaps at the start to reduce lags*/
void BE_UploadLightmaps(qboolean force)
{
int i;
lightmapinfo_t *lm;
for (i = 0; i < numlightmaps; i++)
{
if (!lightmap[i])
lm = lightmap[i];
if (!lm)
continue;
if (force)
{
lightmap[i]->rectchange.l = 0;
lightmap[i]->rectchange.t = 0;
lightmap[i]->rectchange.w = LMBLOCK_WIDTH;
lightmap[i]->rectchange.h = LMBLOCK_HEIGHT;
lm->rectchange.l = 0;
lm->rectchange.t = 0;
lm->rectchange.w = LMBLOCK_WIDTH;
lm->rectchange.h = LMBLOCK_HEIGHT;
}
if (lightmap[i]->modified)
{
IDirect3DTexture9 *tex = lightmap_textures[i].ptr;
IDirect3DTexture9 *tex = lm->lightmap_texture.ptr;
D3DLOCKED_RECT lock;
RECT rect;
glRect_t *theRect = &lightmap[i]->rectchange;
glRect_t *theRect = &lm->rectchange;
int r;
if (!tex)
{
lightmap_textures[i] = R_AllocNewTexture("***lightmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
tex = lightmap_textures[i].ptr;
lm->lightmap_texture = R_AllocNewTexture("***lightmap***", LMBLOCK_WIDTH, LMBLOCK_HEIGHT);
tex = lm->lightmap_texture.ptr;
if (!tex)
continue;
}
lightmap[i]->modified = 0;
lm->modified = 0;
rect.left = theRect->l;
rect.right = theRect->l + theRect->w;
rect.top = theRect->t;
@ -2445,10 +2613,10 @@ void D3DBE_SubmitBatch(batch_t *batch)
shaderstate.curshader = batch->shader;
shaderstate.curtexnums = batch->skin;
shaderstate.flags = batch->flags;
if (batch->lightmap < 0)
if (batch->lightmap[0] < 0)
shaderstate.curlightmap = r_nulltex;
else
shaderstate.curlightmap = lightmap_textures[batch->lightmap];
shaderstate.curlightmap = lightmap[batch->lightmap[0]]->lightmap_texture;
BE_DrawMeshChain_Internal();
}
@ -2891,7 +3059,7 @@ void D3DBE_DrawWorld (qbyte *vis)
#ifdef RTLIGHTS
RSpeedRemark();
D3DBE_SelectEntity(&r_worldentity);
Sh_DrawLights(vis, batches);
Sh_DrawLights(vis);
RSpeedEnd(RSPEED_STENCILSHADOWS);
#endif

View File

@ -1,4 +1,5 @@
#include "quakedef.h"
#include "winquake.h"
#ifdef D3DQUAKE
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
#define HMONITOR_DECLARED
@ -27,6 +28,8 @@ void D3D_Image_Shutdown(void)
tx = t->tex.ptr;
if (tx)
IDirect3DTexture9_Release(tx);
free(t);
}
}

View File

@ -2,6 +2,7 @@
#ifdef D3DQUAKE
#include "shader.h"
#include "winquake.h"
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
#define HMONITOR_DECLARED
DECLARE_HANDLE(HMONITOR);

View File

@ -1120,6 +1120,7 @@ static void (D3D9_Draw_Init) (void)
}
static void (D3D9_Draw_Shutdown) (void)
{
R2D_Shutdown();
}
static void (D3D9_R_Init) (void)
@ -1202,7 +1203,7 @@ static void (D3D9_R_RenderView) (void)
{
D3D9_SetupViewPort();
if (r_clear.ival && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(255,0,0), 1, 0));
else
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);

View File

@ -25,9 +25,6 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nacl", "..\nacl\nacl.vcproj", "{4735677B-6D5A-4BE6-A945-CB32A7282F56}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}"
ProjectSection(ProjectDependencies) = postProject
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364} = {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -175,7 +172,6 @@ Global
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|Win32.ActiveCfg = Debug
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|x64.ActiveCfg = Debug
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|Win32.ActiveCfg = Release
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|Win32.Build.0 = Release
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|x64.ActiveCfg = Release
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|x64.Build.0 = Release
{E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug Dedicated Server|Win32.ActiveCfg = Debug
@ -236,7 +232,6 @@ Global
{2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|Win32.Build.0 = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|x64.ActiveCfg = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|Win32.ActiveCfg = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|Win32.Build.0 = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|x64.ActiveCfg = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
@ -272,7 +267,6 @@ Global
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|Win32.Build.0 = Debug|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|x64.ActiveCfg = Debug|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|Win32.ActiveCfg = Release|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|Win32.Build.0 = Release|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|x64.ActiveCfg = Release|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
@ -331,40 +325,31 @@ Global
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|x64.ActiveCfg = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DDebug|Win32.Build.0 = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DDebug|x64.ActiveCfg = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|Win32.ActiveCfg = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|Win32.Build.0 = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|x64.ActiveCfg = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32

View File

@ -463,11 +463,11 @@
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
BrowseInformation="1"
BrowseInformationFile="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
CallingConvention="1"
CompileAs="0"
DisableSpecificWarnings="4996"
/>
<Tool
@ -491,6 +491,7 @@
GenerateManifest="false"
IgnoreDefaultLibraryNames="libc.lib;msvcrt.lib"
SubSystem="2"
LargeAddressAware="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
@ -660,7 +661,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include"
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;MULTITHREAD;BOTLIB_STATIC"
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;MULTITHREAD;BOTLIB_STATIC;USE_MSVCRT_DEBUG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableFunctionLevelLinking="true"
@ -1911,6 +1912,7 @@
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="0"
CallingConvention="1"
CompileAs="0"
DisableSpecificWarnings="4996"
/>
@ -23037,6 +23039,194 @@
RelativePath="..\gl\gl_font.c"
>
</File>
<File
RelativePath="..\gl\gl_hlmdl.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_model.c"
>
@ -25504,194 +25694,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_hlmdl.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_rmain.c"
>

View File

@ -1,7 +1,9 @@
package com.fteqw;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLConfig;
//import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
@ -26,6 +28,8 @@ import android.os.Environment;
public class FTEDroidActivity extends Activity
{
private static final int USE_GLES_VERSION = 1; //valid values: 1 or 2. If set to 2, it'll still fall back to 1 if gles2 isn't supported on this device.
private SensorManager sensorman;
private Sensor sensoracc;
private FTEView view;
@ -34,6 +38,7 @@ public class FTEDroidActivity extends Activity
private class FTERenderer implements GLSurfaceView.Renderer
{
private boolean inited;
public int glesversion;
private String basedir, userdir;
FTEDroidActivity act;
@ -51,7 +56,7 @@ public class FTEDroidActivity extends Activity
}
// try
// {
userdir = Environment.getExternalStorageDirectory().getPath();
userdir = Environment.getExternalStorageDirectory().getPath() + "/fte";
// }
// catch(foo)
// {
@ -73,7 +78,7 @@ public class FTEDroidActivity extends Activity
public void onSurfaceChanged(GL10 gl, int width, int height)
{
android.util.Log.i("FTEDroid", "Surface changed, now " + width + " by " + height + ".");
FTEDroidEngine.init(width, height, basedir, userdir);
FTEDroidEngine.init(width, height, glesversion, basedir, userdir);
inited = true;
}
@Override
@ -81,32 +86,94 @@ public class FTEDroidActivity extends Activity
{
}
}
/*
private class FTEEGLConfig implements GLSurfaceView.EGLConfigChooser
{
public void setversion(FTEView view, int version)
{
view.setEGLContextClientVersion(version);
}
public boolean CheckGLES2Support()
{
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
EGLConfig cfg;
int[] version = new int[2];
egl.eglInitialize(display, version);
cfg = chooseConfig(egl, display);
int[] value = {0};
egl.eglGetConfigAttrib(display, cfg, EGL10.EGL_RENDERABLE_TYPE, value);
egl.eglTerminate(display);
return ((value[0] & 4) == 4);
}
@Override
public EGLConfig chooseConfig (javax.microedition.khronos.egl.EGL10 egl, javax.microedition.khronos.egl.EGLDisplay display)
public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display)
{
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
EGLConfig[] cfg = new EGLConfig[1];
EGLConfig[] cfg = new EGLConfig[64];
int[] num_configs = {0};
int[] value = {0};
int i;
int[] attribs =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
egl.EGL_RENDERABLE_TYPE, 4/*egl.EGL_OPENGL_ES2_BIT*/,
// egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
egl.EGL_BLUE_SIZE, 5,
egl.EGL_GREEN_SIZE, 6,
egl.EGL_RED_SIZE, 5,
egl.EGL_DEPTH_SIZE, 16,
egl.EGL_STENCIL_SIZE, 8,
// egl.EGL_STENCIL_SIZE, 8,
egl.EGL_NONE, egl.EGL_NONE
};
egl.eglChooseConfig(display, attribs, cfg, 1, num_configs);
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
throw new IllegalArgumentException("eglChooseConfig failed");
if (num_configs[0] == 0)
{
attribs[1] = 1; //egl.EGL_RENDERABLE_TYPE, 1/*egl.EGL_OPENGL_ES_BIT*/,
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
throw new IllegalArgumentException("eglChooseConfig failed");
if (num_configs[0] == 0)
{
throw new IllegalArgumentException("eglChooseConfig didn't report any valid configs");
}
}
android.util.Log.i("FTEDroid", "Found " + num_configs[0] + " EGL configs.");
for (i = 0; i < num_configs[0]; i++)
{
android.util.Log.i("FTEDroid", "Config " + i + ":");
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RED_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_RED_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_GREEN_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_GREEN_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_BLUE_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_BLUE_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_DEPTH_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_DEPTH_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_STENCIL_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_STENCIL_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RENDERABLE_TYPE, value);
android.util.Log.i("FTEDroid", "EGL_RENDERABLE_TYPE " + value[0]);
if ((value[0] & 4) == 4)
{
android.util.Log.i("FTEDroid", "Found a GLES2 context!");
return cfg[i];
}
}
return cfg[0];
}
}
*/
private class FTEView extends GLSurfaceView implements SensorEventListener
{
private final FTERenderer rndr;
@ -260,7 +327,35 @@ public class FTEDroidActivity extends Activity
inputevent = new FTELegacyInputEvent();
rndr = new FTERenderer(context, context);
// setEGLConfigChooser(new FTEEGLConfig());
if (USE_GLES_VERSION < 2)
{
android.util.Log.i("FTEDroid", "GLES2 disabled at game compile time");
rndr.glesversion = 1;
}
else if (android.os.Build.VERSION.SDK_INT >= 8) //could be 5 with setEGLContextFactory instead of setEGLContextClientVersion
{
FTEEGLConfig cfgchooser = new FTEEGLConfig();
setEGLConfigChooser(cfgchooser);
if (cfgchooser.CheckGLES2Support())
{
android.util.Log.i("FTEDroid", "Support for GLES2 detected");
rndr.glesversion = 2;
cfgchooser.setversion(this, rndr.glesversion);
}
else
{
android.util.Log.i("FTEDroid", "GLES2 not supported. Using GLES1.");
rndr.glesversion = 1;
}
}
else
{
android.util.Log.i("FTEDroid", "GLES2 requires android 2.2+");
rndr.glesversion = 1;
}
setRenderer(rndr);
setFocusable(true);
setFocusableInTouchMode(true);
@ -372,7 +467,7 @@ public class FTEDroidActivity extends Activity
if (runningintheemulator())
{
android.util.Log.i("FTEDroid", "emulator detected - skipping sensors to avoid emulator hangs");
android.util.Log.i("FTEDroid", "emulator detected - skipping sensors to avoid emulator bugs");
sensorman = null;
}
else

View File

@ -2,7 +2,7 @@ package com.fteqw;
public class FTEDroidEngine
{
public static native void init(int w, int h, String apkpath, String usrpath); /* init/reinit */
public static native void init(int w, int h, int gles2, String apkpath, String usrpath); /* init/reinit */
public static native void frame(float ax, float ay, float az);
public static native void keypress(int down, int qkey, int unicode);
public static native void motion(int act, int pointerid, float x, float y);

View File

@ -183,7 +183,8 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
*forcedtex = NULL;
if (e->skinnum >= 100 && e->skinnum < 110)
/*hexen2 feature: global skins */
if (inf->numskins < 100 && e->skinnum >= 100 && e->skinnum < 110)
{
shader_t *s;
s = R_RegisterSkin(va("gfx/skin%d.lmp", e->skinnum), NULL);
@ -224,31 +225,18 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
galiascolourmapped_t *cm;
char hashname[512];
// if (e->scoreboard->skin->cachedbpp
/* if (cls.protocol == CP_QUAKE2)
if (e->scoreboard && e->scoreboard->skin)
{
if (e->scoreboard && e->scoreboard->skin)
snprintf(hashname, sizeof(hashname), "%s$%s$%i", modelname, e->scoreboard->skin->name, surfnum);
else
snprintf(hashname, sizeof(hashname), "%s$%i", modelname, surfnum);
snprintf(hashname, sizeof(hashname), "%s$%s$%i", model->name, e->scoreboard->skin->name, surfnum);
skinname = hashname;
}
else */
else if (surfnum)
{
if (e->scoreboard && e->scoreboard->skin)
{
snprintf(hashname, sizeof(hashname), "%s$%s$%i", model->name, e->scoreboard->skin->name, surfnum);
skinname = hashname;
}
else if (surfnum)
{
snprintf(hashname, sizeof(hashname), "%s$%i", model->name, surfnum);
skinname = hashname;
}
else
skinname = model->name;
snprintf(hashname, sizeof(hashname), "%s$%i", model->name, surfnum);
skinname = hashname;
}
else
skinname = model->name;
if (!skincolourmapped.numbuckets)
{
@ -291,6 +279,8 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
if (cm->tcolour == tc && cm->bcolour == bc && cm->skinnum == e->skinnum && cm->subframe == subframe && cm->pclass == pc)
{
*forcedtex = &cm->texnum;
if (!shader)
shader = R_RegisterSkin(skinname, NULL);
return shader;
}
}
@ -706,7 +696,7 @@ static void R_DrawShadowVolume(mesh_t *mesh)
#endif
//true if no shading is to be used.
static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
{
vec3_t lightdir;
int i;
@ -1017,7 +1007,10 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
b->skin = skin;
b->texture = NULL;
b->shader = shader;
b->lightmap = -1;
b->lightmap[0] = -1;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->surf_first = surfnum;
b->flags = 0;
sort = shader->sort;
@ -1570,7 +1563,6 @@ static void R_DB_LightningBeam(batch_t *batch)
mesh.indexes = indexarray;
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
mesh.colors4f_array = (vec4_t*)colors;
mesh.lmst_array = NULL;
mesh.normals_array = NULL;
mesh.numvertexes = 4;
mesh.st_array = texcoords;
@ -1641,11 +1633,9 @@ static void R_DB_RailgunBeam(batch_t *batch)
mesh.indexes = indexarray;
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
mesh.colors4f_array = (vec4_t*)colors;
mesh.lmst_array = NULL;
mesh.normals_array = NULL;
mesh.numvertexes = 4;
mesh.st_array = texcoords;
}
#endif
static void R_DB_Sprite(batch_t *batch)
@ -1746,12 +1736,21 @@ static void R_DB_Sprite(batch_t *batch)
spraxis[1][1]*=e->scale;
spraxis[1][2]*=e->scale;
if (e->shaderRGBAf[0] > 1)
if (e->shaderRGBAf[0] != 0 || e->shaderRGBAf[1] != 0 || e->shaderRGBAf[2] != 0 || (batch->flags & BEF_FORCECOLOURMOD))
{
if (e->shaderRGBAf[0] > 1)
e->shaderRGBAf[0] = 1;
if (e->shaderRGBAf[1] > 1)
e->shaderRGBAf[1] = 1;
if (e->shaderRGBAf[2] > 1)
e->shaderRGBAf[2] = 1;
}
else
{
e->shaderRGBAf[0] = 1;
if (e->shaderRGBAf[1] > 1)
e->shaderRGBAf[1] = 1;
if (e->shaderRGBAf[2] > 1)
e->shaderRGBAf[2] = 1;
}
Vector4Copy(e->shaderRGBAf, colours[0]);
Vector4Copy(e->shaderRGBAf, colours[1]);
@ -1780,7 +1779,6 @@ static void R_DB_Sprite(batch_t *batch)
mesh.indexes = indexes;
mesh.numindexes = sizeof(indexes)/sizeof(indexes[0]);
mesh.colors4f_array = colours;
mesh.lmst_array = NULL;
mesh.normals_array = NULL;
mesh.numvertexes = 4;
mesh.st_array = texcoords;
@ -1851,7 +1849,10 @@ static void R_Sprite_GenerateBatch(entity_t *e, batch_t **batches, void (*drawfu
b->skin = &shader->defaulttextures;
b->texture = NULL;
b->shader = shader;
b->lightmap = -1;
b->lightmap[0] = -1;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->surf_first = 0;
b->flags |= BEF_NODLIGHT|BEF_NOSHADOWS;
b->vbo = NULL;
@ -1899,7 +1900,10 @@ void BE_GenPolyBatches(batch_t **batches)
b->skin = &shader->defaulttextures;
b->texture = NULL;
b->shader = shader;
b->lightmap = -1;
b->lightmap[0] = -1;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->surf_first = i;
b->flags = BEF_NODLIGHT|BEF_NOSHADOWS;
b->vbo = 0;
@ -1907,6 +1911,7 @@ void BE_GenPolyBatches(batch_t **batches)
batches[shader->sort] = b;
}
}
void R_HalfLife_GenerateBatches(entity_t *e, batch_t **batches);
void BE_GenModelBatches(batch_t **batches)
{
@ -1975,9 +1980,13 @@ void BE_GenModelBatches(batch_t **batches)
case mod_sprite:
R_Sprite_GenerateBatch(ent, batches, R_DB_Sprite);
break;
case mod_halflife:
#ifdef HALFLIFEMODELS
R_HalfLife_GenerateBatches(ent, batches);
#endif
break;
// warning: enumeration value mod_* not handled in switch
case mod_dummy:
case mod_halflife:
case mod_heightmap:
break;
}

View File

@ -5,6 +5,8 @@
#ifdef GLQUAKE
#define r_refract_fboival 0
#include "glquake.h"
#include "shader.h"
#ifdef _WIN32
@ -141,6 +143,7 @@ struct {
int currentprogram;
int lastuniform; /*program which was last set, so using the same prog for multiple surfaces on the same ent (ie: world) does not require lots of extra uniform chnges*/
batch_t dummybatch;
vbo_t dummyvbo;
int colourarraytype;
int currentvbo;
@ -183,9 +186,8 @@ struct {
vbo_t *sourcevbo;
const shader_t *curshader;
const entity_t *curentity;
const batch_t *curbatch;
const texnums_t *curtexnums;
texid_t curlightmap;
texid_t curdeluxmap;
float curtime;
float updatetime;
@ -237,7 +239,7 @@ static void BE_PolyOffset(qboolean pushdepth)
else
{
#ifndef FORCESTATE
if (*(int*)&shaderstate.curpolyoffset != *(int*)&shaderstate.curshader->polyoffset || *(int*)&shaderstate.curpolyoffset != *(int*)&shaderstate.curshader->polyoffset)
if (*(int*)&shaderstate.curpolyoffset.factor != *(int*)&shaderstate.curshader->polyoffset.factor || *(int*)&shaderstate.curpolyoffset.unit != *(int*)&shaderstate.curshader->polyoffset.unit)
#endif
{
shaderstate.curpolyoffset = shaderstate.curshader->polyoffset;
@ -350,6 +352,14 @@ void GL_SetShaderState2D(qboolean is2d)
if (is2d)
memcpy(shaderstate.modelviewmatrix, r_refdef.m_view, sizeof(shaderstate.modelviewmatrix));
BE_SelectMode(BEM_STANDARD);
if (cl.paused || cls.state < ca_active)
shaderstate.updatetime = r_refdef.time;
else
shaderstate.updatetime = cl.servertime;
BE_SelectEntity(&r_worldentity);
shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime;
}
void GL_SelectTexture(int target)
@ -371,14 +381,18 @@ void GL_SelectVBO(int vbo)
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, shaderstate.currentvbo);
}
}
void GL_SelectEBO(int vbo)
void GL_DeselectVAO(void)
{
//EBO is part of the current VAO, so keep things matching that
if (shaderstate.currentvao)
{
qglBindVertexArray(0);
shaderstate.currentvao = 0;
}
}
void GL_SelectEBO(int vbo)
{
//EBO is part of the current VAO, so keep things matching that
GL_DeselectVAO();
#ifndef FORCESTATE
if (shaderstate.currentebo != vbo)
@ -570,8 +584,20 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
qglVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->texcoord.gl.addr);
break;
case VATTR_LMCOORD:
GL_SelectVBO(shaderstate.sourcevbo->lmcoord.gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord.gl.addr);
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[0].gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[0].gl.addr);
break;
case VATTR_LMCOORD2:
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[1].gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD2, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[1].gl.addr);
break;
case VATTR_LMCOORD3:
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[2].gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD3, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[2].gl.addr);
break;
case VATTR_LMCOORD4:
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[3].gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD4, 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord[3].gl.addr);
break;
case VATTR_NORMALS:
if (!shaderstate.sourcevbo->normals.gl.addr)
@ -661,6 +687,9 @@ void GLBE_SetupVAO(vbo_t *vbo, unsigned vaodynamic)
(1u<<(gl_config.nofixedfunc?VATTR_VERTEX1:VATTR_LEG_VERTEX))|
(1u<<VATTR_TEXCOORD)|
(1u<<VATTR_LMCOORD)|
(1u<<VATTR_LMCOORD2)|
(1u<<VATTR_LMCOORD3)|
(1u<<VATTR_LMCOORD4)|
(1u<<VATTR_COLOUR)|
(1u<<VATTR_NORMALS)|
(1u<<VATTR_SNORMALS)|
@ -712,10 +741,8 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
if (gl_config.nofixedfunc)
{
//shaderstate.sourcevbo = &shaderstate.dummyvbo;
GL_SelectProgram(shaderstate.allblackshader);
qglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), verts);
qglVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(vecV_t), verts);
BE_EnableShaderAttributes(gl_config.nofixedfunc?(1u<<VATTR_VERTEX1):(1u<<VATTR_LEG_VERTEX));
{
@ -729,7 +756,6 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
}
else
{
GL_SelectEBO(shaderstate.dummyvbo.indicies.gl.vbo);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX));
//draw cached world shadow mesh
@ -935,6 +961,8 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
{
extern texid_t missing_texture;
extern texid_t scenepp_postproc_cube;
extern texid_t r_whiteimage;
texid_t t;
switch(pass->texgen)
{
@ -946,10 +974,16 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
t = pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes];
break;
case T_GEN_LIGHTMAP:
t = shaderstate.curlightmap;
if (shaderstate.curbatch->lightmap[0] < 0)
t = r_whiteimage;
else
t = lightmap[shaderstate.curbatch->lightmap[0]]->lightmap_texture;
break;
case T_GEN_DELUXMAP:
t = shaderstate.curdeluxmap;
if (shaderstate.curbatch->lightmap[0] < 0)
t = r_nulltex; //fixme
else
t = lightmap[shaderstate.curbatch->lightmap[0]]->deluxmap_texture;
break;
case T_GEN_DIFFUSE:
if (shaderstate.curtexnums && TEXVALID(shaderstate.curtexnums->base))
@ -1015,6 +1049,11 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
t = shaderstate.tex_reflection;
break;
case T_GEN_REFRACTION:
if (!r_refract_fboival)
{
T_Gen_CurrentRender(tmu);
return;
}
t = shaderstate.tex_refraction;
break;
case T_GEN_RIPPLEMAP:
@ -1153,11 +1192,20 @@ void GenerateFogTexture(texid_t *tex, float density, float zscale)
R_Upload(*tex, "fog", TF_RGBA32, fogdata, NULL, FOGS, FOGT, IF_CLAMP|IF_NOMIPMAP);
}
void GLBE_Shutdown(void)
{
BZ_Free(shaderstate.wbatches);
shaderstate.wbatches = NULL;
shaderstate.maxwbatches = 0;
}
void GLBE_Init(void)
{
int i;
double t;
GLBE_Shutdown();
memset(&shaderstate, 0, sizeof(shaderstate));
shaderstate.curentity = &r_worldentity;
@ -1187,6 +1235,8 @@ void GLBE_Init(void)
}
shaderstate.identitylighting = 1;
for (i = 0; i < MAXLIGHTMAPS; i++)
shaderstate.dummybatch.lightmap[i] = -1;
/*normally we load these lazily, but if they're probably going to be used anyway, load them now to avoid stalls.*/
if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_rtlight && gl_config.arb_shader_objects)
@ -2123,10 +2173,9 @@ static void GenerateColourMods(const shaderpass_t *pass)
}
}
static void BE_GeneratePassTC(const shaderpass_t *pass, int passno)
static void BE_GeneratePassTC(const shaderpass_t *pass, int tmu)
{
pass += passno;
qglClientActiveTextureARB(mtexid0 + passno);
qglClientActiveTextureARB(mtexid0 + tmu);
if (!pass->numtcmods)
{
//if there are no tcmods, pass through here as fast as possible
@ -2137,15 +2186,15 @@ static void BE_GeneratePassTC(const shaderpass_t *pass, int passno)
}
else if (pass->tcgen == TC_GEN_LIGHTMAP)
{
if (!shaderstate.sourcevbo->lmcoord.gl.addr)
if (!shaderstate.sourcevbo->lmcoord[0].gl.addr)
{
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord.gl.addr);
}
else
{
GL_SelectVBO(shaderstate.sourcevbo->lmcoord.gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->lmcoord.gl.addr);
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[0].gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->lmcoord[0].gl.addr);
}
}
else if (pass->tcgen == TC_GEN_NORMAL)
@ -2166,12 +2215,12 @@ static void BE_GeneratePassTC(const shaderpass_t *pass, int passno)
else
{
//specular highlights and reflections have no fixed data, and must be generated.
GenerateTCMods(pass, passno);
GenerateTCMods(pass, tmu);
}
}
else
{
GenerateTCMods(pass, passno);
GenerateTCMods(pass, tmu);
}
}
@ -2180,11 +2229,11 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
unsigned int delta;
/*2d mode doesn't depth test or depth write*/
if (shaderstate.force2d)
{
#ifdef warningmsg
#pragma warningmsg("fixme: q3 doesn't seem to have this, why do we need it?")
#endif
if (shaderstate.force2d)
{
sbits &= ~(SBITS_MISC_DEPTHWRITE|SBITS_MISC_DEPTHEQUALONLY);
sbits |= SBITS_MISC_NODEPTHTEST;
}
@ -2239,17 +2288,17 @@ static void BE_SendPassBlendDepthMask(unsigned int sbits)
case SBITS_SRCBLEND_ONE_MINUS_DST_ALPHA: src = GL_ONE_MINUS_DST_ALPHA; break;
case SBITS_SRCBLEND_ALPHA_SATURATE: src = GL_SRC_ALPHA_SATURATE; break;
}
switch(sbits & SBITS_DSTBLEND_BITS)
switch((sbits & SBITS_DSTBLEND_BITS)>>4)
{
case SBITS_DSTBLEND_ZERO: dst = GL_ZERO; break;
case SBITS_DSTBLEND_ZERO>>4: dst = GL_ZERO; break;
default:
case SBITS_DSTBLEND_ONE: dst = GL_ONE; break;
case SBITS_DSTBLEND_SRC_COLOR: dst = GL_SRC_COLOR; break;
case SBITS_DSTBLEND_ONE_MINUS_SRC_COLOR: dst = GL_ONE_MINUS_SRC_COLOR; break;
case SBITS_DSTBLEND_SRC_ALPHA: dst = GL_SRC_ALPHA; break;
case SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA: dst = GL_ONE_MINUS_SRC_ALPHA; break;
case SBITS_DSTBLEND_DST_ALPHA: dst = GL_DST_ALPHA; break;
case SBITS_DSTBLEND_ONE_MINUS_DST_ALPHA: dst = GL_ONE_MINUS_DST_ALPHA; break;
case SBITS_DSTBLEND_ONE>>4: dst = GL_ONE; break;
case SBITS_DSTBLEND_SRC_COLOR>>4: dst = GL_SRC_COLOR; break;
case SBITS_DSTBLEND_ONE_MINUS_SRC_COLOR>>4: dst = GL_ONE_MINUS_SRC_COLOR; break;
case SBITS_DSTBLEND_SRC_ALPHA>>4: dst = GL_SRC_ALPHA; break;
case SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA>>4: dst = GL_ONE_MINUS_SRC_ALPHA; break;
case SBITS_DSTBLEND_DST_ALPHA>>4: dst = GL_DST_ALPHA; break;
case SBITS_DSTBLEND_ONE_MINUS_DST_ALPHA>>4: dst = GL_ONE_MINUS_DST_ALPHA; break;
}
qglEnable(GL_BLEND);
qglBlendFunc(src, dst);
@ -2438,7 +2487,8 @@ static void BE_SubmitMeshChain(void)
static void DrawPass(const shaderpass_t *pass)
{
int i;
extern cvar_t temp1;
int i, j, k;
int tmu;
int lastpass = pass->numMergedPasses;
unsigned int attr = (1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR);
@ -2469,12 +2519,84 @@ static void DrawPass(const shaderpass_t *pass)
Shader_BindTextureForPass(tmu, pass+i);
attr |= (1u<<(VATTR_LEG_TMU0+tmu));
BE_GeneratePassTC(pass, i);
BE_GeneratePassTC(pass+i, tmu);
BE_SetPassBlendMode(tmu, pass[i].blendmode);
tmu++;
//add in
if (pass[i].texgen == T_GEN_LIGHTMAP)
{
//first pass should have been REPLACE
//second pass should be an ADD
//this depends upon rgbgens for light levels, so each pass *must* be pushed to hardware individually
for (j = 1; j < MAXLIGHTMAPS && shaderstate.curbatch->lightmap[j] >= 0; j++)
{
if (j == 1)
BE_SetPassBlendMode(tmu, PBM_REPLACE);
/*make sure no textures linger*/
for (k = tmu; k < shaderstate.lastpasstmus; k++)
{
GL_LazyBind(k, 0, r_nulltex);
}
shaderstate.lastpasstmus = tmu;
/*push it*/
BE_EnableShaderAttributes(attr);
BE_SubmitMeshChain();
tmu = 0;
/*bind the light texture*/
GL_LazyBind(tmu, GL_TEXTURE_2D, lightmap[shaderstate.curbatch->lightmap[j]]->lightmap_texture);
/*set up the colourmod for this style's lighting*/
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
shaderstate.pendingcolourflat[0] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f;
shaderstate.pendingcolourflat[1] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f;
shaderstate.pendingcolourflat[2] = shaderstate.identitylighting * d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f;
shaderstate.pendingcolourflat[3] = 1;
/*pick the correct st coords for this lightmap pass*/
qglClientActiveTextureARB(mtexid0 + tmu);
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[j].gl.vbo);
qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->lmcoord[j].gl.addr);
BE_SetPassBlendMode(tmu, PBM_ADD);
BE_SendPassBlendDepthMask((pass[0].shaderbits & ~SBITS_BLEND_BITS) | SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE);
attr = (1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR);
attr |= (1u<<(VATTR_LEG_TMU0+tmu));
tmu++;
}
//might need to break the pass here
if (j > 1 && i != lastpass)
{
for (k = tmu; k < shaderstate.lastpasstmus; k++)
{
GL_LazyBind(k, 0, r_nulltex);
}
shaderstate.lastpasstmus = tmu;
BE_EnableShaderAttributes(attr);
BE_SubmitMeshChain();
tmu = 0;
BE_SendPassBlendDepthMask(pass[i+1].shaderbits);
GenerateColourMods(&pass[i+1]);
}
}
}
if (!tmu)
return;
for (i = tmu; i < shaderstate.lastpasstmus; i++)
{
GL_LazyBind(i, 0, r_nulltex);
@ -2550,22 +2672,40 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
break;
case SP_E_LMSCALE:
if (perm & PERMUTATION_LIGHTSTYLES)
{
vec4_t colscale;
vec4_t colscale[MAXLIGHTMAPS];
int j;
for (j = 0; j < MAXLIGHTMAPS ; j++)
{
if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
{
float sc = (1<<bound(0, gl_overbright.ival, 2)) * shaderstate.identitylighting;
VectorSet(colscale[j], sc, sc, sc);
}
else
{
VectorSet(colscale[j], shaderstate.identitylighting, shaderstate.identitylighting, shaderstate.identitylighting);
}
colscale[j][3] = 1;
VectorScale(colscale[j], d_lightstylevalue[shaderstate.curbatch->lightstyle[j]]/256.0f, colscale[j]);
}
qglUniform4fvARB(p->handle[perm], j, (GLfloat*)colscale);
}
else
{
vec4_t colscale[4];
if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
{
float sc = (1<<bound(0, gl_overbright.ival, 2)) * shaderstate.identitylighting;
VectorScale(shaderstate.curentity->shaderRGBAf, sc, colscale);
VectorSet(colscale[0], sc, sc, sc);
}
else if (shaderstate.identitylighting == 1)
{
VectorCopy(shaderstate.curentity->shaderRGBAf, colscale);
}
else
{
VectorScale(shaderstate.curentity->shaderRGBAf, shaderstate.identitylighting, colscale);
VectorSet(colscale[0], shaderstate.identitylighting, shaderstate.identitylighting, shaderstate.identitylighting);
}
colscale[3] = shaderstate.curentity->shaderRGBAf[3];
colscale[0][3] = 1;
qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)colscale);
}
@ -2759,6 +2899,8 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
perm |= PERMUTATION_FOG;
if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET].glsl)
perm |= PERMUTATION_OFFSET;
if (shaderstate.curbatch->lightmap[1] >= 0 && p->handle[perm|PERMUTATION_LIGHTSTYLES].glsl)
perm |= PERMUTATION_LIGHTSTYLES;
if (shaderstate.currentvao != shaderstate.sourcevbo->vao)
{
@ -2783,12 +2925,28 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
{
Shader_BindTextureForPass(i, pass+i);
}
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
if (perm & PERMUTATION_LIGHTSTYLES)
{
GL_LazyBind(i, 0, r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[1] >= 0?lightmap[shaderstate.curbatch->lightmap[1]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[2] >= 0?lightmap[shaderstate.curbatch->lightmap[2]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[3] >= 0?lightmap[shaderstate.curbatch->lightmap[3]]->lightmap_texture:r_nulltex);
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
{
GL_LazyBind(i, 0, r_nulltex);
}
shaderstate.lastpasstmus = pass->numMergedPasses+3;
}
else
{
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
{
GL_LazyBind(i, 0, r_nulltex);
}
shaderstate.lastpasstmus = pass->numMergedPasses;
}
shaderstate.lastpasstmus = pass->numMergedPasses;
}
else
{
@ -2796,7 +2954,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
for (i = 0; i < pass->numMergedPasses; i++)
{
Shader_BindTextureForPass(i, pass+i);
BE_GeneratePassTC(pass, i);
BE_GeneratePassTC(pass+i, i);
}
for (; i < shaderstate.lastpasstmus; i++)
{
@ -2869,7 +3027,7 @@ void GLBE_SelectMode(backendmode_t mode)
/*BEM_STENCIL doesn't support mesh writing*/
BE_PushOffsetShadow(false);
if (!shaderstate.allblackshader)
if (gl_config.nofixedfunc && !shaderstate.allblackshader)
{
char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config.gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false);
@ -2993,6 +3151,7 @@ void GLBE_SelectEntity(entity_t *ent)
}
shaderstate.lastuniform = 0;
shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime;
}
void BE_SelectFog(vec3_t colour, float alpha, float density)
@ -3047,44 +3206,34 @@ void GLBE_SelectDLight(dlight_t *dl, vec3_t colour)
void BE_PushOffsetShadow(qboolean pushdepth)
{
extern cvar_t r_polygonoffset_stencil_offset, r_polygonoffset_stencil_factor;
polyoffset_t po;
if (pushdepth)
{
/*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc
we move them back very slightly using polygonoffset to avoid really ugly z-fighting*/
extern cvar_t r_polygonoffset_submodel_offset, r_polygonoffset_submodel_factor;
polyoffset_t po;
po.factor = r_polygonoffset_submodel_factor.value;
po.unit = r_polygonoffset_submodel_offset.value;
#ifndef FORCESTATE
if (((int*)&shaderstate.curpolyoffset)[0] != ((int*)&po)[0] || ((int*)&shaderstate.curpolyoffset)[1] != ((int*)&po)[1])
#endif
{
shaderstate.curpolyoffset = po;
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
{
qglEnable(GL_POLYGON_OFFSET_FILL);
qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
}
else
qglDisable(GL_POLYGON_OFFSET_FILL);
}
po.factor = r_polygonoffset_submodel_factor.value + r_polygonoffset_stencil_factor.value;
po.unit = r_polygonoffset_submodel_offset.value + r_polygonoffset_stencil_offset.value;
}
else
{
po.factor = r_polygonoffset_stencil_factor.value;
po.unit = r_polygonoffset_stencil_offset.value;
}
#ifndef FORCESTATE
if (*(int*)&shaderstate.curpolyoffset != 0 || *(int*)&shaderstate.curpolyoffset != 0)
if (((int*)&shaderstate.curpolyoffset)[0] != ((int*)&po)[0] || ((int*)&shaderstate.curpolyoffset)[1] != ((int*)&po)[1])
#endif
{
shaderstate.curpolyoffset = po;
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
{
shaderstate.curpolyoffset = shaderstate.curshader->polyoffset;
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
{
qglEnable(GL_POLYGON_OFFSET_FILL);
qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
}
else
qglDisable(GL_POLYGON_OFFSET_FILL);
qglEnable(GL_POLYGON_OFFSET_FILL);
qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
}
else
qglDisable(GL_POLYGON_OFFSET_FILL);
}
}
@ -3189,7 +3338,7 @@ static void BE_LegacyLighting(void)
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = coloursarray;
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
GL_DeselectVAO();
GL_DeSelectProgram();
BE_EnableShaderAttributes(attr);
@ -3286,19 +3435,20 @@ static void DrawMeshes(void)
BE_RenderMeshProgram(shaderstate.crepopaqueshader, shaderstate.crepopaqueshader->passes);
break;
case BEM_DEPTHONLY:
GL_DeselectVAO();
GL_DeSelectProgram();
#ifdef warningmsg
#pragma warningmsg("fixme: support alpha test")
#endif
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX));
BE_SubmitMeshChain();
break;
case BEM_FOG:
GL_DeselectVAO();
GL_DeSelectProgram();
GenerateTCFog(0);
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX));
BE_SubmitMeshChain();
break;
@ -3307,7 +3457,7 @@ static void DrawMeshes(void)
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright) && !gl_config.nofixedfunc)
{
//FIXME: do this with a shader instead? its not urgent as we can draw the shader normally anyway, just faster.
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
GL_DeselectVAO();
GL_DeSelectProgram();
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
@ -3334,7 +3484,7 @@ static void DrawMeshes(void)
break;
else
{
GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo);
GL_DeselectVAO();
GL_DeSelectProgram();
while (passno < shaderstate.curshader->numpasses)
{
@ -3352,6 +3502,7 @@ static void DrawMeshes(void)
void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_t *vbo, texnums_t *texnums, unsigned int beflags)
{
shaderstate.curbatch = &shaderstate.dummybatch;
if (!vbo)
{
mesh_t *m;
@ -3361,11 +3512,8 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_
if (shaderstate.curentity != &r_worldentity)
{
BE_SelectEntity(&r_worldentity);
shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime;
}
shaderstate.curtexnums = texnums;
shaderstate.curlightmap = r_nulltex;
shaderstate.curdeluxmap = r_nulltex;
while (nummeshes--)
{
@ -3407,11 +3555,8 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_
if (shaderstate.curentity != &r_worldentity)
{
BE_SelectEntity(&r_worldentity);
shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime;
}
shaderstate.curtexnums = texnums;
shaderstate.curlightmap = r_nulltex;
shaderstate.curdeluxmap = r_nulltex;
shaderstate.meshcount = nummeshes;
shaderstate.meshes = meshlist;
@ -3428,18 +3573,18 @@ void GLBE_SubmitBatch(batch_t *batch)
{
int lm;
shaderstate.curbatch = batch;
if (batch->vbo)
{
shaderstate.sourcevbo = batch->vbo;
shaderstate.colourarraytype = GL_FLOAT;
lm = batch->lightmap;
}
else
{
shaderstate.dummyvbo.coord.gl.addr = batch->mesh[0]->xyz_array;
shaderstate.dummyvbo.coord2.gl.addr = batch->mesh[0]->xyz2_array;
shaderstate.dummyvbo.texcoord.gl.addr = batch->mesh[0]->st_array;
shaderstate.dummyvbo.lmcoord.gl.addr = batch->mesh[0]->lmst_array;
shaderstate.dummyvbo.lmcoord[0].gl.addr = batch->mesh[0]->lmst_array[0];
shaderstate.dummyvbo.indicies.gl.addr = batch->mesh[0]->indexes;
shaderstate.dummyvbo.normals.gl.addr = batch->mesh[0]->normals_array;
shaderstate.dummyvbo.svector.gl.addr = batch->mesh[0]->snormals_array;
@ -3462,25 +3607,11 @@ void GLBE_SubmitBatch(batch_t *batch)
lm = -1;
}
if (lm < 0)
{
extern texid_t r_whiteimage;
/*FIXME: this doesn't compensate for overbrighting*/
shaderstate.curlightmap = r_whiteimage;
shaderstate.curdeluxmap = r_nulltex;
}
else
{
shaderstate.curlightmap = lightmap_textures[lm];
shaderstate.curdeluxmap = deluxmap_textures[lm];
}
shaderstate.curshader = batch->shader;
shaderstate.flags = batch->flags;
if (shaderstate.curentity != batch->ent)
{
BE_SelectEntity(batch->ent);
shaderstate.curtime = r_refdef.time - shaderstate.curentity->shaderTime;
}
if (batch->skin)
shaderstate.curtexnums = batch->skin;
@ -3550,6 +3681,7 @@ static void GLBE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
GL_ForceDepthWritable();
qglClear(GL_DEPTH_BUFFER_BIT);
currententity = &r_worldentity;
shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime;
}
}
}
@ -3598,7 +3730,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
{
//these flags require rendering some view as an fbo
if (r_refdef.recurse)
return;
continue;
if (batch->shader->flags & SHADER_HASREFLECT)
{
@ -3616,32 +3748,39 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_reflection, true);
qglViewport (0, 0, vid.pixelwidth/2, vid.pixelheight/2);
GL_ForceDepthWritable();
qglClear(GL_DEPTH_BUFFER_BIT);
qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, 1);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
}
if (batch->shader->flags & SHADER_HASREFRACT)
{
if (!shaderstate.tex_refraction.num)
if (r_refract_fboival)
{
shaderstate.tex_refraction = GL_AllocNewTexture("***tex_refraction***", vid.pixelwidth/2, vid.pixelheight/2);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refraction);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GL_ForceDepthWritable();
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, true);
qglViewport (0, 0, vid.pixelwidth/2, vid.pixelheight/2);
GL_ForceDepthWritable();
qglClear(GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, 2);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
if (!shaderstate.tex_refraction.num)
{
shaderstate.tex_refraction = GL_AllocNewTexture("***tex_refraction***", vid.pixelwidth/2, vid.pixelheight/2);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refraction);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GL_ForceDepthWritable();
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, true);
qglViewport (0, 0, vid.pixelwidth/2, vid.pixelheight/2);
GL_ForceDepthWritable();
qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, 2);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
}
else
GLR_DrawPortal(batch, cl.worldmodel->batches, 2);
}
if (batch->shader->flags & SHADER_HASRIPPLEMAP)
{
@ -3695,33 +3834,35 @@ void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop)
static void BE_UpdateLightmaps(void)
{
int lm;
for (lm = 0; lm < numlightmaps; lm++)
lightmapinfo_t *lm;
int lmidx;
for (lmidx = 0; lmidx < numlightmaps; lmidx++)
{
if (!lightmap[lm])
if (!lightmap[lmidx])
continue;
if (lightmap[lm]->modified)
lm = lightmap[lmidx];
if (lm->modified)
{
glRect_t *theRect;
lightmap[lm]->modified = false;
theRect = &lightmap[lm]->rectchange;
GL_MTBind(0, GL_TEXTURE_2D, lightmap_textures[lm]);
lm->modified = false;
theRect = &lm->rectchange;
GL_MTBind(0, GL_TEXTURE_2D, lm->lightmap_texture);
switch (lightmap_bytes)
{
case 4:
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, (lightmap_bgra?GL_BGRA_EXT:GL_RGBA), GL_UNSIGNED_INT_8_8_8_8_REV,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*4);
lm->lightmaps+(theRect->t) *LMBLOCK_WIDTH*4);
break;
case 3:
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*3);
lm->lightmaps+(theRect->t) *LMBLOCK_WIDTH*3);
break;
case 1:
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, GL_LUMINANCE, GL_UNSIGNED_BYTE,
lightmap[lm]->lightmaps+(theRect->t) *LMBLOCK_WIDTH);
lm->lightmaps+(theRect->t) *LMBLOCK_WIDTH);
break;
}
theRect->l = LMBLOCK_WIDTH;
@ -3729,14 +3870,14 @@ static void BE_UpdateLightmaps(void)
theRect->h = 0;
theRect->w = 0;
if (lightmap[lm]->deluxmodified)
if (lm->deluxmodified)
{
lightmap[lm]->deluxmodified = false;
theRect = &lightmap[lm]->deluxrectchange;
GL_MTBind(0, GL_TEXTURE_2D, deluxmap_textures[lm]);
lm->deluxmodified = false;
theRect = &lm->deluxrectchange;
GL_MTBind(0, GL_TEXTURE_2D, lm->deluxmap_texture);
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, GL_RGB, GL_UNSIGNED_BYTE,
lightmap[lm]->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3);
lm->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3);
theRect->l = LMBLOCK_WIDTH;
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
@ -4002,7 +4143,10 @@ void GLBE_DrawWorld (qbyte *vis)
BE_GenModelBatches(batches);
R_GenDlightBatches(batches);
shaderstate.curentity = &r_worldentity;
shaderstate.updatetime = cl.servertime;
if (cl.paused || cls.state < ca_active)
shaderstate.updatetime = r_refdef.time;
else
shaderstate.updatetime = cl.servertime;
BE_SelectEntity(&r_worldentity);

View File

@ -498,6 +498,8 @@ void GLDraw_DeInit (void)
{
Cmd_RemoveCommand ("r_imagelist");
R2D_Shutdown();
if (font_conchar)
Font_Free(font_conchar);
font_conchar = NULL;

View File

@ -315,7 +315,10 @@ void GL_DrawHeightmapModel (batch_t **batches, entity_t *e)
b = BE_GetTempBatch();
if (b)
{
b->lightmap = -1;
b->lightmap[0] = -1;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->ent = e;
b->shader = hm->skyshader;
b->flags = 0;
@ -370,7 +373,7 @@ void GL_DrawHeightmapModel (batch_t **batches, entity_t *e)
{
mesh->xyz_array = BZ_Malloc((sizeof(vecV_t)+sizeof(vec2_t)+sizeof(vec2_t)) * (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE));
mesh->st_array = (void*) (mesh->xyz_array + (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE));
mesh->lmst_array = (void*) (mesh->st_array + (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE));
mesh->lmst_array[0] = (void*) (mesh->st_array + (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE));
}
mesh->numvertexes = 0;
/*64 quads across requires 65 verticies*/
@ -392,14 +395,14 @@ void GL_DrawHeightmapModel (batch_t **batches, entity_t *e)
mesh->st_array[v][1] = mesh->xyz_array[v][1] / 64;
//calc the position in the range -0.5 to 0.5
mesh->lmst_array[v][0] = (((float)vx / (SECTHEIGHTSIZE-1))-0.5);
mesh->lmst_array[v][1] = (((float)vy / (SECTHEIGHTSIZE-1))-0.5);
mesh->lmst_array[0][v][0] = (((float)vx / (SECTHEIGHTSIZE-1))-0.5);
mesh->lmst_array[0][v][1] = (((float)vy / (SECTHEIGHTSIZE-1))-0.5);
//scale down to a half-texel
mesh->lmst_array[v][0] *= (SECTTEXSIZE-1.0f)/LMBLOCK_WIDTH;
mesh->lmst_array[v][1] *= (SECTTEXSIZE-1.0f)/LMBLOCK_HEIGHT;
mesh->lmst_array[0][v][0] *= (SECTTEXSIZE-1.0f)/LMBLOCK_WIDTH;
mesh->lmst_array[0][v][1] *= (SECTTEXSIZE-1.0f)/LMBLOCK_HEIGHT;
//bias it
mesh->lmst_array[v][0] += ((float)SECTTEXSIZE/(LMBLOCK_WIDTH*2)) + ((float)(s->lmy) / LMBLOCK_WIDTH);
mesh->lmst_array[v][1] += ((float)SECTTEXSIZE/(LMBLOCK_HEIGHT*2)) + ((float)(s->lmx) / LMBLOCK_HEIGHT);
mesh->lmst_array[0][v][0] += ((float)SECTTEXSIZE/(LMBLOCK_WIDTH*2)) + ((float)(s->lmy) / LMBLOCK_WIDTH);
mesh->lmst_array[0][v][1] += ((float)SECTTEXSIZE/(LMBLOCK_HEIGHT*2)) + ((float)(s->lmx) / LMBLOCK_HEIGHT);
//TODO: include colour tints
}
@ -437,8 +440,8 @@ void GL_DrawHeightmapModel (batch_t **batches, entity_t *e)
GL_SelectVBO(0);
s->vbo.texcoord.gl.addr = (void*)((char*)mesh->st_array - (char*)mesh->xyz_array);
s->vbo.texcoord.gl.vbo = s->vbo.coord.gl.vbo;
s->vbo.lmcoord.gl.addr = (void*)((char*)mesh->lmst_array - (char*)mesh->xyz_array);
s->vbo.lmcoord.gl.vbo = s->vbo.coord.gl.vbo;
s->vbo.lmcoord[0].gl.addr = (void*)((char*)mesh->lmst_array - (char*)mesh->xyz_array);
s->vbo.lmcoord[0].gl.vbo = s->vbo.coord.gl.vbo;
// Z_Free(mesh->xyz_array);
// mesh->xyz_array = NULL;
// mesh->st_array = NULL;
@ -476,7 +479,10 @@ void GL_DrawHeightmapModel (batch_t **batches, entity_t *e)
b->skin = &s->textures;
b->texture = NULL;
b->vbo = &s->vbo;
b->lightmap = s->lightmap;
b->lightmap[0] = s->lightmap;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->next = batches[b->shader->sort];
batches[b->shader->sort] = b;

View File

@ -2,7 +2,7 @@
#ifdef HALFLIFEMODELS
#include "glquake.h"
#include "shader.h"
/*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Half-Life Model Renderer (Experimental) Copyright (C) 2001 James 'Ender' Brown [ender@quakesrc.org] This program is
@ -83,7 +83,7 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
hlmdl_tex_t *tex;
hlmdl_bone_t *bones;
hlmdl_bonecontroller_t *bonectls;
texid_t *texnums;
shader_t **shaders;
int start, end, total;
/*~~*/
@ -198,11 +198,12 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
model->bones = (char *)bones - (char *)model;
model->bonectls = (char *)bonectls - (char *)model;
texnums = Hunk_Alloc(texheader->numtextures*sizeof(model->texnums));
model->texnums = (char *)texnums - (char *)model;
shaders = Hunk_Alloc(texheader->numtextures*sizeof(shader_t));
model->shaders = (char *)shaders - (char *)model;
for(i = 0; i < texheader->numtextures; i++)
{
texnums[i] = GL_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) texheader + tex[i].offset, (qbyte *) texheader + tex[i].w * tex[i].h + tex[i].offset, IF_NOALPHA|IF_NOGAMMA);
shaders[i] = R_RegisterSkin(va("%s_%i.tga", mod->name, i), mod->name);
shaders[i]->defaulttextures.base = R_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) texheader + tex[i].offset, (qbyte *) texheader + tex[i].w * tex[i].h + tex[i].offset, IF_NOALPHA|IF_NOGAMMA);
}
@ -555,6 +556,8 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
}
}
#if 0
/*
=======================================================================================================================
R_Draw_HL_AliasModel - main drawing function
@ -568,7 +571,6 @@ void R_DrawHLModel(entity_t *curent)
int b, m, v;
short *skins;
int bgroup, cbone, lastbone;
float mmat[16], mvmat[16];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//general model
@ -577,7 +579,7 @@ void R_DrawHLModel(entity_t *curent)
model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures);
model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones);
model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls);
model.texnums = (texid_t *) ((char *)modelc + modelc->texnums);
model.shaders = (shader_t **) ((char *)modelc + modelc->shaders);
skins = (short *) ((qbyte *) model.texheader + model.texheader->skins);
@ -590,30 +592,9 @@ void R_DrawHLModel(entity_t *curent)
for (b = 0; b < MAX_BONE_CONTROLLERS; b++)
model.controller[b] = curent->framestate.bonecontrols[b];
GL_TexEnv(GL_MODULATE);
if (curent->shaderRGBAf[3]<1)
{
qglEnable(GL_BLEND);
}
else
{
qglDisable(GL_BLEND);
}
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Con_Printf("%s %i\n", sequence->name, sequence->unknown1[0]);
qglPushMatrix();
{
vec3_t difuse, ambient, ldir;
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, curent->origin, difuse, ambient, ldir);
qglColor4f(difuse[0]/255+ambient[0]/255, difuse[1]/255+ambient[1]/255, difuse[2]/255+ambient[2]/255, curent->shaderRGBAf[3]);
}
R_RotateForEntity (mmat, mvmat, curent, curent->model);
qglLoadMatrixf(mvmat);
cbone = 0;
for (bgroup = 0; bgroup < FS_COUNT; bgroup++)
@ -684,16 +665,12 @@ void R_DrawHLModel(entity_t *curent)
{
tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w;
tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h;
GL_LazyBind(0, GL_TEXTURE_2D, model.texnums[skins[mesh->skinindex]]);
// GL_LazyBind(0, GL_TEXTURE_2D, model.shaders[skins[mesh->skinindex]]->defaulttextures.base);
}
GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h);
}
}
qglPopMatrix();
GL_TexEnv(GL_REPLACE);
}
/*
@ -734,6 +711,8 @@ void GL_Draw_HL_AliasFrame(short *order, vec3_t *transformed, float tex_w, float
float *verts = transformed[order[0]];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//FIXME: what's order[1]?
/* texture coordinates come from the draw list */
qglTexCoord2f(order[2] * tex_w, order[3] * tex_h);
order += 4;
@ -745,5 +724,246 @@ void GL_Draw_HL_AliasFrame(short *order, vec3_t *transformed, float tex_w, float
qglEnd();
}
}
#endif
void R_HL_BuildFrame(hlmodel_t *model, hlmdl_model_t *amodel, entity_t *curent, short *order, float tex_s, float tex_t, mesh_t *mesh)
{
static vecV_t xyz[2048];
static vec3_t norm[2048];
static vec2_t st[2048];
static index_t index[4096];
int count;
int b;
int cbone;
int bgroup;
int lastbone;
int v, i;
vec3_t *verts;
qbyte *bone;
vec3_t transformed[2048];
int idx = 0;
int vert = 0;
mesh->xyz_array = xyz;
mesh->st_array = st;
mesh->normals_array = norm; //for lighting algos to not crash
mesh->snormals_array = norm; //for rtlighting
mesh->tnormals_array = norm; //for rtlighting
mesh->indexes = index;
for (b = 0; b < MAX_BONE_CONTROLLERS; b++)
model->controller[b] = curent->framestate.bonecontrols[b];
// Con_Printf("%s %i\n", sequence->name, sequence->unknown1[0]);
cbone = 0;
for (bgroup = 0; bgroup < FS_COUNT; bgroup++)
{
lastbone = curent->framestate.g[bgroup].endbone;
if (bgroup == FS_COUNT-1)
lastbone = model->header->numbones;
if (cbone >= lastbone)
continue;
HL_SetupBones(model, curent->framestate.g[bgroup].frame[0], cbone, lastbone, (curent->framestate.g[bgroup].subblendfrac+1)*0.5, curent->framestate.g[bgroup].frametime[0]); /* Setup the bones */
cbone = lastbone;
}
verts = (vec3_t *) ((qbyte *) model->header + amodel->vertindex);
bone = ((qbyte *) model->header + amodel->vertinfoindex);
for(v = 0; v < amodel->numverts; v++)
{
VectorTransform(verts[v], (void *)transform_matrix[bone[v]], transformed[v]);
}
for(;;)
{
count = *order++; /* get the vertex count and primitive type */
if(!count) break; /* done */
if(count < 0)
{
count = -count;
//emit (count-2)*3 indicies as a fan
for (i = 0; i < count-2; i++)
{
index[idx++] = vert + 0;
index[idx++] = vert + i+1;
index[idx++] = vert + i+2;
}
}
else
{
//emit (count-2)*3 indicies as a strip
for (i = 0; ; )
{
if (i == count-2)
break;
index[idx++] = vert + i;
index[idx++] = vert + i+1;
index[idx++] = vert + i+2;
i++;
if (i == count-2)
break;
index[idx++] = vert + i;
index[idx++] = vert + i+2;
index[idx++] = vert + i+1;
i++;
}
}
do
{
VectorCopy(transformed[order[0]], xyz[vert]);
//FIXME: what's order[1]?
/* texture coordinates come from the draw list */
st[vert][0] = order[2] * tex_s;
st[vert][1] = order[3] * tex_t;
norm[vert][1] = 1;
order += 4;
vert++;
} while(--count);
}
mesh->numindexes = idx;
mesh->numvertexes = vert;
}
void R_HalfLife_WalkMeshes(entity_t *rent, batch_t *b, batch_t **batches);
void R_HL_BuildMesh(struct batch_s *b)
{
R_HalfLife_WalkMeshes(b->ent, b, NULL);
}
void R_HalfLife_WalkMeshes(entity_t *rent, batch_t *b, batch_t **batches)
{
hlmodelcache_t *modelc = Mod_Extradata(rent->model);
hlmodel_t model;
int body, m, v;
short *skins;
int bgroup, cbone, lastbone;
int batchid = 0;
static mesh_t bmesh, *mptr = &bmesh;
//general model
model.header = (hlmdl_header_t *) ((char *)modelc + modelc->header);
model.texheader = (hlmdl_header_t *) ((char *)modelc + modelc->texheader);
model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures);
model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones);
model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls);
model.shaders = (shader_t **) ((char *)modelc + modelc->shaders);
skins = (short *) ((qbyte *) model.texheader + model.texheader->skins);
for (body = 0; body < model.header->numbodyparts; body++)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
hlmdl_bodypart_t *bodypart = (hlmdl_bodypart_t *) ((qbyte *) model.header + model.header->bodypartindex) + body;
int bodyindex = (0 / bodypart->base) % bodypart->nummodels;
hlmdl_model_t *amodel = (hlmdl_model_t *) ((qbyte *) model.header + bodypart->modelindex) + bodyindex;
qbyte *bone = ((qbyte *) model.header + amodel->vertinfoindex);
vec3_t *verts = (vec3_t *) ((qbyte *) model.header + amodel->vertindex);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Draw each mesh */
for(m = 0; m < amodel->nummesh; m++)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
hlmdl_mesh_t *mesh = (hlmdl_mesh_t *) ((qbyte *) model.header + amodel->meshindex) + m;
float tex_w;
float tex_h;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (batches)
{
shader_t *shader;
int sort;
b = BE_GetTempBatch();
if (!b)
return;
shader = model.shaders[skins[mesh->skinindex]];
b->buildmeshes = R_HL_BuildMesh;
b->ent = rent;
b->mesh = NULL;
b->firstmesh = 0;
b->meshes = 1;
b->skin = &shader->defaulttextures;
b->texture = NULL;
b->shader = shader;
b->lightmap[0] = -1;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->surf_first = batchid;
b->flags = 0;
sort = shader->sort;
//fixme: we probably need to force some blend modes based on the surface flags.
if (rent->flags & RF_FORCECOLOURMOD)
b->flags |= BEF_FORCECOLOURMOD;
if (rent->flags & Q2RF_ADDITIVE)
{
b->flags |= BEF_FORCEADDITIVE;
if (sort < SHADER_SORT_ADDITIVE)
sort = SHADER_SORT_ADDITIVE;
}
if (rent->flags & Q2RF_TRANSLUCENT)
{
b->flags |= BEF_FORCETRANSPARENT;
if (SHADER_SORT_PORTAL < sort && sort < SHADER_SORT_BLEND)
sort = SHADER_SORT_BLEND;
}
if (rent->flags & RF_NODEPTHTEST)
{
b->flags |= BEF_FORCENODEPTH;
if (sort < SHADER_SORT_NEAREST)
sort = SHADER_SORT_NEAREST;
}
if (rent->flags & RF_NOSHADOW)
b->flags |= BEF_NOSHADOWS;
b->vbo = NULL;
b->next = batches[sort];
batches[sort] = b;
}
else
{
if (batchid == b->surf_first)
{
tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w;
tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h;
b->mesh = &mptr;
R_HL_BuildFrame(&model, amodel, b->ent, (short *) ((qbyte *) model.header + mesh->index), tex_w, tex_h, b->mesh[0]);
return;
}
}
batchid++;
}
}
}
qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel);
void R_HalfLife_GenerateBatches(entity_t *e, batch_t **batches)
{
R_CalcModelLighting(e, e->model);
R_HalfLife_WalkMeshes(e, NULL, batches);
}
#endif

View File

@ -96,18 +96,60 @@ void RMod_UpdateLightmap(int snum)
#endif
void RMod_BatchList_f(void)
{
int m, i;
model_t *mod;
batch_t *batch;
unsigned int count;
for (m=0 , mod=mod_known ; m<mod_numknown ; m++, mod++)
{
if (mod->type == mod_brush && !mod->needload)
{
Con_Printf("%s:\n", mod->name);
count = 0;
for (i = 0; i < SHADER_SORT_COUNT; i++)
{
for (batch = mod->batches[i]; batch; batch = batch->next)
{
if (batch->lightmap[3] >= 0)
Con_Printf("%s lm=(%i:%i %i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->lightmap[1], batch->lightstyle[1], batch->lightmap[2], batch->lightstyle[2], batch->lightmap[3], batch->lightstyle[3], batch->maxmeshes);
else if (batch->lightmap[2] >= 0)
Con_Printf("%s lm=(%i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->lightmap[1], batch->lightstyle[1], batch->lightmap[2], batch->lightstyle[2], batch->maxmeshes);
else if (batch->lightmap[1] >= 0)
Con_Printf("%s lm=(%i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->lightmap[1], batch->lightstyle[1], batch->maxmeshes);
else if (batch->lightstyle[0] != 255)
Con_Printf("%s lm=(%i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lightstyle[0], batch->maxmeshes);
else
Con_Printf("%s lm=%i surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->maxmeshes);
count++;
}
}
Con_Printf("%u\n", count);
}
}
}
void RMod_TextureList_f(void)
{
int m, i;
texture_t *tx;
model_t *mod;
qboolean shownmodelname;
qboolean shownmodelname = false;
int count = 0;
for (m=0 , mod=mod_known ; m<mod_numknown ; m++, mod++)
{
if (shownmodelname)
Con_Printf("%u\n", count);
shownmodelname = false;
if (mod->type == mod_brush && !mod->needload)
{
if (*mod->name == '*')
continue;// inlines don't count
if (shownmodelname)
Con_Printf("%u\n", count);
count = 0;
shownmodelname = false;
for (i = 0; i < mod->numtextures; i++)
{
@ -119,12 +161,16 @@ void RMod_TextureList_f(void)
{
shownmodelname = true;
Con_Printf("%s\n", mod->name);
count = 0;
}
Con_Printf("%s\n", tx->name);
count++;
}
}
}
if (shownmodelname)
Con_Printf("%u\n", count);
}
void RMod_BlockTextureColour_f (void)
@ -378,6 +424,7 @@ void RMod_Init (void)
mod_numknown = 0;
Q1BSP_Init();
Cmd_AddCommand("mod_batchlist", RMod_BatchList_f);
Cmd_AddCommand("mod_texturelist", RMod_TextureList_f);
Cmd_AddCommand("mod_usetexture", RMod_BlockTextureColour_f);
}
@ -387,6 +434,7 @@ void RMod_Shutdown (void)
RMod_ClearAll();
mod_numknown = 0;
Cmd_RemoveCommand("mod_batchlist");
Cmd_RemoveCommand("mod_texturelist");
Cmd_RemoveCommand("mod_usetexture");
}
@ -1088,9 +1136,10 @@ void RMod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps)
if (!TEXVALID(tn->base))
{
tn->base = R_LoadReplacementTexture(mt->name, "bmodels", alphaed?0:IF_NOALPHA);
if (!TEXVALID(tn->base))
if (base && !TEXVALID(tn->base))
tn->base = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, (alphaed?0:IF_NOALPHA));
}
BZ_Free(base);
}
*tx->name = *mt->name;
@ -1410,7 +1459,7 @@ void RMod_NowLoadExternal(void)
data = W_GetTexture(tx->name, &width, &height, &alphaed);
if (data)
{ //data is from temp hunk, so no need to free.
{
tx->alphaed = alphaed;
}
@ -1421,6 +1470,7 @@ void RMod_NowLoadExternal(void)
// if (!TEXVALID(tn.base))
// tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA|IF_MIPCAP); //a fallback. :/
}
BZ_Free(data);
}
if (!TEXVALID(tn.bump) && *tx->name != '{' && r_loadbumpmapping)
{
@ -2110,7 +2160,7 @@ void CalcSurfaceExtents (msurface_t *s);
Mod_LoadFaces
=================
*/
qboolean RMod_LoadFaces (lump_t *l, qboolean lm)
qboolean RMod_LoadFaces (lump_t *l, qboolean lm, mesh_t **meshlist)
{
dsface_t *ins;
dlface_t *inl;
@ -2143,6 +2193,7 @@ qboolean RMod_LoadFaces (lump_t *l, qboolean lm)
}
out = Hunk_AllocName ( count*sizeof(*out), loadname);
*meshlist = Hunk_AllocName(count*sizeof(**meshlist), loadname);
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
for ( surfnum=0 ; surfnum<count ; surfnum++, out++)
@ -2171,6 +2222,8 @@ qboolean RMod_LoadFaces (lump_t *l, qboolean lm)
lofs = LittleLong(ins->lightofs);
ins++;
}
// (*meshlist)[surfnum].vbofirstvert = out->firstedge;
// (*meshlist)[surfnum].numvertexes = out->numedges;
out->flags = 0;
if (side)
@ -2234,6 +2287,499 @@ qboolean RMod_LoadFaces (lump_t *l, qboolean lm)
return true;
}
void RModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, void *cookie)
{
int i, lindex;
mesh_t *mesh = surf->mesh;
medge_t *pedge;
float *vec;
float s, t, d;
int sty;
//output the mesh's indicies
for (i=0 ; i<mesh->numvertexes-2 ; i++)
{
mesh->indexes[i*3] = 0;
mesh->indexes[i*3+1] = i+1;
mesh->indexes[i*3+2] = i+2;
}
//output the renderable verticies
for (i=0 ; i<mesh->numvertexes ; i++)
{
lindex = mod->surfedges[surf->firstedge + i];
if (lindex > 0)
{
pedge = &mod->edges[lindex];
vec = mod->vertexes[pedge->v[0]].position;
}
else
{
pedge = &mod->edges[-lindex];
vec = mod->vertexes[pedge->v[1]].position;
}
s = DotProduct (vec, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
t = DotProduct (vec, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3];
VectorCopy (vec, mesh->xyz_array[i]);
mesh->st_array[i][0] = s/surf->texinfo->texture->width;
mesh->st_array[i][1] = t/surf->texinfo->texture->height;
for (sty = 0; sty < 1; sty++)
{
mesh->lmst_array[sty][i][0] = (s - surf->texturemins[0] + (surf->light_s[sty]*16) + 8) / (mod->lightmaps.width*16);
mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]*16) + 8) / (mod->lightmaps.height*16);
}
//figure out the texture directions, for bumpmapping and stuff
if (surf->flags & SURF_PLANEBACK)
VectorNegate(surf->plane->normal, mesh->normals_array[i]);
else
VectorCopy(surf->plane->normal, mesh->normals_array[i]);
VectorNegate(surf->texinfo->vecs[0], mesh->snormals_array[i]);
VectorNegate(surf->texinfo->vecs[1], mesh->tnormals_array[i]);
//the s+t vectors are axis-aligned, so fiddle them so they're normal aligned instead
d = -DotProduct(mesh->normals_array[i], mesh->snormals_array[i]);
VectorMA(mesh->snormals_array[i], d, mesh->normals_array[i], mesh->snormals_array[i]);
d = -DotProduct(mesh->normals_array[i], mesh->tnormals_array[i]);
VectorMA(mesh->tnormals_array[i], d, mesh->normals_array[i], mesh->tnormals_array[i]);
VectorNormalize(mesh->snormals_array[i]);
VectorNormalize(mesh->tnormals_array[i]);
//q1bsp has no colour information (fixme: sample from the lightmap)
mesh->colors4f_array[i][0] = 1;
mesh->colors4f_array[i][1] = 1;
mesh->colors4f_array[i][2] = 1;
mesh->colors4f_array[i][3] = 1;
}
}
static void RMod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindicies, void (*build)(model_t *mod, msurface_t *surf, void *cookie), void *buildcookie)
{
batch_t *batch;
msurface_t *surf;
mesh_t *mesh;
int numverts = 0;
int numindicies = 0;
int j;
int sortid;
int sty;
vbo_t vbo;
int styles = MAXLIGHTMAPS;
vbo.indicies.dummy = Hunk_AllocName(sizeof(index_t) * maxindicies, "indexdata");
vbo.coord.dummy = Hunk_AllocName((sizeof(vecV_t)+sizeof(vec2_t)*(1+styles)+sizeof(vec3_t)*3+sizeof(vec4_t))* maxverts, "vertdata");
vbo.texcoord.dummy = (vecV_t*)vbo.coord.dummy + maxverts;
vbo.lmcoord[0].dummy = (vec2_t*)vbo.texcoord.dummy + maxverts;
for (sty = 1; sty < styles; sty++)
vbo.lmcoord[sty].dummy = (vec2_t*)vbo.lmcoord[sty-1].dummy + maxverts;
vbo.normals.dummy = (vec2_t*)vbo.lmcoord[styles-1].dummy + maxverts;
vbo.svector.dummy = (vec3_t*)vbo.normals.dummy + maxverts;
vbo.tvector.dummy = (vec3_t*)vbo.svector.dummy + maxverts;
vbo.colours.dummy = (vec3_t*)vbo.tvector.dummy + maxverts;
numindicies = 0;
numverts = 0;
//build each mesh
for (sortid=0; sortid<SHADER_SORT_COUNT; sortid++)
{
for (batch = mod->batches[sortid]; batch; batch = batch->next)
{
for (j = 0; j < batch->maxmeshes; j++)
{
surf = (msurface_t*)batch->mesh[j];
mesh = surf->mesh;
batch->mesh[j] = mesh;
mesh->vbofirstvert = numverts;
mesh->vbofirstelement = numindicies;
numverts += mesh->numvertexes;
numindicies += mesh->numindexes;
//set up the arrays. the arrangement is required for the backend to optimise vbos
mesh->xyz_array = (vecV_t*)vbo.coord.dummy + mesh->vbofirstvert;
mesh->st_array = (vec2_t*)vbo.texcoord.dummy + mesh->vbofirstvert;
for (sty = 0; sty < styles; sty++)
mesh->lmst_array[sty] = (vec2_t*)vbo.lmcoord[sty].dummy + mesh->vbofirstvert;
for ( ; sty < MAXLIGHTMAPS; sty++)
mesh->lmst_array[sty] = NULL;
mesh->normals_array = (vec3_t*)vbo.normals.dummy + mesh->vbofirstvert;
mesh->snormals_array = (vec3_t*)vbo.svector.dummy + mesh->vbofirstvert;
mesh->tnormals_array = (vec3_t*)vbo.tvector.dummy + mesh->vbofirstvert;
mesh->colors4f_array = (vec4_t*)vbo.colours.dummy + mesh->vbofirstvert;
mesh->indexes = (index_t*)vbo.indicies.dummy + mesh->vbofirstelement;
mesh->vbofirstvert = 0;
mesh->vbofirstelement = 0;
build(mod, surf, buildcookie);
}
batch->meshes = 0;
batch->firstmesh = 0;
}
}
}
/*
batch->firstmesh is set only in and for this function, its cleared out elsewhere
*/
static void RMod_Batches_Generate(model_t *mod)
{
int i;
msurface_t *surf;
shader_t *shader;
int sortid;
batch_t *batch, *lbatch = NULL;
vec4_t plane;
//for each surface, find a suitable batch to insert it into.
//we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit)
for (i=0; i<mod->nummodelsurfaces; i++)
{
surf = mod->surfaces + mod->firstmodelsurface + i;
shader = surf->texinfo->texture->shader;
if (shader)
{
sortid = shader->sort;
//shaders that are portals need to be split into separate batches to have the same surface planes
if (sortid == SHADER_SORT_PORTAL || (shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT)))
{
if (surf->flags & SURF_PLANEBACK)
{
VectorNegate(surf->plane->normal, plane);
plane[3] = -surf->plane->dist;
}
else
{
VectorCopy(surf->plane->normal, plane);
plane[3] = surf->plane->dist;
}
}
else
{
VectorClear(plane);
plane[3] = 0;
}
}
else
{
sortid = SHADER_SORT_OPAQUE;
VectorClear(plane);
plane[3] = 0;
}
if (lbatch && (lbatch->texture == surf->texinfo->texture && lbatch->lightmap[0] == surf->lightmaptexturenums[0] && Vector4Compare(plane, lbatch->plane) && lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) &&
lbatch->lightmap[1] == surf->lightmaptexturenums[1] &&
lbatch->lightmap[2] == surf->lightmaptexturenums[2] &&
lbatch->lightmap[3] == surf->lightmaptexturenums[3])
batch = lbatch;
else
{
for (batch = mod->batches[sortid]; batch; batch = batch->next)
{
if (batch->texture == surf->texinfo->texture && batch->lightmap[0] == surf->lightmaptexturenums[0] && Vector4Compare(plane, batch->plane) && batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES &&
batch->lightmap[1] == surf->lightmaptexturenums[1] &&
batch->lightmap[2] == surf->lightmaptexturenums[2] &&
batch->lightmap[3] == surf->lightmaptexturenums[3])
break;
}
}
if (!batch)
{
batch = Hunk_AllocName(sizeof(*batch), "batch");
batch->lightmap[0] = surf->lightmaptexturenums[0];
batch->lightmap[1] = surf->lightmaptexturenums[1];
batch->lightmap[2] = surf->lightmaptexturenums[2];
batch->lightmap[3] = surf->lightmaptexturenums[3];
batch->texture = surf->texinfo->texture;
batch->next = mod->batches[sortid];
batch->ent = &r_worldentity;
Vector4Copy(plane, batch->plane);
mod->batches[sortid] = batch;
}
surf->sbatch = batch; //let the surface know which batch its in
batch->maxmeshes++;
batch->firstmesh += surf->mesh->numvertexes;
lbatch = batch;
}
}
typedef struct
{
int allocated[LMBLOCK_WIDTH];
int lmnum;
} lmalloc_t;
static void RMod_LightmapAllocInit(lmalloc_t *lmallocator)
{
memset(lmallocator, 0, sizeof(*lmallocator));
}
static void RMod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod)
{
mod->lightmaps.first = 1;
mod->lightmaps.count = lmallocator->lmnum;
}
static void RMod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short *x, unsigned short *y, int *tnum)
{
int best, best2;
int i, j;
if (!lmallocator->lmnum)
lmallocator->lmnum = 1;
for(;;)
{
best = LMBLOCK_HEIGHT;
for (i = 0; i <= LMBLOCK_WIDTH - w; i++)
{
best2 = 0;
for (j=0; j < w; j++)
{
if (lmallocator->allocated[i+j] >= best)
break;
if (lmallocator->allocated[i+j] > best2)
best2 = lmallocator->allocated[i+j];
}
if (j == w)
{ // this is a valid spot
*x = i;
*y = best = best2;
}
}
if (best + h > LMBLOCK_HEIGHT)
{
memset(lmallocator->allocated, 0, sizeof(lmallocator->allocated));
lmallocator->lmnum++;
continue;
}
for (i=0; i < w; i++)
lmallocator->allocated[*x + i] = best + h;
*tnum = lmallocator->lmnum;
break;
}
}
static void RMod_LightmapAllocSurf(lmalloc_t *lmallocator, msurface_t *surf, int surfstyle)
{
int smax, tmax;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
if (isDedicated ||
(surf->texinfo->texture->shader && !(surf->texinfo->texture->shader->flags & SHADER_HASLIGHTMAP)) || //fte
(surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) || //q1
(surf->texinfo->flags & TEX_SPECIAL) || //the original 'no lightmap'
(surf->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP)) || //q2 surfaces
smax > LMBLOCK_WIDTH || tmax > LMBLOCK_HEIGHT || smax < 0 || tmax < 0) //bugs/bounds/etc
{
surf->lightmaptexturenums[surfstyle] = -1;
return;
}
RMod_LightmapAllocBlock (lmallocator, smax, tmax, &surf->light_s[surfstyle], &surf->light_t[surfstyle], &surf->lightmaptexturenums[surfstyle]);
}
static void RMod_Batches_SplitLightmaps(model_t *mod)
{
batch_t *batch;
batch_t *nb;
int i, j, sortid;
msurface_t *surf;
int sty;
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{
surf = (msurface_t*)batch->mesh[0];
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
{
batch->lightmap[sty] = surf->lightmaptexturenums[sty];
batch->lightstyle[sty] = surf->styles[sty];
}
for (j = 1; j < batch->maxmeshes; j++)
{
surf = (msurface_t*)batch->mesh[j];
if (surf->lightmaptexturenums[0] != batch->lightmap[0] ||
surf->lightmaptexturenums[1] != batch->lightmap[1] ||
surf->lightmaptexturenums[2] != batch->lightmap[2] ||
surf->lightmaptexturenums[3] != batch->lightmap[3] ||
//fixme: we should merge later (reverted matching) surfaces into the prior batch
surf->styles[0] != batch->lightstyle[0] ||
surf->styles[1] != batch->lightstyle[1] ||
surf->styles[2] != batch->lightstyle[2] ||
surf->styles[3] != batch->lightstyle[3] )
{
nb = Hunk_AllocName(sizeof(*batch), "batch");
*nb = *batch;
batch->next = nb;
nb->mesh = batch->mesh + j*2;
nb->maxmeshes = batch->maxmeshes - j;
batch->maxmeshes = j;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
{
nb->lightmap[sty] = surf->lightmaptexturenums[sty];
nb->lightstyle[sty] = surf->styles[sty];
}
memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes);
for (i = 0; i < nb->maxmeshes; i++)
{
surf = (msurface_t*)nb->mesh[i];
surf->sbatch = nb;
}
batch = nb;
j = 1;
}
}
}
}
/*
allocates lightmaps and splits batches upon lightmap boundaries
*/
static void RMod_Batches_AllocLightmaps(model_t *mod)
{
batch_t *batch;
batch_t *nb;
lmalloc_t lmallocator;
int i, j, sortid;
msurface_t *surf;
int sty;
RMod_LightmapAllocInit(&lmallocator);
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{
surf = (msurface_t*)batch->mesh[0];
RMod_LightmapAllocSurf (&lmallocator, surf, 0);
for (sty = 1; sty < MAXLIGHTMAPS; sty++)
surf->lightmaptexturenums[sty] = -1;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
{
batch->lightmap[sty] = surf->lightmaptexturenums[sty];
batch->lightstyle[sty] = 255;//don't do special backend rendering of lightstyles.
}
for (j = 1; j < batch->maxmeshes; j++)
{
surf = (msurface_t*)batch->mesh[j];
RMod_LightmapAllocSurf (&lmallocator, surf, 0);
for (sty = 1; sty < MAXLIGHTMAPS; sty++)
surf->lightmaptexturenums[sty] = -1;
if (surf->lightmaptexturenums[0] != batch->lightmap[0])
{
nb = Hunk_AllocName(sizeof(*batch), "batch");
*nb = *batch;
batch->next = nb;
nb->mesh = batch->mesh + j*2;
nb->maxmeshes = batch->maxmeshes - j;
batch->maxmeshes = j;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
nb->lightmap[sty] = surf->lightmaptexturenums[sty];
memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes);
for (i = 0; i < nb->maxmeshes; i++)
{
surf = (msurface_t*)nb->mesh[i];
surf->sbatch = nb;
}
batch = nb;
j = 0;
}
}
}
RMod_LightmapAllocDone(&lmallocator, mod);
}
extern void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift);
//if build is NULL, uses q1/q2 surf generation, and allocates lightmaps
void RMod_Batches_Build(mesh_t *meshlist, model_t *mod, void (*build)(model_t *mod, msurface_t *surf, void *cookie), void *buildcookie)
{
int i;
int numverts = 0, numindicies=0;
msurface_t *surf;
mesh_t *mesh;
mesh_t **bmeshes;
int sortid;
batch_t *batch;
currentmodel = mod;
if (meshlist)
meshlist += mod->firstmodelsurface;
else if (!build)
meshlist = Hunk_Alloc(sizeof(mesh_t) * mod->nummodelsurfaces);
for (i=0; i<mod->nummodelsurfaces; i++)
{
surf = mod->surfaces + i + mod->firstmodelsurface;
if (meshlist)
{
mesh = surf->mesh = &meshlist[i];
mesh->numvertexes = surf->numedges;
mesh->numindexes = (surf->numedges-2)*3;
}
else
mesh = surf->mesh;
numverts += mesh->numvertexes;
numindicies += mesh->numindexes;
// surf->lightmaptexturenum = -1;
}
/*assign each mesh to a batch, generating as needed*/
RMod_Batches_Generate(mod);
bmeshes = Hunk_AllocName(sizeof(*bmeshes)*mod->nummodelsurfaces*2, "batchmeshes");
//we now know which batch each surface is in, and how many meshes there are in each batch.
//allocate the mesh-pointer-lists for each batch. *2 for recursion.
for (i = 0, sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{
batch->mesh = bmeshes + i;
i += batch->maxmeshes*2;
}
//store the *surface* into the batch's mesh list (yes, this is an evil cast hack, but at least both are pointers)
for (i=0; i<mod->nummodelsurfaces; i++)
{
surf = mod->surfaces + mod->firstmodelsurface + i;
surf->sbatch->mesh[surf->sbatch->meshes++] = (mesh_t*)surf;
}
if (build)
RMod_Batches_SplitLightmaps(mod);
else
RMod_Batches_AllocLightmaps(mod);
if (!build)
build = RModQ1_Batches_BuildQ1Q2Poly;
RMod_Batches_BuildModelMeshes(mod, numverts, numindicies, build, buildcookie);
if (BE_GenBrushModelVBO)
BE_GenBrushModelVBO(mod);
}
/*
=================
@ -3181,6 +3727,7 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
int start;
qboolean noerrors;
qboolean longm = false;
mesh_t *meshlist = NULL;
#if (defined(ODE_STATIC) || defined(ODE_DYNAMIC))
qboolean ode = true;
#else
@ -3223,6 +3770,9 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
return false;
}
mod->lightmaps.width = LMBLOCK_WIDTH;
mod->lightmaps.height = LMBLOCK_HEIGHT;
// swap all the lumps
mod_base = (qbyte *)header;
@ -3299,7 +3849,7 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
if (!isDedicated || ode)
{
noerrors = noerrors && RMod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
noerrors = noerrors && RMod_LoadFaces (&header->lumps[LUMP_FACES], longm);
noerrors = noerrors && RMod_LoadFaces (&header->lumps[LUMP_FACES], longm, &meshlist);
}
if (!isDedicated)
noerrors = noerrors && RMod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES], longm);
@ -3373,6 +3923,13 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
mod->numleafs = bm->visleafs;
memset(&mod->batches, 0, sizeof(mod->batches));
mod->vbos = NULL;
if (meshlist)
{
RMod_Batches_Build(meshlist, mod, NULL, NULL);
}
if (i < mod->numsubmodels-1)
{ // duplicate the basic information
char name[10];

View File

@ -69,7 +69,7 @@ typedef struct mesh_s
vec3_t *snormals_array;/*required for rtlighting*/
vec3_t *tnormals_array;/*required for rtlighting*/
vec2_t *st_array; /*texture coords*/
vec2_t *lmst_array; /*second texturecoord set (merely dubbed lightmap)*/
vec2_t *lmst_array[MAXLIGHTMAPS]; /*second texturecoord set (merely dubbed lightmap, one for each potential lightstyle)*/
avec4_t *colors4f_array;/*floating point colours array*/
byte_vec4_t *colors4b_array;/*byte colours array*/
@ -102,8 +102,10 @@ typedef struct batch_s
shader_t *shader;
struct vbo_s *vbo;
int lightmap; /*used for shader lightmap textures*/
entity_t *ent; /*used for shader properties*/
int lightmap[MAXLIGHTMAPS]; /*used for shader lightmap textures*/
unsigned char lightstyle[MAXLIGHTMAPS];
struct texture_s *texture; /*is this used by the backend?*/
struct texnums_s *skin;
@ -120,7 +122,7 @@ typedef struct batch_s
unsigned int surf_first;
unsigned int surf_count;
};
vec3_t normal; /*used only at load (for portal surfaces, so multiple planes are not part of the same batch)*/
vec4_t plane; /*used only at load (for portal surfaces, so multiple planes are not part of the same batch)*/
};
} batch_t;
/*
@ -240,7 +242,7 @@ typedef struct vboarray_s
{
union
{
int dummy;
void *dummy;
#ifdef GLQUAKE
struct
@ -278,7 +280,7 @@ typedef struct vbo_s
vboarray_t coord;
vboarray_t coord2;
vboarray_t texcoord;
vboarray_t lmcoord;
vboarray_t lmcoord[MAXLIGHTMAPS];
vboarray_t normals;
vboarray_t svector;
@ -395,15 +397,13 @@ typedef struct msurface_s
short texturemins[2];
short extents[2];
int light_s, light_t; // gl lightmap coordinates
unsigned short light_s[MAXLIGHTMAPS], light_t[MAXLIGHTMAPS]; // gl lightmap coordinates
mfog_t *fog;
mesh_t *mesh;
entity_t *ownerent;
batch_t *sbatch;
mtexinfo_t *texinfo;
struct msurface_s **mark;
int visframe; // should be drawn when node is crossed
int shadowframe;
@ -411,7 +411,7 @@ typedef struct msurface_s
int dlightframe;
int dlightbits;
int lightmaptexturenum;
int lightmaptexturenums[MAXLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps
qbyte styles[MAXLIGHTMAPS];
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
qboolean cached_dlight; // true if dynamic light in cache
@ -957,6 +957,13 @@ typedef struct model_s
vbo_t *vbos;
void *terrain;
batch_t *batches[SHADER_SORT_COUNT];
struct
{
int first;
int count;
int width;
int height;
} lightmaps;
unsigned checksum;
unsigned checksum2;

View File

@ -28,7 +28,7 @@ extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
int r_dlightframecount;
int d_lightstylevalue[256]; // 8.8 fraction of base light value
int d_lightstylevalue[MAX_LIGHTSTYLES]; // 8.8 fraction of base light value
/*
==================
@ -391,7 +391,10 @@ void R_GenDlightBatches(batch_t *batches[])
b->skin = &lpplight_shader->defaulttextures;
b->texture = NULL;
b->shader = lpplight_shader;
b->lightmap = -1;
b->lightmap[0] = -1;
b->lightmap[1] = -1;
b->lightmap[2] = -1;
b->lightmap[3] = -1;
b->surf_first = i;
b->flags |= BEF_NOSHADOWS;
b->vbo = NULL;
@ -423,7 +426,7 @@ void R_PushDlights (void)
#ifdef RTLIGHTS
/*if we're doing full rtlighting only, then don't bother calculating old-style dlights as they won't be visible anyway*/
if (r_shadow_realtime_world.value && r_shadow_realtime_world_lightmaps.value < 0.1)
if (r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value < 0.1)
return;
#endif
@ -817,12 +820,9 @@ void R_LoadRTLights(void)
dl->coronascale = coronascale;
dl->die = 0;
dl->flags = flags;
if (ambientscale || diffusescale || specularscale)
{
dl->lightcolourscales[0] = ambientscale;
dl->lightcolourscales[1] = diffusescale;
dl->lightcolourscales[2] = specularscale;
}
dl->lightcolourscales[0] = ambientscale;
dl->lightcolourscales[1] = diffusescale;
dl->lightcolourscales[2] = specularscale;
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
Q_strncpyz(dl->cubemapname, cubename, sizeof(dl->cubemapname));

View File

@ -106,6 +106,7 @@ texid_t scenepp_postproc_cube;
// processing shaders
void GL_InitSceneProcessingShaders_WaterWarp (void)
{
scenepp_waterwarp = NULL;
if (gl_config.arb_shader_objects)
{
scenepp_waterwarp = R_RegisterShader("waterwarp",
@ -645,6 +646,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype)
refdef_t oldrefdef;
mesh_t *mesh = batch->mesh[batch->firstmesh];
int sort;
qbyte newvis[(MAX_MAP_LEAFS+7)/8];
if (r_refdef.recurse)
return;
@ -680,9 +682,54 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype)
else if (portaltype == 2)
{
/*refraction image (same view, just with things culled*/
r_refdef.externalview = false;
r_refdef.externalview = oldrefdef.externalview;
VectorNegate(plane.normal, plane.normal);
plane.dist = -plane.dist;
//use the player's origin for r_viewleaf, because there's not much we can do anyway*/
VectorCopy(r_origin, r_refdef.pvsorigin);
if (cl.worldmodel && cl.worldmodel->funcs.LeafPVS && !r_novis.ival)
{
int lnum, i, j;
float d;
vec3_t point;
int pvsbytes = (cl.worldmodel->numleafs+7)>>3;
if (pvsbytes > sizeof(newvis))
pvsbytes = sizeof(newvis);
r_refdef.forcevis = true;
r_refdef.forcedvis = NULL;
for (i = batch->firstmesh; i < batch->meshes; i++)
{
mesh = batch->mesh[i];
VectorClear(point);
for (j = 0; j < mesh->numvertexes; j++)
VectorAdd(point, mesh->xyz_array[j], point);
VectorScale(point, 1.0f/mesh->numvertexes, point);
d = DotProduct(point, plane.normal) - plane.dist;
d += 0.1; //an epsilon on the far side
VectorMA(point, d, plane.normal, point);
lnum = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, point);
if (i == batch->firstmesh)
r_refdef.forcedvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, lnum, newvis, sizeof(newvis));
else
{
if (r_refdef.forcedvis != newvis)
{
memcpy(newvis, r_refdef.forcedvis, pvsbytes);
}
r_refdef.forcedvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, lnum, NULL, sizeof(newvis));
for (j = 0; j < pvsbytes; j+= 4)
{
*(int*)&newvis[j] |= *(int*)&r_refdef.forcedvis[j];
}
r_refdef.forcedvis = newvis;
}
}
memset(newvis, 0xff, pvsbytes);
}
}
else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin))
{
@ -795,7 +842,10 @@ void R_Clear (void)
GL_ForceDepthWritable();
{
if (r_clear.ival && !r_secondaryview && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
qglClearColor(1, 0, 0, 0);
qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
else
qglClear (GL_DEPTH_BUFFER_BIT);
gldepthmin = 0;

View File

@ -28,15 +28,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void GLBE_ClearVBO(vbo_t *vbo)
{
int vboh[7];
int vboh[6 + MAXLIGHTMAPS];
int i, j;
vboh[0] = vbo->indicies.gl.vbo;
vboh[1] = vbo->coord.gl.vbo;
vboh[2] = vbo->texcoord.gl.vbo;
vboh[3] = vbo->lmcoord.gl.vbo;
vboh[4] = vbo->normals.gl.vbo;
vboh[5] = vbo->svector.gl.vbo;
vboh[6] = vbo->tvector.gl.vbo;
vboh[3] = vbo->normals.gl.vbo;
vboh[4] = vbo->svector.gl.vbo;
vboh[5] = vbo->tvector.gl.vbo;
for (i = 0; i < MAXLIGHTMAPS; i++)
vboh[6+i] = vbo->lmcoord[i].gl.vbo;
for (i = 0; i < 7; i++)
{
@ -53,7 +54,7 @@ void GLBE_ClearVBO(vbo_t *vbo)
if (vbo->vertdata)
BZ_Free(vbo->vertdata);
BZ_Free(vbo->meshlist);
memset(vbo, 0, sizeof(*vbo));
BZ_Free(vbo);
}
void GLBE_SetupVAO(vbo_t *vbo, unsigned int vaodynamic);
@ -61,6 +62,7 @@ void GLBE_SetupVAO(vbo_t *vbo, unsigned int vaodynamic);
static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int elementsize, unsigned int vaodynamic)
{
unsigned int vbos[2];
int s;
if (!qglGenBuffersARB)
return false;
@ -84,10 +86,13 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
vbo->texcoord.gl.vbo = vbos[0];
vbo->texcoord.gl.addr = (vec2_t*)((char*)vbo->texcoord.gl.addr - (char*)vdata);
}
if (vbo->lmcoord.gl.addr)
for (s = 0; s < MAXLIGHTMAPS; s++)
{
vbo->lmcoord.gl.vbo = vbos[0];
vbo->lmcoord.gl.addr = (vec2_t*)((char*)vbo->lmcoord.gl.addr - (char*)vdata);
if (vbo->lmcoord[s].gl.addr)
{
vbo->lmcoord[s].gl.vbo = vbos[0];
vbo->lmcoord[s].gl.addr = (vec2_t*)((char*)vbo->lmcoord[s].gl.addr - (char*)vdata);
}
}
if (vbo->normals.gl.addr)
{
@ -136,7 +141,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
unsigned int maxvboverts;
unsigned int maxvboelements;
unsigned int i;
unsigned int i, s;
unsigned int v;
unsigned int vcount, ecount;
unsigned int pervertsize; //erm, that name wasn't intentional
@ -148,7 +153,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
vecV_t *coord;
vec2_t *texcoord;
vec2_t *lmcoord;
vec2_t *lmcoord[MAXLIGHTMAPS];
vec3_t *normals;
vec3_t *svector;
vec3_t *tvector;
@ -164,7 +169,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
meshes = 0;
for(batch = firstbatch; batch != stopbatch; batch = batch->next)
{
for (i=0 ; i<batch->meshes ; i++)
for (i=0 ; i<batch->maxmeshes ; i++)
{
m = batch->mesh[i];
meshes++;
@ -181,7 +186,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
pervertsize = sizeof(vecV_t)+ //coord
sizeof(vec2_t)+ //tex
sizeof(vec2_t)+ //lm
sizeof(vec2_t)*MAXLIGHTMAPS+ //lm
sizeof(vec3_t)+ //normal
sizeof(vec3_t)+ //sdir
sizeof(vec3_t)+ //tdir
@ -193,7 +198,8 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
vbo->coord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vecV_t));
vbo->texcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
vbo->lmcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
for (s = 0; s < MAXLIGHTMAPS; s++)
vbo->lmcoord[s].gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
vbo->normals.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->svector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->tvector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
@ -202,7 +208,8 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
coord = vbo->coord.gl.addr;
texcoord = vbo->texcoord.gl.addr;
lmcoord = vbo->lmcoord.gl.addr;
for (s = 0; s < 4; s++)
lmcoord[s] = vbo->lmcoord[s].gl.addr;
normals = vbo->normals.gl.addr;
svector = vbo->svector.gl.addr;
tvector = vbo->tvector.gl.addr;
@ -218,7 +225,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
for(batch = firstbatch; batch != stopbatch; batch = batch->next)
{
batch->vbo = vbo;
for (i=0 ; i<batch->meshes ; i++)
for (i=0 ; i<batch->maxmeshes ; i++)
{
m = batch->mesh[i];
@ -239,10 +246,13 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
texcoord[vcount+v][0] = m->st_array[v][0];
texcoord[vcount+v][1] = m->st_array[v][1];
}
if (m->lmst_array)
for (s = 0; s < MAXLIGHTMAPS; s++)
{
lmcoord[vcount+v][0] = m->lmst_array[v][0];
lmcoord[vcount+v][1] = m->lmst_array[v][1];
if (m->lmst_array[s])
{
lmcoord[s][vcount+v][0] = m->lmst_array[s][v][0];
lmcoord[s][vcount+v][1] = m->lmst_array[s][v][1];
}
}
if (m->normals_array)
{
@ -291,6 +301,7 @@ void GLBE_GenBrushModelVBO(model_t *mod)
batch_t *batch, *fbatch;
int sortid;
int i;
fbatch = NULL;
vcount = 0;
@ -308,11 +319,14 @@ void GLBE_GenBrushModelVBO(model_t *mod)
fbatch = batch;
vcount = 0;
}
vcount += batch->firstmesh;
for (i = 0; i < batch->maxmeshes; i++)
vcount += batch->mesh[i]->numvertexes;
}
GLBE_GenBatchVBOs(&mod->vbos, fbatch, batch);
}
#if 0
if (!mod->numsurfaces)
return;
@ -455,6 +469,7 @@ void GLBE_GenBrushModelVBO(model_t *mod)
void GLBE_UploadAllLightmaps(void)
{
lightmapinfo_t *lm;
int i;
//
// upload all lightmaps that were filled
@ -463,48 +478,50 @@ void GLBE_UploadAllLightmaps(void)
{
if (!lightmap[i])
break; // no more used
lightmap[i]->rectchange.l = LMBLOCK_WIDTH;
lightmap[i]->rectchange.t = LMBLOCK_HEIGHT;
lightmap[i]->rectchange.w = 0;
lightmap[i]->rectchange.h = 0;
if (!lightmap[i]->modified)
lm = lightmap[i];
lm->rectchange.l = lm->width;
lm->rectchange.t = lm->height;
lm->rectchange.w = 0;
lm->rectchange.h = 0;
if (!lm->modified)
continue;
lightmap[i]->modified = false;
GL_MTBind(0, GL_TEXTURE_2D, lightmap_textures[i]);
lm->modified = false;
GL_MTBind(0, GL_TEXTURE_2D, lm->lightmap_texture);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
switch (lightmap_bytes)
{
case 4:
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, (lightmap_bgra?GL_BGRA_EXT:GL_RGBA), GL_UNSIGNED_INT_8_8_8_8_REV,
lm->width, lm->height, 0, (lightmap_bgra?GL_BGRA_EXT:GL_RGBA), GL_UNSIGNED_INT_8_8_8_8_REV,
lightmap[i]->lightmaps);
break;
case 3:
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
lm->width, lm->height, 0, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
lightmap[i]->lightmaps);
break;
case 1:
qglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
LMBLOCK_WIDTH, LMBLOCK_WIDTH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
lm->width, lm->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
lightmap[i]->lightmaps);
break;
}
if (r_deluxemapping.ival)
{
lightmap[i]->deluxmodified = false;
lightmap[i]->deluxrectchange.l = LMBLOCK_WIDTH;
lightmap[i]->deluxrectchange.t = LMBLOCK_HEIGHT;
lightmap[i]->deluxrectchange.l = lm->width;
lightmap[i]->deluxrectchange.t = lm->height;
lightmap[i]->deluxrectchange.w = 0;
lightmap[i]->deluxrectchange.h = 0;
GL_MTBind(0, GL_TEXTURE_2D, deluxmap_textures[i]);
GL_MTBind(0, GL_TEXTURE_2D, lm->deluxmap_texture);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexImage2D (GL_TEXTURE_2D, 0, 3
, LMBLOCK_WIDTH, LMBLOCK_HEIGHT, 0,
, lm->width, lm->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, lightmap[i]->deluxmaps);
}
}
}
#endif

View File

@ -811,6 +811,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
"#define SKELETAL\n",
"#define FOG\n",
"#define FRAMEBLEND\n",
"#define LIGHTSTYLED\n",
NULL
};
char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0]) + 64 + 1];
@ -1599,6 +1600,9 @@ struct shader_field_names_s shader_attr_names[] =
{"v_tvector", VATTR_TNORMALS},
{"v_bone", VATTR_BONENUMS},
{"v_weight", VATTR_BONEWEIGHTS},
{"v_lmcoord2", VATTR_LMCOORD2},
{"v_lmcoord3", VATTR_LMCOORD3},
{"v_lmcoord4", VATTR_LMCOORD4},
{NULL}
};
@ -3147,6 +3151,8 @@ void Shader_Shutdown (void)
}
}
Shader_FlushGenerics();
free(r_shaders);
r_shaders = NULL;
free(shader_hash);
@ -3448,6 +3454,8 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
}
else return;
if (pass->texgen == T_GEN_LIGHTMAP && pass->blendmode == PBM_REPLACELIGHT && pass2->blendmode == PBM_MODULATE && config_tex_env_combine)
pass2->blendmode = PBM_OVERBRIGHT;
if (pass2->texgen == T_GEN_LIGHTMAP && pass2->blendmode == PBM_MODULATE && config_tex_env_combine)
pass2->blendmode = PBM_OVERBRIGHT;
}
@ -4020,7 +4028,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
if (!builtin)
builtin = (
"{\n"
"if $deluxmap\n"
/* "if $deluxmap\n"
"[\n"
"{\n"
"map $normalmap\n"
@ -4032,21 +4040,25 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"tcgen lightmap\n"
"}\n"
"]\n"
*/// "if !r_fullbright\n"
// "[\n"
"{\n"
"map $lightmap\n"
// "if $deluxmap\n"
// "[\n"
// "blendfunc gl_dst_color gl_zero\n"
// "]\n"
"}\n"
// "]\n"
"{\n"
"map $diffuse\n"
"tcgen base\n"
"if $deluxmap\n"
"[\n"
"blendfunc gl_one gl_zero\n"
"]\n"
// "if $deluxmap || !r_fullbright\n"
// "[\n"
// "blendfunc gl_dst_color gl_zero\n"
"blendfunc filter\n"
// "]\n"
"}\n"
"if !r_fullbright\n"
"[\n"
"{\n"
"map $lightmap\n"
"blendfunc gl_dst_color gl_zero\n"
"}\n"
"]\n"
"if gl_fb_bmodels\n"
"[\n"
"{\n"
@ -4086,6 +4098,115 @@ void Shader_DefaultSkybox(char *shortname, shader_t *s, const void *args)
);
}
char *Shader_DefaultBSPWater(char *shortname)
{
int wstyle;
if (r_wateralpha.value == 0)
wstyle = -1;
else if (r_fastturb.ival)
wstyle = 0;
#ifdef GLQUAKE
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && r_waterstyle.ival>0 && !r_fastturb.ival && strncmp(shortname, "*lava", 5))
wstyle = r_waterstyle.ival; //r_waterstyle does not apply to lava, and requires glsl and stuff
#endif
else
wstyle = 1;
{
switch(wstyle)
{
case -1: //invisible
return (
"{\n"
"sort blend\n"
"surfaceparm nodraw\n"
"surfaceparm nodlight\n"
"}\n"
);
case 0: //fastturb
return (
"{\n"
"sort blend\n"
"{\n"
"map $whiteimage\n"
"rgbgen const $r_fastturbcolour\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
default:
case 1: //vanilla style
return (
"{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"program defaultwarp\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"if r_wateralpha != 1\n"
"[\n"
"alphagen const $r_wateralpha\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"]\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
case 2: //refraction of the underwater surface, with a fresnel
return (
"{\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"program altwater#FRESNEL=4\n"
"}\n"
);
case 3: //ripples
return (
"{\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
case 4: //reflections
return (
"{\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
}
}
}
void Shader_DefaultBSPQ2(char *shortname, shader_t *s, const void *args)
{
if (!strncmp(shortname, "sky/", 4))
@ -4099,15 +4220,7 @@ void Shader_DefaultBSPQ2(char *shortname, shader_t *s, const void *args)
}
else if (!strncmp(shortname, "warp/", 5))
{
Shader_DefaultScript(shortname, s,
"{\n"
"program defaultwarp\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0 0.01 0.5 0\n"
"}\n"
"}\n"
);
Shader_DefaultScript(shortname, s, Shader_DefaultBSPWater(shortname));
}
else if (!strncmp(shortname, "warp33/", 7))
{
@ -4204,115 +4317,7 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
if (!builtin && (*shortname == '*'))
{
int wstyle;
if (r_wateralpha.value == 0)
wstyle = -1;
else if (r_fastturb.ival)
wstyle = 0;
else if (gl_config.arb_shader_objects && r_waterstyle.ival>0 && !r_fastturb.ival && strncmp(shortname, "*lava", 5))
wstyle = r_waterstyle.ival; //r_waterstyle does not apply to lava, and requires glsl and stuff
else
wstyle = 1;
{
switch(wstyle)
{
case -1: //invisible
builtin = (
"{\n"
"sort blend\n"
"surfaceparm nodraw\n"
"surfaceparm nodlight\n"
"}\n"
);
break;
case 0: //fastturb
builtin = (
"{\n"
"sort blend\n"
"{\n"
"map $whiteimage\n"
"rgbgen const $r_fastturbcolour\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
break;
default:
case 1: //vanilla style
builtin = (
"{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"program defaultwarp\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"if r_wateralpha != 1\n"
"[\n"
"alphagen const $r_wateralpha\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"]\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
break;
case 2: //refraction of the underwater surface, with a fresnel
builtin = (
"{\n"
"{\n"
"map $currentrender\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"program altwater#FRESNEL=4\n"
"}\n"
);
break;
case 3: //ripples
builtin = (
"{\n"
"{\n"
"map $currentrender\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
break;
case 4: //reflections
builtin = (
"{\n"
"{\n"
"map $currentrender\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
break;
}
}
builtin = Shader_DefaultBSPWater(shortname);
}
if (!builtin && !strncmp(shortname, "sky", 3))
{

View File

@ -1,5 +1,11 @@
#include "quakedef.h"
/*
room for improvement:
There is no screen-space culling of lit surfaces.
model meshes are interpolated multiple times per frame
*/
#if defined(GLQUAKE) || defined(D3DQUAKE)
#ifdef RTLIGHTS
@ -1098,6 +1104,7 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
int i, e;
mesh_t *sm;
vec3_t ext;
float sc;
cv.numedges = 0;
cv.numpoints = 0;
cv.numtris = 0;
@ -1107,7 +1114,7 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
sms = &sh_shmesh->batches[tno];
if (!sms->count)
continue;
if ((cl.worldmodel->textures[tno]->shader->flags & (SHADER_BLEND|SHADER_NODRAW)))
if ((cl.worldmodel->shadowbatches[tno].tex->shader->flags & (SHADER_BLEND|SHADER_NODRAW)))
continue;
for (sno = 0; sno < sms->count; sno++)
@ -1150,12 +1157,13 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
ext[0] = cv.points[i][0]-dl->origin[0];
ext[1] = cv.points[i][1]-dl->origin[1];
ext[2] = cv.points[i][2]-dl->origin[2];
VectorNormalize(ext);
sc = dl->radius * VectorNormalize(ext);
/*back face*/
sh_shmesh->verts[(i * 2) + 1][0] = cv.points[i][0] + ext[0] * dl->radius;
sh_shmesh->verts[(i * 2) + 1][1] = cv.points[i][1] + ext[1] * dl->radius;
sh_shmesh->verts[(i * 2) + 1][2] = cv.points[i][2] + ext[2] * dl->radius;
sh_shmesh->verts[(i * 2) + 1][0] = cv.points[i][0] + ext[0] * sc;
sh_shmesh->verts[(i * 2) + 1][1] = cv.points[i][1] + ext[1] * sc;
sh_shmesh->verts[(i * 2) + 1][2] = cv.points[i][2] + ext[2] * sc;
}
sh_shmesh->numverts = i*2;
@ -1229,7 +1237,7 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
{
case fg_quake:
case fg_halflife:
if (!dl->die)
/*if (!dl->die)
{
SHM_BeginShadowMesh(dl, true);
SHM_MarkLeavesQ1(dl, lvis);
@ -1237,7 +1245,7 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
if (!surfonly)
SHM_ComposeVolume_BruteForce(dl);
}
else
else*/
{
SHM_BeginShadowMesh(dl, surfonly);
SHM_MarkLeavesQ1(dl, lvis);
@ -1373,41 +1381,6 @@ typedef struct
} srect_t;
static void Sh_Scissor (srect_t r)
{
#if 0 //visible scissors
extern cvar_t temp1;
if (temp1.ival)
{
qglMatrixMode(GL_PROJECTION);
qglPushMatrix();
qglLoadIdentity();
qglOrtho (0, vid.pixelwidth, vid.pixelheight, 0, -99999, 99999);
qglMatrixMode(GL_MODELVIEW);
qglPushMatrix();
qglLoadIdentity();
// GL_Set2D();
qglColor4f(1,1,1,1);
qglDisable(GL_DEPTH_TEST);
qglDisable(GL_SCISSOR_TEST);
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
qglDisable(GL_TEXTURE_2D);
qglBegin(GL_LINE_LOOP);
qglVertex2f(r.x, vid.pixelheight - (r.y + r.height));
qglVertex2f(r.x+r.width, vid.pixelheight - (r.y + r.height));
qglVertex2f(r.x+r.width, vid.pixelheight - (r.y));
qglVertex2f(r.x, vid.pixelheight - (r.y));
qglEnd();
qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
qglMatrixMode(GL_PROJECTION);
qglPopMatrix();
qglMatrixMode(GL_MODELVIEW);
qglPopMatrix();
}
#endif
switch(qrenderer)
{
#ifdef GLQUAKE
@ -1516,7 +1489,7 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, srect_t *r)
r->height = vid.pixelheight;
r->dmin = 0;
r->dmax = 1;
if (1)//!r_shadow_scissor.integer)
if (0)//!r_shadow_scissor.integer)
{
return false;
}
@ -2332,11 +2305,6 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
struct shadowmesh_s *sm;
entity_t *ent;
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
BE_PushOffsetShadow(false);
#endif
sm = SHM_BuildShadowMesh(dl, lvis, vvis, false);
if (!sm)
Sh_DrawBrushModelShadow(dl, &r_worldentity);

View File

@ -592,8 +592,8 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglActiveStencilFaceEXT = (void *) getglext("glActiveStencilFaceEXT");
/*not enabled - its only useful for shadow volumes, but (on nvidia) it affects the depth values even when not clamped which results in shadow z-fighting. best rely upon infinite projection matricies instead*/
// if (GL_CheckExtension("GL_ARB_depth_clamp") || GL_CheckExtension("GL_NV_depth_clamp"))
// gl_config.arb_depth_clamp = true;
if (GL_CheckExtension("GL_ARB_depth_clamp") || GL_CheckExtension("GL_NV_depth_clamp"))
gl_config.arb_depth_clamp = true;
if (GL_CheckExtension("GL_ARB_texture_compression"))
{
@ -608,14 +608,14 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
else
gl_config.arb_texture_compression = true;
}
/*
if (GL_CheckExtension("GL_EXT_depth_bounds_test"))
qglDepthBoundsEXT = (void *)getglext("glDepthBoundsEXT");
else if (GL_CheckExtension("GL_NV_depth_bounds_test"))
qglDepthBoundsEXT = (void *)getglext("glDepthBoundsNV");
else
qglDepthBoundsEXT = NULL;
*/
if (GL_CheckExtension("GL_ATI_pn_triangles"))
{
qglPNTrianglesfATI = (void *)getglext("glPNTrianglesfATI");
@ -666,10 +666,14 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglUnmapBufferARB = (void *)getglext("glUnmapBufferARB");
}
if (0 && !gl_config.nofixedfunc)
{
Con_Printf(CON_NOTICE "GLSL disabled\n");
}
// glslang
//the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects.
//but our code kinda requires both for clean workings.
if (strstr(gl_renderer, " Mesa ") && Cvar_Get("gl_blacklist_mesa_glsl", "1", CVAR_RENDERERLATCH, "gl blacklists")->ival && (gl_config.glversion < 3 || gl_config.gles))
else if (strstr(gl_renderer, " Mesa ") && (gl_config.glversion < 3 || gl_config.gles) && Cvar_Get("gl_blacklist_mesa_glsl", "1", CVAR_RENDERERLATCH, "gl blacklists")->ival)
{
//(9:12:33 PM) bigfoot: Spike, can you please blacklist your menu shader on Mesa? My machine just hard locked up again because I forgot that pressing escape in FTE is verboten
//(11:51:42 PM) bigfoot: OpenGL vendor string: Tungsten Graphics, Inc
@ -936,7 +940,7 @@ static const char *glsl_hdrs[] =
"{\n"
"#if defined(RELIEFMAPPING) && !defined(GL_ES)\n"
"float i, f;\n"
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(1.0, -1.0), -1.0);\n"
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(-1.0, 1.0), -1.0);\n"
"vec3 RT = vec3(vec2(base.xy"/* - OffsetVector.xy*OffsetMapping_Bias*/"), 1.0);\n"
"OffsetVector /= 10.0;\n"
"for(i = 1.0; i < 10.0; ++i)\n"
@ -1073,6 +1077,10 @@ GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstan
length[strings] = strlen(prstrings[strings]);
strings++;
//prstrings[strings] = "invariant gl_Position;\n";
//length[strings] = strlen(prstrings[strings]);
//strings++;
switch (shadertype)
{
case GL_FRAGMENT_SHADER_ARB:
@ -1244,6 +1252,9 @@ GLhandleARB GLSlang_CreateProgramObject (char *name, GLhandleARB vert, GLhandleA
qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour");
qglBindAttribLocationARB(program, VATTR_TEXCOORD, "v_texcoord");
qglBindAttribLocationARB(program, VATTR_LMCOORD, "v_lmcoord");
qglBindAttribLocationARB(program, VATTR_LMCOORD2, "v_lmcoord2");
qglBindAttribLocationARB(program, VATTR_LMCOORD3, "v_lmcoord3");
qglBindAttribLocationARB(program, VATTR_LMCOORD4, "v_lmcoord4");
qglBindAttribLocationARB(program, VATTR_NORMALS, "v_normal");
qglBindAttribLocationARB(program, VATTR_SNORMALS, "v_svector");
qglBindAttribLocationARB(program, VATTR_TNORMALS, "v_tvector");

View File

@ -20,11 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "glquake.h"
#ifdef GL_ES_VERSION_2_0
qboolean gles2 = true;
#else
qboolean gles2 = false;
#endif
extern qboolean sys_glesversion;
static dllhandle_t *sys_gl_module = NULL;
@ -89,11 +85,11 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
Cons: GL_EndRendering call will not swap buffers. Buffers will be swapped on return to java.
*/
if (gles2)
if (sys_glesversion >= 2)
Sys_Printf("Loading GLES2 driver\n");
else
Sys_Printf("Loading GLES1 driver\n");
sys_gl_module = Sys_LoadLibrary(gles2?"libGLESv2.so":"libGLESv1_CM.so", NULL);
sys_gl_module = Sys_LoadLibrary((sys_glesversion>=2)?"libGLESv2.so":"libGLESv1_CM.so", NULL);
if (!sys_gl_module)
{
GLVID_DeInit();
@ -143,7 +139,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
gl_canstencil = 0;
const EGLint attribs[] = {
EGL_RENDERABLE_TYPE, gles2?EGL_OPENGL_ES2_BIT:EGL_OPENGL_ES_BIT,
EGL_RENDERABLE_TYPE, (sys_glesversion>=2)?EGL_OPENGL_ES2_BIT:EGL_OPENGL_ES_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BLUE_SIZE, (info->bpp==16)?5:8,
EGL_GREEN_SIZE, (info->bpp==16)?6:8,
@ -152,12 +148,12 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
// EGL_STENCIL_SIZE, 8,
EGL_NONE
};
EGLint ctxattribs[] = {EGL_CONTEXT_CLIENT_VERSION, gles2?2:1, EGL_NONE};
EGLint ctxattribs[] = {EGL_CONTEXT_CLIENT_VERSION, sys_glesversion, EGL_NONE};
EGLint w, h, dummy, format;
EGLint numConfigs;
EGLConfig config;
sys_gl_module = Sys_LoadLibrary(gles2?"libGLESv2.so":"libGLESv1_CM.so", NULL);
sys_gl_module = Sys_LoadLibrary((sys_glesversion>=2)?"libGLESv2.so":"libGLESv1_CM.so", NULL);
if (!sys_gl_module)
{
GLVID_DeInit();

View File

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "glquake.h"
#include "winquake.h"
#include "resource.h"
#include "shader.h"
#include <commctrl.h>
#ifndef SetWindowLongPtr //yes its a define, for unicode support
@ -1476,6 +1477,7 @@ void GLVID_Shutdown (void)
gammaworks = false;
GLBE_Shutdown();
VID_UnSetMode();
}
@ -1715,11 +1717,13 @@ qboolean GLAppActivate(BOOL fActive, BOOL minimize)
****************************************************************************/
{
static BOOL sound_active;
HWND foregroundwindow;
if (ActiveApp == fActive && Minimized == minimize)
return false; //so windows doesn't crash us over and over again.
ActiveApp = fActive;
foregroundwindow = GetForegroundWindow();
ActiveApp = fActive;// && (foregroundwindow==mainwindow);
Minimized = minimize;
// enable/disable sound on focus gain/loss
@ -1954,7 +1958,7 @@ LONG WINAPI GLMainWndProc (
case WM_ACTIVATE:
fActive = LOWORD(wParam);
fMinimized = (BOOL) HIWORD(wParam);
if (!GLAppActivate(!(fActive == WA_INACTIVE), fMinimized))
// if (!GLAppActivate(!(fActive == WA_INACTIVE), fMinimized))
break;//so, urm, tell me microsoft, what changed?
if (modestate == MS_FULLDIB)
ShowWindow(mainwindow, SW_SHOWNORMAL);

View File

@ -89,7 +89,7 @@ void R_DrawSkyChain (batch_t *batch)
return;
}
#if defined(GLQUAKE) && !defined(ANDROID)
if (*r_fastsky.string && qrenderer == QR_OPENGL && TEXVALID(batch->shader->defaulttextures.base))
if (*r_fastsky.string && qrenderer == QR_OPENGL && TEXVALID(batch->shader->defaulttextures.base) && TEXVALID(batch->shader->defaulttextures.fullbright))
{
R_CalcSkyChainBounds(batch);
@ -397,15 +397,15 @@ static void gl_skyspherecalc(int skytype)
skymesh.indexes = skysphere_element3i;
skymesh.st_array = (void*)skysphere_texcoord2f;
skymesh.lmst_array = (void*)skysphere_texcoord2f;
skymesh.lmst_array[0] = (void*)skysphere_texcoord2f;
skymesh.xyz_array = (void*)skysphere_vertex3f;
skymesh.numindexes = skysphere_numtriangles * 3;
skymesh.numvertexes = skysphere_numverts;
dx = 16;
dy = 16;
dz = 16 / 3;
dx = 1;
dy = 1;
dz = 1 / 3.0;
vertex = skysphere_vertex3f;
texcoord2f = skysphere_texcoord2f;
for (j = 0;j <= skygridy;j++)
@ -487,6 +487,7 @@ static void R_DrawSkyMesh(batch_t *batch, mesh_t *m, shader_t *shader)
b.shader = shader;
b.skin = &shader->defaulttextures;
b.texture = NULL;
b.vbo = NULL;
BE_SubmitBatch(&b);
}

View File

@ -22,8 +22,6 @@ int Doom_SectorNearPoint(vec3_t p);
//4. That ALL sectors are fully enclosed, and not made of two areas.
//5. That no sectors are inside out.
enum {
THING_PLAYER = 1,
THING_PLAYER2 = 2,
@ -162,8 +160,8 @@ typedef struct {
typedef struct {
int visframe;
shader_t *floortex;
shader_t *ceilingtex;
int floortex;
int ceilingtex;
short floorheight;
short ceilingheight;
@ -211,6 +209,21 @@ extern model_t *loadmodel;
extern char loadname[];
typedef struct
{
char name[8];
shader_t *shader;
unsigned short width;
unsigned short height;
batch_t batch;
mesh_t *meshptr;
mesh_t mesh;
int maxverts;
int maxindicies;
} gldoomtexture_t;
gldoomtexture_t *gldoomtextures;
int numgldoomtextures;
////////////////////////////////////////////////////////////////////////////////////////////
//physics
@ -696,47 +709,46 @@ void Doom_LoadPalette(void)
}
}
shader_t *Doom_LoadFlat(char *name)
int Doom_LoadFlat(char *flatname)
{
char *file;
char texname[64];
shader_t *shad;
int texnum;
Doom_LoadPalette();
sprintf(texname, "flats/%-.8s", flatname);
for (texnum = 0; texnum < numgldoomtextures; texnum++)
{
if (!strcmp(gldoomtextures[texnum].name, texname))
return texnum;
}
gldoomtextures = BZ_Realloc(gldoomtextures, sizeof(*gldoomtextures)*((numgldoomtextures+16)&~15));
memset(gldoomtextures + numgldoomtextures, 0, sizeof(gldoomtextures[numgldoomtextures]));
numgldoomtextures++;
strncpy(gldoomtextures[texnum].name, texname, 8);
gldoomtextures[texnum].shader = R_RegisterShader(texname, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\n}\n}\n");
gldoomtextures[texnum].width = 64;
gldoomtextures[texnum].height = 64;
gldoomtextures[texnum].meshptr = &gldoomtextures[texnum].mesh;
gldoomtextures[texnum].batch.mesh = &gldoomtextures[texnum].meshptr;
gldoomtextures[texnum].batch.next = loadmodel->batches[gldoomtextures[texnum].shader->sort];
loadmodel->batches[gldoomtextures[texnum].shader->sort] = &gldoomtextures[texnum].batch;
sprintf(texname, "flats/%-.8s", name);
Q_strlwr(texname);
shad = R_RegisterShader(texname, "{\n{\nmap $diffuse\n}\n}\n");
file = FS_LoadMallocFile(texname);
if (file)
{
shad->defaulttextures.base = R_LoadTexture8Pal24(texname, 64, 64, file, doompalette, 0);
gldoomtextures[texnum].shader->defaulttextures.base = R_LoadTexture8Pal24(texname, 64, 64, file, doompalette, 0);
Z_Free(file);
}
else
{
Con_Printf("Flat %-0.8s not found\n", name);
}
return shad;
return texnum;
}
typedef struct
{
char name[8];
shader_t *shader;
unsigned short width;
unsigned short height;
batch_t batch;
mesh_t *meshptr;
mesh_t mesh;
int maxverts;
int maxindicies;
} gldoomtexture_t;
gldoomtexture_t *gldoomtextures;
int numgldoomtextures;
static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float frontfloor, float x2, float y2, float backfloor, qboolean unpegged, unsigned int colour4b)
static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float z1, float x2, float y2, float z2, qboolean unpegged, unsigned int colour4b)
{
gldoomtexture_t *tex = gldoomtextures+texnum;
mesh_t *mesh = &tex->mesh;
@ -751,13 +763,15 @@ static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float fro
if (unpegged)
{
t2 = t/tex->height;
t1 = t2 - (backfloor-frontfloor)/tex->height;
t1 = t2 - (z2-z1)/tex->height;
}
else
{
t1 = t/tex->height;
t2 = t1 + (backfloor-frontfloor)/tex->height;
t2 = t1 + (z2-z1)/tex->height;
}
t1 = 0;
t2 = 1;
if (mesh->numvertexes+4 > tex->maxverts)
{
@ -773,19 +787,19 @@ static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float fro
}
col = colour4b * 0x01010101;
((unsigned int*)&col)[3] = 0xff;
((unsigned char*)&col)[3] = 0xff;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+0] = col;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+1] = col;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+2] = col;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+3] = col;
VectorSet(mesh->xyz_array[mesh->numvertexes+0], x1, y1, frontfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+1], x1, y1, backfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+2], x2, y2, backfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+3], x2, y2, frontfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+0], x1, y1, z1);
VectorSet(mesh->xyz_array[mesh->numvertexes+1], x1, y1, z2);
VectorSet(mesh->xyz_array[mesh->numvertexes+2], x2, y2, z2);
VectorSet(mesh->xyz_array[mesh->numvertexes+3], x2, y2, z1);
Vector2Set(mesh->st_array[mesh->numvertexes+0], s1, t2);
Vector2Set(mesh->st_array[mesh->numvertexes+1], s1, t1);
Vector2Set(mesh->st_array[mesh->numvertexes+2], s2, t1);
Vector2Set(mesh->st_array[mesh->numvertexes+2], s2, t2);
Vector2Set(mesh->st_array[mesh->numvertexes+3], s2, t2);
mesh->indexes[mesh->numindexes+0] = mesh->numvertexes+0;
mesh->indexes[mesh->numindexes+1] = mesh->numvertexes+1;
@ -797,6 +811,93 @@ static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float fro
mesh->numvertexes += 4;
mesh->numindexes += 6;
BE_DrawMesh_Single(tex->shader, mesh, NULL, &tex->shader->defaulttextures, 0);
}
static void GLR_DrawFlats(int floortexnum, int floorheight, int ceiltexnum, int ceilheight, int numverts, unsigned short *verts, unsigned int colour4b)
{
mesh_t *mesh;
unsigned int col;
unsigned int v, i;
//floor
{
gldoomtexture_t *floortex = gldoomtextures + floortexnum;
mesh = &floortex->mesh;
if (mesh->numvertexes+numverts > floortex->maxverts)
{
floortex->maxverts = mesh->numvertexes+numverts;
mesh->colors4b_array = BZ_Realloc(mesh->colors4b_array, sizeof(*mesh->colors4b_array) * floortex->maxverts);
mesh->xyz_array = BZ_Realloc(mesh->xyz_array, sizeof(*mesh->xyz_array) * floortex->maxverts);
mesh->st_array = BZ_Realloc(mesh->st_array, sizeof(*mesh->st_array) * floortex->maxverts);
}
if (mesh->numindexes+numverts > floortex->maxindicies)
{
floortex->maxindicies = mesh->numindexes+numverts;
mesh->indexes = BZ_Realloc(mesh->indexes, sizeof(*mesh->indexes) * floortex->maxindicies);
}
col = colour4b * 0x01010101;
((unsigned char*)&col)[3] = 0xff;
for (i = 0; i < numverts; i++)
{
v = verts[i];
VectorSet(mesh->xyz_array[mesh->numvertexes+i], vertexesl[v].xpos, vertexesl[v].ypos, floorheight);
Vector2Set(mesh->st_array[mesh->numvertexes+i], vertexesl[v].xpos/64.0f, vertexesl[v].ypos/64.0f);
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+i] = col;
}
for (i = 0; i < numverts; i++)
{
mesh->indexes[mesh->numindexes+i] = mesh->numvertexes+i;
}
mesh->numvertexes += numverts;
mesh->numindexes += numverts;
BE_DrawMesh_Single(floortex->shader, mesh, NULL, &floortex->shader->defaulttextures, 0);
}
//ceiling
{
gldoomtexture_t *ceiltex = gldoomtextures + ceiltexnum;
mesh = &ceiltex->mesh;
if (mesh->numvertexes+numverts > ceiltex->maxverts)
{
ceiltex->maxverts = mesh->numvertexes+numverts;
mesh->colors4b_array = BZ_Realloc(mesh->colors4b_array, sizeof(*mesh->colors4b_array) * ceiltex->maxverts);
mesh->xyz_array = BZ_Realloc(mesh->xyz_array, sizeof(*mesh->xyz_array) * ceiltex->maxverts);
mesh->st_array = BZ_Realloc(mesh->st_array, sizeof(*mesh->st_array) * ceiltex->maxverts);
}
if (mesh->numindexes+numverts > ceiltex->maxindicies)
{
ceiltex->maxindicies = mesh->numindexes+numverts;
mesh->indexes = BZ_Realloc(mesh->indexes, sizeof(*mesh->indexes) * ceiltex->maxindicies);
}
col = colour4b * 0x01010101;
((unsigned char*)&col)[3] = 0xff;
for (i = 0; i < numverts; i++)
{
v = verts[numverts-1-i];
VectorSet(mesh->xyz_array[mesh->numvertexes+i], vertexesl[v].xpos, vertexesl[v].ypos, ceilheight);
Vector2Set(mesh->st_array[mesh->numvertexes+i], vertexesl[v].xpos/64.0f, vertexesl[v].ypos/64.0f);
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+i] = col;
}
for (i = 0; i < numverts; i++)
{
mesh->indexes[mesh->numindexes+i] = mesh->numvertexes+i;
}
mesh->numvertexes += numverts;
mesh->numindexes += numverts;
BE_DrawMesh_Single(ceiltex->shader, mesh, NULL, &ceiltex->shader->defaulttextures, 0);
}
}
static void GLR_DrawSSector(unsigned int ssec)
@ -814,28 +915,8 @@ static void GLR_DrawSSector(unsigned int ssec)
if (sec->visframe != r_visframecount)
{
#if 0
qglColor4ub(sectorm[i].lightlev, sectorm[i].lightlev, sectorm[i].lightlev, 255);
GL_Bind(sectorm[i].floortex);
qglBegin(GL_TRIANGLES);
for (v = 0; v < sectorm[i].numflattris*3; v++)
{
v1 = sectorm[i].flats[v];
qglTexCoord2f(vertexesl[v1].xpos/64.0f, vertexesl[v1].ypos/64.0f);
qglVertex3f(vertexesl[v1].xpos, vertexesl[v1].ypos, sectorm[i].floorheight);
}
qglEnd();
GLR_DrawFlats(sec->floortex, sec->floorheight, sec->ceilingtex, sec->ceilingheight, sec->numflattris*3, sec->flats, sec->lightlev);
GL_Bind(sectorm[i].ceilingtex);
qglBegin(GL_TRIANGLES);
for (v = sectorm[i].numflattris*3-1; v >= 0; v--)
{
v1 = sectorm[i].flats[v];
qglTexCoord2f(vertexesl[v1].xpos/64.0f, vertexesl[v1].ypos/64.0f);
qglVertex3f(vertexesl[v1].xpos, vertexesl[v1].ypos, sectorm[i].ceilingheight);
}
qglEnd();
#endif
sec->visframe = r_visframecount;
}
for (seg = ssectorsl[ssec].first + ssectorsl[ssec].segcount-1; seg >= ssectorsl[ssec].first; seg--)
@ -1479,7 +1560,7 @@ static void Doom_ExtractPName(unsigned int *out, doomimage_t *di, int outwidth,
}
}
static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned short *width, unsigned short *height)
static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned short *width, unsigned short *height, qboolean *hasalpha)
{
char patch[32] = "patches/";
unsigned int *tex;
@ -1498,7 +1579,7 @@ static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned shor
if (!strncmp(tx->name, name, 8))
{
tex = BZ_Malloc(tx->width*tx->height*4);
memset(tex, 255, tx->width*tx->height*4);
memset(tex, 0, tx->width*tx->height*4);
*width = tx->width;
*height = tx->height;
tc = (ddoomtexturecomponant_t*)(tx+1);
@ -1511,6 +1592,16 @@ static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned shor
Doom_ExtractPName(tex, (doomimage_t *)COM_LoadTempFile(patch), tx->width, tx->height, tc->xoffset, tc->yoffset);
}
*hasalpha = false;
for (i = 0; i < tx->width * tx->height; i++)
{
if (!(tex[i] & 0xff000000))
{
*hasalpha = true;
break;
}
}
result = R_LoadTexture32(name, tx->width, tx->height, tex, 0);
BZ_Free(tex);
return result;
@ -1523,6 +1614,8 @@ static texid_t Doom_LoadPatchFromTexWad(char *name, void *texlump, unsigned shor
}
static int Doom_LoadPatch(char *name)
{
texid_t tex;
qboolean hasalpha = false;
int texnum;
for (texnum = 0; texnum < numgldoomtextures; texnum++) //a hash table might be a good plan.
@ -1541,27 +1634,28 @@ static int Doom_LoadPatch(char *name)
strncpy(gldoomtextures[texnum].name, name, 8);
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\nrgbgen vertex\n}\n}\n");
tex = r_nulltex;
if (textures1 && !TEXVALID(tex))
tex = Doom_LoadPatchFromTexWad(name, textures1, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height, &hasalpha);
if (textures2 && !TEXVALID(tex))
tex = Doom_LoadPatchFromTexWad(name, textures2, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height, &hasalpha);
if (!TEXVALID(tex))
{
//all else failed.
gldoomtextures[texnum].width = image_width;
gldoomtextures[texnum].height = image_height;
gldoomtextures[texnum].meshptr = &gldoomtextures[texnum].mesh;
gldoomtextures[texnum].batch.mesh = &gldoomtextures[texnum].meshptr;
gldoomtextures[texnum].batch.next = loadmodel->batches[gldoomtextures[texnum].shader->sort];
loadmodel->batches[gldoomtextures[texnum].shader->sort] = &gldoomtextures[texnum].batch;
}
if (hasalpha)
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\nalphafunc ge128\n}\n}\n");
else
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\nrgbgen vertex\nalphagen vertex\n}\n}\n");
gldoomtextures[texnum].shader->defaulttextures.base = tex;
if (textures1)
{
gldoomtextures[texnum].shader->defaulttextures.base = Doom_LoadPatchFromTexWad(name, textures1, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height);
if (TEXVALID(gldoomtextures[texnum].shader->defaulttextures.base))
return texnum;
}
if (textures2)
{
gldoomtextures[texnum].shader->defaulttextures.base = Doom_LoadPatchFromTexWad(name, textures2, &gldoomtextures[texnum].width, &gldoomtextures[texnum].height);
if (TEXVALID(gldoomtextures[texnum].shader->defaulttextures.base))
return texnum;
}
//all else failed.
gldoomtextures[texnum].width = image_width;
gldoomtextures[texnum].height = image_height;
gldoomtextures[texnum].meshptr = &gldoomtextures[texnum].mesh;
gldoomtextures[texnum].batch.mesh = &gldoomtextures[texnum].meshptr;
gldoomtextures[texnum].batch.next = loadmodel->batches[gldoomtextures[texnum].shader->sort];
loadmodel->batches[gldoomtextures[texnum].shader->sort] = &gldoomtextures[texnum].batch;
return texnum;
}
static void Doom_Purge (struct model_s *mod)

View File

@ -213,7 +213,7 @@ typedef struct
hlmdl_tex_t *textures;
hlmdl_bone_t *bones;
hlmdl_bonecontroller_t *bonectls;
texid_t *texnums;
shader_t **shaders;
} hlmodel_t;
typedef struct //this is stored as the cache. an hlmodel_t is generated when drawing
@ -223,7 +223,7 @@ typedef struct //this is stored as the cache. an hlmodel_t is generated when dra
int textures;
int bones;
int bonectls;
int texnums;
int shaders;
} hlmodelcache_t;
/* HL mathlib prototypes: */

View File

@ -5,8 +5,25 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#ifdef GLQUAKE
{QR_OPENGL, 110, "altwater",
//modifier: REFLECT
//modifier: REFLECT (s_t2 is a reflection instead of diffusemap)
//modifier: STRENGTH (0.1 = fairly gentle, 0.2 = big waves)
//modifier: FRESNEL (5=water)
//modifier: TXSCALE (0.2 - wave strength)
//modifier: RIPPLEMAP (s_t3 contains a ripplemap
//modifier: TINT (some colour value)
"#ifndef FRESNEL\n"
"#define FRESNEL 5.0\n"
"#endif\n"
"#ifndef STRENGTH\n"
"#define STRENGTH 0.1\n"
"#endif\n"
"#ifndef TXSCALE\n"
"#define TXSCALE 0.2\n"
"#endif\n"
"#ifndef TINT\n"
"#define TINT vec3(0.7, 0.8, 0.7)\n"
"#endif\n"
"varying vec2 tc;\n"
"varying vec4 tf;\n"
@ -28,9 +45,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0; //refract\n"
"uniform sampler2D s_t1; //normalmap\n"
"uniform sampler2D s_t2; //diffuse\n"
"#ifdef REFLECT\n"
"uniform sampler2D s_t3; //reflect\n"
"uniform sampler2D s_t2; //diffuse/reflection\n"
"#ifdef RIPPLEMAP\n"
"uniform sampler2D s_t3; //ripplemap\n"
"#endif\n"
"uniform float e_time;\n"
@ -46,27 +63,29 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
//generate the two wave patterns from the normalmap
"n = (texture2D(s_t1, 0.2*tc + vec2(e_time*0.1, 0)).xyz);\n"
"n += (texture2D(s_t1, 0.2*tc - vec2(0, e_time*0.097)).xyz);\n"
"n = (texture2D(s_t1, TXSCALE*tc + vec2(e_time*0.1, 0)).xyz);\n"
"n += (texture2D(s_t1, TXSCALE*tc - vec2(0, e_time*0.097)).xyz);\n"
"n -= 1.0 - 4.0/256.0;\n"
"n = normalize(n);\n"
"#if 1//def REFRACT\n"
"refr = texture2D(s_t0, stc + n.st*0.2).rgb;\n"
"#else\n"
"refr = texture2D(s_t2, ntc).xyz;\n"
"#endif\n"
"#ifdef REFLECT\n"
"refl = texture2D(s_t3, stc - n.st*0.2).rgb;\n"
"#else\n"
"refl = texture2D(s_t2, ntc).xyz;\n"
"#ifdef RIPPLEMAP\n"
"n += texture2D(s_t3, stc)*3;\n"
"#endif\n"
//the fresnel term decides how transparent the water should be
"f = pow(1.0-abs(dot(n, normalize(eye))), float(FRESNEL));\n"
"f = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));\n"
"refr = texture2D(s_t0, stc + n.st*STRENGTH).rgb * TINT;\n"
"#ifdef REFLECT\n"
"refl = texture2D(s_t2, stc - n.st*STRENGTH).rgb;\n"
"#else\n"
"refl = texture2D(s_t2, ntc).xyz;\n"
"#endif\n"
// refl += 0.1*pow(dot(n, vec3(0.0,0.0,1.0)), 64.0);
"fres = refr * (1.0-f) + refl*f;\n"
// fres = texture2D(s_t2, stc).xyz;
"gl_FragColor = vec4(fres, 1.0);\n"
"}\n"
"#endif\n"
@ -483,6 +502,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!permu OFFSETMAPPING\n"
"!!permu FULLBRIGHT\n"
"!!permu FOG\n"
"!!permu LIGHTSTYLED\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
//this is what normally draws all of your walls, even with rtlights disabled
@ -492,10 +512,24 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#if defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"varying vec2 tc;\n"
"#ifdef LIGHTSTYLED\n"
//we could use an offset, but that would still need to be per-surface which would break batches
//fixme: merge attributes?
"varying vec2 lm, lm2, lm3, lm4;\n"
"#else\n"
"varying vec2 lm;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 tc, lm;\n"
"#ifdef LIGHTSTYLED\n"
"attribute vec2 v_lmcoord2;\n"
"attribute vec2 v_lmcoord3;\n"
"attribute vec2 v_lmcoord4;\n"
"#endif\n"
"#if defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"attribute vec3 v_normal;\n"
@ -506,16 +540,24 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"{\n"
"#if defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
"eyevector.x = dot(eyeminusvertex, v_svector.xyz);\n"
"eyevector.y = -dot(eyeminusvertex, v_tvector.xyz);\n"
"eyevector.x = -dot(eyeminusvertex, v_svector.xyz);\n"
"eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n"
"eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n"
"#endif\n"
"tc = v_texcoord;\n"
"lm = v_lmcoord;\n"
"#ifdef LIGHTSTYLED\n"
"lm2 = v_lmcoord2;\n"
"lm3 = v_lmcoord3;\n"
"lm4 = v_lmcoord4;\n"
"#endif\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
//samplers
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"#ifdef OFFSETMAPPING\n"
@ -524,8 +566,17 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4;\n"
"#endif\n"
"varying vec2 tc, lm;\n"
"#ifdef LIGHTSTYLED\n"
"uniform sampler2D s_t5;\n"
"uniform sampler2D s_t6;\n"
"uniform sampler2D s_t7;\n"
"#endif\n"
"#ifdef LIGHTSTYLED\n"
"uniform vec4 e_lmscale[4];\n"
"#else\n"
"uniform vec4 e_lmscale;\n"
"#endif\n"
"uniform vec4 e_colourident;\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
@ -536,7 +587,18 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
"gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"gl_FragColor = texture2D(s_t0, tc);\n"
"#ifdef LIGHTSTYLED\n"
"vec4 lightmaps;\n"
"lightmaps = texture2D(s_t1, lm ) * e_lmscale[0];\n"
"lightmaps += texture2D(s_t5, lm2) * e_lmscale[1];\n"
"lightmaps += texture2D(s_t6, lm3) * e_lmscale[2];\n"
"lightmaps += texture2D(s_t7, lm4) * e_lmscale[3];\n"
"gl_FragColor.rgb *= lightmaps.rgb;\n"
"#else\n"
"gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
"#endif\n"
@ -865,13 +927,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"tcbase = v_texcoord; //pass the texture coords straight through\n"
"vec3 lightminusvertex = l_lightposition - w.xyz;\n"
"lightvector.x = dot(lightminusvertex, s.xyz);\n"
"lightvector.x = -dot(lightminusvertex, s.xyz);\n"
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = -dot(eyeminusvertex, t.xyz);\n"
"eyevector.x = -dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = dot(eyeminusvertex, t.xyz);\n"
"eyevector.z = dot(eyeminusvertex, n.xyz);\n"
"#endif\n"
"#if defined(PCF) || defined(SPOT) || defined(PROJECTION) || defined(CUBE)\n"
@ -906,30 +968,37 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"void main ()\n"
"{\n"
//read raw texture samples (offsetmapping munges the tex coords first)
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);\n"
"#define tcbase tcoffsetmap\n"
"#endif\n"
"vec3 bases = vec3(texture2D(s_t0, tcbase));\n"
"#if defined(BUMP) || defined(SPECULAR)\n"
"vec3 bumps = vec3(texture2D(s_t1, tcbase)) - 0.5;\n"
"vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5);\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec4 specs = texture2D(s_t2, tcbase);\n"
"#endif\n"
"vec3 nl = normalize(lightvector);\n"
"float colorscale = max(1.0 - dot(lightvector, lightvector)/(l_lightradius*l_lightradius), 0.0);\n"
"float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);\n"
"vec3 diff;\n"
"#ifdef BUMP\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(2.0*bumps, nl), 0.0));\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));\n"
"#else\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec3 halfdir = normalize(lightvector - normalize(eyevector));\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 1.0 + 32.0 * specs.a);\n"
"diff += spec * specs.rgb * l_lightcolourscale.z;\n"
"vec3 halfdir = normalize(normalize(eyevector) + nl);\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);\n"
"diff += l_lightcolourscale.z * spec * specs.rgb;\n"
"#endif\n"
"#ifdef CUBE\n"
"diff *= textureCube(s_t3, vshadowcoord.xyz).rgb;\n"
"#endif\n"

View File

@ -268,7 +268,8 @@ enum{
PERMUTATION_SKELETAL = 32,
PERMUTATION_FOG = 64,
PERMUTATION_FRAMEBLEND = 128,
PERMUTATIONS = 256
PERMUTATION_LIGHTSTYLES = 256,
PERMUTATIONS = 512
};
enum shaderattribs_e
@ -285,6 +286,9 @@ enum shaderattribs_e
VATTR_TNORMALS,
VATTR_BONENUMS, /*skeletal only*/
VATTR_BONEWEIGHTS, /*skeletal only*/
VATTR_LMCOORD2,
VATTR_LMCOORD3,
VATTR_LMCOORD4,
VATTR_LEG_COLOUR,
VATTR_LEG_ELEMENTS,
@ -381,13 +385,13 @@ typedef struct {
} polyoffset_t;
struct shader_s
{
char name[MAX_QPATH];
int uses;
int width;
int height;
int numpasses;
texnums_t defaulttextures;
struct shader_s *next;
char name[MAX_QPATH];
//end of shared fields.
byte_vec4_t fog_color;
@ -486,6 +490,7 @@ mfog_t *CM_FogForOrigin(vec3_t org);
#ifdef GLQUAKE
void GLBE_Init(void);
void GLBE_Shutdown(void);
void GLBE_SelectMode(backendmode_t mode);
void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **mesh, vbo_t *vbo, texnums_t *texnums, unsigned int beflags);
void GLBE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums, unsigned int beflags);
@ -519,6 +524,27 @@ qboolean D3DShader_CreateProgram (program_t *prog, int permu, char **precompiler
int D3DShader_FindUniform(union programhandle_u *h, int type, char *name);
void D3DShader_Init(void);
void D3DBE_Reset(qboolean before);
void D3D11BE_Init(void);
void D3D11BE_SelectMode(backendmode_t mode);
void D3D11BE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **mesh, vbo_t *vbo, texnums_t *texnums, unsigned int beflags);
void D3D11BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums, unsigned int beflags);
void D3D11BE_SubmitBatch(batch_t *batch);
batch_t *D3D11BE_GetTempBatch(void);
void D3D11BE_GenBrushModelVBO(model_t *mod);
void D3D11BE_ClearVBO(vbo_t *vbo);
void D3D11BE_UploadAllLightmaps(void);
void D3D11BE_DrawWorld (qbyte *vis);
qboolean D3D11BE_LightCullModel(vec3_t org, model_t *model);
void D3D11BE_SelectEntity(entity_t *ent);
void D3D11BE_SelectDLight(dlight_t *dl, vec3_t colour);
qboolean D3D11Shader_CreateProgram (program_t *prog, int permu, char **precompilerconstants, char *vert, char *frag);
int D3D11Shader_FindUniform(union programhandle_u *h, int type, char *name);
void D3D11Shader_Init(void);
void D3D11BE_Reset(qboolean before);
#endif
//Asks the backend to invoke DrawMeshChain for each surface, and to upload lightmaps as required

View File

@ -31,43 +31,64 @@
PR_PrintStatement
=================
*/
/*
void PR_PrintStatement (progfuncs_t *progfuncs, dstatement16_t *s)
static void PR_PrintStatement (progfuncs_t *progfuncs, int statementnum)
{
int i;
printf("PR_PrintStatement is unsupported\n");
return;
if ( (unsigned)s->op < OP_NUMOPS)
unsigned int op;
unsigned int arg[3];
switch(current_progstate->structtype)
{
printf ("%s ", pr_opcodes[s->op].name);
i = strlen(pr_opcodes[s->op].name);
case PST_DEFAULT:
case PST_QTEST:
op = ((dstatement16_t*)current_progstate->statements + statementnum)->op;
arg[0] = ((dstatement16_t*)current_progstate->statements + statementnum)->a;
arg[1] = ((dstatement16_t*)current_progstate->statements + statementnum)->b;
arg[2] = ((dstatement16_t*)current_progstate->statements + statementnum)->c;
break;
case PST_KKQWSV:
case PST_FTE32:
op = ((dstatement32_t*)current_progstate->statements + statementnum)->op;
arg[0] = ((dstatement32_t*)current_progstate->statements + statementnum)->a;
arg[1] = ((dstatement32_t*)current_progstate->statements + statementnum)->b;
arg[2] = ((dstatement32_t*)current_progstate->statements + statementnum)->c;
break;
}
#ifndef MINIMAL
if ( (unsigned)op < OP_NUMOPS)
{
printf ("%s ", pr_opcodes[op].name);
i = strlen(pr_opcodes[op].name);
for ( ; i<10 ; i++)
printf (" ");
}
else
#endif
printf ("op%3i ");
if (s->op == OP_IF || s->op == OP_IFNOT)
printf ("%sbranch %i",PR_GlobalString(progfuncs, s->a),s->b);
else if (s->op == OP_GOTO)
if (op == OP_IF_F || op == OP_IFNOT_F)
printf ("%sbranch %i",PR_GlobalString(progfuncs, arg[0]),arg[1]);
else if (op == OP_GOTO)
{
printf ("branch %i",s->a);
printf ("branch %i",arg[0]);
}
else if ( (unsigned)(s->op - OP_STORE_F) < 6)
else if ( (unsigned)(op - OP_STORE_F) < 6)
{
printf ("%s",PR_GlobalString(progfuncs, s->a));
printf ("%s", PR_GlobalStringNoContents(progfuncs, s->b));
printf ("%s",PR_GlobalString(progfuncs, arg[0]));
printf ("%s", PR_GlobalStringNoContents(progfuncs, arg[1]));
}
else
{
if (s->a)
printf ("%s",PR_GlobalString(progfuncs, s->a));
if (s->b)
printf ("%s",PR_GlobalString(progfuncs, s->b));
if (s->c)
printf ("%s", PR_GlobalStringNoContents(progfuncs, s->c));
if (arg[0])
printf ("%s",PR_GlobalString(progfuncs, arg[0]));
if (arg[1])
printf ("%s",PR_GlobalString(progfuncs, arg[1]));
if (arg[2])
printf ("%s", PR_GlobalStringNoContents(progfuncs, arg[2]));
}
printf ("\n");
}
*/
/*
============
@ -808,6 +829,12 @@ static char *lastfile = 0;
int i;
dfunction_t *f = pr_xfunction;
if (!externs->useeditor)
{
PR_PrintStatement(progfuncs, statement);
return statement;
}
if (f && pr_progstate[pn].linenums && externs->useeditor)
{
if (lastline == pr_progstate[pn].linenums[statement] && lastfile == f->s_file+progfuncs->stringtable)

View File

@ -262,6 +262,7 @@ typedef union eval_s
#define PR_AddString(pf, ed, len) (*pf->AddString) (pf, ed, len)
#define PR_Alloc(pf,size,whatfor) (*pf->Tempmem) (pf, size, whatfor)
#define PR_AddressableAlloc(pf,size) (*pf->AddressableAlloc) (pf, size)
#define PR_AddressableFree(pf,mem) (*pf->AddressableFree) (pf, mem)
#define PROG_TO_EDICT(pf, ed) (*pf->ProgsToEdict) (pf, ed)
#define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, (struct edict_s*)ed)

View File

@ -1450,7 +1450,7 @@ static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement
newofs = 0;
for (i = firststatement, st = &statements[i]; i < laststatement; i++, st++)
{
if (pr_opcodes[st->op].type_a && st->a == t->ofs)
if (pr_opcodes[st->op].type_a && st->a >= t->ofs && st->a < t->ofs + t->size)
{
if (!newofs)
{
@ -1467,9 +1467,9 @@ static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement
#endif
pr.localvars = def;
}
st->a = newofs;
st->a = st->a - t->ofs + newofs;
}
if (pr_opcodes[st->op].type_b && st->b == t->ofs)
if (pr_opcodes[st->op].type_b && st->b >= t->ofs && st->b < t->ofs + t->size)
{
if (!newofs)
{
@ -1486,9 +1486,9 @@ static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement
#endif
pr.localvars = def;
}
st->b = newofs;
st->b = st->b - t->ofs + newofs;
}
if (pr_opcodes[st->op].type_c && st->c == t->ofs)
if (pr_opcodes[st->op].type_c && st->c >= t->ofs && st->c < t->ofs + t->size)
{
if (!newofs)
{
@ -1505,7 +1505,7 @@ static void QCC_RemapLockedTemp(temp_t *t, int firststatement, int laststatement
#endif
pr.localvars = def;
}
st->c = newofs;
st->c = st->c - t->ofs + newofs;
}
}
}
@ -4259,7 +4259,8 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
{
allowarray = false;
if (idx)
allowarray = t->arraysize>0;
allowarray = t->arraysize>0 ||
(t->type == ev_vector);
else if (!idx)
{
allowarray = d->arraysize ||
@ -4285,7 +4286,7 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
{
/*automatic runtime bounds checks on strings, I'm not going to check this too much...*/
}
else if (!idx && d->type->type == ev_vector && !d->arraysize)
else if ((!idx && d->type->type == ev_vector && !d->arraysize) || (idx && t->type == ev_vector && !t->arraysize))
{
if (tmp->constant)
{
@ -4297,7 +4298,7 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
if (i < 0 || i >= 3)
QCC_PR_ParseErrorPrintDef(0, d, "(vector) array index out of bounds");
}
else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
else if (QCC_OPCodeValid(&pr_opcodes[OP_BOUNDCHECK]))
{
tmp = QCC_SupplyConversion(tmp, ev_integer, true);
QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, 3, 0, false);
@ -4320,13 +4321,14 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
}
else
{
if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))
if (QCC_OPCodeValid(&pr_opcodes[OP_BOUNDCHECK]))
{
tmp = QCC_SupplyConversion(tmp, ev_integer, true);
QCC_PR_SimpleStatement (OP_BOUNDCHECK, tmp->ofs, ((!idx)?d->arraysize:t->arraysize), 0, false);
}
}
if (t->size != 1 && (idx || QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F]))) /*don't multiply by type size if the instruction/emulation will do that instead*/
if (t->size != 1) /*don't multiply by type size if the instruction/emulation will do that instead*/
{
if (tmp->type->type == ev_float)
tmp = QCC_PR_Statement(&pr_opcodes[OP_MUL_F], tmp, QCC_MakeFloatConst(t->size), NULL);
@ -4335,7 +4337,9 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
}
/*calc the new index*/
if (idx)
if (idx && idx->type->type == ev_float && tmp->type->type == ev_float)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], idx, QCC_SupplyConversion(tmp, ev_float, true), NULL);
else if (idx)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, QCC_SupplyConversion(tmp, ev_integer, true), NULL);
else
idx = tmp;
@ -4356,11 +4360,22 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
if (!t)
QCC_PR_ParseError(0, "%s is not a member", pr_token);
tmp = QCC_MakeIntConst(t->ofs);
if (idx)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, tmp, NULL);
if (QCC_OPCodeValid(&pr_opcodes[OP_ADD_I]))
{
tmp = QCC_MakeIntConst(t->ofs);
if (idx)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_I], idx, tmp, NULL);
else
idx = tmp;
}
else
idx = tmp;
{
tmp = QCC_MakeFloatConst(t->ofs);
if (idx)
idx = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], idx, tmp, NULL);
else
idx = tmp;
}
}
else
break;
@ -4479,7 +4494,7 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 0, false);
rhs = QCC_PR_Expression(TOP_PRIORITY, 0);
if (rhs->type->type != d->type->type)
if (rhs->type->type != t->type)
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "Type Mismatch on array assignment");
args[0] = QCC_SupplyConversion(idx, ev_float, true);
@ -4536,12 +4551,55 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign)
d->references++;
/*make sure the function type that we're calling exists*/
def_parms[0].type = type_float;
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 0, false);
args[0] = QCC_SupplyConversion(idx, ev_float, true);
d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
d->type = t;
if (d->type->type == ev_vector)
{
def_parms[0].type = type_vector;
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 0, false);
args[0] = QCC_SupplyConversion(idx, ev_float, true);
d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
d->type = t;
}
else
{
def_parms[0].type = type_float;
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 0, false);
if (t->size > 1)
{
QCC_def_t *r;
unsigned int i;
int old_op = opt_assignments;
d = QCC_GetTemp(t);
idx = QCC_SupplyConversion(idx, ev_float, true);
for (i = 0; i < t->size; i++)
{
if (i)
args[0] = QCC_PR_Statement(&pr_opcodes[OP_ADD_F], idx, QCC_MakeFloatConst(i), (QCC_dstatement_t **)0xffffffff);
else
{
args[0] = idx;
opt_assignments = false;
}
r = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
opt_assignments = old_op;
QCC_UnFreeTemp(idx);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], r, d, (QCC_dstatement_t **)0xffffffff));
d->ofs++;
}
QCC_FreeTemp(idx);
d->ofs -= i;
QCC_UnFreeTemp(d);
}
else
{
args[0] = QCC_SupplyConversion(idx, ev_float, true);
d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
}
d->type = t;
}
}
/*parse recursively*/
@ -7582,6 +7640,13 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi
{
QCC_dstatement_t *st;
QCC_def_t *eq;
int stride;
if (array->type->type == ev_vector)
stride = 3;
else
stride = 1; //struct arrays should be 1, so that every element can be accessed...
if (min == max || min+1 == max)
{
eq = QCC_PR_Statement(pr_opcodes+OP_LT_F, index, QCC_MakeFloatConst(min+0.5f), NULL);
@ -7589,7 +7654,7 @@ void QCC_PR_ArrayRecurseDivideRegular(QCC_def_t *array, QCC_def_t *index, int mi
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
st->b = 2;
QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
st->a = array->ofs + min*array->type->size;
st->a = array->ofs + min*stride;
}
else
{
@ -7650,6 +7715,12 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
QCC_dfunction_t *df;
QCC_def_t *temp, *index, *func;
int numslots;
//array shouldn't ever be a vector array
numslots = array->arraysize*array->type->size;
numslots = (numslots+2)/3;
func = QCC_PR_GetDef(type_function, qcva("ArrayGetVec*%s", array->name), NULL, true, 0, false);
pr_scope = func;
@ -7674,7 +7745,7 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatConst(3), temp, false);
QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, temp, temp, temp, false);//round down to int
QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, (array->arraysize+2)/3); //round up
QCC_PR_ArrayRecurseDivideUsingVectors(array, temp, 0, numslots);
QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, NULL); //err... we didn't find it, give up.
QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL); //err... we didn't find it, give up.
@ -7694,6 +7765,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
QCC_def_t *eq;
QCC_def_t *fasttrackpossible;
int numslots;
if (flag_fasttrackarrays)
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
@ -7702,10 +7774,13 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0, false);
if (def->arraysize >= 15 && def->type->size == 1)
{
if (def->type->type == ev_vector)
numslots = def->arraysize;
else
numslots = def->arraysize*def->type->size;
if (numslots >= 15 && def->type->type != ev_vector)
vectortrick = QCC_PR_EmitArrayGetVector(def);
}
else
vectortrick = NULL;
@ -7733,7 +7808,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
//fetch_gbl takes: (float size, variant array[]), float index, variant pos
//note that the array size is coded into the globals, one index before the array.
if (def->type->size >= 3)
if (def->type->type == ev_vector)
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_V], def, index, &def_ret, true);
else
QCC_PR_Statement3(&pr_opcodes[OP_FETCH_GBL_F], def, index, &def_ret, true);
@ -7755,7 +7830,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 0, false);
intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 0, false);
eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatConst((float)def->arraysize), NULL); //escape clause - should call some sort of error function instead.. that'd rule!
eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatConst((float)numslots), NULL); //escape clause - should call some sort of error function instead.. that'd rule!
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
st->b = 2;
QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, &st);
@ -7800,7 +7875,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
else
{
QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false);
QCC_PR_ArrayRecurseDivideRegular(def, index, 0, def->arraysize);
QCC_PR_ArrayRecurseDivideRegular(def, index, 0, numslots);
}
QCC_PR_Statement(pr_opcodes+OP_RETURN, QCC_MakeFloatConst(0), 0, NULL);
@ -7820,17 +7895,24 @@ void QCC_PR_ArraySetRecurseDivide(QCC_def_t *array, QCC_def_t *index, QCC_def_t
{
QCC_dstatement_t *st;
QCC_def_t *eq;
int stride;
if (array->type->type == ev_vector)
stride = 3;
else
stride = 1; //struct arrays should be 1, so that every element can be accessed...
if (min == max || min+1 == max)
{
eq = QCC_PR_Statement(pr_opcodes+OP_EQ_F, index, QCC_MakeFloatConst((float)min), NULL);
QCC_UnFreeTemp(index);
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
st->b = 3;
if (array->type->size == 3)
if (stride == 3)
QCC_PR_Statement(pr_opcodes+OP_STORE_V, value, array, &st);
else
QCC_PR_Statement(pr_opcodes+OP_STORE_F, value, array, &st);
st->b = array->ofs + min*array->type->size;
st->b = array->ofs + min*stride;
QCC_PR_Statement(pr_opcodes+OP_RETURN, 0, 0, &st);
}
else
@ -7858,6 +7940,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
QCC_def_t *def, *index, *value;
QCC_def_t *fasttrackpossible;
int numslots;
if (flag_fasttrackarrays)
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
@ -7867,6 +7950,11 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
def = QCC_PR_GetDef(NULL, arrayname, NULL, false, 0, false);
pr_scope = scope;
if (def->type->type == ev_vector)
numslots = def->arraysize;
else
numslots = def->arraysize*def->type->size;
if (numfunctions >= MAX_FUNCTIONS)
QCC_Error(ERR_INTERNAL, "Too many function defs");
@ -7910,7 +7998,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
}
QCC_PR_Statement3(pr_opcodes+OP_BITAND_F, index, index, index, false);
QCC_PR_ArraySetRecurseDivide(def, index, value, 0, def->arraysize);
QCC_PR_ArraySetRecurseDivide(def, index, value, 0, numslots);
QCC_PR_Statement(pr_opcodes+OP_DONE, 0, 0, NULL);
@ -8278,7 +8366,12 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
{ //write the array size
ofs = QCC_GetFreeOffsetSpace(1 + (type->size * arraysize));
((int *)qcc_pr_globals)[ofs] = arraysize-1; //An array needs the size written first. This is a hexen2 opcode thing.
//An array needs the size written first. This is a hexen2 opcode thing.
//note that for struct emulation, union and struct arrays, the size is the total size of global slots, rather than array elements
if (type->type == ev_vector)
((int *)qcc_pr_globals)[ofs] = arraysize-1;
else
((int *)qcc_pr_globals)[ofs] = (arraysize*type->size)-1;
ofs++;
}
else

View File

@ -495,6 +495,21 @@ void SVPR_Event_Think(world_t *w, wedict_t *s)
PR_ExecuteProgram (w->progs, s->v->think);
}
qboolean SVPR_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype)
{
if (ent->xv->contentstransition)
{
void *pr_globals = PR_globals(w->progs, PR_CURRENT);
pr_global_struct->self = EDICT_TO_PROG(w->progs, ent);
pr_global_struct->time = w->physicstime;
G_FLOAT(OFS_PARM0) = oldwatertype;
G_FLOAT(OFS_PARM1) = newwatertype;
PR_ExecuteProgram (w->progs, ent->xv->contentstransition);
return true;
}
return false; //do legacy behaviour
}
void Q_SetProgsParms(qboolean forcompiler)
{
progstype = PROG_NONE;
@ -547,6 +562,7 @@ void Q_SetProgsParms(qboolean forcompiler)
sv.world.Event_Touch = SVPR_Event_Touch;
sv.world.Event_Think = SVPR_Event_Think;
sv.world.Event_Sound = SVQ1_StartSound;
sv.world.Event_ContentsTransition = SVPR_Event_ContentsTransition;
sv.world.Get_CModel = SVPR_GetCModel;
sv.world.Get_FrameState = SVPR_Get_FrameState;
PRSV_ClearThreads();
@ -2957,7 +2973,7 @@ static void QCBUILTIN PF_LocalSound(progfuncs_t *prinst, struct globalvars_s *pr
if (!isDedicated)
{
if ((sfx = S_PrecacheSound(s)))
S_StartSound(cl.playernum[0], chan, sfx, cl.simorg[0], vol, 0.0, 0, 0);
S_StartSound(cl.playernum[0], chan, sfx, cl.playerview[0].simorg, vol, 0.0, 0, 0);
}
#endif
};
@ -3904,9 +3920,18 @@ void QCBUILTIN PF_applylightstyle(int style, char *val, int col)
// change the string in sv
if (sv.strings.lightstyles[style])
Z_Free(sv.strings.lightstyles[style]);
sv.strings.lightstyles[style] = Z_Malloc(strlen(val)+1);
if (!svprogfuncs)
{
if (sv.strings.lightstyles[style])
BZ_Free(sv.strings.lightstyles[style]);
sv.strings.lightstyles[style] = BZ_Malloc(strlen(val)+1);
}
else
{
if (sv.strings.lightstyles[style])
PR_AddressableFree(svprogfuncs, sv.strings.lightstyles[style]);
sv.strings.lightstyles[style] = PR_AddressableAlloc(svprogfuncs, strlen(val)+1);
}
strcpy(sv.strings.lightstyles[style], val);
// sv.lightstyles[style] = val;
#ifdef PEXT_LIGHTSTYLECOL

View File

@ -1325,6 +1325,11 @@ void Q1QVM_Event_Think(world_t *w, wedict_t *s)
PR_ExecuteProgram (w->progs, s->v->think);
}
qboolean Q1QVM_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype)
{
return false; //always do legacy behaviour
}
qboolean PR_LoadQ1QVM(void)
{
static float writable;
@ -1368,6 +1373,8 @@ qboolean PR_LoadQ1QVM(void)
sv.world.Event_Touch = Q1QVM_Event_Touch;
sv.world.Event_Think = Q1QVM_Event_Think;
sv.world.Event_Sound = SVQ1_StartSound;
sv.world.Event_ContentsTransition = Q1QVM_Event_ContentsTransition;
sv.world.Get_CModel = SVPR_GetCModel;
sv.world.num_edicts = 0; //we're not ready for most of the builtins yet

View File

@ -191,8 +191,10 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(hull)/*PEXT_HEXEN2*/\
comfieldentity(movechain)/*hexen2*/\
comfieldfunction(chainmoved, ".void()")/*hexen2*/\
comfieldfunction(contentstransition, ".void(float old, float new)")/*ENTITYCONTENTSTRANSITION*/\
comfieldfloat(dimension_solid)/*EXT_DIMENSION_PHYSICS*/\
comfieldfloat(dimension_hit)/*EXT_DIMENSION_PHYSICS*/\
comfieldfloat(hitcontentsmask)\
comfieldfloat(scale)/*DP_ENT_SCALE*/\
comfieldfloat(fatness)/*FTE_PEXT_FATNESS*/\
comfieldfloat(alpha)/*DP_ENT_ALPHA*/\
@ -230,6 +232,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(glow_size)\
comfieldfloat(glow_color)\
comfieldfloat(glow_trail)\
comfieldfloat(traileffectnum)/*DP_ENT_TRAILEFFECTNUM*/\
comfieldvector(color)/*Hexen2 has a .float color, the warnings should be benign*/ \
comfieldfloat(light_lev)\
comfieldfloat(style)\

View File

@ -1091,9 +1091,11 @@ qboolean PR_ShouldTogglePause(client_t *initiator, qboolean pausedornot);
// sv_ents.c
//
void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignorepvs);
void SVFTE_EmitBaseline(entity_state_t *to, qboolean numberisimportant, sizebuf_t *msg);
void SVQ3Q1_BuildEntityPacket(client_t *client, packet_entities_t *pack);
int SV_HullNumForPlayer(int h2hull, float *mins, float *maxs);
void SV_GibFilterInit(void);
void SV_GibFilterPurge(void);
void SV_CleanupEnts(void);
void SV_CSQC_DroppedPacket(client_t *client, int sequence);
@ -1310,3 +1312,25 @@ void SV_CheckTimer(void);
void SV_LogPlayer(client_t *cl, char *msg);
void AddLinksToPmove ( edict_t *player, areanode_t *node );
#ifdef HLSERVER
void SVHL_SaveLevelCache(char *filename);
//network frame info
void SVHL_Snapshot_Build(client_t *client, packet_entities_t *pack, qbyte *pvs, edict_t *clent, qboolean ignorepvs);
qbyte *SVHL_Snapshot_SetupPVS(client_t *client, qbyte *pvs, unsigned int pvsbufsize);
void SVHL_BuildStats(client_t *client, int *si, float *sf, char **ss);
//gamecode entry points
int SVHL_InitGame(void);
void SVHL_SetupGame(void);
void SVHL_SpawnEntities(char *entstring);
void SVHL_RunFrame (void);
qboolean SVHL_ClientConnect(client_t *client, netadr_t adr, char rejectmessage[128]);
void SVHL_PutClientInServer(client_t *client);
void SVHL_RunPlayerCommand(client_t *cl, usercmd_t *oldest, usercmd_t *oldcmd, usercmd_t *newcmd);
qboolean HLSV_ClientCommand(client_t *client);
void SVHL_DropClient(client_t *drop);
void SVHL_ShutdownGame(void);
#endif

Some files were not shown because too many files have changed in this diff Show More