d3d rendering is diabled (framestate, read later - merged will compile just sw+gl for now).

fte particle scripts are disabled (classic works).
I'll fix these in the new year.
Redid framestate stuff again. Slightly better now, but this is the bulk of the changes here.
Reworked the renderqueue to provide batches of items instead of individual items. This cleans up the particle rendering code significantly, and is a step towards multiple concurrent particle systems. fte's scripted particles are broken as I'm trying to find a way to rework them to batch types together, rather than having to restart each batch after each particle when you have two particles in a trail. I'll fix it some time.
Reworked some alias model code regarding skeletal models. Added some conceptual skeletal bone control builtins available to csqc. Currently it can query the bone names and save off animation states, but can't animate - its just not complete.
Added more info to glsl custom shaders.
Updated surface sorting on halflife maps to properly cope with alphaed entities, rather than just texture-based blends (q2-style).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3095 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2008-12-23 02:55:20 +00:00
parent e49d712c6f
commit 6e3f69f504
54 changed files with 2058 additions and 1329 deletions

View File

@ -1155,7 +1155,7 @@ void CL_Record_f (void)
else
MSG_WriteByte (&buf, j);
MSG_WriteByte (&buf, ent->frame1);
MSG_WriteByte (&buf, ent->framestate.g[FS_REG].frame[0]);
MSG_WriteByte (&buf, 0);
MSG_WriteByte (&buf, ent->skinnum);
for (j=0 ; j<3 ; j++)

View File

@ -159,7 +159,7 @@ dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float
return dl;
}
void CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time,
dlight_t *CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time,
float r, float g, float b)
{
dlight_t *dl;
@ -173,6 +173,8 @@ void CL_NewDlightRGB (int key, float x, float y, float z, float radius, float ti
dl->color[0] = r;
dl->color[1] = g;
dl->color[2] = b;
return dl;
}
@ -1166,10 +1168,8 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
vec3_t axis[3];
float transform[12], parent[12], result[12], old[12], temp[12];
int model = 0; //these two are only initialised because msvc sucks at detecting usage.
int frame = 0;
int frame2;
float frame2ness;
int model;
framestate_t fstate;
if (tagent > cl.maxlerpents)
{
@ -1177,7 +1177,9 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
return;
}
frame2 = cl.lerpents[tagent].frame;
memset(&fstate, 0, sizeof(fstate));
fstate.g[FS_REG].frame[1] = cl.lerpents[tagent].frame;
ent->keynum = tagent;
@ -1190,7 +1192,7 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
org = ps->origin;
ang = ps->angles;
model = ps->modelindex;
frame = ps->frame;
fstate.g[FS_REG].frame[0] = ps->frame;
}
else
{
@ -1209,7 +1211,7 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
ang = cl.frames[parsecountmod].playerstate[tagent-1].viewangles;
}
model = cl.frames[parsecountmod].playerstate[tagent-1].modelindex;
frame = cl.frames[parsecountmod].playerstate[tagent-1].frame;
fstate.g[FS_REG].frame[0] = cl.frames[parsecountmod].playerstate[tagent-1].frame;
}
}
@ -1220,8 +1222,10 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
ang[0]*=-1;
VectorInverse(axis[1]);
frame2ness = CL_EntLerpFactor(tagent);
if (Mod_GetTag(cl.model_precache[model], tagnum, frame, frame2, frame2ness, cl.time - cl.lerpents[tagent].framechange, cl.time - cl.lerpents[tagent].oldframechange, transform))
fstate.g[FS_REG].lerpfrac = CL_EntLerpFactor(tagent);
fstate.g[FS_REG].frametime[0] = cl.time - cl.lerpents[tagent].framechange;
fstate.g[FS_REG].frametime[1] = cl.time - cl.lerpents[tagent].oldframechange;
if (Mod_GetTag(cl.model_precache[model], tagnum, &fstate, transform))
{
old[0] = ent->axis[0][0];
old[1] = ent->axis[1][0];
@ -1345,7 +1349,7 @@ void V_AddEntity(entity_t *in)
ent->angles[0]*=-1;
}
void V_AddLerpEntity(entity_t *in) //a convienience function
void VQ2_AddLerpEntity(entity_t *in) //a convienience function
{
entity_t *ent;
float fwds, back;
@ -1358,14 +1362,14 @@ void V_AddLerpEntity(entity_t *in) //a convienience function
*ent = *in;
fwds = ent->lerpfrac;
back = 1 - ent->lerpfrac;
fwds = ent->framestate.g[FS_REG].lerpfrac;
back = 1 - ent->framestate.g[FS_REG].lerpfrac;
for (i = 0; i < 3; i++)
{
ent->origin[i] = in->origin[i]*fwds + in->oldorigin[i]*back;
}
ent->lerpfrac = 1 - ent->lerpfrac;
ent->framestate.g[FS_REG].lerpfrac = back;
ent->angles[0]*=-1;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
@ -1607,16 +1611,18 @@ void CL_LinkPacketEntities (void)
le = &cl.lerpents[state->number];
memset(&ent->framestate, 0, sizeof(ent->framestate));
if (le->framechange == le->oldframechange)
ent->lerpfrac = 0;
ent->framestate.g[FS_REG].lerpfrac = 0;
else
{
ent->lerpfrac = 1-(servertime - le->framechange) / (le->framechange - le->oldframechange);
if (ent->lerpfrac > 1)
ent->lerpfrac = 1;
else if (ent->lerpfrac < 0)
ent->framestate.g[FS_REG].lerpfrac = 1-(servertime - le->framechange) / (le->framechange - le->oldframechange);
if (ent->framestate.g[FS_REG].lerpfrac > 1)
ent->framestate.g[FS_REG].lerpfrac = 1;
else if (ent->framestate.g[FS_REG].lerpfrac < 0)
{
ent->lerpfrac = 0;
ent->framestate.g[FS_REG].lerpfrac = 0;
//le->oldframechange = le->framechange;
}
}
@ -1709,11 +1715,11 @@ void CL_LinkPacketEntities (void)
ent->drawflags = state->hexen2flags;
// set frame
ent->frame1 = state->frame;
ent->frame2 = le->frame;
ent->framestate.g[FS_REG].frame[0] = state->frame;
ent->framestate.g[FS_REG].frame[1] = le->frame;
ent->frame1time = cl.servertime - le->framechange;
ent->frame2time = cl.servertime - le->oldframechange;
ent->framestate.g[FS_REG].frametime[0] = cl.servertime - le->framechange;
ent->framestate.g[FS_REG].frametime[1] = cl.servertime - le->oldframechange;
// f = (sin(realtime)+1)/2;
@ -2260,7 +2266,7 @@ void CL_LinkProjectiles (void)
#endif
ent->model = cl.model_precache[pr->modelindex];
ent->skinnum = 0;
ent->frame1 = 0;
memset(&ent->framestate, 0, sizeof(ent->framestate));
ent->flags = 0;
#ifdef SWQUAKE
ent->palremap = D_IdentityRemap();
@ -2649,32 +2655,38 @@ void CL_AddFlagModels (entity_t *ent, int team)
vec3_t v_forward, v_right, v_up;
entity_t *newent;
vec3_t angles;
float offs;
if (cl_flagindex == -1)
return;
f = 14;
if (ent->frame1 >= 29 && ent->frame1 <= 40) {
if (ent->frame1 >= 29 && ent->frame1 <= 34) { //axpain
if (ent->frame1 == 29) f = f + 2;
else if (ent->frame1 == 30) f = f + 8;
else if (ent->frame1 == 31) f = f + 12;
else if (ent->frame1 == 32) f = f + 11;
else if (ent->frame1 == 33) f = f + 10;
else if (ent->frame1 == 34) f = f + 4;
} else if (ent->frame1 >= 35 && ent->frame1 <= 40) { // pain
if (ent->frame1 == 35) f = f + 2;
else if (ent->frame1 == 36) f = f + 10;
else if (ent->frame1 == 37) f = f + 10;
else if (ent->frame1 == 38) f = f + 8;
else if (ent->frame1 == 39) f = f + 4;
else if (ent->frame1 == 40) f = f + 2;
for (i = 0; i < 2; i++)
{
f = 14;
if (ent->framestate.g[FS_REG].frame[i] >= 29 && ent->framestate.g[FS_REG].frame[i] <= 40) {
if (ent->framestate.g[FS_REG].frame[i] >= 29 && ent->framestate.g[FS_REG].frame[i] <= 34) { //axpain
if (ent->framestate.g[FS_REG].frame[i] == 29) f = f + 2;
else if (ent->framestate.g[FS_REG].frame[i] == 30) f = f + 8;
else if (ent->framestate.g[FS_REG].frame[i] == 31) f = f + 12;
else if (ent->framestate.g[FS_REG].frame[i] == 32) f = f + 11;
else if (ent->framestate.g[FS_REG].frame[i] == 33) f = f + 10;
else if (ent->framestate.g[FS_REG].frame[i] == 34) f = f + 4;
} else if (ent->framestate.g[FS_REG].frame[i] >= 35 && ent->framestate.g[FS_REG].frame[i] <= 40) { // pain
if (ent->framestate.g[FS_REG].frame[i] == 35) f = f + 2;
else if (ent->framestate.g[FS_REG].frame[i] == 36) f = f + 10;
else if (ent->framestate.g[FS_REG].frame[i] == 37) f = f + 10;
else if (ent->framestate.g[FS_REG].frame[i] == 38) f = f + 8;
else if (ent->framestate.g[FS_REG].frame[i] == 39) f = f + 4;
else if (ent->framestate.g[FS_REG].frame[i] == 40) f = f + 2;
}
} else if (ent->framestate.g[FS_REG].frame[i] >= 103 && ent->framestate.g[FS_REG].frame[i] <= 118) {
if (ent->framestate.g[FS_REG].frame[i] >= 103 && ent->framestate.g[FS_REG].frame[i] <= 104) f = f + 6; //nailattack
else if (ent->framestate.g[FS_REG].frame[i] >= 105 && ent->framestate.g[FS_REG].frame[i] <= 106) f = f + 6; //light
else if (ent->framestate.g[FS_REG].frame[i] >= 107 && ent->framestate.g[FS_REG].frame[i] <= 112) f = f + 7; //rocketattack
else if (ent->framestate.g[FS_REG].frame[i] >= 112 && ent->framestate.g[FS_REG].frame[i] <= 118) f = f + 7; //shotattack
}
} else if (ent->frame1 >= 103 && ent->frame1 <= 118) {
if (ent->frame1 >= 103 && ent->frame1 <= 104) f = f + 6; //nailattack
else if (ent->frame1 >= 105 && ent->frame1 <= 106) f = f + 6; //light
else if (ent->frame1 >= 107 && ent->frame1 <= 112) f = f + 7; //rocketattack
else if (ent->frame1 >= 112 && ent->frame1 <= 118) f = f + 7; //shotattack
offs += f + ((i==0)?(ent->framestate.g[FS_REG].lerpfrac):(1-ent->framestate.g[FS_REG].lerpfrac));
}
newent = CL_NewTempEntity ();
@ -2684,7 +2696,7 @@ void CL_AddFlagModels (entity_t *ent, int team)
AngleVectors (ent->angles, v_forward, v_right, v_up);
v_forward[2] = -v_forward[2]; // reverse z component
for (i=0 ; i<3 ; i++)
newent->origin[i] = ent->origin[i] - f*v_forward[i] + 22*v_right[i];
newent->origin[i] = ent->origin[i] - offs*v_forward[i] + 22*v_right[i];
newent->origin[2] -= 16;
VectorCopy (ent->angles, newent->angles)
@ -2706,7 +2718,7 @@ void CL_AddVWeapModel(entity_t *player, int model)
VectorCopy(player->angles, newent->angles);
newent->skinnum = player->skinnum;
newent->model = cl.model_precache[model];
newent->frame1 = player->frame1;
newent->framestate = player->framestate;
VectorCopy(newent->angles, angles);
angles[0]*=-1;
@ -2792,21 +2804,21 @@ void CL_LinkPlayers (void)
ent->model = cl.model_precache[state->modelindex];
ent->skinnum = state->skinnum;
ent->frame1time = cl.time - cl.lerpplayers[j].framechange;
ent->frame2time = cl.time - cl.lerpplayers[j].oldframechange;
ent->framestate.g[FS_REG].frametime[0] = cl.time - cl.lerpplayers[j].framechange;
ent->framestate.g[FS_REG].frametime[1] = cl.time - cl.lerpplayers[j].oldframechange;
if (ent->frame1 != cl.lerpplayers[j].frame)
if (ent->framestate.g[FS_REG].frame[0] != cl.lerpplayers[j].frame)
{
ent->frame2 = ent->frame1;
ent->frame1 = cl.lerpplayers[j].frame;
ent->framestate.g[FS_REG].frame[1] = ent->framestate.g[FS_REG].frame[0];
ent->framestate.g[FS_REG].frame[0] = cl.lerpplayers[j].frame;
}
ent->lerpfrac = 1-(realtime - cl.lerpplayers[j].framechange)*10;
if (ent->lerpfrac > 1)
ent->lerpfrac = 1;
else if (ent->lerpfrac < 0)
ent->framestate.g[FS_REG].lerpfrac = 1-(realtime - cl.lerpplayers[j].framechange)*10;
if (ent->framestate.g[FS_REG].lerpfrac > 1)
ent->framestate.g[FS_REG].lerpfrac = 1;
else if (ent->framestate.g[FS_REG].lerpfrac < 0)
{
ent->lerpfrac = 0;
ent->framestate.g[FS_REG].lerpfrac = 0;
//state->lerpstarttime = 0;
}
@ -2996,24 +3008,24 @@ void CL_LinkViewModel(void)
ent.shaderRGBAf[2] = 1;
ent.shaderRGBAf[3] = alpha;
ent.frame1 = cl.viewent[r_refdef.currentplayernum].frame1;
ent.frame2 = oldframe[r_refdef.currentplayernum];
ent.framestate.g[FS_REG].frame[0] = cl.viewent[r_refdef.currentplayernum].framestate.g[FS_REG].frame[0];
ent.framestate.g[FS_REG].frame[1] = oldframe[r_refdef.currentplayernum];
if (ent.frame1 != prevframe[r_refdef.currentplayernum])
if (ent.framestate.g[FS_REG].frame[0] != prevframe[r_refdef.currentplayernum])
{
oldframe[r_refdef.currentplayernum] = ent.frame2 = prevframe[r_refdef.currentplayernum];
oldframe[r_refdef.currentplayernum] = ent.framestate.g[FS_REG].frame[1] = prevframe[r_refdef.currentplayernum];
lerptime[r_refdef.currentplayernum] = realtime;
}
prevframe[r_refdef.currentplayernum] = ent.frame1;
prevframe[r_refdef.currentplayernum] = ent.framestate.g[FS_REG].frame[0];
if (ent.model != oldmodel[r_refdef.currentplayernum])
{
oldmodel[r_refdef.currentplayernum] = ent.model;
oldframe[r_refdef.currentplayernum] = ent.frame2 = ent.frame1;
oldframe[r_refdef.currentplayernum] = ent.framestate.g[FS_REG].frame[1] = ent.framestate.g[FS_REG].frame[0];
lerptime[r_refdef.currentplayernum] = realtime;
}
ent.lerpfrac = 1-(realtime-lerptime[r_refdef.currentplayernum])*10;
ent.lerpfrac = bound(0, ent.lerpfrac, 1);
ent.framestate.g[FS_REG].lerpfrac = 1-(realtime-lerptime[r_refdef.currentplayernum])*10;
ent.framestate.g[FS_REG].lerpfrac = bound(0, ent.framestate.g[FS_REG].lerpfrac, 1);
#define Q2RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors
#define Q2RF_WEAPONMODEL 4 // only draw through eyes

View File

@ -2618,7 +2618,7 @@ void CL_Download_f (void)
return;
}
CL_EnqueDownload(url, url, DLLF_REQUIRED|DLLF_OVERWRITE|DLLF_VERBOSE);
CL_EnqueDownload(url, url, DLLF_IGNOREFAILED|DLLF_REQUIRED|DLLF_OVERWRITE|DLLF_VERBOSE);
}
void CL_DownloadSize_f(void)

View File

@ -1219,7 +1219,11 @@ void CL_SendDownloadReq(sizebuf_t *msg)
{
int i = CL_RequestADownloadChunk();
if (i >= 0)
CL_SendClientCommand(false, "nextdl %i - %i\n", i, download_file_number);
{
char *cmd = va("nextdl %i - %i\n", i, download_file_number);
CL_RemoveClientCommands(cmd);
CL_SendClientCommand(false, "%s", cmd);
}
else
break;//we can stop downloading now.
}
@ -1396,8 +1400,8 @@ void CL_ParseChunkedDownload(void)
if (!strncmp(cls.downloadtempname,"skins/",6))
{
FS_CreatePath (va("qw/%s", cls.downloadtempname), FS_BASE);
cls.downloadqw = FS_OpenVFS (va("qw/%s", cls.downloadtempname), "wb", FS_BASE);
FS_CreatePath (va("qw/%s", cls.downloadtempname), FS_ROOT);
cls.downloadqw = FS_OpenVFS (va("qw/%s", cls.downloadtempname), "wb", FS_ROOT);
}
else
{
@ -1897,7 +1901,7 @@ qboolean CL_StartUploadFile(char *filename)
CL_StopUpload();
upload_file = FS_OpenVFS(filename, "rb", FS_BASE);
upload_file = FS_OpenVFS(filename, "rb", FS_ROOT);
upload_size = VFS_GETLEN(upload_file);
upload_pos = 0;
@ -2977,7 +2981,7 @@ void CL_ParseStatic (int version)
// copy it to the current state
ent->model = cl.model_precache[es.modelindex];
ent->frame2 = ent->frame1 = es.frame;
ent->framestate.g[FS_REG].frame[0] = ent->framestate.g[FS_REG].frame[1] = es.frame;
#ifdef SWQUAKE
ent->palremap = D_IdentityRemap();
#endif

View File

@ -2857,9 +2857,9 @@ void CL_UpdateExplosions (void)
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]);
ent->model = ex->model;
ent->frame1 = (int)f+firstframe;
ent->frame2 = of+firstframe;
ent->lerpfrac = 1-(f - (int)f);
ent->framestate.g[FS_REG].frame[0] = (int)f+firstframe;
ent->framestate.g[FS_REG].frame[1] = of+firstframe;
ent->framestate.g[FS_REG].lerpfrac = 1-(f - (int)f);
ent->shaderRGBAf[3] = 1.0 - f/(numframes);
ent->flags = ex->flags;
}

View File

@ -1,12 +1,12 @@
#include "quakedef.h"
#ifdef VM_UI
#include "clq3defs.h"
#include "ui_public.h"
#include "cl_master.h"
#include "shader.h"
int keycatcher;
#include "clq3defs.h"
void GLDraw_ShaderImage (int x, int y, int w, int h, float s1, float t1, float s2, float t2, struct shader_s *pic);
@ -397,10 +397,10 @@ void VQ3_AddEntity(const q3refEntity_t *q3)
cl_visedicts = cl_visedicts_list[0];
memset(&ent, 0, sizeof(ent));
ent.model = VM_FROMMHANDLE(q3->hModel);
ent.frame1 = q3->frame;
ent.frame2 = q3->oldframe;
ent.framestate.g[FS_REG].frame[0] = q3->frame;
ent.framestate.g[FS_REG].frame[1] = q3->oldframe;
memcpy(ent.axis, q3->axis, sizeof(q3->axis));
ent.lerpfrac = q3->backlerp;
ent.framestate.g[FS_REG].lerpfrac = q3->backlerp;
ent.scale = q3->radius;
ent.rtype = q3->reType;
ent.rotation = q3->rotation;

View File

@ -689,6 +689,7 @@ extern float server_version; // version of server we connected to
// cl_main
//
dlight_t *CL_AllocDlight (int key);
dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float time, int type);
void CL_DecayLights (void);
void CL_ParseDelta (struct entity_state_s *from, struct entity_state_s *to, int bits, qboolean);

View File

@ -652,7 +652,7 @@ void CLQ2_AddProjectiles (void)
V_AddLight (pr->origin, 200, 0.2, 0.2, 0);
VectorCopy (pr->angles, ent.angles);
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
}
}
#endif
@ -1354,15 +1354,15 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
// set frame
if (effects & Q2EF_ANIM01)
ent.frame1 = autoanim & 1;
ent.framestate.g[FS_REG].frame[0] = autoanim & 1;
else if (effects & Q2EF_ANIM23)
ent.frame1 = 2 + (autoanim & 1);
ent.framestate.g[FS_REG].frame[0] = 2 + (autoanim & 1);
else if (effects & Q2EF_ANIM_ALL)
ent.frame1 = autoanim;
ent.framestate.g[FS_REG].frame[0] = autoanim;
else if (effects & Q2EF_ANIM_ALLFAST)
ent.frame1 = cl.time / 100;
ent.framestate.g[FS_REG].frame[0] = cl.time / 100;
else
ent.frame1 = s1->frame;
ent.framestate.g[FS_REG].frame[0] = s1->frame;
// quad and pent can do different things on client
if (effects & Q2EF_PENT)
@ -1395,8 +1395,8 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
}
// pmm
//======
ent.frame2 = cent->prev.frame;
ent.lerpfrac = cl.lerpfrac;
ent.framestate.g[FS_REG].frame[1] = cent->prev.frame;
ent.framestate.g[FS_REG].lerpfrac = cl.lerpfrac;
if (renderfx & (Q2RF_FRAMELERP|Q2RF_BEAM))
{ // step origin discretely, because the frames
@ -1421,7 +1421,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
ent.shaderRGBAf[3] = 0.30;
ent.skinnum = (s1->skinnum >> ((rand() % 4)*8)) & 0xff;
ent.model = NULL;
ent.lerpfrac = 1;
ent.framestate.g[FS_REG].lerpfrac = 1;
}
else
{
@ -1573,7 +1573,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
//pmm
// add to refresh list
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
// color shells generate a seperate entity for the main model
@ -1630,7 +1630,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
ent.forcedshader = R_RegisterCustom("q2/shell", Shader_DefaultSkinShell);
}
#endif
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
}
#ifdef Q3SHADERS
ent.forcedshader = NULL;
@ -1686,7 +1686,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
}
*/ // pmm
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
//PGM - make sure these get reset.
ent.flags = 0;
@ -1696,12 +1696,12 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
if (s1->modelindex3)
{
ent.model = cl.model_precache[s1->modelindex3];
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
}
if (s1->modelindex4)
{
ent.model = cl.model_precache[s1->modelindex4];
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
}
if ( effects & Q2EF_POWERSCREEN )
@ -1711,7 +1711,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
ent.frame = 0;
ent.flags |= (Q2RF_TRANSLUCENT | Q2RF_SHELL_GREEN);
ent.alpha = 0.30;
V_AddLerpEntity (&ent);
VQ2_AddLerpEntity (&ent);
*/ }
// add automatic particle trails
@ -1928,14 +1928,14 @@ void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops)
gun.angles[1] = cl_gunangley.value;
gun.angles[2] = cl_gunanglez.value;
gun.frame1 = ps->gunframe;
if (gun.frame1 == 0)
gun.frame2 = 0; // just changed weapons, don't lerp from old
gun.framestate.g[FS_REG].frame[0] = ps->gunframe;
if (gun.framestate.g[FS_REG].frame[0] == 0)
gun.framestate.g[FS_REG].frame[1] = 0; // just changed weapons, don't lerp from old
else
gun.frame2 = ops->gunframe;
gun.framestate.g[FS_REG].frame[1] = ops->gunframe;
gun.flags = Q2RF_MINLIGHT | Q2RF_DEPTHHACK | Q2RF_WEAPONMODEL;
gun.lerpfrac = 1-cl.lerpfrac;
gun.framestate.g[FS_REG].lerpfrac = 1-cl.lerpfrac;
VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all
V_AddEntity (&gun);
}

View File

@ -397,8 +397,8 @@ void CLQ3_ParseDownload(void)
return;
}
COM_CreatePath(cls.downloadtempname);
cls.downloadqw = FS_OpenVFS(cls.downloadtempname, "wb", FS_BASE);
FS_CreatePath(cls.downloadtempname, FS_ROOT);
cls.downloadqw = FS_OpenVFS(cls.downloadtempname, "wb", FS_ROOT);
if (!cls.downloadqw)
{
Con_Printf("Couldn't write to temporary file %s - stopping download\n", cls.downloadtempname);
@ -414,7 +414,7 @@ void CLQ3_ParseDownload(void)
{
VFS_CLOSE(cls.downloadqw);
cls.downloadqw = NULL;
FS_Rename(cls.downloadtempname, cls.downloadname, FS_BASE); // ->
FS_Rename(cls.downloadtempname, cls.downloadname, FS_ROOT); // ->
*cls.downloadtempname = *cls.downloadname = 0;
cls.downloadmethod = DL_NONE;
@ -485,7 +485,7 @@ qboolean CLQ3_SystemInfoChanged(char *str)
if (!strchr(com_token, '/')) //don't let some muppet tell us to download quake3.exe
break;
f = FS_OpenVFS(va("%s.pk3", com_token), "rb", FS_BASE);
f = FS_OpenVFS(va("%s.pk3", com_token), "rb", FS_ROOT);
if (f)
VFS_CLOSE(f);
else

View File

@ -162,7 +162,7 @@ static void WriteInstalledPackages(void)
{
char *s;
package_t *p;
vfsfile_t *f = FS_OpenVFS(INSTALLEDFILES, "wb", FS_BASE);
vfsfile_t *f = FS_OpenVFS(INSTALLEDFILES, "wb", FS_ROOT);
if (!f)
{
Con_Printf("menu_download: Can't update installed list\n");
@ -346,7 +346,7 @@ qboolean MD_ApplyDownloads (union menuoption_s *mo,struct menu_s *m,int key)
if (*p->gamedir)
{
char *fname = va("%s/%s", p->gamedir, p->dest);
FS_Remove(fname, FS_BASE);
FS_Remove(fname, FS_ROOT);
}
else
FS_Remove(p->dest, FS_GAME);
@ -629,9 +629,9 @@ static void Menu_Download_Got(char *fname, qboolean successful)
else
destname = va("%s", p->dest);
if (!FS_Remove(destname, *p->gamedir?FS_BASE:FS_GAME))
if (!FS_Remove(destname, *p->gamedir?FS_ROOT:FS_GAME))
Con_Printf("Deleted old %s\n", destname);
if (FS_Rename2(diskname, destname, FS_GAME, *p->gamedir?FS_BASE:FS_GAME))
if (FS_Rename2(diskname, destname, FS_GAME, *p->gamedir?FS_ROOT:FS_GAME))
{
Con_Printf("Couldn't rename %s to %s. Removed instead.\n", diskname, destname);
FS_Remove (diskname, FS_GAME);
@ -775,7 +775,7 @@ void Menu_DownloadStuff_f (void)
{
static qboolean loadedinstalled;
vfsfile_t *f = loadedinstalled?NULL:FS_OpenVFS(INSTALLEDFILES, "rb", FS_BASE);
vfsfile_t *f = loadedinstalled?NULL:FS_OpenVFS(INSTALLEDFILES, "rb", FS_ROOT);
loadedinstalled = true;
if (f)
{

View File

@ -3,6 +3,39 @@ struct progfuncs_s;
struct globalvars_s;
struct texture_s;
#ifdef HALFLIFEMODELS
#define MAX_BONE_CONTROLLERS 5
#endif
#define FST_BASE 0 //base frames
#define FS_REG 1 //regular frames
#define FS_COUNT 2 //regular frames
typedef struct {
struct {
int frame[2];
float frametime[2];
float lerpfrac;
#ifdef HALFLIFEMODELS
float subblendfrac; //hl models are weird
#endif
int endbone;
} g[2];
float *bonestate;
int bonecount;
#ifdef HALFLIFEMODELS
float bonecontrols[MAX_BONE_CONTROLLERS]; //hl special bone controllers
#endif
} framestate_t;
//function prototypes
#if defined(SERVERONLY)
@ -13,7 +46,6 @@ struct texture_s;
extern r_qrenderer_t qrenderer;
extern char *q_renderername;
extern mpic_t *(*Draw_SafePicFromWad) (char *name);
extern mpic_t *(*Draw_CachePic) (char *path);
extern mpic_t *(*Draw_SafeCachePic) (char *path);
@ -104,9 +136,14 @@ extern int FNC(Mod_SkinForName) (struct model_s *model, char *name);
#undef FNC
extern qboolean Mod_GetTag (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
extern qboolean Mod_GetTag (struct model_s *model, int tagnum, framestate_t *framestate, float *transforms);
extern int Mod_TagNumForName (struct model_s *model, char *name);
int Mod_GetNumBones(struct model_s *model, qboolean allowtags);
int Mod_GetBoneRelations(struct model_s *model, int numbones, framestate_t *fstate, float *result);
int Mod_GetBoneParent(struct model_s *model, int bonenum);
char *Mod_GetBoneName(struct model_s *model, int bonenum);
void Draw_FunString(int x, int y, unsigned char *str);
void Draw_FunStringLen(int x, int y, unsigned char *str, int len);
@ -181,7 +218,7 @@ typedef struct {
void (*Mod_NowLoadExternal) (void);
void (*Mod_Think) (void);
qboolean(*Mod_GetTag) (struct model_s *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result);
qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, framestate_t *fstate, float *result);
int (*Mod_TagNumForName) (struct model_s *model, char *name);
int (*Mod_SkinForName) (struct model_s *model, char *name);

View File

@ -644,7 +644,7 @@ qboolean Master_LoadMasterList (char *filename, int defaulttype, int depth)
return false;
depth--;
f = FS_OpenVFS(filename, "rb", FS_BASE);
f = FS_OpenVFS(filename, "rb", FS_ROOT);
if (!f)
return false;

View File

@ -371,9 +371,7 @@ static void PClassic_DrawParticles(void)
//please don't make me do so.
#ifdef RGLQUAKE
RSpeedRemark();
qglBegin(GL_QUADS);
RQ_RenderDistAndClear();
qglEnd();
RSpeedEnd(RSPEED_PARTICLESDRAW);
#endif
}

View File

@ -47,9 +47,7 @@ static void PNULL_DrawParticles(void)
RSpeedRemark();
#ifdef GLQUAKE
qglBegin(GL_QUADS);
RQ_RenderDistAndClear();
qglEnd();
#endif
RSpeedEnd(RSPEED_PARTICLESDRAW);
}

File diff suppressed because it is too large Load Diff

View File

@ -69,6 +69,57 @@ extern sfx_t *cl_sfx_ric2;
extern sfx_t *cl_sfx_ric3;
extern sfx_t *cl_sfx_r_exp3;
//shared constants
typedef enum
{
VF_MIN = 1,
VF_MIN_X = 2,
VF_MIN_Y = 3,
VF_SIZE = 4,
VF_SIZE_X = 5,
VF_SIZE_Y = 6,
VF_VIEWPORT = 7,
VF_FOV = 8,
VF_FOVX = 9,
VF_FOVY = 10,
VF_ORIGIN = 11,
VF_ORIGIN_X = 12,
VF_ORIGIN_Y = 13,
VF_ORIGIN_Z = 14,
VF_ANGLES = 15,
VF_ANGLES_X = 16,
VF_ANGLES_Y = 17,
VF_ANGLES_Z = 18,
VF_DRAWWORLD = 19,
VF_ENGINESBAR = 20,
VF_DRAWCROSSHAIR = 21,
VF_CARTESIAN_ANGLES = 22,
//this is a DP-compatibility hack.
VF_CL_VIEWANGLES_V = 33,
VF_CL_VIEWANGLES_X = 34,
VF_CL_VIEWANGLES_Y = 35,
VF_CL_VIEWANGLES_Z = 36,
#pragma message("FIXME: add cshift")
//33-36 used by DP...
VF_PERSPECTIVE = 200,
//201 used by DP... WTF? CLEARSCREEN
VF_LPLAYER = 202,
VF_AFOV = 203, //aproximate fov (match what the engine would normally use for the fov cvar). p0=fov, p1=zoom
} viewflags;
#define CSQCRF_VIEWMODEL 1 //Not drawn in mirrors
#define CSQCRF_EXTERNALMODEL 2 //drawn ONLY in mirrors
#define CSQCRF_DEPTHHACK 4 //fun depthhack
#define CSQCRF_ADDITIVE 8 //add instead of blend
#define CSQCRF_USEAXIS 16 //use v_forward/v_right/v_up as an axis/matrix - predraw is needed to use this properly
#define CSQCRF_NOSHADOW 32 //don't cast shadows upon other entities (can still be self shadowing, if the engine wishes, and not additive)
#define CSQCRF_FRAMETIMESARESTARTTIMES 64 //EXT_CSQC_1: frame times should be read as (time-frametime).
//If I do it like this, I'll never forget to register something...
#define csqcglobals \
globalfunction(init_function, "CSQC_Init"); \
@ -254,7 +305,9 @@ static void CSQC_FindGlobals(void)
fieldfloat(bonecontrol4); /*FTE_CSQC_HALFLIFE_MODELS*/\
fieldfloat(bonecontrol5); /*FTE_CSQC_HALFLIFE_MODELS*/\
fieldfloat(subblendfrac); /*FTE_CSQC_HALFLIFE_MODELS*/\
fieldfloat(basesubblendfrac); /*FTE_CSQC_HALFLIFE_MODELS*/\
fieldfloat(basesubblendfrac); /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\
\
fieldfloat(skeletonindex); /*FTE_CSQC_SKELETONOBJECTS*/\
\
fieldfloat(drawmask); /*So that the qc can specify all rockets at once or all bannanas at once*/ \
fieldfunction(predraw); /*If present, is called just before it's drawn.*/ \
@ -333,6 +386,29 @@ static int csqcentsize;
static char *csqcmapentitydata;
static qboolean csqcmapentitydataloaded;
#define MAX_SKEL_OBJECTS 1024
typedef struct {
int inuse;
model_t *model;
qboolean absolute;
int numbones;
float *bonematrix;
} skelobject_t;
skelobject_t skelobjects[MAX_SKEL_OBJECTS];
int numskelobjectsused;
skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount);
void skel_dodelete(void);
static model_t *CSQC_GetModelForIndex(int index);
static void CS_LinkEdict(csqcedict_t *ent, qboolean touchtriggers);
@ -592,6 +668,75 @@ static void CS_CheckVelocity(csqcedict_t *ent)
}
static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t *out)
{
//FTE_CSQC_HALFLIFE_MODELS
#ifdef HALFLIFEMODELS
out->bonecontrols[0] = in->v->bonecontrol1;
out->bonecontrols[1] = in->v->bonecontrol2;
out->bonecontrols[2] = in->v->bonecontrol3;
out->bonecontrols[3] = in->v->bonecontrol4;
out->bonecontrols[4] = in->v->bonecontrol5;
out->g[FS_REG].subblendfrac = in->v->subblendfrac;
out->g[FST_BASE].subblendfrac = in->v->subblendfrac;
#endif
//FTE_CSQC_BASEFRAME
out->g[FST_BASE].endbone = in->v->basebone;
if (out->g[FST_BASE].endbone)
{ //small optimisation.
out->g[FST_BASE].frame[0] = in->v->baseframe;
out->g[FST_BASE].frame[1] = in->v->baseframe2;
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{
out->g[FST_BASE].frametime[0] = *csqcg.svtime - in->v->baseframe1time;
out->g[FST_BASE].frametime[1] = *csqcg.svtime - in->v->baseframe2time;
}
else
{
out->g[FST_BASE].frametime[0] = in->v->baseframe1time;
out->g[FST_BASE].frametime[1] = in->v->baseframe2time;
}
out->g[FST_BASE].lerpfrac = in->v->baselerpfrac;
}
//and the normal frames.
out->g[FS_REG].frame[0] = in->v->frame;
out->g[FS_REG].frame[1] = in->v->frame2;
out->g[FS_REG].lerpfrac = in->v->lerpfrac;
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{
out->g[FS_REG].frametime[0] = *csqcg.svtime - in->v->frame1time;
out->g[FS_REG].frametime[1] = *csqcg.svtime - in->v->frame2time;
}
else
{
out->g[FS_REG].frametime[0] = in->v->frame1time;
out->g[FS_REG].frametime[1] = in->v->frame2time;
}
out->bonecount = 0;
out->bonestate = NULL;
if (in->v->skeletonindex)
{
skelobject_t *so;
so = skel_get(csqcprogs, in->v->skeletonindex, 0);
if (so && so->inuse == 1)
{
out->bonecount = so->numbones;
out->bonestate = so->bonematrix;
}
}
}
static void PF_cs_remove (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ed;
@ -713,13 +858,6 @@ void EularToQuaternian(vec3_t angles, float *quat)
quaternion_multiply(t, z, quat);
}
*/
#define CSQCRF_VIEWMODEL 1 //Not drawn in mirrors
#define CSQCRF_EXTERNALMODEL 2 //drawn ONLY in mirrors
#define CSQCRF_DEPTHHACK 4 //fun depthhack
#define CSQCRF_ADDITIVE 8 //add instead of blend
#define CSQCRF_USEAXIS 16 //use v_forward/v_right/v_up as an axis/matrix - predraw is needed to use this properly
#define CSQCRF_NOSHADOW 32 //don't cast shadows upon other entities (can still be self shadowing, if the engine wishes, and not additive)
#define CSQCRF_FRAMETIMESARESTARTTIMES 64 //EXT_CSQC_1: frame times should be read as (time-frametime).
static model_t *CSQC_GetModelForIndex(int index)
{
@ -737,7 +875,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
{
int i;
model_t *model;
int rflags;
unsigned int rflags;
i = in->v->modelindex;
model = CSQC_GetModelForIndex(in->v->modelindex);
@ -766,53 +904,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
else
rflags = 0;
//From here.
//FTE_CSQC_HALFLIFE_MODELS
#ifdef HALFLIFEMODELS
out->bonecontrols[0] = in->v->bonecontrol1;
out->bonecontrols[1] = in->v->bonecontrol2;
out->bonecontrols[2] = in->v->bonecontrol3;
out->bonecontrols[3] = in->v->bonecontrol4;
out->bonecontrols[4] = in->v->bonecontrol5;
out->subblendfrac = in->v->subblendfrac;
out->basesubblendfrac = in->v->basesubblendfrac;
#endif
//FTE_CSQC_BASEFRAME
out->basebone = in->v->basebone;
if (out->basebone)
{ //small optimisation.
out->baseframe1 = in->v->baseframe;
out->baseframe2 = in->v->baseframe2;
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{
out->baseframe1time = *csqcg.svtime - in->v->baseframe1time;
out->baseframe2time = *csqcg.svtime - in->v->baseframe2time;
}
else
{
out->baseframe1time = in->v->baseframe1time;
out->baseframe2time = in->v->baseframe2time;
}
out->baselerpfrac = in->v->baselerpfrac;
}
//and the normal frames.
out->frame1 = in->v->frame;
out->frame2 = in->v->frame2;
out->lerpfrac = in->v->lerpfrac;
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{
out->frame1time = *csqcg.svtime - in->v->frame1time;
out->frame2time = *csqcg.svtime - in->v->frame2time;
}
else
{
out->frame1time = in->v->frame1time;
out->frame2time = in->v->frame2time;
}
//to here... We read only frames and frame times... Yeah... Q1 originally had only a frame field. :D
cs_getframestate(in, rflags, &out->framestate);
VectorCopy(in->v->origin, out->origin);
if (rflags & CSQCRF_USEAXIS)
@ -1074,6 +1166,7 @@ static void PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_global
CL_SetUpPlayerPrediction(true);
}
skel_dodelete();
CL_SwapEntityLists();
view_frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK];
@ -1101,46 +1194,6 @@ static void PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_global
csqc_drawsbar = false;
}
typedef enum
{
VF_MIN = 1,
VF_MIN_X = 2,
VF_MIN_Y = 3,
VF_SIZE = 4,
VF_SIZE_X = 5,
VF_SIZE_Y = 6,
VF_VIEWPORT = 7,
VF_FOV = 8,
VF_FOVX = 9,
VF_FOVY = 10,
VF_ORIGIN = 11,
VF_ORIGIN_X = 12,
VF_ORIGIN_Y = 13,
VF_ORIGIN_Z = 14,
VF_ANGLES = 15,
VF_ANGLES_X = 16,
VF_ANGLES_Y = 17,
VF_ANGLES_Z = 18,
VF_DRAWWORLD = 19,
VF_ENGINESBAR = 20,
VF_DRAWCROSSHAIR = 21,
VF_CARTESIAN_ANGLES = 22,
//this is a DP-compatibility hack.
VF_CL_VIEWANGLES_V = 33,
VF_CL_VIEWANGLES_X = 34,
VF_CL_VIEWANGLES_Y = 35,
VF_CL_VIEWANGLES_Z = 36,
#pragma message("FIXME: add cshift")
//33-36 used by DP...
VF_PERSPECTIVE = 200,
//201 used by DP... WTF? CLEARSCREEN
VF_LPLAYER = 202,
VF_AFOV = 203, //aproximate fov (match what the engine would normally use for the fov cvar). p0=fov, p1=zoom
} viewflags;
static void PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
viewflags parametertype = G_FLOAT(OFS_PARM0);
@ -3116,11 +3169,6 @@ static void PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalvars_s *pr_
float *srcorg = ent->v->origin;
int modelindex = ent->v->modelindex;
int frame1 = ent->v->frame;
int frame2 = ent->v->frame2;
float lerp = ent->v->lerpfrac;
float frame1time = ent->v->frame1time;
float frame2time = ent->v->frame2time;
float *retorg = G_VECTOR(OFS_RETURN);
@ -3129,11 +3177,11 @@ static void PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalvars_s *pr_
float src[12];
float dest[12];
int i;
framestate_t fstate;
if (lerp < 0) lerp = 0;
if (lerp > 1) lerp = 1;
cs_getframestate(ent, ent->v->renderflags, &fstate);
if (Mod_GetTag(mod, tagnum, frame1, frame2, lerp, frame1time, frame2time, transforms))
if (Mod_GetTag(mod, tagnum, &fstate, transforms))
{
VectorCopy(csqcg.forward, src+0);
src[3] = 0;
@ -3190,11 +3238,6 @@ static void PF_cs_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globa
float *origin = G_VECTOR(OFS_RETURN);
int modelindex = ent->v->modelindex;
int frame1 = ent->v->frame;
int frame2 = ent->v->frame2;
float lerp = ent->v->lerpfrac;
float frame1time = ent->v->frame1time;
float frame2time = ent->v->frame2time;
model_t *mod = CSQC_GetModelForIndex(modelindex);
@ -3202,8 +3245,12 @@ static void PF_cs_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globa
float transforms[12];
float result[12];
framestate_t fstate;
cs_getframestate(ent, ent->v->renderflags, &fstate);
#pragma message("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)")
if (!Mod_GetTag(mod, tagnum, frame1, frame2, lerp, frame1time, frame2time, transforms))
if (!Mod_GetTag(mod, tagnum, &fstate, transforms))
{
memset(transforms, 0, sizeof(transforms));
}
@ -3291,6 +3338,314 @@ static void PF_shaderforname (progfuncs_t *prinst, struct globalvars_s *pr_globa
#endif
}
void skel_reset(void)
{
numskelobjectsused = 0;
}
void skel_dodelete(void)
{
int skelidx;
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{
if (skelobjects[skelidx].inuse == 2)
skelobjects[skelidx].inuse = 0;
}
}
skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount)
{
if (skelidx == 0)
{
//allocation
if (!bonecount)
return NULL;
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{
if (!skelobjects[skelidx].inuse && skelobjects[skelidx].numbones == bonecount)
return &skelobjects[skelidx];
}
for (skelidx = 0; skelidx <= numskelobjectsused; skelidx++)
{
if (!skelobjects[skelidx].inuse && !skelobjects[skelidx].numbones)
{
skelobjects[skelidx].numbones = bonecount;
skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount);
if (skelidx < numskelobjectsused)
{
numskelobjectsused = skelidx + 1;
skelobjects[skelidx].model = NULL;
skelobjects[skelidx].inuse = 1;
}
return &skelobjects[skelidx];
}
}
return NULL;
}
else
{
skelidx--;
if ((unsigned int)skelidx >= numskelobjectsused)
return NULL;
if (skelobjects[skelidx].inuse != 1)
return NULL;
if (bonecount && skelobjects[skelidx].numbones != bonecount)
return NULL;
return &skelobjects[skelidx];
}
}
//#263 float(entity ent) skel_buildrel (FTE_CSQC_SKELETONOBJECTS)
//#263 float(entity ent, float skel) skel_updaterel (FTE_CSQC_SKELETONOBJECTS)
static void PF_skel_buildrel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
int skelidx;
int numbones;
framestate_t fstate;
skelobject_t *skelobj;
qboolean isabs;
model_t *model;
if (*prinst->callargc > 1)
skelidx = G_FLOAT(OFS_PARM1);
else
skelidx = 0;
//default to failure
G_FLOAT(OFS_RETURN) = 0;
model = CSQC_GetModelForIndex(ent->v->modelindex);
if (!model)
return; //no model set, can't get a skeleton
cs_getframestate(ent, ent->v->renderflags, &fstate);
//heh... don't copy.
fstate.bonecount = 0;
fstate.bonestate = NULL;
isabs = false;
numbones = Mod_GetNumBones(model, isabs);
if (!numbones)
{
// isabs = true;
// numbones = Mod_GetNumBones(model, isabs);
// if (!numbones)
return; //this isn't a skeletal model.
}
skelobj = skel_get(prinst, skelidx, numbones);
if (!skelobj)
return; //couldn't get one, ran out of memory or something?
if (isabs || skelobj->numbones != Mod_GetBoneRelations(model, skelobj->numbones, &fstate, skelobj->bonematrix))
{
isabs = true;
// float *ab;
// ab = Alias_GetBonePositions(model, &fstate, skelobj->bonematrix, skelobj->numbones);
// if (ab != skelobj->bonematrix)
// memcpy(skelobj->bonematrix, ab, skelobj->numbones*12*sizeof(float));
}
skelobj->model = model;
skelobj->absolute = isabs;
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
}
//#264 float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
static void PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = skelobj->numbones;
}
//#265 string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
static void PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_INT(OFS_RETURN) = 0;
else
{
RETURN_TSTRING(Mod_GetBoneName(skelobj->model, boneidx));
}
}
//#266 float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
static void PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_GetBoneParent(skelobj->model, boneidx);
}
//#267 float(float skel, string tagname) gettagindex (DP_MD3_TAGSINFO)
static void PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
char *bname = PR_GetStringOfs(prinst, OFS_PARM1);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(skelobj->model, bname);
}
//#268 vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
static void PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[4];
skelobject_t *skelobj;
matrix[0] = csqcg.forward;
matrix[1] = csqcg.right;
matrix[2] = csqcg.up;
matrix[3] = G_VECTOR(OFS_RETURN);
skelobj = skel_get(prinst, skelidx, 0);
if (!skelobj || skelobj->absolute || (unsigned int)boneidx >= skelobj->numbones)
{
matrix[0][0] = 1;
matrix[0][1] = 0;
matrix[0][2] = 0;
matrix[1][0] = 0;
matrix[1][1] = 1;
matrix[1][2] = 0;
matrix[2][0] = 0;
matrix[2][1] = 0;
matrix[2][2] = 1;
matrix[3][0] = 0;
matrix[3][1] = 0;
matrix[3][2] = 0;
}
else
{
memcpy(matrix[0], skelobj->bonematrix + boneidx*12 + 0, sizeof(vec3_t));
memcpy(matrix[1], skelobj->bonematrix + boneidx*12 + 3, sizeof(vec3_t));
memcpy(matrix[2], skelobj->bonematrix + boneidx*12 + 6, sizeof(vec3_t));
memcpy(matrix[3], skelobj->bonematrix + boneidx*12 + 9, sizeof(vec3_t));
}
}
//#269 vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
static void PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[4];
skelobject_t *skelobj;
matrix[0] = csqcg.forward;
matrix[1] = csqcg.right;
matrix[2] = csqcg.up;
matrix[3] = G_VECTOR(OFS_RETURN);
skelobj = skel_get(prinst, skelidx, 0);
//codeme
}
//#270 void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
static void PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[4];
skelobject_t *skelobj;
matrix[0] = csqcg.forward;
matrix[1] = csqcg.right;
matrix[2] = csqcg.up;
matrix[3] = G_VECTOR(OFS_PARM2);
skelobj = skel_get(prinst, skelidx, 0);
//codeme
}
//#271 void(float skel, float bonenum, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
static void PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int boneidx = G_FLOAT(OFS_PARM1)-1;
float *matrix[4];
matrix[0] = csqcg.forward;
matrix[1] = csqcg.right;
matrix[2] = csqcg.up;
matrix[3] = G_VECTOR(OFS_PARM2);
//codeme
}
//#272 void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
static void PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
int startbone = G_FLOAT(OFS_PARM1)-1;
int endbone = G_FLOAT(OFS_PARM2)-1;
float *matrix[4];
matrix[0] = csqcg.forward;
matrix[1] = csqcg.right;
matrix[2] = csqcg.up;
matrix[3] = G_VECTOR(OFS_PARM3);
//codeme
}
//#273 void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
static void PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skeldst = G_FLOAT(OFS_PARM0);
int skelsrc = G_FLOAT(OFS_PARM1);
int startbone = G_FLOAT(OFS_PARM2)-1;
int endbone = G_FLOAT(OFS_PARM3)-1;
//codeme
}
//#274 void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
static void PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int skelidx = G_FLOAT(OFS_PARM0);
skelobject_t *skelobj;
skelobj = skel_get(prinst, skelidx, 0);
if (skelobj)
skelobj->inuse = 2; //2 means don't reuse yet.
}
static qboolean CS_CheckBottom (csqcedict_t *ent)
{
int savedhull;
@ -4047,6 +4402,19 @@ static struct {
{"stoh", PF_stoh, 261},
{"htos", PF_htos, 262},
{"skel_buildrel", PF_skel_buildrel, 263},//float(entity ent) skel_buildrel (FTE_CSQC_SKELETONOBJECTS)
{"skel_get_numbones", PF_skel_get_numbones, 264},//float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS)
{"skel_get_bonename", PF_skel_get_bonename, 265},//string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
{"skel_get_boneparent", PF_skel_get_boneparent, 266},//float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS)
{"skel_find_bone", PF_skel_find_bone, 267},//float(float skel, string tagname) gettagindex (DP_MD3_TAGSINFO)
{"skel_get_bonerel", PF_skel_get_bonerel, 268},//vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
{"skel_get_boneabs", PF_skel_get_boneabs, 269},//vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
{"skel_set_bone", PF_skel_set_bone, 270},//void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
{"skel_mul_bone", PF_skel_mul_bone, 271},//void(float skel, float bonenum, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
{"skel_mul_bones", PF_skel_mul_bones, 272},//void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc)
{"skel_copybones", PF_skel_copybones, 273},//void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS)
{"skel_delete", PF_skel_delete, 274},//void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS)
//300
{"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC)
{"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC)
@ -4523,6 +4891,7 @@ qboolean CSQC_Init (unsigned int checksum)
pr_builtin[BuiltinList[i].ebfsnum] = BuiltinList[i].bifunc;
}
skel_reset();
memset(cl.model_csqcname, 0, sizeof(cl.model_csqcname));
memset(cl.model_csqcprecache, 0, sizeof(cl.model_csqcprecache));

View File

@ -278,8 +278,8 @@ void R_StoreEfrags (efrag_t **ppefrag)
if ((pent->visframe != r_framecount) &&
(cl_numvisedicts < MAX_VISEDICTS))
{
pent->frame1time = cl.time;
pent->frame2time = cl.time;
pent->framestate.g[FS_REG].frametime[0] = cl.time;
pent->framestate.g[FS_REG].frametime[1] = cl.time;
cl_visedicts[cl_numvisedicts++] = *pent;
// mark that we've recorded this entity for this frame

View File

@ -54,7 +54,6 @@ typedef enum {
RT_MAX_REF_ENTITY_TYPE
} refEntityType_t;
#define MAX_BONE_CONTROLLERS 5
typedef struct entity_s
{
int keynum; // for matching entities in different frames
@ -87,24 +86,7 @@ typedef struct entity_s
// that splits bmodel, or NULL if
// not split
int frame1;
int frame2;
float frame1time;
float frame2time;
float lerpfrac;
#ifdef HALFLIFEMODELS
float subblendfrac; //hl models are weird
float bonecontrols[MAX_BONE_CONTROLLERS]; //hl special bone controllers
float basesubblendfrac;//hl models are weird
#endif
int baseframe1; //used to control legs animations
int baseframe2;
float baseframe1time;
float baseframe2time;
float baselerpfrac;//
int basebone; //the base frame fills bones up to this one (thus if 0, base sequence is not used).
framestate_t framestate;
int flags;
@ -399,7 +381,6 @@ void GL_InfinatePerspective(double fovx, double fovy, double zNear);
#if defined(RGLQUAKE) || defined(D3DQUAKE)
void GLMod_Init (void);
qboolean Mod_GetTag(struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *result);
int Mod_TagNumForName(struct model_s *model, char *name);
int Mod_SkinNumForName(struct model_s *model, char *name);
@ -472,9 +453,6 @@ void BoostGamma(qbyte *rgba, int width, int height);
void SaturateR8G8B8(qbyte *data, int size, float sat);
void AddOcranaLEDsIndexed (qbyte *image, int h, int w);
void CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time,
float r, float g, float b);
void Renderer_Init(void);
void R_RestartRenderer_f (void);//this goes here so we can save some stack when first initing the sw renderer.

View File

@ -2216,7 +2216,7 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
float *pintervals, fullinterval, targettime, time;
psprite = currententity->model->cache.data;
frame = currententity->frame1;
frame = currententity->framestate.g[FS_REG].frame[0];
if ((frame >= psprite->numframes) || (frame < 0))
{
@ -2240,7 +2240,7 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
time = currententity->frame1time;
time = currententity->framestate.g[FS_REG].frametime[0];
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by 0
@ -2368,7 +2368,7 @@ texture_t *R_TextureAnimation (texture_t *base)
int reletive;
int count;
if (currententity->frame1)
if (currententity->framestate.g[FS_REG].frame[0])
{
if (base->alternate_anims)
base = base->alternate_anims;

View File

@ -15,14 +15,14 @@ int rqmaxgrad, rqmingrad;
int rquesize = 0x2000;
void RQ_AddDistReorder(void (*render) (void *, void *), void *data1, void *data2, float *pos)
void RQ_AddDistReorder(void (*render) (int count, void **objects, void *objtype), void *object, void *objtype, float *pos)
{
int dist;
vec3_t delta;
renderque_t *rq;
if (!freerque)
{
render(data1, data2);
render(1, &object, objtype);
return;
}
@ -50,8 +50,8 @@ void RQ_AddDistReorder(void (*render) (void *, void *), void *data1, void *data2
distlastarque[dist] = rq;
rq->render = render;
rq->data1 = data1;
rq->data2 = data2;
rq->data1 = object;
rq->data2 = objtype;
if (!distrque[dist])
distrque[dist] = rq;
@ -66,7 +66,7 @@ void RQ_RenderDistAndClear(void)
{
for (rq = distrque[i]; rq; rq=rq->next)
{
rq->render(rq->data1, rq->data2);
rq->render(1, &rq->data1, rq->data2);
}
if (distlastarque[i])
{
@ -79,6 +79,45 @@ void RQ_RenderDistAndClear(void)
rqmaxgrad=0;
rqmingrad = NUMGRADUATIONS-1;
}
void RQ_RenderBatchClear(void)
{
#define SLOTS 512
void *slot[SLOTS];
void *typeptr = NULL;
int maxslot = SLOTS;
void (*lr) (int count, void **objects, void *objtype) = NULL;
int i;
renderque_t *rq;
for (i = rqmaxgrad; i>=rqmingrad; i--)
// for (i = rqmingrad; i<=rqmaxgrad; i++)
{
for (rq = distrque[i]; rq; rq=rq->next)
{
if (!maxslot || rq->render != lr || typeptr != rq->data2)
{
if (maxslot != SLOTS)
lr(SLOTS - maxslot, &slot[maxslot], typeptr);
maxslot = SLOTS;
}
slot[--maxslot] = rq->data1;
typeptr = rq->data2;
lr = rq->render;
}
if (distlastarque[i])
{
distlastarque[i]->next = freerque;
freerque = distrque[i];
distrque[i] = NULL;
distlastarque[i] = NULL;
}
}
if (maxslot != SLOTS)
lr(SLOTS - maxslot, &slot[maxslot], typeptr);
rqmaxgrad=0;
rqmingrad = NUMGRADUATIONS-1;
}
void RQ_Init(void)
{

View File

@ -1,14 +1,15 @@
#ifndef RENDERQUE_H
#define RENDERQUE_H
void RQ_AddDistReorder(void (*render) (void *, void *), void *data1, void *data2, float *pos);
void RQ_AddDistReorder(void (*render) (int count, void **objects, void *objtype), void *object, void *objtype, float *pos);
void RQ_RenderDistAndClear(void);
void RQ_RenderBatchClear(void);
typedef struct renderque_s
{
struct renderque_s *next;
void (*render) (void *data1, void *data2);
void (*render) (int count, void **objects, void *objtype);
void *data1;
void *data2;
} renderque_t;

View File

@ -1198,7 +1198,7 @@ void V_CalcRefdef (int pnum)
view->model = NULL;
else
view->model = cl.model_precache[cl.stats[pnum][STAT_WEAPON]];
view->frame1 = view_message?view_message->weaponframe:0;
view->framestate.g[FS_REG].frame[0] = view_message?view_message->weaponframe:0;
#ifdef SWQUAKE
view->palremap = D_IdentityRemap();
#endif

View File

@ -34,6 +34,6 @@ void SWV_UpdatePalette (qboolean force, double ftime);
void V_ClearCShifts (void);
qboolean V_CheckGamma (void);
void V_AddEntity(entity_t *in);
void V_AddLerpEntity(entity_t *in);
void VQ2_AddLerpEntity(entity_t *in);
void V_AddAxisEntity(entity_t *in);
void V_AddLight (vec3_t org, float quant, float r, float g, float b);

View File

@ -21,6 +21,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef __BOTHDEFS_H
#define __BOTHDEFS_H
#ifdef D3DQUAKE
#pragma message("d3dquake is temporarily disabled!")
#undef D3DQUAKE
#endif
#if defined(__APPLE__) && defined(__MACH__)
#define MACOSX
#endif
@ -165,6 +170,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
#ifdef PSET_SCRIPT
#pragma message("fte particles are temporarily disabled!")
#undef PSET_SCRIPT
#endif
//fix things a little...
#ifndef _WIN32

View File

@ -506,6 +506,8 @@ typedef struct
#define SURF_NODRAW 0x80 // don't bother referencing the texture
#define SURF_ALPHATEST 0x100
#define Q3SURF_LADDER 0x8 //wee
// content masks

View File

@ -1,4 +1,48 @@
#include "quakedef.h"
#include "com_mesh.h"
extern model_t *loadmodel;
extern char loadname[];
//Common loader function.
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
{
#ifndef SERVERONLY
//we've got to have this bit
if (loadmodel->engineflags & MDLF_DOCRC)
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
QCRC_Init(&crc);
for (len = buffersize, p = buffer; len; len--, p++)
QCRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
(int)crc);
}
if (!(loadmodel->engineflags & MDLF_PLAYER))
{ //eyes
loadmodel->tainted = (crc != 6967);
}
}
#endif
}
#if defined(D3DQUAKE) || defined(RGLQUAKE) || defined(SERVERONLY)
#ifdef D3DQUAKE
@ -8,8 +52,6 @@
#include "glquake.h"
#endif
#include "com_mesh.h"
#ifdef _WIN32
#include <malloc.h>
#else
@ -22,10 +64,6 @@ extern cvar_t r_skin_overlays;
extern cvar_t mod_md3flags;
extern model_t *loadmodel;
extern char loadname[];
typedef struct
{
@ -80,6 +118,280 @@ clampedmodel_t clampedmodel[] = {
#ifdef SKELETALMODELS
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, float *xyzout)
{
int i;
float *out, *matrix;
galisskeletaltransforms_t *v = weights;
for (i = 0;i < numweights;i++, v++)
{
out = xyzout + v->vertexindex * 3;
matrix = bonepose+v->boneindex*12;
// FIXME: this can very easily be optimized with SSE or 3DNow
out[0] += v->org[0] * matrix[0] + v->org[1] * matrix[1] + v->org[2] * matrix[ 2] + v->org[3] * matrix[ 3];
out[1] += v->org[0] * matrix[4] + v->org[1] * matrix[5] + v->org[2] * matrix[ 6] + v->org[3] * matrix[ 7];
out[2] += v->org[0] * matrix[8] + v->org[1] * matrix[9] + v->org[2] * matrix[10] + v->org[3] * matrix[11];
}
}
static int Alias_BuildLerps(float plerp[4], float *pose[4], int numbones, galiasgroup_t *g1, galiasgroup_t *g2, float lerpfrac, float fg1time, float fg2time)
{
int frame1;
int frame2;
float mlerp; //minor lerp, poses within a group.
int l = 0;
mlerp = (fg1time)*g1->rate;
frame1=mlerp;
frame2=frame1+1;
mlerp-=frame1;
if (g1->loop)
{
frame1=frame1%g1->numposes;
frame2=frame2%g1->numposes;
}
else
{
frame1=(frame1>g1->numposes-1)?g1->numposes-1:frame1;
frame2=(frame2>g1->numposes-1)?g1->numposes-1:frame2;
}
plerp[l] = (1-mlerp)*(1-lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*numbones*12*frame1);
plerp[l] = (mlerp)*(1-lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*numbones*12*frame2);
if (lerpfrac)
{
mlerp = (fg2time)*g2->rate;
frame1=mlerp;
frame2=frame1+1;
mlerp-=frame1;
if (g2->loop)
{
frame1=frame1%g2->numposes;
frame2=frame2%g2->numposes;
}
else
{
frame1=(frame1>g2->numposes-1)?g2->numposes-1:frame1;
frame2=(frame2>g2->numposes-1)?g2->numposes-1:frame2;
}
plerp[l] = (1-mlerp)*(lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*numbones*12*frame1);
plerp[l] = (mlerp)*(lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*numbones*12*frame2);
}
return l;
}
//
int Alias_GetBoneRelations(galiasinfo_t *inf, framestate_t *fstate, float *result, int numbones)
{
#ifdef SKELETALMODELS
if (inf->numbones)
{
galiasbone_t *bone;
galiasgroup_t *g1, *g2;
float *matrix; //the matrix for a single bone in a single pose.
int b, k; //counters
float *pose[4]; //the per-bone matricies (one for each pose)
float plerp[4]; //the ammount of that pose to use (must combine to 1)
int numposes = 0;
int frame1, frame2;
float f1time, f2time;
float f2ness;
int bonegroup;
int cbone = 0;
int lastbone;
if (numbones > inf->numbones)
numbones = inf->numbones;
if (!numbones)
return 0;
for (bonegroup = 0; bonegroup < FS_COUNT; bonegroup++)
{
lastbone = fstate->g[bonegroup].endbone;
if (bonegroup == FS_COUNT-1 || lastbone > numbones)
lastbone = numbones;
if (lastbone == cbone)
continue;
frame1 = fstate->g[bonegroup].frame[0];
frame2 = fstate->g[bonegroup].frame[1];
f1time = fstate->g[bonegroup].frametime[0];
f2time = fstate->g[bonegroup].frametime[1];
f2ness = fstate->g[bonegroup].lerpfrac;
if (frame1 < 0 || frame1 >= inf->groups)
continue; //invalid, try ignoring this group
if (frame2 < 0 || frame2 >= inf->groups)
{
f2ness = 0;
frame2 = frame1;
}
bone = (galiasbone_t*)((char*)inf + inf->ofsbones);
//the higher level merges old/new anims, but we still need to blend between automated frame-groups.
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
if (!g1->isheirachical)
return 0;
if (!g2->isheirachical)
g2 = g1;
numposes = Alias_BuildLerps(plerp, pose, inf->numbones, g1, g2, f2ness, f1time, f2time);
if (numposes == 1)
{
memcpy(result, pose[0]+cbone*12, (lastbone-cbone)*12*sizeof(float));
result += (lastbone-cbone)*12;
cbone = lastbone;
}
else
{
//set up the identity matrix
for (; cbone < lastbone; cbone++)
{
//set up the per-bone transform matrix
for (k = 0;k < 12;k++)
result[k] = 0;
for (b = 0;b < numposes;b++)
{
matrix = pose[b] + cbone*12;
for (k = 0;k < 12;k++)
result[k] += matrix[k] * plerp[b];
}
result += 12;
}
}
}
return cbone;
}
#endif
return 0;
}
//_may_ into bonepose, return value is the real result
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize)
{
float relationsbuf[MAX_BONES][12];
float *relations = NULL;
galiasbone_t *bones = (galiasbone_t *)((char*)inf+inf->ofsbones);
int numbones;
if (buffersize < inf->numbones)
numbones = 0;
else if (fstate->bonestate && fstate->bonecount >= inf->numbones)
{
relations = fstate->bonestate;
numbones = inf->numbones;
}
else
{
numbones = Alias_GetBoneRelations(inf, fstate, (float*)relationsbuf, inf->numbones);
if (numbones == inf->numbones)
relations = (float*)relationsbuf;
}
if (relations)
{
int i, k;
for (i = 0; i < numbones; i++)
{
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)(buffer + bones[i].parent*12), (void*)((float*)relations+i*12), (void*)(buffer+i*12));
else
for (k = 0;k < 12;k++) //parentless
buffer[i*12+k] = ((float*)relations)[i*12+k];
}
return buffer;
}
else
{
int i, k;
int l=0;
float plerp[4];
float *pose[4];
int numposes;
int f;
float lerpfrac = fstate->g[FS_REG].lerpfrac;
galiasgroup_t *g1, *g2;
galiasbone_t *bones = (galiasbone_t *)((char*)inf+inf->ofsbones);
if (buffersize < inf->numbones)
return NULL;
f = fstate->g[FS_REG].frame[0];
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*bound(0, f, inf->groups-1));
f = fstate->g[FS_REG].frame[1];
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*bound(0, f, inf->groups-1));
if (g2->isheirachical)
g2 = g1;
numposes = Alias_BuildLerps(plerp, pose, inf->numbones, g1, g2, lerpfrac, fstate->g[FS_REG].frametime[0], fstate->g[FS_REG].frametime[1]);
{
//this is not hierachal, using base frames is not a good idea.
//just blend the poses here
if (numposes == 1)
return pose[0];
else if (numposes == 2)
{
for (i = 0; i < inf->numbones*12; i++)
{
((float*)buffer)[i] = pose[0][i]*plerp[0] + pose[1][i]*plerp[1];
}
}
else
{
for (i = 0; i < inf->numbones; i++)
{
for (l = 0; l < 12; l++)
buffer[i*12+l] = 0;
for (k = 0; k < numposes; k++)
{
for (l = 0; l < 12; l++)
buffer[i*12+l] += pose[k][i*12+l] * plerp[k];
}
}
}
}
return buffer;
}
}
static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, float bonepose[MAX_BONES][12])
{
int i, k, b;
@ -123,22 +435,7 @@ static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bon
}
}
}
static void R_TransformVerticies(float bonepose[MAX_BONES][12], galisskeletaltransforms_t *weights, int numweights, float *xyzout)
{
int i;
float *out, *matrix;
galisskeletaltransforms_t *v = weights;
for (i = 0;i < numweights;i++, v++)
{
out = xyzout + v->vertexindex * 3;
matrix = bonepose[v->boneindex];
// FIXME: this can very easily be optimized with SSE or 3DNow
out[0] += v->org[0] * matrix[0] + v->org[1] * matrix[1] + v->org[2] * matrix[ 2] + v->org[3] * matrix[ 3];
out[1] += v->org[0] * matrix[4] + v->org[1] * matrix[5] + v->org[2] * matrix[ 6] + v->org[3] * matrix[ 7];
out[2] += v->org[0] * matrix[8] + v->org[1] * matrix[9] + v->org[2] * matrix[10] + v->org[3] * matrix[11];
}
}
#ifndef SERVERONLY
static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int poses, galiasbone_t *bones, int bonecount, galisskeletaltransforms_t *weights, int numweights, qboolean usehierarchy)
{
@ -198,7 +495,7 @@ static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int po
mesh->colors_array = NULL;
memset(mesh->xyz_array, 0, mesh->numvertexes*sizeof(vec3_t));
R_TransformVerticies(bonepose, weights, numweights, (float*)mesh->xyz_array);
Alias_TransformVerticies((float*)bonepose, weights, numweights, (float*)mesh->xyz_array);
@ -629,10 +926,10 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, ve
{
if (!mod->sharesbones)
R_LerpBones(&frac, (float**)posedata, 1, (galiasbone_t*)((char*)mod + mod->ofsbones), mod->numbones, bonepose);
R_TransformVerticies(bonepose, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
Alias_TransformVerticies((float*)bonepose, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
}
else
R_TransformVerticies((void*)posedata, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
Alias_TransformVerticies((float*)posedata, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
}
#endif
@ -696,45 +993,6 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, ve
}
//Common loader function.
static void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
{
#ifndef SERVERONLY
//we've got to have this bit
if (loadmodel->engineflags & MDLF_DOCRC)
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
QCRC_Init(&crc);
for (len = buffersize, p = buffer; len; len--, p++)
QCRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
(int)crc);
}
if (!(loadmodel->engineflags & MDLF_PLAYER))
{ //eyes
loadmodel->tainted = (crc != 6967);
}
}
#endif
}
static void Mod_ClampModelSize(model_t *mod)
{
#ifndef SERVERONLY
@ -1577,8 +1835,6 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
loadmodel=mod;
Mod_DoCRC(loadmodel, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
pq1inmodel = (dmdl_t *)buffer;
@ -1898,8 +2154,6 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer)
loadmodel->engineflags |= MDLF_NEEDOVERBRIGHT;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
pq2inmodel = (md2_t *)buffer;
@ -2121,9 +2375,76 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer)
int Mod_GetNumBones(model_t *model, qboolean allowtags)
{
galiasinfo_t *inf;
if (!model || model->type != mod_alias)
return 0;
inf = Mod_Extradata(model);
#ifdef SKELETALMODELS
if (inf->numbones)
return inf->numbones;
else
#endif
if (allowtags)
return inf->numtags;
else
return 0;
}
int Mod_GetBoneRelations(model_t *model, int numbones, framestate_t *fstate, float *result)
{
galiasinfo_t *inf;
if (!model || model->type != mod_alias)
return false;
inf = Mod_Extradata(model);
return Alias_GetBoneRelations(inf, fstate, result, numbones);
}
int Mod_GetBoneParent(model_t *model, int bonenum)
{
galiasbone_t *bone;
galiasinfo_t *inf;
if (!model || model->type != mod_alias)
return 0;
inf = Mod_Extradata(model);
bonenum--;
if ((unsigned int)bonenum >= inf->numbones)
return 0; //no parent
bone = (galiasbone_t*)((char*)inf + inf->ofsbones);
return bone[bonenum].parent+1;
}
char *Mod_GetBoneName(model_t *model, int bonenum)
{
galiasbone_t *bone;
galiasinfo_t *inf;
if (!model || model->type != mod_alias)
return 0;
inf = Mod_Extradata(model);
bonenum--;
if ((unsigned int)bonenum >= inf->numbones)
return 0; //no parent
bone = (galiasbone_t*)((char*)inf + inf->ofsbones);
return bone[bonenum].name;
}
typedef struct {
@ -2132,9 +2453,7 @@ typedef struct {
float ang[3][3];
} md3tag_t;
qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result)
qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *result)
{
galiasinfo_t *inf;
@ -2158,6 +2477,17 @@ qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2
float plerp[4]; //the ammount of that pose to use (must combine to 1)
int numposes = 0;
int frame1, frame2;
float f1time, f2time;
float f2ness;
#pragma message("fixme")
frame1 = fstate->g[FS_REG].frame[0];
frame2 = fstate->g[FS_REG].frame[1];
f1time = fstate->g[FS_REG].frametime[0];
f2time = fstate->g[FS_REG].frametime[1];
f2ness = fstate->g[FS_REG].lerpfrac;
if (tagnum <= 0 || tagnum > inf->numbones)
return false;
tagnum--; //tagnum 0 is 'use my angles/org'
@ -2237,6 +2567,16 @@ qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2
{
md3tag_t *t1, *t2;
int frame1, frame2;
float f1time, f2time;
float f2ness;
frame1 = fstate->g[FS_REG].frame[0];
frame2 = fstate->g[FS_REG].frame[1];
f1time = fstate->g[FS_REG].frametime[0];
f2time = fstate->g[FS_REG].frametime[1];
f2ness = fstate->g[FS_REG].lerpfrac;
if (tagnum <= 0 || tagnum > inf->numtags)
return false;
if (frame1 < 0)
@ -2465,8 +2805,6 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer)
loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
header = buffer;
@ -2871,8 +3209,6 @@ qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer)
loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
header = buffer;
@ -3227,8 +3563,6 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer)
loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
header = buffer;
@ -3887,8 +4221,6 @@ qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer)
loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
@ -4159,8 +4491,6 @@ qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer)
loadmodel=mod;
Mod_DoCRC(mod, buffer, com_filesize);
hunkstart = Hunk_LowMark ();
@ -4304,8 +4634,25 @@ int Mod_TagNumForName(model_t *model, char *name)
{
return 0;
}
qboolean Mod_GetTag(model_t *model, int tagnum, int frame1, int frame2, float f2ness, float f1time, float f2time, float *result)
qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *framestate, float *result)
{
return false;
}
int Mod_GetNumBones(struct model_s *model, qboolean allowtags)
{
return 0;
}
int Mod_GetBoneRelations(struct model_s *model, int numbones, framestate_t *fstate, float *result)
{
return 0;
}
int Mod_GetBoneParent(struct model_s *model, int bonenum)
{
return 0;
}
char *Mod_GetBoneName(struct model_s *model, int bonenum)
{
return "";
}
#endif //#if defined(D3DQUAKE) || defined(RGLQUAKE)

View File

@ -120,4 +120,23 @@ typedef struct {
} galiascolourmapped_t;
#endif
float *Alias_GetBonePositions(galiasinfo_t *inf, framestate_t *fstate, float *buffer, int buffersize);
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, float *xyzout);
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize);
qboolean Mod_LoadQ1Model (model_t *mod, void *buffer);
#ifdef MD2MODELS
qboolean Mod_LoadQ2Model (model_t *mod, void *buffer);
#endif
#ifdef MD3MODELS
qboolean Mod_LoadQ3Model(model_t *mod, void *buffer);
#endif
#ifdef ZYMOTICMODELS
qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer);
qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer);
#endif
#ifdef MD5MODELS
qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer);
qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer);
#endif

View File

@ -348,7 +348,7 @@ void FS_ReloadPackFiles(void);
char *FS_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
enum {
FS_GAME,
FS_BASE,
FS_ROOT,
FS_GAMEONLY,
FS_CONFIGONLY,
FS_SKINS

View File

@ -2135,7 +2135,7 @@ vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto)
else
snprintf(fullname, sizeof(fullname), "%sqw/skins/%s", com_quakedir, filename);
break;
case FS_BASE:
case FS_ROOT:
if (*com_homedir)
{
snprintf(fullname, sizeof(fullname), "%s%s", com_homedir, filename);
@ -2203,7 +2203,7 @@ int FS_Rename2(char *oldf, char *newf, int oldrelativeto, int newrelativeto)
else
snprintf(oldfullname, sizeof(oldfullname), "%sqw/skins/", com_quakedir);
break;
case FS_BASE:
case FS_ROOT:
if (*com_homedir)
snprintf(oldfullname, sizeof(oldfullname), "%s", com_homedir);
else
@ -2227,7 +2227,7 @@ int FS_Rename2(char *oldf, char *newf, int oldrelativeto, int newrelativeto)
else
snprintf(newfullname, sizeof(newfullname), "%sqw/skins/", com_quakedir);
break;
case FS_BASE:
case FS_ROOT:
if (*com_homedir)
snprintf(newfullname, sizeof(newfullname), "%s", com_homedir);
else
@ -2262,7 +2262,7 @@ int FS_Rename(char *oldf, char *newf, int relativeto)
else
snprintf(oldfullname, sizeof(oldfullname), "%sqw/skins/", com_quakedir);
break;
case FS_BASE:
case FS_ROOT:
if (*com_homedir)
snprintf(oldfullname, sizeof(oldfullname), "%s", com_homedir);
else
@ -2296,7 +2296,7 @@ int FS_Remove(char *fname, int relativeto)
else
snprintf(fullname, sizeof(fullname), "%sqw/skins/%s", com_quakedir, fname);
break;
case FS_BASE:
case FS_ROOT:
if (*com_homedir)
snprintf(fullname, sizeof(fullname), "%s%s", com_homedir, fname);
else
@ -2317,7 +2317,7 @@ void FS_CreatePath(char *pname, int relativeto)
case FS_GAME:
snprintf(fullname, sizeof(fullname), "%s/%s", com_gamedir, pname);
break;
case FS_BASE:
case FS_ROOT:
if (*com_homedir)
snprintf(fullname, sizeof(fullname), "%s%s", com_homedir, pname);
else

View File

@ -188,7 +188,7 @@ void Log_String (logtype_t lognum, char *s)
vfsfile_t *fi;
// check file size, use x as temp
if ((fi = FS_OpenVFS(f, "rb", FS_BASE)))
if ((fi = FS_OpenVFS(f, "rb", FS_ROOT)))
{
x = VFS_GETLEN(fi);
VFS_CLOSE(fi);
@ -206,7 +206,7 @@ void Log_String (logtype_t lognum, char *s)
// unlink file at the top of the chain
snprintf(oldf, sizeof(oldf)-1, "%s.%i", f, i);
FS_Remove(oldf, FS_BASE);
FS_Remove(oldf, FS_ROOT);
// rename files through chain
for (x = i-1; x > 0; x--)
@ -215,12 +215,12 @@ void Log_String (logtype_t lognum, char *s)
snprintf(oldf, sizeof(oldf)-1, "%s.%i", f, x);
// check if file exists, otherwise skip
if ((fi = FS_OpenVFS(oldf, "rb", FS_BASE)))
if ((fi = FS_OpenVFS(oldf, "rb", FS_ROOT)))
VFS_CLOSE(fi);
else
continue; // skip nonexistant files
if (FS_Rename(oldf, newf, FS_BASE))
if (FS_Rename(oldf, newf, FS_ROOT))
{
// rename failed, disable log and bug out
Cvar_ForceSet(&log_enable[lognum], "0");
@ -231,7 +231,7 @@ void Log_String (logtype_t lognum, char *s)
// TODO: option to compress file somewhere in here?
// rename our base file, which better exist...
if (FS_Rename(f, oldf, FS_BASE))
if (FS_Rename(f, oldf, FS_ROOT))
{
// rename failed, disable log and bug out
Cvar_ForceSet(&log_enable[lognum], "0");
@ -241,8 +241,8 @@ void Log_String (logtype_t lognum, char *s)
}
}
FS_CreatePath(f, FS_BASE);
if ((fi = FS_OpenVFS(f, "ab", FS_BASE)))
FS_CreatePath(f, FS_ROOT);
if ((fi = FS_OpenVFS(f, "ab", FS_ROOT)))
{
VFS_WRITE(fi, logbuf, strlen(logbuf));
VFS_CLOSE(fi);

View File

@ -312,7 +312,7 @@ void VVPerpendicularVector(vec3_t dst, const vec3_t src)
VectorNormalize(dst);
}
}
void VectorVectors(vec3_t forward, vec3_t right, vec3_t up)
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
{
VVPerpendicularVector(right, forward);
CrossProduct(right, forward, up);
@ -389,7 +389,7 @@ void _VectorCopy (vec3_t in, vec3_t out)
out[2] = in[2];
}
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross)
{
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
cross[1] = v1[2]*v2[0] - v1[0]*v2[2];

View File

@ -91,7 +91,7 @@ void VARGS BOPS_Error (void);
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
void ClearBounds (vec3_t mins, vec3_t maxs);
float ColorNormalize (vec3_t in, vec3_t out);
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
void FloorDivMod (double numer, double denom, int *quotient, int *rem);
int GreatestCommonDivisor (int i1, int i2);
fixed16_t Invert24To16 (fixed16_t val);
@ -129,4 +129,4 @@ vec_t VectorNormalize2 (vec3_t v, vec3_t out);
void VectorNormalizeFast(vec3_t v);
void VectorScale (vec3_t in, vec_t scale, vec3_t out);
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out);
void VectorVectors (vec3_t forward, vec3_t right, vec3_t up);
void VectorVectors (const vec3_t forward, vec3_t right, vec3_t up);

View File

@ -241,7 +241,7 @@ static int VMEnumMods(char *match, int size, void *args)
return true; //we only count directories with a pk3 file
Q_strncpyz(desc, match, sizeof(desc));
f = FS_OpenVFS(va("%s/description.txt", match), "rb", FS_BASE);
f = FS_OpenVFS(va("%s/description.txt", match), "rb", FS_ROOT);
if (f)
{
VFS_GETS(f, desc, sizeof(desc));

View File

@ -588,8 +588,6 @@ SOURCE=..\server\svq3_game.c
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# PROP Exclude_From_Build 1
@ -2017,6 +2015,45 @@ SOURCE=..\client\p_classic.c
# End Source File
# Begin Source File
SOURCE=..\client\p_darkplaces.c
!IF "$(CFG)" == "ftequake - Win32 Release"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3"
!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\client\p_null.c
!IF "$(CFG)" == "ftequake - Win32 Release"
@ -2336,7 +2373,6 @@ SOURCE=..\client\r_partset.c
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# PROP Exclude_From_Build 1
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
@ -3282,6 +3318,8 @@ SOURCE=..\gl\gl_alias.c
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# PROP Exclude_From_Build 1
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# PROP BASE Exclude_From_Build 1

View File

@ -17,7 +17,7 @@
#ifdef RGLQUAKE
#include "glquake.h"
#endif
#if defined(RGLQUAKE) || defined(SERVERONLY)
#if defined(RGLQUAKE)
#ifdef _WIN32
#include <malloc.h>
@ -27,9 +27,7 @@
#define MAX_BONES 256
#ifndef SERVERONLY
static model_t *loadmodel;
#endif
static model_t *loadmodel;
#include "com_mesh.h"
@ -93,45 +91,7 @@ extern cvar_t r_vertexdlights;
extern cvar_t mod_md3flags;
extern cvar_t r_skin_overlays;
#ifdef SKELETALMODELS
static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bones, int startingbone, int bonecount, float bonepose[MAX_BONES][12]);
static void R_TransformVerticies(float bonepose[MAX_BONES][12], galisskeletaltransforms_t *weights, int numweights, float *xyzout);
#endif
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
{
#ifndef SERVERONLY
//we've got to have this bit
if (loadmodel->engineflags & MDLF_DOCRC)
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
QCRC_Init(&crc);
for (len = buffersize, p = buffer; len; len--, p++)
QCRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
(int)crc);
}
if (!(loadmodel->engineflags & MDLF_PLAYER))
{ //eyes
loadmodel->tainted = (crc != 6967);
}
}
#endif
}
/*
qboolean GLMod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
galiasinfo_t *mod = Mod_Extradata(model);
@ -172,10 +132,10 @@ qboolean GLMod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start,
{
if (!mod->sharesbones)
R_LerpBones(&frac, (float**)posedata, 1, (galiasbone_t*)((char*)mod + mod->ofsbones), 0, mod->numbones, bonepose);
R_TransformVerticies(bonepose, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
Alias_TransformVerticies(bonepose, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
}
else
R_TransformVerticies((void*)posedata, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
Alias_TransformVerticies((void*)posedata, (galisskeletaltransforms_t*)((char*)mod + mod->ofstransforms), mod->numtransforms, posedata);
}
#endif
@ -237,6 +197,7 @@ qboolean GLMod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start,
return trace->fraction != 1;
}
*/
#ifndef SERVERONLY
static hashtable_t skincolourmapped;
@ -365,242 +326,9 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
}
#endif
#ifdef SKELETALMODELS
static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bones, int startingbone, int bonecount, float bonepose[MAX_BONES][12])
{
int i, k, b;
float *matrix, *matrix2, m[12];
if (poses == 1)
{
// vertex weighted skeletal
// interpolate matrices and concatenate them to their parents
matrix = pose[0] + startingbone*12;
for (i = startingbone;i < bonecount;i++)
{
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)bonepose[bones[i].parent], (void*)matrix, (void*)bonepose[i]);
else
for (k = 0;k < 12;k++) //parentless
bonepose[i][k] = matrix[k];
matrix += 12;
}
}
else if (poses == 2)
{
// vertex weighted skeletal
// interpolate matrices and concatenate them to their parents
matrix = pose[0] + startingbone*12;
matrix2 = pose[1] + startingbone*12;
for (i = startingbone;i < bonecount;i++)
{
//only two poses, blend the matricies to generate a temp matrix
for (k = 0;k < 12;k++)
m[k] = (matrix[k] * plerp[0]) + (matrix2[k] * plerp[1]);
matrix += 12;
matrix2 += 12;
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)bonepose[bones[i].parent], (void*)m, (void*)bonepose[i]);
else
for (k = 0;k < 12;k++) //parentless
bonepose[i][k] = m[k];
}
}
else
{
// vertex weighted skeletal
// interpolate matrices and concatenate them to their parents
for (i = startingbone;i < bonecount;i++)
{
for (k = 0;k < 12;k++)
m[k] = 0;
for (b = 0;b < poses;b++)
{
matrix = pose[b] + i*12;
for (k = 0;k < 12;k++)
m[k] += matrix[k] * plerp[b];
}
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)bonepose[bones[i].parent], (void*)m, (void*)bonepose[i]);
else
for (k = 0;k < 12;k++) //parentless
bonepose[i][k] = m[k];
}
}
}
static void R_TransformVerticies(float bonepose[MAX_BONES][12], galisskeletaltransforms_t *weights, int numweights, float *xyzout)
{
int i;
float *out, *matrix;
galisskeletaltransforms_t *v = weights;
for (i = 0;i < numweights;i++, v++)
{
out = xyzout + v->vertexindex * 3;
matrix = bonepose[v->boneindex];
// FIXME: this can very easily be optimized with SSE or 3DNow
out[0] += v->org[0] * matrix[0] + v->org[1] * matrix[1] + v->org[2] * matrix[ 2] + v->org[3] * matrix[ 3];
out[1] += v->org[0] * matrix[4] + v->org[1] * matrix[5] + v->org[2] * matrix[ 6] + v->org[3] * matrix[ 7];
out[2] += v->org[0] * matrix[8] + v->org[1] * matrix[9] + v->org[2] * matrix[10] + v->org[3] * matrix[11];
}
}
static int R_BuildSkeletonLerps(float plerp[4], float *pose[4], int numbones, galiasgroup_t *g1, galiasgroup_t *g2, float lerpfrac, float fg1time, float fg2time)
{
int frame1;
int frame2;
float mlerp; //minor lerp, poses within a group.
int l = 0;
mlerp = (fg1time)*g1->rate;
frame1=mlerp;
frame2=frame1+1;
mlerp-=frame1;
if (g1->loop)
{
frame1=frame1%g1->numposes;
frame2=frame2%g1->numposes;
}
else
{
frame1=(frame1>g1->numposes-1)?g1->numposes-1:frame1;
frame2=(frame2>g1->numposes-1)?g1->numposes-1:frame2;
}
plerp[l] = (1-mlerp)*(1-lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*numbones*12*frame1);
plerp[l] = (mlerp)*(1-lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g1 + g1->poseofs + sizeof(float)*numbones*12*frame2);
if (lerpfrac)
{
mlerp = (fg2time)*g2->rate;
frame1=mlerp;
frame2=frame1+1;
mlerp-=frame1;
if (g2->loop)
{
frame1=frame1%g2->numposes;
frame2=frame2%g2->numposes;
}
else
{
frame1=(frame1>g2->numposes-1)?g2->numposes-1:frame1;
frame2=(frame2>g2->numposes-1)?g2->numposes-1:frame2;
}
plerp[l] = (1-mlerp)*(lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*numbones*12*frame1);
plerp[l] = (mlerp)*(lerpfrac);
if (plerp[l]>0)
pose[l++] = (float *)((char *)g2 + g2->poseofs + sizeof(float)*numbones*12*frame2);
}
return l;
}
//writes into bonepose
static void R_BuildSkeleton(galiasinfo_t *inf, entity_t *e, float bonepose[MAX_BONES][12])
{
int i, k;
int l=0;
float plerp[4];
float *pose[4];
float baseplerp[4];
float *basepose[4];
qboolean hirachy;
int numposes, basenumposes;
int basebone = e->basebone;
int frame1 = e->frame1;
int frame2 = e->frame2;
float lerpfrac = e->lerpfrac;
float baselerpfrac = e->baselerpfrac;
galiasgroup_t *g1, *g2, *bg1, *bg2;
galiasbone_t *bones = (galiasbone_t *)((char*)inf+inf->ofsbones);
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
if (basebone < 0)
basebone = 0;
if (basebone > inf->numbones)
basebone = inf->numbones;
if (basebone)
{
bg1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*e->baseframe1);
bg2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*e->baseframe2);
if (!bg1->isheirachical || !g1->isheirachical)
{
//mixing not supported
basebone = 0;
bg1 = g1;
bg2 = g2;
}
}
else
{
bg1 = g1;
bg2 = g2;
}
if (g1->isheirachical != g2->isheirachical || lerpfrac < 0)
lerpfrac = 0;
hirachy = g1->isheirachical;
numposes = R_BuildSkeletonLerps(plerp, pose, inf->numbones, g1, g2, lerpfrac, e->frame1time, e->frame2time);
if (hirachy)
{
if (basebone)
{
basenumposes = R_BuildSkeletonLerps(baseplerp, basepose, inf->numbones, bg1, bg2, baselerpfrac, e->baseframe1time, e->baseframe2time);
R_LerpBones(baseplerp, basepose, basenumposes, bones, 0, basebone, bonepose);
}
R_LerpBones(plerp, pose, numposes, bones, basebone, inf->numbones, bonepose);
}
else
{
//this is not hierachal, using base frames is not a good idea.
//just blend the poses here
if (numposes == 1)
memcpy(bonepose, pose[0], sizeof(float)*12*inf->numbones);
else if (numposes == 2)
{
for (i = 0; i < inf->numbones*12; i++)
{
((float*)bonepose)[i] = pose[0][i]*plerp[0] + pose[1][i]*plerp[1];
}
}
else
{
for (i = 0; i < inf->numbones; i++)
{
for (l = 0; l < 12; l++)
bonepose[i][l] = 0;
for (k = 0; k < numposes; k++)
{
for (l = 0; l < 12; l++)
bonepose[i][l] += pose[k][i*12+l] * plerp[k];
}
}
}
}
}
#ifndef SERVERONLY
static void R_BuildSkeletalMesh(mesh_t *mesh, float bonepose[MAX_BONES][12], galisskeletaltransforms_t *weights, int numweights)
static void Alias_BuildSkeletalMesh(mesh_t *mesh, float *bonepose, galisskeletaltransforms_t *weights, int numweights)
{
int i;
@ -629,7 +357,7 @@ static void R_BuildSkeletalMesh(mesh_t *mesh, float bonepose[MAX_BONES][12], gal
mesh->colors_array = NULL;
memset(mesh->xyz_array, 0, mesh->numvertexes*sizeof(vec3_t));
R_TransformVerticies(bonepose, weights, numweights, (float*)mesh->xyz_array);
Alias_TransformVerticies(bonepose, weights, numweights, (float*)mesh->xyz_array);
@ -840,42 +568,17 @@ static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf,
{
galiasgroup_t *g1, *g2;
int frame1 = e->frame1;
int frame2 = e->frame2;
float lerp = e->lerpfrac;
float fg1time = e->frame1time;
float fg2time = e->frame2time;
int frame1;
int frame2;
float lerp;
float fg1time;
float fg2time;
if (!inf->groups)
{
Con_DPrintf("Model with no frames (%s)\n", currententity->model->name);
return false;
}
if (frame1 < 0)
{
Con_DPrintf("Negative frame (%s)\n", currententity->model->name);
frame1 = 0;
}
if (frame2 < 0)
{
Con_DPrintf("Negative frame (%s)\n", currententity->model->name);
frame2 = frame1;
}
if (frame1 >= inf->groups)
{
Con_DPrintf("Too high frame %i (%s)\n", frame1, currententity->model->name);
frame1 %= inf->groups;
}
if (frame2 >= inf->groups)
{
Con_DPrintf("Too high frame %i (%s)\n", frame2, currententity->model->name);
frame2 = frame1;
}
if (lerp <= 0)
frame2 = frame1;
else if (lerp >= 1)
frame1 = frame2;
if (numTempColours < inf->numverts)
{
@ -915,9 +618,6 @@ static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf,
#endif
mesh->xyz_array = tempVertexCoords;
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
//we don't support meshes with one pose skeletal and annother not.
//we don't support meshes with one group skeletal and annother not.
@ -925,12 +625,48 @@ static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf,
if (inf->numbones)
{
float bonepose[MAX_BONES][12];
R_BuildSkeleton(inf, e, bonepose);
R_BuildSkeletalMesh(mesh, bonepose, (galisskeletaltransforms_t *)((char*)inf+inf->ofstransforms), inf->numtransforms);
float *usebonepose;
usebonepose = Alias_GetBonePositions(inf, &e->framestate, (float*)bonepose, MAX_BONES);
Alias_BuildSkeletalMesh(mesh, usebonepose, (galisskeletaltransforms_t *)((char*)inf+inf->ofstransforms), inf->numtransforms);
return false;
}
#endif
frame1 = e->framestate.g[FS_REG].frame[0];
frame2 = e->framestate.g[FS_REG].frame[1];
lerp = e->framestate.g[FS_REG].lerpfrac;
fg1time = e->framestate.g[FS_REG].frametime[0];
fg2time = e->framestate.g[FS_REG].frametime[1];
if (frame1 < 0)
{
Con_DPrintf("Negative frame (%s)\n", currententity->model->name);
frame1 = 0;
}
if (frame2 < 0)
{
Con_DPrintf("Negative frame (%s)\n", currententity->model->name);
frame2 = frame1;
}
if (frame1 >= inf->groups)
{
Con_DPrintf("Too high frame %i (%s)\n", frame1, currententity->model->name);
frame1 %= inf->groups;
}
if (frame2 >= inf->groups)
{
Con_DPrintf("Too high frame %i (%s)\n", frame2, currententity->model->name);
frame2 = frame1;
}
if (lerp <= 0)
frame2 = frame1;
else if (lerp >= 1)
frame1 = frame2;
g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1);
g2 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame2);
if (g1 == g2) //lerping within group is only done if not changing group
{
lerp = fg1time*g1->rate;
@ -2851,5 +2587,4 @@ void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris,
}
#endif
#endif // defined(RGLQUAKE) || defined(SERVERONLY)
#endif // defined(RGLQUAKE)

View File

@ -2041,6 +2041,9 @@ void R_RenderMeshProgram ( meshbuffer_t *mb, shaderpass_t *pass )
{
switch(s->progparm[i].type)
{
case SP_EYEPOS:
qglUniform3fvARB(s->progparm[i].handle, 1, r_origin);
break;
case SP_TIME:
qglUniform1fARB(s->progparm[i].handle, r_localShaderTime);
break;

View File

@ -4187,6 +4187,45 @@ int GL_LoadTexture32 (char *identifier, int width, int height, unsigned *data, q
return texture_extension_number-1;
}
int GL_LoadTexture32_BGRA (char *identifier, int width, int height, unsigned *data, qboolean mipmap, qboolean alpha)
{
// qboolean noalpha;
// int p, s;
gltexture_t *glt;
// see if the texture is already present
if (identifier[0])
{
glt = GL_MatchTexture(identifier, 32, width, height);
if (glt)
return glt->texnum;
}
glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t));
glt->next = gltextures;
gltextures = glt;
strcpy (glt->identifier, identifier);
glt->texnum = texture_extension_number;
glt->width = width;
glt->height = height;
glt->bpp = 32;
glt->mipmap = mipmap;
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
// if (!isDedicated)
{
GL_Bind(texture_extension_number );
GL_Upload32_BGRA (identifier, data, width, height, mipmap, alpha);
}
texture_extension_number++;
return texture_extension_number-1;
}
int GL_LoadCompressed(char *name)
{
qbyte *COM_LoadFile (char *path, int usehunk);

View File

@ -62,11 +62,11 @@ void QuaternionGLAngle(const vec3_t angles, vec4_t quaternion)
quaternion[3] = cosr * cosp * cosy + sinr * sinp * siny;
}
#define MAX_BONES 128
matrix3x4 transform_matrix[128]; /* Vertex transformation matrix */
matrix3x4 transform_matrix[MAX_BONES]; /* Vertex transformation matrix */
void GL_Draw_HL_AliasFrame(short *order, vec3_t *transformed, float tex_w, float tex_h);
@ -139,6 +139,12 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer)
Hunk_FreeToLowMark(start);
return false;
}
if (header->numbones > MAX_BONES)
{
Con_Printf(CON_ERROR "Cannot load model %s - too many bones %i\n", mod->name, header->numbones);
Hunk_FreeToLowMark(start);
return false;
}
tex = (hlmdl_tex_t *) ((qbyte *) header + header->textures);
bones = (hlmdl_bone_t *) ((qbyte *) header + header->boneindex);
@ -474,6 +480,7 @@ void R_DrawHLModel(entity_t *curent)
hlmodel_t model;
int b, m, v;
short *skins;
int bgroup, cbone, lastbone;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//general model
@ -485,7 +492,7 @@ void R_DrawHLModel(entity_t *curent)
skins = (short *) ((qbyte *) model.header + model.header->skins);
for (b = 0; b < MAX_BONE_CONTROLLERS; b++)
model.controller[b] = curent->bonecontrols[b];
model.controller[b] = curent->framestate.bonecontrols[b];
GL_TexEnv(GL_MODULATE);
@ -511,8 +518,16 @@ void R_DrawHLModel(entity_t *curent)
R_RotateForEntity (curent);
HL_SetupBones(&model, curent->baseframe1, 0, curent->basebone, (curent->basesubblendfrac+1)*0.5); /* Setup the bones */
HL_SetupBones(&model, curent->frame1, curent->basebone, model.header->numbones, (curent->subblendfrac+1)*0.5); /* Setup the bones */
cbone = 0;
for (bgroup = 0; bgroup < FS_COUNT; bgroup++)
{
lastbone = curent->framestate.g[bgroup].endbone;
if (bgroup == FS_COUNT)
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); /* Setup the bones */
}
/* Manipulate each mesh directly */
for(b = 0; b < model.header->numbodyparts; b++)

View File

@ -35,9 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "d3dquake.h"
#endif
#ifdef Q3SHADERS
#include "shader.h"
#endif
#include "com_mesh.h"
extern cvar_t r_shadow_bumpscale_basetexture;
extern cvar_t r_replacemodels;
@ -55,7 +53,6 @@ extern char loadname[32]; // for hunk tags
void CM_Init(void);
qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer);
qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer);
qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer);
qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer);
@ -64,27 +61,12 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer);
qboolean Mod_LoadQ2BrushModel (model_t *mod, void *buffer);
#endif
qboolean Mod_LoadHLModel (model_t *mod, void *buffer);
#ifdef ZYMOTICMODELS
qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer);
qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer);
#endif
#ifdef MD5MODELS
qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer);
#endif
model_t *GLMod_LoadModel (model_t *mod, qboolean crash);
#ifdef DOOMWADS
qboolean Mod_LoadDoomLevel(model_t *mod);
#endif
qboolean Mod_LoadQ1Model (model_t *mod, void *buffer);
#ifdef MD2MODELS
qboolean Mod_LoadQ2Model (model_t *mod, void *buffer);
#endif
#ifdef MD3MODELS
qboolean Mod_LoadQ3Model (model_t *mod, void *buffer);
#endif
#ifdef DOOMWADS
void GLMod_LoadDoomSprite (model_t *mod);
#endif
@ -538,6 +520,7 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash)
//
// fill it in
//
Mod_DoCRC(mod, (char*)buf, com_filesize);
switch (LittleLong(*(unsigned *)buf))
{
@ -1910,8 +1893,14 @@ qboolean GLMod_LoadFaces (lump_t *l)
continue;
}
/*if (*out->texinfo->texture->name == '~')
{
out->texinfo->flags |= SURF_BLENDED;
continue;
}*/
if (!Q_strncmp(out->texinfo->texture->name,"{",1)) // alpha
{
out->texinfo->flags |= SURF_ALPHATEST;
out->flags |= (SURF_DRAWALPHA);
continue;
}

View File

@ -6,6 +6,7 @@
#ifdef RGLQUAKE
#include "glquake.h"
#include "shader.h"
#include "renderque.h"
#define qglGetError() 0
@ -384,8 +385,17 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
if (tex->alphaed || currententity->shaderRGBAf[3]<1)
{
qglEnable(GL_BLEND);
GL_TexEnv(GL_MODULATE);
if (*tex->name == '{')
{
qglEnable(GL_ALPHA_TEST);
qglDisable(GL_BLEND);
GL_TexEnv(GL_REPLACE);
}
else
{
qglEnable(GL_BLEND);
GL_TexEnv(GL_MODULATE);
}
}
else
{
@ -403,6 +413,12 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
GL_TexEnv(GL_MODULATE);
/* if (currententity->shaderRGBAf[3]<1)
{
s->lightmaptexturenum = -1;
qglBlendFunc(GL_SRC_COLOR, GL_ONE);
}
*/
if (overbright != 1)
{
GL_TexEnv(GL_COMBINE_ARB);
@ -466,6 +482,9 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
GL_SelectTexture(GL_TEXTURE0_ARB);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (tex->alphaed)
qglDisable(GL_ALPHA_TEST);
}
/*
@ -1910,7 +1929,7 @@ void PPL_BaseBModelTextures(entity_t *e)
for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++)
{
if (s->texinfo->flags & SURF_TRANS33 || s->texinfo->flags & SURF_TRANS66)
if (s->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
{
s->ownerent = currententity;
s->nextalphasurface = r_alpha_surfaces;
@ -2116,7 +2135,7 @@ void R_DrawBeam( entity_t *e )
scale = e->scale;
if (!scale)
scale = e->frame1;
scale = e->framestate.g[FS_REG].frame[0];
if (!scale)
scale = 6;
VectorScale( perpvec, scale / 2, perpvec );
@ -2224,6 +2243,19 @@ void PPL_DrawEnt(entity_t *e, void *parm)
qglBegin(GL_QUADS);
}
void PPL_DelayBaseBModelTextures(int count, void **e, void *parm)
{
while(count--)
{
currententity = *e++;
qglDepthFunc ( gldepthfunc );
qglEnable(GL_DEPTH_TEST);
qglDepthMask(1);
PPL_BaseBModelTextures (currententity);
}
}
void PPL_BaseEntTextures(void)
{
extern model_t *currentmodel;
@ -2280,10 +2312,15 @@ void PPL_BaseEntTextures(void)
break;
case mod_brush:
qglDepthFunc ( gldepthfunc );
qglEnable(GL_DEPTH_TEST);
qglDepthMask(1);
PPL_BaseBModelTextures (currententity);
if (currententity->shaderRGBAf[3] < 1)
RQ_AddDistReorder(PPL_DelayBaseBModelTextures, currententity, NULL, currententity->origin);
else
{
qglDepthFunc ( gldepthfunc );
qglEnable(GL_DEPTH_TEST);
qglDepthMask(1);
PPL_BaseBModelTextures (currententity);
}
break;
default:
@ -4645,8 +4682,6 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
}
#endif
void CL_NewDlight (int key, float x, float y, float z, float radius, float time,
int type);
//generates stencil shadows of the world geometry.
//redraws world geometry
qboolean PPL_AddLight(dlight_t *dl)

View File

@ -665,17 +665,15 @@ void R_DrawSpriteModel (entity_t *e)
//==================================================================================
void GLR_DrawSprite(void *e, void *parm)
void GLR_DrawSprite(int count, void **e, void *parm)
{
qglEnd();
currententity = e;
qglEnable(GL_TEXTURE_2D);
while(count--)
{
currententity = *e++;
qglEnable(GL_TEXTURE_2D);
R_DrawSpriteModel (currententity);
P_FlushRenderer();
qglBegin(GL_QUADS);
R_DrawSpriteModel (currententity);
}
}
/*
=============

View File

@ -754,7 +754,7 @@ void GLR_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *
#endif
int stride = LMBLOCK_WIDTH*lightmap_bytes;
if (!surf->samples)
if (!surf->samples && currentmodel->lightdata)
return;
shift += 7; // increase to base value
@ -2171,7 +2171,7 @@ void GLR_DrawAlphaSurfaces (void)
qglEnable(GL_ALPHA_TEST);
qglDisable(GL_BLEND);
if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2))
// if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2))
{ //this is a mahoosive hack.
qglDepthMask(0); //this makes no difference to the cheating.
@ -2187,7 +2187,7 @@ void GLR_DrawAlphaSurfaces (void)
break;
}
s->flags |= 0x80000;
if (*s->texinfo->texture->name == '{')
if (s->texinfo->flags & SURF_ALPHATEST)
{ //simple alpha testing.
if (s->ownerent != currententity)
@ -2197,7 +2197,6 @@ void GLR_DrawAlphaSurfaces (void)
qglPushMatrix();
R_RotateForEntity(currententity);
}
Sys_Error("GLR_DrawAlphaSurfaces needs work");
/*
if (gl_mtexable)
{
@ -2230,9 +2229,9 @@ void GLR_DrawAlphaSurfaces (void)
else
*/
{
if (s->samples) //could do true vertex lighting... ?
qglColor4ub (*s->samples,*s->samples,*s->samples,255);
else
// if (s->samples) //could do true vertex lighting... ?
// qglColor4ub (*s->samples,*s->samples,*s->samples,255);
// else
qglColor4f (1,1,1,1);
DrawGLPoly (s->mesh);
qglColor4f (1,1,1,1);
@ -2289,7 +2288,6 @@ matrixInvert(GLfloat in[16], GLfloat out[16])
}
#endif
void VectorVectors(vec3_t forward, vec3_t right, vec3_t up);
/*
================
DrawTextureChains

View File

@ -603,7 +603,22 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
{
parmtype = SP_TIME;
}
else if (!Q_stricmp(token, "eyepos"))
{
parmtype = SP_EYEPOS;
}
else if (!Q_stricmp(token, "colours") || !Q_stricmp(token, "colors"))
{
parmtype = SP_ENTCOLOURS;
}
else if (!Q_stricmp(token, "upper"))
{
parmtype = SP_TOPCOLOURS;
}
else if (!Q_stricmp(token, "lower"))
{
parmtype = SP_BOTTOMCOLOURS;
}
if (!shader->programhandle)
{

View File

@ -192,10 +192,12 @@ typedef struct
typedef struct {
enum shaderprogparmtype_e {
SP_BAD,
SP_ENTCOLOURS,
SP_TOPCOLOURS,
SP_BOTTOMCOLOURS,
SP_TIME,
SP_EYEPOS,
//things that are set immediatly
SP_FIRSTIMMEDIATE, //never set

View File

@ -424,7 +424,16 @@ reeval:
//get a pointer to a field var
case OP_ADDRESS:
if ((unsigned)OPA->edict >= (unsigned)maxedicts)
{
#ifndef DEBUGABLE
pr_trace++;
printf("OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
st--;
goto cont;
#else
PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
#endif
}
ed = PROG_TO_EDICT(progfuncs, OPA->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
@ -432,7 +441,15 @@ reeval:
if (!ed || ed->readonly)
{
pr_xstatement = st-pr_statements;
#ifndef DEBUGABLE
//boot it over to the debugger
pr_trace++;
printf("assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
st--;
goto cont;
#else
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
#endif
}
//Whilst the next block would technically be correct, we don't use it as it breaks too many quake mods.

View File

@ -411,23 +411,35 @@ char *PR_StringToNative (progfuncs_t *progfuncs, string_t str)
{
int i = str & ~0x80000000;
if (i >= prinst->numallocedstrings)
{
pr_trace = 1;
return "";
}
if (prinst->allocedstrings[i])
return prinst->allocedstrings[i];
else
{
pr_trace = 1;
return ""; //urm, was freed...
}
}
if ((unsigned int)str & 0x40000000)
{
int i = str & ~0x40000000;
if (i >= prinst->numtempstrings)
{
pr_trace = 1;
return "";
}
return prinst->tempstrings[i];
}
}
if (str >= progfuncs->stringtablesize)
{
pr_trace = 1;
return "";
}
return progfuncs->stringtable + str;
}

View File

@ -3049,11 +3049,16 @@ retry:
{
d16 = ED_FindGlobal16(progfuncs, s);
if (!d16)
Sys_Error("Progs requires \"%s\" the external function \"%s\", but the definition was stripped", filename, s);
{
printf("Progs requires \"%s\" the external function \"%s\", but the definition was stripped", filename, s);
PRHunkFree(progfuncs, hmark);
pr_progs=NULL;
return false;
}
((int *)glob)[d16->ofs] = PR_FindFunc(progfuncs, s, PR_ANY);
if (!((int *)glob)[d16->ofs])
Sys_Error("Runtime-linked function %s was not found in primary progs (loading %s)", s, filename);
printf("Warning: Runtime-linked function %s was not found in primary progs (loading %s)", s, filename);
/*
d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
if (!d2)
@ -3075,9 +3080,14 @@ retry:
d32 = ED_FindGlobal32(progfuncs, s);
d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
if (!d2)
Sys_Error("Runtime-linked function %s was not found in existing progs", s);
printf("Warning: Runtime-linked function %s was not found in existing progs", s);
if (!d32)
Sys_Error("Couldn't find def for \"%s\"", s);
{
printf("Couldn't find def for \"%s\"", s);
PRHunkFree(progfuncs, hmark);
pr_progs=NULL;
return false;
}
((int *)glob)[d32->ofs] = (*(func_t *)&pr_progstate[0].globals[*d2]);
s+=strlen(s)+1;

View File

@ -793,16 +793,37 @@ void PR_Compile_f(void)
double time = Sys_DoubleTime();
char *argv[64] = {"", "-src", "src", "-srcfile", "qwprogs.src"};
if (Cmd_Argc() == 2)
{
argv[4] = Cmd_Argv(1);
argc = 5;
}
else if (Cmd_Argc()>2)
if (Cmd_Argc()>2)
{
for (argc = 0; argc < Cmd_Argc(); argc++)
argv[argc] = Cmd_Argv(argc);
}
else
{
//override the source name
if (Cmd_Argc() == 2)
{
argv[4] = Cmd_Argv(1);
argc = 5;
}
if (!FS_FLocateFile(va("%s/%s", argv[2], argv[4]), FSLFRT_IFFOUND, NULL))
{
//try the qc path
argv[2] = "qc";
}
if (!FS_FLocateFile(va("%s/%s", argv[2], argv[4]), FSLFRT_IFFOUND, NULL))
{
//try the progs path (yeah... gah)
argv[2] = "progs";
}
if (!FS_FLocateFile(va("%s/%s", argv[2], argv[4]), FSLFRT_IFFOUND, NULL))
{
//try the gamedir path
argv[1] = argv[3];
argv[2] = argv[4];
argc -= 2;
}
}
if (!svprogfuncs)
Q_SetProgsParms(true);
@ -8224,6 +8245,7 @@ static void EdictToTransform(edict_t *ed, float *trans)
// #452 vector(entity ent, float tagindex) gettaginfo (DP_MD3_TAGSINFO)
void PF_sv_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
framestate_t fstate;
float transtag[12];
float transent[12];
float result[12];
@ -8240,7 +8262,10 @@ void PF_sv_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (!model)
model = Mod_FindName(sv.strings.model_precache[(int)ent->v->modelindex]);
if (!Mod_GetTag(model, tagnum, ent->v->frame, ent->v->frame, 0, 0, 0, transtag))
memset(&fstate, 0, sizeof(fstate));
fstate.g[FS_REG].frame[0] = fstate.g[FS_REG].frame[0] = ent->v->frame;
if (!Mod_GetTag(model, tagnum, &fstate, transtag))
{
return;
}

View File

@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "d_local.h"
vec3_t r_pright, r_pup, r_ppn;
//Spike: Particles are depth sorted. So why depth write? They are the last to be drawn anyway.
#define PARTICLEFACTOR 0x8000 // Change DP_Partfac in ASM to match this

View File

@ -179,7 +179,7 @@ void MakeVideoPalette(void)
// pal555to8 = Hunk_AllocName(PAL555_SIZE, "RGB data");
// load in previously created table
if ((f = FS_OpenVFS("pal555.pal", "rb", FS_BASE)))
if ((f = FS_OpenVFS("pal555.pal", "rb", FS_GAME)))
{
VFS_READ(f, pal555to8, PAL555_SIZE);
VFS_CLOSE(f);

View File

@ -124,7 +124,7 @@ qboolean R_AliasCheckBBox (void)
R_AliasSetUpTransform (0);
// construct the base bounding box for this frame
nframe = currententity->frame1;
nframe = currententity->framestate.g[FS_REG].frame[0];
// TODO: don't repeat this check when drawing?
if ((nframe >= pmdl->numframes) || (nframe < 0))
{
@ -134,7 +134,7 @@ qboolean R_AliasCheckBBox (void)
}
// construct the base bounding box for this frame
oframe = currententity->frame2;
oframe = currententity->framestate.g[FS_REG].frame[1];
// TODO: don't repeat this check when drawing?
if ((oframe >= pmdl->numframes) || (oframe < 0))
{
@ -771,20 +771,20 @@ void R_AliasSetupFrame (void)
// vec3_t max1, max2;
float fl, bl;
frame = currententity->frame1;
frame = currententity->framestate.g[FS_REG].frame[0];
if ((frame >= pmdl->numframes) || (frame < 0))
{
Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
frame = 0;
}
oframe = currententity->frame2;
oframe = currententity->framestate.g[FS_REG].frame[1];
if ((oframe >= pmdl->numframes) || (oframe < 0))
{
// Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", oframe); //pointless
oframe = 0;
}
bl = currententity->lerpfrac;
bl = currententity->framestate.g[FS_REG].lerpfrac;
if (bl < 0)
bl = 0;
else if (bl > 1)
@ -811,7 +811,7 @@ void R_AliasSetupFrame (void)
numframes = paliasgroup->numframes;
fullinterval = pintervals[numframes-1];
time = currententity->frame1time;
time = currententity->framestate.g[FS_REG].frametime[0];
//
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values
@ -842,7 +842,7 @@ void R_AliasSetupFrame (void)
numframes = paliasgroup->numframes;
fullinterval = pintervals[numframes-1];
time = currententity->frame1time;
time = currententity->framestate.g[FS_REG].frametime[1];
//
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values

View File

@ -641,7 +641,7 @@ void R_RenderFace (msurface_t *fa, int clipflags)
medge_t *pedges, tedge;
clipplane_t *pclip;
if (fa->texinfo->texture && (*fa->texinfo->texture->name == '{' || fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)))
if (fa->texinfo->texture && (fa->texinfo->flags & (SURF_ALPHATEST|SURF_TRANS33|SURF_TRANS66)))
{
if (fa->nextalphasurface)
return;
@ -873,7 +873,7 @@ void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
return;
}
if (*psurf->texinfo->texture->name == '{' || psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66|SURF_ALPHATEST))
{
if (psurf->nextalphasurface)
return;

View File

@ -1030,7 +1030,7 @@ texture_t *SWR_TextureAnimation (texture_t *base)
int reletive;
int count;
if (currententity->frame1)
if (currententity->framestate.g[FS_REG].frame[0])
{
if (base->alternate_anims)
base = base->alternate_anims;

View File

@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "r_local.h"
#include "com_mesh.h"
model_t *loadmodel;
char loadname[32]; // for hunk tags
@ -388,6 +390,7 @@ model_t *SWMod_LoadModel (model_t *mod, qboolean crash)
//
// fill it in
//
Mod_DoCRC(mod, (char*)buf, com_filesize);
switch (LittleLong(*(unsigned *)buf))
{
@ -1256,9 +1259,9 @@ qboolean SWMod_LoadTexinfo (lump_t *l)
{
out->flags |= SURF_TRANS66;
}
else if (*out->texture->name == '{') //halflife levels
else if (*out->texture->name == '~') //halflife levels
{
// out->flags |= SURF_TRANS66;
out->flags |= SURF_ALPHATEST;
}
else if (*out->texture->name == '!') //halflife levels
{
@ -2457,30 +2460,6 @@ qboolean SWMod_LoadAliasModel (model_t *mod, void *buffer)
int skinsize;
int start, end, total;
qboolean qtest = false;
if (loadmodel->engineflags & MDLF_DOCRC)
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
QCRC_Init(&crc);
for (len = com_filesize, p = buffer; len; len--, p++)
QCRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
(int)crc);
}
}
start = Hunk_LowMark ();
@ -2794,31 +2773,6 @@ qboolean SWMod_LoadAlias2Model (model_t *mod, void *buffer)
vec3_t mins, maxs;
if (loadmodel->engineflags & MDLF_DOCRC)
{
unsigned short crc;
qbyte *p;
int len;
char st[40];
QCRC_Init(&crc);
for (len = com_filesize, p = buffer; len; len--, p++)
QCRC_ProcessByte(&crc, *p);
sprintf(st, "%d", (int) crc);
Info_SetValueForKey (cls.userinfo,
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
st, MAX_INFO_STRING);
if (cls.state >= ca_connected)
{
CL_SendClientCommand(true, "setinfo %s %d",
(loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name,
(int)crc);
}
}
start = Hunk_LowMark ();
pinmodel = (md2_t *)buffer;