Skip to content

Commit

Permalink
Compatible with goldsrc
Browse files Browse the repository at this point in the history
  • Loading branch information
anchurcn committed Mar 30, 2021
1 parent db0a414 commit 03e339d
Show file tree
Hide file tree
Showing 11 changed files with 777 additions and 13 deletions.
24 changes: 24 additions & 0 deletions cl_dll/cdll_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#include "tri.h"
#include "vgui_TeamFortressViewport.h"
#include "../public/interface.h"
#include "physics.h"
#include"phy_corpse.h"

cl_enginefunc_t gEngfuncs;
CHud gHUD;
Expand Down Expand Up @@ -154,6 +156,7 @@ int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion )
}


bool newLevelBegin = false;
/*
==========================
HUD_VidInit
Expand All @@ -170,9 +173,30 @@ int DLLEXPORT HUD_VidInit( void )
gHUD.VidInit();

VGui_Startup();
newLevelBegin = true;

return 1;
}
void CheckLevelChange()
{
if (newLevelBegin)
{
newLevelBegin = false;

const char* pLevelName = gEngfuncs.pfnGetLevelName();
if (pLevelName && pLevelName[0]) {
gPhysics.ChangeLevel(pLevelName);
if (!pgCorpseMgr)
delete pgCorpseMgr;
pgCorpseMgr = new CorpseManager();
}
else
{
gEngfuncs.pfnClientCmd("disconnect\n");
gEngfuncs.Con_Printf("Couldn't get map name from level name!\n");
}
}
}

/*
==========================
Expand Down
20 changes: 20 additions & 0 deletions cl_dll/entity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "Exports.h"

#include "particleman.h"
#include"physics.h"
#include<com_model.h>
extern IParticleMan *g_pParticleMan;

void Game_AddObjects( void );
Expand Down Expand Up @@ -61,6 +63,15 @@ int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *mode

}

if (ent->index && ent->index < 512)
{
// server side brush entity only.(breakables, trains, func_walls...)
if (ent->model->type == modtype_t::mod_brush)
{
gPhysics.AddCollider(ent);
}
}

return 1;
}

Expand Down Expand Up @@ -318,6 +329,12 @@ void DLLEXPORT HUD_CreateEntities( void )
Game_AddObjects();

GetClientVoiceMgr()->CreateEntities();

static float oldtime = 0;
float currentTime = gEngfuncs.GetClientTime();
float delta = currentTime-oldtime;
oldtime = currentTime;
gPhysics.Update(delta);
}

#if defined( _TFC )
Expand Down Expand Up @@ -470,6 +487,9 @@ void DLLEXPORT HUD_TempEntUpdate (
}
if ( !active ) // Kill it
{
if (pTemp->callback && pTemp->flags & FTENT_KILLCALLBACK)
pTemp->callback(pTemp, frametime, client_time);

pTemp->next = *ppTempEntFree;
*ppTempEntFree = pTemp;
if ( !pprev ) // Deleting at head of list
Expand Down
41 changes: 41 additions & 0 deletions cl_dll/gsphysics/phy_corpse.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include<APIProxy.h>
#include<cl_entity.h>
#include<r_efx.h>

// magic num
#define PhyCorpseFlag1 (753951)
#define PhyCorpseFlag2 (152358)

#define MAX_ENTITIES 512


class CorpseManager
{
public:
CorpseManager(void);

// check if the entity is already dead
bool IsEntityDead(cl_entity_t* ent);

// tells the mgr that the entity died just now.
void EntityDie(cl_entity_t* ent);

// if entity plays any sequences other than death sequences,
// we tells the mgr this entity is alive.
void EntityRespawn(cl_entity_t* ent);

// create ragdoll corpse for specified entity
TEMPENTITY* CreateRagdollCorpse(cl_entity_t* ent);

// check if the entity is a ragdoll corpse (temp entity)
bool IsRagdollCorpse(cl_entity_t* ent);

private:
// max server side entity count elements
bool _entityDead[MAX_ENTITIES];
int _corpseIndex = MAX_ENTITIES;
};

extern CorpseManager* pgCorpseMgr;
124 changes: 124 additions & 0 deletions cl_dll/gsphysics/physics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@

#include<physics.h>
#include <metahost.h>
#include<stdio.h>
#include<Windows.h>
//#include <mscoree.h>

#pragma comment(lib, "mscoree.lib")

PhsicsAPI gPhysics;

#ifdef _DEBUG
const wchar_t PhyDllPath[] = L".\\gsphysics\\bin\\GoldsrcPhysics.dll";
#else// _DEBUG
const wchar_t PhyDllPath[] = L".\\gsphysics\\bin\\GoldsrcPhysics.dll";
#endif

//globle CLR handle
ICLRMetaHost* pMetaHost = nullptr;
ICLRMetaHostPolicy* pMetaHostPolicy = nullptr;
ICLRRuntimeHost* pRuntimeHost = nullptr;
ICLRRuntimeInfo* pRuntimeInfo = nullptr;

void ReleaseCLR()
{
if (pRuntimeInfo != nullptr)
{
pRuntimeInfo->Release();
pRuntimeInfo = nullptr;
}

if (pRuntimeHost != nullptr)
{
pRuntimeHost->Release();
pRuntimeHost = nullptr;
}

if (pMetaHost != nullptr)
{
pMetaHost->Release();
pMetaHost = nullptr;
}
}

int InitCLR()
{
if (pRuntimeInfo != nullptr)
return 0;
HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));

if (FAILED(hr)) {
ReleaseCLR();
}

hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pRuntimeHost));
hr = pRuntimeHost->Start();
return (int)hr;
}

int ExitCLR()
{
pRuntimeHost->Stop();//return HRESULT
ReleaseCLR();
return 0;
}

void* GetFunctionPointer(LPWSTR name)
{
void* pfn = NULL;

const int bufsize = 128;
wchar_t buffer[bufsize];//marshal args to [0xXXXX|MethodName] format
swprintf(buffer, bufsize, L"%p|%s", &pfn, name);

DWORD dwRet = 0;
HRESULT hr = pRuntimeHost->ExecuteInDefaultAppDomain(PhyDllPath,
L"UsrSoft.ManagedExport.ManagedExporter",
L"GetFunctionPointer",
buffer,
&dwRet);

if (hr != S_OK)
exit(12345);
if ((DWORD)pfn != dwRet)
exit(54321);

return pfn;
}

//auto generated
extern "C" void InitPhysicsInterface(char* msg)
{
InitCLR();
gPhysics.Set = (void(_stdcall*)(const char* key, const char* value))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Set");
gPhysics.Test = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Test");
gPhysics.InitSystem = (void(_stdcall*)(const char* modFolder, void* pEngineStudioAPI))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.InitSystem");
gPhysics.ChangeLevel = (void(_stdcall*)(const char* mapName))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ChangeLevel");
gPhysics.LevelReset = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.LevelReset");
gPhysics.Update = (void(_stdcall*)(float delta))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Update");
gPhysics.Pause = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Pause");
gPhysics.Resume = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Resume");
gPhysics.ShotDown = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ShotDown");
gPhysics.ShowConfigForm = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ShowConfigForm");
gPhysics.CreateRagdollController = (void(_stdcall*)(int entityId, char* modelName))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.CreateRagdollController");
gPhysics.CreateRagdollControllerIndex = (void(_stdcall*)(int entityId, int index))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.CreateRagdollControllerIndex");
gPhysics.CreateRagdollControllerModel = (void(_stdcall*)(int entityId, void * model))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.CreateRagdollControllerModel");
gPhysics.StartRagdoll = (void(_stdcall*)(int entityId))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.StartRagdoll");
gPhysics.StopRagdoll = (void(_stdcall*)(int entityId))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.StopRagdoll");
gPhysics.SetupBonesPhysically = (void(_stdcall*)(int entityId))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.SetupBonesPhysically");
gPhysics.ChangeOwner = (void(_stdcall*)(int oldEntity, int newEntity))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ChangeOwner");
gPhysics.SetVelocity = (void(_stdcall*)(int entityId, Vector3 * v))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.SetVelocity");
gPhysics.DisposeRagdollController = (void(_stdcall*)(int entityId))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.DisposeRagdollController");
gPhysics.ImpulseBone = (void(_stdcall*)(int entityId, int boneId, Vector3 * force))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ImpulseBone");
gPhysics.ClearRagdoll = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ClearRagdoll");
gPhysics.HeadShootRagdoll = (void(_stdcall*)(int entityId, Vector3 * force))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.HeadShootRagdoll");
gPhysics.Explosion = (void(_stdcall*)(Vector3 * pos, float intensity))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Explosion");
gPhysics.Shoot = (void(_stdcall*)(Vector3 * from, Vector3 * force))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.Shoot");
gPhysics.PickBodyLocal = (void(_stdcall*)(Vector3 from, Vector3 to))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.PickBodyLocal");
gPhysics.ReleaseBodyLocal = (void(_stdcall*)())GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.ReleaseBodyLocal");
gPhysics.MoveBodyLocal = (void(_stdcall*)(Vector3 from, Vector3 to))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.MoveBodyLocal");
gPhysics.SetPose = (void(_stdcall*)(int entityId, float* pBoneWorldTransform))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.SetPose");
gPhysics.AddCollider = (void(_stdcall*)(void*))GetFunctionPointer(L"GoldsrcPhysics.ExportAPIs.PhysicsMain.AddCollider");
}
Loading

0 comments on commit 03e339d

Please sign in to comment.