From: Rudolf Polzer Date: Sun, 13 Nov 2011 19:55:09 +0000 (+0100) Subject: restructured it a lot X-Git-Tag: xonotic-v0.6.0~74^2~100^2~89 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=0716ef2ec2ac4d429a7d6e9455d16ca56c410d65;p=xonotic%2Fxonotic-data.pk3dir.git restructured it a lot --- diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 48b52acbc..f769f4ea2 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -35,8 +35,9 @@ tturrets.qh ../server/movelib.qc main.qh vehicles/vehicles.qh -../common/csqcmodel.qh -../common/csqcplayer.qh +../csqcmodel/settings.qh +../csqcmodel/cl_model.qh +../csqcmodel/cl_player.qh sortlist.qc miscfunctions.qc @@ -58,8 +59,9 @@ projectile.qc gibs.qc damage.qc casings.qc -../common/csqcmodel.qc -../common/csqcplayer.qc +../csqcmodel/common.qc +../csqcmodel/cl_model.qc +../csqcmodel/cl_player.qc effects.qc wall.qc modeleffects.qc diff --git a/qcsrc/common/csqcmodel.qc b/qcsrc/common/csqcmodel.qc deleted file mode 100644 index c03d0f5e9..000000000 --- a/qcsrc/common/csqcmodel.qc +++ /dev/null @@ -1,135 +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 - -.vector glowmod; -.vector view_ofs; - -#define ALLPROPERTIES \ - PROPERTY(1, ReadCoord, WriteCoord, origin_x) \ - PROPERTY(1, ReadCoord, WriteCoord, origin_y) \ - PROPERTY(1, ReadCoord, WriteCoord, origin_z) \ - PROPERTY(2, ReadAngle, WriteAngle, angles_x) \ - PROPERTY(2, ReadAngle, WriteAngle, angles_y) \ - PROPERTY(2, ReadAngle, WriteAngle, angles_z) \ - PROPERTY(4, ReadShort, WriteShort, modelindex) \ - PROPERTY(8, ReadByte, WriteByte, frame) \ - PROPERTY(16, ReadByte, WriteByte, skin) \ - PROPERTY(32, ReadInt24_t, WriteInt24_t, effects) \ - PROPERTY_SCALED(64, ReadByte, WriteByte, alpha, 255, 0, 255) \ - PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_x, 32, 0, 255) \ - PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_y, 32, 0, 255) \ - PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_z, 32, 0, 255) \ - PROPERTY(256, ReadChar, WriteChar, view_ofs_z) \ - PROPERTY(512, ReadShort, WriteShort, colormap) - -#ifdef SVQC - -#define PROPERTY(flag,r,w,f) \ - .float csqcmodel_##f; -#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) PROPERTY(flag,r,w,f) - ALLPROPERTIES -#undef PROPERTY_SCALED -#undef PROPERTY - -float CSQCModel_Send(entity to, float sf) -{ - WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL); - WriteShort(MSG_ENTITY, sf); - -#define PROPERTY(flag,r,w,f) \ - if(sf & flag) \ - { \ - w(MSG_ENTITY, self.csqcmodel_##f); \ - } -#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) PROPERTY(flag,r,w,f) - ALLPROPERTIES -#undef PROPERTY_SCALED -#undef PROPERTY - - return TRUE; -} - -void CSQCModel_CheckUpdate() -{ - float tmp; -#define PROPERTY(flag,r,w,f) \ - tmp = self.f; \ - if(tmp != self.csqcmodel_##f) \ - { \ - self.csqcmodel_##f = tmp; \ - self.SendFlags |= flag; \ - } -#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \ - tmp = bound(mi, s * self.f, ma); \ - if(tmp != self.csqcmodel_##f) \ - { \ - self.csqcmodel_##f = tmp; \ - self.SendFlags |= flag; \ - } - ALLPROPERTIES -#undef PROPERTY_SCALED -#undef PROPERTY -} - -void CSQCModel_LinkEntity() -{ - Net_LinkEntity(self, TRUE, 0, CSQCModel_Send); -} - -#endif - -#ifdef CSQC - -void CSQCModel_Draw() -{ - InterpolateOrigin_Do(); -} - -void CSQCModel_Read() -{ - float sf; - sf = ReadShort(); - - CSQCPlayer_PreUpdate(); - InterpolateOrigin_Undo(); - -#define PROPERTY(flag,r,w,f) \ - if(sf & flag) \ - self.f = r(); -#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \ - if(sf & flag) \ - self.f = r() / s; - ALLPROPERTIES -#undef PROPERTY_SCALED -#undef PROPERTY - - InterpolateOrigin_Note(); - CSQCPlayer_PostUpdate(); - - // draw it - self.drawmask = MASK_NORMAL; - self.predraw = CSQCModel_Draw; -} - -#endif diff --git a/qcsrc/common/csqcmodel.qh b/qcsrc/common/csqcmodel.qh deleted file mode 100644 index bc054a8ec..000000000 --- a/qcsrc/common/csqcmodel.qh +++ /dev/null @@ -1,32 +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 - -#ifdef SVQC -void CSQCModel_CheckUpdate(); -void CSQCModel_LinkEntity(); -#endif - -#ifdef CSQC -void CSQCModel_Read(); -#endif diff --git a/qcsrc/common/csqcplayer.qc b/qcsrc/common/csqcplayer.qc deleted file mode 100644 index 206789b4b..000000000 --- a/qcsrc/common/csqcplayer.qc +++ /dev/null @@ -1,176 +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 autocvar_cl_predictionerrorcompensation = 0; -float autocvar_cl_movement_replay; -float autocvar_chase_active; -float autocvar_chase_back; - -.float pmove_flags; - -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_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_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; - } - runstandardplayerphysics(self); - - csqcplayer_moveframe++; - } - - //add in anything that was applied after (for low packet rate protocols) - input_angles = view_angles; -} - -void CSQCPlayer_SetCamera() -{ - if(csqcplayer) - { - vector org, ang; - entity oldself; - oldself = self; - self = csqcplayer; - - if(servercommandframe == 0) - { - InterpolateOrigin_Do(); - } - 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; - CSQCPlayer_SavePrediction(); - } - CSQCPlayer_PredictTo(clientcommandframe); - } - - self = oldself; - - org = csqcplayer.origin + csqcplayer.view_ofs + CSQCPlayer_GetPredictionError(); - ang = R_SetView3fv(VF_ANGLES); - - // simulate missing engine features - if(autocvar_chase_active) - { - float dist; - vector chase_dest; - dist = -autocvar_chase_back - 8; - makevectors(ang); - chase_dest = org + v_forward * dist; - traceline(org, chase_dest, MOVE_NOMONSTERS, csqcplayer); - org = trace_endpos + 8 * v_forward + 4 * trace_plane_normal; - } - - R_SetView3fv(VF_ORIGIN, org); - R_SetView3fv(VF_ANGLES, ang); - } -} - -float CSQCPlayer_PreUpdate() -{ - if(self.entnum != player_localentnum) - return 0; - cvar_clientsettemp("cl_movement_replay", "0"); - if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER) - CSQCPlayer_Unpredict(); - return 1; -} - -float CSQCPlayer_PostUpdate() -{ - if(self.entnum <= maxclients) - self.renderflags |= RF_EXTERNALMODEL; - else - self.renderflags &~= RF_EXTERNALMODEL; - if(self.entnum != player_localentnum) - return 0; - csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER; - csqcplayer = self; - return 1; -} diff --git a/qcsrc/common/csqcplayer.qh b/qcsrc/common/csqcplayer.qh deleted file mode 100644 index 7f7329bd5..000000000 --- a/qcsrc/common/csqcplayer.qh +++ /dev/null @@ -1,30 +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(); diff --git a/qcsrc/csqcmodel/cl_model.qc b/qcsrc/csqcmodel/cl_model.qc new file mode 100644 index 000000000..6fc076b86 --- /dev/null +++ b/qcsrc/csqcmodel/cl_model.qc @@ -0,0 +1,159 @@ +/* + * 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 + +var float autocvar_cl_lerpanim_maxdelta_framegroups = 0.1; +var float autocvar_cl_nolerp = 0; + +.float csqcmodel_lerpfrac; +.float csqcmodel_lerpfrac2; +.float csqcmodel_lerpfractime; + +void CSQCModel_InterpolateAnimation_PreNote(float sf) +{ +#ifdef CSQCMODELS_HAVE_TWO_FRAMES + if(sf & PROPERTY_FRAME) + { + self.frame3 = self.frame; + self.frame3time = self.frame1time; + } + if(sf & PROPERTY_FRAME2) + { + self.frame4 = self.frame2; + self.frame4time = self.frame2time; + } + if(sf & PROPERTY_LERPFRAC) + { + self.csqcmodel_lerpfrac2 = self.csqcmodel_lerpfrac; + self.lerpfrac = self.csqcmodel_lerpfrac; + } +#else + if(sf & PROPERTY_FRAME) + { + self.frame2 = self.frame; + self.frame2time = self.frame1time; + self.frame1time = time; + } +#endif +} + +void CSQCModel_InterpolateAnimation_Note(float sf) +{ +#ifdef CSQCMODELS_HAVE_TWO_FRAMES + if(sf & PROPERTY_FRAME) + { + self.frame1time = time; + } + if(sf & PROPERTY_FRAME2) + { + self.frame2time = time; + } + if(sf & PROPERTY_LERPFRAC) + { + self.csqcmodel_lerpfrac = self.lerpfrac; + self.csqcmodel_lerpfractime = time; + } +#else + if(sf & PROPERTY_FRAME) + { + self.frame2 = self.frame; + self.frame2time = self.frame1time; + self.frame1time = time; + } +#endif +} + +void CSQCModel_InterpolateAnimation_Do() +{ +#ifdef CSQCMODELS_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; + l13 = bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); + l24 = bound(0, (time - self.frame2time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); + 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); + } +#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() +{ + InterpolateOrigin_Do(); + CSQCModel_InterpolateAnimation_Do(); +} + +void CSQCModel_Read() +{ + float sf; + sf = ReadShort(); + + self.iflags |= IFLAG_ANGLES; // interpolate angles too + + CSQCPlayer_PreUpdate(); + InterpolateOrigin_Undo(); + CSQCModel_InterpolateAnimation_PreNote(sf); + +#define PROPERTY(flag,r,w,f) \ + if(sf & flag) \ + self.f = r(); +#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \ + if(sf & flag) \ + self.f = r() / s; + ALLPROPERTIES +#undef PROPERTY_SCALED +#undef PROPERTY + + CSQCModel_InterpolateAnimation_Note(sf); + InterpolateOrigin_Note(); + CSQCPlayer_PostUpdate(); + +#ifdef CSQCMODELS_SUPPORT_GETTAGINFO_BEFORE_DRAW + InterpolateOrigin_Do(); + CSQCModel_InterpolateAnimation_Do(); +#endif + + // draw it + self.drawmask = MASK_NORMAL; + self.predraw = CSQCModel_Draw; +} diff --git a/qcsrc/csqcmodel/cl_model.qh b/qcsrc/csqcmodel/cl_model.qh new file mode 100644 index 000000000..e087ee670 --- /dev/null +++ b/qcsrc/csqcmodel/cl_model.qh @@ -0,0 +1,25 @@ +/* + * 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_Read(); diff --git a/qcsrc/csqcmodel/cl_player.qc b/qcsrc/csqcmodel/cl_player.qc new file mode 100644 index 000000000..eb1715c67 --- /dev/null +++ b/qcsrc/csqcmodel/cl_player.qc @@ -0,0 +1,176 @@ +/* + * 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; +var float autocvar_cl_movement_replay; +var float autocvar_chase_active; +var float autocvar_chase_back; + +.float pmove_flags; + +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_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_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; + } + runstandardplayerphysics(self); + + csqcplayer_moveframe++; + } + + //add in anything that was applied after (for low packet rate protocols) + input_angles = view_angles; +} + +void CSQCPlayer_SetCamera() +{ + if(csqcplayer) + { + vector org, ang; + entity oldself; + oldself = self; + self = csqcplayer; + + if(servercommandframe == 0) + { + InterpolateOrigin_Do(); + } + 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; + CSQCPlayer_SavePrediction(); + } + CSQCPlayer_PredictTo(clientcommandframe); + } + + self = oldself; + + org = csqcplayer.origin + csqcplayer.view_ofs + CSQCPlayer_GetPredictionError(); + ang = R_SetView3fv(VF_ANGLES); + + // simulate missing engine features + if(autocvar_chase_active) + { + float dist; + vector chase_dest; + dist = -autocvar_chase_back - 8; + makevectors(ang); + chase_dest = org + v_forward * dist; + traceline(org, chase_dest, MOVE_NOMONSTERS, csqcplayer); + org = trace_endpos + 8 * v_forward + 4 * trace_plane_normal; + } + + R_SetView3fv(VF_ORIGIN, org); + R_SetView3fv(VF_ANGLES, ang); + } +} + +float CSQCPlayer_PreUpdate() +{ + if(self.entnum != player_localentnum) + return 0; + cvar_clientsettemp("cl_movement_replay", "0"); + if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER) + CSQCPlayer_Unpredict(); + return 1; +} + +float CSQCPlayer_PostUpdate() +{ + if(self.entnum <= maxclients) + self.renderflags |= RF_EXTERNALMODEL; + else + self.renderflags &~= RF_EXTERNALMODEL; + if(self.entnum != player_localentnum) + return 0; + csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER; + csqcplayer = self; + return 1; +} diff --git a/qcsrc/csqcmodel/cl_player.qh b/qcsrc/csqcmodel/cl_player.qh new file mode 100644 index 000000000..7f7329bd5 --- /dev/null +++ b/qcsrc/csqcmodel/cl_player.qh @@ -0,0 +1,30 @@ +/* + * 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(); diff --git a/qcsrc/csqcmodel/common.qc b/qcsrc/csqcmodel/common.qc new file mode 100644 index 000000000..5677f9a4c --- /dev/null +++ b/qcsrc/csqcmodel/common.qc @@ -0,0 +1,44 @@ +.vector glowmod; +.vector view_ofs; +.float frame; +.float frame1time; +.float frame2; +.float frame2time; +.float lerpfrac; + +#define PROPERTY_FRAME 32768 +#define PROPERTY_FRAME2 16384 +#define PROPERTY_LERPFRAC 8192 + +#define ALLPROPERTIES_COMMON \ + PROPERTY(PROPERTY_FRAME, ReadByte, WriteByte, frame) \ + PROPERTY(1, ReadCoord, WriteCoord, origin_x) \ + PROPERTY(1, ReadCoord, WriteCoord, origin_y) \ + PROPERTY(1, ReadCoord, WriteCoord, origin_z) \ + PROPERTY(2, ReadAngle, WriteAngle, angles_x) \ + PROPERTY(2, ReadAngle, WriteAngle, angles_y) \ + PROPERTY(2, ReadAngle, WriteAngle, angles_z) \ + PROPERTY(4, ReadShort, WriteShort, modelindex) \ + PROPERTY(16, ReadByte, WriteByte, skin) \ + PROPERTY(32, ReadInt24_t, WriteInt24_t, effects) \ + PROPERTY_SCALED(64, ReadByte, WriteByte, alpha, 255, 0, 255) \ + PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_x, 32, 0, 255) \ + PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_y, 32, 0, 255) \ + PROPERTY_SCALED(128, ReadByte, WriteByte, glowmod_z, 32, 0, 255) \ + PROPERTY(256, ReadChar, WriteChar, view_ofs_z) \ + PROPERTY(512, ReadShort, WriteShort, colormap) + +#ifdef CSQCMODELS_HAVE_TWO_FRAMES +.float frame3; +.float frame3time; +.float lerpfrac3; +.float frame4; +.float frame4time; +.float lerpfrac4; +#define ALLPROPERTIES ALLPROPERTIES_COMMON \ + PROPERTY(PROPERTY_FRAME2, ReadByte, WriteByte, frame2) \ + PROPERTY_SCALED(PROPERTY_LERPFRAC, ReadByte, WriteByte, lerpfrac, 255, 0, 255) +#else +#define ALLPROPERTIES ALLPROPERTIES_COMMON +#endif + diff --git a/qcsrc/csqcmodel/settings.qh b/qcsrc/csqcmodel/settings.qh new file mode 100644 index 000000000..e542bfa5d --- /dev/null +++ b/qcsrc/csqcmodel/settings.qh @@ -0,0 +1,2 @@ +//#define CSQCMODELS_HAVE_TWO_FRAMES +//#define CSQCMODELS_SUPPORT_GETTAGINFO_BEFORE_DRAW diff --git a/qcsrc/csqcmodel/sv_model.qc b/qcsrc/csqcmodel/sv_model.qc new file mode 100644 index 000000000..010258b10 --- /dev/null +++ b/qcsrc/csqcmodel/sv_model.qc @@ -0,0 +1,75 @@ +/* + * 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 + +#define PROPERTY(flag,r,w,f) \ + .float csqcmodel_##f; +#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) PROPERTY(flag,r,w,f) + ALLPROPERTIES +#undef PROPERTY_SCALED +#undef PROPERTY + +float CSQCModel_Send(entity to, float sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL); + WriteShort(MSG_ENTITY, sf); + +#define PROPERTY(flag,r,w,f) \ + if(sf & flag) \ + { \ + w(MSG_ENTITY, self.csqcmodel_##f); \ + } +#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) PROPERTY(flag,r,w,f) + ALLPROPERTIES +#undef PROPERTY_SCALED +#undef PROPERTY + + return TRUE; +} + +void CSQCModel_CheckUpdate() +{ + float tmp; +#define PROPERTY(flag,r,w,f) \ + tmp = self.f; \ + if(tmp != self.csqcmodel_##f) \ + { \ + self.csqcmodel_##f = tmp; \ + self.SendFlags |= flag; \ + } +#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \ + tmp = bound(mi, s * self.f, ma); \ + if(tmp != self.csqcmodel_##f) \ + { \ + self.csqcmodel_##f = tmp; \ + self.SendFlags |= flag; \ + } + ALLPROPERTIES +#undef PROPERTY_SCALED +#undef PROPERTY +} + +void CSQCModel_LinkEntity() +{ + Net_LinkEntity(self, TRUE, 0, CSQCModel_Send); +} diff --git a/qcsrc/csqcmodel/sv_model.qh b/qcsrc/csqcmodel/sv_model.qh new file mode 100644 index 000000000..bb45a74b4 --- /dev/null +++ b/qcsrc/csqcmodel/sv_model.qh @@ -0,0 +1,26 @@ +/* + * 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(); diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index a602f3220..734ba840b 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -40,7 +40,8 @@ campaign.qh accuracy.qh csqcprojectile.qh -../common/csqcmodel.qh +../csqcmodel/settings.qh +../csqcmodel/sv_model.qh csqceffects.qc anticheat.qh @@ -179,7 +180,8 @@ target_music.qc accuracy.qc -../common/csqcmodel.qc +../csqcmodel/common.qc +../csqcmodel/sv_model.qc csqcprojectile.qc playerdemo.qc