diff --git a/funnyassets/meshes/spot.fmesh_c b/funnyassets/meshes/spot.fmesh_c new file mode 100644 index 0000000..6de04bd Binary files /dev/null and b/funnyassets/meshes/spot.fmesh_c differ diff --git a/funnyassets/shaders/mesh_raster.shader b/funnyassets/shaders/mesh_raster.shader index 9d3acf0..7abde48 100644 --- a/funnyassets/shaders/mesh_raster.shader +++ b/funnyassets/shaders/mesh_raster.shader @@ -57,19 +57,16 @@ VS PS { #include "brdf.hlsl" - - float4 psMain( PS_INPUT input ) + struct PS_OUTPUT { - - float4 vWorldSpacePosition = input.m_vNormal; - BRDF_t brdf = {}; - brdf.m_vRayIn = normalize(g_vViewPosition.xyz-input.m_vWorldPosition.xyz); - brdf.m_vRayOut = normalize(-input.m_vWorldPosition.xyz); - brdf.m_vNormal = input.m_vNormal.xyz; - brdf.m_fRoughness = 1; - brdf.m_fMetalness = 1; + float4 m_vAlbedo: SV_Target0; + } - return float4(brdf.BurleyDiffuse(), 1); + PS_OUTPUT psMain( PS_INPUT input ) + { + PS_OUTPUT output = {}; + output.m_vAlbedo = input.m_vNormal; + return output; } } diff --git a/game/client/baseentity.cpp b/game/client/baseentity.cpp new file mode 100644 index 0000000..f7d8b42 --- /dev/null +++ b/game/client/baseentity.cpp @@ -0,0 +1,114 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#include "baseentity.h" +#include "datamap.h" +#include "tier0/lib.h" + +C_BaseEntity::~C_BaseEntity() +{ + +} +void C_BaseEntity::Precache() +{ + +} + +void C_BaseEntity::Spawn() +{ + +} + +void C_BaseEntity::SetAbsAngles( float fPitch, float fYaw, float fRoll ) +{ +} + +void C_BaseEntity::SetAbsOrigin( Vector origin ) +{ + m_vPosition = origin; +} + +void C_BaseEntity::SetScale( float fScale ) +{ + m_vScale.x = fScale; + m_vScale.y = fScale; + m_vScale.z = fScale; +} + + +QAngle C_BaseEntity::GetAbsAngles( void ) +{ + +} + +Vector C_BaseEntity::GetAbsOrigin( void ) +{ + +} + +float C_BaseEntity::GetScale( void ) +{ + +} + +void C_BaseEntity::SetThinkImpl( fnThink pfnThink ) +{ + m_pfnThink = pfnThink; + V_printf("%p\n", pfnThink); +} + +void C_BaseEntity::SetNextThink( float fThink ) +{ + +} +typedescription_t *C_BaseEntity::FindDataByName( const char *szName ) +{ + datamap_t *pDataMap; + int i; + + pDataMap = GetDataMap(); + +lookforname: + for ( i = 0; i < pDataMap->m_iNumFields; i++ ) + { + if (!V_strcmp(pDataMap->m_pData[i].m_szFieldName, szName)) + return &pDataMap->m_pData[i]; + } + pDataMap = pDataMap->m_pBase; + + if (pDataMap) + goto lookforname; + + return NULL; +}; + +typedescription_t *C_BaseEntity::FindDataByMapName( const char *szName ) +{ + datamap_t *pDataMap; + int i; + + pDataMap = GetDataMap(); + +lookforname: + for ( i = 0; i < pDataMap->m_iNumFields; i++ ) + { + if (!V_strcmp(pDataMap->m_pData[i].m_szEditorName, szName)) + return &pDataMap->m_pData[i]; + } + pDataMap = pDataMap->m_pBase; + + if (pDataMap) + goto lookforname; + + return NULL; +}; + + +BEGIN_DATADESC_NOBASE(C_BaseEntity) + DEFINE_KEYFIELD(m_vPosition, FIELD_VECTOR, "origin") + DEFINE_KEYFIELD(m_vRotation, FIELD_QUATERNION, "angles") + DEFINE_KEYFIELD(m_vScale, FIELD_VECTOR, "scales") +END_DATADESC() diff --git a/game/client/baseentity.h b/game/client/baseentity.h new file mode 100644 index 0000000..0640f51 --- /dev/null +++ b/game/client/baseentity.h @@ -0,0 +1,81 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#ifndef BASEENTITY_H +#define BASEENTITY_H + +#include "entitysystem.h" +#include "datamap.h" +#include "cglm/cglm.h" +#include "trig.h" + +#define DECLARE_CLASS_NOBASE( className ) \ + typedef className ThisClass; +#define DECLARE_CLASS( className, baseName ) \ + typedef baseName BaseClass; \ + typedef className ThisClass; + +#define LINK_ENTITY_TO_CLASS( mapClassName, DLLClassName) \ + static CEntityFactory g_EntityFactory_##mapClassName( #mapClassName ); + +class C_BaseEntity; + +class IEntityFactory +{ +public: + virtual C_BaseEntity *Create() = 0; +}; + + +template +class CEntityFactory : public IEntityFactory +{ +public: + CEntityFactory( const char *szClassName ) + { + EntitySystem()->RegisterEntityClass(this, szClassName); + }; + virtual C_BaseEntity *Create() { + return new T; + } +}; + + +class C_BaseEntity; +typedef void(C_BaseEntity::*fnThink)( float fTime ); +class C_BaseEntity +{ +public: + DECLARE_CLASS_NOBASE(C_BaseEntity); + DECLARE_DATADESC_NOBASE() + + typedescription_t *FindDataByName( const char *szName ); + typedescription_t *FindDataByMapName( const char *szName ); + + virtual ~C_BaseEntity(); + virtual void Precache(); + virtual void Spawn(); + + virtual void SetAbsAngles( float fPitch, float fYaw, float fRoll ); + virtual void SetAbsOrigin( Vector origin ); + virtual void SetScale( float fScale ); + + virtual QAngle GetAbsAngles( void ); + virtual Vector GetAbsOrigin( void ); + virtual float GetScale( void ); + +#define SetThink(fn) SetThinkImpl((fnThink)&ThisClass::fn) + virtual void SetThinkImpl( fnThink pfnThink ); + virtual void SetNextThink( float fThink ); + + fnThink m_pfnThink = NULL; +private: + Vector m_vPosition; + Quat m_vRotation; + Vector m_vScale; +}; + +#endif diff --git a/game/client/build.cpp b/game/client/build.cpp index 4d3ed17..7a63901 100644 --- a/game/client/build.cpp +++ b/game/client/build.cpp @@ -16,8 +16,12 @@ DECLARE_BUILD_STAGE(Client) compileProject.files = { "game.cpp", "worldrender.cpp", + "baseentity.cpp", + "entitysystem.cpp", + "milmoba/player.cpp", }; compileProject.includeDirectories = { + "../shared", "../../public", FUNNYSTDLIB"public", EXTERNAL"cglm/include" diff --git a/game/client/entitysystem.cpp b/game/client/entitysystem.cpp new file mode 100644 index 0000000..38cc063 --- /dev/null +++ b/game/client/entitysystem.cpp @@ -0,0 +1,120 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#include "entitysystem.h" +#include "baseentity.h" +#include "stddef.h" +#include "string.h" +#include "stdlib.h" + + +CEntitySystem *EntitySystem() +{ + static CEntitySystem s_entitySystem; + return &s_entitySystem; +} + +static struct EntityRegistry_t +{ + IEntityFactory *m_pFactory; + const char *m_szClassName; + struct EntityRegistry_t *m_pNext; +} *s_pEntitiesRegistry = NULL; + +CEntitySystem::CEntitySystem() +{ + int i = 0; + for ( i = 0; i < MAX_EDICTS; i++ ) + { + m_pEntities[i] = NULL; + } + m_nEntityCount = 0; +} + +void CEntitySystem::RegisterEntityClass( IEntityFactory *pEntityFactory, const char *szClassName ) +{ + IEntityFactory *pFactory; + EntityRegistry_t *pRegistry; + + pFactory = GetFactoryByClassname(szClassName); + + if ( pFactory != NULL ) + { + // Already registered + return; + } + + pRegistry = new EntityRegistry_t; + pRegistry->m_pFactory = pEntityFactory; + pRegistry->m_pNext = s_pEntitiesRegistry; + pRegistry->m_szClassName = szClassName; + s_pEntitiesRegistry = pRegistry; +} + +C_BaseEntity *CEntitySystem::CreateByClassname( const char *szName ) +{ + IEntityFactory *pFactory; + C_BaseEntity *pEntity; + int i; + int iSelectedSlot; + + pFactory = GetFactoryByClassname(szName); + if ( !pFactory ) + return NULL; + + // We do not want to have more than MAX_EDICT entities + if ( m_nEntityCount >= MAX_EDICTS-1 ) + return NULL; + + // Search for space + // Could be more efficient but nobody cares + for ( i = 0; i < MAX_EDICTS; i++ ) + { + if ( m_pEntities[i] == NULL ) + { + iSelectedSlot = i; + break; + } + } + + pEntity = pFactory->Create(); + m_pEntities[iSelectedSlot] = pEntity; + m_nEntityCount++; + return pEntity; +} + +IEntityFactory *CEntitySystem::GetFactoryByClassname( const char *szName ) +{ + EntityRegistry_t *pEntity; + + for ( pEntity = s_pEntitiesRegistry; pEntity; pEntity = pEntity->m_pNext ) + { + if (!strcmp(szName, pEntity->m_szClassName)) + { + return pEntity->m_pFactory; + } + } + return NULL; +} + + +void CEntitySystem::Think() +{ + C_BaseEntity *pEntity; + int i; + + for ( i = 0; i < MAX_EDICTS; i++ ) + { + pEntity = m_pEntities[i]; + if ( pEntity == NULL ) + continue; + + if ( !pEntity->m_pfnThink ) + continue; + + (pEntity->*pEntity->m_pfnThink)(0); + } +} diff --git a/game/client/entitysystem.h b/game/client/entitysystem.h new file mode 100644 index 0000000..a4c7cf0 --- /dev/null +++ b/game/client/entitysystem.h @@ -0,0 +1,33 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#ifndef ENTITIES_H +#define ENTITIES_H + +class IEntityFactory; +class C_BaseEntity; + +#define MAX_EDICTS 8192 + +class CEntitySystem +{ +public: + CEntitySystem(); + + virtual void RegisterEntityClass( IEntityFactory *pEntityFactory, const char *szClassName ); + virtual C_BaseEntity *CreateByClassname( const char *szName ); + + virtual IEntityFactory *GetFactoryByClassname( const char *szName ); + + virtual void Think(); +private: + C_BaseEntity *m_pEntities[MAX_EDICTS]; + int m_nEntityCount; +}; + +CEntitySystem *EntitySystem(); + +#endif diff --git a/game/client/game.cpp b/game/client/game.cpp index 12c0fcd..03770b9 100644 --- a/game/client/game.cpp +++ b/game/client/game.cpp @@ -2,12 +2,17 @@ #include "materialsystem/imaterialsystem.h" #include "enginebridge.h" #include "worldrender.h" +#include "entitysystem.h" +#include "baseentity.h" +#include "game.h" #include "cglm/mat4.h" #include "cglm/cglm.h" IFileSystem *filesystem; IRenderContext *g_pRenderContext; IGameWindow *g_pMainWindow; +static CEngineVars s_vars; +CEngineVars *g_pEngineVars = &s_vars; class CFunnyGameBridge: public IEngineBridge { @@ -16,8 +21,6 @@ class CFunnyGameBridge: public IEngineBridge virtual void Frame( float fDelta ) override; virtual void Shutdown() override; virtual void ConnectInterface( const char *psz, void *pInterface ) override; - IMeshInstance *m_pMeshInstance; - float m_fTime = 0; }; IEngineBridge *EngineBridge() @@ -30,38 +33,9 @@ EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION void CFunnyGameBridge::Init() { - IVertexBuffer *pBuffer; - IBuffer *pDataBuffer; - IShader *pShader; - IMaterial *pMaterial; g_pWorldRenderer->Init(); - pShader = g_pRenderContext->CreateShader("game/core/shaders/mesh_raster.shader_c"); - - IFileHandle *pHandle = filesystem->Open("game/core/meshes/cube.fmesh_c", FILEMODE_READ); - float *pData = (float*)V_malloc(filesystem->Size(pHandle)); - filesystem->Read(pHandle, pData, filesystem->Size(pHandle)); - pBuffer = g_pRenderContext->CreateVertexBuffer(filesystem->Size(pHandle)); - pBuffer->Lock(); - void *pMapped = pBuffer->Map(); - V_memcpy(pMapped, pData, filesystem->Size(pHandle)); - pBuffer->Unmap(); - pBuffer->Unlock(); - V_free(pData); - filesystem->Close(pHandle); - - - IMesh *pMesh = g_pWorldRenderer->CreateMesh("Triangle"); - g_pWorldRenderer->SetCameraPosition((Vector){0,0,-20}); - g_pWorldRenderer->SetCameraRotation((Quat){1,0,0,0}); - - pMesh->ConfigureShader(pShader); - pShader->Build(); - pMaterial = g_pRenderContext->CreateMaterial(pShader); - - pMesh->SetVertices(pBuffer); - pMesh->SetMaterial(pMaterial); - m_pMeshInstance = g_pWorldRenderer->CreateInstance(pMesh); - m_pMeshInstance->SetScale({5, 5, 5}); + C_BaseEntity *pEntity = EntitySystem()->CreateByClassname("player"); + pEntity->Spawn(); } void CFunnyGameBridge::Tick( float fDelta ) @@ -70,11 +44,9 @@ void CFunnyGameBridge::Tick( float fDelta ) void CFunnyGameBridge::Frame( float fDelta ) { - versor q; - m_fTime += fDelta; - glm_euler_zyx_quat((vec3){0,m_fTime, 0}, q); - m_pMeshInstance->SetPosition({sin(m_fTime/3)*10,0,0}); - m_pMeshInstance->SetRotation({q[0], q[1], q[2], q[3]}); + g_pEngineVars->m_fTime += fDelta; + g_pEngineVars->m_fDeltaTime = fDelta; + EntitySystem()->Think(); g_pWorldRenderer->Frame(fDelta); } diff --git a/game/client/milmoba/player.cpp b/game/client/milmoba/player.cpp index f6baee4..81c79af 100644 --- a/game/client/milmoba/player.cpp +++ b/game/client/milmoba/player.cpp @@ -1,21 +1,15 @@ -#include "baseplayer.h" -#include "cglm/affine-pre.h" -#include "cglm/mat4.h" -#include "engine.h" -#include "rendering.h" -#include "input.h" -#include "fgui/widget.h" -#include "fgui/rect.h" -#include "fgui/label.h" -#include "mesh.h" +#include "../baseentity.h" +#include "../worldrender.h" +#include "materialsystem/imaterialsystem.h" +#include "game.h" class C_MOBAPlayer: public C_BaseEntity { public: + DECLARE_CLASS(C_MOBAPlayer, C_BaseEntity) virtual void Precache ( void ) override; virtual void Spawn( void ) override; - virtual void Destroy( void ) override; - virtual void Think( float fDelta ) override; + virtual void Think( float fDelta ); IMesh *m_pMesh; IMeshInstance *m_pMeshInstance; @@ -23,95 +17,56 @@ public: void C_MOBAPlayer::Precache() { + IVertexBuffer *pBuffer; + IBuffer *pDataBuffer; + IShader *pShader; + IMaterial *pMaterial; + g_pWorldRenderer->Init(); + pShader = g_pRenderContext->CreateShader("game/core/shaders/mesh_raster.shader_c"); + + IFileHandle *pHandle = filesystem->Open("game/core/meshes/spot.fmesh_c", FILEMODE_READ); + float *pData = (float*)V_malloc(filesystem->Size(pHandle)); + filesystem->Read(pHandle, pData, filesystem->Size(pHandle)); + pBuffer = g_pRenderContext->CreateVertexBuffer(filesystem->Size(pHandle)); + pBuffer->Lock(); + void *pMapped = pBuffer->Map(); + V_memcpy(pMapped, pData, filesystem->Size(pHandle)); + pBuffer->Unmap(); + pBuffer->Unlock(); + V_free(pData); + filesystem->Close(pHandle); + + + m_pMesh = g_pWorldRenderer->CreateMesh("game/core/meshes/spot.fmesh_c"); + g_pWorldRenderer->SetCameraPosition((Vector){0,0,-20}); + g_pWorldRenderer->SetCameraRotation((Quat){1,0,0,0}); + + m_pMesh->ConfigureShader(pShader); + pShader->Build(); + pMaterial = g_pRenderContext->CreateMaterial(pShader); + + m_pMesh->SetVertices(pBuffer); + m_pMesh->SetMaterial(pMaterial); + m_pMeshInstance = g_pWorldRenderer->CreateInstance(m_pMesh); + m_pMeshInstance->SetScale({5, 5, 5}); + m_pMeshInstance->SetPosition({0,0,0}); + m_pMeshInstance->SetRotation({1,0,0,0}); } + void C_MOBAPlayer::Spawn() { - float cubeVertices[] = { - // Front face - -0.1f, -0.1f, 0.1f, 0, 0, - 0.1f, -0.1f, 0.1f, 1, 0, - 0.1f, 0.1f, 0.1f, 1, 1, - -0.1f, -0.1f, 0.1f, 0, 0, - 0.1f, 0.1f, 0.1f, 1, 1, - -0.1f, 0.1f, 0.1f, 0, 1, - - // Back face - 0.1f, -0.1f, -0.1f, 0, 0, - -0.1f, -0.1f, -0.1f, 1, 0, - -0.1f, 0.1f, -0.1f, 1, 1, - 0.1f, -0.1f, -0.1f, 0, 0, - -0.1f, 0.1f, -0.1f, 1, 1, - 0.1f, 0.1f, -0.1f, 0, 1, - - // Left face - -0.1f, -0.1f, -0.1f, 0, 0, - -0.1f, -0.1f, 0.1f, 1, 0, - -0.1f, 0.1f, 0.1f, 1, 1, - -0.1f, -0.1f, -0.1f, 0, 0, - -0.1f, 0.1f, 0.1f, 1, 1, - -0.1f, 0.1f, -0.1f, 0, 1, - - // Right face - 0.1f, -0.1f, 0.1f, 0, 0, - 0.1f, -0.1f, -0.1f, 1, 0, - 0.1f, 0.1f, -0.1f, 1, 1, - 0.1f, -0.1f, 0.1f, 0, 0, - 0.1f, 0.1f, -0.1f, 1, 1, - 0.1f, 0.1f, 0.1f, 0, 1, - - // Top face - -0.1f, 0.1f, 0.1f, 0, 0, - 0.1f, 0.1f, 0.1f, 1, 0, - 0.1f, 0.1f, -0.1f, 1, 1, - -0.1f, 0.1f, 0.1f, 0, 0, - 0.1f, 0.1f, -0.1f, 1, 1, - -0.1f, 0.1f, -0.1f, 0, 1, - - // Bottom face - -0.1f, -0.1f, -0.1f, 0, 0, - 0.1f, -0.1f, -0.1f, 1, 0, - 0.1f, -0.1f, 0.1f, 1, 1, - -0.1f, -0.1f, -0.1f, 0, 0, - 0.1f, -0.1f, 0.1f, 1, 1, - -0.1f, -0.1f, 0.1f, 0, 1 - }; - - IVertexBuffer *pVertexBuffer = Renderer()->CreateVertexBuffer(sizeof(cubeVertices)); - void *pMapping = pVertexBuffer->Map(); - V_memcpy(pMapping, cubeVertices, sizeof(cubeVertices)); - pVertexBuffer->Unmap(); - - m_pMesh = IMeshRendering::CreateMesh(); - m_pMesh->SetVertexBuffer(0, pVertexBuffer); - m_pMeshInstance = m_pMesh->CreateInstance(); - + Precache(); + SetThink(Think); }; -void C_MOBAPlayer::Destroy() -{ - -} void C_MOBAPlayer::Think( float fDelta ) { - float x = g_fAxisValues[AXIS_MOUSE_X]; - float y = g_fAxisValues[AXIS_MOUSE_Y]; - float fPitch = glm_rad(x); - float fYaw = glm_rad(y); - if (g_localClient->pBasePlayer == pEntity) - { - glm_mat4_identity(g_cameraView); - glm_rotate_z(g_cameraView, fYaw, g_cameraView); - glm_rotate_y(g_cameraView, fPitch, g_cameraView); - g_cameraView[3][0] = pEntity->m_position[0]; - g_cameraView[3][1] = pEntity->m_position[1]; - g_cameraView[3][2] = pEntity->m_position[2]+0.7; - } - mat4 m; - glm_mat4_identity(m); - m_pMeshInstance->SetMatrix(m); - m_pMeshInstance->SetPosition(pEntity->m_position); - m_pMeshInstance->Draw(); + m_pMeshInstance->SetPosition({0,0,-(float)g_pEngineVars->m_fTime}); + versor v; + glm_euler_zxy_quat((vec3){(float)g_pEngineVars->m_fTime,0,0}, v); + m_pMeshInstance->SetRotation({v[0], v[1], v[2], v[3]}); }; -LINK_CLIENT_ENTITY(C_MOBAPlayer, CMOBAPlayer) +LINK_ENTITY_TO_CLASS(player, C_MOBAPlayer) + diff --git a/game/client/modelloader.cpp b/game/client/modelloader.cpp new file mode 100644 index 0000000..e69de29 diff --git a/game/client/modelloader.h b/game/client/modelloader.h new file mode 100644 index 0000000..e69de29 diff --git a/game/client/worldrender.cpp b/game/client/worldrender.cpp index a0c0523..1327318 100644 --- a/game/client/worldrender.cpp +++ b/game/client/worldrender.cpp @@ -56,7 +56,6 @@ void CFunnyMesh::SetVertices( IVertexBuffer *pBuffer ) void CFunnyMesh::SetIndicies( IIndexBuffer *pBuffer, EIndexFormat eIndexFormat ) { - } void CFunnyMesh::SetMaterial( IMaterial *pMaterial ) @@ -180,7 +179,7 @@ void CFunnyWorldRenderer::Frame( float fDelta ) uint32_t uWidth = g_pMainWindow->GetRenderWidth(); uint32_t uHeight = g_pMainWindow->GetRenderHeight(); mat4 matCamera; - glm_perspective(glm_rad(60), uWidth/(float)uHeight, 0.01, 100, matCamera); + glm_perspective(glm_rad(60), uWidth/(float)uHeight, 0.01, 10000, matCamera); glm_translate(matCamera, m_vPos); /* V_printf("%f %f %f %f\n", matCamera[0][0], matCamera[0][1], matCamera[0][2], matCamera[0][3]); diff --git a/game/server/baseentity.h b/game/server/baseentity.h index 92a19a1..373551a 100644 --- a/game/server/baseentity.h +++ b/game/server/baseentity.h @@ -45,7 +45,7 @@ public: class CBaseEntity; -typedef void(*fnThink)( CBaseEntity *pThis ); +typedef void(*fnThink)( float fTime ); class CBaseEntity { public: diff --git a/game/server/build.cpp b/game/server/build.cpp index 79a11ed..736be0a 100644 --- a/game/server/build.cpp +++ b/game/server/build.cpp @@ -20,6 +20,8 @@ DECLARE_BUILD_STAGE(Server) }; compileProject.includeDirectories = { "../../public", + ".", + "../shared", FUNNYSTDLIB"public", EXTERNAL"cglm/include" }; diff --git a/game/server/entitysystem.cpp b/game/server/entitysystem.cpp index 5e704f8..47ce830 100644 --- a/game/server/entitysystem.cpp +++ b/game/server/entitysystem.cpp @@ -115,6 +115,6 @@ void CEntitySystem::Think() if ( !pEntity->m_pfnThink ) continue; - pEntity->m_pfnThink(pEntity); + pEntity->m_pfnThink(0); } } diff --git a/game/server/milmoba/baseentity.cpp b/game/server/milmoba/baseentity.cpp new file mode 100644 index 0000000..abf615b --- /dev/null +++ b/game/server/milmoba/baseentity.cpp @@ -0,0 +1,109 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#include "baseentity.h" +#include "datamap.h" +#include "tier0/lib.h" + +CBaseEntity::~CBaseEntity() +{ + +} + +void CBaseEntity::Spawn() +{ + +} + +void CBaseEntity::SetAbsAngles( float fPitch, float fYaw, float fRoll ) +{ +} + +void CBaseEntity::SetAbsOrigin( Vector origin ) +{ + m_vPosition = origin; +} + +void CBaseEntity::SetScale( float fScale ) +{ + m_vScale.x = fScale; + m_vScale.y = fScale; + m_vScale.z = fScale; +} + + +QAngle CBaseEntity::GetAbsAngles( void ) +{ + +} + +Vector CBaseEntity::GetAbsOrigin( void ) +{ + +} + +float CBaseEntity::GetScale( void ) +{ + +} + +void CBaseEntity::SetThink( fnThink pfnThink ) +{ + m_pfnThink = pfnThink; +} + +void CBaseEntity::SetNextThink( float fThink ) +{ + +} +typedescription_t *CBaseEntity::FindDataByName( const char *szName ) +{ + datamap_t *pDataMap; + int i; + + pDataMap = GetDataMap(); + +lookforname: + for ( i = 0; i < pDataMap->m_iNumFields; i++ ) + { + if (!V_strcmp(pDataMap->m_pData[i].m_szFieldName, szName)) + return &pDataMap->m_pData[i]; + } + pDataMap = pDataMap->m_pBase; + + if (pDataMap) + goto lookforname; + + return NULL; +}; + +typedescription_t *CBaseEntity::FindDataByMapName( const char *szName ) +{ + datamap_t *pDataMap; + int i; + + pDataMap = GetDataMap(); + +lookforname: + for ( i = 0; i < pDataMap->m_iNumFields; i++ ) + { + if (!V_strcmp(pDataMap->m_pData[i].m_szEditorName, szName)) + return &pDataMap->m_pData[i]; + } + pDataMap = pDataMap->m_pBase; + + if (pDataMap) + goto lookforname; + + return NULL; +}; + + +BEGIN_DATADESC_NOBASE(CBaseEntity) + DEFINE_KEYFIELD(m_vPosition, FIELD_VECTOR, "origin") + DEFINE_KEYFIELD(m_vRotation, FIELD_QUATERNION, "angles") + DEFINE_KEYFIELD(m_vScale, FIELD_VECTOR, "scales") +END_DATADESC() diff --git a/game/server/milmoba/baseentity.h b/game/server/milmoba/baseentity.h new file mode 100644 index 0000000..92a19a1 --- /dev/null +++ b/game/server/milmoba/baseentity.h @@ -0,0 +1,79 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#ifndef BASEENTITY_H +#define BASEENTITY_H + +#include "entitysystem.h" +#include "datamap.h" +#include "cglm/cglm.h" +#include "trig.h" + +#define DECLARE_CLASS_NOBASE( className ) \ + typedef className ThisClass; +#define DECLARE_CLASS( className, baseName ) \ + typedef baseName BaseClass; \ + typedef className ThisClass; + +#define LINK_ENTITY_TO_CLASS( mapClassName, DLLClassName) \ + static CEntityFactory g_EntityFactory_##mapClassName( #mapClassName ); + +class CBaseEntity; + +class IEntityFactory +{ +public: + virtual CBaseEntity *Create() = 0; +}; + + +template +class CEntityFactory : public IEntityFactory +{ +public: + CEntityFactory( const char *szClassName ) + { + EntitySystem()->RegisterEntityClass(this, szClassName); + }; + virtual CBaseEntity *Create() { + return new T; + } +}; + + +class CBaseEntity; +typedef void(*fnThink)( CBaseEntity *pThis ); +class CBaseEntity +{ +public: + DECLARE_CLASS_NOBASE(CBaseEntity); + DECLARE_DATADESC_NOBASE() + + typedescription_t *FindDataByName( const char *szName ); + typedescription_t *FindDataByMapName( const char *szName ); + + virtual ~CBaseEntity(); + virtual void Spawn(); + + virtual void SetAbsAngles( float fPitch, float fYaw, float fRoll ); + virtual void SetAbsOrigin( Vector origin ); + virtual void SetScale( float fScale ); + + virtual QAngle GetAbsAngles( void ); + virtual Vector GetAbsOrigin( void ); + virtual float GetScale( void ); + + virtual void SetThink( fnThink pfnThink ); + virtual void SetNextThink( float fThink ); + + fnThink m_pfnThink = NULL; +private: + Vector m_vPosition; + Quat m_vRotation; + Vector m_vScale; +}; + +#endif diff --git a/game/server/milmoba/build.cpp b/game/server/milmoba/build.cpp new file mode 100644 index 0000000..79a11ed --- /dev/null +++ b/game/server/milmoba/build.cpp @@ -0,0 +1,44 @@ +#include "helper.h" +#include "c.h" +#include "ld.h" + +#define EXTERNAL "../../external/" +#define FUNNYSTDLIB EXTERNAL"funnystdlib/" +ADD_DEPENDENCY_BUILD_FILE(tier0, FUNNYSTDLIB"tier0/build.cpp"); +ADD_DEPENDENCY_BUILD_FILE(tier1, FUNNYSTDLIB"tier1/build.cpp"); +ADD_DEPENDENCY_BUILD_FILE(tier2, FUNNYSTDLIB"tier2/build.cpp"); +DECLARE_BUILD_STAGE(Server) +{ + CProject_t compileProject = {}; + LinkProject_t ldProject = {}; + + compileProject.m_szName = "server"; + compileProject.files = { + "game.cpp", + "entitysystem.cpp", + "baseentity.cpp", + }; + compileProject.includeDirectories = { + "../../public", + FUNNYSTDLIB"public", + EXTERNAL"cglm/include" + }; + compileProject.bFPIC = true; + ldProject = ccompiler->Compile(&compileProject); + ldProject.linkType = ELINK_DYNAMIC_LIBRARY; + ldProject.libraryObjects = { + GET_PROJECT_LIBRARY(tier0, "tier0"), + }; + ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier1, "tier1")}); + ldProject.objects.AppendTail({GET_PROJECT_LIBRARY(tier2, "tier2")}); + + if (ldProject.m_target.kernel & TARGET_KERNEL_WINDOWS_DEVICES) + { + ldProject.libraries.AppendTail("pthread"); + }; + + CUtlString outputProject = linker->Link(&ldProject); + ADD_OUTPUT_OBJECT("server", outputProject); + + return 0; +} diff --git a/game/server/milmoba/datamap.h b/game/server/milmoba/datamap.h new file mode 100644 index 0000000..27a1416 --- /dev/null +++ b/game/server/milmoba/datamap.h @@ -0,0 +1,97 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: Valve-styled entity data maps +// +// Note: This file is insipired by Valve's convention in Source SDK, but it +// was written for scratch with compatibility in mind. +// +//===========================================================================// + +#ifndef DATAMAP_H +#define DATAMAP_H +#include "stddef.h" + +enum fieldtype_t { + FIELD_VOID = 0, + FIELD_FLOAT, + FIELD_STRING, + FIELD_VECTOR2D, + FIELD_VECTOR, + FIELD_VECTOR4D, + FIELD_QUATERNION, + FIELD_QUATERNION_QANGLE, + FIELD_COLOR255, + FIELD_COLOR1, + FIELD_INTEGER, + FIELD_BOOLEAN, + + FIELD_MATERIAL, + FIELD_TEXTURE, + FIELD_MODEL, +}; + +struct typedescription_t +{ + const char *m_szFieldName; + const char *m_szEditorName; + fieldtype_t m_eFieldType; + size_t m_iFieldOffset; + unsigned int m_uFieldCount; + unsigned short m_uFieldSize; + unsigned int m_iFlags; +}; + +struct datamap_t +{ + struct datamap_t *m_pBase; + + typedescription_t *m_pData; + int m_iNumFields; +}; + +#define DECLARE_DATADESC() \ + datamap_t *GetBaseMap(); \ + virtual datamap_t *GetDataMap() override; \ + virtual datamap_t DataMapInit() override; + +#define DECLARE_DATADESC_NOBASE() \ + datamap_t *GetBaseMap(); \ + virtual datamap_t *GetDataMap(); \ + virtual datamap_t DataMapInit(); + +#define BEGIN_DATADESC( className ) \ + datamap_t *className::GetBaseMap() { return BaseClass::GetDataMap(); } \ + BEGIN_DATADESC_INTERNAL(className) +#define BEGIN_DATADESC_NOBASE( className ) \ + datamap_t *className::GetBaseMap() { return NULL; } \ + BEGIN_DATADESC_INTERNAL(className) + +#define BEGIN_DATADESC_INTERNAL( className ) \ + datamap_t *className::GetDataMap() { static datamap_t s_DataMap = ThisClass::DataMapInit(); return &s_DataMap; } \ + datamap_t className::DataMapInit() \ + { \ + datamap_t map; \ + map.m_pBase = ThisClass::GetBaseMap(); \ + static typedescription_t dataDesc[] \ + {\ + +#define END_DATADESC() \ + };\ + map.m_iNumFields = sizeof(dataDesc)/sizeof(typedescription_t); \ + map.m_pData = dataDesc; \ + return map; \ + } + +#define IMPLEMENT_NULL_DATADESC( className ) \ + BEGIN_DATADESC(className) \ + END_DATADESC() + +#define _class_offsetof( class, var ) ((size_t)&(((class*)0)->var)) + +#define _FIELD( name, fieldtype, count, flags, mapname, tolerance) { #name, mapname, fieldtype, _class_offsetof(ThisClass, name), count, sizeof(((ThisClass*)0)->name), flags }, +#define DEFINE_KEYFIELD( name, fieldtype, mapname ) _FIELD( name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0) + +#define FTYPEDESC_KEY 0x0004 + + +#endif diff --git a/game/server/milmoba/entitysystem.cpp b/game/server/milmoba/entitysystem.cpp new file mode 100644 index 0000000..5e704f8 --- /dev/null +++ b/game/server/milmoba/entitysystem.cpp @@ -0,0 +1,120 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: +// +//===========================================================================// + +#include "entitysystem.h" +#include "baseentity.h" +#include "stddef.h" +#include "string.h" +#include "stdlib.h" + + +CEntitySystem *EntitySystem() +{ + static CEntitySystem s_entitySystem; + return &s_entitySystem; +} + +static struct EntityRegistry_t +{ + IEntityFactory *m_pFactory; + const char *m_szClassName; + struct EntityRegistry_t *m_pNext; +} *s_pEntitiesRegistry = NULL; + +CEntitySystem::CEntitySystem() +{ + int i = 0; + for ( i = 0; i < MAX_EDICTS; i++ ) + { + m_pEntities[i] = NULL; + } + m_nEntityCount = 0; +} + +void CEntitySystem::RegisterEntityClass( IEntityFactory *pEntityFactory, const char *szClassName ) +{ + IEntityFactory *pFactory; + EntityRegistry_t *pRegistry; + + pFactory = GetFactoryByClassname(szClassName); + + if ( pFactory != NULL ) + { + // Already registered + return; + } + + pRegistry = new EntityRegistry_t; + pRegistry->m_pFactory = pEntityFactory; + pRegistry->m_pNext = s_pEntitiesRegistry; + pRegistry->m_szClassName = szClassName; + s_pEntitiesRegistry = pRegistry; +} + +CBaseEntity *CEntitySystem::CreateByClassname( const char *szName ) +{ + IEntityFactory *pFactory; + CBaseEntity *pEntity; + int i; + int iSelectedSlot; + + pFactory = GetFactoryByClassname(szName); + if ( !pFactory ) + return NULL; + + // We do not want to have more than MAX_EDICT entities + if ( m_nEntityCount >= MAX_EDICTS-1 ) + return NULL; + + // Search for space + // Could be more efficient but nobody cares + for ( i = 0; i < MAX_EDICTS; i++ ) + { + if ( m_pEntities[i] == NULL ) + { + iSelectedSlot = i; + break; + } + } + + pEntity = pFactory->Create(); + m_pEntities[iSelectedSlot] = pEntity; + m_nEntityCount++; + return pEntity; +} + +IEntityFactory *CEntitySystem::GetFactoryByClassname( const char *szName ) +{ + EntityRegistry_t *pEntity; + + for ( pEntity = s_pEntitiesRegistry; pEntity; pEntity = pEntity->m_pNext ) + { + if (!strcmp(szName, pEntity->m_szClassName)) + { + return pEntity->m_pFactory; + } + } + return NULL; +} + + +void CEntitySystem::Think() +{ + CBaseEntity *pEntity; + int i; + + for ( i = 0; i < MAX_EDICTS; i++ ) + { + pEntity = m_pEntities[i]; + if ( pEntity == NULL ) + continue; + + if ( !pEntity->m_pfnThink ) + continue; + + pEntity->m_pfnThink(pEntity); + } +} diff --git a/game/server/milmoba/game.cpp b/game/server/milmoba/game.cpp new file mode 100644 index 0000000..2ea56bd --- /dev/null +++ b/game/server/milmoba/game.cpp @@ -0,0 +1,49 @@ +#include "tier2/ifilesystem.h" +#include "materialsystem/imaterialsystem.h" +#include "enginebridge.h" + +IFileSystem *filesystem; +IRenderContext *g_pRenderContext; +IGameWindow *g_pMainWindow; + +class CFunnyGameBridge: public IEngineBridge +{ + virtual void Init() override; + virtual void Tick( float fDelta ) override; + virtual void Frame( float fDelta ) override; + virtual void Shutdown() override; + virtual void ConnectInterface( const char *psz, void *pInterface ) override; +}; + +IEngineBridge *EngineBridge() +{ + static CFunnyGameBridge s_bridge; + return &s_bridge; +} + +EXPOSE_INTERFACE_FN(EngineBridge, IEngineBridge, ENGINE_BRIDGE_INTERFACE_VERSION) + +void CFunnyGameBridge::Init() +{ +} + +void CFunnyGameBridge::Tick( float fDelta ) +{ + +} + +void CFunnyGameBridge::Frame( float fDelta ) +{ + +} + +void CFunnyGameBridge::Shutdown() +{ + +} + +#define CONNECT_INTERFACE(szName, pGlobal) if (!V_strcmp(psz, szName)) { pGlobal = (typeof(pGlobal))pInterface; return; } +void CFunnyGameBridge::ConnectInterface( const char *psz, void *pInterface ) +{ +} + diff --git a/game/server/scene.cpp b/game/server/milmoba/scene.cpp similarity index 100% rename from game/server/scene.cpp rename to game/server/milmoba/scene.cpp diff --git a/game/server/scene.h b/game/server/milmoba/scene.h similarity index 100% rename from game/server/scene.h rename to game/server/milmoba/scene.h diff --git a/game/shared/datamap.h b/game/shared/datamap.h new file mode 100644 index 0000000..27a1416 --- /dev/null +++ b/game/shared/datamap.h @@ -0,0 +1,97 @@ +//================= Copyright kotofyt, All rights reserved ==================// +// +// Purpose: Valve-styled entity data maps +// +// Note: This file is insipired by Valve's convention in Source SDK, but it +// was written for scratch with compatibility in mind. +// +//===========================================================================// + +#ifndef DATAMAP_H +#define DATAMAP_H +#include "stddef.h" + +enum fieldtype_t { + FIELD_VOID = 0, + FIELD_FLOAT, + FIELD_STRING, + FIELD_VECTOR2D, + FIELD_VECTOR, + FIELD_VECTOR4D, + FIELD_QUATERNION, + FIELD_QUATERNION_QANGLE, + FIELD_COLOR255, + FIELD_COLOR1, + FIELD_INTEGER, + FIELD_BOOLEAN, + + FIELD_MATERIAL, + FIELD_TEXTURE, + FIELD_MODEL, +}; + +struct typedescription_t +{ + const char *m_szFieldName; + const char *m_szEditorName; + fieldtype_t m_eFieldType; + size_t m_iFieldOffset; + unsigned int m_uFieldCount; + unsigned short m_uFieldSize; + unsigned int m_iFlags; +}; + +struct datamap_t +{ + struct datamap_t *m_pBase; + + typedescription_t *m_pData; + int m_iNumFields; +}; + +#define DECLARE_DATADESC() \ + datamap_t *GetBaseMap(); \ + virtual datamap_t *GetDataMap() override; \ + virtual datamap_t DataMapInit() override; + +#define DECLARE_DATADESC_NOBASE() \ + datamap_t *GetBaseMap(); \ + virtual datamap_t *GetDataMap(); \ + virtual datamap_t DataMapInit(); + +#define BEGIN_DATADESC( className ) \ + datamap_t *className::GetBaseMap() { return BaseClass::GetDataMap(); } \ + BEGIN_DATADESC_INTERNAL(className) +#define BEGIN_DATADESC_NOBASE( className ) \ + datamap_t *className::GetBaseMap() { return NULL; } \ + BEGIN_DATADESC_INTERNAL(className) + +#define BEGIN_DATADESC_INTERNAL( className ) \ + datamap_t *className::GetDataMap() { static datamap_t s_DataMap = ThisClass::DataMapInit(); return &s_DataMap; } \ + datamap_t className::DataMapInit() \ + { \ + datamap_t map; \ + map.m_pBase = ThisClass::GetBaseMap(); \ + static typedescription_t dataDesc[] \ + {\ + +#define END_DATADESC() \ + };\ + map.m_iNumFields = sizeof(dataDesc)/sizeof(typedescription_t); \ + map.m_pData = dataDesc; \ + return map; \ + } + +#define IMPLEMENT_NULL_DATADESC( className ) \ + BEGIN_DATADESC(className) \ + END_DATADESC() + +#define _class_offsetof( class, var ) ((size_t)&(((class*)0)->var)) + +#define _FIELD( name, fieldtype, count, flags, mapname, tolerance) { #name, mapname, fieldtype, _class_offsetof(ThisClass, name), count, sizeof(((ThisClass*)0)->name), flags }, +#define DEFINE_KEYFIELD( name, fieldtype, mapname ) _FIELD( name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0) + +#define FTYPEDESC_KEY 0x0004 + + +#endif diff --git a/game/shared/game.h b/game/shared/game.h new file mode 100644 index 0000000..19f2cad --- /dev/null +++ b/game/shared/game.h @@ -0,0 +1,17 @@ +#ifndef GAME_H +#define GAME_H +#include "tier2/ifilesystem.h" +#include "materialsystem/imaterialsystem.h" +extern IRenderContext *g_pRenderContext; +extern IFileSystem *filesystem; +extern IGameWindowManager *g_pWindowManager; + +class CEngineVars +{ +public: + double m_fTime; + double m_fDeltaTime; +}; + +extern CEngineVars *g_pEngineVars; +#endif diff --git a/perf.data b/perf.data deleted file mode 100644 index abd493c..0000000 Binary files a/perf.data and /dev/null differ