cl_pred.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "client.h"
  16. /*
  17. ===================
  18. CL_CheckPredictionError
  19. ===================
  20. */
  21. void CL_CheckPredictionError (void)
  22. {
  23. int frame;
  24. int delta[3];
  25. int i;
  26. int len;
  27. if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
  28. return;
  29. // calculate the last usercmd_t we sent that the server has processed
  30. frame = cls.netchan.incoming_acknowledged;
  31. frame &= (CMD_BACKUP-1);
  32. // compare what the server returned with what we had predicted it to be
  33. VectorSubtract (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame], delta);
  34. // save the prediction error for interpolation
  35. len = abs(delta[0]) + abs(delta[1]) + abs(delta[2]);
  36. if (len > 640) // 80 world units
  37. { // a teleport or something
  38. VectorClear (cl.prediction_error);
  39. }
  40. else
  41. {
  42. if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]) )
  43. Com_Printf ("prediction miss on %i: %i\n", cl.frame.serverframe,
  44. delta[0] + delta[1] + delta[2]);
  45. VectorCopy (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame]);
  46. // save for error itnerpolation
  47. for (i=0 ; i<3 ; i++)
  48. cl.prediction_error[i] = delta[i]*0.125;
  49. }
  50. }
  51. /*
  52. ====================
  53. CL_ClipMoveToEntities
  54. ====================
  55. */
  56. void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t *tr )
  57. {
  58. int i, x, zd, zu;
  59. trace_t trace;
  60. int headnode;
  61. float *angles;
  62. entity_state_t *ent;
  63. int num;
  64. cmodel_t *cmodel;
  65. vec3_t bmins, bmaxs;
  66. for (i=0 ; i<cl.frame.num_entities ; i++)
  67. {
  68. num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
  69. ent = &cl_parse_entities[num];
  70. if (!ent->solid)
  71. continue;
  72. if (ent->number == cl.playernum+1)
  73. continue;
  74. if (ent->solid == 31)
  75. { // special value for bmodel
  76. cmodel = cl.model_clip[ent->modelindex];
  77. if (!cmodel)
  78. continue;
  79. headnode = cmodel->headnode;
  80. angles = ent->angles;
  81. }
  82. else
  83. { // encoded bbox
  84. x = 8*(ent->solid & 31);
  85. zd = 8*((ent->solid>>5) & 31);
  86. zu = 8*((ent->solid>>10) & 63) - 32;
  87. bmins[0] = bmins[1] = -x;
  88. bmaxs[0] = bmaxs[1] = x;
  89. bmins[2] = -zd;
  90. bmaxs[2] = zu;
  91. headnode = CM_HeadnodeForBox (bmins, bmaxs);
  92. angles = vec3_origin; // boxes don't rotate
  93. }
  94. if (tr->allsolid)
  95. return;
  96. trace = CM_TransformedBoxTrace (start, end,
  97. mins, maxs, headnode, MASK_PLAYERSOLID,
  98. ent->origin, angles);
  99. if (trace.allsolid || trace.startsolid ||
  100. trace.fraction < tr->fraction)
  101. {
  102. trace.ent = (struct edict_s *)ent;
  103. if (tr->startsolid)
  104. {
  105. *tr = trace;
  106. tr->startsolid = true;
  107. }
  108. else
  109. *tr = trace;
  110. }
  111. else if (trace.startsolid)
  112. tr->startsolid = true;
  113. }
  114. }
  115. /*
  116. ================
  117. CL_PMTrace
  118. ================
  119. */
  120. trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
  121. {
  122. trace_t t;
  123. // check against world
  124. t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
  125. if (t.fraction < 1.0)
  126. t.ent = (struct edict_s *)1;
  127. // check all other solid models
  128. CL_ClipMoveToEntities (start, mins, maxs, end, &t);
  129. return t;
  130. }
  131. int CL_PMpointcontents (vec3_t point)
  132. {
  133. int i;
  134. entity_state_t *ent;
  135. int num;
  136. cmodel_t *cmodel;
  137. int contents;
  138. contents = CM_PointContents (point, 0);
  139. for (i=0 ; i<cl.frame.num_entities ; i++)
  140. {
  141. num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
  142. ent = &cl_parse_entities[num];
  143. if (ent->solid != 31) // special value for bmodel
  144. continue;
  145. cmodel = cl.model_clip[ent->modelindex];
  146. if (!cmodel)
  147. continue;
  148. contents |= CM_TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles);
  149. }
  150. return contents;
  151. }
  152. /*
  153. =================
  154. CL_PredictMovement
  155. Sets cl.predicted_origin and cl.predicted_angles
  156. =================
  157. */
  158. void CL_PredictMovement (void)
  159. {
  160. int ack, current;
  161. int frame;
  162. int oldframe;
  163. usercmd_t *cmd;
  164. pmove_t pm;
  165. int i;
  166. int step;
  167. int oldz;
  168. if (cls.state != ca_active)
  169. return;
  170. if (cl_paused->value)
  171. return;
  172. if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
  173. { // just set angles
  174. for (i=0 ; i<3 ; i++)
  175. {
  176. cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
  177. }
  178. return;
  179. }
  180. ack = cls.netchan.incoming_acknowledged;
  181. current = cls.netchan.outgoing_sequence;
  182. // if we are too far out of date, just freeze
  183. if (current - ack >= CMD_BACKUP)
  184. {
  185. if (cl_showmiss->value)
  186. Com_Printf ("exceeded CMD_BACKUP\n");
  187. return;
  188. }
  189. // copy current state to pmove
  190. memset (&pm, 0, sizeof(pm));
  191. pm.trace = CL_PMTrace;
  192. pm.pointcontents = CL_PMpointcontents;
  193. pm_airaccelerate = atof(cl.configstrings[CS_AIRACCEL]);
  194. pm.s = cl.frame.playerstate.pmove;
  195. // SCR_DebugGraph (current - ack - 1, 0);
  196. frame = 0;
  197. // run frames
  198. while (++ack < current)
  199. {
  200. frame = ack & (CMD_BACKUP-1);
  201. cmd = &cl.cmds[frame];
  202. pm.cmd = *cmd;
  203. Pmove (&pm);
  204. // save for debug checking
  205. VectorCopy (pm.s.origin, cl.predicted_origins[frame]);
  206. }
  207. oldframe = (ack-2) & (CMD_BACKUP-1);
  208. oldz = cl.predicted_origins[oldframe][2];
  209. step = pm.s.origin[2] - oldz;
  210. if (step > 63 && step < 160 && (pm.s.pm_flags & PMF_ON_GROUND) )
  211. {
  212. cl.predicted_step = step * 0.125;
  213. cl.predicted_step_time = cls.realtime - cls.frametime * 500;
  214. }
  215. // copy results out for rendering
  216. cl.predicted_origin[0] = pm.s.origin[0]*0.125;
  217. cl.predicted_origin[1] = pm.s.origin[1]*0.125;
  218. cl.predicted_origin[2] = pm.s.origin[2]*0.125;
  219. VectorCopy (pm.viewangles, cl.predicted_angles);
  220. }