extendedMoveList.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. #include "platform/platform.h"
  2. #include "T3D/gameBase/extended/extendedMoveList.h"
  3. #include "T3D/gameBase/gameConnection.h"
  4. #include "core/stream/bitStream.h"
  5. #define MAX_MOVE_PACKET_SENDS 4
  6. ExtendedMoveList::ExtendedMoveList()
  7. {
  8. mMoveCredit = MaxMoveCount;
  9. mControlMismatch = false;
  10. reset();
  11. }
  12. void ExtendedMoveList::reset()
  13. {
  14. mLastMoveAck = 0;
  15. mLastClientMove = 0;
  16. mFirstMoveIndex = 0;
  17. mExtMoveVec.clear();
  18. }
  19. bool ExtendedMoveList::getNextExtMove( ExtendedMove &curMove )
  20. {
  21. if ( mExtMoveVec.size() > MaxMoveQueueSize )
  22. return false;
  23. // From MoveList
  24. F32 pitchAdd = MoveManager::mPitchUpSpeed - MoveManager::mPitchDownSpeed;
  25. F32 yawAdd = MoveManager::mYawLeftSpeed - MoveManager::mYawRightSpeed;
  26. F32 rollAdd = MoveManager::mRollRightSpeed - MoveManager::mRollLeftSpeed;
  27. curMove.pitch = MoveManager::mPitch + pitchAdd;
  28. curMove.yaw = MoveManager::mYaw + yawAdd;
  29. curMove.roll = MoveManager::mRoll + rollAdd;
  30. MoveManager::mPitch = 0;
  31. MoveManager::mYaw = 0;
  32. MoveManager::mRoll = 0;
  33. curMove.x = MoveManager::mRightAction - MoveManager::mLeftAction + MoveManager::mXAxis_L;
  34. curMove.y = MoveManager::mForwardAction - MoveManager::mBackwardAction + MoveManager::mYAxis_L;
  35. curMove.z = MoveManager::mUpAction - MoveManager::mDownAction;
  36. curMove.freeLook = MoveManager::mFreeLook;
  37. curMove.deviceIsKeyboardMouse = MoveManager::mDeviceIsKeyboardMouse;
  38. for(U32 i = 0; i < MaxTriggerKeys; i++)
  39. {
  40. curMove.trigger[i] = false;
  41. if(MoveManager::mTriggerCount[i] & 1)
  42. curMove.trigger[i] = true;
  43. else if(!(MoveManager::mPrevTriggerCount[i] & 1) && MoveManager::mPrevTriggerCount[i] != MoveManager::mTriggerCount[i])
  44. curMove.trigger[i] = true;
  45. MoveManager::mPrevTriggerCount[i] = MoveManager::mTriggerCount[i];
  46. }
  47. for(U32 i=0; i<ExtendedMove::MaxPositionsRotations; ++i)
  48. {
  49. // Process position
  50. curMove.posX[i] = ExtendedMoveManager::mPosX[i];
  51. curMove.posY[i] = ExtendedMoveManager::mPosY[i];
  52. curMove.posZ[i] = ExtendedMoveManager::mPosZ[i];
  53. // Process rotation. There are two possible forms of rotation: Angle Axis and Euler angles.
  54. curMove.EulerBasedRotation[i] = ExtendedMoveManager::mRotIsEuler[i];
  55. if(curMove.EulerBasedRotation[i])
  56. {
  57. // Euler angle based rotation passed in as degrees. We only need to work with three components.
  58. curMove.rotX[i] = mDegToRad(ExtendedMoveManager::mRotAX[i]);
  59. curMove.rotY[i] = mDegToRad(ExtendedMoveManager::mRotAY[i]);
  60. curMove.rotZ[i] = mDegToRad(ExtendedMoveManager::mRotAZ[i]);
  61. }
  62. else
  63. {
  64. //Rotation is passed in as an Angle Axis in degrees. We need to convert this into a Quat.
  65. AngAxisF q(Point3F(ExtendedMoveManager::mRotAX[i], ExtendedMoveManager::mRotAY[i], ExtendedMoveManager::mRotAZ[i]), mDegToRad(ExtendedMoveManager::mRotAA[i]));
  66. curMove.rotX[i] = q.axis.x;
  67. curMove.rotY[i] = q.axis.y;
  68. curMove.rotZ[i] = q.axis.z;
  69. curMove.rotW[i] = q.angle;
  70. }
  71. }
  72. if (mConnection->getControlObject())
  73. mConnection->getControlObject()->preprocessMove(&curMove);
  74. curMove.clamp(); // clamp for net traffic
  75. return true;
  76. }
  77. U32 ExtendedMoveList::getMoves(Move** movePtr,U32* numMoves)
  78. {
  79. // We don't want to be here
  80. AssertFatal(0, "getMoves() called");
  81. numMoves = 0;
  82. return 0;
  83. }
  84. U32 ExtendedMoveList::getExtMoves( ExtendedMove** movePtr, U32 *numMoves )
  85. {
  86. if (!mConnection->isConnectionToServer())
  87. {
  88. if (mExtMoveVec.size() > mMoveCredit)
  89. mExtMoveVec.setSize(mMoveCredit);
  90. }
  91. // From MoveList but converted to use mExtMoveVec
  92. if (mConnection->isConnectionToServer())
  93. {
  94. // give back moves starting at the last client move...
  95. AssertFatal(mLastClientMove >= mFirstMoveIndex, "Bad move request");
  96. AssertFatal(mLastClientMove - mFirstMoveIndex <= mExtMoveVec.size(), "Desynched first and last move.");
  97. *numMoves = mExtMoveVec.size() - mLastClientMove + mFirstMoveIndex;
  98. *movePtr = mExtMoveVec.address() + mLastClientMove - mFirstMoveIndex;
  99. }
  100. else
  101. {
  102. // return the full list
  103. *numMoves = mExtMoveVec.size();
  104. *movePtr = mExtMoveVec.begin();
  105. }
  106. return *numMoves;
  107. }
  108. void ExtendedMoveList::collectMove()
  109. {
  110. ExtendedMove mv;
  111. if (mConnection)
  112. {
  113. if(!mConnection->isPlayingBack() && getNextExtMove(mv))
  114. {
  115. mv.checksum=Move::ChecksumMismatch;
  116. pushMove(mv);
  117. mConnection->recordBlock(GameConnection::BlockTypeMove, sizeof(ExtendedMove), &mv);
  118. }
  119. }
  120. else
  121. {
  122. if(getNextExtMove(mv))
  123. {
  124. mv.checksum=Move::ChecksumMismatch;
  125. pushMove(mv);
  126. }
  127. }
  128. }
  129. void ExtendedMoveList::pushMove(const Move &mv)
  130. {
  131. const ExtendedMove* extMove = dynamic_cast<const ExtendedMove*>(&mv);
  132. AssertFatal(extMove, "Regular Move struct passed to pushMove()");
  133. pushExtMove(*extMove);
  134. }
  135. void ExtendedMoveList::pushExtMove( const ExtendedMove &mv )
  136. {
  137. U32 id = mFirstMoveIndex + mExtMoveVec.size();
  138. U32 sz = mExtMoveVec.size();
  139. mExtMoveVec.push_back(mv);
  140. mExtMoveVec[sz].id = id;
  141. mExtMoveVec[sz].sendCount = 0;
  142. }
  143. void ExtendedMoveList::clearMoves(U32 count)
  144. {
  145. if (!mConnection->isConnectionToServer())
  146. {
  147. count = mClamp(count,0,mMoveCredit);
  148. mMoveCredit -= count;
  149. }
  150. // From MoveList but converted to use mExtMoveVec
  151. if (mConnection->isConnectionToServer())
  152. {
  153. mLastClientMove += count;
  154. AssertFatal(mLastClientMove >= mFirstMoveIndex, "Bad move request");
  155. AssertFatal(mLastClientMove - mFirstMoveIndex <= mExtMoveVec.size(), "Desynched first and last move.");
  156. if (!mConnection)
  157. // drop right away if no connection
  158. ackMoves(count);
  159. }
  160. else
  161. {
  162. AssertFatal(count <= mExtMoveVec.size(),"GameConnection: Clearing too many moves");
  163. for (S32 i=0; i<count; i++)
  164. if (mExtMoveVec[i].checksum == Move::ChecksumMismatch)
  165. mControlMismatch = true;
  166. else
  167. mControlMismatch = false;
  168. if (count == mExtMoveVec.size())
  169. mExtMoveVec.clear();
  170. else
  171. while (count--)
  172. mExtMoveVec.pop_front();
  173. }
  174. }
  175. void ExtendedMoveList::advanceMove()
  176. {
  177. AssertFatal(!mConnection->isConnectionToServer(), "Cannot inc move credit on the client.");
  178. // Game tick increment
  179. mMoveCredit++;
  180. if (mMoveCredit > MaxMoveCount)
  181. mMoveCredit = MaxMoveCount;
  182. // Clear pending moves for the elapsed time if there
  183. // is no control object.
  184. if ( mConnection->getControlObject() == NULL )
  185. mExtMoveVec.clear();
  186. }
  187. void ExtendedMoveList::clientWriteMovePacket(BitStream *bstream)
  188. {
  189. AssertFatal(mLastMoveAck == mFirstMoveIndex, "Invalid move index.");
  190. U32 count = mExtMoveVec.size();
  191. ExtendedMove* extMove = mExtMoveVec.address();
  192. U32 start = mLastMoveAck;
  193. U32 offset;
  194. for(offset = 0; offset < count; offset++)
  195. if(extMove[offset].sendCount < MAX_MOVE_PACKET_SENDS)
  196. break;
  197. if(offset == count && count != 0)
  198. offset--;
  199. start += offset;
  200. count -= offset;
  201. if (count > MaxMoveCount)
  202. count = MaxMoveCount;
  203. bstream->writeInt(start,32);
  204. bstream->writeInt(count,MoveCountBits);
  205. ExtendedMove* prevExtMove = NULL;
  206. for (int i = 0; i < count; i++)
  207. {
  208. extMove[offset + i].sendCount++;
  209. extMove[offset + i].pack(bstream,prevExtMove);
  210. bstream->writeInt(extMove[offset + i].checksum & (~(0xFFFFFFFF << Move::ChecksumBits)),Move::ChecksumBits);
  211. prevExtMove = &extMove[offset+i];
  212. }
  213. }
  214. void ExtendedMoveList::serverReadMovePacket(BitStream *bstream)
  215. {
  216. // Server side packet read.
  217. U32 start = bstream->readInt(32);
  218. U32 count = bstream->readInt(MoveCountBits);
  219. ExtendedMove* prevExtMove = NULL;
  220. ExtendedMove prevExtMoveHolder;
  221. // Skip forward (must be starting up), or over the moves
  222. // we already have.
  223. int skip = mLastMoveAck - start;
  224. if (skip < 0)
  225. {
  226. mLastMoveAck = start;
  227. }
  228. else
  229. {
  230. if (skip > count)
  231. skip = count;
  232. for (int i = 0; i < skip; i++)
  233. {
  234. prevExtMoveHolder.unpack(bstream,prevExtMove);
  235. prevExtMoveHolder.checksum = bstream->readInt(Move::ChecksumBits);
  236. prevExtMove = &prevExtMoveHolder;
  237. S32 idx = mExtMoveVec.size()-skip+i;
  238. if (idx>=0)
  239. {
  240. #ifdef TORQUE_DEBUG_NET_MOVES
  241. if (mExtMoveVec[idx].checksum != prevExtMoveHolder.checksum)
  242. Con::printf("updated checksum on move %i from %i to %i",mExtMoveVec[idx].id,mExtMoveVec[idx].checksum,prevExtMoveHolder.checksum);
  243. #endif
  244. mExtMoveVec[idx].checksum = prevExtMoveHolder.checksum;
  245. }
  246. }
  247. start += skip;
  248. count = count - skip;
  249. }
  250. // Put the rest on the move list.
  251. int index = mExtMoveVec.size();
  252. mExtMoveVec.increment(count);
  253. while (index < mExtMoveVec.size())
  254. {
  255. mExtMoveVec[index].unpack(bstream,prevExtMove);
  256. mExtMoveVec[index].checksum = bstream->readInt(Move::ChecksumBits);
  257. prevExtMove = &mExtMoveVec[index];
  258. mExtMoveVec[index].id = start++;
  259. index ++;
  260. }
  261. mLastMoveAck += count;
  262. }
  263. void ExtendedMoveList::serverWriteMovePacket(BitStream * bstream)
  264. {
  265. #ifdef TORQUE_DEBUG_NET_MOVES
  266. Con::printf("ack %i minus %i",mLastMoveAck,mExtMoveVec.size());
  267. #endif
  268. // acknowledge only those moves that have been ticked
  269. bstream->writeInt(mLastMoveAck - mExtMoveVec.size(),32);
  270. }
  271. void ExtendedMoveList::clientReadMovePacket(BitStream * bstream)
  272. {
  273. #ifdef TORQUE_DEBUG_NET_MOVES
  274. Con::printf("pre move ack: %i", mLastMoveAck);
  275. #endif
  276. mLastMoveAck = bstream->readInt(32);
  277. #ifdef TORQUE_DEBUG_NET_MOVES
  278. Con::printf("post move ack %i, first move %i, last move %i", mLastMoveAck, mFirstMoveIndex, mLastClientMove);
  279. #endif
  280. if (mLastMoveAck < mFirstMoveIndex)
  281. mLastMoveAck = mFirstMoveIndex;
  282. if(mLastMoveAck > mLastClientMove)
  283. mLastClientMove = mLastMoveAck;
  284. while(mFirstMoveIndex < mLastMoveAck)
  285. {
  286. if (mExtMoveVec.size())
  287. {
  288. mExtMoveVec.pop_front();
  289. mFirstMoveIndex++;
  290. }
  291. else
  292. {
  293. AssertWarn(1, "Popping off too many moves!");
  294. mFirstMoveIndex = mLastMoveAck;
  295. }
  296. }
  297. }
  298. bool ExtendedMoveList::isBacklogged()
  299. {
  300. if ( !mConnection->isConnectionToServer() )
  301. return false;
  302. return mLastClientMove - mFirstMoveIndex == mExtMoveVec.size() &&
  303. mExtMoveVec.size() >= MaxMoveCount;
  304. }
  305. bool ExtendedMoveList::areMovesPending()
  306. {
  307. return mConnection->isConnectionToServer() ?
  308. mExtMoveVec.size() - mLastClientMove + mFirstMoveIndex :
  309. mExtMoveVec.size();
  310. }
  311. void ExtendedMoveList::ackMoves(U32 count)
  312. {
  313. mLastMoveAck += count;
  314. if(mLastMoveAck > mLastClientMove)
  315. mLastClientMove = mLastMoveAck;
  316. while(mFirstMoveIndex < mLastMoveAck)
  317. {
  318. if (mExtMoveVec.size())
  319. {
  320. mExtMoveVec.pop_front();
  321. mFirstMoveIndex++;
  322. }
  323. else
  324. {
  325. AssertWarn(1, "Popping off too many moves!");
  326. mFirstMoveIndex = mLastMoveAck;
  327. }
  328. }
  329. }