#include "tier2/ifilesystem.h" #include "materialsystem/imaterialsystem.h" #include "enginebridge.h" #include "worldrender.h" #include "entitysystem.h" #include "baseentity.h" #include "game.h" #include "cglm/mat4.h" #include "cglm/cglm.h" #include "inetworkclient.h" #include "netprotocol.h" IFileSystem *filesystem; IRenderContext *g_pRenderContext; IGameWindow *g_pMainWindow; static CEngineVars s_vars; CEngineVars *g_pEngineVars = &s_vars; EngineConsts_t *g_pEngineConstants; INetworkBase *g_pServerBridge; class CFunnyGameBridge: public IEngineBridge { virtual void Init() override; virtual void Tick( float fDelta ) override; virtual void Frame( float fDelta ) override; virtual void Shutdown() override; virtual void ConnectInterface( const char *psz, void *pInterface ) override; }; IEngineBridge *EngineBridge() { static CFunnyGameBridge s_bridge; return &s_bridge; } EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION) void CFunnyGameBridge::Init() { g_pWorldRenderer->Init(); g_pServerBridge = g_pEngineConstants->ConnectLocalBridge(0); PlayerJoined_t join = { MESSAGE_PLAYER_JOINED, "LocalPlayer" }; g_pServerBridge->SendPacket({&join, sizeof(join)}); } void CFunnyGameBridge::Tick( float fDelta ) { } void *ENT_GetNetMapData(C_BaseEntity *pEntity, netmap_t *pMap, uint32_t uIndex ) { netmap_t *pCurrentMap = pMap; uint32_t uCurrentIndex = uIndex; searchIndex: if (uCurrentIndex >= pCurrentMap->m_uFieldCount) { if (!pCurrentMap->m_uFieldCount) return NULL; uCurrentIndex -= pCurrentMap->m_uFieldCount; pCurrentMap = pCurrentMap->m_pBase; if (!pCurrentMap) return NULL; goto searchIndex; } return (char*)pEntity+pCurrentMap->m_pFields[uCurrentIndex].m_uOffset; } void CFunnyGameBridge::Frame( float fDelta ) { g_pEngineVars->m_fTime += fDelta; g_pEngineVars->m_fDeltaTime = fDelta; g_pServerBridge->NetThink(); while ( g_pServerBridge->BHasUpdates() ) { NetPacket_t packet = g_pServerBridge->PeekPacket(); // discard it if (packet.uSize < sizeof (EMessageType)) continue; PlayerPacket_t *pPacket = (PlayerPacket_t*)packet.pData; C_BaseEntity *pEntity; switch (pPacket->m_eType) { case MESSAGE_ENTITY_CLASS_SYNC: pEntity = EntitySystem()->CreateByClassnameWithIndex( (char*)pPacket->m_entityClass.m_szEntityName, pPacket->m_entityClass.m_uIndex ); pEntity->Spawn(); g_pServerBridge->RecievePacket(); break; case MESSAGE_ENTITY_DATA_SYNC: pEntity = EntitySystem()->GetEntities()[pPacket->m_entityData.m_uIndex]; union { void *pData; char *pcCurrentData; EntityDataSyncValue_t *pcSyncValue; }; pData = pPacket; pcCurrentData += sizeof(EntityDataSync_t); for ( uint32_t u = 0; u < pPacket->m_entityData.m_uCount; u++ ) { uint32_t uVariableSize = pcSyncValue->m_uVariableSize; void *pValueData = (float*)ENT_GetNetMapData( pEntity, pEntity->GetRecvMap(), pcSyncValue->m_uVariableIndex); pcCurrentData += sizeof(EntityDataSyncValue_t); if (pValueData) V_memcpy(pValueData, pcCurrentData, uVariableSize); pcCurrentData += (uVariableSize+7) & ~7; } g_pServerBridge->RecievePacket(); break; default: continue; } } EntitySystem()->Think(); g_pWorldRenderer->Frame(fDelta); } void CFunnyGameBridge::Shutdown() { } #define CONNECT_INTERFACE(szName, pGlobal) if (!V_strcmp(psz, szName)) { pGlobal = (typeof(pGlobal))pInterface; return; } void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface ) { CONNECT_INTERFACE(RENDER_CONTEXT_INTERFACE_VERSION, g_pRenderContext); CONNECT_INTERFACE(FILESYSTEM_INTERFACE_VERSION, filesystem); CONNECT_INTERFACE("MainWindow", g_pMainWindow); CONNECT_INTERFACE("EngineConstants", g_pEngineConstants); }