diff options
Diffstat (limited to 'src/parsec_server/include/e_simulator.h')
| -rwxr-xr-x | src/parsec_server/include/e_simulator.h | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/src/parsec_server/include/e_simulator.h b/src/parsec_server/include/e_simulator.h new file mode 100755 index 0000000..c339cf4 --- /dev/null +++ b/src/parsec_server/include/e_simulator.h @@ -0,0 +1,286 @@ +/* +* PARSEC HEADER: e_simulator.h +*/ + +#ifndef _E_SIMULATOR_H_ +#define _E_SIMULATOR_H_ + +#include "net_util.h" +#include "utl_math.h" // for playerlerp_s + +// forward decls -------------------------------------------------------------- +// +class E_Distributable; +class E_SimClientNetOutput; +class E_ClientInfo; +class E_GameServer; +class E_REList; +template <class T> class UTL_List; + + +//FIXME: +// gamecode stuff is skipped for now +#define GAMECODE( x ) {} + +// gamecode2 is executed +#define GAMECODE2( x ) x + + +// class holding a ship state ------------------------------------------------- +// +class E_SimShipState +{ +protected: + + Xmatrx m_ObjPosition; + fixed_t m_CurSpeed; + bams_t m_CurYaw; + bams_t m_CurPitch; + bams_t m_CurRoll; + geomv_t m_CurSlideHorz; + geomv_t m_CurSlideVert; + +public: + // standard ctor + E_SimShipState() + { + Reset(); + } + + // reset al data members + void Reset(); + + E_SimShipState& operator= ( E_SimShipState& _other ) + { + ASSERT( FALSE ); + return _other;//remove the warning without it + } + + // copy from other + E_SimShipState& CopyFrom( E_SimShipState& _other ) + { + memcpy( &m_ObjPosition, &_other.m_ObjPosition, sizeof( Xmatrx ) ); + m_CurSpeed = _other.m_CurSpeed; + m_CurYaw = _other.m_CurYaw; + m_CurPitch = _other.m_CurPitch; + m_CurRoll = _other.m_CurRoll; + m_CurSlideHorz = _other.m_CurSlideHorz; + m_CurSlideVert = _other.m_CurSlideVert; + + return *this; + } + + // copy information from ShipRemInfo struct + void CopyFromPlayerAndShipStatus( RE_PlayerAndShipStatus& _other ) + { + memcpy( &m_ObjPosition, &_other.ObjPosition, sizeof( Xmatrx ) ); + m_CurSpeed = _other.CurSpeed; + m_CurYaw = _other.CurYaw; + m_CurPitch = _other.CurPitch; + m_CurRoll = _other.CurRoll; + m_CurSlideHorz = _other.CurSlideHorz; + m_CurSlideVert = _other.CurSlideVert; + } + + // various get/set functions + pXmatrx GetObjPosition() { return m_ObjPosition; } + + //FIXME: get rid of friend classes + friend class E_SimClientState; + friend class E_REList; +}; + + +// class handling the network input for a client ----------------------------- +// +class E_SimClientState { +protected: + E_SimShipState* m_States; + int m_nNumStateSlots; + + E_SimShipState m_InputState; + dword m_nInputStateMessageID; + dword m_nLastInputStateMessageId; + + refframe_t m_LastSwitchToSimRefFrame; + + int m_nClientID; + + enum ClientMovementMode_t { CMM_SIMULATING, CMM_SMOOTHING }; + ClientMovementMode_t m_ClientMovementMode; + playerlerp_s m_playerlerp; + + bool_t m_ResyncClient; + bool_t m_ClientHasStateSync; + +public: + E_SimClientState() + { + m_States = NULL; + m_nNumStateSlots = -1; + m_nInputStateMessageID = 0; + m_nLastInputStateMessageId = 0; + m_ClientMovementMode = CMM_SIMULATING; + m_ResyncClient = FALSE; + m_LastSwitchToSimRefFrame = -1; + m_ClientHasStateSync = FALSE; + } + + ~E_SimClientState() + { + Reset(); + } + + // reset all data-members + void Reset() + { + if ( m_States != NULL ) { + delete []m_States; + m_States = NULL; + } + m_nNumStateSlots = -1; + m_nInputStateMessageID = 0; + m_nLastInputStateMessageId = 0; + m_InputState.Reset(); + m_ClientMovementMode = CMM_SIMULATING; + m_ResyncClient = FALSE; + m_LastSwitchToSimRefFrame = -1; + m_ClientHasStateSync = FALSE; + } + + // connect a client + void Connect( int nClientID ); + + // disconnect a client + void Disconnect() + { + Reset(); + } + + // check the movement bounds between the last received state + int CheckMovementBounds( dword MessageID, RE_PlayerAndShipStatus* pPAS ); + + // store the received state as the newest + void StoreNewState( dword MessageID, RE_PlayerAndShipStatus* pPAS ); + + // reset the sim state + void ForceNewState( E_SimShipState* pSimShipState ); + + // either apply simulation or smoothing to get newest client-state + void CalcNewState( refframe_t CurSimRefFrames ); + + // dump some SimClientState for debugging purposes + void Dump(); + + // return the current/last simulation-state-slot + E_SimShipState* GetCurSimFrameStateSlot(); + E_SimShipState* GetPrevSimFrameStateSlot(); + + // set the client resync flag ( RE_PLAYERANDSHIPSTATUS for this client sent from server to client ) + void SetClientResync() { m_ResyncClient = TRUE; } + + // clear the client resync flag + void ClearClientResync() { m_ResyncClient = FALSE; } + + // check whether we must resync this client + int NeedsResync() { return m_ResyncClient; } + + // Check whether state variables (nebula id, ammo pack sizes) have been sent + int HasState() { return m_ClientHasStateSync; } + + void SetState() { m_ClientHasStateSync = TRUE; } + +protected: + // calculate the newest smooothing target + void _CalcNewSmoothingTarget(); + + // check whether the change from the last to the current state involved a movement + int _CheckForMovement( dword MessageID, RE_PlayerAndShipStatus* pPAS ); + + // update the message ids the lateste state comes from ( dead reckoning ) + void _UpdateStateMessageID( dword MessageID ); +}; + + +// class for handling the overall simulation as well as all the states -------- +// +class E_Simulator { +protected: + + refframe_t m_CurRefFrame; // the current RefFrame + refframe_t m_CurSimRefFrames; // refframes to advance in current sim step + refframe_t m_LastSimRefFrame; // last sim refframe + + E_SimPlayerInfo* m_SimPlayerInfos; + E_SimClientState* m_SimClientState; + + int m_nSimFrame; + + // ctor/dtor + E_Simulator(); + ~E_Simulator(); + +public: + // SINGLETON access + static E_Simulator* GetSimulator() + { + static E_Simulator _TheSimulator; + return &_TheSimulator; + } + + // main simulation method + int DoSim( refframe_t CurSimRefFrame ); + + // get the PlayerInfo for a client + E_SimPlayerInfo* GetSimPlayerInfo( int nClientID ); + + // return the current simulation refframe + refframe_t GetCurSimRefFrame() { return m_CurRefFrame; } + + // return the refframes the simulation runs in this sim-frame + refframe_t GetThisFrameRefFrames() { return m_CurSimRefFrames; } + + // get the SimClientState for a specific client + E_SimClientState* GetSimClientState( int nClientID ); + + // get the latest valid player + E_SimShipState* GetLatestSimShipState( int nClientID ); + + // reset all data + void Reset(); + + // connect the player in a specific slot + int ConnectPlayer( int nClientID ); + + // disconnect the player in a specific slot + int DisconnectPlayer( int nClientID ); + + // check whether a player in a slot is joined + int IsPlayerJoined( int nClientID ); + + // check whether a player in a slot is connected + int IsPlayerDisconnected( int nClientID ); + + // return the current simulation frame + int GetSimFrame() { return m_nSimFrame; } + +protected: + + // update the shipstate ( according to the current sim refframes ) + void _UpdateShipState( int nClientID ); + + // simulate ship movements + void _SimulateShips(); + + // calculate the refframes we want to apply to this simulation step + int _CalcSimRefFrames(); + + // apply the current sim-state to the engine state ( E_SimShipState -> ShipObject ) + void _ApplySimToEngineState(); + + // apply the current engine state to the sim-state ( ShipObject -> E_SimShipState ) + void _ApplyEngineToSimState(); +}; + + +#endif // _E_SIMULATOR_H_ |
