From 6e3f69f504ada10ed4db15732cd8928d097bb6c0 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 23 Dec 2008 02:55:20 +0000 Subject: [PATCH] d3d rendering is diabled (framestate, read later - merged will compile just sw+gl for now). fte particle scripts are disabled (classic works). I'll fix these in the new year. Redid framestate stuff again. Slightly better now, but this is the bulk of the changes here. Reworked the renderqueue to provide batches of items instead of individual items. This cleans up the particle rendering code significantly, and is a step towards multiple concurrent particle systems. fte's scripted particles are broken as I'm trying to find a way to rework them to batch types together, rather than having to restart each batch after each particle when you have two particles in a trail. I'll fix it some time. Reworked some alias model code regarding skeletal models. Added some conceptual skeletal bone control builtins available to csqc. Currently it can query the bone names and save off animation states, but can't animate - its just not complete. Added more info to glsl custom shaders. Updated surface sorting on halflife maps to properly cope with alphaed entities, rather than just texture-based blends (q2-style). git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3095 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_demo.c | 2 +- engine/client/cl_ents.c | 144 ++--- engine/client/cl_main.c | 2 +- engine/client/cl_parse.c | 14 +- engine/client/cl_tent.c | 6 +- engine/client/cl_ui.c | 8 +- engine/client/client.h | 1 + engine/client/clq2_ents.c | 40 +- engine/client/clq3_parse.c | 8 +- engine/client/m_download.c | 10 +- engine/client/merged.h | 43 +- engine/client/net_master.c | 2 +- engine/client/p_classic.c | 2 - engine/client/p_null.c | 2 - engine/client/p_script.c | 1067 +++++++++++++++++----------------- engine/client/pr_csqc.c | 589 +++++++++++++++---- engine/client/r_efrag.c | 4 +- engine/client/render.h | 24 +- engine/client/renderer.c | 6 +- engine/client/renderque.c | 49 +- engine/client/renderque.h | 5 +- engine/client/view.c | 2 +- engine/client/view.h | 2 +- engine/common/bothdefs.h | 10 + engine/common/bspfile.h | 2 + engine/common/com_mesh.c | 509 +++++++++++++--- engine/common/com_mesh.h | 19 + engine/common/common.h | 2 +- engine/common/fs.c | 12 +- engine/common/log.c | 14 +- engine/common/mathlib.c | 4 +- engine/common/mathlib.h | 4 +- engine/common/q3common.c | 2 +- engine/ftequake/ftequake.dsp | 44 +- engine/gl/gl_alias.c | 369 ++---------- engine/gl/gl_backend.c | 3 + engine/gl/gl_draw.c | 39 ++ engine/gl/gl_hlmdl.c | 25 +- engine/gl/gl_model.c | 27 +- engine/gl/gl_ppl.c | 55 +- engine/gl/gl_rmain.c | 16 +- engine/gl/gl_rsurf.c | 14 +- engine/gl/gl_shader.c | 17 +- engine/gl/shader.h | 2 + engine/qclib/execloop.h | 17 + engine/qclib/initlib.c | 12 + engine/qclib/pr_edict.c | 18 +- engine/server/pr_cmds.c | 39 +- engine/sw/d_part.c | 2 + engine/sw/d_trans.c | 2 +- engine/sw/r_alias.c | 14 +- engine/sw/r_draw.c | 4 +- engine/sw/r_surf.c | 2 +- engine/sw/sw_model.c | 56 +- 54 files changed, 2058 insertions(+), 1329 deletions(-) diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 4bc04efe7..ff298ff21 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 6424fff67..0d95f161a 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 7ef10db63..7fb4333e5 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 d1096c6f9..bd152b732 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 e7f120eaf..be1565bbf 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 ccd880d03..e9681aa41 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 730e73892..a03a688f0 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 b25ab55ce..0e5accc2f 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 b0aa927e7..9b2f0ac2a 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 186214075..f33a64015 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 9a0a7db7e..722efbd8b 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 054d98a85..c5888744f 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 15bd5d3d2..7ed1fae5c 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 dda443984..adc8fb315 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 b4d3776c9..fb517c132 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 7e446683f..90b83a31f 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 a3a1096b2..dbd6a7618 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 7e52ed37a..cf672be04 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 d5baa24e9..5cae567cb 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 1592339a5..fb981f6e6 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 f1174d77c..cd8682961 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 6b07fa4f5..4b75038a2 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 7341bffea..b01e32ba6 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 ba6f8805d..b3eee086a 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 f1eb7bad5..753d0baeb 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 58b4ce5ad..9f69f1c19 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 7da48f6bc..5496114a4 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 fc189dad3..7f3f407b6 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 9712c22e2..33f923893 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 397d30666..f5fa7c1e0 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 9198797d1..73c6e5e6a 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 7ef52b9cf..098e13078 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 fefb0c881..657e54b26 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 2139c8d8f..d7731081e 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 3e5be3614..05f0c0d0a 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 9061e2e22..df8fc24fd 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 e3040761c..58c79cc3b 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 436351494..5c4816538 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 c15f4f28d..a96ccb68b 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 7030da80d..58f58eb54 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 b8226da73..2401b7b06 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 28511cc34..d5b35b620 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 810e6405b..49c92a295 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 ce54effea..a7ed4dc6d 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 1611ad9cc..1a7791147 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 d12c02975..7cf88d4dc 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 81cd006c4..d48f93173 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 1986d656e..545ad0c5a 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 d468e2b5c..0b50b2edf 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 e79705a56..94d8410a7 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 2737270ad..130282800 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 192ac35a6..af0cada2c 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 3000df9f7..2c7b285e5 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 9683ff284..0625c903d 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;