diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 4bc04efe..ff298ff2 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -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++) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 6424fff6..0d95f161 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -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 diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 7ef10db6..7fb4333e 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -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) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index d1096c6f..bd152b73 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -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 diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index e7f120ea..be1565bb 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -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; } diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index ccd880d0..e9681aa4 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -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; diff --git a/engine/client/client.h b/engine/client/client.h index 730e7389..a03a688f 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -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); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index b25ab55c..0e5accc2 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -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); } diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index b0aa927e..9b2f0ac2 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -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 diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 18621407..f33a6401 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -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) { diff --git a/engine/client/merged.h b/engine/client/merged.h index 9a0a7db7..722efbd8 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -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); diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 054d98a8..c5888744 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -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; diff --git a/engine/client/p_classic.c b/engine/client/p_classic.c index 15bd5d3d..7ed1fae5 100644 --- a/engine/client/p_classic.c +++ b/engine/client/p_classic.c @@ -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 } diff --git a/engine/client/p_null.c b/engine/client/p_null.c index dda44398..adc8fb31 100644 --- a/engine/client/p_null.c +++ b/engine/client/p_null.c @@ -47,9 +47,7 @@ static void PNULL_DrawParticles(void) RSpeedRemark(); #ifdef GLQUAKE - qglBegin(GL_QUADS); RQ_RenderDistAndClear(); - qglEnd(); #endif RSpeedEnd(RSPEED_PARTICLESDRAW); } diff --git a/engine/client/p_script.c b/engine/client/p_script.c index b4d3776c..fb517c13 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -118,6 +118,21 @@ typedef struct skytris_s { struct msurface_s *face; } skytris_t; +//these are the details of each particle which are exposed at render time - things that are static +typedef struct { + enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type; + + blendmode_t blendmode; + + int texturenum; +#ifdef D3DQUAKE + void *d3dtexture; +#endif + + float scalefactor; + float invscalefactor; +} plooks_t; + //these could be deltas or absolutes depending on ramping mode. typedef struct { vec3_t rgb; @@ -130,14 +145,15 @@ typedef struct part_type_s { char name[MAX_QPATH]; char texname[MAX_QPATH]; vec3_t rgb; + float alpha; vec3_t rgbchange; + float alphachange; vec3_t rgbrand; int colorindex; int colorrand; float rgbchangetime; vec3_t rgbrandsync; - float scale, alpha; - float alphachange; + float scale; float die, randdie; float randomvel, veladd; float orgadd; @@ -146,22 +162,18 @@ typedef struct part_type_s { float randomvelvert; float randscale; + plooks_t looks; + float spawntime; float spawnchance; - enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type; - blendmode_t blendmode; - float rotationstartmin, rotationstartrand; float rotationmin, rotationrand; float scaledelta; float count; float countrand; - int texturenum; -#ifdef D3DQUAKE - void *d3dtexture; -#endif + int assoc; int cliptype; int inwater; @@ -173,8 +185,6 @@ typedef struct part_type_s { float areaspread; float areaspreadvert; - float scalefactor; - float invscalefactor; float spawnparam1; float spawnparam2; @@ -225,7 +235,7 @@ typedef struct part_type_s { #define PS_INRUNLIST 0x1 // particle type is currently in execution list } part_type_t; -void PScript_DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type_t*), void (*sparklineparticles)(particle_t*,part_type_t*), void (*sparkfanparticles)(particle_t*,part_type_t*), void (*sparktexturedparticles)(particle_t*,part_type_t*), void (*beamparticlest)(beamseg_t*,part_type_t*), void (*beamparticlesut)(beamseg_t*,part_type_t*), void (*drawdecalparticles)(clippeddecal_t*,part_type_t*)); +void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticlest)(int count, beamseg_t**,plooks_t*), void (*beamparticlesut)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*)); #ifndef TYPESONLY @@ -266,8 +276,6 @@ trailstate_t *trailstates; int ts_cycle; // current cyclic index of trailstates int r_numtrailstates; -vec3_t r_pright, r_pup, r_ppn; - extern cvar_t r_bouncysparks; extern cvar_t r_part_rain; extern cvar_t r_bloodstains; @@ -458,42 +466,42 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) case QR_OPENGL: if (*ptype->texname && strcmp(ptype->texname, "default")) { - ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); + ptype->looks.texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); - if (!ptype->texturenum) + if (!ptype->looks.texturenum) { if (warn) Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball")) - ptype->texturenum = balltexture; + ptype->looks.texturenum = balltexture; else - ptype->texturenum = explosiontexture; + ptype->looks.texturenum = explosiontexture; } } else - ptype->texturenum = explosiontexture; + ptype->looks.texturenum = explosiontexture; break; #endif #ifdef D3DQUAKE case QR_DIRECT3D: if (*ptype->texname && strcmp(ptype->texname, "default")) { - ptype->d3dtexture = NULL;//Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); + ptype->looks.d3dtexture = NULL;//Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); - if (!ptype->d3dtexture) + if (!ptype->looks.d3dtexture) { if (warn) Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball")) - ptype->d3dtexture = d3dballtexture; + ptype->looks.d3dtexture = d3dballtexture; else - ptype->d3dtexture = d3dexplosiontexture; + ptype->looks.d3dtexture = d3dexplosiontexture; } } else - ptype->d3dtexture = d3dexplosiontexture; + ptype->looks.d3dtexture = d3dexplosiontexture; break; #endif default: @@ -658,7 +666,7 @@ static void P_ParticleEffect_f(void) ptype->randscale = atof(value); else if (!strcmp(var, "scalefactor")) - ptype->scalefactor = atof(value); + ptype->looks.scalefactor = atof(value); else if (!strcmp(var, "scaledelta")) ptype->scaledelta = atof(value); @@ -834,13 +842,13 @@ static void P_ParticleEffect_f(void) else if (!strcmp(var, "blend")) { if (!strcmp(value, "add")) - ptype->blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADD; else if (!strcmp(value, "subtract")) - ptype->blendmode = BM_SUBTRACT; + ptype->looks.blendmode = BM_SUBTRACT; else if (!strcmp(value, "blendcolour") || !strcmp(value, "blendcolor")) - ptype->blendmode = BM_BLENDCOLOUR; + ptype->looks.blendmode = BM_BLENDCOLOUR; else - ptype->blendmode = BM_BLEND; + ptype->looks.blendmode = BM_BLEND; } else if (!strcmp(var, "spawnmode")) { @@ -875,23 +883,23 @@ static void P_ParticleEffect_f(void) else if (!strcmp(var, "type")) { if (!strcmp(value, "beam")) - ptype->type = PT_BEAM; + ptype->looks.type = PT_BEAM; else if (!strcmp(value, "spark")) - ptype->type = PT_SPARK; + ptype->looks.type = PT_SPARK; else if (!strcmp(value, "sparkfan") || !strcmp(value, "trianglefan")) - ptype->type = PT_SPARKFAN; + ptype->looks.type = PT_SPARKFAN; else if (!strcmp(value, "texturedspark")) - ptype->type = PT_TEXTUREDSPARK; + ptype->looks.type = PT_TEXTUREDSPARK; else if (!strcmp(value, "decal")) - ptype->type = PT_DECAL; + ptype->looks.type = PT_DECAL; else - ptype->type = PT_NORMAL; + ptype->looks.type = PT_NORMAL; settype = true; } else if (!strcmp(var, "isbeam")) { Con_DPrintf("isbeam is deprechiated, use type beam\n"); - ptype->type = PT_BEAM; + ptype->looks.type = PT_BEAM; } else if (!strcmp(var, "spawntime")) ptype->spawntime = atof(value); @@ -1071,7 +1079,7 @@ static void P_ParticleEffect_f(void) else Con_DPrintf("%s is not a recognised particle type field (in %s)\n", var, ptype->name); } - ptype->invscalefactor = 1-ptype->scalefactor; + ptype->looks.invscalefactor = 1-ptype->looks.scalefactor; ptype->loaded = 1; if (ptype->clipcount < 1) ptype->clipcount = 1; @@ -1085,18 +1093,18 @@ static void P_ParticleEffect_f(void) if (!settype) { - if (ptype->type == PT_NORMAL && !*ptype->texname) - ptype->type = PT_SPARK; - if (ptype->type == PT_SPARK) + if (ptype->looks.type == PT_NORMAL && !*ptype->texname) + ptype->looks.type = PT_SPARK; + if (ptype->looks.type == PT_SPARK) { if (*ptype->texname) - ptype->type = PT_TEXTUREDSPARK; + ptype->looks.type = PT_TEXTUREDSPARK; if (ptype->scale) - ptype->type = PT_SPARKFAN; + ptype->looks.type = PT_SPARKFAN; } } - if (ptype->type == PT_BEAM && !setbeamlen) + if (ptype->looks.type == PT_BEAM && !setbeamlen) ptype->rotationstartmin = 1/128.0; // use old behavior if not using alphadelta @@ -1889,7 +1897,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, else ts = NULL; - if (ptype->type == PT_DECAL) + if (ptype->looks.type == PT_DECAL) { clippeddecal_t *d; int decalcount; @@ -2025,7 +2033,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, { case SM_UNICIRCLE: m = pcount; - if (ptype->type == PT_BEAM) + if (ptype->looks.type == PT_BEAM) m--; if (m < 1) @@ -2091,7 +2099,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, if (!free_particles) break; p = free_particles; - if (ptype->type == PT_BEAM) + if (ptype->looks.type == PT_BEAM) { if (!free_beams) break; @@ -2319,7 +2327,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, } // update beam list - if (ptype->type == PT_BEAM) + if (ptype->looks.type == PT_BEAM) { if (b) { @@ -2770,7 +2778,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype } p = free_particles; - if (ptype->type == PT_BEAM) + if (ptype->looks.type == PT_BEAM) { if (!free_beams) { @@ -3009,7 +3017,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype ts->state1.lastdist = len; // update beamseg list - if (ptype->type == PT_BEAM) + if (ptype->looks.type == PT_BEAM) { if (b) { @@ -3045,7 +3053,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype } } } - else if (ptype->type == PT_BEAM) + else if (ptype->looks.type == PT_BEAM) { if (b) { @@ -3097,265 +3105,275 @@ static void PScript_ParticleTrailIndex (vec3_t start, vec3_t end, int color, int P_ParticleTrail(start, end, pe_defaulttrail, tsk); } - -static part_type_t *lastgltype; vec3_t pright, pup; static float pframetime; #ifdef RGLQUAKE -static void GL_DrawTexturedParticle(particle_t *p, part_type_t *type) +static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *type) { + particle_t *p; float x,y; float scale; - if (lastgltype != type) + + qglEnable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_FLAT); + qglBegin(GL_QUADS); + + + while (count--) { - if (!lastgltype || lastgltype->type != type->type || lastgltype->texturenum != type->texturenum || lastgltype->blendmode != type->blendmode) + p = *plist++; + + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); + if (scale < 20) + scale = 0.25; + else + scale = 0.25 + scale * 0.001; + + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + + if (p->angle) { - qglEnd(); - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_FLAT); - qglBegin(GL_QUADS); + x = sin(p->angle)*scale; + y = cos(p->angle)*scale; } - lastgltype = type; + else + { + x = 0; + y = scale; + } + qglTexCoord2f(0,0); + qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]); + qglTexCoord2f(0,1); + qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]); + qglTexCoord2f(1,1); + qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]); + qglTexCoord2f(1,0); + qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]); } - - scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] - + (p->org[2] - r_origin[2])*vpn[2]; - scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); - if (scale < 20) - scale = 0.25; - else - scale = 0.25 + scale * 0.001; - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - - if (p->angle) - { - x = sin(p->angle)*scale; - y = cos(p->angle)*scale; - } - else - { - x = 0; - y = scale; - } - qglTexCoord2f(0,0); - qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]); - qglTexCoord2f(0,1); - qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]); - qglTexCoord2f(1,1); - qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]); - qglTexCoord2f(1,0); - qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]); + qglEnd(); } -static void GL_DrawSketchParticle(particle_t *p, part_type_t *type) +static void GL_DrawSketchParticle(int count, particle_t **plist, plooks_t *type) { + particle_t *p; float x,y; float scale; int quant; - if (lastgltype != type) + qglDisable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); +// if (type->blendmode == BM_ADD) //addative +// glBlendFunc(GL_SRC_ALPHA, GL_ONE); +// else if (type->blendmode == BM_SUBTRACT) //subtractive +// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// else + qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglShadeModel(GL_SMOOTH); + qglBegin(GL_LINES); + + while (count--) { - lastgltype = type; - qglEnd(); - qglDisable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); -// if (type->blendmode == BM_ADD) //addative -// glBlendFunc(GL_SRC_ALPHA, GL_ONE); -// else if (type->blendmode == BM_SUBTRACT) //subtractive -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// else - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_LINES); + p = *plist++; + + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); + if (scale < 20) + scale = 0.25; + else + scale = 0.25 + scale * 0.001; + + qglColor4f (p->rgb[0]/2, + p->rgb[1]/2, + p->rgb[2]/2, + p->alpha*2); + + quant = scale; + + if (p->angle) + { + x = sin(p->angle)*scale; + y = cos(p->angle)*scale; + } + else + { + x = 0; + y = scale; + } + qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]); + qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]); + qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]); + qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]); } - - scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] - + (p->org[2] - r_origin[2])*vpn[2]; - scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); - if (scale < 20) - scale = 0.25; - else - scale = 0.25 + scale * 0.001; - - qglColor4f (p->rgb[0]/2, - p->rgb[1]/2, - p->rgb[2]/2, - p->alpha*2); - - quant = scale; - - if (p->angle) - { - x = sin(p->angle)*scale; - y = cos(p->angle)*scale; - } - else - { - x = 0; - y = scale; - } - qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]); - qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]); - qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]); - qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]); + qglEnd(); } -static void GL_DrawTrifanParticle(particle_t *p, part_type_t *type) +static void GL_DrawTrifanParticle(int count, particle_t **plist, plooks_t *type) { + particle_t *p; int i; vec3_t v; float scale; + qglDisable(GL_TEXTURE_2D); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + + while (count--) + { + p = *plist++; + + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); + if (scale < 20) + scale = 0.05; + else + scale = 0.05 + scale * 0.0001; + /* + if ((p->vel[0]*p->vel[0]+p->vel[1]*p->vel[1]+p->vel[2]*p->vel[2])*2*scale > 30*30) + scale = 1+1/30/Length(p->vel)*2;*/ + + qglBegin (GL_TRIANGLE_FAN); + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + qglVertex3fv (p->org); + qglColor4f (p->rgb[0]/2, + p->rgb[1]/2, + p->rgb[2]/2, + 0); + for (i=7 ; i>=0 ; i--) + { + v[0] = p->org[0] - p->vel[0]*scale + vright[0]*cost[i%7]*p->scale + vup[0]*sint[i%7]*p->scale; + v[1] = p->org[1] - p->vel[1]*scale + vright[1]*cost[i%7]*p->scale + vup[1]*sint[i%7]*p->scale; + v[2] = p->org[2] - p->vel[2]*scale + vright[2]*cost[i%7]*p->scale + vup[2]*sint[i%7]*p->scale; + qglVertex3fv (v); + } + qglEnd (); + } +} + +static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *type) +{ + particle_t *p; + + qglDisable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + qglBegin(GL_LINES); + + while (count--) + { + p = *plist++; + + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + qglVertex3f (p->org[0], p->org[1], p->org[2]); + + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + 0); + qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); + } qglEnd(); - - if (lastgltype != type) - { - lastgltype = type; - qglDisable(GL_TEXTURE_2D); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - } - - scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] - + (p->org[2] - r_origin[2])*vpn[2]; - scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); - if (scale < 20) - scale = 0.05; - else - scale = 0.05 + scale * 0.0001; -/* - if ((p->vel[0]*p->vel[0]+p->vel[1]*p->vel[1]+p->vel[2]*p->vel[2])*2*scale > 30*30) - scale = 1+1/30/Length(p->vel)*2;*/ - - qglBegin (GL_TRIANGLE_FAN); - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3fv (p->org); - qglColor4f (p->rgb[0]/2, - p->rgb[1]/2, - p->rgb[2]/2, - 0); - for (i=7 ; i>=0 ; i--) - { - v[0] = p->org[0] - p->vel[0]*scale + vright[0]*cost[i%7]*p->scale + vup[0]*sint[i%7]*p->scale; - v[1] = p->org[1] - p->vel[1]*scale + vright[1]*cost[i%7]*p->scale + vup[1]*sint[i%7]*p->scale; - v[2] = p->org[2] - p->vel[2]*scale + vright[2]*cost[i%7]*p->scale + vup[2]*sint[i%7]*p->scale; - qglVertex3fv (v); - } - qglEnd (); - qglBegin (GL_TRIANGLES); } -static void GL_DrawLineSparkParticle(particle_t *p, part_type_t *type) -{ - if (lastgltype != type) - { - lastgltype = type; - qglEnd(); - qglDisable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_LINES); - } - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3f (p->org[0], p->org[1], p->org[2]); - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); -} - -static void GL_DrawTexturedSparkParticle(particle_t *p, part_type_t *type) +static void GL_DrawTexturedSparkParticle(int count, particle_t **plist, plooks_t *type) { + particle_t *p; vec3_t v, cr, o2, point; - if (lastgltype != type) + + qglEnable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + qglBegin(GL_QUADS); + + + while(count--) { - lastgltype = type; - qglEnd(); - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_QUADS); + p = *plist++; + + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + + VectorSubtract(r_refdef.vieworg, p->org, v); + CrossProduct(v, p->vel, cr); + VectorNormalize(cr); + + VectorMA(p->org, -p->scale/2, cr, point); + qglTexCoord2f(0, 0); + qglVertex3fv(point); + VectorMA(p->org, p->scale/2, cr, point); + qglTexCoord2f(0, 1); + qglVertex3fv(point); + + + VectorMA(p->org, 0.1, p->vel, o2); + + VectorSubtract(r_refdef.vieworg, o2, v); + CrossProduct(v, p->vel, cr); + VectorNormalize(cr); + + VectorMA(o2, p->scale/2, cr, point); + qglTexCoord2f(1, 1); + qglVertex3fv(point); + VectorMA(o2, -p->scale/2, cr, point); + qglTexCoord2f(1, 0); + qglVertex3fv(point); } - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - - VectorSubtract(r_refdef.vieworg, p->org, v); - CrossProduct(v, p->vel, cr); - VectorNormalize(cr); - - VectorMA(p->org, -p->scale/2, cr, point); - qglTexCoord2f(0, 0); - qglVertex3fv(point); - VectorMA(p->org, p->scale/2, cr, point); - qglTexCoord2f(0, 1); - qglVertex3fv(point); - - - VectorMA(p->org, 0.1, p->vel, o2); - - VectorSubtract(r_refdef.vieworg, o2, v); - CrossProduct(v, p->vel, cr); - VectorNormalize(cr); - - VectorMA(o2, p->scale/2, cr, point); - qglTexCoord2f(1, 1); - qglVertex3fv(point); - VectorMA(o2, -p->scale/2, cr, point); - qglTexCoord2f(1, 0); - qglVertex3fv(point); + qglEnd(); } -static void GL_DrawSketchSparkParticle(particle_t *p, part_type_t *type) +static void GL_DrawSketchSparkParticle(int count, particle_t **plist, plooks_t *type) { - if (lastgltype != type) + particle_t *p; + + qglDisable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + qglBegin(GL_LINES); + + while(count--) { - lastgltype = type; - qglEnd(); - qglDisable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_LINES); + p = *plist++; + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + qglVertex3f (p->org[0], p->org[1], p->org[2]); + + qglColor4f (p->rgb[0], + p->rgb[1], + p->rgb[2], + 0); + qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); } - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3f (p->org[0], p->org[1], p->org[2]); - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); + qglEnd(); } -static void GL_DrawParticleBeam_Textured(beamseg_t *b, part_type_t *type) +static void GL_DrawParticleBeam_Textured(int count, beamseg_t **blist, plooks_t *type) { + beamseg_t *b; vec3_t v, point; vec3_t cr; beamseg_t *c; @@ -3363,267 +3381,280 @@ static void GL_DrawParticleBeam_Textured(beamseg_t *b, part_type_t *type) particle_t *q; float ts; -// if (!b->next) -// return; - - c = b->next; - - q = c->p; -// if (!q) -// return; - - p = b->p; -// if (!p) -// return; - - if (lastgltype != type) + qglEnable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + qglBegin(GL_QUADS); + + while(count--) { - lastgltype = type; - qglEnd(); - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_QUADS); + b = *blist++; + + c = b->next; + + q = c->p; +// if (!q) +// continue; + + p = b->p; +// if (!p) +// continue; + + qglColor4f(q->rgb[0], + q->rgb[1], + q->rgb[2], + q->alpha); + // qglBegin(GL_LINE_LOOP); + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, cr); + ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(q->org, -q->scale, cr, point); + qglTexCoord2f(ts, 0); + qglVertex3fv(point); + VectorMA(q->org, q->scale, cr, point); + qglTexCoord2f(ts, 1); + qglVertex3fv(point); + + qglColor4f(p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, cr); // replace with old p->dir? + ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; + + VectorMA(p->org, p->scale, cr, point); + qglTexCoord2f(ts, 1); + qglVertex3fv(point); + VectorMA(p->org, -p->scale, cr, point); + qglTexCoord2f(ts, 0); + qglVertex3fv(point); } - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - q->alpha); -// qglBegin(GL_LINE_LOOP); - VectorSubtract(r_refdef.vieworg, q->org, v); - VectorNormalize(v); - CrossProduct(c->dir, v, cr); - ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin; - - VectorMA(q->org, -q->scale, cr, point); - qglTexCoord2f(ts, 0); - qglVertex3fv(point); - VectorMA(q->org, q->scale, cr, point); - qglTexCoord2f(ts, 1); - qglVertex3fv(point); - - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - - VectorSubtract(r_refdef.vieworg, p->org, v); - VectorNormalize(v); - CrossProduct(b->dir, v, cr); // replace with old p->dir? - ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin; - - VectorMA(p->org, p->scale, cr, point); - qglTexCoord2f(ts, 1); - qglVertex3fv(point); - VectorMA(p->org, -p->scale, cr, point); - qglTexCoord2f(ts, 0); - qglVertex3fv(point); -// qglEnd(); + qglEnd(); } -static void GL_DrawParticleBeam_Untextured(beamseg_t *b, part_type_t *type) +static void GL_DrawParticleBeam_Untextured(int count, beamseg_t **blist, plooks_t *type) { vec3_t v; vec3_t cr; beamseg_t *c; particle_t *p; particle_t *q; + beamseg_t *b; vec3_t point[4]; -// if (!b->next) -// return; - c = b->next; + qglDisable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + qglBegin(GL_QUADS); - q = c->p; -// if (!q) -// return; - - p = b->p; -// if (!p) -// return; - - if (lastgltype != type) + while(count--) { - lastgltype = type; - qglEnd(); - qglDisable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_QUADS); + b = *blist++; + + c = b->next; + + q = c->p; + // if (!q) + // continue; + + p = b->p; + // if (!p) + // continue; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, cr); + + VectorMA(q->org, -q->scale, cr, point[0]); + VectorMA(q->org, q->scale, cr, point[1]); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, cr); // replace with old p->dir? + + VectorMA(p->org, p->scale, cr, point[2]); + VectorMA(p->org, -p->scale, cr, point[3]); + + + //one half + //back out + //back in + //front in + //front out + qglColor4f(q->rgb[0], + q->rgb[1], + q->rgb[2], + 0); + qglVertex3fv(point[0]); + qglColor4f(q->rgb[0], + q->rgb[1], + q->rgb[2], + q->alpha); + qglVertex3fv(q->org); + + qglColor4f(p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + qglVertex3fv(p->org); + qglColor4f(p->rgb[0], + p->rgb[1], + p->rgb[2], + 0); + qglVertex3fv(point[3]); + + //front out + //front in + //back in + //back out + qglColor4f(p->rgb[0], + p->rgb[1], + p->rgb[2], + 0); + qglVertex3fv(point[2]); + qglColor4f(p->rgb[0], + p->rgb[1], + p->rgb[2], + p->alpha); + qglVertex3fv(p->org); + + qglColor4f(q->rgb[0], + q->rgb[1], + q->rgb[2], + q->alpha); + qglVertex3fv(q->org); + qglColor4f(q->rgb[0], + q->rgb[1], + q->rgb[2], + 0); + qglVertex3fv(point[1]); } - -// qglBegin(GL_LINE_LOOP); - VectorSubtract(r_refdef.vieworg, q->org, v); - VectorNormalize(v); - CrossProduct(c->dir, v, cr); - - VectorMA(q->org, -q->scale, cr, point[0]); - VectorMA(q->org, q->scale, cr, point[1]); - - - VectorSubtract(r_refdef.vieworg, p->org, v); - VectorNormalize(v); - CrossProduct(b->dir, v, cr); // replace with old p->dir? - - VectorMA(p->org, p->scale, cr, point[2]); - VectorMA(p->org, -p->scale, cr, point[3]); - - - //one half - //back out - //back in - //front in - //front out - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - 0); - qglVertex3fv(point[0]); - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - q->alpha); - qglVertex3fv(q->org); - - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3fv(p->org); - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3fv(point[3]); - - //front out - //front in - //back in - //back out - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3fv(point[2]); - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3fv(p->org); - - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - q->alpha); - qglVertex3fv(q->org); - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - 0); - qglVertex3fv(point[1]); - -// qglEnd(); + qglEnd(); } -static void GL_DrawClippedDecal(clippeddecal_t *d, part_type_t *type) +static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *type) { - if (lastgltype != type) + clippeddecal_t *d; + + qglEnable(GL_TEXTURE_2D); + GL_Bind(type->texturenum); + APPLYBLEND(type->blendmode); + qglShadeModel(GL_SMOOTH); + +// qglDisable(GL_TEXTURE_2D); +// qglBegin(GL_LINE_LOOP); + + qglBegin(GL_TRIANGLES); + + while (count--) { - lastgltype = type; - qglEnd(); - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); + d = *dlist++; -// qglDisable(GL_TEXTURE_2D); -// qglBegin(GL_LINE_LOOP); + qglColor4f(d->rgb[0], + d->rgb[1], + d->rgb[2], + d->alpha); - qglBegin(GL_TRIANGLES); + qglTexCoord2fv(d->texcoords[0]); + qglVertex3fv(d->vertex[0]); + qglTexCoord2fv(d->texcoords[1]); + qglVertex3fv(d->vertex[1]); + qglTexCoord2fv(d->texcoords[2]); + qglVertex3fv(d->vertex[2]); } - - qglColor4f(d->rgb[0], - d->rgb[1], - d->rgb[2], - d->alpha); - - qglTexCoord2fv(d->texcoords[0]); - qglVertex3fv(d->vertex[0]); - qglTexCoord2fv(d->texcoords[1]); - qglVertex3fv(d->vertex[1]); - qglTexCoord2fv(d->texcoords[2]); - qglVertex3fv(d->vertex[2]); + qglEnd(); } #endif #ifdef SWQUAKE -static void SWD_DrawParticleSpark(particle_t *p, part_type_t *type) +static void SWD_DrawParticleSpark(int count, particle_t **plist, plooks_t *type) { float speed; vec3_t src, dest; + particle_t *p; int r,g,b; //if you have a cpu with mmx, good for you... - r = p->rgb[0]*255; - if (r < 0) - r = 0; - else if (r > 255) - r = 255; - g = p->rgb[1]*255; - if (g < 0) - g = 0; - else if (g > 255) - g = 255; - b = p->rgb[2]*255; - if (b < 0) - b = 0; - else if (b > 255) - b = 255; - p->color = GetPaletteIndex(r, g, b); - speed = Length(p->vel); - if ((speed) < 1) + while (count--) { - VectorCopy(p->org, src); - VectorCopy(p->org, dest); - } - else - { //causes flickers with lower vels (due to bouncing in physics) - if (speed < 50) - speed *= 50/speed; - VectorMA(p->org, 2.5/(speed), p->vel, src); - VectorMA(p->org, -2.5/(speed), p->vel, dest); - } + p = *plist++; - D_DrawSparkTrans(p, src, dest, type->blendmode); + r = p->rgb[0]*255; + if (r < 0) + r = 0; + else if (r > 255) + r = 255; + g = p->rgb[1]*255; + if (g < 0) + g = 0; + else if (g > 255) + g = 255; + b = p->rgb[2]*255; + if (b < 0) + b = 0; + else if (b > 255) + b = 255; + p->color = GetPaletteIndex(r, g, b); + + speed = Length(p->vel); + if ((speed) < 1) + { + VectorCopy(p->org, src); + VectorCopy(p->org, dest); + } + else + { //causes flickers with lower vels (due to bouncing in physics) + if (speed < 50) + speed *= 50/speed; + VectorMA(p->org, 2.5/(speed), p->vel, src); + VectorMA(p->org, -2.5/(speed), p->vel, dest); + } + + D_DrawSparkTrans(p, src, dest, type->blendmode); + } } -static void SWD_DrawParticleBlob(particle_t *p, part_type_t *type) +static void SWD_DrawParticleBlob(int count, particle_t **plist, plooks_t *type) { + particle_t *p; int r,g,b; //This really shouldn't be like this. Pitty the 32 bit renderer... - r = p->rgb[0]*255; - if (r < 0) - r = 0; - else if (r > 255) - r = 255; - g = p->rgb[1]*255; - if (g < 0) - g = 0; - else if (g > 255) - g = 255; - b = p->rgb[2]*255; - if (b < 0) - b = 0; - else if (b > 255) - b = 255; - p->color = GetPaletteIndex(r, g, b); - D_DrawParticleTrans(p->org, p->alpha, p->scale, p->color, type->blendmode); + + while(count--) + { + p = *plist++; + + r = p->rgb[0]*255; + if (r < 0) + r = 0; + else if (r > 255) + r = 255; + g = p->rgb[1]*255; + if (g < 0) + g = 0; + else if (g > 255) + g = 255; + b = p->rgb[2]*255; + if (b < 0) + b = 0; + else if (b > 255) + b = 255; + p->color = GetPaletteIndex(r, g, b); + D_DrawParticleTrans(p->org, p->alpha, p->scale, p->color, type->blendmode); + } } -static void SWD_DrawParticleBeam(beamseg_t *beam, part_type_t *type) +static void SWD_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type) { int r,g,b; //if you have a cpu with mmx, good for you... + beamseg_t *beam; beamseg_t *c; particle_t *p; particle_t *q; @@ -3631,35 +3662,40 @@ static void SWD_DrawParticleBeam(beamseg_t *beam, part_type_t *type) // if (!b->next) // return; - c = beam->next; + while(count--) + { + beam = *blist++; - q = c->p; -// if (!q) -// return; + c = beam->next; - p = beam->p; + q = c->p; + // if (!q) + // return; - r = p->rgb[0]*255; - if (r < 0) - r = 0; - else if (r > 255) - r = 255; - g = p->rgb[1]*255; - if (g < 0) - g = 0; - else if (g > 255) - g = 255; - b = p->rgb[2]*255; - if (b < 0) - b = 0; - else if (b > 255) - b = 255; - p->color = GetPaletteIndex(r, g, b); - D_DrawSparkTrans(p, p->org, q->org, type->blendmode); + p = beam->p; + + r = p->rgb[0]*255; + if (r < 0) + r = 0; + else if (r > 255) + r = 255; + g = p->rgb[1]*255; + if (g < 0) + g = 0; + else if (g > 255) + g = 255; + b = p->rgb[2]*255; + if (b < 0) + b = 0; + else if (b > 255) + b = 255; + p->color = GetPaletteIndex(r, g, b); + D_DrawSparkTrans(p, p->org, q->org, type->blendmode); + } } #endif -void PScript_DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type_t*), void (*sparklineparticles)(particle_t*,part_type_t*), void (*sparkfanparticles)(particle_t*,part_type_t*), void (*sparktexturedparticles)(particle_t*,part_type_t*), void (*beamparticlest)(beamseg_t*,part_type_t*), void (*beamparticlesut)(beamseg_t*,part_type_t*), void (*drawdecalparticles)(clippeddecal_t*,part_type_t*)) +void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticlest)(int count, beamseg_t**,plooks_t*), void (*beamparticlesut)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*)) { RSpeedMark(); @@ -3683,8 +3719,6 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type int traces=r_particle_tracelimit.value; int rampind; - lastgltype = NULL; - pframetime = host_frametime; if (cl.paused || r_secondaryview) pframetime = 0; @@ -3804,7 +3838,7 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type d->alpha += pframetime*type->alphachange; } - drawdecalparticles(d, type); + drawdecalparticles(1, &d, &type->looks); } } @@ -3813,7 +3847,7 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type // set drawing methods by type and cvars and hope branch // prediction takes care of the rest - switch(type->type) + switch(type->looks.type) { case PT_BEAM: if (*type->texname) @@ -4078,7 +4112,7 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type p->vel[1] *= type->clipbounce; p->vel[2] *= type->clipbounce; - if (!*type->texname && Length(p->vel)<1000*pframetime && type->type == PT_NORMAL) + if (!*type->texname && Length(p->vel)<1000*pframetime && type->looks.type == PT_NORMAL) p->die = -1; } else @@ -4221,7 +4255,6 @@ static void PScript_FlushRenderer(void) qglEnable (GL_BLEND); GL_TexEnv(GL_MODULATE); qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - lastgltype = NULL; #endif } @@ -4251,21 +4284,16 @@ static void PScript_DrawParticles (void) qglDepthFunc(gldepthfunc); qglDisable(GL_ALPHA_TEST); - qglBegin(GL_QUADS); if (r_drawflat.value == 2) PScript_DrawParticleTypes(GL_DrawSketchParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal); else PScript_DrawParticleTypes(GL_DrawTexturedParticle, GL_DrawLineSparkParticle, GL_DrawTrifanParticle, GL_DrawTexturedSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal); - qglEnd(); qglDisable(GL_POLYGON_OFFSET_FILL); RSpeedRemark(); - lastgltype = NULL; - qglBegin(GL_QUADS); - RQ_RenderDistAndClear(); - qglEnd(); + RQ_RenderBatchClear(); RSpeedEnd(RSPEED_PARTICLESDRAW); qglEnable(GL_TEXTURE_2D); @@ -4280,7 +4308,6 @@ static void PScript_DrawParticles (void) #ifdef SWQUAKE if (qrenderer == QR_SOFTWARE) { - lastgltype = NULL; PScript_DrawParticleTypes(SWD_DrawParticleBlob, SWD_DrawParticleSpark, SWD_DrawParticleSpark, SWD_DrawParticleSpark, SWD_DrawParticleBeam, SWD_DrawParticleBeam, NULL); RSpeedRemark(); diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 7e446683..90b83a31 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -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)); diff --git a/engine/client/r_efrag.c b/engine/client/r_efrag.c index a3a1096b..dbd6a761 100644 --- a/engine/client/r_efrag.c +++ b/engine/client/r_efrag.c @@ -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 diff --git a/engine/client/render.h b/engine/client/render.h index 7e52ed37..cf672be0 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -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. diff --git a/engine/client/renderer.c b/engine/client/renderer.c index d5baa24e..5cae567c 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -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; diff --git a/engine/client/renderque.c b/engine/client/renderque.c index 1592339a..fb981f6e 100644 --- a/engine/client/renderque.c +++ b/engine/client/renderque.c @@ -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) { diff --git a/engine/client/renderque.h b/engine/client/renderque.h index f1174d77..cd868296 100644 --- a/engine/client/renderque.h +++ b/engine/client/renderque.h @@ -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; diff --git a/engine/client/view.c b/engine/client/view.c index 6b07fa4f..4b75038a 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -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 diff --git a/engine/client/view.h b/engine/client/view.h index 7341bffe..b01e32ba 100644 --- a/engine/client/view.h +++ b/engine/client/view.h @@ -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); diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index ba6f8805..b3eee086 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -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 diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index f1eb7bad..753d0bae 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -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 diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 58b4ce5a..9f69f1c1 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -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 #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) diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 7da48f6b..5496114a 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -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 diff --git a/engine/common/common.h b/engine/common/common.h index fc189dad..7f3f407b 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -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 diff --git a/engine/common/fs.c b/engine/common/fs.c index 9712c22e..33f92389 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -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 diff --git a/engine/common/log.c b/engine/common/log.c index 397d3066..f5fa7c1e 100644 --- a/engine/common/log.c +++ b/engine/common/log.c @@ -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); diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index 9198797d..73c6e5e6 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -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]; diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index 7ef52b9c..098e1307 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -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); diff --git a/engine/common/q3common.c b/engine/common/q3common.c index fefb0c88..657e54b2 100644 --- a/engine/common/q3common.c +++ b/engine/common/q3common.c @@ -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)); diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index 2139c8d8..d7731081 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -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 diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 3e5be361..05f0c0d0 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -17,7 +17,7 @@ #ifdef RGLQUAKE #include "glquake.h" #endif -#if defined(RGLQUAKE) || defined(SERVERONLY) +#if defined(RGLQUAKE) #ifdef _WIN32 #include @@ -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) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 9061e2e2..df8fc24f 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -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; diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index e3040761..58c79cc3 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -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); diff --git a/engine/gl/gl_hlmdl.c b/engine/gl/gl_hlmdl.c index 43635149..5c481653 100644 --- a/engine/gl/gl_hlmdl.c +++ b/engine/gl/gl_hlmdl.c @@ -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++) diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index c15f4f28..a96ccb68 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -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; } diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index 7030da80..58f58eb5 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -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) diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index b8226da7..2401b7b0 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -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); + } } /* ============= diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 28511cc3..d5b35b62 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -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 diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 810e6405..49c92a29 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -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) { diff --git a/engine/gl/shader.h b/engine/gl/shader.h index ce54effe..a7ed4dc6 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -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 diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index 1611ad9c..1a779114 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -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. diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index d12c0297..7cf88d4d 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -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; } diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 81cd006c..d48f9317 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -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; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 1986d656..545ad0c5 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -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; } diff --git a/engine/sw/d_part.c b/engine/sw/d_part.c index d468e2b5..0b50b2ed 100644 --- a/engine/sw/d_part.c +++ b/engine/sw/d_part.c @@ -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 diff --git a/engine/sw/d_trans.c b/engine/sw/d_trans.c index e79705a5..94d8410a 100644 --- a/engine/sw/d_trans.c +++ b/engine/sw/d_trans.c @@ -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); diff --git a/engine/sw/r_alias.c b/engine/sw/r_alias.c index 2737270a..13028280 100644 --- a/engine/sw/r_alias.c +++ b/engine/sw/r_alias.c @@ -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 diff --git a/engine/sw/r_draw.c b/engine/sw/r_draw.c index 192ac35a..af0cada2 100644 --- a/engine/sw/r_draw.c +++ b/engine/sw/r_draw.c @@ -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; diff --git a/engine/sw/r_surf.c b/engine/sw/r_surf.c index 3000df9f..2c7b285e 100644 --- a/engine/sw/r_surf.c +++ b/engine/sw/r_surf.c @@ -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; diff --git a/engine/sw/sw_model.c b/engine/sw/sw_model.c index 9683ff28..0625c903 100644 --- a/engine/sw/sw_model.c +++ b/engine/sw/sw_model.c @@ -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;