/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef ENGINE_CLIENT_CLIENT_H #define ENGINE_CLIENT_CLIENT_H class CGraph { public: enum { // restrictions: Must be power of two MAX_VALUES=128, }; float m_Min, m_Max; float m_aValues[MAX_VALUES]; float m_aColors[MAX_VALUES][3]; int m_Index; void Init(float Min, float Max); void ScaleMax(); void ScaleMin(); void Add(float v, float r, float g, float b); void Render(IGraphics *pGraphics, int Font, float x, float y, float w, float h, const char *pDescription); }; class CSmoothTime { int64 m_Snap; int64 m_Current; int64 m_Target; int64 m_RLast; int64 m_TLast; CGraph m_Graph; int m_SpikeCounter; float m_aAdjustSpeed[2]; // 0 = down, 1 = up public: void Init(int64 Target); void SetAdjustSpeed(int Direction, float Value); int64 Get(int64 Now); void UpdateInt(int64 Target); void Update(CGraph *pGraph, int64 Target, int TimeLeft, int AdjustDirection); }; class CClient : public IClient, public CDemoPlayer::IListner { // needed interfaces IEngine *m_pEngine; IEditor *m_pEditor; IEngineInput *m_pInput; IEngineGraphics *m_pGraphics; IEngineSound *m_pSound; IGameClient *m_pGameClient; IEngineMap *m_pMap; IConsole *m_pConsole; IStorage *m_pStorage; IEngineMasterServer *m_pMasterServer; enum { NUM_SNAPSHOT_TYPES=2, PREDICTION_MARGIN=1000/50/2, // magic network prediction value }; class CNetClient m_NetClient; class CDemoPlayer m_DemoPlayer; class CDemoRecorder m_DemoRecorder; class CServerBrowser m_ServerBrowser; class CFriends m_Friends; class CMapChecker m_MapChecker; char m_aServerAddressStr[256]; unsigned m_SnapshotParts; int64 m_LocalStartTime; int m_DebugFont; int64 m_LastRenderTime; float m_RenderFrameTimeLow; float m_RenderFrameTimeHigh; int m_RenderFrames; NETADDR m_ServerAddress; int m_WindowMustRefocus; int m_SnapCrcErrors; bool m_AutoScreenshotRecycle; bool m_EditorActive; bool m_SoundInitFailed; bool m_ResortServerBrowser; int m_AckGameTick; int m_CurrentRecvTick; int m_RconAuthed; int m_UseTempRconCommands; // version-checking char m_aVersionStr[10]; // pinging int64 m_PingStartTime; // char m_aCurrentMap[256]; unsigned m_CurrentMapCrc; // char m_aCmdConnect[256]; // map download char m_aMapdownloadFilename[256]; char m_aMapdownloadName[256]; IOHANDLE m_MapdownloadFile; int m_MapdownloadChunk; int m_MapdownloadCrc; int m_MapdownloadAmount; int m_MapdownloadTotalsize; // time CSmoothTime m_GameTime; CSmoothTime m_PredictedTime; // input struct // TODO: handle input better { int m_aData[MAX_INPUT_SIZE]; // the input data int m_Tick; // the tick that the input is for int64 m_PredictedTime; // prediction latency when we sent this input int64 m_Time; } m_aInputs[200]; int m_CurrentInput; // graphs CGraph m_InputtimeMarginGraph; CGraph m_GametimeMarginGraph; CGraph m_FpsGraph; // the game snapshots are modifiable by the game class CSnapshotStorage m_SnapshotStorage; CSnapshotStorage::CHolder *m_aSnapshots[NUM_SNAPSHOT_TYPES]; int m_RecivedSnapshots; char m_aSnapshotIncommingData[CSnapshot::MAX_SIZE]; class CSnapshotStorage::CHolder m_aDemorecSnapshotHolders[NUM_SNAPSHOT_TYPES]; char *m_aDemorecSnapshotData[NUM_SNAPSHOT_TYPES][2][CSnapshot::MAX_SIZE]; class CSnapshotDelta m_SnapshotDelta; // class CServerInfo m_CurrentServerInfo; int64 m_CurrentServerInfoRequestTime; // >= 0 should request, == -1 got info // version info struct CVersionInfo { enum { STATE_INIT=0, STATE_START, STATE_READY, }; int m_State; class CHostLookup m_VersionServeraddr; } m_VersionInfo; volatile int m_GfxState; static void GraphicsThreadProxy(void *pThis) { ((CClient*)pThis)->GraphicsThread(); } void GraphicsThread(); public: IEngine *Engine() { return m_pEngine; } IEngineGraphics *Graphics() { return m_pGraphics; } IEngineInput *Input() { return m_pInput; } IEngineSound *Sound() { return m_pSound; } IGameClient *GameClient() { return m_pGameClient; } IEngineMasterServer *MasterServer() { return m_pMasterServer; } IStorage *Storage() { return m_pStorage; } CClient(); // ----- send functions ----- virtual int SendMsg(CMsgPacker *pMsg, int Flags); int SendMsgEx(CMsgPacker *pMsg, int Flags, bool System=true); void SendInfo(); void SendEnterGame(); void SendReady(); virtual bool RconAuthed() { return m_RconAuthed != 0; } virtual bool UseTempRconCommands() { return m_UseTempRconCommands != 0; } void RconAuth(const char *pName, const char *pPassword); virtual void Rcon(const char *pCmd); virtual bool ConnectionProblems(); virtual bool SoundInitFailed() { return m_SoundInitFailed; } virtual int GetDebugFont() { return m_DebugFont; } void DirectInput(int *pInput, int Size); void SendInput(); // TODO: OPT: do this alot smarter! virtual int *GetInput(int Tick); const char *LatestVersion(); void VersionUpdate(); // ------ state handling ----- void SetState(int s); // called when the map is loaded and we should init for a new round void OnEnterGame(); virtual void EnterGame(); virtual void Connect(const char *pAddress); void DisconnectWithReason(const char *pReason); virtual void Disconnect(); virtual void GetServerInfo(CServerInfo *pServerInfo); void ServerInfoRequest(); int LoadData(); // --- void *SnapGetItem(int SnapID, int Index, CSnapItem *pItem); void SnapInvalidateItem(int SnapID, int Index); void *SnapFindItem(int SnapID, int Type, int ID); int SnapNumItems(int SnapID); void SnapSetStaticsize(int ItemType, int Size); void Render(); void DebugRender(); virtual void Quit(); virtual const char *ErrorString(); const char *LoadMap(const char *pName, const char *pFilename, unsigned WantedCrc); const char *LoadMapSearch(const char *pMapName, int WantedCrc); static int PlayerScoreComp(const void *a, const void *b); void ProcessConnlessPacket(CNetChunk *pPacket); void ProcessServerPacket(CNetChunk *pPacket); virtual int MapDownloadAmount() { return m_MapdownloadAmount; } virtual int MapDownloadTotalsize() { return m_MapdownloadTotalsize; } void PumpNetwork(); virtual void OnDemoPlayerSnapshot(void *pData, int Size); virtual void OnDemoPlayerMessage(void *pData, int Size); void Update(); void RegisterInterfaces(); void InitInterfaces(); void Run(); static void Con_Connect(IConsole::IResult *pResult, void *pUserData); static void Con_Disconnect(IConsole::IResult *pResult, void *pUserData); static void Con_Quit(IConsole::IResult *pResult, void *pUserData); static void Con_Minimize(IConsole::IResult *pResult, void *pUserData); static void Con_Ping(IConsole::IResult *pResult, void *pUserData); static void Con_Screenshot(IConsole::IResult *pResult, void *pUserData); static void Con_Rcon(IConsole::IResult *pResult, void *pUserData); static void Con_RconAuth(IConsole::IResult *pResult, void *pUserData); static void Con_AddFavorite(IConsole::IResult *pResult, void *pUserData); static void Con_RemoveFavorite(IConsole::IResult *pResult, void *pUserData); static void Con_Play(IConsole::IResult *pResult, void *pUserData); static void Con_Record(IConsole::IResult *pResult, void *pUserData); static void Con_StopRecord(IConsole::IResult *pResult, void *pUserData); static void Con_AddDemoMarker(IConsole::IResult *pResult, void *pUserData); static void ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); void RegisterCommands(); const char *DemoPlayer_Play(const char *pFilename, int StorageType); void DemoRecorder_Start(const char *pFilename, bool WithTimestamp); void DemoRecorder_HandleAutoStart(); void DemoRecorder_Stop(); void DemoRecorder_AddDemoMarker(); void AutoScreenshot_Start(); void AutoScreenshot_Cleanup(); void ServerBrowserUpdate(); }; #endif