#include "fgui/fgui.h" #include "input.h" #include "mainmenu.h" #include "networking.h" #include "tier0/network.h" #include "tier0/platform.h" #include "tier1/commandline.h" #include "tier1/utlstring.h" #include "tier0/lib.h" #include "console.h" #include "filesystem.h" #include "rendering.h" #include "engine.h" #include "baseentity.h" #include "server.h" #include "physics.h" #include "signal.h" #include "steam/steam_api.h" #include "steam/isteamgameserver.h" #include "steam/steam_gameserver.h" #include "networking.h" double fPrev = 0; double fCurrent = 0; funnyphysics *px; IIClient *g_localClient; CUtlVector g_clients = {}; //----------------------------------------------------------------------------- // Purpose: Engine entry point //----------------------------------------------------------------------------- extern "C" void FunnyMain( int argc, char **argv ) { ICommandLine::CreateCommandLine(argc, argv); IEngine::Init(); for (;;) { fPrev = fCurrent; fCurrent = Plat_GetTime(); IEngine::Frame(fCurrent-fPrev); }; /* deinit is handled explicitly */ }; //----------------------------------------------------------------------------- // Purpose: Recieves signals from the system //----------------------------------------------------------------------------- void IEngine_Signal(int sig) { printf("Trapped signal %i\n",sig); switch (sig) { case SIGSEGV: case SIGILL: case SIGABRT: printf("Consider running app with debugger attached\n"); Plat_Backtrace(); break; default: break; }; IEngine::Shutdown(); Plat_Exit(0); }; //----------------------------------------------------------------------------- // Purpose: Initializes engine //----------------------------------------------------------------------------- void IEngine::Init() { /* trap signals */ #ifdef __linux__ signal(SIGHUP, IEngine_Signal); signal(SIGINT, IEngine_Signal); signal(SIGQUIT, IEngine_Signal); signal(SIGILL, IEngine_Signal); signal(SIGTRAP, IEngine_Signal); signal(SIGIOT, IEngine_Signal); signal(SIGBUS, IEngine_Signal); signal(SIGFPE, IEngine_Signal); signal(SIGSEGV, IEngine_Signal); signal(SIGTERM, IEngine_Signal); #endif #ifdef __WIN32__ signal(SIGINT, IEngine_Signal); signal(SIGILL, IEngine_Signal); signal(SIGFPE, IEngine_Signal); signal(SIGSEGV, IEngine_Signal); signal(SIGTERM, IEngine_Signal); #endif #ifdef STEAM_ENABLED if (!SteamAPI_Init()) { Plat_FatalErrorFunc("Failed to init Steam\n"); } #endif FileSystem()->InitFilesystem(); px = px_init(); if (!ICommandLine::CheckParam("-dedicated")) { // Run local client g_localClient = new IIClient(); IIEngine::ConnectClient(g_localClient); // Init IO IVideo::Init(); IInput::Init(); IInput::SetInputMode(INPUT_MODE_MENU); IFGUI::Init(); }; INetworking::Init(); // load game IServer::LoadGame("funnygame"); // create pipelines for rendering if (!ICommandLine::CheckParam("-dedicated")) IVideo::CreatePipelines(); // execute default config Console()->AddCommand("exec default.cfg;"); Console()->Execute(); MainMenu()->Init(); IConsoleUI::Init(); }; //----------------------------------------------------------------------------- // Purpose: Updates every frame //----------------------------------------------------------------------------- void IEngine::Frame(float fDelta) { IServer::Think(fDelta); if (!ICommandLine::CheckParam("-dedicated")) { MainMenu()->Frame(); IFGUI::Frame(); IVideo::Frame(fDelta); } }; //----------------------------------------------------------------------------- // Purpose: Deinitializes engine //----------------------------------------------------------------------------- void IEngine::Shutdown() { MainMenu()->Deinit(); INetworking::Deinit(); }; //----------------------------------------------------------------------------- // Purpose: Spawns entity in the world //----------------------------------------------------------------------------- uint64_t g_lastServerID = 1; uint64_t g_lastPredictedID = 1; CBaseEntity *IIEngine::SpawnEntity( const char *szName ) { for (auto &entity: EntityManager()->m_RegisteredEntities) { if (!V_strcmp(entity->m_szName, szName)) { CBaseEntity *pEnt = entity->m_pfn(); pEnt->m_id = g_lastPredictedID+=1; EntityManager()->m_entities.AppendTail(pEnt); if (ICommandLine::CheckParam("-dedicated")) return pEnt; if (entity->m_pClientfn) { pEnt->pClientEntity = entity->m_pClientfn(); pEnt->pClientEntity->pEntity = pEnt; } return pEnt; } } return 0; }; //----------------------------------------------------------------------------- // Purpose: Spawns entity without any parameters //----------------------------------------------------------------------------- void IIEngine::InitEntity( CBaseEntity *pEntity ) { if (!pEntity) return; pEntity->Spawn(); if (pEntity->pClientEntity) pEntity->pClientEntity->Spawn(); }; //----------------------------------------------------------------------------- // Purpose: Destroys entity //----------------------------------------------------------------------------- void IIEngine::DestroyEntity( CBaseEntity *pEntity ) { uint32_t i = 0; if (pEntity == NULL) return; for (auto &entity: EntityManager()->m_entities) { if (pEntity == entity) { pEntity->Destroy(); if (pEntity->pClientEntity) pEntity->pClientEntity->Destroy(); EntityManager()->m_entities.RemoveAt(i); return; } i++; } }; //----------------------------------------------------------------------------- // Purpose: Connects client to the server //----------------------------------------------------------------------------- void IIEngine::ConnectClient( IIClient *pClient ) { g_clients.AppendTail(pClient); } //----------------------------------------------------------------------------- // Purpose: Disconnects client from the server //----------------------------------------------------------------------------- void IIEngine::DisconnectClient( IIClient *pClient ) { DisconnectClient(pClient->playerID); } void IIEngine::DisconnectClient( uint64_t playerID ) { uint32_t i = 0; for (auto &client: g_clients) { if (client->playerID == playerID) { g_clients.RemoveAt(i); break; } i++; } }; void IIEngine::DisconnectClientByHandle( uint32_t playerHandle ) { uint32_t i = 0; for (auto &client: g_clients) { if (client->playerHandle == playerHandle) { IIEngine::DestroyEntity((CBaseEntity*)client->pBasePlayer); g_clients.RemoveAt(i); break; } i++; } };