1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 5 * Copyright (c) 2013-2016, The OpenClonk Team and contributors 6 * 7 * Distributed under the terms of the ISC license; see accompanying file 8 * "COPYING" for details. 9 * 10 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 11 * See accompanying file "TRADEMARK" for details. 12 * 13 * To redistribute this file separately, substitute the full license texts 14 * for the above references. 15 */ 16 /* control management */ 17 18 #ifndef INC_C4GameControl 19 #define INC_C4GameControl 20 21 #include "control/C4Control.h" 22 #include "control/C4Record.h" 23 24 enum C4ControlMode 25 { 26 CM_None, 27 CM_Local, // control = input 28 CM_Network, // control = input + network input 29 CM_Replay // control = replay 30 }; 31 32 enum C4ControlDeliveryType 33 { 34 CDT_Queue = 0, // Send in control queue (sync) 35 CDT_Sync = 1, // Send, delay execution until net is sync (sync) 36 CDT_Direct = 2, // Send directly to all clients (not sync) 37 CDT_Private = 3, // Send only to some clients (not sync, obviously) 38 39 CDT_Decide // Use whatever sync mode seems fastest atm (sync) 40 }; 41 42 // Additional notes / requirements: 43 // * Direct control always reaches all clients faster than queue control. 44 // * Sync is the only synchronous control mode were it's garantueed that 45 // the control is actually executed within a fixed time. 46 // * CDT_Decide is guesswork, control isn't garantueed to be faster. 47 48 #include "network/C4GameControlNetwork.h" 49 50 #ifdef _DEBUG 51 const int32_t C4SyncCheckRate = 1, 52 #else 53 const int32_t C4SyncCheckRate = 100, 54 #endif 55 C4SyncCheckMaxKeep = 50; 56 57 class C4GameControl 58 { 59 friend class C4ControlSyncCheck; 60 friend class C4GameControlNetwork; 61 public: 62 C4GameControl(); 63 ~C4GameControl(); 64 65 public: 66 C4Control Input; 67 C4GameControlNetwork Network; 68 69 protected: 70 C4ControlMode eMode; 71 bool fInitComplete; 72 bool fHost; // (set for local, too) 73 bool fActivated; 74 bool fRecordNeeded; 75 int32_t iClientID; 76 77 C4Record *pRecord; 78 C4Playback *pPlayback; 79 80 C4Control SyncChecks; 81 82 C4GameControlClient *pClients; 83 84 C4Control *pExecutingControl; // Control that is in the process of being executed - needed by non-initial records 85 86 public: 87 // ticks 88 int32_t ControlRate; 89 int32_t ControlTick; 90 int32_t SyncRate; 91 bool DoSync; 92 93 public: 94 95 // configuration isLocal()96 bool isLocal() const { return eMode == CM_Local; } isNetwork()97 bool isNetwork() const { return eMode == CM_Network; } isReplay()98 bool isReplay() const { return eMode == CM_Replay; } isCtrlHost()99 bool isCtrlHost() const { return fHost; } isRecord()100 bool isRecord() const { return !! pRecord; } GetRecord()101 C4Record * GetRecord() { return pRecord; } ClientID()102 int32_t ClientID() const { return iClientID; } SyncMode()103 bool SyncMode() const { return eMode != CM_Local || pRecord; } 104 NoInput()105 bool NoInput() const { return isReplay(); } 106 107 // client list 108 C4GameControlClient *getClient(int32_t iID); 109 C4GameControlClient *getClient(const char *szName); 110 111 // initialization 112 bool InitLocal(C4Client *pLocal); 113 bool InitNetwork(C4Client *pLocal); 114 bool InitReplay(C4Group &rGroup); 115 116 void ChangeToLocal(); 117 118 void Clear(); 119 void Default(); 120 121 // records 122 bool StartRecord(bool fInitial, bool fStreaming); 123 void StopRecord(StdStrBuf *pRecordName = nullptr, BYTE *pRecordSHA1 = nullptr); 124 void RequestRuntimeRecord(); 125 bool IsRuntimeRecordPossible() const; 126 bool RecAddFile(const char *szLocalFilename, const char *szAddAs); 127 128 // execution 129 bool Prepare(); 130 void Execute(); 131 void Ticks(); 132 133 // public helpers 134 bool CtrlTickReached(int32_t iTick); 135 int32_t getCtrlTick(int32_t iFrame) const; 136 int32_t getNextControlTick() const; 137 138 // control rate 139 void AdjustControlRate(int32_t iBy); KeyAdjustControlRate(int32_t iBy)140 bool KeyAdjustControlRate(int32_t iBy) 141 { AdjustControlRate(iBy); return true; } 142 143 // activation 144 void SetActivated(bool fActivated); 145 146 // input 147 void DoInput(C4PacketType eCtrlType, C4ControlPacket *pPkt, C4ControlDeliveryType eDelivery); 148 void DbgRec(C4RecordChunkType eType, const uint8_t *pData=nullptr, size_t iSize=0); // record debug stuff 149 C4ControlDeliveryType DecideControlDelivery(); 150 151 // sync check 152 void DoSyncCheck(); 153 154 // execute and record control (by self or C4GameControlNetwork) 155 void ExecControl(const C4Control &rCtrl); 156 void ExecControlPacket(C4PacketType eCtrlType, class C4ControlPacket *pPkt); 157 void OnGameSynchronizing(); // start record if desired 158 159 protected: 160 161 // sync checks 162 C4ControlSyncCheck *GetSyncCheck(int32_t iTick); 163 void RemoveOldSyncChecks(); 164 165 // add per-controlframe input 166 void PrepareInput(); 167 168 }; 169 extern C4GameControl Control; 170 171 #endif // INC_C4GameControl 172