diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index f72768c4a..031961c68 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -638,20 +638,7 @@ qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, cons AngleVectors, GenMatrixPosQuat4Scale, COM_StripExtension, - Alias_ForceConvertBoneData, -#ifdef USERBE - World_LinkEdict, - World_RegisterPhysicsEngine, - World_UnregisterPhysicsEngine, - World_GenerateCollisionMesh, - World_ReleaseCollisionMesh -#else - NULL, - NULL, - NULL, - NULL, - NULL -#endif + Alias_ForceConvertBoneData }; if (VM_LONG(arg[0]) >= sizeof(funcs)) return (qintptr_t)&funcs; diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 87c8b3dc2..199e17c25 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1435,7 +1435,10 @@ void SCR_DrawGameClock(void) else timelimit = 0; - showtime = timelimit - cl.matchgametime; + if (cl.playerview[0].statsf[STAT_MATCHSTARTTIME]) + showtime = timelimit - (cl.servertime - cl.playerview[0].statsf[STAT_MATCHSTARTTIME]); + else + showtime = timelimit - cl.matchgametime; if (showtime < 0) { diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 934047a4a..b73bec410 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1178,7 +1178,7 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n")); #endif TRACE(("dbg: R_ApplyRenderer: reloading server map\n")); - sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_ERROR); + sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_WARN); TRACE(("dbg: R_ApplyRenderer: loaded\n")); if (sv.world.worldmodel->loadstate == MLS_LOADING) COM_WorkerPartialSync(sv.world.worldmodel, &sv.world.worldmodel->loadstate, MLS_LOADING); diff --git a/engine/client/view.c b/engine/client/view.c index 561e26588..d942ca6cc 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -27,6 +27,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include // for isdigit(); cvar_t ffov = SCVAR("ffov", "0"); +#if defined(_WIN32) && !defined(MINIMAL) +//amusing gimmick / easteregg. +#include "winquake.h" +cvar_t itburnsitburnsmakeitstop = CVARFD("itburnsitburnsmakeitstop", "0", CVAR_NOTFROMSERVER, "Ouch"); +#endif /* @@ -373,6 +378,37 @@ void V_Gamma_Callback(struct cvar_s *var, char *oldvalue) V_UpdatePalette (true); } +#ifdef _WIN32 +void W32_BlowChunk(vec3_t pos, float radius) +{ + vec3_t center; + if (Matrix4x4_CM_Project(pos, center, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y)) + { + int mid_x = center[0]*r_refdef.vrect.width+r_refdef.vrect.x; + int mid_y = (1-center[1])*r_refdef.vrect.height+r_refdef.vrect.y; + + HRGN tmp = CreateRectRgn(0,0,0,0); + HRGN newrgn = CreateRectRgn(0,0,0,0); + HRGN oldrgn = CreateRectRgn(0,0,0,0); + HRGN hole = CreateEllipticRgn(mid_x-radius, mid_y-radius, mid_x+radius, mid_y+radius); + if (GetWindowRgn(mainwindow, oldrgn) <= NULLREGION) + { + RECT rect; + DeleteObject(oldrgn); + GetWindowRect(mainwindow, &rect); + oldrgn = CreateRectRgn(0,0,rect.right-rect.left,rect.bottom-rect.top); + } + CombineRgn(tmp, oldrgn, hole, RGN_XOR); + CombineRgn(newrgn, oldrgn, tmp, RGN_AND); + DeleteObject(oldrgn); + DeleteObject(hole); + DeleteObject(tmp); + SetWindowRgn(mainwindow, newrgn, TRUE); + } +} +#endif + + /* =============== V_ParseDamage @@ -394,6 +430,11 @@ void V_ParseDamage (playerview_t *pv) pv->faceanimtime = cl.time + 0.2; // but sbar face into pain frame +#if defined(_WIN32) && !defined(MINIMAL) + if (itburnsitburnsmakeitstop.value > 0) + W32_BlowChunk(from, (armor+blood) * itburnsitburnsmakeitstop.value); +#endif + #ifdef CSQC_DAT if (CSQC_Parse_Damage(armor, blood, from)) return; @@ -1871,4 +1912,8 @@ void V_Init (void) Cvar_Register (&chase_active, VIEWVARS); Cvar_Register (&chase_back, VIEWVARS); Cvar_Register (&chase_up, VIEWVARS); + +#if defined(_WIN32) && !defined(MINIMAL) + Cvar_Register (&itburnsitburnsmakeitstop, VIEWVARS); +#endif } diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index e05bbdf35..9dd19567c 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -154,8 +154,16 @@ typedef struct #define Q1CONTENTS_SLIME -4 #define Q1CONTENTS_LAVA -5 #define Q1CONTENTS_SKY -6 -#define Q1CONTENTS_CLIP -8 -#define Q1CONTENTS_LADDER -16 +#define Q1CONTENTS_STRIPPED -7 /*not known to engine*/ +#define Q1CONTENTS_CLIP -8 /*solid to players*/ +#define Q1CONTENTS_FLOW_1 -9 /*moves player*/ +#define Q1CONTENTS_FLOW_2 -10 /*moves player*/ +#define Q1CONTENTS_FLOW_3 -11 /*moves player*/ +#define Q1CONTENTS_FLOW_4 -12 /*moves player*/ +#define Q1CONTENTS_FLOW_5 -13 /*moves player*/ +#define Q1CONTENTS_FLOW_6 -14 /*moves player*/ +#define Q1CONTENTS_TRANS -15 /*should be solid I guess*/ +#define Q1CONTENTS_LADDER -16 /*player can climb up/down*/ // !!! if this is changed, it must be changed in asm_i386.h too !!! typedef struct diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 8d7512648..74febeddf 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -192,11 +192,11 @@ typedef struct void (QDECL *StripExtension) (const char *in, char *out, int outlen); void (QDECL *ForceConvertBoneData)(skeltype_t sourcetype, const float *sourcedata, size_t bonecount, galiasbone_t *bones, skeltype_t desttype, float *destbuffer, size_t destbonecount); - void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers); - qboolean (QDECL *RegisterPhysicsEngine)(const char *enginename, void(QDECL*World_Bullet_Start)(world_t*world)); //returns false if there's already one active. - void (QDECL *UnregisterPhysicsEngine)(const char *enginename); //returns false if there's already one active. - qboolean (QDECL *GenerateCollisionMesh)(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter); - void (QDECL *ReleaseCollisionMesh) (wedict_t *ed); + void *unused1; + void *reserved2; + void *unused3; + void *unused4; + void *unused5; } modplugfuncs_t; #define MODPLUGFUNCS_VERSION 2 diff --git a/engine/common/com_phys_ode.c b/engine/common/com_phys_ode.c index e7b13f251..7d73c8bbe 100644 --- a/engine/common/com_phys_ode.c +++ b/engine/common/com_phys_ode.c @@ -41,7 +41,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef USERBE #include "pr_common.h" -#include "com_mesh.h" #ifndef FTEENGINE #define BZ_Malloc malloc @@ -67,13 +66,13 @@ static BUILTINR(dllhandle_t *, Sys_LoadLibrary, (const char *name,dllfunction_t static BUILTIN(void, Sys_CloseLibrary, (dllhandle_t *hdl)); #undef ARGNAMES #define ARGNAMES ,version -static BUILTINR(modplugfuncs_t*, Mod_GetPluginModelFuncs, (int version)); +static BUILTINR(rbeplugfuncs_t*, RBE_GetPluginFuncs, (int version)); #undef ARGNAMES #define ARGNAMES ,name,defaultval,flags,description,groupname static BUILTINR(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname)); #undef ARGNAMES -static modplugfuncs_t *modfuncs; +static rbeplugfuncs_t *rbefuncs; //============================================================================ // physics engine support @@ -1383,7 +1382,7 @@ static void QDECL World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed) } ed->ode.ode_body = NULL; - modfuncs->ReleaseCollisionMesh(ed); + rbefuncs->ReleaseCollisionMesh(ed); if(ed->ode.ode_massbuf) BZ_Free(ed->ode.ode_massbuf); ed->ode.ode_massbuf = NULL; @@ -1483,7 +1482,7 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed) VectorCopy(avelocity, ed->ode.ode_avelocity); ed->ode.ode_gravity = dBodyGetGravityMode(body); - modfuncs->LinkEdict(world, ed, true); + rbefuncs->LinkEdict(world, ed, true); } static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed) @@ -2114,7 +2113,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed) World_ODE_RemoveFromEntity(world, ed); return; } - if (!modfuncs->GenerateCollisionMesh(world, model, ed, geomcenter)) + if (!rbefuncs->GenerateCollisionMesh(world, model, ed, geomcenter)) { if (ed->ode.ode_physics) World_ODE_RemoveFromEntity(world, ed); @@ -2779,28 +2778,33 @@ static void World_ODE_RunCmd(world_t *world, rbecommandqueue_t *cmd) static qintptr_t QDECL Plug_ODE_Shutdown(qintptr_t *args) { - if (modfuncs) - modfuncs->UnregisterPhysicsEngine("ODE"); + if (rbefuncs) + rbefuncs->UnregisterPhysicsEngine("ODE"); World_ODE_Shutdown(); return 0; } qintptr_t Plug_Init(qintptr_t *args) { - CHECKBUILTIN(Mod_GetPluginModelFuncs); + CHECKBUILTIN(RBE_GetPluginFuncs); CHECKBUILTIN(Cvar_GetNVFDG); #ifndef ODE_STATIC CHECKBUILTIN(Sys_LoadLibrary); CHECKBUILTIN(Sys_CloseLibrary); #endif - if (BUILTINISVALID(Mod_GetPluginModelFuncs)) + if (BUILTINISVALID(RBE_GetPluginFuncs)) { - modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t)); - if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION) - modfuncs = NULL; + rbefuncs = pRBE_GetPluginFuncs(sizeof(rbeplugfuncs_t)); + if (rbefuncs && rbefuncs->version < RBEPLUGFUNCS_VERSION) + rbefuncs = NULL; } - if (!modfuncs || !BUILTINISVALID(Cvar_GetNVFDG)) + if (!rbefuncs) + { + Con_Printf("ODE plugin failed: Engine does not support external rigid body engines.\n"); + return false; + } + if (!BUILTINISVALID(Cvar_GetNVFDG)) { Con_Printf("ODE plugin failed: Engine too old.\n"); return false; @@ -2813,9 +2817,9 @@ qintptr_t Plug_Init(qintptr_t *args) } #endif - if (!modfuncs || !modfuncs->RegisterPhysicsEngine) + if (!rbefuncs || !rbefuncs->RegisterPhysicsEngine) Con_Printf("ODE plugin failed: Engine doesn't support physics engine plugins.\n"); - else if (!modfuncs->RegisterPhysicsEngine("ODE", World_ODE_Start)) + else if (!rbefuncs->RegisterPhysicsEngine("ODE", World_ODE_Start)) Con_Printf("ODE plugin failed: Engine already has a physics plugin active.\n"); else { diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 303cd4766..7cb8ab6a2 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -1277,6 +1277,31 @@ qintptr_t VARGS Plug_UpdateInputBuffer(void *offset, quintptr_t mask, const qint return bufferlen; } +#ifdef USERBE +#include "pr_common.h" +//functions useful for rigid body engines. +qintptr_t VARGS Plug_RBE_GetPluginFuncs(void *offset, quintptr_t mask, const qintptr_t *arg) +{ + static rbeplugfuncs_t funcs = + { + RBEPLUGFUNCS_VERSION, + + World_RegisterPhysicsEngine, + World_UnregisterPhysicsEngine, + World_GenerateCollisionMesh, + World_ReleaseCollisionMesh, + World_LinkEdict, + + VectorAngles, + AngleVectors + }; + if (VM_LONG(arg[0]) >= sizeof(funcs)) + return (qintptr_t)&funcs; + else + return 0; +} +#endif + void Plug_CloseAll_f(void); void Plug_List_f(void); void Plug_Close_f(void); @@ -1399,6 +1424,10 @@ void Plug_Initialise(qboolean fromgamedir) Plug_RegisterBuiltin("Sys_LoadLibrary", Plug_Sys_LoadLibrary, PLUG_BIF_DLLONLY); Plug_RegisterBuiltin("Sys_CloseLibrary", Plug_Sys_CloseLibrary, PLUG_BIF_DLLONLY); +#ifdef USERBE + Plug_RegisterBuiltin("RBE_GetPluginFuncs", Plug_RBE_GetPluginFuncs, PLUG_BIF_DLLONLY); +#endif + Plug_Client_Init(); } diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 108a0b4a1..c6e466e4a 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -540,6 +540,22 @@ pbool QDECL ED_CanFree (edict_t *ed); #define JOINTTYPE_HINGE2 5 #define JOINTTYPE_FIXED -1 +typedef struct +{ + int version; + + qboolean (QDECL *RegisterPhysicsEngine)(const char *enginename, void(QDECL*World_Bullet_Start)(world_t*world)); //returns false if there's already one active. + void (QDECL *UnregisterPhysicsEngine)(const char *enginename); //returns false if there's already one active. + qboolean (QDECL *GenerateCollisionMesh)(world_t *world, model_t *mod, wedict_t *ed, vec3_t geomcenter); + void (QDECL *ReleaseCollisionMesh) (wedict_t *ed); + void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers); + + void (QDECL *VectorAngles)(float *forward, float *up, float *result); + void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +} rbeplugfuncs_t; +#define RBEPLUGFUNCS_VERSION 1 + + #define DAMAGE_NO 0 #define DAMAGE_YES 1 #define DAMAGE_AIM 2 diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 4c11abd78..4c4e21c3d 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -375,7 +375,7 @@ struct traceinfo_s unsigned int solidcontents; trace_t trace; - qboolean sphere; + qboolean capsule; float radius; /*set even for sphere traces (used for bbox tests)*/ vec3_t mins; @@ -383,6 +383,10 @@ struct traceinfo_s vec3_t start; vec3_t end; + + vec3_t up; + vec3_t capsulesize; + vec3_t extents; }; static void Q1BSP_ClipToBrushes(struct traceinfo_s *traceinfo, mbrush_t *brush) @@ -409,9 +413,13 @@ static void Q1BSP_ClipToBrushes(struct traceinfo_s *traceinfo, mbrush_t *brush) for (i = brush->numplanes, plane = brush->planes; i; i--, plane++) { /*calculate the distance based upon the shape of the object we're tracing for*/ - if (traceinfo->sphere) + if (traceinfo->capsule) { - dist = plane->dist + traceinfo->radius; + dist = DotProduct(traceinfo->up, plane->normal); + dist = dist*(traceinfo->capsulesize[(dist<0)?1:2]) - traceinfo->capsulesize[0]; + dist = plane->dist - dist; + + //dist = plane->dist + traceinfo->radius; } else { @@ -644,8 +652,27 @@ static unsigned int Q1BSP_TranslateContents(int contents) return FTECONTENTS_SKY; case Q1CONTENTS_LADDER: return FTECONTENTS_LADDER; + case Q1CONTENTS_CLIP: + return FTECONTENTS_PLAYERCLIP; + case Q1CONTENTS_TRANS: + return FTECONTENTS_SOLID; + + //q2 is better than nothing, right? + case Q1CONTENTS_FLOW_1: + return Q2CONTENTS_CURRENT_0; + case Q1CONTENTS_FLOW_2: + return Q2CONTENTS_CURRENT_90; + case Q1CONTENTS_FLOW_3: + return Q2CONTENTS_CURRENT_180; + case Q1CONTENTS_FLOW_4: + return Q2CONTENTS_CURRENT_270; + case Q1CONTENTS_FLOW_5: + return Q2CONTENTS_CURRENT_UP; + case Q1CONTENTS_FLOW_6: + return Q2CONTENTS_CURRENT_DOWN; + default: - Sys_Error("Q1BSP_TranslateContents: Unknown contents type - %i", contents); + Con_Printf("Q1BSP_TranslateContents: Unknown contents type - %i", contents); return FTECONTENTS_SOLID; } } @@ -855,7 +882,23 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3] VectorCopy(maxs, traceinfo.maxs); VectorCopy(start, traceinfo.start); VectorCopy(end, traceinfo.end); - traceinfo.sphere = false; + traceinfo.capsule = capsule; + + if (traceinfo.capsule) + { + float ext; + traceinfo.capsulesize[0] = ((maxs[0]-mins[0]) + (maxs[1]-mins[1]))/4.0; + traceinfo.capsulesize[1] = maxs[2]; + traceinfo.capsulesize[2] = mins[2]; + ext = (traceinfo.capsulesize[1] > -traceinfo.capsulesize[2])?traceinfo.capsulesize[1]:-traceinfo.capsulesize[2]; + traceinfo.capsulesize[1] -= traceinfo.capsulesize[0]; + traceinfo.capsulesize[2] += traceinfo.capsulesize[0]; + traceinfo.extents[0] = ext+1; + traceinfo.extents[1] = ext+1; + traceinfo.extents[2] = ext+1; + VectorSet(traceinfo.up, 0, 0, 1); + } + /* traceinfo.sphere = true; traceinfo.radius = 48; traceinfo.mins[0] = -traceinfo.radius; diff --git a/engine/gl/ltface.c b/engine/gl/ltface.c index be762b6f2..b137baecb 100644 --- a/engine/gl/ltface.c +++ b/engine/gl/ltface.c @@ -441,13 +441,16 @@ static void LightCalcFaceExtents (llightinfo_t *l) l->exactmins[i] = mins[i]; l->exactmaxs[i] = maxs[i]; - mins[i] = floor(mins[i]/16); - maxs[i] = ceil(maxs[i]/16); + mins[i] = floor(mins[i]/(1<lmshift)); + maxs[i] = ceil(maxs[i]/(1<lmshift)); l->texmins[i] = mins[i]; l->texsize[i] = maxs[i] - mins[i]; if (l->texsize[i] > 17) - Error ("Bad surface extents"); + { + l->texsize[i] = 17; + Con_Printf("Bad surface extents"); + } } }