no engine anymore

This commit is contained in:
2025-07-30 23:53:26 +03:00
parent 8a29e6b86f
commit 395ced9e28
159 changed files with 2767 additions and 9484 deletions

View File

@@ -5,37 +5,16 @@
#include "tier1/commandline.h"
CUtlVector<CUtlString> engine_CompiledFiles = {
"engine/interface.cpp",
"engine/console.cpp",
"engine/filesystem.cpp",
"engine/server.cpp",
"engine/engine.cpp",
"engine/physics.cpp",
"engine/gamemode.cpp",
"engine/rendering.cpp",
/* io */
"engine/input.cpp",
"engine/networking.cpp",
/* audio */
"engine/ma_audio.cpp",
"engine/mesh.cpp",
/* entities */
"engine/baseentity.cpp",
"engine/level.cpp",
"engine/brush.cpp",
/* server entities */
"engine/sv_worldspawn.cpp",
"engine/sv_light.cpp",
"engine/sv_playerstart.cpp",
/* client entities */
"engine/cl_worldspawn.cpp",
"engine/cl_light.cpp",
"engine/engine.cpp",
"engine/cvar.cpp",
"engine/filesystem.cpp",
"engine/filesystem_pak.cpp",
"engine/filesystem_libc.cpp",
"engine/gamewindow_sdl.cpp",
"engine/sv_dll.cpp",
"engine/cl_dll.cpp",
};
CUtlVector<CUtlString> engine_Libraries = {
@@ -43,56 +22,39 @@ CUtlVector<CUtlString> engine_Libraries = {
"SDL3",
};
int engine_build()
{
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_IOS || Target_t::DefaultTarget().kernel == TARGET_KERNEL_DARWIN)
{
engine_CompiledFiles.AppendTail("engine/ml_videosdl.cpp");
engine_CompiledFiles.AppendTail("engine/ml_video.cpp");
engine_CompiledFiles.AppendTail("engine/ml_video.mm");
} else {
engine_CompiledFiles.AppendTail("engine/vk_videosdl.cpp");
engine_CompiledFiles.AppendTail("engine/vk_video.cpp");
}
if (Target_t::DefaultTarget().kernel == TARGET_KERNEL_LINUX)
{
engine_Libraries.AppendTail("vulkan");
}
CCProject compileProject = {};
CLDProject ldProject = {};
DECLARE_BUILD_STAGE(engine)
{
CProject_t compileProject = {};
LinkProject_t ldProject = {};
compileProject.m_szName = "engine";
compileProject.files = engine_CompiledFiles;
compileProject.includeDirectories = all_IncludeDirectories;
compileProject.bFPIC = true;
if (bStaticBuild)
compileProject.macros.AppendTail((C_Macro_t){"STATIC_BUILD","1"});
if (bSteam)
compileProject.macros.AppendTail((C_Macro_t){"STEAM_ENABLED","1"});
ldProject = compileProject.Compile();
ldProject.libraries = engine_Libraries;
ldProject = ccompiler->Compile(&compileProject);
if (bStaticBuild)
ldProject.linkType = ELINK_STATIC_LIBRARY;
else
{
ldProject.objects.AppendTail((CObject){tier1_lib});
ldProject.objects.AppendTail((CObject){fgui_lib});
ldProject.objects.AppendTail((CObject){rapier_lib});
ldProject.objects.AppendTail((Object_t){tier1_lib});
ldProject.objects.AppendTail((Object_t){rapier_lib});
if (bSteam)
ldProject.objects.AppendTail((CObject){steam_lib});
ldProject.objects.AppendTail((Object_t){steam_lib});
ldProject.linkType = ELINK_DYNAMIC_LIBRARY;
}
CUtlString outputProject = ldProject.Link();
ldProject.libraries = engine_Libraries;
CUtlString outputProject = linker->Link(&ldProject);
if (!bStaticBuild)
{
IFileSystem2::MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString()));
IFileSystem2::CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), outputProject);
filesystem2->MakeDirectory(CUtlString("%s/bin",szOutputDir.GetString()));
filesystem2->CopyFile(CUtlString("%s/bin", szOutputDir.GetString()), outputProject);
} else {
engine_lib = outputProject;
}
return 0;
};
DECLARE_BUILD_STAGE(engine, engine_build);

View File

@@ -1,81 +0,0 @@
#include "baseentity.h"
#include "tier0/platform.h"
#include "tier1/utlstring.h"
CBaseEntity::CBaseEntity()
{
glm_mat3_identity(m_matrix);
glm_vec3_zero(m_position);
glm_vec3_zero(m_scale);
};
void CBaseEntity::ReadParameter( const char *szName, const char *szValue )
{
CUtlString name = szName;
if (name == "origin")
V_sscanf(szValue, "%f %f %f", &m_position[0], &m_position[1], &m_position[2]);
}
void CBaseEntity::SetPosition( vec3 position )
{
V_memcpy(m_position, position, sizeof(vec3));
}
void CBaseEntity::SetRotationEuler( vec3 euler )
{
}
void CBaseEntity::SetRotationQuat( vec4 quaternion )
{
}
void CBaseEntity::SetRotationMatrix( mat3 matrix )
{
V_memcpy(m_matrix, matrix, sizeof(mat3));
}
void CBaseEntity::SetScale( vec3 scale )
{
V_memcpy(m_scale, scale, sizeof(vec3));
}
class CEntityManager: public IEntityManager
{
public:
virtual void Init() override {}
virtual void Frame() override {}
virtual void Deinit() override {}
};
DECLARE_ENGINE_INTERFACE(EntityManager, CEntityManager);
CEntityRegistryObject::CEntityRegistryObject(const char *szName, const char *szClass, EntityRegistryFn pfn) :
m_szName(szName), m_szClass(szClass), m_pfn(pfn), m_pClientfn(0)
{
for (auto &entity: EntityManager()->m_RegisteredEntities)
{
if (!V_strcmp(entity->m_szClass, szClass))
{
entity->m_szName = szName;
entity->m_pfn = pfn;
return;
}
}
EntityManager()->m_RegisteredEntities.AppendTail(this);
};
C_EntityRegistry::C_EntityRegistry( const char *szName, ClientEntityRegistryFn pfn )
{
for (auto &entity: EntityManager()->m_RegisteredEntities)
{
if (!V_strcmp(entity->m_szClass, szName))
{
entity->m_pClientfn = pfn;
return;
}
}
CEntityRegistryObject *pObject = new CEntityRegistryObject(0, szName, 0);
pObject->m_pClientfn = pfn;
}

View File

@@ -1,181 +0,0 @@
#include "brush.h"
#include "baseentity.h"
#include "cglm/mat4.h"
#include "physics.h"
#include "rendering.h"
#include "tier0/platform.h"
#include "tier1/utlbuffer.h"
#include "tier1/utlvector.h"
#include "math3d.h"
CUtlVector<IVertexBuffer*> g_BrushVertices;
void CBrushEntity::Precache()
{
}
void CBrushEntity::Spawn()
{
/* physics don't support unindexed meshes, so generate indicies */
CUtlBuffer<uint32_t> indicies(m_mesh.GetSize()*3);
for (uint32_t i = 0;i<indicies.GetSize();i++)
{
indicies[i]=i;
}
/* copy over the triangles to a separate buffer, which will be used by physics */
CUtlBuffer<Point<float>> triangles(m_mesh.GetSize()*3);
uint32_t i = 0;
for (auto tri: m_mesh)
{
V_memcpy(&triangles[i],tri.location,36);
i+=3;
}
/* use them */
px_collider_params params = {};
params.friction = 0.0;
m_collider = px_trimesh((Point<float>*)triangles.GetMemory(), triangles.GetSize(), (uint32_t(*)[3])indicies.GetMemory(), indicies.GetSize()/3 ,params);
px_fixedbody(px, m_collider);
};
void CBrushEntity::Destroy()
{
}
void CBrushEntity::Think( float fDelta )
{
};
void CBrushEntity::SendToServer()
{
};
void CBrushEntity::RecieveFromServer( void *pData, uint32_t nDataSize )
{
};
void CBrushEntity::ReadParameter( const char *szName, const char *szValue )
{
CBaseEntity::ReadParameter(szName, szValue);
};
void C_BrushEntity::Precache()
{
CBrushEntity* pBrushEntity = dynamic_cast<CBrushEntity*>(pEntity);
if (!pBrushEntity)
Plat_FatalErrorFunc("pEntity is not a CBrushEntity");
}
void C_BrushEntity::Spawn()
{
struct Vertex_t
{
float position[3];
float uv[2];
};
CBrushEntity* pBrushEntity = (CBrushEntity*)pEntity;
uint32_t numVertices = pBrushEntity->m_mesh.GetSize();
vertexBuffer = Renderer()->CreateVertexBuffer(numVertices*60);
Vertex_t *pTriangles = (Vertex_t*)vertexBuffer->Map();
uint32_t i = 0;
for (auto &triangle: pBrushEntity->m_mesh)
{
pTriangles[i].position[0] = triangle.location[0];
pTriangles[i].position[1] = triangle.location[1];
pTriangles[i].position[2] = triangle.location[2];
pTriangles[i].uv[0] = triangle.uv[0];
pTriangles[i].uv[1] = triangle.uv[1];
pTriangles[i+1].position[0] = triangle.location[3];
pTriangles[i+1].position[1] = triangle.location[4];
pTriangles[i+1].position[2] = triangle.location[5];
pTriangles[i+1].uv[0] = triangle.uv[2];
pTriangles[i+1].uv[1] = triangle.uv[3];
pTriangles[i+2].position[0] = triangle.location[6];
pTriangles[i+2].position[1] = triangle.location[7];
pTriangles[i+2].position[2] = triangle.location[8];
pTriangles[i+2].uv[0] = triangle.uv[4];
pTriangles[i+2].uv[1] = triangle.uv[5];
i+=3;
}
vertexBuffer->Unmap();
};
void C_BrushEntity::Destroy()
{
}
void C_BrushEntity::Think( float fDelta )
{
g_BrushVertices.AppendTail(vertexBuffer);
};
class CBrushRendering: public IRenderingPipelineStep
{
public:
virtual void Init() override;
virtual void Frame( float fDelta ) override;
virtual void Deinit() override;
private:
};
DECLARE_MESH_RENDERING_STAGE(CBrushRendering, brush_rasterizer);
IGraphicsPipeline *g_BrushPipeline;
ITexture *bricks;
void CBrushRendering::Init()
{
g_BrushPipeline = Renderer()->CreateGraphicsPipeline(
{
{"gfx/mesh_vert.shader", SHADER_TYPE_VERTEX},
{"gfx/mesh_frag.shader", SHADER_TYPE_FRAGMENT},
},
{
{SHADER_INPUT_TYPE_UNIFORM_BUFFER,0},
{SHADER_INPUT_TYPE_TEXTURES,1},
},
80,
20,
{{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32Z32}, {12,1,EVertexFormat::VERTEX_FORMAT_X32Y32}},
{EImageFormat::IMAGE_FORMAT_R8G8B8A8},
true
);
bricks = ITextureManager::LoadTexture("textures/bricks.png");
};
void CBrushRendering::Frame( float fDelta )
{
g_BrushPipeline->BindData(0, Renderer()->GetCameraMatrix(), 0);
g_BrushPipeline->PushBindings();
Renderer()->ResetState();
Renderer()->SetDepthMode(DEPTH_MODE_LESS);
Renderer()->BindPipeline(g_BrushPipeline);
struct {
mat4 i;
uint32_t a = ITextureManager::GetTextureID(bricks);
uint32_t b = 0;
uint32_t c = 0;
} constants;
glm_mat4_identity(constants.i);
Renderer()->SetConstants(sizeof(constants), &constants);
for (auto &v: g_BrushVertices)
{
Renderer()->Draw(v, 0);
}
g_BrushVertices = {};
};
void CBrushRendering::Deinit()
{
};

1
engine/cl_dll.cpp Normal file
View File

@@ -0,0 +1 @@

View File

@@ -1,31 +0,0 @@
#include "baseentity.h"
#include "rendering.h"
class C_Light: public C_BaseEntity
{
public:
virtual void Precache ( void ) override;
virtual void Spawn( void ) override;
virtual void Destroy( void ) override;
virtual void Think( float fDelta ) override;
};
void C_Light::Precache()
{
}
void C_Light::Spawn()
{
};
void C_Light::Destroy()
{
}
void C_Light::Think( float fDelta )
{
};
LINK_CLIENT_ENTITY(C_Light, CLight)

View File

@@ -1,33 +0,0 @@
#include "brush.h"
#include "rendering.h"
class C_WorldSpawn: public C_BrushEntity
{
public:
virtual void Precache ( void ) override;
virtual void Spawn( void ) override;
virtual void Destroy( void ) override;
virtual void Think( float fDelta ) override;
};
void C_WorldSpawn::Precache()
{
C_BrushEntity::Precache();
}
void C_WorldSpawn::Spawn()
{
C_BrushEntity::Spawn();
};
void C_WorldSpawn::Destroy()
{
C_BrushEntity::Destroy();
}
void C_WorldSpawn::Think( float fDelta )
{
C_BrushEntity::Think(fDelta);
};
LINK_CLIENT_ENTITY(C_WorldSpawn, CWorldSpawn)

View File

@@ -1 +0,0 @@
#include "client.h"

View File

@@ -1,407 +0,0 @@
#include "console.h"
#include "fgui/rect.h"
#include "fgui/widget.h"
#include "fgui/label.h"
#include "filesystem.h"
#include "interface.h"
#include "rendering.h"
#include "tier1/utlstring.h"
#include "tier1/utlvector.h"
#include "stdarg.h"
enum EConsoleMessageType
{
CONSOLE_MESSAGE_TYPE_MESSAGE,
CONSOLE_MESSAGE_TYPE_WARNING,
CONSOLE_MESSAGE_TYPE_ERROR,
};
struct ConsoleMessage_t
{
EConsoleMessageType type;
CUtlString szMessage;
};
void Msg( const char* message )
{
printf(message);
}
void Warning( const char* message )
{
}
void Error( const char* message )
{
}
interface CConsole: public IConsole
{
public:
virtual void Init() override;
virtual void Frame() override;
virtual void Deinit() override;
// Variables
virtual void RegisterVar( ConVar *cvar ) override;
virtual void UnRegisterVar( ConVar *cvar ) override;
virtual ConVar *FindVar( const char *pName ) override;
// Commands
virtual void RegisterCommand( ConCommand *cvar ) override;
virtual void UnRegisterCommand( ConCommand *cvar ) override;
virtual ConCommand *FindCommand( const char *pName ) override;
// Command buffer
virtual void Execute( void ) override;
virtual void ExecuteArguments( CUtlVector<CUtlString> &args ) override;
virtual CUtlVector<CUtlVector<CUtlString>> ParseCommandLine( CUtlString psz ) override;
virtual void AddCommand( const char *psz ) override;
virtual void InsertCommand( const char *psz ) override;
};
DECLARE_ENGINE_INTERFACE(Console, CConsole)
void CConsole::Init()
{
}
void CConsole::Frame()
{
}
void CConsole::Deinit()
{
}
void CConsole::RegisterVar( ConVar *cvar )
{
m_convars.AppendTail(cvar);
}
void CConsole::UnRegisterVar( ConVar *cvar )
{
}
ConVar *CConsole::FindVar( const char *pName )
{
for (auto &var: m_convars)
{
if (!V_strcmp(var->GetName(), pName))
return var;
}
return NULL;
}
void CConsole::RegisterCommand( ConCommand *cvar )
{
m_commands.AppendTail(cvar);
}
void CConsole::UnRegisterCommand( ConCommand *cvar )
{
}
ConCommand *CConsole::FindCommand( const char *pName )
{
for (auto &var: m_commands)
{
if (!V_strcmp(var->GetName(), pName))
return var;
}
return NULL;
}
CUtlString g_commandBuffer;
//-----------------------------------------------------------------------------
// Executes arguments from CConsole::Execute
//-----------------------------------------------------------------------------
void CConsole::ExecuteArguments( CUtlVector<CUtlString> &args )
{
if (args.GetSize()<1)
return;
ConCommand *cmd = CConsole::FindCommand(args[0]);
if (!cmd)
{
V_printf("%s not found\n", args[0].GetString());
return;
}
CUtlBuffer<char*> strbuffer(args.GetSize());
for ( size_t i = 0; i < args.GetSize(); i++)
{
strbuffer[i] = args[i].GetString();
};
(cmd->GetCallback())(args.GetSize(), strbuffer);
}
void CConsole::Execute( void )
{
CUtlVector<CUtlVector<CUtlString>> commands = ParseCommandLine(g_commandBuffer);
g_commandBuffer = 0;
for (auto &command: commands)
{
ExecuteArguments(command);
}
}
//-----------------------------------------------------------------------------
// Parses command buffer.
//-----------------------------------------------------------------------------
CUtlVector<CUtlVector<CUtlString>> CConsole::ParseCommandLine( CUtlString psz )
{
CUtlVector<CUtlString> arguments;
CUtlVector<CUtlVector<CUtlString>> commands;
CUtlString szArgument;
bool bIsQuote = false;
for ( auto &c: (CUtlVector<char>&)psz )
{
if ( c == '\"' )
{
bIsQuote = !bIsQuote;
continue;
}
if ( c == ';' || c == '\n' )
{
if (bIsQuote)
{
continue;
}
if (szArgument != 0)
arguments.AppendTail(szArgument);
if ( arguments.GetSize() > 0 )
commands.AppendTail(arguments);
szArgument = 0;
arguments = {};
continue;
}
if ( c == '\t' || c == ' ' )
{
if (bIsQuote)
{
szArgument.AppendTail(c);
continue;
}
if (szArgument != 0)
arguments.AppendTail(szArgument);
szArgument = 0;
continue;
}
szArgument.AppendTail(c);
};
if (szArgument != 0)
arguments.AppendTail(szArgument);
if ( arguments.GetSize() > 0 )
commands.AppendTail(arguments);
return commands;
}
void CConsole::AddCommand( const char *psz )
{
g_commandBuffer.AppendTail(psz);
}
void CConsole::InsertCommand( const char *psz )
{
g_commandBuffer.AppendHead(psz);
};
ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags )
: ConVar(pName, pDefaultValue, flags, 0)
{
}
ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString )
: ConVar(pName, pDefaultValue, flags, pHelpString, 0)
{
}
ConVar::ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, ConCommandFn callback )
{
m_szName = pName;
m_flags = flags;
m_szValue = pDefaultValue;
m_fValue = V_atof(pDefaultValue);
m_nValue = V_atoi(pDefaultValue);
Console()->RegisterVar(this);
}
bool ConVar::IsFlagSet( int flag )
{
}
const char *ConVar::GetHelpText( void )
{
return m_szHelpString;
}
bool ConVar::IsRegistered( void )
{
}
const char *ConVar::GetName( void )
{
return m_szName;
}
void ConVar::AddFlags( int flags )
{
}
bool ConVar::IsCommand( void )
{
}
void ConVar::InstallChangeCallback( ConCommandFn )
{
}
float ConVar::GetFloat( void )
{
return m_fValue;
}
int ConVar::GetInt( void )
{
return m_nValue;
}
bool ConVar::GetBool( void )
{
return m_nValue;
}
const char *ConVar::GetString( void )
{
}
void ConVar::SetValue( const char *szValue )
{
if (!szValue)
return;
m_szValue = szValue;
m_fValue = V_atof(szValue);
m_nValue = V_atoi(szValue);
}
void ConVar::SetValue( float fValue )
{
m_fValue = fValue;
m_nValue = fValue;
m_szValue = CUtlString("%f\n",fValue);
}
void ConVar::SetValue( int iValue )
{
m_fValue = iValue;
m_nValue = iValue;
m_szValue = CUtlString("%i\n",iValue);
}
ConCommand::ConCommand(const char *pName, ConCommandFn callback,
const char *pHelpString, int flags)
{
m_szName = pName;
m_callback = callback;
m_flags = flags;
Console()->RegisterCommand(this);
};
const char *ConCommand::GetHelpText( void )
{
return m_szHelpString;
}
const char *ConCommand::GetName( void )
{
return m_szName;
}
ConCommandFn ConCommand::GetCallback( void )
{
return m_callback;
}
void IConsole_Exec( int argc, char **argv)
{
if (argc != 2)
return;
FileHandle_t f = FileSystem()->Open(argv[1], IFILE_READ);
if (!f)
return;
CUtlBuffer<char> b(FileSystem()->Size(f)+1);
FileSystem()->Read(f, b, b.GetSize());
b[FileSystem()->Size(f)] = 0;
Console()->AddCommand(b);
Console()->AddCommand(";");
Console()->Execute();
}
ConCommand IConsole_ExecCmd("exec", IConsole_Exec);
class CConsoleGUI: public CFGUI_Widget
{
public:
CConsoleGUI();
virtual void Event( FGUI_Event_t event ) override;
virtual void Draw() override;
virtual void Frame() override;
private:
CFGUI_Rect *m_pBackground = 0;
CFGUI_Label *m_pLog = 0;
};
bool console_bDrawUI = false;
CConsoleGUI::CConsoleGUI()
{
m_pBackground = new CFGUI_Rect();
m_pBackground->SetBoxColor(0.13, 0.13, 0.13, 1);
m_pBackground->SetSize(200, 200);
m_pBackground->SetPosition(0, 0);
m_pBackground->SetParent(this);
m_pLog = new CFGUI_Label();
m_pLog->SetFont("fonts/IBMPlexMono-Regular");
m_pLog->SetLabel("CONSOLE");
m_pLog->SetPosition(0, 0);
m_pLog->SetGlyphSize(24);
m_pLog->SetParent(this);
};
void CConsoleGUI::Event( FGUI_Event_t event )
{
}
void CConsoleGUI::Draw()
{
SetPosition(20, 20);
m_pBackground->SetSize(g_nWindowWidth-40, g_nWindowHeight-40);
m_pBackground->SetSize(g_nWindowWidth-40, g_nWindowHeight-40);
}
void CConsoleGUI::Frame()
{
SetVisibility(console_bDrawUI);
}
void IConsoleUI::Init()
{
new CConsoleGUI;
};
void IConsoleUI::SetVisibility( bool bIsVisisble )
{
console_bDrawUI = bIsVisisble;
}
bool IConsoleUI::IsVisibile()
{
return console_bDrawUI;
}

View File

@@ -1,281 +1,26 @@
#include "fgui/fgui.h"
#include "input.h"
#include "mainmenu.h"
#include "networking.h"
#include "steam/steam_api_common.h"
#include "tier0/network.h"
#include "tier0/platform.h"
#include "ifilesystem.h"
#include "igamewindow.h"
#include "tier1/interface.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"
#include "tier0/mem.h"
#include "sv_dll.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)
extern "C" void FunnyMain( int argc, char **argv )
{
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);
};
CommandLine()->CreateCommandLine(argc, argv);
//-----------------------------------------------------------------------------
// 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
filesystem = (IFileSystem*)CreateInterface(FILESYSTEM_INTERFACE_NAME, NULL);
filesystem->Init();
#ifdef STEAM_ENABLED
if(SteamAPI_RestartAppIfNecessary(480))
{
Plat_Exit(0);
}
gamewindow = (IGameWindow*)CreateInterface(GAME_WINDOW_INTERFACE_NAME, NULL);
gamewindow->Init();
SteamErrMsg err;
if (SteamAPI_InitEx(&err) != k_ESteamAPIInitResult_OK)
{
Plat_FatalErrorFunc("Failed to init Steam: %s\n", err);
}
#endif
ServerGameDLL()->Init();
FileSystem()->InitFilesystem();
px = px_init();
if (!ICommandLine::CheckParam("-dedicated"))
{
// Run local client
g_localClient = new IIClient();
IIEngine::ConnectClient(g_localClient);
// Init IO
IVideo::Init();
Input()->Init();
Input()->SetInputMode(INPUT_MODE_MENU);
IFGUI::Init();
for (;;) {
gamewindow->UpdateWindow();
};
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)
{
#ifdef STEAM_ENABLED
SteamAPI_RunCallbacks();
#endif
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++;
}
};

View File

@@ -1,288 +1,86 @@
#include "interface.h"
#include "tier0/platform.h"
#include "tier1/commandline.h"
#include "filesystem.h"
#include "unistd.h"
#include <cstdio>
#include "ifilesystem.h"
#include "tier1/interface.h"
#include "tier0/lib.h"
#define BASEDIR "rtt"
#define GAMEDIR "funnygame"
struct PackHeader_t
size_t IFileHandle::Write( const void *pData, size_t nDataSize )
{
char id[8];
unsigned long long offset;
unsigned long long size;
};
struct PackDirectory_t
return m_pFileSystem->Write(this, pData, nDataSize);
}
size_t IFileHandle::Read( void *pData, size_t nDataSize )
{
char name[56];
unsigned long long offset;
unsigned long long size;
};
struct Pack_t
return m_pFileSystem->Read(this, pData, nDataSize);
}
size_t IFileHandle::Seek( ESeekMode eSeekMode, size_t nOffset )
{
FILE* handle;
PackHeader_t header;
CUtlVector<PackDirectory_t> files;
};
struct FileDirectory_t
return m_pFileSystem->Seek(this, eSeekMode, nOffset);
}
size_t IFileHandle::Tell( void )
{
CUtlString path;
Pack_t pack;
};
return m_pFileSystem->Tell(this);
}
void IFileHandle::Close( void )
{
m_pFileSystem->Close(this);
}
CUtlString fs_basedir;
CUtlString fs_gamedir;
CUtlSelfReferencingVector<FileDirectory_t> fs_directories;
interface CFileSystem: public IFileSystem
class CFileSystem : public IFileSystem
{
public:
virtual void Init() override {}
virtual void Frame() override {}
virtual void Deinit() override {}
virtual void InitFilesystem( void ) override;
virtual void AddGameDirectory( const char *psz ) override;
virtual bool LoadPackFile( const char *szFilename ) override;
virtual void CreatePath( const char *szPath ) override;
virtual FileHandle_t Open( const char *szFilename, EFileOptions options ) override;
virtual void Close( FileHandle_t file ) override;
virtual size_t Size( FileHandle_t file ) override;
virtual size_t Read( FileHandle_t file, void *pOutput, size_t nSize) override;
virtual size_t ReadLine( FileHandle_t file, void *pOutput, size_t nSize) override;
virtual size_t Write( FileHandle_t file, void *pInput, size_t nSize) override;
virtual size_t Seek( FileHandle_t file, size_t nSize) override;
virtual size_t Tell( FileHandle_t file, size_t nSize) override;
virtual size_t fprintf( FileHandle_t file, const char *szFormat, ...) override;
static void AddDirectory( const char *psz );
static void AddFile( const char *psz );
};
DECLARE_ENGINE_INTERFACE(FileSystem, CFileSystem);
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CFileSystem::InitFilesystem()
{
#ifdef STATIC_BUILD
fs_basedir = ICommandLine::ParamValue("-basedir");
if ( fs_basedir == 0 )
fs_basedir=BASEDIR;
if ( fs_basedir.GetString()[0] == '-' )
fs_basedir=BASEDIR;
fs_gamedir = ICommandLine::ParamValue("-gamedir");
if ( fs_gamedir == 0 )
fs_gamedir=GAMEDIR;
if ( fs_gamedir.GetString()[0] == '-' )
fs_gamedir=GAMEDIR;
AddGameDirectory(fs_gamedir);
#endif
AddGameDirectory(".");
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CFileSystem::AddFile( const char *psz )
{
CUtlString extension = Plat_GetExtension(psz);
if (extension=="pak")
{
FileSystem()->LoadPackFile(psz);
virtual void Init() override {
filesystem_backend = (IFileSystem*)CreateInterface(FILESYSTEM_BACKEND_INTERFACE_NAME, NULL);
filesystem_backend->Init();
filesystem_pak = (IFileSystem*)CreateInterface(FILESYSTEM_PAK_INTERFACE_NAME, NULL);
filesystem_pak->Init();
};
}
virtual void Shutdown() override {
//-----------------------------------------------------------------------------
// Adds directory which can contain pack files
//-----------------------------------------------------------------------------
void CFileSystem::AddGameDirectory( const char *psz )
{
FileDirectory_t dir = {};
dir.path = psz;
fs_directories.AppendTail(dir);
Plat_ListDirRecursive(psz, CFileSystem::AddFile, 0);
for (auto &dir: fs_directories)
{
V_printf("%s\n",(char*)dir.path);
};
virtual IFileHandle *Open( const char *szFileName, int eOpCode ) override
{
IFileHandle *pHandle = NULL;
pHandle = filesystem_pak->Open(szFileName, eOpCode);
if (pHandle) return pHandle;
pHandle = filesystem_backend->Open(szFileName, eOpCode);
if (pHandle) return pHandle;
return NULL;
}
virtual size_t Write( IFileHandle *pFile, const void *pData, size_t nDataSize ) override
{
return pFile->Write(pData, nDataSize);
}
virtual size_t Read( IFileHandle *pFile, void *pData, size_t nDataSize ) override
{
return pFile->Read(pData, nDataSize);
}
virtual size_t Seek( IFileHandle *pFile, ESeekMode eSeekMode, size_t nOffset ) override
{
return pFile->Seek(eSeekMode, nOffset);
}
virtual size_t Tell( IFileHandle *pFile ) override
{
return pFile->Tell();
}
virtual void Close( IFileHandle *pFile ) override
{
}
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CFileSystem::LoadPackFile( const char *szFilename )
{
Pack_t pack = {};
PackHeader_t header = {};
unsigned long long nNumFiles = 0;
PackDirectory_t *pDirs = NULL;
FILE* f = V_fopen(szFilename, "rb");
if (!f)
Plat_FatalErrorFunc("Failed to open %s",szFilename);
V_fread(&header,1,sizeof(header),f);
// check for rttpacku
if (
header.id[0]!='r' || header.id[1] != 't' || header.id[2] != 't' || header.id[3]!='p' ||
header.id[4]!='a' || header.id[5] != 'c' || header.id[6] != 'k' || header.id[7]!='u'
)
{
Plat_FatalErrorFunc("%s is not a pack file",szFilename);
}
nNumFiles = header.size/sizeof(PackDirectory_t);
pDirs = (PackDirectory_t*)V_malloc(header.size);
V_fseek(f, header.offset, SEEK_SET);
V_fread(pDirs, sizeof(PackDirectory_t), nNumFiles, f);
pack.header = header;
pack.handle = f;
pack.files = CUtlVector<PackDirectory_t>(nNumFiles);
V_memcpy(pack.files.GetData(),pDirs, header.size);
V_free(pDirs);
nNumFiles = header.size/sizeof(PackDirectory_t);
FileDirectory_t fd = {};
fd.path = szFilename;
fd.pack = pack;
fs_directories.AppendTail(fd);
return true;
}
//-----------------------------------------------------------------------------
// Creates path
//-----------------------------------------------------------------------------
void CFileSystem::CreatePath( const char *szPath )
{
}
//-----------------------------------------------------------------------------
// Opens file
// If it is located in a pack then it can only be read
//-----------------------------------------------------------------------------
FileHandle_t CFileSystem::Open( const char *szFilename, EFileOptions options )
{
if (options == IFILE_READ)
{
FILE *file = V_fopen(szFilename, "rb");
/* found in fs */
if ( file != NULL )
{
FileHandle_t filehandle = new FileHandle_s;
filehandle->file = file;
filehandle->nPtr = 0;
filehandle->options = IFILE_READ;
/* get size */
V_fseek(file, 0, SEEK_END);
filehandle->nSize = V_ftell(file);
V_fseek(file, 0, SEEK_SET);
return filehandle;
}
/* not found in fs, try to search in packs */
for ( auto &pak: fs_directories )
{
for ( auto &file: pak.pack.files )
{
if ( !strncmp(file.name, szFilename, 56) )
{
FileHandle_t filehandle = new FileHandle_s;
filehandle->file = 0;
filehandle->parent = pak.pack.handle;
filehandle->nSize = file.size;
filehandle->nOffset = file.offset;
filehandle->nPtr = 0;
filehandle->options = IFILE_READ;
return filehandle;
}
}
};
}
return 0;
}
//-----------------------------------------------------------------------------
// Closes file
//-----------------------------------------------------------------------------
void CFileSystem::Close( FileHandle_t file )
{
/* close only fs files */
if (file->file)
{
V_fclose(file->file);
}
delete file;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
size_t CFileSystem::Size( FileHandle_t file )
{
return file->nSize;
}
//-----------------------------------------------------------------------------
// Reads nSize bytes of file
//-----------------------------------------------------------------------------
size_t CFileSystem::Read( FileHandle_t file, void *pOutput, size_t nSize)
{
if (file->file)
{
size_t readsize = V_fread(pOutput, 1, nSize, file->file);
file->nPtr+=readsize;
return readsize;
}
size_t readsize = V_fseek(file->parent, file->nOffset, file->nPtr);
V_fread(pOutput, 1, nSize, file->parent);
return readsize;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
size_t CFileSystem::ReadLine( FileHandle_t file, void *pOutput, size_t nSize)
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
size_t CFileSystem::Write( FileHandle_t file, void *pInput, size_t nSize)
{
}
size_t CFileSystem::Seek( FileHandle_t file, size_t nSize)
{
}
size_t CFileSystem::Tell( FileHandle_t file, size_t nSize)
{
}
size_t CFileSystem::fprintf( FileHandle_t file, const char *szFormat, ...)
{
}
IFileSystem *filesystem;
IFileSystem *filesystem_backend;
IFileSystem *filesystem_pak;
EXPOSE_INTERFACE(CFileSystem, IFileSystem, FILESYSTEM_INTERFACE_NAME);

View File

@@ -0,0 +1,94 @@
#include "ifilesystem.h"
#include "tier1/interface.h"
#include "tier0/lib.h"
class CLIBCFileHandle : public IFileHandle
{
public:
FILE *m_pFile;
};
class CLIBCFileSystem : public IFileSystem
{
public:
virtual void Init() override {};
virtual void Shutdown() override {};
virtual IFileHandle *Open( const char *szFileName, int eOpCode ) override
{
const char *szOperation;
FILE *pFile;
CLIBCFileHandle *pHandle = NULL;
switch (eOpCode)
{
case FILEMODE_READ:
szOperation = "r";
break;
default:
V_printf("Operation is not supported\n");
break;
}
pFile = V_fopen(szFileName, szOperation);
if (!pFile)
return NULL;
pHandle = new CLIBCFileHandle;
pHandle->m_pFileSystem = this;
pHandle->m_pFile = pFile;
return pHandle;
}
virtual size_t Write( IFileHandle *pFile, const void *pData, size_t nDataSize ) override
{
return 0;
}
virtual size_t Read( IFileHandle *pFile, void *pData, size_t nDataSize ) override
{
CLIBCFileHandle *pHandle = (CLIBCFileHandle*)pFile;
if (!pHandle)
return 0;
return V_fread( pData, 1, nDataSize, pHandle->m_pFile );
}
virtual size_t Seek( IFileHandle *pFile, ESeekMode eSeekMode, size_t nOffset ) override
{
CLIBCFileHandle *pHandle = (CLIBCFileHandle*)pFile;
int eLibcSeekMode = 0;
switch (eSeekMode) {
case SEEKMODE_SET:
eLibcSeekMode = SEEK_SET;
break;
case SEEKMODE_RELATIVE_END:
eLibcSeekMode = SEEK_END;
break;
case SEEKMODE_RELATIVE_START:
eLibcSeekMode = SEEK_CUR;
break;
}
if (!pHandle)
return 0;
return V_fseek( pHandle->m_pFile, eLibcSeekMode, nOffset );
}
virtual size_t Tell( IFileHandle *pFile ) override
{
CLIBCFileHandle *pHandle = (CLIBCFileHandle*)pFile;
if (!pHandle)
return 0;
return V_ftell(pHandle->m_pFile);
}
virtual void Close( IFileHandle *pFile ) override
{
CLIBCFileHandle *pHandle = (CLIBCFileHandle*)pFile;
if (!pHandle)
return;
V_fclose(pHandle->m_pFile);
delete pHandle;
}
};
EXPOSE_INTERFACE(CLIBCFileSystem, IFileSystem, FILESYSTEM_BACKEND_INTERFACE_NAME);

81
engine/filesystem_pak.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include "ifilesystem.h"
#include "tier1/interface.h"
#include "tier0/lib.h"
class CPAKFileHandle : public IFileHandle
{
public:
};
class CPAKFileSystem : public IFileSystem
{
public:
virtual void Init() override {};
virtual void Shutdown() override {};
virtual IFileHandle *Open( const char *szFileName, int eOpCode ) override
{
const char *szOperation;
switch (eOpCode)
{
case FILEMODE_READ:
szOperation = "r";
break;
default:
V_printf("Operation is not supported\n");
break;
}
return 0;
CPAKFileHandle *pHandle = new CPAKFileHandle;
return pHandle;
}
virtual size_t Write( IFileHandle *pFile, const void *pData, size_t nDataSize ) override
{
return 0;
}
virtual size_t Read( IFileHandle *pFile, void *pData, size_t nDataSize ) override
{
CPAKFileHandle *pHandle = (CPAKFileHandle*)pFile;
if (!pHandle)
return 0;
return 0;
}
virtual size_t Seek( IFileHandle *pFile, ESeekMode eSeekMode, size_t nOffset ) override
{
int eLibcSeekMode = 0;
switch (eSeekMode) {
case SEEKMODE_SET:
eLibcSeekMode = SEEK_SET;
break;
case SEEKMODE_RELATIVE_END:
eLibcSeekMode = SEEK_END;
break;
case SEEKMODE_RELATIVE_START:
eLibcSeekMode = SEEK_CUR;
break;
}
CPAKFileHandle *pHandle = (CPAKFileHandle*)pFile;
if (!pHandle)
return 0;
}
virtual size_t Tell( IFileHandle *pFile ) override
{
CPAKFileHandle *pHandle = (CPAKFileHandle*)pFile;
if (!pHandle)
return 0;
}
virtual void Close( IFileHandle *pFile ) override
{
CPAKFileHandle *pHandle = (CPAKFileHandle*)pFile;
if (!pHandle)
return;
delete pHandle;
}
};
EXPOSE_INTERFACE(CPAKFileSystem, IFileSystem, FILESYSTEM_PAK_INTERFACE_NAME);

View File

@@ -1,165 +0,0 @@
#include "gamemode.h"
#include "engine.h"
#include "interface.h"
#include "playerstart.h"
#include "networking.h"
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
CGameMode *pCurrentMode = NULL;
CUtlString szCurrentModeName;
//-----------------------------------------------------------------------------
// Round begin handler
//-----------------------------------------------------------------------------
void CGameMode::RoundBegin( void )
{
size_t i = 0;
for (auto &start: g_PlayerStarts)
{
start->RoundEnd();
}
for (auto &player: g_clients)
{
CPlayerStart *pSelectedStart = NULL;
for (auto &start: g_PlayerStarts)
{
if (start->m_bIsRunning == false)
pSelectedStart = start;
};
if (pSelectedStart)
pSelectedStart->RoundStart(player);
i++;
}
for (auto &client: g_clients)
{
CSteamID steamID = CSteamID();
if ( client->playerID == 0)
V_printf("%s\t", SteamFriends()->GetPlayerNickname((uint64)client->playerID));
else
V_printf("%s\t", SteamFriends()->GetPersonaName());
V_printf("%llu\t", client->playerID);
V_printf("%u\n", client->playerHandle);
}
}
//-----------------------------------------------------------------------------
// Round end handler
//-----------------------------------------------------------------------------
void CGameMode::RoundEnd( void )
{
}
class CGameModeManager: public IGameModeManager
{
public:
virtual void Init( void ) override;
virtual void Frame( void ) override;
virtual void Deinit( void ) override;
virtual void StartGameMode( const char *szName ) override;
virtual const char *GetCurrentGameMode( void ) override;
virtual CGameMode *GetCurrentGameModeClass( void ) override;
virtual void RestartCurrentGameMode( void ) override;
};
DECLARE_ENGINE_INTERFACE(GameModeManager, CGameModeManager);
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameModeManager::Init( void )
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameModeManager::Frame( void )
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CGameModeManager::Deinit( void )
{
}
//-----------------------------------------------------------------------------
// Sets gamemode
//-----------------------------------------------------------------------------
void CGameModeManager::StartGameMode( const char *szName )
{
if (pCurrentMode)
{
pCurrentMode->RoundEnd();
delete pCurrentMode;
}
for (auto &mode: m_RegisteredGameModes)
{
if (!V_strcmp(mode->m_szName, szName))
{
pCurrentMode = mode->m_pfn();
pCurrentMode->RoundBegin();
szCurrentModeName = szName;
return;
}
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
const char *CGameModeManager::GetCurrentGameMode( void )
{
return szCurrentModeName;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CGameMode *CGameModeManager::GetCurrentGameModeClass( void )
{
return pCurrentMode;
}
//-----------------------------------------------------------------------------
// Restarts the gamemode
//-----------------------------------------------------------------------------
void CGameModeManager::RestartCurrentGameMode( void )
{
if (!pCurrentMode)
return;
if (INetworking::IsServer())
{
PacketGameMode_t mode = {};
mode.type = PACKET_TYPE_GAMEMODE_START;
V_memcpy(mode.szName,szCurrentModeName, min(szCurrentModeName.GetLenght(), 255));
for (auto &client: g_clients)
{
INetworking::SendData(&mode, sizeof(mode), client, MESSAGE_MODE_RELIABLE);
};
};
pCurrentMode->RoundEnd();
pCurrentMode->RoundBegin();
}
CGameModeRegistry::CGameModeRegistry(const char *szName, GameModeRegistryFn pfn) :
m_szName(szName), m_pfn(pfn)
{
GameModeManager()->m_RegisteredGameModes.AppendTail(this);
};

60
engine/gamewindow_sdl.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include "SDL3/SDL_error.h"
#include "igamewindow.h"
#include "tier1/interface.h"
#include "tier0/lib.h"
#include "tier0/platform.h"
#define SDL_MAIN_HANDLED
#include "SDL3/SDL.h"
#include "SDL3/SDL_init.h"
#include "SDL3/SDL_video.h"
#include "SDL3/SDL_vulkan.h"
#include "SDL3/SDL_events.h"
SDL_Window *g_pWindow;
IGameWindow *gamewindow;
class CSDLGameWindow: public IGameWindow
{
public:
virtual void Init() override;
virtual void Shutdown() override;
virtual void UpdateWindow() override;
};
void CSDLGameWindow::Init()
{
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD))
Plat_FatalErrorFunc("SDL_Init: %s\n", SDL_GetError());
g_pWindow = SDL_CreateWindow("funnygame", 1280, 720, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
if (!g_pWindow)
Plat_FatalErrorFunc("SDL_Init: %s\n", SDL_GetError());
}
void CSDLGameWindow::Shutdown()
{
}
void CSDLGameWindow::UpdateWindow()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_EVENT_QUIT:
SDL_Quit();
Plat_Exit(0);
break;
default:
break;
}
}
}
EXPOSE_INTERFACE(CSDLGameWindow, IGameWindow, GAME_WINDOW_INTERFACE_NAME);

View File

@@ -1,301 +0,0 @@
#include "input.h"
#include "console.h"
#include "interface.h"
#include "mainmenu.h"
#include "tier0/lib.h"
#include "tier1/commandline.h"
#include "math3d.h"
char g_PressedKeys[KEY_NUM_KEYS];
float g_fAxisValues[AXIS_NUM_AXIS];
float g_fAxisModifiers[AXIS_NUM_AXIS];
CUtlString g_bindings[256];
bool g_bController = false;
struct KeyName_t {
const char *szName;
EInputKey key;
};
KeyName_t keys[] = {
{"ESCAPE",KEY_ESCAPE},
{"ESC",KEY_ESCAPE},
{"TAB",KEY_TAB},
{"ENTER",KEY_ENTER},
{"CTRL",KEY_CONTROL},
{"CONTROL",KEY_CONTROL},
{"SHIFT",KEY_SHIFT},
{"ALT",KEY_ALT},
{"SPACE",KEY_SPACE},
{"BACKSPACE",KEY_BACKSPACE},
{"[",KEY_LBRACKET},
{"]",KEY_RBRACKET},
{"{",KEY_LBRACKET},
{"}",KEY_RBRACKET},
{"\\",KEY_BACKSLASH},
{";",KEY_SEMICOLON},
{":",KEY_SEMICOLON},
{"\'",KEY_APOSTROPHE},
{"\"",KEY_APOSTROPHE},
{"F1",KEY_F1},
{"F2",KEY_F2},
{"F3",KEY_F3},
{"F4",KEY_F4},
{"F5",KEY_F5},
{"F6",KEY_F6},
{"F7",KEY_F7},
{"F8",KEY_F8},
{"F9",KEY_F9},
{"F10",KEY_F10},
{"F11",KEY_F11},
{"F12",KEY_F12},
{"1",KEY_1},
{"2",KEY_2},
{"3",KEY_3},
{"4",KEY_4},
{"5",KEY_5},
{"6",KEY_6},
{"7",KEY_7},
{"8",KEY_8},
{"9",KEY_9},
{"0",KEY_0},
{"A",KEY_A},
{"B",KEY_B},
{"C",KEY_C},
{"D",KEY_D},
{"E",KEY_E},
{"F",KEY_F},
{"G",KEY_G},
{"H",KEY_H},
{"I",KEY_I},
{"J",KEY_J},
{"K",KEY_K},
{"L",KEY_L},
{"M",KEY_M},
{"N",KEY_N},
{"O",KEY_O},
{"P",KEY_P},
{"Q",KEY_Q},
{"R",KEY_R},
{"S",KEY_S},
{"T",KEY_T},
{"U",KEY_U},
{"V",KEY_V},
{"W",KEY_W},
{"X",KEY_X},
{"Y",KEY_Y},
{"Z",KEY_Z},
};
//-----------------------------------------------------------------------------
// Converts string (eg. tab, mouse0, w, 0) to keycode
//-----------------------------------------------------------------------------
EInputKey IInput_StringToKey( char *psz )
{
for (uint32_t i = 0; i<sizeof(keys)/sizeof(KeyName_t); i++)
{
if (!V_stricmp(keys[i].szName, psz))
return keys[i].key;
};
return KEY_NONE;
};
interface CInput: public IInput
{
public:
virtual void Init() override;
virtual void Frame() override;
virtual void Deinit() override;
virtual void KeyEvent( EInputKey key, EKeyEventType event ) override;
virtual void AxisEvent( EInputAxis axis, float fValue ) override;
};
DECLARE_ENGINE_INTERFACE(Input, CInput)
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CInput::Init( void )
{
}
CUtlVector<EInputMode> g_inputModeStack = {INPUT_MODE_GAME, INPUT_MODE_MENU};
//-----------------------------------------------------------------------------
// Key event may have different different effects based on current input mode.
//
// GAME:
// Generates command call when pressed the key. eg +forward; -left;
// Just to be sure we put ; in the end of the command.
// When user releases the key command event is not generated. But if the first
// command contains + as first character ( in case of example +forward ), then
// it fires -forward
//
// MENU:
// Sends all event to FGUI. KEY_ESCAPE key makes leave the menu and get back to
// the game.
//
// CONSOLE:
// Works as permanent input field.
//
// INPUT FIELD:
// Doesn't recieve any events except for KEY_ESCAPE and KEY_ENTER
//-----------------------------------------------------------------------------
void CInput::KeyEvent( EInputKey key, EKeyEventType event )
{
if (event == KEY_EVENT_TYPE_DOWN && key == KEY_ESCAPE)
{
if (g_inputModeStack.GetSize() == 1)
{
g_inputModeStack.AppendTail(INPUT_MODE_MENU);
IInput::SetInputMode(INPUT_MODE_MENU);
MainMenu()->SetVisibility(true);
return;
}
if (IConsoleUI::IsVisibile())
IConsoleUI::SetVisibility(false);
IInput::SetInputMode(g_inputModeStack[g_inputModeStack.GetSize()-2]);
g_inputModeStack.RemoveTail();
if (g_inputModeStack[g_inputModeStack.GetSize()-1] != INPUT_MODE_MENU)
{
MainMenu()->SetVisibility(false);
}
return;
};
if (event == KEY_EVENT_TYPE_DOWN && key == KEY_TILDE)
{
if (IConsoleUI::IsVisibile())
{
IInput::SetInputMode(g_inputModeStack[g_inputModeStack.GetSize()-2]);
g_inputModeStack.RemoveTail();
IConsoleUI::SetVisibility(false);
} else
{
g_inputModeStack.AppendTail(INPUT_MODE_CONSOLE);
IInput::SetInputMode(INPUT_MODE_CONSOLE);
IConsoleUI::SetVisibility(true);
}
return;
};
if (event == KEY_EVENT_TYPE_DOWN && key == KEY_F11)
{
Console()->AddCommand("exit;");
return;
}
if (g_inputModeStack[g_inputModeStack.GetSize()-1] == INPUT_MODE_GAME)
{
if (event == KEY_EVENT_TYPE_DOWN) {
Console()->AddCommand(g_bindings[key]);
Console()->AddCommand(";");
}
if (event == KEY_EVENT_TYPE_UP)
{
auto binding = Console()->ParseCommandLine(g_bindings[key]);
if (binding.GetSize()==0)
return;
if (binding[0].GetSize() == 0)
return;
if (binding[0][0].GetString()[0] == '+')
{
CUtlString command = binding[0][0];
command.GetString()[0] = '-';
Console()->AddCommand(command);
Console()->AddCommand(";");
}
}
}
if (g_inputModeStack[g_inputModeStack.GetSize()-1] == INPUT_MODE_MENU)
{
};
}
//-----------------------------------------------------------------------------
// Axis events for the input devices such as mouse and controller.
// Game needs to explicitly support all of the devices.
//-----------------------------------------------------------------------------
void CInput::AxisEvent( EInputAxis axis, float fValue )
{
if (g_inputModeStack[g_inputModeStack.GetSize()-1] == INPUT_MODE_GAME)
{
if (axis == AXIS_MOUSE_X || axis == AXIS_MOUSE_Y)
{
g_bController = false;
g_fAxisValues[axis] += fValue*3.09;
}
if (axis == AXIS_CONTROLLER_PITCH || axis == AXIS_CONTROLLER_YAW)
{
g_bController = true;
g_fAxisModifiers[axis] = fValue*3.09;
}
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CInput::Frame( void )
{
g_fAxisValues[AXIS_MOUSE_X] += g_fAxisModifiers[AXIS_CONTROLLER_PITCH];
g_fAxisValues[AXIS_MOUSE_Y] += g_fAxisModifiers[AXIS_CONTROLLER_YAW];
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CInput::Deinit( void )
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void IInput_Bind( int argc, char **argv )
{
if (argc == 1)
return;
if (argc == 2)
return;
EInputKey key = IInput_StringToKey(argv[1]);
if (key == KEY_NONE)
return;
g_bindings[key] = 0;
for ( int i = 2; i<argc; i++ )
{
g_bindings[key].AppendTail(argv[i]);
g_bindings[key].AppendTail(" ");
}
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void IInput_Unbind( int argc, char **argv )
{
};
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void IInput_UnbindAll( int argc, char **argv )
{
};
ConCommand BindCmd("bind", IInput_Bind, 0);
ConCommand UnbindCmd("unbind", IInput_Unbind, 0);
ConCommand UnbindAllcmd("unbindall", IInput_UnbindAll, 0);

View File

@@ -1,7 +0,0 @@
#include "interface.h"
#include "tier0/lib.h"
CInterfaceRegistry::CInterfaceRegistry( const char *szName, InterfaceRegistryFn pfn )
{
};

View File

@@ -1,92 +0,0 @@
#include "level.h"
#include "baseentity.h"
#include "brush.h"
#include "engine.h"
#include "filesystem.h"
#include "interface.h"
#include "tier1/utlbuffer.h"
#include "tier1/utlstring.h"
struct MapHeader_t
{
char id[8];
uint32_t nEntities;
};
struct EntityHeader_t
{
uint32_t nTriangles;
uint32_t nProperties;
};
interface CLevelManager: public ILevelManager
{
public:
virtual void Init() override {}
virtual void Frame() override {}
virtual void Deinit() override {}
virtual void LoadLevel( const char *szLevelName ) override;
};
DECLARE_ENGINE_INTERFACE(LevelManager, CLevelManager);
//-----------------------------------------------------------------------------
// Loads level from file, deserializes it and creates entities.
//-----------------------------------------------------------------------------
void CLevelManager::LoadLevel( const char *szLevelName )
{
FileHandle_t handle = FileSystem()->Open(CUtlString("%s.fmap",szLevelName), IFILE_READ);
CUtlBuffer<char> mapdata(FileSystem()->Size(handle));
FileSystem()->Read(handle, mapdata.GetMemory(), mapdata.GetSize());
FileSystem()->Close(handle);
MapHeader_t* pHeader = (MapHeader_t*)mapdata.GetMemory();
char *pData = (char*)mapdata.GetMemory()+sizeof(MapHeader_t);
for ( uint32_t i = 0; i < pHeader->nEntities; i++ )
{
CUtlBuffer<char> szEntityType(V_strlen(pData)+1);
V_strcpy(szEntityType, pData);
pData+=szEntityType.GetSize();
EntityHeader_t* pEntityHeader = (EntityHeader_t*)pData;
pData+=sizeof(EntityHeader_t);
CBaseEntity *pEntity = IIEngine::SpawnEntity(szEntityType);
if (!pEntity)
continue;
for ( uint32_t j = 0; j<pEntityHeader->nProperties; j++ )
{
CUtlBuffer<char> szParamName(V_strlen(pData)+1);
V_strcpy(szParamName, pData);
pData+=szParamName.GetSize();
CUtlBuffer<char> szParamValue(V_strlen(pData)+1);
V_strcpy(szParamValue, pData);
pData+=szParamValue.GetSize();
pEntity->ReadParameter(szParamName, szParamValue);
};
CBrushEntity *pBrush = dynamic_cast<CBrushEntity*>(pEntity);
if (!pBrush)
{
IIEngine::InitEntity(pEntity);
continue;
}
pBrush->m_mesh = CUtlVector<Triangle_t>(0);
for ( uint32_t j = 0; j<pEntityHeader->nTriangles; j++ )
{
Triangle_t triangle = {};
V_memcpy(triangle.location, pData, 4*9);
pData+=4*9;
V_memcpy(triangle.uv, pData, 4*6);
pData+=4*6;
CUtlBuffer<char> szTextureName(V_strlen(pData)+1);
V_strcpy(szTextureName, pData);
pData+=szTextureName.GetSize();
pBrush->m_mesh.AppendTail(triangle);
};
IIEngine::InitEntity(pBrush);
};
};

View File

@@ -1,49 +0,0 @@
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"
#include "audio.h"
class CMASound
{
};
class CMAAudioManager: public IAudioManager
{
virtual void Init() override;
virtual void Frame() override;
virtual void Deinit() override;
virtual ISound *CreateSound() override;
virtual I3DSound *Create3DSound() override;
};
DECLARE_ENGINE_INTERFACE(AudioManager, CMAAudioManager)
ma_engine ma_audioEngine;
void CMAAudioManager::Init()
{
ma_result r;
r = ma_engine_init(NULL, &ma_audioEngine);
}
void CMAAudioManager::Frame()
{
}
void CMAAudioManager::Deinit()
{
}
ISound *CMAAudioManager::CreateSound()
{
}
I3DSound *CMAAudioManager::Create3DSound()
{
}

View File

@@ -1,4 +0,0 @@
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio.h"

View File

@@ -1,156 +0,0 @@
#include "mesh.h"
#include "cglm/mat4.h"
#include "rendering.h"
CUtlVector<IMeshInstance*> g_meshes;
class CMeshInstance: public IMeshInstance
{
public:
virtual void SetPosition( vec3 position ) override;
virtual void SetRotationEuler( vec3 angle ) override;
virtual void SetRotationQuat( vec4 quaternion) override;
virtual void SetMatrix( mat4 matrix ) override;
virtual void SetScale( vec3 scale ) override;
virtual void Draw() override;
mat4 m_matrix;
vec3 m_position;
IVertexBuffer *m_pVertexBuffer;
IIndexBuffer *m_pIndexBuffer;
};
void CMeshInstance::SetPosition( vec3 position )
{
glm_vec3_copy(position, m_position);
}
void CMeshInstance::SetRotationEuler( vec3 angle )
{
}
void CMeshInstance::SetRotationQuat( vec4 quaternion)
{
}
void CMeshInstance::SetMatrix( mat4 matrix )
{
glm_mat4_copy(matrix, m_matrix);
}
void CMeshInstance::SetScale( vec3 scale )
{
}
void CMeshInstance::Draw()
{
g_meshes.AppendTail(this);
}
class CMesh: public IMesh
{
public:
virtual void SetVertexBuffer( IVertexBuffer *pBuffer ) override;
virtual void SetIndexBuffer( IIndexBuffer *pBuffer ) override;
virtual IMeshInstance *CreateInstance() override;
IVertexBuffer *m_pVertexBuffer = 0;
IIndexBuffer *m_pIndexBuffer = 0;
};
void CMesh::SetVertexBuffer( IVertexBuffer *pBuffer )
{
m_pVertexBuffer = pBuffer;
}
void CMesh::SetIndexBuffer( IIndexBuffer *pBuffer )
{
m_pIndexBuffer = pBuffer;
}
IMeshInstance *CMesh::CreateInstance()
{
CMeshInstance *pInstance = new CMeshInstance;
pInstance->m_pVertexBuffer = m_pVertexBuffer;
pInstance->m_pIndexBuffer = m_pIndexBuffer;
return pInstance;
};
IGraphicsPipeline *g_MeshPipeline;
class CMeshRendering: public IMeshRendering
{
virtual void Init() override;
virtual void Frame( float fDelta ) override;
virtual void Deinit() override;
};
void CMeshRendering::Init()
{
g_MeshPipeline = Renderer()->CreateGraphicsPipeline(
{
{"gfx/mesh_vert.shader", SHADER_TYPE_VERTEX},
{"gfx/mesh_frag.shader", SHADER_TYPE_FRAGMENT},
},
{
{SHADER_INPUT_TYPE_UNIFORM_BUFFER,0},
{SHADER_INPUT_TYPE_TEXTURES,1},
},
80,
20,
{{0,0,EVertexFormat::VERTEX_FORMAT_X32Y32Z32}, {12,1,EVertexFormat::VERTEX_FORMAT_X32Y32}},
{EImageFormat::IMAGE_FORMAT_R8G8B8A8},
true
);
}
void CMeshRendering::Frame( float fDelta )
{
g_MeshPipeline->BindData(0, Renderer()->GetCameraMatrix(), 0);
g_MeshPipeline->PushBindings();
Renderer()->ResetState();
Renderer()->SetDepthMode(DEPTH_MODE_LESS);
Renderer()->BindPipeline(g_MeshPipeline);
for (auto &v: g_meshes)
{
CMeshInstance *pMesh = (CMeshInstance*)v;
struct {
mat4 i;
uint32_t a = 0;
uint32_t b = 0;
uint32_t c = 0;
} constants;
glm_mat4_copy(pMesh->m_matrix,constants.i);
constants.i[3][0] = pMesh->m_position[0];
constants.i[3][1] = pMesh->m_position[1];
constants.i[3][2] = pMesh->m_position[2];
Renderer()->SetConstants(sizeof(constants), &constants);
Renderer()->Draw(pMesh->m_pVertexBuffer, pMesh->m_pIndexBuffer);
}
g_meshes = {};
}
void CMeshRendering::Deinit()
{
}
IMesh *IMeshRendering::CreateMesh()
{
CMesh *pMesh = new CMesh;
return pMesh;
};
DECLARE_MESH_RENDERING_STAGE(CMeshRendering, mesh_rendering)

View File

@@ -1,685 +0,0 @@
#include "Metal/Metal.hpp"
#include "math3d.h"
#include "filesystem.h"
#include "rendering.h"
#include "tier0/lib.h"
#include "tier1/utlvector.h"
#include "tier0/platform.h"
#include "rendering.h"
#include "ml_video.h"
#define STB_IMAGE_IMPLEMENTATION
#if defined(__APPLE__) && defined(__MACH__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE
// iOS
#define STBI_NO_THREAD_LOCALS
#else
// macOS
#endif
#else
// Other platforms
#endif
#include "stb_image.h"
mat4 g_cameraView;
IImage *g_meshDepth;
IImage *g_meshDepthMSAA;
IImage *g_meshColor;
IImage *g_meshColorMSAA;
CUtlVector<ITexture*> g_textures;
IBuffer *g_cameraProperties;
struct CameraProjection {
mat4 viewprojection;
};
CameraProjection *g_cameraDataMap;
static MTL::RenderPassDescriptor *s_pRenderPass;
static MTL::RenderCommandEncoder *s_pEncoder;
static uint32_t s_nNumAttachments;
CUtlVector<MTL::Texture*> g_destroyImageBuffer;
CUtlVector<MTL::Buffer*> g_destroyBuffersBuffer;
extern MTL::PixelFormat g_swapchainFormat;
MTL::PixelFormat IRenderer_FormatToMl( EImageFormat format )
{
switch (format)
{
case IMAGE_FORMAT_R8G8B8A8: return MTL::PixelFormatRGBA8Unorm;
case IMAGE_FORMAT_R16G16B16A16: return MTL::PixelFormatRGBA16Unorm;
case IMAGE_FORMAT_DEPTH: return MTL::PixelFormatDepth32Float;
case IMAGE_FORMAT_WINDOW: return g_swapchainFormat;
default: return MTL::PixelFormatRGBA8Unorm;
}
};
MTL::VertexFormat IRenderer_VertexToMl( EVertexFormat format )
{
switch (format)
{
case VERTEX_FORMAT_X16: return MTL::VertexFormatHalf;
case VERTEX_FORMAT_X16Y16: return MTL::VertexFormatHalf2;
case VERTEX_FORMAT_X16Y16Z16: return MTL::VertexFormatHalf3;
case VERTEX_FORMAT_X16Y16Z16W16: return MTL::VertexFormatHalf4;
case VERTEX_FORMAT_X32: return MTL::VertexFormatFloat;
case VERTEX_FORMAT_X32Y32: return MTL::VertexFormatFloat2;
case VERTEX_FORMAT_X32Y32Z32: return MTL::VertexFormatFloat3;
case VERTEX_FORMAT_X32Y32Z32W32: return MTL::VertexFormatFloat4;
default: return MTL::VertexFormatFloat3;
}
};
MTL::LoadAction IRenderer_LoadOpMl( EAttachmentLoadMode mode )
{
switch (mode)
{
case ATTACHMENT_LOAD_MODE_DONT_CARE: return MTL::LoadActionDontCare;
case ATTACHMENT_LOAD_MODE_CLEAR: return MTL::LoadActionClear;
case ATTACHMENT_LOAD_MODE_LOAD: return MTL::LoadActionLoad;
default: return MTL::LoadActionDontCare;
}
}
MTL::StoreAction IRenderer_StoreOpMl( EAttachmentStoreMode mode )
{
switch (mode)
{
case ATTACHMENT_STORE_MODE_DONT_CARE: return MTL::StoreActionStore;
case ATTACHMENT_STORE_MODE_STORE: return MTL::StoreActionStore;
default: return MTL::StoreActionDontCare;
}
}
class CMlBuffer: public IBuffer
{
public:
void *Map() override;
void Unmap() override;
MTL::Buffer *m_buffer;
uint32_t m_nSize;
};
class CMlImage: public IImage
{
public:
MTL::Texture *m_image;
};
void *CMlBuffer::Map()
{
return m_buffer->contents();
}
void CMlBuffer::Unmap()
{
}
struct MLShader_t {
EShaderType shaderType;
MTL::Library *library;
MTL::Function *function;
NS::String *szMain;
};
class CMlGraphicsPipeline: public IGraphicsPipeline
{
public:
CUtlVector<MLShader_t> m_shaders;
MTL::RenderPipelineState *m_pipeline;
CUtlVector<ShaderInput_t> m_inputs;
uint32_t m_nVertexSize;
};
class CMlTexture: public ITexture
{
public:
MTL::Texture *m_texture;
};
IStorageBuffer *IRenderer::CreateStorageBuffer( uint32_t uSize )
{
CMlBuffer *pBuffer = new CMlBuffer;
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
pBuffer->m_nSize = uSize;
return pBuffer;
}
IUniformBuffer *IRenderer::CreateUniformBuffer( uint32_t uSize )
{
CMlBuffer *pBuffer = new CMlBuffer;
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
pBuffer->m_nSize = uSize;
return pBuffer;
}
IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize )
{
CMlBuffer *pBuffer = new CMlBuffer;
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
pBuffer->m_nSize = uSize;
return pBuffer;
}
IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize )
{
CMlBuffer *pBuffer = new CMlBuffer;
pBuffer->m_buffer = g_mlDevice->newBuffer(uSize, MTL::ResourceStorageModeShared);
pBuffer->m_nSize = uSize;
return pBuffer;
}
IImage *IRenderer::CreateImage( EImageFormat format, uint32_t usage, uint32_t nWidth, uint32_t nHeight, uint32_t nSamples )
{
CMlImage *pImage = new CMlImage;
MTL::TextureDescriptor *pCreateInfo = MTL::TextureDescriptor::alloc()->init();
pCreateInfo->setPixelFormat(IRenderer_FormatToMl(format));
pCreateInfo->setWidth(nWidth);
pCreateInfo->setHeight(nHeight);
MTL::TextureUsage mlusage = 0;
if (usage&IMAGE_USAGE_COLOR_ATTACHMENT) mlusage |= MTL::TextureUsageRenderTarget;
if (usage&IMAGE_USAGE_DEPTH_ATTACHMENT) mlusage |= MTL::TextureUsageRenderTarget;
mlusage |= MTL::TextureUsageShaderRead;
mlusage |= MTL::TextureUsageShaderWrite;
pCreateInfo->setUsage(mlusage);
pImage->m_image = g_mlDevice->newTexture(pCreateInfo);
pCreateInfo->release();
return pImage;
};
void IRenderer::DestroyBuffer( IBuffer *pBuffer )
{
if (!pBuffer)
return;
CMlBuffer *pMlBuffer = (CMlBuffer*)pBuffer;
g_destroyBuffersBuffer.AppendTail(pMlBuffer->m_buffer);
delete (pMlBuffer);
}
void IRenderer::DestroyImage( IImage *pImage )
{
if (!pImage)
return;
CMlImage *pMlImage = (CMlImage*)pImage;
g_destroyImageBuffer.AppendTail(pMlImage->m_image);
delete (pMlImage);
}
IPipeline *g_pCurrentPipeline;
void IRenderer::SetConstants( uint32_t nSize, void *pData )
{
if (!g_pCurrentPipeline)
return;
uint32_t nRoundedSize = nSize/8*8;
void *pTemporaryBuffer = V_malloc(nRoundedSize);
V_memcpy(pTemporaryBuffer, pData, nSize);
if (g_pCurrentPipeline->type == PIPELINE_TYPE_RASTERIZATION)
{
CMlGraphicsPipeline *pMlPipeline = (CMlGraphicsPipeline*)g_pCurrentPipeline;
s_pEncoder->setVertexBytes(pTemporaryBuffer, nRoundedSize, 29);
s_pEncoder->setFragmentBytes(pTemporaryBuffer, nRoundedSize, 29);
}
V_free(pTemporaryBuffer);
}
void IRenderer::Barrier( uint32_t stageIn, uint32_t stageOut, CUtlVector<BufferBarrier_t> buffers, CUtlVector<ImageBarrier_t> images )
{
}
void IRenderer::BindData( uint32_t binding, IBuffer *pBuffer, IImage* pImage)
{
if (!g_pCurrentPipeline)
return;
if (g_pCurrentPipeline->type == PIPELINE_TYPE_RASTERIZATION)
{
CMlBuffer *pMlBuffer = (CMlBuffer*)pBuffer;
CMlGraphicsPipeline *pMlPipeline = (CMlGraphicsPipeline*)g_pCurrentPipeline;
for (auto &input: pMlPipeline->m_inputs)
{
if (input.binding != binding)
continue;
switch (input.type)
{
case SHADER_INPUT_TYPE_STORAGE_BUFFER:
case SHADER_INPUT_TYPE_UNIFORM_BUFFER:
if (!pBuffer)
Plat_FatalErrorFunc("pBuffer is NULL\n");
s_pEncoder->setVertexBuffer(pMlBuffer->m_buffer, 0, binding);
s_pEncoder->setFragmentBuffer(pMlBuffer->m_buffer, 0, binding);
break;
case SHADER_INPUT_TYPE_IMAGE:
break;
case SHADER_INPUT_TYPE_TLAS:
break;
case SHADER_INPUT_TYPE_TEXTURES:
break;
};
}
};
}
void IRenderer::BindPipeline( IPipeline *pPipeline )
{
if (!pPipeline)
return;
if (pPipeline->type == PIPELINE_TYPE_RASTERIZATION)
{
CMlGraphicsPipeline *pVkPipeline = (CMlGraphicsPipeline*)pPipeline;
s_pEncoder->setRenderPipelineState(pVkPipeline->m_pipeline);
}
g_pCurrentPipeline = pPipeline;
}
void IRenderer::PushBindings()
{
if (!g_pCurrentPipeline)
return;
if (g_pCurrentPipeline->type == PIPELINE_TYPE_RASTERIZATION)
{
CMlGraphicsPipeline *pPipeline = (CMlGraphicsPipeline*)g_pCurrentPipeline;
bool bHasTextures = false;
for ( int i = 0; i < pPipeline->m_inputs.GetSize(); i++ )
{
if (pPipeline->m_inputs[i].type == SHADER_INPUT_TYPE_TEXTURES)
{
bHasTextures = true;
break;
}
}
if (!bHasTextures)
return;
MTL::ArgumentEncoder *argumentEncoder = 0;
for (auto &shader: pPipeline->m_shaders)
{
if (shader.shaderType == SHADER_TYPE_FRAGMENT)
{
argumentEncoder = shader.function->newArgumentEncoder(21);
break;
};
}
MTL::Buffer *argumentBuffer = g_mlDevice->newBuffer(argumentEncoder->encodedLength(), MTL::ResourceStorageModeShared);
argumentEncoder->setArgumentBuffer(argumentBuffer, 0);
for ( uint32_t i = 0; i < g_textures.GetSize(); i++ )
{
CMlTexture *texture = (CMlTexture*)g_textures[i];
argumentEncoder->setTexture(texture->m_texture, i);
s_pEncoder->useResource(texture->m_texture, MTL::ResourceUsageRead);
}
s_pEncoder->useResource(argumentBuffer, MTL::ResourceUsageRead);
s_pEncoder->setFragmentBuffer(argumentBuffer, 0, 21);
g_destroyBuffersBuffer.AppendTail(argumentBuffer);
argumentEncoder->release();
}
}
void IRenderer::Begin( uint32_t nWidth, uint32_t nHeight, CUtlVector<RenderingColorAttachment_t> attachments, RenderingDepthAttachment_t depth )
{
s_pRenderPass = MTL::RenderPassDescriptor::alloc()->init();
uint32_t i = 0;
for (auto &attachment: attachments)
{
CMlImage *pImage = (CMlImage*)attachment.pOutput;
CMlImage *pTemporary = (CMlImage*)attachment.pTemporary;
auto mlattachment = s_pRenderPass->colorAttachments()->object(i);
mlattachment->setTexture(pImage->m_image);
mlattachment->setLoadAction(IRenderer_LoadOpMl(attachment.loadMode));
mlattachment->setStoreAction(IRenderer_StoreOpMl(attachment.storeMode));
mlattachment->setClearColor(MTL::ClearColor(attachment.clearColor[0],attachment.clearColor[1],attachment.clearColor[2],attachment.clearColor[3]));
i++;
};
if (depth.pOutput)
{
CMlImage *pImage = (CMlImage*)depth.pOutput;
CMlImage *pTemporary = (CMlImage*)depth.pTemporary;
s_pRenderPass->depthAttachment()->setClearDepth(depth.clearValue);
s_pRenderPass->depthAttachment()->setTexture(pImage->m_image);
s_pRenderPass->depthAttachment()->setLoadAction(IRenderer_LoadOpMl(depth.loadMode));
s_pRenderPass->depthAttachment()->setStoreAction(IRenderer_StoreOpMl(depth.storeMode));
}
s_pEncoder = g_mlCommandBuffer->renderCommandEncoder(s_pRenderPass);
}
void IRenderer::ResetState()
{
}
void IRenderer::SetDepthMode( EDepthMode mode )
{
MTL::DepthStencilDescriptor* depthStencilDesc = MTL::DepthStencilDescriptor::alloc()->init();
if (mode == DEPTH_MODE_DISABLED)
{
depthStencilDesc->setDepthWriteEnabled(false);
} else {
depthStencilDesc->setDepthWriteEnabled(true);
switch (mode)
{
case DEPTH_MODE_LESS:
depthStencilDesc->setDepthCompareFunction(MTL::CompareFunctionLess); break;
default:
break;
}
}
auto depthStencilState = g_mlDevice->newDepthStencilState(depthStencilDesc);
s_pEncoder->setDepthStencilState(depthStencilState);
depthStencilDesc->release();
}
void IRenderer::Draw( IVertexBuffer *pVertex, IIndexBuffer *pIndex )
{
CMlBuffer *pMlVertex = (CMlBuffer*)pVertex;
CMlBuffer *pMlIndex = (CMlBuffer*)pIndex;
if (pMlIndex)
{
} else {
CMlGraphicsPipeline *pPipeline = (CMlGraphicsPipeline*)g_pCurrentPipeline;
s_pEncoder->setVertexBuffer(pMlVertex->m_buffer, 0, 30);
s_pEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(pMlVertex->m_nSize/pPipeline->m_nVertexSize));
}
}
void IRenderer::End()
{
s_pEncoder->endEncoding();
}
IBuffer *IRenderer::GetCameraMatrix()
{
return g_cameraProperties;
}
static CMlImage *pOutputImage = new CMlImage;
IImage *IRenderer::GetOutputImage()
{
pOutputImage->m_image = g_mlDrawableTexture;
return pOutputImage;
}
IGraphicsPipeline *IRenderer::CreateGraphicsPipeline(
CUtlVector<Shader_t> shaders,
CUtlVector<ShaderInput_t> inputs,
uint32_t nConstantsSize,
uint32_t nVertexSize,
CUtlVector<VertexAttribute_t> vertexFormat,
CUtlVector<EImageFormat> outputFormats,
bool bDepth
)
{
CMlGraphicsPipeline *pPipeline = new CMlGraphicsPipeline;
CUtlVector<MLShader_t> mlshaders;
MTL::RenderPipelineDescriptor *pCreateInfo = MTL::RenderPipelineDescriptor::alloc()->init();
MTL::VertexDescriptor *vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
uint32_t i = 0;
for ( auto &vertex: vertexFormat )
{
vertexDescriptor->attributes()->object(i)->setFormat(IRenderer_VertexToMl(vertex.format));
vertexDescriptor->attributes()->object(i)->setOffset(vertex.offset);
vertexDescriptor->attributes()->object(i)->setBufferIndex(30);
i++;
}
vertexDescriptor->layouts()->object(30)->setStride(nVertexSize);
vertexDescriptor->layouts()->object(30)->setStepRate(1);
vertexDescriptor->layouts()->object(30)->setStepFunction(MTL::VertexStepFunctionPerVertex);
NS::Error *error = NULL;
for ( auto &shader: shaders )
{
MLShader_t mlshader = {};
FileHandle_t f = FileSystem()->Open(shader.szPath, IFILE_READ);
if (!f)
Plat_FatalErrorFunc("Failed to open shader %s\n", shader.szPath.GetString());
CUtlBuffer<uint8_t> buffer(FileSystem()->Size(f)+1);
FileSystem()->Read(f, buffer.GetMemory(), buffer.GetSize());
buffer[FileSystem()->Size(f)] = 0;
FileSystem()->Close(f);
NS::String *szSourceCode = NS::String::string((const char*)buffer.GetMemory(), NS::StringEncoding::UTF8StringEncoding);
MTL::CompileOptions *options = NULL;
mlshader.library = g_mlDevice->newLibrary(szSourceCode, options, &error);
if (error)
Plat_FatalErrorFunc("%s\n",error->localizedDescription()->utf8String());
mlshader.szMain = NS::String::string("_main", NS::StringEncoding::UTF8StringEncoding);
mlshader.function = mlshader.library->newFunction(mlshader.szMain);
if (shader.type == SHADER_TYPE_FRAGMENT)
pCreateInfo->setFragmentFunction(mlshader.function);
if (shader.type == SHADER_TYPE_VERTEX)
pCreateInfo->setVertexFunction(mlshader.function);
mlshader.shaderType = shader.type;
mlshaders.AppendTail(mlshader);
}
for ( i = 0; i < outputFormats.GetSize(); i++ )
{
pCreateInfo->colorAttachments()->object(i)->setPixelFormat(IRenderer_FormatToMl(outputFormats[i]));
};
if (bDepth)
pCreateInfo->setDepthAttachmentPixelFormat(MTL::PixelFormatDepth32Float);
pCreateInfo->setVertexDescriptor(vertexDescriptor);
pPipeline->type = PIPELINE_TYPE_RASTERIZATION;
pPipeline->m_pipeline = g_mlDevice->newRenderPipelineState(pCreateInfo, &error);
pPipeline->m_nVertexSize = nVertexSize;
pPipeline->m_inputs = inputs;
pPipeline->m_shaders = mlshaders;
if (error)
Plat_FatalErrorFunc("%s\n",error->localizedDescription()->utf8String());
return pPipeline;
};
uint32_t ITextureManager::GetTextureID(ITexture *pTexture)
{
uint32_t i = 0;
for (auto &t: g_textures)
{
if (pTexture == t)
return i;
i++;
}
return 0;
}
ITexture *ITextureManager::LoadTexture( void *pData, uint32_t X, uint32_t Y, uint32_t numChannels )
{
CMlTexture *pTexture = new CMlTexture;
*pTexture = {};
pTexture->x = X;
pTexture->y = Y;
MTL::TextureDescriptor *pCreateInfo = MTL::TextureDescriptor::alloc()->init();
pCreateInfo->setPixelFormat(MTL::PixelFormatRGBA8Unorm_sRGB);
pCreateInfo->setWidth(X);
pCreateInfo->setHeight(Y);
pCreateInfo->setUsage(MTL::TextureUsageShaderRead);
pTexture->m_texture = g_mlDevice->newTexture(pCreateInfo);
MTL::Region region = MTL::Region(0, 0, 0, X, Y, 1);
NS::UInteger bytesPerRow = 4 * X;
pTexture->m_texture->replaceRegion(region, 0, pData, bytesPerRow);
pCreateInfo->release();
g_textures.AppendTail(pTexture);
return pTexture;
};
ITexture *ITextureManager::LoadTexture( const char *szName )
{
for (ITexture *texture: g_textures)
{
if (!texture->szName)
continue;
if (!V_strcmp(texture->szName, szName))
return texture;
};
FileHandle_t file = FileSystem()->Open(szName, IFILE_READ);
if (!file)
Plat_FatalErrorFunc("Failed to load %s\n", szName);
CUtlBuffer<stbi_uc> buffer(FileSystem()->Size(file));
FileSystem()->Read(file, buffer.GetMemory(), buffer.GetSize());
int nImageX;
int nImageY;
int nImageChannels;
stbi_uc *pixels = stbi_load_from_memory((stbi_uc*)buffer.GetMemory(), buffer.GetSize(), &nImageX, &nImageY, &nImageChannels, STBI_rgb_alpha);
ITexture *pTexture = ITextureManager::LoadTexture(pixels, nImageX, nImageY, 4);
pTexture->szName = szName;
return pTexture;
};
void IMetal::Init()
{
char invalidTexture[1024] = {};
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
int index = i * 16 + j;
if ((i + j) % 2 == 0) {
invalidTexture[index*4] = 255;
}
}
}
g_cameraProperties = IRenderer::CreateUniformBuffer(sizeof(CameraProjection));
g_cameraDataMap = (CameraProjection*)g_cameraProperties->Map();
ITextureManager::LoadTexture(invalidTexture, 16, 16, 4);
g_meshDepth = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, 1280, 720, 1);
g_meshDepthMSAA = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, 1280, 720, 4);
g_meshColor = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, 1280, 720, 1);
g_meshColorMSAA = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, 1280, 720, 4);
glm_mat4_identity(g_cameraView);
}
static MTL::RenderPipelineState* s_fullScreenDraw;
void IMetal::CreatePipelines()
{
for (auto &step: Renderer()->m_StepPrepass)
step.pPipeline->Init();
for (auto &step: Renderer()->m_StepMeshRendering)
step.pPipeline->Init();
for (auto &step: Renderer()->m_StepShading)
step.pPipeline->Init();
for (auto &step: Renderer()->m_StepPostProcessing)
step.pPipeline->Init();
for (auto &step: Renderer()->m_StepUI)
step.pPipeline->Init();
NS::Error *error = 0;
FileHandle_t f = FileSystem()->Open("gfx/ml_quad.metal", IFILE_READ);
CUtlBuffer<uint8_t> buffer(FileSystem()->Size(f)+1);
FileSystem()->Read(f, buffer.GetMemory(), buffer.GetSize());
buffer[FileSystem()->Size(f)] = 0;
FileSystem()->Close(f);
NS::String *szSourceCode = NS::String::string((const char*)buffer.GetMemory(), NS::StringEncoding::UTF8StringEncoding);
MTL::CompileOptions *options = NULL;
MTL::Library *library = g_mlDevice->newLibrary(szSourceCode, options, &error);
MTL::Function *vertexFunc = library->newFunction(NS::String::string("vertex_main", NS::UTF8StringEncoding));
MTL::Function *fragmentFunc = library->newFunction(NS::String::string("fragment_main", NS::UTF8StringEncoding));
MTL::RenderPipelineDescriptor *pipelineDesc = MTL::RenderPipelineDescriptor::alloc()->init();
pipelineDesc->setVertexFunction(vertexFunc);
pipelineDesc->setFragmentFunction(fragmentFunc);
pipelineDesc->colorAttachments()->object(0)->setPixelFormat(MTL::PixelFormatBGRA8Unorm);
s_fullScreenDraw = g_mlDevice->newRenderPipelineState(pipelineDesc, &error);
}
void IMetal::Frame()
{
mat4 perspective;
glm_mat4_inv(g_cameraView, g_cameraDataMap->viewprojection);
glm_perspective(glm_rad(68),(float)g_nWindowWidth/g_nWindowHeight, 0.01, 10000, perspective);
glm_rotate(perspective, glm_rad(90), (vec4){1,0,0,0});
glm_scale(perspective, (vec4){1,-1,1,1});
glm_rotate(perspective, glm_rad(90), (vec4){0,0,1,0});
glm_mat4_mul(perspective,g_cameraDataMap->viewprojection,g_cameraDataMap->viewprojection);
if (g_bConfigNotify)
{
IRenderer::DestroyImage(g_meshDepth);
IRenderer::DestroyImage(g_meshDepthMSAA);
IRenderer::DestroyImage(g_meshColor);
IRenderer::DestroyImage(g_meshColorMSAA);
g_meshDepth = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 1);
g_meshDepthMSAA = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 4);
g_meshColor = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 1);
g_meshColorMSAA = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 4);
}
for (auto &step: g_StepPrepass)
step.pPipeline->Frame(0);
IRenderer::Begin(g_nWindowWidth, g_nWindowHeight,
{
{
g_meshColor,
0,
ATTACHMENT_LOAD_MODE_CLEAR,
ATTACHMENT_STORE_MODE_STORE,
}
},
{
g_meshDepth,
0,
ATTACHMENT_LOAD_MODE_CLEAR,
ATTACHMENT_STORE_MODE_STORE,
1,
});
for (auto &step: g_StepMeshRendering)
step.pPipeline->Frame(0);
IRenderer::End();
CMlImage *pInImage = (CMlImage*)g_meshColor;
MTL::RenderPassDescriptor *renderPassDesc = MTL::RenderPassDescriptor::renderPassDescriptor();
renderPassDesc->colorAttachments()->object(0)->setTexture(g_mlDrawableTexture);
renderPassDesc->colorAttachments()->object(0)->setLoadAction(MTL::LoadActionClear);
renderPassDesc->colorAttachments()->object(0)->setStoreAction(MTL::StoreActionStore);
renderPassDesc->colorAttachments()->object(0)->setClearColor(MTL::ClearColor(0.1, 0.1, 0.1, 1.0));
MTL::RenderCommandEncoder *encoder = g_mlCommandBuffer->renderCommandEncoder(renderPassDesc);
encoder->setRenderPipelineState(s_fullScreenDraw);
encoder->setFragmentTexture(pInImage->m_image, 0);
encoder->drawPrimitives(MTL::PrimitiveTypeTriangleStrip, NS::UInteger(0), NS::UInteger(4));
encoder->endEncoding();
for (auto &step: g_StepShading)
step.pPipeline->Frame(0);
for (auto &step: g_StepPostProcessing)
step.pPipeline->Frame(0);
for (auto &step: g_StepUI)
step.pPipeline->Frame(0);
}
void IMetal::Deinit()
{
}

View File

@@ -1,31 +0,0 @@
#ifndef ML_VIDEO_H
#define ML_VIDEO_H
#include "tier0/platform.h"
#include "Metal/Metal.hpp"
#include "QuartzCore/QuartzCore.hpp"
extern CA::MetalLayer *g_mlLayer;
extern MTL::Device *g_mlDevice;
extern MTL::CommandQueue *g_mlCommandQueue;
extern MTL::CommandBuffer *g_mlCommandBuffer;
extern NS::AutoreleasePool *g_mlPool;
extern char g_bConfigNotify;
extern uint32_t g_nWindowWidth;
extern uint32_t g_nWindowHeight;
extern CUtlVector<MTL::Texture*> g_destroyImageBuffer;
extern CUtlVector<MTL::Buffer*> g_destroyBuffersBuffer;
extern MTL::Texture *g_mlDrawableTexture;
interface IMetal
{
public:
static void Init();
static void CreatePipelines();
static void Frame();
static void Deinit();
};
#endif

View File

@@ -1,13 +0,0 @@
#import <QuartzCore/CAMetalLayer.h>
#import <Metal/Metal.h>
namespace CA {
class MetalLayer;
}
void APPLE_ConfigureLayer(CA::MetalLayer* pMetalLayer)
{
if (!pMetalLayer) return;
CAMetalLayer* nsLayer = (__bridge CAMetalLayer*)pMetalLayer;
};

View File

@@ -1,266 +0,0 @@
#include "rendering.h"
#include "tier0/platform.h"
#include "tier1/utlvector.h"
#include "console.h"
#include "tier1/commandline.h"
#include "input.h"
#define NS_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION
#define MTK_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#include "tier0/minmax_off.h"
#include "QuartzCore/CAMetalLayer.hpp"
#include "Metal/Metal.hpp"
#include "SDL3/SDL.h"
#include "SDL3/SDL_keycode.h"
#include "SDL3/SDL_metal.h"
#include "SDL3/SDL_events.h"
#include "tier0/minmax.h"
#include "ml_video.h"
char g_bConfigNotify = 0;
uint32_t g_nWindowWidth = 1280;
uint32_t g_nWindowHeight = 720;
SDL_Window *g_window;
SDL_MetalView g_mlView;
CA::MetalLayer *g_mlLayer;
MTL::Device *g_mlDevice;
MTL::CommandQueue *g_mlCommandQueue;
MTL::CommandBuffer *g_mlCommandBuffer;
NS::AutoreleasePool *g_mlPool;
MTL::Texture *g_mlDrawableTexture;
MTL::PixelFormat g_swapchainFormat;
#if defined(__APPLE__) && defined(__MACH__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE
// iOS
#define SDL_METAL_VIEW UI::View
#define STBI_NO_THREAD_LOCALS
#else
// macOS
#define SDL_METAL_VIEW NS::View
#endif
#else
// Other platforms
#endif
void IInput::SetInputMode( EInputMode mode )
{
switch (mode)
{
case INPUT_MODE_GAME:
g_currentInputMode = INPUT_MODE_GAME;
SDL_SetWindowRelativeMouseMode(g_window, true);
return;
default:
g_currentInputMode = INPUT_MODE_MENU;
SDL_SetWindowRelativeMouseMode(g_window, false);
return;
}
}
EInputKey ISDL_KeyName(SDL_Keycode key)
{
switch(key)
{
case SDLK_ESCAPE: return KEY_ESCAPE;
case SDLK_TAB: return KEY_TAB;
case SDLK_RETURN: return KEY_ENTER;
case SDLK_RCTRL: return KEY_CONTROL;
case SDLK_LCTRL: return KEY_CONTROL;
case SDLK_RSHIFT: return KEY_SHIFT;
case SDLK_LSHIFT: return KEY_SHIFT;
case SDLK_RALT: return KEY_ALT;
case SDLK_LALT: return KEY_ALT;
case SDLK_SPACE: return KEY_SPACE;
case SDLK_F1: return KEY_F1;
case SDLK_F2: return KEY_F2;
case SDLK_F3: return KEY_F3;
case SDLK_F4: return KEY_F4;
case SDLK_F5: return KEY_F5;
case SDLK_F6: return KEY_F6;
case SDLK_F7: return KEY_F7;
case SDLK_F8: return KEY_F8;
case SDLK_F9: return KEY_F9;
case SDLK_F10: return KEY_F10;
case SDLK_F11: return KEY_F11;
case SDLK_F12: return KEY_F12;
case SDLK_1: return KEY_1;
case SDLK_2: return KEY_2;
case SDLK_3: return KEY_3;
case SDLK_4: return KEY_4;
case SDLK_5: return KEY_5;
case SDLK_6: return KEY_6;
case SDLK_7: return KEY_7;
case SDLK_8: return KEY_8;
case SDLK_9: return KEY_9;
case SDLK_0: return KEY_0;
case SDLK_A: return KEY_A;
case SDLK_B: return KEY_B;
case SDLK_C: return KEY_C;
case SDLK_D: return KEY_D;
case SDLK_E: return KEY_E;
case SDLK_F: return KEY_F;
case SDLK_G: return KEY_G;
case SDLK_H: return KEY_H;
case SDLK_I: return KEY_I;
case SDLK_J: return KEY_J;
case SDLK_K: return KEY_K;
case SDLK_L: return KEY_L;
case SDLK_M: return KEY_M;
case SDLK_N: return KEY_N;
case SDLK_O: return KEY_O;
case SDLK_P: return KEY_P;
case SDLK_Q: return KEY_Q;
case SDLK_R: return KEY_R;
case SDLK_S: return KEY_S;
case SDLK_T: return KEY_T;
case SDLK_U: return KEY_U;
case SDLK_V: return KEY_V;
case SDLK_W: return KEY_W;
case SDLK_X: return KEY_X;
case SDLK_Y: return KEY_Y;
case SDLK_Z: return KEY_Z;
}
return KEY_NONE;
};
void IVideo_HandleEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
SDL_KeyboardEvent *key = &event.key;
SDL_MouseMotionEvent *motion = &event.motion;
switch (event.type)
{
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
g_nWindowWidth = event.window.data1;
g_nWindowHeight = event.window.data2;
g_bConfigNotify = 2;
break;
case SDL_EVENT_KEY_DOWN:
if (!key->repeat)
IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_DOWN);
break;
case SDL_EVENT_KEY_UP:
key = &event.key;
if (!key->repeat)
IInput::KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP);
break;
case SDL_EVENT_MOUSE_MOTION:
IInput::AxisEvent(AXIS_MOUSE_X, motion->yrel*0.022);
IInput::AxisEvent(AXIS_MOUSE_Y, -motion->xrel*0.022);
break;
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
{
SDL_GamepadAxis axis = (SDL_GamepadAxis)event.gaxis.axis;
float value = event.gaxis.value / 32768.0f;
if (abs(event.gaxis.value)<1000)
value = 0;
SDL_JoystickID id = event.gaxis.which;
if (axis == SDL_GAMEPAD_AXIS_RIGHTY)
{
IInput::AxisEvent(AXIS_CONTROLLER_PITCH, value);
}
if (axis == SDL_GAMEPAD_AXIS_RIGHTX)
{
IInput::AxisEvent(AXIS_CONTROLLER_YAW, -value);
}
}
break;
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
break;
case SDL_EVENT_GAMEPAD_BUTTON_UP:
break;
}
};
};
void APPLE_ConfigureLayer(CA::MetalLayer* pMetalLayer);
void IVideo::Init()
{
SDL_SetHint(SDL_HINT_RENDER_VSYNC, "0");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD);
g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_METAL | SDL_WINDOW_HIGH_PIXEL_DENSITY);
int nNumGamepads = 0;
SDL_JoystickID *pGamepads = SDL_GetGamepads(&nNumGamepads);
for ( uint32_t i = 0; i < nNumGamepads; i++ )
{
SDL_OpenGamepad(pGamepads[i]);
}
g_mlView = SDL_Metal_CreateView(g_window);
g_mlLayer = (CA::MetalLayer*)SDL_Metal_GetLayer(g_mlView);
g_mlDevice = MTL::CreateSystemDefaultDevice();
g_mlLayer->setDevice(g_mlDevice);
g_mlLayer->setPixelFormat(MTL::PixelFormatBGRA8Unorm);
g_swapchainFormat = MTL::PixelFormatBGRA8Unorm;
g_mlCommandQueue = g_mlDevice->newCommandQueue();
g_mlLayer->setDrawableSize(CGSizeMake(1280, 720));
g_mlLayer->setFramebufferOnly(false);
IMetal::Init();
}
void IVideo::Frame( float fDelta )
{
IVideo_HandleEvents();
NS::AutoreleasePool *pool = NS::AutoreleasePool::alloc()->init();
g_mlLayer->setDrawableSize(CGSizeMake(g_nWindowWidth, g_nWindowHeight));
CA::MetalDrawable *drawable = g_mlLayer->nextDrawable();
if (!drawable)
return;
g_mlDrawableTexture = drawable->texture();
g_mlCommandBuffer = g_mlCommandQueue->commandBuffer();
IMetal::Frame();
g_mlCommandBuffer->presentDrawable(drawable);
g_mlCommandBuffer->commit();
g_mlCommandBuffer->waitUntilCompleted();
for (auto &image: g_destroyImageBuffer)
{
image->release();
}
for (auto &buffer: g_destroyBuffersBuffer)
{
buffer->release();
}
g_destroyImageBuffer = {};
g_destroyBuffersBuffer = {};
pool->release();
g_bConfigNotify = 0;
}
void IVideo::Deinit()
{
g_mlCommandQueue->release();
g_mlDevice->release();
};
void IVideo::CreatePipelines( )
{
IMetal::CreatePipelines();
}

View File

@@ -1,448 +0,0 @@
#include "networking.h"
#include "console.h"
#include "engine.h"
#include "gamemode.h"
#include "server.h"
#include "steam/isteamfriends.h"
#include "steam/isteamnetworking.h"
#include "steam/isteamnetworkingsockets.h"
#include "steam/steam_api_common.h"
#include "steam/steamnetworkingtypes.h"
#include "tier0/platform.h"
#include "tier0/lib.h"
#include "tier1/commandline.h"
#include "tier0/network.h"
#include "tier1/utlvector.h"
#include "baseplayer.h"
#include "steam/steam_api.h"
#include "steam/steam_gameserver.h"
#include "steam/steamnetworkingsockets.h"
#include "steam/isteamgameserver.h"
#include "steam/isteamnetworkingutils.h"
#ifndef STEAMNETWORKINGSOCKETS_OPENSOURCE
#include "steam/steam_api.h"
#endif
HSteamNetConnection net_connection = 0;
HSteamNetConnection net_server = 0;
HSteamListenSocket net_listenSocket = -1;
CUtlVector<IIClient*> net_clients;
bool net_bIsServer = false;
static int net_nMaxPlayers = 0;
static uint64_t net_nLastSteamID = 90071992547409920;
class CClientNetworkingCallbacks
{
STEAM_CALLBACK(CClientNetworkingCallbacks, RelayNetworkStatusChanged, SteamRelayNetworkStatus_t);
};
void CClientNetworkingCallbacks::RelayNetworkStatusChanged( SteamRelayNetworkStatus_t *pCallback )
{
};
class CServerNetworkingCallbacks
{
STEAM_GAMESERVER_CALLBACK(CServerNetworkingCallbacks, ClientConnected, SteamNetConnectionStatusChangedCallback_t);
STEAM_GAMESERVER_CALLBACK(CServerNetworkingCallbacks, SteamNetAuthenticated, SteamNetAuthenticationStatus_t);
};
void CServerNetworkingCallbacks::ClientConnected( SteamNetConnectionStatusChangedCallback_t *pCallback )
{
INetworking::ClientConnectedCallback(pCallback);
};
void CServerNetworkingCallbacks::SteamNetAuthenticated( SteamNetAuthenticationStatus_t *pCallback )
{
if (net_nLastSteamID == SteamGameServer()->GetSteamID().ConvertToUint64())
return;
net_nLastSteamID = SteamGameServer()->GetSteamID().ConvertToUint64();
V_printf("-------------- SERVER INFO ----------------\n");
V_printf(" STEAMID64:\t%llu\n", net_nLastSteamID);
V_printf(" MAX PLAYERS:\t%i\n", net_nMaxPlayers);
V_printf("-------------- TIPS -----------------------\n");
V_printf(" players can join by using connect <STEAMID64>\n");
V_printf("-------------------------------------------\n");
};
static CServerNetworkingCallbacks *net_pServerCallbacks;
static CClientNetworkingCallbacks *net_pClientCallbacks;
void INetworking::Init()
{
Net_Init();
#ifdef STEAMNETWORKINGSOCKETS_OPENSOURCE
GameNetworkingSockets_Init(NULL, &errMsg)
#endif
V_printf("Cool\n");
if (ICommandLine::CheckParam("-steamdebug"))
{
SteamNetworkingUtils()->SetDebugOutputFunction(k_ESteamNetworkingSocketsDebugOutputType_Msg,
[](ESteamNetworkingSocketsDebugOutputType severity, const char *szMessage) {
V_printf("Steam: %s\n", szMessage);
});
}
if (ICommandLine::CheckParam("-dedicated"))
{
net_pServerCallbacks = new CServerNetworkingCallbacks;
// Run dedicated server with steam
SteamGameServer_Init(0, 27015, 27016, eServerModeAuthentication, "0.0.0.0");
SteamGameServer()->SetProduct("funnygame");
SteamGameServer()->SetGameDescription("not that funny but ok");
SteamGameServer()->SetModDir("funnygame");
SteamGameServer()->SetDedicatedServer(true);
SteamGameServer()->LogOnAnonymous();
net_nMaxPlayers = atoi(ICommandLine::ParamValue("-maxplayers", "128"));
SteamGameServer()->SetMaxPlayerCount(net_nMaxPlayers);
SteamGameServer()->SetAdvertiseServerActive(true);
} else {
net_pClientCallbacks = new CClientNetworkingCallbacks;
}
SteamDatagramErrMsg errMsg = {};
SteamNetworkingUtils()->InitRelayNetworkAccess();
if (ICommandLine::CheckParam("-dedicated"))
{
net_listenSocket = SteamGameServerNetworkingSockets()->CreateListenSocketP2P(0, 0, NULL);
net_bIsServer = true;
} else {
if (ICommandLine::ParamValue("-connect"))
{
Console()->AddCommand(CUtlString("connect %s;", ICommandLine::ParamValue("-connect")));
};
}
}
void INetworking::Deinit()
{
if (net_listenSocket == -1)
return;
if (ICommandLine::CheckParam("-dedicated"))
SteamGameServerNetworkingSockets()->CloseListenSocket(net_listenSocket);
else
SteamNetworkingSockets()->CloseConnection(net_listenSocket, 0, NULL, false);
}
bool INetworking::IsServer()
{
return net_bIsServer;
}
bool INetworking::IsClient()
{
return !net_bIsServer;
}
bool INetworking::IsConnected()
{
return (bool)net_server;
}
void INetworking::Frame()
{
if (IsServer())
{
SteamGameServer_RunCallbacks();
for (auto &client: g_clients)
{
SteamNetworkingMessage_t *pMessages[64];
while (true)
{
int nMessages = SteamGameServerNetworkingSockets()->ReceiveMessagesOnConnection(client->playerHandle, pMessages, 64);
if ( nMessages <= 0 )
break;
for ( int i = 0; i < nMessages; i++ )
{
ProcessPacket((void*)pMessages[i]->GetData(), pMessages[i]->GetSize(), client);
}
}
}
} else {
SteamNetworkingMessage_t *pMessages[64];
while (true)
{
int nMessages = SteamNetworkingSockets()->ReceiveMessagesOnConnection(net_connection, pMessages, 64);
if ( nMessages <= 0 )
break;
for ( int i = 0; i < nMessages; i++ )
{
ProcessPacket((void*)pMessages[i]->GetData(), pMessages[i]->GetSize(), NULL);
pMessages[i]->Release();
}
}
}
}
void INetworking::SendData( void *pData, uint32_t nSize, IIClient *pClient, EMessageMode messageMode )
{
if (!IsConnected() && IsClient())
return;
int nSendFlags = 0;
switch ( messageMode )
{
case MESSAGE_MODE_UNRELIABLE:
nSendFlags |= k_nSteamNetworkingSend_Unreliable;
break;
case MESSAGE_MODE_RELIABLE:
nSendFlags |= k_nSteamNetworkingSend_Reliable;
break;
};
/* Send to server if client is NULL */
EResult r = k_EResultNone;
if (pClient == NULL)
r = SteamNetworkingSockets()->SendMessageToConnection(net_server, pData, nSize, nSendFlags, NULL);
else
r = SteamGameServerNetworkingSockets()->SendMessageToConnection(pClient->playerHandle, pData, nSize, nSendFlags, NULL);
}
void INetworking::SendDataEverybody( void *pData, uint32_t nSize, EMessageMode messageMode )
{
for (auto &client: g_clients)
{
SendData(pData, nSize, client, messageMode);
}
}
void INetworking::SendDataEverybodyExcept( void *pData, uint32_t nSize, IIClient *pClient, EMessageMode messageMode )
{
for (auto &client: g_clients)
{
if (client == pClient)
continue;
SendData(pData, nSize, client, messageMode);
}
}
void INetworking::SendDataEverybodyExcept( void *pData, uint32_t nSize, CBasePlayer *pPlayer, EMessageMode messageMode )
{
for (auto &client: g_clients)
{
if (client->pBasePlayer == pPlayer)
continue;
SendData(pData, nSize, client, messageMode);
}
}
void INetworking::ProcessPacket( void *pData, uint32_t nSize, IIClient *pClient )
{
Packet_t *pPacketHeader = (Packet_t*)pData;
if (IsServer() && pPacketHeader->type != PACKET_TYPE_PLAYER_MOVEMENT)
return;
if (nSize < sizeof(Packet_t))
return;
PacketPlayer_t *pPlayerPacket = (PacketPlayer_t*)pData;
PacketGameMode_t *pGameModePacket = (PacketGameMode_t*)pData;
IIClient *pNewClient;
switch(pPacketHeader->type)
{
case PACKET_TYPE_PLAYER_MOVEMENT:
if (nSize < sizeof(PacketPlayer_t))
return;
if (IsServer())
{
if (pClient->pBasePlayer)
pClient->pBasePlayer->RecieveFromServer(pData, nSize);
}
for (auto &client: g_clients)
{
if (client->playerHandle == pPlayerPacket->playerHandle)
{
if (!client->pBasePlayer)
return;
client->pBasePlayer->RecieveFromServer(pData, nSize);
return;
}
}
return;
case PACKET_TYPE_PLAYER_JOIN:
if (nSize != sizeof(PacketPlayer_t))
return;
// Player join and leave can be processed only by the clients
pNewClient = new IIClient;
*pNewClient = {
.playerID = pPlayerPacket->playerID,
.playerHandle = pPlayerPacket->playerHandle,
};
V_printf("%i\n",g_clients.GetSize());
IIEngine::ConnectClient(pNewClient);
for (auto &client: g_clients)
{
CSteamID steamID = CSteamID();
if ( client->playerID == 0)
V_printf("%s\t", SteamFriends()->GetPlayerNickname((uint64)client->playerID));
else
V_printf("%s\t", SteamFriends()->GetPersonaName());
V_printf("%llu\t", client->playerID);
V_printf("%u\n", client->playerHandle);
if (client->playerHandle == 0)
g_localClient = client;
}
return;
case PACKET_TYPE_PLAYER_LEAVE:
IIEngine::DisconnectClientByHandle(pPlayerPacket->playerHandle);
return;
case PACKET_TYPE_GAMEMODE_START:
V_printf("PacketGameMode\n");
if (nSize != sizeof(PacketGameMode_t))
return;
GameModeManager()->StartGameMode(pGameModePacket->szName);
return;
default:
return;
}
}
void INetworking::GetServerInfo()
{
}
uint32_t INetworking_IPv4ToUint(const char *szIP) {
if (CUtlString(szIP) == "localhost")
return 0x7F000001;
struct in_addr ipAdress;
if (inet_pton(AF_INET, szIP, &ipAdress) != 1) {
V_printf("Invalid IPv4 address: %s\n", szIP);
return 0;
}
return ntohl(ipAdress.s_addr);
}
void INetworking::JoinServer( const char *szIP )
{
g_clients = {};
if (net_connection)
{
SteamNetworkingSockets()->CloseConnection(net_connection, 0, NULL, false);
}
SteamNetworkingIPAddr localAddress = {};
localAddress.Clear();
localAddress.SetIPv4(INetworking_IPv4ToUint(szIP), 27015);
net_connection = SteamNetworkingSockets()->ConnectByIPAddress(localAddress, 0, NULL);
net_server = net_connection;
}
void INetworking::JoinServer( uint64_t nSteamID )
{
g_clients = {};
if (net_connection)
{
SteamNetworkingSockets()->CloseConnection(net_connection, 0, NULL, false);
}
SteamNetworkingIdentity remoteIdentity = {};
remoteIdentity.Clear();
remoteIdentity.SetSteamID64(nSteamID);
net_connection = SteamNetworkingSockets()->ConnectP2P(remoteIdentity, 0, 0, 0);
net_server = net_connection;
}
void INetworking::ClientConnectedCallback( SteamNetConnectionStatusChangedCallback_t *pCallback )
{
IIClient *pClient = new IIClient;
switch (pCallback->m_info.m_eState)
{
case k_ESteamNetworkingConnectionState_Connecting:
V_printf("Awaiting connection: %llu\n",pCallback->m_info.m_identityRemote.GetSteamID64());
SteamNetworkingSockets()->AcceptConnection(pCallback->m_hConn);
break;
case k_ESteamNetworkingConnectionState_Connected:
V_printf("Connected: %llu %u\n",pCallback->m_info.m_identityRemote.GetSteamID64(), pCallback->m_hConn);
*pClient = {
.playerID = pCallback->m_info.m_identityRemote.GetSteamID64(),
.playerHandle = pCallback->m_hConn,
};
// send out to all clients
for (auto &client: g_clients)
{
PacketPlayer_t packet = {
.playerID = pClient->playerID,
.playerHandle = pClient->playerHandle,
};
packet.type = PACKET_TYPE_PLAYER_JOIN;
SendData(&packet, sizeof(packet), client, MESSAGE_MODE_RELIABLE);
};
IIEngine::ConnectClient(pClient);
// register all clients on connected one
for (auto &client: g_clients)
{
PacketPlayer_t packet = {
.playerID = client->playerID,
.playerHandle = client->playerHandle,
};
if (client == pClient)
{
packet.playerID = 0;
packet.playerHandle = 0;
}
packet.type = PACKET_TYPE_PLAYER_JOIN;
SendData(&packet, sizeof(packet), pClient, MESSAGE_MODE_RELIABLE);
};
GameModeManager()->RestartCurrentGameMode();
break;
case k_ESteamNetworkingConnectionState_ClosedByPeer:
case k_ESteamNetworkingConnectionState_ProblemDetectedLocally:
SteamNetworkingSockets()->CloseConnection(pCallback->m_hConn, 0, NULL, false);
V_printf("Disconnected: %llu %u\n",pCallback->m_info.m_identityRemote.GetSteamID64(), pCallback->m_hConn);
IIEngine::DisconnectClientByHandle(pCallback->m_hConn);
// send out to all clients
for (auto &client: g_clients)
{
PacketPlayer_t packet = {
.playerID = pCallback->m_info.m_identityRemote.GetSteamID64(),
.playerHandle = pCallback->m_hConn,
};
packet.type = PACKET_TYPE_PLAYER_LEAVE;
SendData(&packet, sizeof(packet), client, MESSAGE_MODE_RELIABLE);
};
break;
default:
break;
}
}
void INetworking_Connect( int argc, char **argv )
{
if (ICommandLine::CheckParam("-dedicated"))
return;
if (argc != 2)
{
V_printf("connect <IPv4>\n");
return;
}
INetworking::JoinServer(argv[1]);
};
void INetworking_ConnectFriend( int argc, char **argv )
{
if (ICommandLine::CheckParam("-dedicated"))
return;
if (argc != 2)
{
V_printf("connect_friend <steamid>\n");
return;
}
uint64_t nFriendID = 0;
V_sscanf(argv[1], "%llu\n", &nFriendID);
V_printf("Connecting to %llu\n",nFriendID);
INetworking::JoinServer(nFriendID);
};
ConCommand ConnectCmd("connect", INetworking_ConnectFriend);

View File

@@ -1,160 +0,0 @@
#include "physics.h"
#include "math3d.h"
PxCastResult_t IPxWorld::BoxCast( vec3 size, vec3 origin, vec3 destination, vec3 rotation )
{
vec3 velocity;
PxCastResult_t result = {};
px_cast_result r = {};
for ( int i = 0; i < 3; i++ )
velocity[i] = destination[i] - origin[i];
r = px_box_cast(px, size[0], size[1], size[2], PX_GLM_VEC3(origin), PX_GLM_VEC3(rotation), PX_GLM_VEC3(velocity), 1);
result.bHit = r.hit;
result.fTime = r.time;
for ( int i = 0; i < 3; i++ )
{
result.position[i] = origin[i] + velocity[i] * result.fTime;
result.normal[i] = r.normal1.m[i];
result.normal2[i] = r.normal2.m[i];
}
return result;
}
void CPxCollider::Spawn( float fFriction )
{
};
void CPxCollider::Destroy()
{
};
void CPxBallMesh::Spawn( float fFriction )
{
m_pCollider = px_ball(m_fRadius, {.friction = fFriction});
};
void CPxBallMesh::Destroy()
{
};
void CPxBoxMesh::Spawn( float fFriction )
{
m_pCollider = px_box(m_fRadius[0], m_fRadius[1], m_fRadius[2], {.friction = fFriction});
};
void CPxBoxMesh::Destroy()
{
};
void CPxTriangleMesh::Spawn( float fFriction )
{
};
void CPxTriangleMesh::Destroy()
{
};
void CPxRigidKinematicPosition::Spawn( CPxCollider *pCollider, px_matrix matrix, px_rigidbody_params params )
{
m_pRigidBody = px_kinematic_position_body(px, pCollider->m_pCollider, matrix, params);
};
void CPxRigidKinematicPosition::SetPosition( px_vec3 position )
{
px_setposition(px, m_pRigidBody, position);
};
px_vec3 CPxRigidKinematicPosition::GetPosition( void )
{
return px_getposition(px, m_pRigidBody);
};
px_matrix CPxRigidKinematicPosition::GetMatrix ( void )
{
return px_getmatrix(px, m_pRigidBody);
};
void CPxRigidKinematicPosition::Destroy()
{
};
void CPxRigidBody::Spawn( CPxCollider *pCollider, px_matrix matrix, px_rigidbody_params params )
{
m_pRigidBody = px_rigidbody(px, pCollider->m_pCollider, matrix, params);
};
void CPxRigidBody::SetPosition( px_vec3 position )
{
px_setposition(px, m_pRigidBody, position);
}
void CPxRigidBody::SetVelocity( px_vec3 velocity )
{
px_setvelocity(px, m_pRigidBody, velocity);
}
px_vec3 CPxRigidBody::GetPosition( void )
{
return px_getposition(px, m_pRigidBody);
};
px_vec3 CPxRigidBody::GetVelocity( void )
{
return px_getvelocity(px, m_pRigidBody);
};
px_matrix CPxRigidBody::GetMatrix ( void )
{
return px_getmatrix(px, m_pRigidBody);
};
void CPxRigidBody::Destroy()
{
};
void CPxStaticBody::Spawn( CPxCollider *pCollider, px_matrix matrix, px_rigidbody_params params )
{
px_staticbody(px, pCollider->m_pCollider, matrix);
};
px_vec3 CPxStaticBody::GetPosition( void )
{
return px_getposition(px, m_pCollider);
};
px_matrix CPxStaticBody::GetMatrix ( void )
{
return px_getmatrix(px, m_pCollider);
};
void CPxStaticBody::Destroy()
{
}
;
void CPxFixedBody::Spawn( CPxCollider *pCollider, px_matrix matrix, px_rigidbody_params params )
{
px_fixedbody(px, pCollider->m_pCollider);
};
px_vec3 CPxFixedBody::GetPosition( void )
{
return px_getposition(px, m_pCollider);
};
px_matrix CPxFixedBody::GetMatrix ( void )
{
return px_getmatrix(px, m_pCollider);
};
void CPxFixedBody::Destroy()
{
};

View File

@@ -1,37 +0,0 @@
#include "rendering.h"
CRenderingStep::CRenderingStep()
{
}
CRenderingStep::CRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
}
CPrepassRenderingStep::CPrepassRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
Renderer()->m_StepPrepass.AppendTail({pfn(), szStepName});
}
CMeshRenderingStep::CMeshRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
Renderer()->m_StepMeshRendering.AppendTail({pfn(), szStepName});
}
CShadingRenderingStep::CShadingRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
Renderer()->m_StepShading.AppendTail({pfn(), szStepName});
}
CPostProcessingRenderingStep::CPostProcessingRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
Renderer()->m_StepPostProcessing.AppendTail({pfn(), szStepName});
}
CUIRenderingStep::CUIRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
Renderer()->m_StepUI.AppendTail({pfn(), szStepName});
}

View File

@@ -1,80 +0,0 @@
#include "server.h"
#include "engine.h"
#include "input.h"
#include "steam/steam_api_common.h"
#include "tier1/commandline.h"
#include "tier1/utlstring.h"
#include "baseentity.h"
#include "console.h"
#include "physics.h"
#include "input.h"
#include "networking.h"
void *g_serverdll;
ConVar g_tickrate("tickrate","64",FCVAR_PROTECTED);
float g_fAccumulator = 0;
extern "C" void IGame_Load(void);
//-----------------------------------------------------------------------------
// Loads game and client libraries if linking dynamically, otherwise it runs
// IGame_Load compiled statically.
//-----------------------------------------------------------------------------
void IServer::LoadGame( const char *psz )
{
#ifndef STATIC_BUILD
#ifdef __linux__
g_serverdll = Plat_LoadLibrary(CUtlString("%s/bin/libserver.so", psz));
if (!ICommandLine::CheckParam("-dedicated"))
Plat_LoadLibrary(CUtlString("%s/bin/libclient.so", psz));
#endif
#ifdef __APPLE__
g_serverdll = Plat_LoadLibrary(CUtlString("%s/bin/libserver.dylib", psz));
if (!ICommandLine::CheckParam("-dedicated"))
Plat_LoadLibrary(CUtlString("%s/bin/libclient.dylib", psz));
#endif
void (*GameLoadfn)() = (void(*)())Plat_GetProc(g_serverdll, "IGame_Load");
if (!GameLoadfn)
Plat_FatalErrorFunc("IGame_Load not found in libserver.so\n");
GameLoadfn();
#else
IGame_Load();
#endif
};
//-----------------------------------------------------------------------------
// Updates server and client state.
//-----------------------------------------------------------------------------
void IServer::Think( float fDelta )
{
g_fAccumulator += fDelta;
float fTickrate = 1.0/g_tickrate.GetFloat();
/* tickrate */
while(g_fAccumulator>=fTickrate)
{
if (INetworking::IsClient())
Input()->Frame();
Console()->Execute();
g_fAccumulator-=fTickrate;
for (auto &entity: EntityManager()->m_entities)
{
entity->Think(fTickrate);
entity->SendToServer();
}
px_frame(px, fTickrate);
INetworking::Frame();
}
for (auto &entity: EntityManager()->m_entities)
{
if (entity->pClientEntity)
entity->pClientEntity->Think(fDelta);
}
};
void IGame_Exit( int argc, char **argv ) {
IEngine::Shutdown();
Plat_Exit(0);
}
ConCommand ExitCmd("exit", IGame_Exit, 0);

21
engine/sv_dll.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include "sv_dll.h"
#include "tier1/interface.h"
#include "tier0/platform.h"
void CServerGameDLL::Init()
{
#if defined(__linux__)
#endif
}
void CServerGameDLL::Shutdown()
{
}
CServerGameDLL *ServerGameDLL()
{
static CServerGameDLL s_serverdll;
return &s_serverdll;
}

View File

@@ -1,49 +0,0 @@
#include "baseentity.h"
#include "physics.h"
class CLight: public CBaseEntity
{
public:
virtual void Precache ( void ) override;
virtual void Spawn( void ) override;
virtual void ReadParameter( const char *szName, const char *szValue ) override;
virtual void Destroy( void ) override;
virtual void Think( float fDelta ) override;
virtual void SendToServer() override;
virtual void RecieveFromServer( void *pData, uint32_t nDataSize ) override;
};
void CLight::Precache()
{
}
void CLight::Spawn()
{
};
void CLight::ReadParameter( const char *szName, const char *szValue )
{
CBaseEntity::ReadParameter(szName, szValue);
}
void CLight::Destroy()
{
}
void CLight::Think( float fDelta )
{
};
void CLight::SendToServer()
{
}
void CLight::RecieveFromServer( void *pData, uint32_t nDataSize )
{
};
DECLARE_ENTITY(light, CLight)

View File

@@ -1,74 +0,0 @@
#include "baseentity.h"
#include "baseplayer.h"
#include "engine.h"
#include "tier1/utlvector.h"
CUtlVector<CPlayerStart*> g_PlayerStarts = {};
void CPlayerStart::Precache()
{
}
void CPlayerStart::Spawn()
{
g_PlayerStarts.AppendTail(this);
};
void CPlayerStart::ReadParameter( const char *szName, const char *szValue )
{
CBaseEntity::ReadParameter(szName, szValue);
}
void CPlayerStart::Destroy()
{
uint32_t i = 0;
for (auto &start: g_PlayerStarts)
{
if (start == this)
{
g_PlayerStarts.RemoveAt(i);
break;
}
i++;
}
}
void CPlayerStart::Think( float fDelta )
{
}
void CPlayerStart::RoundEnd( void )
{
m_bIsRunning = false;
}
void CPlayerStart::RoundStart(IIClient *pClient)
{
IIEngine::DestroyEntity(pOwningPlayer);
if (!pClient)
return;
m_bIsRunning = true;
pOwningPlayer = (CBasePlayer*)IIEngine::SpawnEntity("player");
if (pOwningPlayer)
{
pOwningPlayer->pOwningSpawn = this;
pOwningPlayer->SetPosition(m_position);
}
else
V_printf("Failed to spawn player\n");
IIEngine::InitEntity(pOwningPlayer);
pClient->pBasePlayer = pOwningPlayer;
};
void CPlayerStart::SendToServer()
{
};
void CPlayerStart::RecieveFromServer( void *pData, uint32_t nDataSize )
{
};
DECLARE_ENTITY(info_player_start, CPlayerStart);

View File

@@ -1,51 +0,0 @@
#include "brush.h"
class CWorldSpawn: public CBrushEntity
{
public:
virtual void Precache ( void ) override;
virtual void Spawn( void ) override;
virtual void ReadParameter( const char *szName, const char *szValue ) override;
virtual void Destroy( void ) override;
virtual void Think( float fDelta ) override;
virtual void SendToServer() override;
virtual void RecieveFromServer( void *pData, uint32_t nDataSize ) override;
};
void CWorldSpawn::Precache()
{
CBrushEntity::Precache();
}
void CWorldSpawn::Spawn()
{
CBrushEntity::Spawn();
};
void CWorldSpawn::ReadParameter( const char *szName, const char *szValue )
{
CBrushEntity::ReadParameter(szName, szValue);
}
void CWorldSpawn::Destroy()
{
CBrushEntity::Destroy();
}
void CWorldSpawn::Think( float fDelta )
{
CBrushEntity::Think(fDelta);
}
void CWorldSpawn::SendToServer()
{
}
void CWorldSpawn::RecieveFromServer( void *pData, uint32_t nDataSize )
{
};
DECLARE_ENTITY(worldspawn, CWorldSpawn)

View File

@@ -1,16 +0,0 @@
VK_DEVICE_FUNCTION(vkCmdSetPolygonModeEXT);
VK_DEVICE_FUNCTION(vkCmdSetRasterizationSamplesEXT);
VK_DEVICE_FUNCTION(vkCmdSetVertexInputEXT);
VK_DEVICE_FUNCTION(vkCmdSetSampleMaskEXT);
VK_DEVICE_FUNCTION(vkCmdSetAlphaToCoverageEnableEXT);
VK_DEVICE_FUNCTION(vkCmdSetViewportWithCount);
VK_DEVICE_FUNCTION(vkCmdSetColorBlendEnableEXT);
VK_DEVICE_FUNCTION(vkCmdSetColorBlendEquationEXT);
VK_DEVICE_FUNCTION(vkCmdSetColorWriteMaskEXT);
VK_DEVICE_FUNCTION(vkCmdSetLogicOpEXT);
VK_DEVICE_FUNCTION(vkCmdTraceRaysKHR);
VK_DEVICE_FUNCTION(vkCreateAccelerationStructureKHR);
VK_DEVICE_FUNCTION(vkDestroyAccelerationStructureKHR);
VK_DEVICE_FUNCTION(vkGetAccelerationStructureBuildSizesKHR);
VK_DEVICE_FUNCTION(vkCmdBuildAccelerationStructuresKHR);
VK_DEVICE_FUNCTION(vkCreateRayTracingPipelinesKHR);

View File

@@ -1,74 +0,0 @@
#include "filesystem.h"
#include "rendering.h"
#include "tier0/platform.h"
#include "tier1/utlvector.h"
#include "console.h"
#include "tier1/commandline.h"
#include "vulkan/vulkan.h"
#define VULKAN_RENDERING_IMPL
#include "vk_video.h"
#define VK_DEVICE_FUNCTION(name) extern PFN_##name _##name
#include "vk_external_functions.cpp"
#undef VK_DEVICE_FUNCTION
class CVkBuffer: public IBuffer
{
public:
void *Map() override;
void Unmap() override;
vk_buffer_t m_buffer;
void *m_pAllocated = NULL;
};
class CVkImage: public IImage
{
public:
vk_image2d_t m_image = {};
uint32_t m_usage;
VkImageLayout m_currentLayout;
};
class CVkTexture: public ITexture
{
public:
vk_image2d_t image;
};
extern VkInstance g_vkInstance;
extern VkPhysicalDevice g_vkPhysicalDevice;
extern VkDevice g_vkDevice;
extern uint32_t g_drawfamily;
extern VkQueue g_drawQueue;
extern uint32_t g_presentfamily;
extern VkQueue g_presentQueue;
extern VmaAllocator g_allocator;
extern VkSurfaceKHR g_surface;
extern VkSwapchainKHR g_swapchain;
extern VkCommandPool g_vkCommandPool;
extern VkCommandBuffer g_vkCommandBuffer;
extern VkImageView g_swapchainImageView;
extern VkImage g_swapchainImage;
extern VkFormat g_swapchainFormat;
extern char g_bConfigNotify;
extern uint32_t g_nWindowWidth;
extern uint32_t g_nWindowHeight;
extern VkSampler g_invalidTextureSampler;
extern CUtlVector<ITexture*> g_textures;
extern IBuffer *g_cameraProperties;
extern IImage *g_meshDepth;
extern IImage *g_meshDepthMSAA;
extern IImage *g_meshColor;
extern IImage *g_meshColorMSAA;

File diff suppressed because it is too large Load Diff

View File

@@ -1,107 +0,0 @@
#ifndef VK_VIDEO_H
#define VK_VIDEO_H
#include "rendering.h"
#include "tier0/platform.h"
#include "tier1/utlvector.h"
#include "vulkan/vulkan.h"
#include "vulkan/vulkan_core.h"
#ifndef VULKAN_RENDERING_IMPL
#error "Not a vulkan rendering implementation. Do not use this file!"
#endif
#include "vk_mem_alloc.h"
struct vk_framedata_t {
VkSemaphore draw;
VkSemaphore present;
VkFence fence;
};
struct vk_shader_t
{
void Create( const char *szPath, VkShaderStageFlagBits shaderStage );
void Create( CUtlBuffer<uint8_t> &spirv, VkShaderStageFlagBits shaderStage );
void Destroy( void );
VkShaderModule m_shaderModule = NULL;
VkPipelineShaderStageCreateInfo m_stageCreateInfo;
};
struct vk_tripipeline_t
{
void Create(
CUtlVector<vk_shader_t> &shaders,
CUtlVector<VkDescriptorSetLayoutBinding> &bindings,
uint32_t pushConstantsSize,
uint32_t nVertexSize,
CUtlVector<VertexAttribute_t> vertexFormat,
CUtlVector<VkFormat> formats
/* the rest of the stuff is set by the dynamic state */
/* literally */
);
void Destroy();
CUtlVector<vk_shader_t> m_shaders;
VkDescriptorSetLayout m_descriptorSetLayout;
VkPipelineLayout m_layout;
VkPipeline m_pipeline;
};
struct vk_comppipeline_t
{
void Create(
vk_shader_t &shader,
CUtlVector<VkDescriptorSetLayoutBinding> &bindings,
uint32_t pushConstantsSize
);
void Destroy();
VkDescriptorSetLayout m_descriptorSetLayout;
VkPipelineLayout m_layout;
VkPipeline m_pipeline;
};
struct vk_buffer_t
{
void Create(size_t size, VkBufferUsageFlags usage);
void Destroy();
void *Map(size_t offset, size_t size);
void Unmap();
void CopyTo(struct vk_image2d_t *image);
void CopyTo(struct vk_buffer_t *buffer);
size_t m_nSize;
VkBuffer m_buffer;
VmaAllocation m_memory;
VkDeviceAddress m_address;
};
struct vk_image2d_t
{
void Create(size_t x, size_t y, VkFormat format, VkImageUsageFlags usage, VkSampleCountFlagBits samples);
void Destroy();
void CopyTo(struct vk_image2d_t *image);
void CopyTo(struct vk_buffer_t *buffer);
uint32_t m_X;
uint32_t m_Y;
VkFormat m_format;
VkImage m_image;
VkImageView m_imageView;
VmaAllocation m_memory;
};
interface IVulkan
{
public:
static void Init();
static void CreatePipelines();
static void Frame();
static void Deinit();
};
#endif

View File

@@ -1,452 +0,0 @@
#include "rendering.h"
#include "tier1/utlvector.h"
#include "console.h"
#include "tier1/commandline.h"
#include "X11/X.h"
#include "X11/Xlib.h"
#include "vulkan/vulkan.h"
#include "vulkan/vulkan_core.h"
#include "vulkan/vulkan_xlib.h"
#define VULKAN_RENDERING_IMPL
#include "vk_video.h"
#define VMA_VULKAN_VERSION 1004000
#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"
Display* g_xdisplay;
int g_xscreen;
Window g_xroot;
Window g_xwin;
VkInstance g_vkInstance = NULL;
VkPhysicalDevice g_vkPhysicalDevice = NULL;
VkDevice g_vkDevice = NULL;
uint32_t g_drawfamily = 0;
VkQueue g_drawQueue;
uint32_t g_presentfamily = 0;
VkQueue g_presentQueue;
VmaAllocator g_allocator = NULL;
VkSurfaceKHR g_surface;
VkSwapchainKHR g_swapchain;
ConVar vulkan_gpu("vk_gpu", "0", FCVAR_ARCHIVE);
VkCommandPool g_vkCommandPool;
/* more efficient */
CUtlVector<VkCommandBuffer> g_commandBuffers;
VkCommandBuffer g_vkCommandBuffer;
CUtlVector<vk_framedata_t> g_frameData;
CUtlVector<VkImage> g_swapchainImages;
CUtlVector<VkImageView> g_swapchainImageViews;
VkImageView g_swapchainImageView;
VkImage g_swapchainImage;
uint32_t g_nNumSwapchainImages = 0;
#define VK_DEVICE_FUNCTION(name) PFN_##name _##name
#include "vk_external_functions.cpp"
#undef VK_DEVICE_FUNCTION
char g_bConfigNotify = 0;
uint32_t g_nWindowWidth = 1280;
uint32_t g_nWindowHeight = 720;
void IVideo_SwapchainInit()
{
/* swapchain */
VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {};
surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
surfaceCreateInfo.dpy = g_xdisplay;
surfaceCreateInfo.window = g_xwin;
vkCreateXlibSurfaceKHR(g_vkInstance, &surfaceCreateInfo, NULL, &g_surface);
VkSurfaceCapabilitiesKHR surfaceCapatibilities = {};
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, g_surface, &surfaceCapatibilities);
const VkFormat preferedSurfaceFormats[] = {
VK_FORMAT_R8G8B8A8_UNORM,
VK_FORMAT_B8G8R8A8_UNORM,
};
uint32_t numSurfaceFormats = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, g_surface, &numSurfaceFormats, NULL);
CUtlVector<VkSurfaceFormatKHR> surfaceFormats(numSurfaceFormats);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, g_surface, &numSurfaceFormats, surfaceFormats.GetData());
VkSurfaceFormatKHR selectedFormat = surfaceFormats[0];
for (auto &format: surfaceFormats)
{
for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++)
{
selectedFormat = surfaceFormats[i];
}
}
uint32_t numSurfacePresentModes = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, NULL);
CUtlVector<VkPresentModeKHR> surfacePresentModes(numSurfacePresentModes);
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, surfacePresentModes.GetData());
VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchainCreateInfo.surface = g_surface;
swapchainCreateInfo.imageFormat = selectedFormat.format;
swapchainCreateInfo.imageColorSpace = selectedFormat.colorSpace;
swapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
swapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform;
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent;
swapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount;
vkCreateSwapchainKHR(g_vkDevice, &swapchainCreateInfo, NULL, &g_swapchain);
vkGetSwapchainImagesKHR(g_vkDevice, g_swapchain, &g_nNumSwapchainImages, NULL);
g_swapchainImages = CUtlVector<VkImage>(g_nNumSwapchainImages);
g_swapchainImageViews = CUtlVector<VkImageView>(g_nNumSwapchainImages);
g_commandBuffers = CUtlVector<VkCommandBuffer>(g_nNumSwapchainImages);
g_frameData = CUtlVector<vk_framedata_t>(g_nNumSwapchainImages);
vkGetSwapchainImagesKHR(g_vkDevice, g_swapchain, &g_nNumSwapchainImages, g_swapchainImages.GetData());
for (int i = 0; i < g_nNumSwapchainImages; i++)
{
VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = g_swapchainImages[i];
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = selectedFormat.format;
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;
vkCreateImageView(g_vkDevice, &createInfo, NULL, &g_swapchainImageViews[i]);
}
/* command buffers */
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.queueFamilyIndex = g_drawfamily;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
vkCreateCommandPool(g_vkDevice, &commandPoolCreateInfo, NULL, &g_vkCommandPool);
VkCommandBufferAllocateInfo commandBufferAllocInfo = {};
commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocInfo.commandPool = g_vkCommandPool;
commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocInfo.commandBufferCount = g_nNumSwapchainImages;
vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, g_commandBuffers.GetData());
/* sync */
VkFenceCreateInfo fenceCreateInfo = {};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
VkSemaphoreCreateInfo semaphoreCreateInfo = {};
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
for (int i = 0; i < g_nNumSwapchainImages; i++)
{
vkCreateFence(g_vkDevice,&fenceCreateInfo, NULL, &g_frameData[i].fence);
vkCreateSemaphore(g_vkDevice, &semaphoreCreateInfo, NULL, &g_frameData[i].draw);
vkCreateSemaphore(g_vkDevice, &semaphoreCreateInfo, NULL, &g_frameData[i].present);
}
};
void IVideo_SwapchainDestroy()
{
vkDestroySwapchainKHR(g_vkDevice, g_swapchain, NULL);
vkDestroySurfaceKHR(g_vkInstance, g_surface, NULL);
for (int i = 0; i < g_nNumSwapchainImages; i++)
{
vkDestroyImageView(g_vkDevice, g_swapchainImageViews[i], NULL);
vkDestroySemaphore(g_vkDevice, g_frameData[i].draw, NULL);
vkDestroySemaphore(g_vkDevice, g_frameData[i].present, NULL);
vkDestroyFence(g_vkDevice, g_frameData[i].fence, NULL);
}
};
void IVideo::Init()
{
g_xdisplay = XOpenDisplay(NULL);
g_xscreen = DefaultScreen(g_xdisplay);
g_xroot = RootWindow(g_xdisplay, g_xscreen);
g_xwin = XCreateSimpleWindow(g_xdisplay, g_xroot, 0, 0, 1280, 720, 0, 0, 0);
XSelectInput(g_xdisplay, g_xwin, StructureNotifyMask);
vulkan_gpu.SetValue(ICommandLine::ParamValue("-gpu"));
VkResult r = VK_SUCCESS;
uint32_t i = 0;
/* Instance */
VkApplicationInfo applicationInfo = {};
applicationInfo.apiVersion = VK_API_VERSION_1_4;
VkInstanceCreateInfo instanceCreateInfo = {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pApplicationInfo = &applicationInfo;
const char *szEnabledExtensions[] = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
};
instanceCreateInfo.enabledExtensionCount = 2;
instanceCreateInfo.ppEnabledExtensionNames = szEnabledExtensions;
r = vkCreateInstance(&instanceCreateInfo, NULL, &g_vkInstance);
if ( r != VK_SUCCESS )
Plat_FatalErrorFunc("Failed to create VkInstance!");
/* Physical Devices */
uint32_t nNumPhysicalDevices = 0;
vkEnumeratePhysicalDevices(g_vkInstance, &nNumPhysicalDevices, NULL);
if ( nNumPhysicalDevices == 0 )
Plat_FatalErrorFunc("No GPU drivers available!");
CUtlVector<VkPhysicalDevice> PhysicalDevices(nNumPhysicalDevices);
vkEnumeratePhysicalDevices(g_vkInstance, &nNumPhysicalDevices, PhysicalDevices.GetData());
/* enumerate them for the user */
for (auto &device: PhysicalDevices)
{
VkPhysicalDeviceProperties Properties = {};
vkGetPhysicalDeviceProperties(device, &Properties);
V_printf("GPU%i available: %s\n", i, Properties.deviceName);
i++;
}
/* select one in vk_gpu */
g_vkPhysicalDevice = PhysicalDevices[vulkan_gpu.GetInt()];
VkPhysicalDeviceProperties Properties = {};
vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &Properties);
V_printf("Using %s\n", Properties.deviceName);
/* queue family */
uint32_t nNumQueueFamilies = 0;
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL);
CUtlVector<VkQueueFamilyProperties> queueFamilyProperties(nNumQueueFamilies);
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData());
i = 0;
for (auto &family: queueFamilyProperties)
{
if (family.queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
g_drawfamily = i;
g_presentfamily = i;
}
i++;
}
/* create device */
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = g_drawfamily;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &queuePriority;
VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT pdvidsfe = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT,
.vertexInputDynamicState = VK_TRUE,
};
VkPhysicalDeviceExtendedDynamicState3FeaturesEXT pdeds3fe = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT,
.pNext = &pdvidsfe,
.extendedDynamicState3DepthClampEnable = VK_TRUE,
.extendedDynamicState3PolygonMode = VK_TRUE,
.extendedDynamicState3RasterizationSamples = VK_TRUE,
.extendedDynamicState3SampleMask = VK_TRUE,
.extendedDynamicState3AlphaToCoverageEnable = VK_TRUE,
.extendedDynamicState3LogicOpEnable = VK_TRUE,
.extendedDynamicState3ColorBlendEnable = VK_TRUE,
.extendedDynamicState3ColorBlendEquation = VK_TRUE,
.extendedDynamicState3ColorWriteMask = VK_TRUE,
};
VkPhysicalDeviceExtendedDynamicState2FeaturesEXT pdeds2fe = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT,
.pNext = &pdeds3fe,
.extendedDynamicState2LogicOp = VK_TRUE,
.extendedDynamicState2PatchControlPoints = VK_TRUE,
};
VkPhysicalDeviceVulkan13Features pdv13f = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
.pNext = &pdeds2fe,
.dynamicRendering = VK_TRUE,
};
VkPhysicalDeviceVulkan12Features pdv12f = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.pNext = &pdv13f,
.runtimeDescriptorArray = VK_TRUE,
.bufferDeviceAddress = VK_TRUE,
};
VkPhysicalDeviceVulkan11Features pdv11f = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
.pNext = &pdv12f,
};
const char *szEnabledGPUExtensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME,
};
VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.enabledExtensionCount = sizeof(szEnabledGPUExtensions)/(sizeof(const char*));
deviceCreateInfo.ppEnabledExtensionNames = szEnabledGPUExtensions;
deviceCreateInfo.pNext = &pdv11f;
r = vkCreateDevice(g_vkPhysicalDevice, &deviceCreateInfo, NULL, &g_vkDevice);
if ( r != VK_SUCCESS )
Plat_FatalErrorFunc("Failed to create VkDevice!");
vkGetDeviceQueue(g_vkDevice, g_drawfamily, 0, &g_drawQueue);
vkGetDeviceQueue(g_vkDevice, g_presentfamily, 0, &g_presentQueue);
VmaVulkanFunctions vulkanFunctions = {};
vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
VmaAllocatorCreateInfo allocatorCreateInfo = {};
allocatorCreateInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_4;
allocatorCreateInfo.physicalDevice = g_vkPhysicalDevice;
allocatorCreateInfo.device = g_vkDevice;
allocatorCreateInfo.instance = g_vkInstance;
vmaCreateAllocator(&allocatorCreateInfo, &g_allocator);
#define VK_DEVICE_FUNCTION(name) _##name = (PFN_##name)vkGetDeviceProcAddr(g_vkDevice, #name)
#include "vk_external_functions.cpp"
#undef VK_DEVICE_FUNCTION
IVideo_SwapchainInit();
XMapWindow(g_xdisplay, g_xwin);
XFlush(g_xdisplay);
IVulkan::Init();
}
void IVideo_HandleX11()
{
XEvent event;
while(XPending(g_xdisplay))
{
XNextEvent(g_xdisplay, &event);
switch (event.type)
{
case KeyPress:
case KeyRelease:
break;
case MotionNotify:
break;
case ButtonPress:
break;
case ButtonRelease:
break;
case CreateNotify:
break;
case ConfigureNotify:
g_nWindowWidth = event.xconfigure.width;
g_nWindowHeight = event.xconfigure.height;
g_bConfigNotify = 2;
break;
}
}
};
void IVideo::Frame( float fDelta )
{
static uint32_t s_frameID = 0;
IVideo_HandleX11();
vk_framedata_t frame = g_frameData[s_frameID];
vkDeviceWaitIdle(g_vkDevice);
vkWaitForFences(g_vkDevice, 1, &frame.fence, VK_TRUE, UINT64_MAX);
uint32_t imageIndex = 0;
VkResult r = vkAcquireNextImageKHR(g_vkDevice, g_swapchain, UINT64_MAX, frame.draw, VK_NULL_HANDLE, &imageIndex);
if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR || g_bConfigNotify == 2)
{
g_bConfigNotify=1;
vkDeviceWaitIdle(g_vkDevice);
IVideo_SwapchainDestroy();
IVideo_SwapchainInit();
return;
}
vk_framedata_t frameindex = g_frameData[imageIndex];
vkResetFences(g_vkDevice, 1, &frame.fence);
g_vkCommandBuffer = g_commandBuffers[s_frameID];
g_swapchainImageView = g_swapchainImageViews[imageIndex];
g_swapchainImage = g_swapchainImages[imageIndex];
vkResetCommandBuffer(g_vkCommandBuffer, 0);
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(g_vkCommandBuffer, &beginInfo);
IVulkan::Frame();
vkEndCommandBuffer(g_vkCommandBuffer);
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &frame.draw;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &g_vkCommandBuffer;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &frameindex.present;
vkQueueSubmit(g_drawQueue, 1, &submitInfo, frame.fence);
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &frameindex.present;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &g_swapchain;
presentInfo.pImageIndices = &imageIndex;
r = vkQueuePresentKHR(g_presentQueue, &presentInfo);
if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR)
{
vkDeviceWaitIdle(g_vkDevice);
IVideo_SwapchainDestroy();
IVideo_SwapchainInit();
return;
}
g_bConfigNotify = 0;
s_frameID=(s_frameID+1)%g_nNumSwapchainImages;
};

View File

@@ -1,566 +0,0 @@
#include "SDL3/SDL_gamepad.h"
#include "SDL3/SDL_joystick.h"
#include "rendering.h"
#include "tier0/platform.h"
#include "tier1/utlvector.h"
#include "console.h"
#include "tier1/commandline.h"
#include "input.h"
#include "vulkan/vulkan.h"
#include "SDL3/SDL.h"
#include "vulkan/vulkan_core.h"
#include "SDL3/SDL_keycode.h"
#include "SDL3/SDL_vulkan.h"
#include "SDL3/SDL_events.h"
#define VULKAN_RENDERING_IMPL
#include "vk_video.h"
#define VMA_VULKAN_VERSION 1004000
#define VMA_IMPLEMENTATION
#include "tier0/minmax_off.h"
#include "vk_mem_alloc.h"
#include "tier0/minmax.h"
SDL_Window *g_window;
VkInstance g_vkInstance = NULL;
VkPhysicalDevice g_vkPhysicalDevice = NULL;
VkDevice g_vkDevice = NULL;
uint32_t g_drawfamily = 0;
VkQueue g_drawQueue;
uint32_t g_presentfamily = 0;
VkQueue g_presentQueue;
VmaAllocator g_allocator = NULL;
VkSurfaceKHR g_surface;
VkSwapchainKHR g_swapchain;
ConVar vulkan_gpu("vk_gpu", "0", FCVAR_ARCHIVE);
VkCommandPool g_vkCommandPool;
/* more efficient */
CUtlVector<VkCommandBuffer> g_commandBuffers;
VkCommandBuffer g_vkCommandBuffer;
CUtlVector<vk_framedata_t> g_frameData;
CUtlVector<VkImage> g_swapchainImages;
CUtlVector<VkImageView> g_swapchainImageViews;
VkImageView g_swapchainImageView;
VkImage g_swapchainImage;
VkFormat g_swapchainFormat;
uint32_t g_nNumSwapchainImages = 0;
char g_bConfigNotify = 0;
uint32_t g_nWindowWidth = 1280;
uint32_t g_nWindowHeight = 720;
#define VK_DEVICE_FUNCTION(name) PFN_##name _##name
#include "vk_external_functions.cpp"
#undef VK_DEVICE_FUNCTION
void IVideo_SwapchainInit()
{
/* swapchain */
SDL_Vulkan_CreateSurface(g_window, g_vkInstance, NULL, &g_surface);
VkSurfaceCapabilitiesKHR surfaceCapatibilities = {};
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vkPhysicalDevice, g_surface, &surfaceCapatibilities);
const VkFormat preferedSurfaceFormats[] = {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_R8G8B8A8_UNORM,
};
uint32_t numSurfaceFormats = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, g_surface, &numSurfaceFormats, NULL);
CUtlVector<VkSurfaceFormatKHR> surfaceFormats(numSurfaceFormats);
vkGetPhysicalDeviceSurfaceFormatsKHR(g_vkPhysicalDevice, g_surface, &numSurfaceFormats, surfaceFormats.GetData());
VkSurfaceFormatKHR selectedFormat = surfaceFormats[0];
for (auto &format: surfaceFormats)
{
for (int i = 0; i < sizeof(preferedSurfaceFormats)/sizeof(VkFormat); i++)
{
if (format.format == preferedSurfaceFormats[i])
{
selectedFormat = format;
goto formatPicked;
}
}
}
formatPicked:
uint32_t numSurfacePresentModes = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, NULL);
CUtlVector<VkPresentModeKHR> surfacePresentModes(numSurfacePresentModes);
vkGetPhysicalDeviceSurfacePresentModesKHR(g_vkPhysicalDevice, g_surface, &numSurfacePresentModes, surfacePresentModes.GetData());
VkSwapchainCreateInfoKHR swapchainCreateInfo = {};
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchainCreateInfo.surface = g_surface;
swapchainCreateInfo.imageFormat = selectedFormat.format;
swapchainCreateInfo.imageColorSpace = selectedFormat.colorSpace;
swapchainCreateInfo.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
swapchainCreateInfo.preTransform = surfaceCapatibilities.currentTransform;
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageExtent = surfaceCapatibilities.minImageExtent;
swapchainCreateInfo.minImageCount = surfaceCapatibilities.minImageCount;
vkCreateSwapchainKHR(g_vkDevice, &swapchainCreateInfo, NULL, &g_swapchain);
vkGetSwapchainImagesKHR(g_vkDevice, g_swapchain, &g_nNumSwapchainImages, NULL);
g_swapchainImages = CUtlVector<VkImage>(g_nNumSwapchainImages);
g_swapchainImageViews = CUtlVector<VkImageView>(g_nNumSwapchainImages);
g_commandBuffers = CUtlVector<VkCommandBuffer>(g_nNumSwapchainImages);
g_frameData = CUtlVector<vk_framedata_t>(g_nNumSwapchainImages);
vkGetSwapchainImagesKHR(g_vkDevice, g_swapchain, &g_nNumSwapchainImages, g_swapchainImages.GetData());
for (int i = 0; i < g_nNumSwapchainImages; i++)
{
VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = g_swapchainImages[i];
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = selectedFormat.format;
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;
vkCreateImageView(g_vkDevice, &createInfo, NULL, &g_swapchainImageViews[i]);
}
g_swapchainFormat = selectedFormat.format;
/* command buffers */
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
commandPoolCreateInfo.queueFamilyIndex = g_drawfamily;
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
vkCreateCommandPool(g_vkDevice, &commandPoolCreateInfo, NULL, &g_vkCommandPool);
VkCommandBufferAllocateInfo commandBufferAllocInfo = {};
commandBufferAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
commandBufferAllocInfo.commandPool = g_vkCommandPool;
commandBufferAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
commandBufferAllocInfo.commandBufferCount = g_nNumSwapchainImages;
vkAllocateCommandBuffers(g_vkDevice, &commandBufferAllocInfo, g_commandBuffers.GetData());
/* sync */
VkFenceCreateInfo fenceCreateInfo = {};
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
VkSemaphoreCreateInfo semaphoreCreateInfo = {};
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
for (int i = 0; i < g_nNumSwapchainImages; i++)
{
vkCreateFence(g_vkDevice,&fenceCreateInfo, NULL, &g_frameData[i].fence);
vkCreateSemaphore(g_vkDevice, &semaphoreCreateInfo, NULL, &g_frameData[i].draw);
vkCreateSemaphore(g_vkDevice, &semaphoreCreateInfo, NULL, &g_frameData[i].present);
}
};
void IVideo_SwapchainDestroy()
{
vkDestroySwapchainKHR(g_vkDevice, g_swapchain, NULL);
vkDestroySurfaceKHR(g_vkInstance, g_surface, NULL);
for (int i = 0; i < g_nNumSwapchainImages; i++)
{
vkDestroyImageView(g_vkDevice, g_swapchainImageViews[i], NULL);
vkDestroySemaphore(g_vkDevice, g_frameData[i].draw, NULL);
vkDestroySemaphore(g_vkDevice, g_frameData[i].present, NULL);
vkDestroyFence(g_vkDevice, g_frameData[i].fence, NULL);
}
};
EInputKey ISDL_KeyName(SDL_Keycode key)
{
switch(key)
{
case SDLK_ESCAPE: return KEY_ESCAPE;
case SDLK_TAB: return KEY_TAB;
case SDLK_RETURN: return KEY_ENTER;
case SDLK_RCTRL: return KEY_CONTROL;
case SDLK_LCTRL: return KEY_CONTROL;
case SDLK_RSHIFT: return KEY_SHIFT;
case SDLK_LSHIFT: return KEY_SHIFT;
case SDLK_RALT: return KEY_ALT;
case SDLK_LALT: return KEY_ALT;
case SDLK_SPACE: return KEY_SPACE;
case SDLK_GRAVE: return KEY_TILDE;
case SDLK_F1: return KEY_F1;
case SDLK_F2: return KEY_F2;
case SDLK_F3: return KEY_F3;
case SDLK_F4: return KEY_F4;
case SDLK_F5: return KEY_F5;
case SDLK_F6: return KEY_F6;
case SDLK_F7: return KEY_F7;
case SDLK_F8: return KEY_F8;
case SDLK_F9: return KEY_F9;
case SDLK_F10: return KEY_F10;
case SDLK_F11: return KEY_F11;
case SDLK_F12: return KEY_F12;
case SDLK_1: return KEY_1;
case SDLK_2: return KEY_2;
case SDLK_3: return KEY_3;
case SDLK_4: return KEY_4;
case SDLK_5: return KEY_5;
case SDLK_6: return KEY_6;
case SDLK_7: return KEY_7;
case SDLK_8: return KEY_8;
case SDLK_9: return KEY_9;
case SDLK_0: return KEY_0;
case SDLK_A: return KEY_A;
case SDLK_B: return KEY_B;
case SDLK_C: return KEY_C;
case SDLK_D: return KEY_D;
case SDLK_E: return KEY_E;
case SDLK_F: return KEY_F;
case SDLK_G: return KEY_G;
case SDLK_H: return KEY_H;
case SDLK_I: return KEY_I;
case SDLK_J: return KEY_J;
case SDLK_K: return KEY_K;
case SDLK_L: return KEY_L;
case SDLK_M: return KEY_M;
case SDLK_N: return KEY_N;
case SDLK_O: return KEY_O;
case SDLK_P: return KEY_P;
case SDLK_Q: return KEY_Q;
case SDLK_R: return KEY_R;
case SDLK_S: return KEY_S;
case SDLK_T: return KEY_T;
case SDLK_U: return KEY_U;
case SDLK_V: return KEY_V;
case SDLK_W: return KEY_W;
case SDLK_X: return KEY_X;
case SDLK_Y: return KEY_Y;
case SDLK_Z: return KEY_Z;
}
return KEY_NONE;
};
void IVideo::Init()
{
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_GAMEPAD);
g_window = SDL_CreateWindow("rtt", 1280, 720, SDL_WINDOW_VULKAN);
int nNumGamepads = 0;
SDL_JoystickID *pGamepads = SDL_GetGamepads(&nNumGamepads);
for ( uint32_t i = 0; i < nNumGamepads; i++ )
{
SDL_OpenGamepad(pGamepads[i]);
}
unsigned int nExtensionCount = 0;
const char* const* szExtensions = SDL_Vulkan_GetInstanceExtensions(&nExtensionCount);
vulkan_gpu.SetValue(ICommandLine::ParamValue("-gpu"));
VkResult r = VK_SUCCESS;
uint32_t i = 0;
/* Instance */
VkApplicationInfo applicationInfo = {};
applicationInfo.apiVersion = VK_API_VERSION_1_4;
VkInstanceCreateInfo instanceCreateInfo = {};
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pApplicationInfo = &applicationInfo;
instanceCreateInfo.enabledExtensionCount = nExtensionCount;
instanceCreateInfo.ppEnabledExtensionNames = szExtensions;
r = vkCreateInstance(&instanceCreateInfo, NULL, &g_vkInstance);
if ( r != VK_SUCCESS )
Plat_FatalErrorFunc("Failed to create VkInstance!");
/* Physical Devices */
uint32_t nNumPhysicalDevices = 0;
vkEnumeratePhysicalDevices(g_vkInstance, &nNumPhysicalDevices, NULL);
if ( nNumPhysicalDevices == 0 )
Plat_FatalErrorFunc("No GPU drivers available!");
CUtlVector<VkPhysicalDevice> PhysicalDevices(nNumPhysicalDevices);
vkEnumeratePhysicalDevices(g_vkInstance, &nNumPhysicalDevices, PhysicalDevices.GetData());
/* enumerate them for the user */
for (auto &device: PhysicalDevices)
{
VkPhysicalDeviceProperties Properties = {};
vkGetPhysicalDeviceProperties(device, &Properties);
V_printf("GPU%i available: %s\n", i, Properties.deviceName);
i++;
}
/* select one in vk_gpu */
g_vkPhysicalDevice = PhysicalDevices[vulkan_gpu.GetInt()];
VkPhysicalDeviceProperties Properties = {};
vkGetPhysicalDeviceProperties(g_vkPhysicalDevice, &Properties);
V_printf("Using %s\n", Properties.deviceName);
/* queue family */
uint32_t nNumQueueFamilies = 0;
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, NULL);
CUtlVector<VkQueueFamilyProperties> queueFamilyProperties(nNumQueueFamilies);
vkGetPhysicalDeviceQueueFamilyProperties(g_vkPhysicalDevice, &nNumQueueFamilies, queueFamilyProperties.GetData());
i = 0;
for (auto &family: queueFamilyProperties)
{
if (family.queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
g_drawfamily = i;
g_presentfamily = i;
}
i++;
}
/* create device */
float queuePriority = 1.0f;
VkDeviceQueueCreateInfo queueCreateInfo = {};
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo.queueFamilyIndex = g_drawfamily;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &queuePriority;
VkPhysicalDeviceShaderObjectFeaturesEXT pdsofe = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT,
.pNext = 0,
.shaderObject = VK_TRUE,
};
VkPhysicalDeviceExtendedDynamicState3FeaturesEXT pdeds3fe = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT,
.pNext = &pdsofe,
.extendedDynamicState3DepthClampEnable = VK_TRUE,
.extendedDynamicState3PolygonMode = VK_TRUE,
.extendedDynamicState3RasterizationSamples = VK_TRUE,
.extendedDynamicState3SampleMask = VK_TRUE,
.extendedDynamicState3AlphaToCoverageEnable = VK_TRUE,
};
VkPhysicalDeviceVulkan13Features pdv13f = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES,
.pNext = &pdeds3fe,
.synchronization2 = VK_TRUE,
.dynamicRendering = VK_TRUE,
};
VkPhysicalDeviceVulkan12Features pdv12f = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.pNext = &pdv13f,
.runtimeDescriptorArray = VK_TRUE,
.bufferDeviceAddress = VK_TRUE,
};
VkPhysicalDeviceVulkan11Features pdv11f = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
.pNext = &pdv12f,
};
const char *szEnabledGPUExtensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME,
};
VkDeviceCreateInfo deviceCreateInfo = {};
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.enabledExtensionCount = sizeof(szEnabledGPUExtensions)/(sizeof(const char*));
deviceCreateInfo.ppEnabledExtensionNames = szEnabledGPUExtensions;
deviceCreateInfo.pNext = &pdv11f;
r = vkCreateDevice(g_vkPhysicalDevice, &deviceCreateInfo, NULL, &g_vkDevice);
if ( r != VK_SUCCESS )
Plat_FatalErrorFunc("Failed to create VkDevice!");
vkGetDeviceQueue(g_vkDevice, g_drawfamily, 0, &g_drawQueue);
vkGetDeviceQueue(g_vkDevice, g_presentfamily, 0, &g_presentQueue);
VmaVulkanFunctions vulkanFunctions = {};
vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
VmaAllocatorCreateInfo allocatorCreateInfo = {};
allocatorCreateInfo.flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_4;
allocatorCreateInfo.physicalDevice = g_vkPhysicalDevice;
allocatorCreateInfo.device = g_vkDevice;
allocatorCreateInfo.instance = g_vkInstance;
vmaCreateAllocator(&allocatorCreateInfo, &g_allocator);
#define VK_DEVICE_FUNCTION(name) _##name = (PFN_##name)vkGetDeviceProcAddr(g_vkDevice, #name)
#include "vk_external_functions.cpp"
#undef VK_DEVICE_FUNCTION
IVideo_SwapchainInit();
IVulkan::Init();
}
void IInput::SetInputMode( EInputMode mode )
{
switch (mode)
{
case INPUT_MODE_GAME:
SDL_SetWindowRelativeMouseMode(g_window, true);
return;
case INPUT_MODE_MENU:
SDL_SetWindowRelativeMouseMode(g_window, false);
return;
case INPUT_MODE_CONSOLE:
SDL_SetWindowRelativeMouseMode(g_window, true);
return;
default:
return;
}
}
ConVar m_pitch("m_pitch", "0.022", FCVAR_ARCHIVE);
ConVar m_yaw("m_yaw", "0.022", FCVAR_ARCHIVE);
void IVideo_HandleEvents()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
SDL_KeyboardEvent *key = &event.key;
SDL_MouseMotionEvent *motion = &event.motion;
switch (event.type)
{
case SDL_EVENT_WINDOW_RESIZED:
g_nWindowWidth = event.window.data1;
g_nWindowHeight = event.window.data2;
g_bConfigNotify = 2;
break;
case SDL_EVENT_KEY_DOWN:
if (!key->repeat)
Input()->KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_DOWN);
break;
case SDL_EVENT_KEY_UP:
key = &event.key;
if (!key->repeat)
Input()->KeyEvent(ISDL_KeyName(key->key),KEY_EVENT_TYPE_UP);
break;
case SDL_EVENT_MOUSE_MOTION:
Input()->AxisEvent(AXIS_MOUSE_X, motion->yrel*m_pitch.GetFloat());
Input()->AxisEvent(AXIS_MOUSE_Y, -motion->xrel*m_yaw.GetFloat());
break;
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
{
SDL_GamepadAxis axis = (SDL_GamepadAxis)event.gaxis.axis;
float value = event.gaxis.value / 32768.0f;
if (abs(event.gaxis.value)<1000)
value = 0;
SDL_JoystickID id = event.gaxis.which;
if (axis == SDL_GAMEPAD_AXIS_RIGHTY)
{
Input()->AxisEvent(AXIS_CONTROLLER_PITCH, value);
}
if (axis == SDL_GAMEPAD_AXIS_RIGHTX)
{
Input()->AxisEvent(AXIS_CONTROLLER_YAW, -value);
}
}
break;
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
break;
case SDL_EVENT_GAMEPAD_BUTTON_UP:
break;
}
};
};
void IVideo::CreatePipelines( )
{
IVulkan::CreatePipelines();
};
void IVideo::Frame( float fDelta )
{
static uint32_t s_frameID = 0;
IVideo_HandleEvents();
vk_framedata_t frame = g_frameData[s_frameID];
vkDeviceWaitIdle(g_vkDevice);
vkWaitForFences(g_vkDevice, 1, &frame.fence, VK_TRUE, UINT64_MAX);
uint32_t imageIndex = 0;
VkResult r = vkAcquireNextImageKHR(g_vkDevice, g_swapchain, UINT64_MAX, frame.draw, VK_NULL_HANDLE, &imageIndex);
if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR || g_bConfigNotify == 2)
{
g_bConfigNotify=1;
vkDeviceWaitIdle(g_vkDevice);
IVideo_SwapchainDestroy();
IVideo_SwapchainInit();
return;
}
vk_framedata_t frameindex = g_frameData[imageIndex];
vkResetFences(g_vkDevice, 1, &frame.fence);
g_vkCommandBuffer = g_commandBuffers[s_frameID];
g_swapchainImageView = g_swapchainImageViews[imageIndex];
g_swapchainImage = g_swapchainImages[imageIndex];
vkResetCommandBuffer(g_vkCommandBuffer, 0);
VkCommandBufferBeginInfo beginInfo = {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
vkBeginCommandBuffer(g_vkCommandBuffer, &beginInfo);
IVulkan::Frame();
vkEndCommandBuffer(g_vkCommandBuffer);
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &frame.draw;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &g_vkCommandBuffer;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &frameindex.present;
vkQueueSubmit(g_drawQueue, 1, &submitInfo, frame.fence);
VkPresentInfoKHR presentInfo = {};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &frameindex.present;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &g_swapchain;
presentInfo.pImageIndices = &imageIndex;
r = vkQueuePresentKHR(g_presentQueue, &presentInfo);
if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR)
{
vkDeviceWaitIdle(g_vkDevice);
IVideo_SwapchainDestroy();
IVideo_SwapchainInit();
return;
}
g_bConfigNotify = 0;
s_frameID=(s_frameID+1)%g_nNumSwapchainImages;
};