273 lines
6.5 KiB
C++
273 lines
6.5 KiB
C++
|
|
#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<IIClient*> 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
|
|
SteamErrMsg err;
|
|
if (SteamAPI_InitEx(&err) != k_ESteamAPIInitResult_OK)
|
|
{
|
|
Plat_FatalErrorFunc("Failed to init Steam: %s\n", err);
|
|
}
|
|
#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();
|
|
|
|
if (INetworking::IsClient())
|
|
{
|
|
MainMenu()->Init();
|
|
IConsoleUI::Init();
|
|
}
|
|
|
|
|
|
};
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Updates every frame
|
|
//-----------------------------------------------------------------------------
|
|
void IEngine::Frame(float fDelta)
|
|
{
|
|
IServer::Think(fDelta);
|
|
|
|
if (INetworking::IsClient())
|
|
{
|
|
MainMenu()->Frame();
|
|
IFGUI::Frame();
|
|
IVideo::Frame(fDelta);
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Deinitializes engine
|
|
//-----------------------------------------------------------------------------
|
|
void IEngine::Shutdown()
|
|
{
|
|
if (INetworking::IsClient())
|
|
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++;
|
|
}
|
|
};
|
|
|