mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 22:54:34 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
400
Engine/source/T3D/gameBase/std/stdGameProcess.cpp
Normal file
400
Engine/source/T3D/gameBase/std/stdGameProcess.cpp
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/gameBase/std/stdGameProcess.h"
|
||||
|
||||
#include "platform/profiler.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/dnet.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "core/frameAllocator.h"
|
||||
#include "core/util/refBase.h"
|
||||
#include "math/mPoint3.h"
|
||||
#include "math/mMatrix.h"
|
||||
#include "math/mathUtils.h"
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
#include "T3D/gameBase/std/stdMoveList.h"
|
||||
#include "T3D/fx/cameraFXMgr.h"
|
||||
|
||||
MODULE_BEGIN( ProcessList )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
StdServerProcessList::init();
|
||||
StdClientProcessList::init();
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
StdServerProcessList::shutdown();
|
||||
StdClientProcessList::shutdown();
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
void StdServerProcessList::init()
|
||||
{
|
||||
smServerProcessList = new StdServerProcessList();
|
||||
}
|
||||
|
||||
void StdServerProcessList::shutdown()
|
||||
{
|
||||
delete smServerProcessList;
|
||||
}
|
||||
|
||||
void StdClientProcessList::init()
|
||||
{
|
||||
smClientProcessList = new StdClientProcessList();
|
||||
}
|
||||
|
||||
void StdClientProcessList::shutdown()
|
||||
{
|
||||
delete smClientProcessList;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// local work class
|
||||
struct GameBaseListNode
|
||||
{
|
||||
GameBaseListNode()
|
||||
{
|
||||
mPrev=this;
|
||||
mNext=this;
|
||||
mObject=NULL;
|
||||
}
|
||||
|
||||
GameBaseListNode * mPrev;
|
||||
GameBaseListNode * mNext;
|
||||
GameBase * mObject;
|
||||
|
||||
void linkBefore(GameBaseListNode * obj)
|
||||
{
|
||||
// Link this before obj
|
||||
mNext = obj;
|
||||
mPrev = obj->mPrev;
|
||||
obj->mPrev = this;
|
||||
mPrev->mNext = this;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// ClientProcessList
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
StdClientProcessList::StdClientProcessList()
|
||||
{
|
||||
}
|
||||
|
||||
bool StdClientProcessList::advanceTime( SimTime timeDelta )
|
||||
{
|
||||
PROFILE_SCOPE( StdClientProcessList_AdvanceTime );
|
||||
|
||||
if ( doBacklogged( timeDelta ) )
|
||||
return false;
|
||||
|
||||
bool ret = Parent::advanceTime( timeDelta );
|
||||
ProcessObject *obj = NULL;
|
||||
|
||||
AssertFatal( mLastDelta >= 0.0f && mLastDelta <= 1.0f, "mLastDelta is not zero to one.");
|
||||
|
||||
obj = mHead.mProcessLink.next;
|
||||
while ( obj != &mHead )
|
||||
{
|
||||
if ( obj->isTicking() )
|
||||
obj->interpolateTick( mLastDelta );
|
||||
|
||||
obj = obj->mProcessLink.next;
|
||||
}
|
||||
|
||||
// Inform objects of total elapsed delta so they can advance
|
||||
// client side animations.
|
||||
F32 dt = F32(timeDelta) / 1000;
|
||||
|
||||
// Update camera FX.
|
||||
gCamFXMgr.update( dt );
|
||||
|
||||
obj = mHead.mProcessLink.next;
|
||||
while ( obj != &mHead )
|
||||
{
|
||||
obj->advanceTime( dt );
|
||||
obj = obj->mProcessLink.next;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void StdClientProcessList::onAdvanceObjects()
|
||||
{
|
||||
PROFILE_SCOPE( StdClientProcessList_OnAdvanceObjects );
|
||||
|
||||
GameConnection* connection = GameConnection::getConnectionToServer();
|
||||
if ( connection )
|
||||
{
|
||||
// process any demo blocks that are NOT moves, and exactly one move
|
||||
// we advance time in the demo stream by a move inserted on
|
||||
// each tick. So before doing the tick processing we advance
|
||||
// the demo stream until a move is ready
|
||||
if ( connection->isPlayingBack() )
|
||||
{
|
||||
U32 blockType;
|
||||
do
|
||||
{
|
||||
blockType = connection->getNextBlockType();
|
||||
bool res = connection->processNextBlock();
|
||||
// if there are no more blocks, exit out of this function,
|
||||
// as no more client time needs to process right now - we'll
|
||||
// get it all on the next advanceClientTime()
|
||||
if(!res)
|
||||
return;
|
||||
}
|
||||
while ( blockType != GameConnection::BlockTypeMove );
|
||||
}
|
||||
|
||||
connection->mMoveList->collectMove();
|
||||
advanceObjects();
|
||||
}
|
||||
else
|
||||
advanceObjects();
|
||||
}
|
||||
|
||||
void StdClientProcessList::onTickObject( ProcessObject *obj )
|
||||
{
|
||||
PROFILE_SCOPE( StdClientProcessList_OnTickObject );
|
||||
|
||||
// In case the object deletes itself during its processTick.
|
||||
SimObjectPtr<SceneObject> safePtr = static_cast<SceneObject*>( obj );
|
||||
|
||||
// Each object is either advanced a single tick, or if it's
|
||||
// being controlled by a client, ticked once for each pending move.
|
||||
Move* movePtr;
|
||||
U32 numMoves;
|
||||
GameConnection* con = obj->getControllingClient();
|
||||
if ( con && con->getControlObject() == obj )
|
||||
{
|
||||
con->mMoveList->getMoves( &movePtr, &numMoves );
|
||||
if ( numMoves )
|
||||
{
|
||||
// Note: should only have a single move at this point
|
||||
AssertFatal(numMoves==1,"ClientProccessList::onTickObject: more than one move in queue");
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum(obj->getControllingClient());
|
||||
#endif
|
||||
|
||||
if ( obj->isTicking() )
|
||||
obj->processTick( movePtr );
|
||||
|
||||
if ( bool(safePtr) && obj->getControllingClient() )
|
||||
{
|
||||
U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() );
|
||||
|
||||
// set checksum if not set or check against stored value if set
|
||||
movePtr->checksum = newsum;
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("move checksum: %i, (start %i), (move %f %f %f)",
|
||||
movePtr->checksum,sum,movePtr->yaw,movePtr->y,movePtr->z);
|
||||
#endif
|
||||
}
|
||||
con->mMoveList->clearMoves( 1 );
|
||||
}
|
||||
}
|
||||
else if ( obj->isTicking() )
|
||||
obj->processTick( 0 );
|
||||
}
|
||||
|
||||
void StdClientProcessList::advanceObjects()
|
||||
{
|
||||
PROFILE_SCOPE( StdClientProcessList_AdvanceObjects );
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("Advance client time...");
|
||||
#endif
|
||||
|
||||
Parent::advanceObjects();
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("---------");
|
||||
#endif
|
||||
}
|
||||
|
||||
void StdClientProcessList::clientCatchup( GameConnection * connection )
|
||||
{
|
||||
SimObjectPtr<GameBase> control = connection->getControlObject();
|
||||
if ( control )
|
||||
{
|
||||
Move * movePtr;
|
||||
U32 numMoves;
|
||||
U32 m = 0;
|
||||
connection->mMoveList->getMoves( &movePtr, &numMoves );
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("client catching up... (%i)", numMoves);
|
||||
#endif
|
||||
|
||||
preTickSignal().trigger();
|
||||
|
||||
if ( control->isTicking() )
|
||||
for ( m = 0; m < numMoves; m++ )
|
||||
control->processTick( movePtr++ );
|
||||
|
||||
connection->mMoveList->clearMoves( m );
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("---------");
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// ServerProcessList
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
StdServerProcessList::StdServerProcessList()
|
||||
{
|
||||
}
|
||||
|
||||
void StdServerProcessList::onPreTickObject( ProcessObject *pobj )
|
||||
{
|
||||
if ( pobj->mIsGameBase )
|
||||
{
|
||||
SimObjectPtr<GameBase> obj = getGameBase( pobj );
|
||||
|
||||
// Each object is either advanced a single tick, or if it's
|
||||
// being controlled by a client, ticked once for each pending move.
|
||||
GameConnection *con = obj->getControllingClient();
|
||||
|
||||
if ( con && con->getControlObject() == obj )
|
||||
{
|
||||
Move* movePtr;
|
||||
U32 numMoves;
|
||||
con->mMoveList->getMoves( &movePtr, &numMoves );
|
||||
|
||||
if ( numMoves == 0 )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("no moves on object %i, skip tick",obj->getId());
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Parent::onPreTickObject (pobj );
|
||||
}
|
||||
|
||||
void StdServerProcessList::onTickObject( ProcessObject *pobj )
|
||||
{
|
||||
PROFILE_SCOPE( StdServerProcessList_OnTickObject );
|
||||
|
||||
// Each object is either advanced a single tick, or if it's
|
||||
// being controlled by a client, ticked once for each pending move.
|
||||
|
||||
GameConnection *con = pobj->getControllingClient();
|
||||
|
||||
if ( pobj->mIsGameBase && con && con->getControlObject() == pobj )
|
||||
{
|
||||
// In case the object is deleted during its own tick.
|
||||
SimObjectPtr<GameBase> obj = getGameBase( pobj );
|
||||
|
||||
Move* movePtr;
|
||||
U32 m, numMoves;
|
||||
con->mMoveList->getMoves( &movePtr, &numMoves );
|
||||
|
||||
// For debugging it can be useful to know when this happens.
|
||||
//if ( numMoves > 1 )
|
||||
// Con::printf( "numMoves: %i", numMoves );
|
||||
|
||||
// Do we really need to test the control object each iteration? Does it change?
|
||||
for ( m = 0; m < numMoves && con && con->getControlObject() == obj; m++, movePtr++ )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
U32 sum = Move::ChecksumMask & obj->getPacketDataChecksum(obj->getControllingClient());
|
||||
#endif
|
||||
|
||||
if ( obj->isTicking() )
|
||||
obj->processTick( movePtr );
|
||||
|
||||
if ( con && con->getControlObject() == obj )
|
||||
{
|
||||
U32 newsum = Move::ChecksumMask & obj->getPacketDataChecksum( obj->getControllingClient() );
|
||||
|
||||
// check move checksum
|
||||
if ( movePtr->checksum != newsum )
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
if( !obj->isAIControlled() )
|
||||
Con::printf("move %i checksum disagree: %i != %i, (start %i), (move %f %f %f)",
|
||||
movePtr->id, movePtr->checksum,newsum,sum,movePtr->yaw,movePtr->y,movePtr->z);
|
||||
#endif
|
||||
|
||||
movePtr->checksum = Move::ChecksumMismatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("move %i checksum agree: %i == %i, (start %i), (move %f %f %f)",
|
||||
movePtr->id, movePtr->checksum,newsum,sum,movePtr->yaw,movePtr->y,movePtr->z);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
con->mMoveList->clearMoves( m );
|
||||
}
|
||||
else if ( pobj->isTicking() )
|
||||
pobj->processTick( 0 );
|
||||
}
|
||||
|
||||
void StdServerProcessList::advanceObjects()
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("Advance server time...");
|
||||
#endif
|
||||
|
||||
Parent::advanceObjects();
|
||||
|
||||
// Credit all connections with the elapsed tick
|
||||
SimGroup *clientGroup = Sim::getClientGroup();
|
||||
for(SimGroup::iterator i = clientGroup->begin(); i != clientGroup->end(); i++)
|
||||
{
|
||||
if (GameConnection *con = dynamic_cast<GameConnection *>(*i))
|
||||
{
|
||||
con->mMoveList->advanceMove();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("---------");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
82
Engine/source/T3D/gameBase/std/stdGameProcess.h
Normal file
82
Engine/source/T3D/gameBase/std/stdGameProcess.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _GAMEPROCESS_STD_H_
|
||||
#define _GAMEPROCESS_STD_H_
|
||||
|
||||
//#include "T3D/gameBase/processList.h"
|
||||
#ifndef _GAMEPROCESS_H_
|
||||
#include "T3D/gameBase/gameProcess.h"
|
||||
#endif
|
||||
|
||||
class GameBase;
|
||||
class GameConnection;
|
||||
struct Move;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
/// List to keep track of GameBases to process.
|
||||
class StdClientProcessList : public ClientProcessList
|
||||
{
|
||||
typedef ClientProcessList Parent;
|
||||
|
||||
protected:
|
||||
|
||||
// ProcessList
|
||||
void onTickObject(ProcessObject *);
|
||||
void advanceObjects();
|
||||
void onAdvanceObjects();
|
||||
|
||||
public:
|
||||
|
||||
StdClientProcessList();
|
||||
|
||||
// ProcessList
|
||||
bool advanceTime( SimTime timeDelta );
|
||||
|
||||
// ClientProcessList
|
||||
void clientCatchup( GameConnection *conn );
|
||||
|
||||
static void init();
|
||||
static void shutdown();
|
||||
};
|
||||
|
||||
class StdServerProcessList : public ServerProcessList
|
||||
{
|
||||
typedef ServerProcessList Parent;
|
||||
|
||||
protected:
|
||||
|
||||
// ProcessList
|
||||
void onPreTickObject( ProcessObject *pobj );
|
||||
void onTickObject( ProcessObject *pobj );
|
||||
void advanceObjects();
|
||||
|
||||
public:
|
||||
|
||||
StdServerProcessList();
|
||||
|
||||
static void init();
|
||||
static void shutdown();
|
||||
};
|
||||
|
||||
#endif // _GAMEPROCESS_STD_H_
|
||||
198
Engine/source/T3D/gameBase/std/stdMoveList.cpp
Normal file
198
Engine/source/T3D/gameBase/std/stdMoveList.cpp
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "T3D/gameBase/std/stdMoveList.h"
|
||||
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
#define MAX_MOVE_PACKET_SENDS 4
|
||||
|
||||
|
||||
StdMoveList::StdMoveList()
|
||||
{
|
||||
mMoveCredit = MaxMoveCount;
|
||||
}
|
||||
|
||||
U32 StdMoveList::getMoves(Move** movePtr,U32* numMoves)
|
||||
{
|
||||
if (!mConnection->isConnectionToServer())
|
||||
{
|
||||
if (mMoveVec.size() > mMoveCredit)
|
||||
mMoveVec.setSize(mMoveCredit);
|
||||
}
|
||||
return Parent::getMoves(movePtr,numMoves);
|
||||
}
|
||||
|
||||
void StdMoveList::clearMoves(U32 count)
|
||||
{
|
||||
if (!mConnection->isConnectionToServer())
|
||||
{
|
||||
count = mClamp(count,0,mMoveCredit);
|
||||
mMoveCredit -= count;
|
||||
}
|
||||
|
||||
Parent::clearMoves(count);
|
||||
}
|
||||
|
||||
void StdMoveList::advanceMove()
|
||||
{
|
||||
AssertFatal(!mConnection->isConnectionToServer(), "Cannot inc move credit on the client.");
|
||||
|
||||
// Game tick increment
|
||||
mMoveCredit++;
|
||||
if (mMoveCredit > MaxMoveCount)
|
||||
mMoveCredit = MaxMoveCount;
|
||||
|
||||
// Clear pending moves for the elapsed time if there
|
||||
// is no control object.
|
||||
if ( mConnection->getControlObject() == NULL )
|
||||
mMoveVec.clear();
|
||||
}
|
||||
|
||||
void StdMoveList::clientWriteMovePacket(BitStream *bstream)
|
||||
{
|
||||
AssertFatal(mLastMoveAck == mFirstMoveIndex, "Invalid move index.");
|
||||
U32 count = mMoveVec.size();
|
||||
|
||||
Move * move = mMoveVec.address();
|
||||
U32 start = mLastMoveAck;
|
||||
U32 offset;
|
||||
for(offset = 0; offset < count; offset++)
|
||||
if(move[offset].sendCount < MAX_MOVE_PACKET_SENDS)
|
||||
break;
|
||||
if(offset == count && count != 0)
|
||||
offset--;
|
||||
|
||||
start += offset;
|
||||
count -= offset;
|
||||
|
||||
if (count > MaxMoveCount)
|
||||
count = MaxMoveCount;
|
||||
bstream->writeInt(start,32);
|
||||
bstream->writeInt(count,MoveCountBits);
|
||||
Move * prevMove = NULL;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
move[offset + i].sendCount++;
|
||||
move[offset + i].pack(bstream,prevMove);
|
||||
bstream->writeInt(move[offset + i].checksum,Move::ChecksumBits);
|
||||
prevMove = &move[offset+i];
|
||||
}
|
||||
}
|
||||
|
||||
void StdMoveList::serverReadMovePacket(BitStream *bstream)
|
||||
{
|
||||
// Server side packet read.
|
||||
U32 start = bstream->readInt(32);
|
||||
U32 count = bstream->readInt(MoveCountBits);
|
||||
|
||||
Move * prevMove = NULL;
|
||||
Move prevMoveHolder;
|
||||
|
||||
// Skip forward (must be starting up), or over the moves
|
||||
// we already have.
|
||||
int skip = mLastMoveAck - start;
|
||||
if (skip < 0)
|
||||
{
|
||||
mLastMoveAck = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skip > count)
|
||||
skip = count;
|
||||
for (int i = 0; i < skip; i++)
|
||||
{
|
||||
prevMoveHolder.unpack(bstream,prevMove);
|
||||
prevMoveHolder.checksum = bstream->readInt(Move::ChecksumBits);
|
||||
prevMove = &prevMoveHolder;
|
||||
S32 idx = mMoveVec.size()-skip+i;
|
||||
if (idx>=0)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
if (mMoveVec[idx].checksum != prevMoveHolder.checksum)
|
||||
Con::printf("updated checksum on move %i from %i to %i",mMoveVec[idx].id,mMoveVec[idx].checksum,prevMoveHolder.checksum);
|
||||
#endif
|
||||
mMoveVec[idx].checksum = prevMoveHolder.checksum;
|
||||
}
|
||||
}
|
||||
start += skip;
|
||||
count = count - skip;
|
||||
}
|
||||
|
||||
// Put the rest on the move list.
|
||||
int index = mMoveVec.size();
|
||||
mMoveVec.increment(count);
|
||||
while (index < mMoveVec.size())
|
||||
{
|
||||
mMoveVec[index].unpack(bstream,prevMove);
|
||||
mMoveVec[index].checksum = bstream->readInt(Move::ChecksumBits);
|
||||
prevMove = &mMoveVec[index];
|
||||
mMoveVec[index].id = start++;
|
||||
index ++;
|
||||
}
|
||||
|
||||
mLastMoveAck += count;
|
||||
}
|
||||
|
||||
void StdMoveList::serverWriteMovePacket(BitStream * bstream)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("ack %i minus %i",mLastMoveAck,mMoveVec.size());
|
||||
#endif
|
||||
|
||||
// acknowledge only those moves that have been ticked
|
||||
bstream->writeInt(mLastMoveAck - mMoveVec.size(),32);
|
||||
}
|
||||
|
||||
void StdMoveList::clientReadMovePacket(BitStream * bstream)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("pre move ack: %i", mLastMoveAck);
|
||||
#endif
|
||||
|
||||
mLastMoveAck = bstream->readInt(32);
|
||||
|
||||
#ifdef TORQUE_DEBUG_NET_MOVES
|
||||
Con::printf("post move ack %i, first move %i, last move %i", mLastMoveAck, mFirstMoveIndex, mLastClientMove);
|
||||
#endif
|
||||
|
||||
if (mLastMoveAck < mFirstMoveIndex)
|
||||
mLastMoveAck = mFirstMoveIndex;
|
||||
|
||||
if(mLastMoveAck > mLastClientMove)
|
||||
mLastClientMove = mLastMoveAck;
|
||||
while(mFirstMoveIndex < mLastMoveAck)
|
||||
{
|
||||
if (mMoveVec.size())
|
||||
{
|
||||
mMoveVec.pop_front();
|
||||
mFirstMoveIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertWarn(1, "Popping off too many moves!");
|
||||
mFirstMoveIndex = mLastMoveAck;
|
||||
}
|
||||
}
|
||||
}
|
||||
55
Engine/source/T3D/gameBase/std/stdMoveList.h
Normal file
55
Engine/source/T3D/gameBase/std/stdMoveList.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MOVELIST_STD_H_
|
||||
#define _MOVELIST_STD_H_
|
||||
|
||||
#ifndef _MOVELIST_H_
|
||||
#include "T3D/gameBase/moveList.h"
|
||||
#endif
|
||||
|
||||
class StdMoveList : public MoveList
|
||||
{
|
||||
typedef MoveList Parent;
|
||||
|
||||
public:
|
||||
|
||||
StdMoveList();
|
||||
|
||||
void clientWriteMovePacket(BitStream *);
|
||||
void clientReadMovePacket(BitStream *);
|
||||
|
||||
void serverWriteMovePacket(BitStream *);
|
||||
void serverReadMovePacket(BitStream *);
|
||||
|
||||
U32 getMoves(Move**,U32* numMoves);
|
||||
void clearMoves(U32 count);
|
||||
|
||||
void advanceMove();
|
||||
void onAdvanceObjects() {}
|
||||
|
||||
protected:
|
||||
|
||||
U32 mMoveCredit;
|
||||
};
|
||||
|
||||
#endif // _MOVELIST_STD_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue