]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
rename some stuff
authorRudolf Polzer <divverent@alientrap.org>
Wed, 21 Dec 2011 20:48:47 +0000 (21:48 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Wed, 21 Dec 2011 20:48:47 +0000 (21:48 +0100)
22 files changed:
qcsrc/client/progs.src
qcsrc/common/csqcmodel_settings.qh [new file with mode: 0644]
qcsrc/csqcmodel/cl_model.qc [deleted file]
qcsrc/csqcmodel/cl_model.qh [deleted file]
qcsrc/csqcmodel/cl_player.qc [deleted file]
qcsrc/csqcmodel/cl_player.qh [deleted file]
qcsrc/csqcmodel/common.qh [deleted file]
qcsrc/csqcmodel/interpolate.qc [deleted file]
qcsrc/csqcmodel/interpolate.qh [deleted file]
qcsrc/csqcmodel/settings.qh [deleted file]
qcsrc/csqcmodel/sv_model.qc [deleted file]
qcsrc/csqcmodel/sv_model.qh [deleted file]
qcsrc/csqcmodellib/cl_model.qc [new file with mode: 0644]
qcsrc/csqcmodellib/cl_model.qh [new file with mode: 0644]
qcsrc/csqcmodellib/cl_player.qc [new file with mode: 0644]
qcsrc/csqcmodellib/cl_player.qh [new file with mode: 0644]
qcsrc/csqcmodellib/common.qh [new file with mode: 0644]
qcsrc/csqcmodellib/interpolate.qc [new file with mode: 0644]
qcsrc/csqcmodellib/interpolate.qh [new file with mode: 0644]
qcsrc/csqcmodellib/sv_model.qc [new file with mode: 0644]
qcsrc/csqcmodellib/sv_model.qh [new file with mode: 0644]
qcsrc/server/progs.src

index 9507161feda819a65793ba5b95fcbdd990439517..7f31cacf2bb779ab769c98462771354af9922f1f 100644 (file)
@@ -22,7 +22,7 @@ Defs.qc
 
 autocvars.qh
 
-../csqcmodel/interpolate.qh
+../csqcmodellib/interpolate.qh
 teamradar.qh
 hud.qh
 scoreboard.qh
@@ -37,10 +37,10 @@ tturrets.qh
 ../server/movelib.qc
 main.qh
 vehicles/vehicles.qh
-../csqcmodel/settings.qh
-../csqcmodel/common.qh
-../csqcmodel/cl_model.qh
-../csqcmodel/cl_player.qh
+../common/csqcmodel_settings.qh
+../csqcmodellib/common.qh
+../csqcmodellib/cl_model.qh
+../csqcmodellib/cl_player.qh
 projectile.qh
 
 sortlist.qc
@@ -62,8 +62,8 @@ projectile.qc
 gibs.qc
 damage.qc
 casings.qc
-../csqcmodel/cl_model.qc
-../csqcmodel/cl_player.qc
+../csqcmodellib/cl_model.qc
+../csqcmodellib/cl_player.qc
 effects.qc
 wall.qc
 modeleffects.qc
@@ -77,7 +77,7 @@ shownames.qc
 announcer.qc
 Main.qc
 View.qc
-../csqcmodel/interpolate.qc
+../csqcmodellib/interpolate.qc
 waypointsprites.qc
 movetypes.qc
 prandom.qc
diff --git a/qcsrc/common/csqcmodel_settings.qh b/qcsrc/common/csqcmodel_settings.qh
new file mode 100644 (file)
index 0000000..257676d
--- /dev/null
@@ -0,0 +1,84 @@
+// define this if svqc code wants to use .frame2 and .lerpfrac
+#define CSQCMODEL_HAVE_TWO_FRAMES
+
+// don't define this ever
+//#define CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW
+
+// a hack for Xonotic
+#ifdef CSQC
+# define TAG_ENTITY_NAME tag_networkentity
+# define TAG_ENTITY_TYPE float
+.float tag_networkentity;
+#else
+# define TAG_ENTITY_NAME tag_entity
+# define TAG_ENTITY_TYPE entity
+#endif
+
+// add properties you want networked to CSQC here
+#define CSQCMODEL_EXTRAPROPERTIES \
+       CSQCMODEL_PROPERTY(1, float, ReadShort, WriteShort, colormap) \
+       CSQCMODEL_PROPERTY(2, float, ReadInt24_t, WriteInt24_t, effects) \
+       CSQCMODEL_PROPERTY(4, float, ReadByte, WriteByte, modelflags) \
+       CSQCMODEL_PROPERTY_SCALED(8, float, ReadByte, WriteByte, alpha, 255, 0, 255) \
+       CSQCMODEL_PROPERTY(16, float, ReadByte, WriteByte, skin) \
+       CSQCMODEL_IF(isplayer) \
+       CSQCMODEL_ENDIF \
+       CSQCMODEL_IF(!isplayer) \
+               CSQCMODEL_PROPERTY(32, TAG_ENTITY_TYPE, ReadShort, WriteEntity, TAG_ENTITY_NAME) \
+               CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_x, 255, 0, 255) \
+               CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_y, 255, 0, 255) \
+               CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_z, 255, 0, 255) \
+       CSQCMODEL_ENDIF
+// TODO get rid of colormod/glowmod here, find good solution for nex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody
+
+// add hook function calls here
+#define CSQCMODEL_HOOK_PREUPDATE \
+       CSQCModel_Hook_PreUpdate(isplayer, islocalplayer);
+#define CSQCMODEL_HOOK_POSTUPDATE \
+       CSQCModel_Hook_PostUpdate(isplayer, islocalplayer);
+#define CSQCMODEL_HOOK_PREDRAW \
+       CSQCModel_Hook_PreDraw(isplayer, islocalplayer);
+#define CSQCPLAYER_HOOK_POSTCAMERASETUP
+
+#define CSQCPLAYER_FORCE_UPDATES 0.25
+
+// mod must define:
+//vector PL_MIN  = ...;
+//vector PL_MAX  = ...;
+//vector PL_VIEW_OFS  = ...;
+//vector PL_CROUCH_MIN  = ...;
+//vector PL_CROUCH_MAX  = ...;
+//vector PL_CROUCH_VIEW_OFS  = ...;
+
+#ifdef SVQC
+# ifdef NO_LEGACY_NETWORKING
+#  define CSQCMODEL_AUTOINIT() CSQCModel_LinkEntity()
+#  define CSQCMODEL_AUTOUPDATE() CSQCModel_CheckUpdate()
+# else
+.float iscsqcmodel;
+float autocvar_sv_use_csqc_players;
+#  define CSQCMODEL_AUTOINIT() \
+       if(autocvar_sv_use_csqc_players) \
+       { \
+               CSQCModel_LinkEntity(); \
+               self.iscsqcmodel = 1; \
+       } \
+       else \
+               self.iscsqcmodel = 0
+#  define CSQCMODEL_AUTOUPDATE() \
+       if(autocvar_sv_use_csqc_players && !self.iscsqcmodel) \
+       { \
+               CSQCModel_LinkEntity(); \
+               self.iscsqcmodel = 1; \
+       } \
+       if(!autocvar_sv_use_csqc_players && self.iscsqcmodel) \
+       { \
+               CSQCModel_UnlinkEntity(); \
+               self.iscsqcmodel = 0; \
+       } \
+       if(self.iscsqcmodel) \
+               CSQCModel_CheckUpdate()
+# endif
+#endif
+
+#define CSQCMODEL_EF_INVISIBLE EF_SELECTABLE
diff --git a/qcsrc/csqcmodel/cl_model.qc b/qcsrc/csqcmodel/cl_model.qc
deleted file mode 100644 (file)
index 0322661..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-var float autocvar_cl_lerpanim_maxdelta_framegroups = 0.1;
-var float autocvar_cl_nolerp = 0;
-
-.float csqcmodel_lerpfrac;
-.float csqcmodel_lerpfrac2;
-.float csqcmodel_lerpfractime;
-.float csqcmodel_lerpfrac2time;
-
-void CSQCModel_InterpolateAnimation_PreNote(float sf)
-{
-#ifdef CSQCMODEL_HAVE_TWO_FRAMES
-       if(sf & CSQCMODEL_PROPERTY_FRAME)
-       {
-               self.frame3 = self.frame;
-               self.frame3time = self.frame1time;
-       }
-       if(sf & CSQCMODEL_PROPERTY_FRAME2)
-       {
-               self.frame4 = self.frame2;
-               self.frame4time = self.frame2time;
-       }
-       if(sf & CSQCMODEL_PROPERTY_LERPFRAC)
-       {
-               self.csqcmodel_lerpfrac2 = self.csqcmodel_lerpfrac;
-               self.csqcmodel_lerpfrac2time = self.csqcmodel_lerpfractime;
-               self.lerpfrac = self.csqcmodel_lerpfrac;
-       }
-#else
-       if(sf & CSQCMODEL_PROPERTY_FRAME)
-       {
-               self.frame2 = self.frame;
-               self.frame2time = self.frame1time;
-       }
-#endif
-}
-
-void CSQCModel_InterpolateAnimation_Note(float sf)
-{
-#ifdef CSQCMODEL_HAVE_TWO_FRAMES
-       if(sf & CSQCMODEL_PROPERTY_FRAME)
-       {
-               self.frame1time = time;
-       }
-       if(sf & CSQCMODEL_PROPERTY_FRAME2)
-       {
-               self.frame2time = time;
-       }
-       if(sf & CSQCMODEL_PROPERTY_LERPFRAC)
-       {
-               self.csqcmodel_lerpfrac = self.lerpfrac;
-               self.csqcmodel_lerpfractime = time;
-       }
-#else
-       if(sf & CSQCMODEL_PROPERTY_FRAME)
-       {
-               self.frame1time = time;
-       }
-#endif
-}
-
-void CSQCModel_InterpolateAnimation_Do()
-{
-#ifdef CSQCMODEL_HAVE_TWO_FRAMES
-       if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0))
-       {
-               self.lerpfrac = self.csqcmodel_lerpfrac;
-               self.lerpfrac3 = 0;
-               self.lerpfrac4 = 0;
-       }
-       else
-       {
-               float l13, l24, llf;
-               float l24_13;
-
-               if(self.frame3time == 0) // if frame1/3 were not previously displayed, only frame1 can make sense
-                       l13 = 1;
-               else
-                       l13 = bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
-
-               if(self.frame4time == 0) // if frame2/4 were not previously displayed, only frame2 can make sense
-                       l24 = 1;
-               else
-                       l24 = bound(0, (time - self.frame2time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
-
-               if(self.csqcmodel_lerpfrac2time == 0) // if there is no old lerpfrac (newly displayed model), only lerpfrac makes sense
-                       llf = 1;
-               else
-                       llf = bound(0, (time - self.csqcmodel_lerpfractime) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
-
-               l24_13 = self.csqcmodel_lerpfrac * llf + self.csqcmodel_lerpfrac2 * (1 - llf);
-
-               self.lerpfrac  = l24 * l24_13;
-               self.lerpfrac4 = (1 - l24) * l24_13;
-               self.lerpfrac3 = (1 - l13) * (1 - l24_13);
-
-               if(l24_13 == 0) // if frames 2/4 are not displayed, clear their frametime
-               {
-                       self.frame2time = 0;
-                       self.frame4time = 0;
-               }
-
-               if(l24_13 == 1) // if frames 1/3 are not displayed, clear their frametime
-               {
-                       self.frame1time = 0;
-                       self.frame3time = 0;
-               }
-       }
-#else
-       if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0))
-       {
-               self.lerpfrac = 0;
-       }
-       else
-       {
-               self.lerpfrac = 1 - bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
-       }
-#endif
-}
-
-void CSQCModel_Draw()
-{
-       // some nice flags for CSQCMODEL_IF and the hooks
-       float isplayer = (self.entnum >= 1 && self.entnum <= maxclients);
-       float islocalplayer = (self.entnum == player_localnum + 1);
-       float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
-
-       // we don't do this for the local player as that one is already handled
-       // by CSQCPlayer_SetCamera()
-       if(!CSQCPlayer_IsLocalPlayer())
-               InterpolateOrigin_Do();
-
-       // TODO csqcplayers: run prediction here too
-       CSQCModel_InterpolateAnimation_Do();
-
-       { CSQCMODEL_HOOK_PREDRAW }
-
-       // inherit draw flags easily
-       entity root = self;
-       while(root.tag_entity)
-               root = root.tag_entity;
-       if(self != root)
-       {
-               self.renderflags &~= RF_EXTERNALMODEL | RF_VIEWMODEL;
-               self.renderflags |= (root.renderflags & (RF_EXTERNALMODEL | RF_VIEWMODEL));
-       }
-
-       // we're drawn, now teleporting is over
-       self.csqcmodel_teleported = 0;
-}
-
-void CSQCModel_Read()
-{
-       float sf;
-       sf = ReadShort();
-
-       // some nice flags for CSQCMODEL_IF and the hooks
-       float isplayer = (self.entnum >= 1 && self.entnum <= maxclients);
-       float islocalplayer = (self.entnum == player_localnum + 1);
-       float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
-
-       self.iflags |= IFLAG_ANGLES; // interpolate angles too
-
-       { CSQCMODEL_HOOK_PREUPDATE }
-
-       CSQCPlayer_PreUpdate();
-       InterpolateOrigin_Undo();
-       CSQCModel_InterpolateAnimation_PreNote(sf);
-
-#define CSQCMODEL_IF(cond) if(cond) {
-#define CSQCMODEL_ENDIF }
-#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
-       if(sf & flag) \
-               self.f = r();
-#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \
-       if(sf & flag) \
-               self.f = r() / s;
-       ALLPROPERTIES
-#undef CSQCMODEL_PROPERTY_SCALED
-#undef CSQCMODEL_PROPERTY
-#undef CSQCMODEL_ENDIF
-#undef CSQCMODEL_IF
-
-       if(sf & CSQCMODEL_PROPERTY_MODELINDEX)
-               setmodelindex(self, self.modelindex); // this retrieves the .model key and sets mins/maxs/absmin/absmax
-
-       if(sf & CSQCMODEL_PROPERTY_TELEPORTED)
-       {
-               self.iflags |= IFLAG_TELEPORTED;
-               self.csqcmodel_teleported = 1;
-       }
-       
-       CSQCModel_InterpolateAnimation_Note(sf);
-       InterpolateOrigin_Note();
-       CSQCPlayer_PostUpdate();
-
-       { CSQCMODEL_HOOK_POSTUPDATE }
-
-#ifdef CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW
-       InterpolateOrigin_Do();
-       CSQCModel_InterpolateAnimation_Do();
-#endif
-
-       // relink
-       setorigin(self, self.origin);
-
-       // set obvious render flags
-#ifdef COMPAT_XON050_ENGINE
-       if(self.entnum == player_localentnum || self.entnum == spectatee_status)
-#else
-       if(self.entnum == player_localentnum)
-#endif
-               self.renderflags |= RF_EXTERNALMODEL;
-       else
-               self.renderflags &~= RF_EXTERNALMODEL;
-
-       // draw it
-       self.drawmask = MASK_NORMAL;
-       self.predraw = CSQCModel_Draw;
-}
-
-entity CSQCModel_server2csqc(float pl)
-{
-       return findfloat(world, entnum, pl); // FIXME optimize this using an array
-}
diff --git a/qcsrc/csqcmodel/cl_model.qh b/qcsrc/csqcmodel/cl_model.qh
deleted file mode 100644 (file)
index d386565..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-void CSQCModel_Read();
-
-#define CSQCMODEL_IF(cond)
-#define CSQCMODEL_ENDIF
-#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
-       .t f;
-#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f)
-       ALLPROPERTIES
-#undef CSQCMODEL_PROPERTY_SCALED
-#undef CSQCMODEL_PROPERTY
-#undef CSQCMODEL_ENDIF
-#undef CSQCMODEL_IF
-
-entity CSQCModel_server2csqc(float pl);
-.float csqcmodel_teleported;
diff --git a/qcsrc/csqcmodel/cl_player.qc b/qcsrc/csqcmodel/cl_player.qc
deleted file mode 100644 (file)
index 9c62bbc..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-var float autocvar_cl_predictionerrorcompensation = 0;
-
-// engine stuff
-.float pmove_flags;
-float pmove_onground; // weird engine flag we shouldn't really use but have to for now
-#define PMF_JUMP_HELD 1
-#define PMF_DUCKED 4
-#define PMF_ONGROUND 8
-#define REFDEFFLAG_TELEPORTED 1
-#define REFDEFFLAG_JUMPING 2
-
-entity csqcplayer;
-vector csqcplayer_origin, csqcplayer_velocity;
-float csqcplayer_sequence, player_pmflags;
-float csqcplayer_moveframe;
-vector csqcplayer_predictionerror;
-float csqcplayer_predictionerrortime;
-
-vector CSQCPlayer_GetPredictionError()
-{
-       if(!autocvar_cl_predictionerrorcompensation)
-               return '0 0 0';
-       if(time < csqcplayer_predictionerrortime)
-               return csqcplayer_predictionerror * (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation;
-       return '0 0 0';
-}
-
-void CSQCPlayer_SetPredictionError(vector v)
-{
-       if(!autocvar_cl_predictionerrorcompensation)
-               return;
-       csqcplayer_predictionerror = (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation * csqcplayer_predictionerror + v;
-       csqcplayer_predictionerrortime = time + 1.0 / autocvar_cl_predictionerrorcompensation;
-}
-
-void CSQCPlayer_Unpredict()
-{
-       if(csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED)
-               return;
-       if(csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED)
-               error("Cannot unpredict in current status");
-       self.origin = csqcplayer_origin;
-       self.velocity = csqcplayer_velocity;
-       csqcplayer_moveframe = csqcplayer_sequence+1; //+1 because the recieved frame has the move already done (server side)
-       self.pmove_flags = player_pmflags;
-}
-
-void CSQCPlayer_SetMinsMaxs()
-{
-       if(self.pmove_flags & PMF_DUCKED)
-       {
-               self.mins = PL_CROUCH_MIN;
-               self.maxs = PL_CROUCH_MAX;
-               self.view_ofs = PL_CROUCH_VIEW_OFS;
-       }
-       else
-       {
-               self.mins = PL_MIN;
-               self.maxs = PL_MAX;
-               self.view_ofs = PL_VIEW_OFS;
-       }
-}
-
-void CSQCPlayer_SavePrediction()
-{
-       player_pmflags = self.pmove_flags;
-       csqcplayer_origin = self.origin;
-       csqcplayer_velocity = self.velocity;
-       csqcplayer_sequence = servercommandframe;
-       csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
-}
-
-void CSQCPlayer_PredictTo(float endframe)
-{
-       CSQCPlayer_Unpredict();
-       CSQCPlayer_SetMinsMaxs();
-
-       csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
-
-       if (getstatf(STAT_HEALTH) <= 0)
-       {
-               csqcplayer_moveframe = clientcommandframe;
-               getinputstate(csqcplayer_moveframe-1);
-               return;
-       }
-
-       while(csqcplayer_moveframe < endframe)
-       {
-               if (!getinputstate(csqcplayer_moveframe))
-               {
-                       break;
-               }
-               if(input_timelength <= 0.0005) // too short move
-               {
-                       dprint("CSQC physics hack: too short frame skipped\n");
-                       // even if not running physics, handle releasing the jump key
-                       if(!(input_buttons & 4))
-                               self.pmove_flags &~= PMF_JUMP_HELD;
-               }
-               else if(input_timelength > 0.05) // too long move
-               {
-                       dprint("CSQC physics hack: too long frame split in two\n");
-                       input_timelength *= 0.5;
-                       runstandardplayerphysics(self);
-                       CSQCPlayer_SetMinsMaxs();
-                       runstandardplayerphysics(self);
-                       CSQCPlayer_SetMinsMaxs();
-               }
-               else
-               {
-                       runstandardplayerphysics(self);
-                       CSQCPlayer_SetMinsMaxs();
-               }
-               csqcplayer_moveframe++;
-       }
-
-       //add in anything that was applied after (for low packet rate protocols)
-       input_angles = view_angles;
-}
-
-float CSQCPlayer_IsLocalPlayer()
-{
-       return (self == csqcplayer);
-}
-
-void(entity e, float fl) V_CalcRefdef = #640; // DP_CSQC_V_CALCREFDEF
-
-void CSQCPlayer_SetCamera()
-{
-       if(csqcplayer)
-       {
-               entity oldself;
-               oldself = self;
-               self = csqcplayer;
-
-#ifdef COMPAT_XON050_ENGINE
-               if(servercommandframe == 0 || !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1")))
-#else
-               if(servercommandframe == 0)
-#endif
-               {
-                       InterpolateOrigin_Do();
-                       self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
-
-                       // get crouch state from the server
-                       if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
-                               self.pmove_flags &~= PMF_DUCKED;
-                       else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
-                               self.pmove_flags |= PMF_DUCKED;
-
-                       // get onground state from the server
-                       if(pmove_onground)
-                               self.pmove_flags |= PMF_ONGROUND;
-                       else
-                               self.pmove_flags &~= PMF_ONGROUND;
-
-                       CSQCPlayer_SetMinsMaxs();
-
-                       // override it back just in case
-                       self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
-               }
-               else
-               {
-                       if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER)
-                       {
-                               vector o, v;
-                               o = self.origin;
-                               v = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
-                               csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
-                               CSQCPlayer_PredictTo(servercommandframe + 1);
-                               CSQCPlayer_SetPredictionError(o - self.origin);
-                               self.origin = o;
-                               self.velocity = v;
-
-                               // get crouch state from the server
-                               if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
-                                       self.pmove_flags &~= PMF_DUCKED;
-                               else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
-                                       self.pmove_flags |= PMF_DUCKED;
-
-                               // get onground state from the server
-                               if(pmove_onground)
-                                       self.pmove_flags |= PMF_ONGROUND;
-                               else
-                                       self.pmove_flags &~= PMF_ONGROUND;
-
-                               CSQCPlayer_SavePrediction();
-                       }
-                       CSQCPlayer_PredictTo(clientcommandframe + 1);
-
-                       CSQCPlayer_SetMinsMaxs();
-
-                       self.angles_y = input_angles_y;
-               }
-
-               // relink
-               setorigin(self, self.origin);
-
-               self = oldself;
-       }
-
-       entity view;
-#ifdef COMPAT_XON050_ENGINE
-       view = CSQCModel_server2csqc((spectatee_status > 0) ? spectatee_status : player_localentnum);
-#else
-       view = CSQCModel_server2csqc(player_localentnum);
-#endif
-
-#ifdef COMPAT_XON050_ENGINE
-       if(view && !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1")))
-       {
-               // legacy code, not totally correct, but good enough for not having V_CalcRefdef
-               setproperty(VF_ORIGIN, view.origin + '0 0 1' * getstati(STAT_VIEWHEIGHT));
-               setproperty(VF_ANGLES, view_angles);
-       }
-       else
-#endif
-       if(view)
-       {
-               var float refdefflags = 0;
-
-               if(view.csqcmodel_teleported)
-                       refdefflags |= REFDEFFLAG_TELEPORTED;
-
-               if(input_buttons & 4)
-                       refdefflags |= REFDEFFLAG_JUMPING;
-
-               V_CalcRefdef(view, refdefflags);
-       }
-       else
-       {
-               setproperty(VF_ORIGIN, pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT));
-               setproperty(VF_ANGLES, view_angles);
-       }
-
-       { CSQCPLAYER_HOOK_POSTCAMERASETUP }
-}
-
-void CSQCPlayer_Remove()
-{
-       if(self.entnum != player_localnum + 1)
-               return;
-       csqcplayer = world;
-       cvar_clientsettemp("cl_movement_replay", "1");
-}
-
-float CSQCPlayer_PreUpdate()
-{
-       if(self.entnum != player_localnum + 1)
-               return 0;
-       cvar_clientsettemp("cl_movement_replay", "0");
-       if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER)
-               CSQCPlayer_Unpredict();
-       return 1;
-}
-
-float CSQCPlayer_PostUpdate()
-{
-       if(self.entnum != player_localentnum)
-               return 0;
-       csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER;
-       csqcplayer = self;
-       self.entremove = CSQCPlayer_Remove;
-       return 1;
-}
diff --git a/qcsrc/csqcmodel/cl_player.qh b/qcsrc/csqcmodel/cl_player.qh
deleted file mode 100644 (file)
index 0eecabe..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-float csqcplayer_status;
-#define CSQCPLAYERSTATUS_UNPREDICTED 0
-#define CSQCPLAYERSTATUS_FROMSERVER 1
-#define CSQCPLAYERSTATUS_PREDICTED 2
-
-void CSQCPlayer_SetCamera();
-float CSQCPlayer_PreUpdate();
-float CSQCPlayer_PostUpdate();
-float CSQCPlayer_IsLocalPlayer();
diff --git a/qcsrc/csqcmodel/common.qh b/qcsrc/csqcmodel/common.qh
deleted file mode 100644 (file)
index 587645c..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-noref string csqcmodel_license = "\
-Copyright (c) 2011 Rudolf Polzer\
-\
-Permission is hereby granted, free of charge, to any person obtaining a copy\
-of this software and associated documentation files (the \"Software\"), to\
-deal in the Software without restriction, including without limitation the\
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\
-sell copies of the Software, and to permit persons to whom the Software is\
-furnished to do so, subject to the following conditions:\
-\
-The above copyright notice and this permission notice shall be included in\
-all copies or substantial portions of the Software.\
-\
-THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\
-IN THE SOFTWARE.\
-";
-
-.vector glowmod;
-.vector view_ofs;
-.float frame;
-.float frame1time;
-.float frame2;
-.float frame2time;
-.float lerpfrac;
-
-#define CSQCMODEL_PROPERTY_FRAME 32768
-#define CSQCMODEL_PROPERTY_FRAME2 16384
-#define CSQCMODEL_PROPERTY_LERPFRAC 8192
-#define CSQCMODEL_PROPERTY_TELEPORTED 4096 // the "teleport bit" cancelling interpolation
-#define CSQCMODEL_PROPERTY_MODELINDEX 2048
-#define CSQCMODEL_PROPERTY_ORIGIN 1024
-#define CSQCMODEL_PROPERTY_YAW 512
-#define CSQCMODEL_PROPERTY_PITCHROLL 256
-
-#define ALLPROPERTIES_COMMON \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME, float, ReadByte, WriteByte, frame) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_MODELINDEX, float, ReadShort, WriteShort, modelindex) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_x) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_y) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_z) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_x) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_YAW, float, ReadAngle, WriteAngle, angles_y) \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_z) \
-       CSQCMODEL_EXTRAPROPERTIES
-
-#ifdef CSQCMODEL_HAVE_TWO_FRAMES
-.float frame3;
-.float frame3time;
-.float lerpfrac3;
-.float frame4;
-.float frame4time;
-.float lerpfrac4;
-#define ALLPROPERTIES ALLPROPERTIES_COMMON \
-       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME2, float, ReadByte, WriteByte, frame2) \
-       CSQCMODEL_PROPERTY_SCALED(CSQCMODEL_PROPERTY_LERPFRAC, float, ReadByte, WriteByte, lerpfrac, 255, 0, 255)
-#else
-#define ALLPROPERTIES ALLPROPERTIES_COMMON
-#endif
diff --git a/qcsrc/csqcmodel/interpolate.qc b/qcsrc/csqcmodel/interpolate.qc
deleted file mode 100644 (file)
index ac0ba6e..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-.vector iorigin1, iorigin2;
-.vector ivelocity1, ivelocity2;
-.vector iforward1, iforward2;
-.vector iup1, iup2;
-.float itime1, itime2;
-void InterpolateOrigin_Reset()
-{
-       self.iflags &~= IFLAG_INTERNALMASK;
-       self.itime1 = self.itime2 = 0;
-}
-void InterpolateOrigin_Note()
-{
-       float dt;
-       float f0;
-
-       dt = time - self.itime2;
-
-       f0 = self.iflags;
-       if(self.iflags & IFLAG_PREVALID)
-               self.iflags |= IFLAG_VALID;
-       else
-               self.iflags |= IFLAG_PREVALID;
-
-       self.iorigin1 = self.iorigin2;
-       self.iorigin2 = self.origin;
-
-       if(self.iflags & IFLAG_AUTOANGLES)
-               if(self.iorigin2 != self.iorigin1)
-                       self.angles = vectoangles(self.iorigin2 - self.iorigin1);
-
-       if(self.iflags & IFLAG_ANGLES)
-       {
-               fixedmakevectors(self.angles);
-               if(f0 & IFLAG_VALID)
-               {
-                       self.iforward1 = self.iforward2;
-                       self.iup1 = self.iup2;
-               }
-               else
-               {
-                       self.iforward1 = v_forward;
-                       self.iup1 = v_up;
-               }
-               self.iforward2 = v_forward;
-               self.iup2 = v_up;
-       }
-
-       if(self.iflags & IFLAG_VELOCITY)
-       {
-               self.ivelocity1 = self.ivelocity2;
-               self.ivelocity2 = self.velocity;
-       }
-
-       if(self.iflags & IFLAG_TELEPORTED)
-       {
-               self.iflags &~= IFLAG_TELEPORTED;
-               self.itime1 = self.itime2 = time; // don't lerp
-       }
-       else if(vlen(self.iorigin2 - self.iorigin1) > 1000)
-       {
-               self.itime1 = self.itime2 = time; // don't lerp
-       }
-       else if((self.iflags & IFLAG_VELOCITY) && (vlen(self.ivelocity2 - self.ivelocity1) > 1000))
-       {
-               self.itime1 = self.itime2 = time; // don't lerp
-       }
-       else if(dt >= 0.2)
-       {
-               self.itime1 = self.itime2 = time;
-       }
-       else
-       {
-               self.itime1 = serverprevtime;
-               self.itime2 = time;
-       }
-}
-void InterpolateOrigin_Do()
-{
-       vector forward, up;
-       if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
-       {
-               float f;
-               f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1 + autocvar_cl_lerpexcess);
-               self.origin = (1 - f) * self.iorigin1 + f * self.iorigin2;
-               if(self.iflags & IFLAG_ANGLES)
-               {
-                       forward = (1 - f) * self.iforward1 + f * self.iforward2;
-                       up = (1 - f) * self.iup1 + f * self.iup2;
-                       self.angles = fixedvectoangles2(forward, up);
-               }
-               if(self.iflags & IFLAG_VELOCITY)
-                       self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2;
-       }
-}
-void InterpolateOrigin_Undo()
-{
-       self.origin = self.iorigin2;
-       if(self.iflags & IFLAG_ANGLES)
-               self.angles = fixedvectoangles2(self.iforward2, self.iup2);
-       if(self.iflags & IFLAG_VELOCITY)
-               self.velocity = self.ivelocity2;
-}
-
diff --git a/qcsrc/csqcmodel/interpolate.qh b/qcsrc/csqcmodel/interpolate.qh
deleted file mode 100644 (file)
index 8254fae..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-.float iflags;
-#define IFLAG_VELOCITY 1
-#define IFLAG_ANGLES 2
-#define IFLAG_AUTOANGLES 4
-#define IFLAG_VALID 8
-#define IFLAG_PREVALID 16
-#define IFLAG_TELEPORTED 32
-#define IFLAG_INTERNALMASK (IFLAG_VALID | IFLAG_PREVALID)
-
-// call this BEFORE reading an entity update
-void InterpolateOrigin_Undo();
-
-// call this AFTER receiving an entity update
-void InterpolateOrigin_Note();
-
-// call this when the entity got teleported, before InterpolateOrigin_Note
-void InterpolateOrigin_Reset();
-
-// call this BEFORE drawing
-void InterpolateOrigin_Do();
diff --git a/qcsrc/csqcmodel/settings.qh b/qcsrc/csqcmodel/settings.qh
deleted file mode 100644 (file)
index 257676d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// define this if svqc code wants to use .frame2 and .lerpfrac
-#define CSQCMODEL_HAVE_TWO_FRAMES
-
-// don't define this ever
-//#define CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW
-
-// a hack for Xonotic
-#ifdef CSQC
-# define TAG_ENTITY_NAME tag_networkentity
-# define TAG_ENTITY_TYPE float
-.float tag_networkentity;
-#else
-# define TAG_ENTITY_NAME tag_entity
-# define TAG_ENTITY_TYPE entity
-#endif
-
-// add properties you want networked to CSQC here
-#define CSQCMODEL_EXTRAPROPERTIES \
-       CSQCMODEL_PROPERTY(1, float, ReadShort, WriteShort, colormap) \
-       CSQCMODEL_PROPERTY(2, float, ReadInt24_t, WriteInt24_t, effects) \
-       CSQCMODEL_PROPERTY(4, float, ReadByte, WriteByte, modelflags) \
-       CSQCMODEL_PROPERTY_SCALED(8, float, ReadByte, WriteByte, alpha, 255, 0, 255) \
-       CSQCMODEL_PROPERTY(16, float, ReadByte, WriteByte, skin) \
-       CSQCMODEL_IF(isplayer) \
-       CSQCMODEL_ENDIF \
-       CSQCMODEL_IF(!isplayer) \
-               CSQCMODEL_PROPERTY(32, TAG_ENTITY_TYPE, ReadShort, WriteEntity, TAG_ENTITY_NAME) \
-               CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_x, 255, 0, 255) \
-               CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_y, 255, 0, 255) \
-               CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_z, 255, 0, 255) \
-       CSQCMODEL_ENDIF
-// TODO get rid of colormod/glowmod here, find good solution for nex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody
-
-// add hook function calls here
-#define CSQCMODEL_HOOK_PREUPDATE \
-       CSQCModel_Hook_PreUpdate(isplayer, islocalplayer);
-#define CSQCMODEL_HOOK_POSTUPDATE \
-       CSQCModel_Hook_PostUpdate(isplayer, islocalplayer);
-#define CSQCMODEL_HOOK_PREDRAW \
-       CSQCModel_Hook_PreDraw(isplayer, islocalplayer);
-#define CSQCPLAYER_HOOK_POSTCAMERASETUP
-
-#define CSQCPLAYER_FORCE_UPDATES 0.25
-
-// mod must define:
-//vector PL_MIN  = ...;
-//vector PL_MAX  = ...;
-//vector PL_VIEW_OFS  = ...;
-//vector PL_CROUCH_MIN  = ...;
-//vector PL_CROUCH_MAX  = ...;
-//vector PL_CROUCH_VIEW_OFS  = ...;
-
-#ifdef SVQC
-# ifdef NO_LEGACY_NETWORKING
-#  define CSQCMODEL_AUTOINIT() CSQCModel_LinkEntity()
-#  define CSQCMODEL_AUTOUPDATE() CSQCModel_CheckUpdate()
-# else
-.float iscsqcmodel;
-float autocvar_sv_use_csqc_players;
-#  define CSQCMODEL_AUTOINIT() \
-       if(autocvar_sv_use_csqc_players) \
-       { \
-               CSQCModel_LinkEntity(); \
-               self.iscsqcmodel = 1; \
-       } \
-       else \
-               self.iscsqcmodel = 0
-#  define CSQCMODEL_AUTOUPDATE() \
-       if(autocvar_sv_use_csqc_players && !self.iscsqcmodel) \
-       { \
-               CSQCModel_LinkEntity(); \
-               self.iscsqcmodel = 1; \
-       } \
-       if(!autocvar_sv_use_csqc_players && self.iscsqcmodel) \
-       { \
-               CSQCModel_UnlinkEntity(); \
-               self.iscsqcmodel = 0; \
-       } \
-       if(self.iscsqcmodel) \
-               CSQCModel_CheckUpdate()
-# endif
-#endif
-
-#define CSQCMODEL_EF_INVISIBLE EF_SELECTABLE
diff --git a/qcsrc/csqcmodel/sv_model.qc b/qcsrc/csqcmodel/sv_model.qc
deleted file mode 100644 (file)
index 1c214e0..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-// generic CSQC model code
-
-float CSQCModel_Send(entity to, float sf)
-{
-       // some nice flags for CSQCMODEL_IF
-       float isplayer = (self.flags & FL_CLIENT);
-       float islocalplayer = (self == to);
-       float isnolocalplayer = (isplayer && (self != to));
-
-       WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL);
-       WriteShort(MSG_ENTITY, sf);
-
-#define CSQCMODEL_IF(cond) if(cond) {
-#define CSQCMODEL_ENDIF }
-#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
-       if(sf & flag) \
-       { \
-               w(MSG_ENTITY, self.csqcmodel_##f); \
-       }
-#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f)
-       ALLPROPERTIES
-#undef CSQCMODEL_PROPERTY_SCALED
-#undef CSQCMODEL_PROPERTY
-#undef CSQCMODEL_ENDIF
-#undef CSQCMODEL_IF
-
-       return TRUE;
-}
-
-#ifdef CSQCPLAYER_FORCE_UPDATES
-.float csqcmodel_nextforcedupdate;
-#endif
-void CSQCModel_CheckUpdate()
-{
-       // some nice flags for CSQCMODEL_IF
-       float isplayer = (self.flags & FL_CLIENT);
-       float islocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags
-       float isnolocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags
-
-#ifdef CSQCPLAYER_FORCE_UPDATES
-       if(isplayer && time > self.csqcmodel_nextforcedupdate)
-       {
-               self.SendFlags |= CSQCMODEL_PROPERTY_ORIGIN;
-               self.csqcmodel_nextforcedupdate = time + CSQCPLAYER_FORCE_UPDATES * (0.5 + random()); // ensure about 4 origin sends per sec
-       }
-#endif
-
-       if(self.effects & EF_RESTARTANIM_BIT)
-       {
-               self.SendFlags |= CSQCMODEL_PROPERTY_FRAME | CSQCMODEL_PROPERTY_FRAME2; // full anim resend please
-               self.effects &~= EF_RESTARTANIM_BIT;
-       }
-
-       if(self.effects & EF_TELEPORT_BIT)
-       {
-               self.SendFlags |= CSQCMODEL_PROPERTY_TELEPORTED; // no interpolation please
-               self.effects &~= EF_TELEPORT_BIT;
-       }
-
-#define CSQCMODEL_IF(cond) if(cond) {
-#define CSQCMODEL_ENDIF }
-#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
-       { \
-               t tmp = self.f; \
-               if(tmp != self.csqcmodel_##f) \
-               { \
-                       self.csqcmodel_##f = tmp; \
-                       self.SendFlags |= flag; \
-               } \
-       }
-#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \
-       { \
-               t tmp = bound(mi, s * self.f, ma); \
-               if(tmp != self.csqcmodel_##f) \
-               { \
-                       self.csqcmodel_##f = tmp; \
-                       self.SendFlags |= flag; \
-               } \
-       }
-       ALLPROPERTIES
-#undef CSQCMODEL_PROPERTY_SCALED
-#undef CSQCMODEL_PROPERTY
-#undef CSQCMODEL_ENDIF
-#undef CSQCMODEL_IF
-}
-
-void CSQCModel_LinkEntity()
-{
-       self.SendEntity = CSQCModel_Send;
-       self.SendFlags = 0xFFFFFF;
-}
-
-void CSQCModel_UnlinkEntity()
-{
-       self.SendEntity = func_null;
-}
diff --git a/qcsrc/csqcmodel/sv_model.qh b/qcsrc/csqcmodel/sv_model.qh
deleted file mode 100644 (file)
index 3c4ce2b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2011 Rudolf Polzer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-// generic CSQC model code
-
-void CSQCModel_CheckUpdate();
-void CSQCModel_LinkEntity();
-void CSQCModel_UnlinkEntity();
-
-#define CSQCMODEL_IF(cond)
-#define CSQCMODEL_ENDIF
-#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
-       .t f; \
-       .t csqcmodel_##f;
-#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f)
-       ALLPROPERTIES
-#undef CSQCMODEL_PROPERTY_SCALED
-#undef CSQCMODEL_PROPERTY
-#undef CSQCMODEL_ENDIF
-#undef CSQCMODEL_IF
diff --git a/qcsrc/csqcmodellib/cl_model.qc b/qcsrc/csqcmodellib/cl_model.qc
new file mode 100644 (file)
index 0000000..0322661
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+var float autocvar_cl_lerpanim_maxdelta_framegroups = 0.1;
+var float autocvar_cl_nolerp = 0;
+
+.float csqcmodel_lerpfrac;
+.float csqcmodel_lerpfrac2;
+.float csqcmodel_lerpfractime;
+.float csqcmodel_lerpfrac2time;
+
+void CSQCModel_InterpolateAnimation_PreNote(float sf)
+{
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
+       {
+               self.frame3 = self.frame;
+               self.frame3time = self.frame1time;
+       }
+       if(sf & CSQCMODEL_PROPERTY_FRAME2)
+       {
+               self.frame4 = self.frame2;
+               self.frame4time = self.frame2time;
+       }
+       if(sf & CSQCMODEL_PROPERTY_LERPFRAC)
+       {
+               self.csqcmodel_lerpfrac2 = self.csqcmodel_lerpfrac;
+               self.csqcmodel_lerpfrac2time = self.csqcmodel_lerpfractime;
+               self.lerpfrac = self.csqcmodel_lerpfrac;
+       }
+#else
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
+       {
+               self.frame2 = self.frame;
+               self.frame2time = self.frame1time;
+       }
+#endif
+}
+
+void CSQCModel_InterpolateAnimation_Note(float sf)
+{
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
+       {
+               self.frame1time = time;
+       }
+       if(sf & CSQCMODEL_PROPERTY_FRAME2)
+       {
+               self.frame2time = time;
+       }
+       if(sf & CSQCMODEL_PROPERTY_LERPFRAC)
+       {
+               self.csqcmodel_lerpfrac = self.lerpfrac;
+               self.csqcmodel_lerpfractime = time;
+       }
+#else
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
+       {
+               self.frame1time = time;
+       }
+#endif
+}
+
+void CSQCModel_InterpolateAnimation_Do()
+{
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
+       if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0))
+       {
+               self.lerpfrac = self.csqcmodel_lerpfrac;
+               self.lerpfrac3 = 0;
+               self.lerpfrac4 = 0;
+       }
+       else
+       {
+               float l13, l24, llf;
+               float l24_13;
+
+               if(self.frame3time == 0) // if frame1/3 were not previously displayed, only frame1 can make sense
+                       l13 = 1;
+               else
+                       l13 = bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
+
+               if(self.frame4time == 0) // if frame2/4 were not previously displayed, only frame2 can make sense
+                       l24 = 1;
+               else
+                       l24 = bound(0, (time - self.frame2time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
+
+               if(self.csqcmodel_lerpfrac2time == 0) // if there is no old lerpfrac (newly displayed model), only lerpfrac makes sense
+                       llf = 1;
+               else
+                       llf = bound(0, (time - self.csqcmodel_lerpfractime) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
+
+               l24_13 = self.csqcmodel_lerpfrac * llf + self.csqcmodel_lerpfrac2 * (1 - llf);
+
+               self.lerpfrac  = l24 * l24_13;
+               self.lerpfrac4 = (1 - l24) * l24_13;
+               self.lerpfrac3 = (1 - l13) * (1 - l24_13);
+
+               if(l24_13 == 0) // if frames 2/4 are not displayed, clear their frametime
+               {
+                       self.frame2time = 0;
+                       self.frame4time = 0;
+               }
+
+               if(l24_13 == 1) // if frames 1/3 are not displayed, clear their frametime
+               {
+                       self.frame1time = 0;
+                       self.frame3time = 0;
+               }
+       }
+#else
+       if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0))
+       {
+               self.lerpfrac = 0;
+       }
+       else
+       {
+               self.lerpfrac = 1 - bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1);
+       }
+#endif
+}
+
+void CSQCModel_Draw()
+{
+       // some nice flags for CSQCMODEL_IF and the hooks
+       float isplayer = (self.entnum >= 1 && self.entnum <= maxclients);
+       float islocalplayer = (self.entnum == player_localnum + 1);
+       float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
+
+       // we don't do this for the local player as that one is already handled
+       // by CSQCPlayer_SetCamera()
+       if(!CSQCPlayer_IsLocalPlayer())
+               InterpolateOrigin_Do();
+
+       // TODO csqcplayers: run prediction here too
+       CSQCModel_InterpolateAnimation_Do();
+
+       { CSQCMODEL_HOOK_PREDRAW }
+
+       // inherit draw flags easily
+       entity root = self;
+       while(root.tag_entity)
+               root = root.tag_entity;
+       if(self != root)
+       {
+               self.renderflags &~= RF_EXTERNALMODEL | RF_VIEWMODEL;
+               self.renderflags |= (root.renderflags & (RF_EXTERNALMODEL | RF_VIEWMODEL));
+       }
+
+       // we're drawn, now teleporting is over
+       self.csqcmodel_teleported = 0;
+}
+
+void CSQCModel_Read()
+{
+       float sf;
+       sf = ReadShort();
+
+       // some nice flags for CSQCMODEL_IF and the hooks
+       float isplayer = (self.entnum >= 1 && self.entnum <= maxclients);
+       float islocalplayer = (self.entnum == player_localnum + 1);
+       float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1));
+
+       self.iflags |= IFLAG_ANGLES; // interpolate angles too
+
+       { CSQCMODEL_HOOK_PREUPDATE }
+
+       CSQCPlayer_PreUpdate();
+       InterpolateOrigin_Undo();
+       CSQCModel_InterpolateAnimation_PreNote(sf);
+
+#define CSQCMODEL_IF(cond) if(cond) {
+#define CSQCMODEL_ENDIF }
+#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
+       if(sf & flag) \
+               self.f = r();
+#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \
+       if(sf & flag) \
+               self.f = r() / s;
+       ALLPROPERTIES
+#undef CSQCMODEL_PROPERTY_SCALED
+#undef CSQCMODEL_PROPERTY
+#undef CSQCMODEL_ENDIF
+#undef CSQCMODEL_IF
+
+       if(sf & CSQCMODEL_PROPERTY_MODELINDEX)
+               setmodelindex(self, self.modelindex); // this retrieves the .model key and sets mins/maxs/absmin/absmax
+
+       if(sf & CSQCMODEL_PROPERTY_TELEPORTED)
+       {
+               self.iflags |= IFLAG_TELEPORTED;
+               self.csqcmodel_teleported = 1;
+       }
+       
+       CSQCModel_InterpolateAnimation_Note(sf);
+       InterpolateOrigin_Note();
+       CSQCPlayer_PostUpdate();
+
+       { CSQCMODEL_HOOK_POSTUPDATE }
+
+#ifdef CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW
+       InterpolateOrigin_Do();
+       CSQCModel_InterpolateAnimation_Do();
+#endif
+
+       // relink
+       setorigin(self, self.origin);
+
+       // set obvious render flags
+#ifdef COMPAT_XON050_ENGINE
+       if(self.entnum == player_localentnum || self.entnum == spectatee_status)
+#else
+       if(self.entnum == player_localentnum)
+#endif
+               self.renderflags |= RF_EXTERNALMODEL;
+       else
+               self.renderflags &~= RF_EXTERNALMODEL;
+
+       // draw it
+       self.drawmask = MASK_NORMAL;
+       self.predraw = CSQCModel_Draw;
+}
+
+entity CSQCModel_server2csqc(float pl)
+{
+       return findfloat(world, entnum, pl); // FIXME optimize this using an array
+}
diff --git a/qcsrc/csqcmodellib/cl_model.qh b/qcsrc/csqcmodellib/cl_model.qh
new file mode 100644 (file)
index 0000000..d386565
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+void CSQCModel_Read();
+
+#define CSQCMODEL_IF(cond)
+#define CSQCMODEL_ENDIF
+#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
+       .t f;
+#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f)
+       ALLPROPERTIES
+#undef CSQCMODEL_PROPERTY_SCALED
+#undef CSQCMODEL_PROPERTY
+#undef CSQCMODEL_ENDIF
+#undef CSQCMODEL_IF
+
+entity CSQCModel_server2csqc(float pl);
+.float csqcmodel_teleported;
diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc
new file mode 100644 (file)
index 0000000..9c62bbc
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+var float autocvar_cl_predictionerrorcompensation = 0;
+
+// engine stuff
+.float pmove_flags;
+float pmove_onground; // weird engine flag we shouldn't really use but have to for now
+#define PMF_JUMP_HELD 1
+#define PMF_DUCKED 4
+#define PMF_ONGROUND 8
+#define REFDEFFLAG_TELEPORTED 1
+#define REFDEFFLAG_JUMPING 2
+
+entity csqcplayer;
+vector csqcplayer_origin, csqcplayer_velocity;
+float csqcplayer_sequence, player_pmflags;
+float csqcplayer_moveframe;
+vector csqcplayer_predictionerror;
+float csqcplayer_predictionerrortime;
+
+vector CSQCPlayer_GetPredictionError()
+{
+       if(!autocvar_cl_predictionerrorcompensation)
+               return '0 0 0';
+       if(time < csqcplayer_predictionerrortime)
+               return csqcplayer_predictionerror * (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation;
+       return '0 0 0';
+}
+
+void CSQCPlayer_SetPredictionError(vector v)
+{
+       if(!autocvar_cl_predictionerrorcompensation)
+               return;
+       csqcplayer_predictionerror = (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation * csqcplayer_predictionerror + v;
+       csqcplayer_predictionerrortime = time + 1.0 / autocvar_cl_predictionerrorcompensation;
+}
+
+void CSQCPlayer_Unpredict()
+{
+       if(csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED)
+               return;
+       if(csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED)
+               error("Cannot unpredict in current status");
+       self.origin = csqcplayer_origin;
+       self.velocity = csqcplayer_velocity;
+       csqcplayer_moveframe = csqcplayer_sequence+1; //+1 because the recieved frame has the move already done (server side)
+       self.pmove_flags = player_pmflags;
+}
+
+void CSQCPlayer_SetMinsMaxs()
+{
+       if(self.pmove_flags & PMF_DUCKED)
+       {
+               self.mins = PL_CROUCH_MIN;
+               self.maxs = PL_CROUCH_MAX;
+               self.view_ofs = PL_CROUCH_VIEW_OFS;
+       }
+       else
+       {
+               self.mins = PL_MIN;
+               self.maxs = PL_MAX;
+               self.view_ofs = PL_VIEW_OFS;
+       }
+}
+
+void CSQCPlayer_SavePrediction()
+{
+       player_pmflags = self.pmove_flags;
+       csqcplayer_origin = self.origin;
+       csqcplayer_velocity = self.velocity;
+       csqcplayer_sequence = servercommandframe;
+       csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
+}
+
+void CSQCPlayer_PredictTo(float endframe)
+{
+       CSQCPlayer_Unpredict();
+       CSQCPlayer_SetMinsMaxs();
+
+       csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
+
+       if (getstatf(STAT_HEALTH) <= 0)
+       {
+               csqcplayer_moveframe = clientcommandframe;
+               getinputstate(csqcplayer_moveframe-1);
+               return;
+       }
+
+       while(csqcplayer_moveframe < endframe)
+       {
+               if (!getinputstate(csqcplayer_moveframe))
+               {
+                       break;
+               }
+               if(input_timelength <= 0.0005) // too short move
+               {
+                       dprint("CSQC physics hack: too short frame skipped\n");
+                       // even if not running physics, handle releasing the jump key
+                       if(!(input_buttons & 4))
+                               self.pmove_flags &~= PMF_JUMP_HELD;
+               }
+               else if(input_timelength > 0.05) // too long move
+               {
+                       dprint("CSQC physics hack: too long frame split in two\n");
+                       input_timelength *= 0.5;
+                       runstandardplayerphysics(self);
+                       CSQCPlayer_SetMinsMaxs();
+                       runstandardplayerphysics(self);
+                       CSQCPlayer_SetMinsMaxs();
+               }
+               else
+               {
+                       runstandardplayerphysics(self);
+                       CSQCPlayer_SetMinsMaxs();
+               }
+               csqcplayer_moveframe++;
+       }
+
+       //add in anything that was applied after (for low packet rate protocols)
+       input_angles = view_angles;
+}
+
+float CSQCPlayer_IsLocalPlayer()
+{
+       return (self == csqcplayer);
+}
+
+void(entity e, float fl) V_CalcRefdef = #640; // DP_CSQC_V_CALCREFDEF
+
+void CSQCPlayer_SetCamera()
+{
+       if(csqcplayer)
+       {
+               entity oldself;
+               oldself = self;
+               self = csqcplayer;
+
+#ifdef COMPAT_XON050_ENGINE
+               if(servercommandframe == 0 || !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1")))
+#else
+               if(servercommandframe == 0)
+#endif
+               {
+                       InterpolateOrigin_Do();
+                       self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+
+                       // get crouch state from the server
+                       if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
+                               self.pmove_flags &~= PMF_DUCKED;
+                       else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
+                               self.pmove_flags |= PMF_DUCKED;
+
+                       // get onground state from the server
+                       if(pmove_onground)
+                               self.pmove_flags |= PMF_ONGROUND;
+                       else
+                               self.pmove_flags &~= PMF_ONGROUND;
+
+                       CSQCPlayer_SetMinsMaxs();
+
+                       // override it back just in case
+                       self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+               }
+               else
+               {
+                       if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER)
+                       {
+                               vector o, v;
+                               o = self.origin;
+                               v = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity
+                               csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED;
+                               CSQCPlayer_PredictTo(servercommandframe + 1);
+                               CSQCPlayer_SetPredictionError(o - self.origin);
+                               self.origin = o;
+                               self.velocity = v;
+
+                               // get crouch state from the server
+                               if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z)
+                                       self.pmove_flags &~= PMF_DUCKED;
+                               else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z)
+                                       self.pmove_flags |= PMF_DUCKED;
+
+                               // get onground state from the server
+                               if(pmove_onground)
+                                       self.pmove_flags |= PMF_ONGROUND;
+                               else
+                                       self.pmove_flags &~= PMF_ONGROUND;
+
+                               CSQCPlayer_SavePrediction();
+                       }
+                       CSQCPlayer_PredictTo(clientcommandframe + 1);
+
+                       CSQCPlayer_SetMinsMaxs();
+
+                       self.angles_y = input_angles_y;
+               }
+
+               // relink
+               setorigin(self, self.origin);
+
+               self = oldself;
+       }
+
+       entity view;
+#ifdef COMPAT_XON050_ENGINE
+       view = CSQCModel_server2csqc((spectatee_status > 0) ? spectatee_status : player_localentnum);
+#else
+       view = CSQCModel_server2csqc(player_localentnum);
+#endif
+
+#ifdef COMPAT_XON050_ENGINE
+       if(view && !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1")))
+       {
+               // legacy code, not totally correct, but good enough for not having V_CalcRefdef
+               setproperty(VF_ORIGIN, view.origin + '0 0 1' * getstati(STAT_VIEWHEIGHT));
+               setproperty(VF_ANGLES, view_angles);
+       }
+       else
+#endif
+       if(view)
+       {
+               var float refdefflags = 0;
+
+               if(view.csqcmodel_teleported)
+                       refdefflags |= REFDEFFLAG_TELEPORTED;
+
+               if(input_buttons & 4)
+                       refdefflags |= REFDEFFLAG_JUMPING;
+
+               V_CalcRefdef(view, refdefflags);
+       }
+       else
+       {
+               setproperty(VF_ORIGIN, pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT));
+               setproperty(VF_ANGLES, view_angles);
+       }
+
+       { CSQCPLAYER_HOOK_POSTCAMERASETUP }
+}
+
+void CSQCPlayer_Remove()
+{
+       if(self.entnum != player_localnum + 1)
+               return;
+       csqcplayer = world;
+       cvar_clientsettemp("cl_movement_replay", "1");
+}
+
+float CSQCPlayer_PreUpdate()
+{
+       if(self.entnum != player_localnum + 1)
+               return 0;
+       cvar_clientsettemp("cl_movement_replay", "0");
+       if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER)
+               CSQCPlayer_Unpredict();
+       return 1;
+}
+
+float CSQCPlayer_PostUpdate()
+{
+       if(self.entnum != player_localentnum)
+               return 0;
+       csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER;
+       csqcplayer = self;
+       self.entremove = CSQCPlayer_Remove;
+       return 1;
+}
diff --git a/qcsrc/csqcmodellib/cl_player.qh b/qcsrc/csqcmodellib/cl_player.qh
new file mode 100644 (file)
index 0000000..0eecabe
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+float csqcplayer_status;
+#define CSQCPLAYERSTATUS_UNPREDICTED 0
+#define CSQCPLAYERSTATUS_FROMSERVER 1
+#define CSQCPLAYERSTATUS_PREDICTED 2
+
+void CSQCPlayer_SetCamera();
+float CSQCPlayer_PreUpdate();
+float CSQCPlayer_PostUpdate();
+float CSQCPlayer_IsLocalPlayer();
diff --git a/qcsrc/csqcmodellib/common.qh b/qcsrc/csqcmodellib/common.qh
new file mode 100644 (file)
index 0000000..587645c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+noref string csqcmodel_license = "\
+Copyright (c) 2011 Rudolf Polzer\
+\
+Permission is hereby granted, free of charge, to any person obtaining a copy\
+of this software and associated documentation files (the \"Software\"), to\
+deal in the Software without restriction, including without limitation the\
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\
+sell copies of the Software, and to permit persons to whom the Software is\
+furnished to do so, subject to the following conditions:\
+\
+The above copyright notice and this permission notice shall be included in\
+all copies or substantial portions of the Software.\
+\
+THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\
+IN THE SOFTWARE.\
+";
+
+.vector glowmod;
+.vector view_ofs;
+.float frame;
+.float frame1time;
+.float frame2;
+.float frame2time;
+.float lerpfrac;
+
+#define CSQCMODEL_PROPERTY_FRAME 32768
+#define CSQCMODEL_PROPERTY_FRAME2 16384
+#define CSQCMODEL_PROPERTY_LERPFRAC 8192
+#define CSQCMODEL_PROPERTY_TELEPORTED 4096 // the "teleport bit" cancelling interpolation
+#define CSQCMODEL_PROPERTY_MODELINDEX 2048
+#define CSQCMODEL_PROPERTY_ORIGIN 1024
+#define CSQCMODEL_PROPERTY_YAW 512
+#define CSQCMODEL_PROPERTY_PITCHROLL 256
+
+#define ALLPROPERTIES_COMMON \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME, float, ReadByte, WriteByte, frame) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_MODELINDEX, float, ReadShort, WriteShort, modelindex) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_x) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_y) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_z) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_x) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_YAW, float, ReadAngle, WriteAngle, angles_y) \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_z) \
+       CSQCMODEL_EXTRAPROPERTIES
+
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
+.float frame3;
+.float frame3time;
+.float lerpfrac3;
+.float frame4;
+.float frame4time;
+.float lerpfrac4;
+#define ALLPROPERTIES ALLPROPERTIES_COMMON \
+       CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME2, float, ReadByte, WriteByte, frame2) \
+       CSQCMODEL_PROPERTY_SCALED(CSQCMODEL_PROPERTY_LERPFRAC, float, ReadByte, WriteByte, lerpfrac, 255, 0, 255)
+#else
+#define ALLPROPERTIES ALLPROPERTIES_COMMON
+#endif
diff --git a/qcsrc/csqcmodellib/interpolate.qc b/qcsrc/csqcmodellib/interpolate.qc
new file mode 100644 (file)
index 0000000..ac0ba6e
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+.vector iorigin1, iorigin2;
+.vector ivelocity1, ivelocity2;
+.vector iforward1, iforward2;
+.vector iup1, iup2;
+.float itime1, itime2;
+void InterpolateOrigin_Reset()
+{
+       self.iflags &~= IFLAG_INTERNALMASK;
+       self.itime1 = self.itime2 = 0;
+}
+void InterpolateOrigin_Note()
+{
+       float dt;
+       float f0;
+
+       dt = time - self.itime2;
+
+       f0 = self.iflags;
+       if(self.iflags & IFLAG_PREVALID)
+               self.iflags |= IFLAG_VALID;
+       else
+               self.iflags |= IFLAG_PREVALID;
+
+       self.iorigin1 = self.iorigin2;
+       self.iorigin2 = self.origin;
+
+       if(self.iflags & IFLAG_AUTOANGLES)
+               if(self.iorigin2 != self.iorigin1)
+                       self.angles = vectoangles(self.iorigin2 - self.iorigin1);
+
+       if(self.iflags & IFLAG_ANGLES)
+       {
+               fixedmakevectors(self.angles);
+               if(f0 & IFLAG_VALID)
+               {
+                       self.iforward1 = self.iforward2;
+                       self.iup1 = self.iup2;
+               }
+               else
+               {
+                       self.iforward1 = v_forward;
+                       self.iup1 = v_up;
+               }
+               self.iforward2 = v_forward;
+               self.iup2 = v_up;
+       }
+
+       if(self.iflags & IFLAG_VELOCITY)
+       {
+               self.ivelocity1 = self.ivelocity2;
+               self.ivelocity2 = self.velocity;
+       }
+
+       if(self.iflags & IFLAG_TELEPORTED)
+       {
+               self.iflags &~= IFLAG_TELEPORTED;
+               self.itime1 = self.itime2 = time; // don't lerp
+       }
+       else if(vlen(self.iorigin2 - self.iorigin1) > 1000)
+       {
+               self.itime1 = self.itime2 = time; // don't lerp
+       }
+       else if((self.iflags & IFLAG_VELOCITY) && (vlen(self.ivelocity2 - self.ivelocity1) > 1000))
+       {
+               self.itime1 = self.itime2 = time; // don't lerp
+       }
+       else if(dt >= 0.2)
+       {
+               self.itime1 = self.itime2 = time;
+       }
+       else
+       {
+               self.itime1 = serverprevtime;
+               self.itime2 = time;
+       }
+}
+void InterpolateOrigin_Do()
+{
+       vector forward, up;
+       if(self.itime1 && self.itime2 && self.itime1 != self.itime2)
+       {
+               float f;
+               f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1 + autocvar_cl_lerpexcess);
+               self.origin = (1 - f) * self.iorigin1 + f * self.iorigin2;
+               if(self.iflags & IFLAG_ANGLES)
+               {
+                       forward = (1 - f) * self.iforward1 + f * self.iforward2;
+                       up = (1 - f) * self.iup1 + f * self.iup2;
+                       self.angles = fixedvectoangles2(forward, up);
+               }
+               if(self.iflags & IFLAG_VELOCITY)
+                       self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2;
+       }
+}
+void InterpolateOrigin_Undo()
+{
+       self.origin = self.iorigin2;
+       if(self.iflags & IFLAG_ANGLES)
+               self.angles = fixedvectoangles2(self.iforward2, self.iup2);
+       if(self.iflags & IFLAG_VELOCITY)
+               self.velocity = self.ivelocity2;
+}
+
diff --git a/qcsrc/csqcmodellib/interpolate.qh b/qcsrc/csqcmodellib/interpolate.qh
new file mode 100644 (file)
index 0000000..8254fae
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+.float iflags;
+#define IFLAG_VELOCITY 1
+#define IFLAG_ANGLES 2
+#define IFLAG_AUTOANGLES 4
+#define IFLAG_VALID 8
+#define IFLAG_PREVALID 16
+#define IFLAG_TELEPORTED 32
+#define IFLAG_INTERNALMASK (IFLAG_VALID | IFLAG_PREVALID)
+
+// call this BEFORE reading an entity update
+void InterpolateOrigin_Undo();
+
+// call this AFTER receiving an entity update
+void InterpolateOrigin_Note();
+
+// call this when the entity got teleported, before InterpolateOrigin_Note
+void InterpolateOrigin_Reset();
+
+// call this BEFORE drawing
+void InterpolateOrigin_Do();
diff --git a/qcsrc/csqcmodellib/sv_model.qc b/qcsrc/csqcmodellib/sv_model.qc
new file mode 100644 (file)
index 0000000..1c214e0
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+// generic CSQC model code
+
+float CSQCModel_Send(entity to, float sf)
+{
+       // some nice flags for CSQCMODEL_IF
+       float isplayer = (self.flags & FL_CLIENT);
+       float islocalplayer = (self == to);
+       float isnolocalplayer = (isplayer && (self != to));
+
+       WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL);
+       WriteShort(MSG_ENTITY, sf);
+
+#define CSQCMODEL_IF(cond) if(cond) {
+#define CSQCMODEL_ENDIF }
+#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
+       if(sf & flag) \
+       { \
+               w(MSG_ENTITY, self.csqcmodel_##f); \
+       }
+#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f)
+       ALLPROPERTIES
+#undef CSQCMODEL_PROPERTY_SCALED
+#undef CSQCMODEL_PROPERTY
+#undef CSQCMODEL_ENDIF
+#undef CSQCMODEL_IF
+
+       return TRUE;
+}
+
+#ifdef CSQCPLAYER_FORCE_UPDATES
+.float csqcmodel_nextforcedupdate;
+#endif
+void CSQCModel_CheckUpdate()
+{
+       // some nice flags for CSQCMODEL_IF
+       float isplayer = (self.flags & FL_CLIENT);
+       float islocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags
+       float isnolocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags
+
+#ifdef CSQCPLAYER_FORCE_UPDATES
+       if(isplayer && time > self.csqcmodel_nextforcedupdate)
+       {
+               self.SendFlags |= CSQCMODEL_PROPERTY_ORIGIN;
+               self.csqcmodel_nextforcedupdate = time + CSQCPLAYER_FORCE_UPDATES * (0.5 + random()); // ensure about 4 origin sends per sec
+       }
+#endif
+
+       if(self.effects & EF_RESTARTANIM_BIT)
+       {
+               self.SendFlags |= CSQCMODEL_PROPERTY_FRAME | CSQCMODEL_PROPERTY_FRAME2; // full anim resend please
+               self.effects &~= EF_RESTARTANIM_BIT;
+       }
+
+       if(self.effects & EF_TELEPORT_BIT)
+       {
+               self.SendFlags |= CSQCMODEL_PROPERTY_TELEPORTED; // no interpolation please
+               self.effects &~= EF_TELEPORT_BIT;
+       }
+
+#define CSQCMODEL_IF(cond) if(cond) {
+#define CSQCMODEL_ENDIF }
+#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
+       { \
+               t tmp = self.f; \
+               if(tmp != self.csqcmodel_##f) \
+               { \
+                       self.csqcmodel_##f = tmp; \
+                       self.SendFlags |= flag; \
+               } \
+       }
+#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \
+       { \
+               t tmp = bound(mi, s * self.f, ma); \
+               if(tmp != self.csqcmodel_##f) \
+               { \
+                       self.csqcmodel_##f = tmp; \
+                       self.SendFlags |= flag; \
+               } \
+       }
+       ALLPROPERTIES
+#undef CSQCMODEL_PROPERTY_SCALED
+#undef CSQCMODEL_PROPERTY
+#undef CSQCMODEL_ENDIF
+#undef CSQCMODEL_IF
+}
+
+void CSQCModel_LinkEntity()
+{
+       self.SendEntity = CSQCModel_Send;
+       self.SendFlags = 0xFFFFFF;
+}
+
+void CSQCModel_UnlinkEntity()
+{
+       self.SendEntity = func_null;
+}
diff --git a/qcsrc/csqcmodellib/sv_model.qh b/qcsrc/csqcmodellib/sv_model.qh
new file mode 100644 (file)
index 0000000..3c4ce2b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 Rudolf Polzer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+// generic CSQC model code
+
+void CSQCModel_CheckUpdate();
+void CSQCModel_LinkEntity();
+void CSQCModel_UnlinkEntity();
+
+#define CSQCMODEL_IF(cond)
+#define CSQCMODEL_ENDIF
+#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
+       .t f; \
+       .t csqcmodel_##f;
+#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f)
+       ALLPROPERTIES
+#undef CSQCMODEL_PROPERTY_SCALED
+#undef CSQCMODEL_PROPERTY
+#undef CSQCMODEL_ENDIF
+#undef CSQCMODEL_IF
index 45d83116f46295b910aadfb84c0d1ceb694f3dfd..083feb4e219cf67936b302ca851d8398c7af387e 100644 (file)
@@ -38,9 +38,9 @@ campaign.qh
 
 accuracy.qh
 csqcprojectile.qh
-../csqcmodel/settings.qh
-../csqcmodel/common.qh
-../csqcmodel/sv_model.qh
+../common/csqcmodel_settings.qh
+../csqcmodellib/common.qh
+../csqcmodellib/sv_model.qh
 csqceffects.qc
 
 anticheat.qh
@@ -179,7 +179,7 @@ target_music.qc
 
 
 accuracy.qc
-../csqcmodel/sv_model.qc
+../csqcmodellib/sv_model.qc
 csqcprojectile.qc
 
 playerdemo.qc