Files
funnygame/engine/engine.cpp
2025-07-20 00:45:31 +03:00

268 lines
6.4 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
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++;
}
};