openclonk/src/control/C4GameControl.h

172 lines
4.7 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2013-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
/* control management */
#ifndef INC_C4GameControl
#define INC_C4GameControl
#include "control/C4Control.h"
#include "control/C4Record.h"
enum C4ControlMode
{
CM_None,
CM_Local, // control = input
CM_Network, // control = input + network input
CM_Replay // control = replay
};
enum C4ControlDeliveryType
{
CDT_Queue = 0, // Send in control queue (sync)
CDT_Sync = 1, // Send, delay execution until net is sync (sync)
CDT_Direct = 2, // Send directly to all clients (not sync)
CDT_Private = 3, // Send only to some clients (not sync, obviously)
CDT_Decide // Use whatever sync mode seems fastest atm (sync)
};
// Additional notes / requirements:
// * Direct control always reaches all clients faster than queue control.
// * Sync is the only synchronous control mode were it's garantueed that
// the control is actually executed within a fixed time.
// * CDT_Decide is guesswork, control isn't garantueed to be faster.
#include "network/C4GameControlNetwork.h"
#ifdef _DEBUG
const int32_t C4SyncCheckRate = 1,
#else
const int32_t C4SyncCheckRate = 100,
#endif
C4SyncCheckMaxKeep = 50;
class C4GameControl
{
friend class C4ControlSyncCheck;
friend class C4GameControlNetwork;
public:
C4GameControl();
~C4GameControl();
public:
C4Control Input;
C4GameControlNetwork Network;
protected:
C4ControlMode eMode;
bool fInitComplete;
bool fHost; // (set for local, too)
bool fActivated;
bool fRecordNeeded;
int32_t iClientID;
C4Record *pRecord;
C4Playback *pPlayback;
C4Control SyncChecks;
C4GameControlClient *pClients;
C4Control *pExecutingControl; // Control that is in the process of being executed - needed by non-initial records
public:
// ticks
int32_t ControlRate;
int32_t ControlTick;
int32_t SyncRate;
bool DoSync;
public:
// configuration
bool isLocal() const { return eMode == CM_Local; }
bool isNetwork() const { return eMode == CM_Network; }
bool isReplay() const { return eMode == CM_Replay; }
bool isCtrlHost() const { return fHost; }
bool isRecord() const { return !! pRecord; }
C4Record * GetRecord() { return pRecord; }
int32_t ClientID() const { return iClientID; }
bool SyncMode() const { return eMode != CM_Local || pRecord; }
bool NoInput() const { return isReplay(); }
// client list
C4GameControlClient *getClient(int32_t iID);
C4GameControlClient *getClient(const char *szName);
// initialization
bool InitLocal(C4Client *pLocal);
bool InitNetwork(C4Client *pLocal);
bool InitReplay(C4Group &rGroup);
void ChangeToLocal();
void Clear();
void Default();
// records
bool StartRecord(bool fInitial, bool fStreaming);
void StopRecord(StdStrBuf *pRecordName = NULL, BYTE *pRecordSHA1 = NULL);
void RequestRuntimeRecord();
bool IsRuntimeRecordPossible() const;
bool RecAddFile(const char *szLocalFilename, const char *szAddAs);
// execution
bool Prepare();
void Execute();
void Ticks();
// public helpers
bool CtrlTickReached(int32_t iTick);
int32_t getCtrlTick(int32_t iFrame) const;
int32_t getNextControlTick() const;
// control rate
void AdjustControlRate(int32_t iBy);
bool KeyAdjustControlRate(int32_t iBy)
{ AdjustControlRate(iBy); return true; }
// activation
void SetActivated(bool fActivated);
// input
void DoInput(C4PacketType eCtrlType, C4ControlPacket *pPkt, C4ControlDeliveryType eDelivery);
void DbgRec(C4RecordChunkType eType, const uint8_t *pData=NULL, size_t iSize=0); // record debug stuff
C4ControlDeliveryType DecideControlDelivery();
// sync check
void DoSyncCheck();
// execute and record control (by self or C4GameControlNetwork)
void ExecControl(const C4Control &rCtrl);
void ExecControlPacket(C4PacketType eCtrlType, class C4ControlPacket *pPkt);
void OnGameSynchronizing(); // start record if desired
protected:
// sync checks
C4ControlSyncCheck *GetSyncCheck(int32_t iTick);
void RemoveOldSyncChecks();
// add per-controlframe input
void PrepareInput();
};
extern C4GameControl Control;
#endif // INC_C4GameControl