diff --git a/metamod/include/dlls/enginecallback.h b/metamod/include/dlls/enginecallback.h
index dbe3e71..987ee35 100644
--- a/metamod/include/dlls/enginecallback.h
+++ b/metamod/include/dlls/enginecallback.h
@@ -67,7 +67,7 @@ extern enginefuncs_t g_engfuncs;
#define TRACE_MODEL (*g_engfuncs.pfnTraceModel)
#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector)
#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand)
-#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
+//#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute)
#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand)
#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect)
#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle)
diff --git a/metamod/msvc/metamod.vcxproj b/metamod/msvc/metamod.vcxproj
index 4f541fc..f93cbe2 100644
--- a/metamod/msvc/metamod.vcxproj
+++ b/metamod/msvc/metamod.vcxproj
@@ -48,7 +48,7 @@
$(ProjectName)_mm
- $(ProjectName)_mm
+ $(ProjectName)
@@ -130,6 +130,7 @@
true
Default
precompiled.h
+ false
.\release/metamod.dll
@@ -175,6 +176,7 @@
+
@@ -204,6 +206,7 @@
+
@@ -211,18 +214,16 @@
-
+
-
-
diff --git a/metamod/msvc/metamod.vcxproj.filters b/metamod/msvc/metamod.vcxproj.filters
index 8bb217f..207f621 100644
--- a/metamod/msvc/metamod.vcxproj.filters
+++ b/metamod/msvc/metamod.vcxproj.filters
@@ -83,6 +83,9 @@
Source Files
+
+ Source Files
+
@@ -109,9 +112,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -130,9 +130,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -142,9 +139,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -178,6 +172,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
diff --git a/metamod/src/api_info.cpp b/metamod/src/api_info.cpp
index 96229de..8918ef9 100644
--- a/metamod/src/api_info.cpp
+++ b/metamod/src/api_info.cpp
@@ -1,234 +1,239 @@
#include "precompiled.h"
+#define API_ENTRY(table, name, loglevel) { offsetof(table, pfn##name), #table "::" #name, loglevel }
+#define DLLAPI_ENTRY(name, loglevel) API_ENTRY(DLL_FUNCTIONS, name, loglevel)
+#define NEWAPI_ENTRY(name, loglevel) API_ENTRY(NEW_DLL_FUNCTIONS, name, loglevel)
+#define ENGAPI_ENTRY(name, loglevel) API_ENTRY(enginefuncs_t, name, loglevel)
+
// trace flag, loglevel, name
dllapi_info_t dllapi_info = {
- { mFALSE, 3, "GameDLLInit" }, // pfnGameInit
- { mFALSE, 10, "DispatchSpawn" }, // pfnSpawn
- { mFALSE, 16, "DispatchThink" }, // pfnThink
- { mFALSE, 9, "DispatchUse" }, // pfnUse
- { mFALSE, 11, "DispatchTouch" }, // pfnTouch
- { mFALSE, 9, "DispatchBlocked" }, // pfnBlocked
- { mFALSE, 10, "DispatchKeyValue" }, // pfnKeyValue
- { mFALSE, 9, "DispatchSave" }, // pfnSave
- { mFALSE, 9, "DispatchRestore" }, // pfnRestore
- { mFALSE, 20, "DispatchObjectCollsionBox" }, // pfnSetAbsBox
- { mFALSE, 9, "SaveWriteFields" }, // pfnSaveWriteFields
- { mFALSE, 9, "SaveReadFields" }, // pfnSaveReadFields
- { mFALSE, 9, "SaveGlobalState" }, // pfnSaveGlobalState
- { mFALSE, 9, "RestoreGlobalState" }, // pfnRestoreGlobalState
- { mFALSE, 9, "ResetGlobalState" }, // pfnResetGlobalState
- { mFALSE, 3, "ClientConnect" }, // pfnClientConnect
- { mFALSE, 3, "ClientDisconnect" }, // pfnClientDisconnect
- { mFALSE, 3, "ClientKill" }, // pfnClientKill
- { mFALSE, 3, "ClientPutInServer" }, // pfnClientPutInServer
- { mFALSE, 9, "ClientCommand" }, // pfnClientCommand
- { mFALSE, 11, "ClientUserInfoChanged" }, // pfnClientUserInfoChanged
- { mFALSE, 3, "ServerActivate" }, // pfnServerActivate
- { mFALSE, 3, "ServerDeactivate" }, // pfnServerDeactivate
- { mFALSE, 14, "PlayerPreThink" }, // pfnPlayerPreThink
- { mFALSE, 14, "PlayerPostThink" }, // pfnPlayerPostThink
- { mFALSE, 18, "StartFrame" }, // pfnStartFrame
- { mFALSE, 9, "ParmsNewLevel" }, // pfnParmsNewLevel
- { mFALSE, 9, "ParmsChangeLevel" }, // pfnParmsChangeLevel
- { mFALSE, 9, "GetGameDescription" }, // pfnGetGameDescription
- { mFALSE, 9, "PlayerCustomization" }, // pfnPlayerCustomization
- { mFALSE, 9, "SpectatorConnect" }, // pfnSpectatorConnect
- { mFALSE, 9, "SpectatorDisconnect" }, // pfnSpectatorDisconnect
- { mFALSE, 9, "SpectatorThink" }, // pfnSpectatorThink
- { mFALSE, 3, "Sys_Error" }, // pfnSys_Error
- { mFALSE, 13, "PM_Move" }, // pfnPM_Move
- { mFALSE, 9, "PM_Init" }, // pfnPM_Init
- { mFALSE, 9, "PM_FindTextureType" }, // pfnPM_FindTextureType
- { mFALSE, 12, "SetupVisibility" }, // pfnSetupVisibility
- { mFALSE, 12, "UpdateClientData" }, // pfnUpdateClientData
- { mFALSE, 16, "AddToFullPack" }, // pfnAddToFullPack
- { mFALSE, 9, "CreateBaseline" }, // pfnCreateBaseline
- { mFALSE, 9, "RegisterEncoders" }, // pfnRegisterEncoders
- { mFALSE, 9, "GetWeaponData" }, // pfnGetWeaponData
- { mFALSE, 15, "CmdStart" }, // pfnCmdStart
- { mFALSE, 15, "CmdEnd" }, // pfnCmdEnd
- { mFALSE, 9, "ConnectionlessPacket" }, // pfnConnectionlessPacket
- { mFALSE, 9, "GetHullBounds" }, // pfnGetHullBounds
- { mFALSE, 9, "CreateInstancedBaselines" }, // pfnCreateInstancedBaselines
- { mFALSE, 3, "InconsistentFile" }, // pfnInconsistentFile
- { mFALSE, 20, "AllowLagCompensation" }, // pfnAllowLagCompensation
+ DLLAPI_ENTRY(GameInit, 1), // pfnGameInit
+ DLLAPI_ENTRY(Spawn, 2), // pfnSpawn
+ DLLAPI_ENTRY(Think, 2), // pfnThink
+ DLLAPI_ENTRY(Use, 2), // pfnUse
+ DLLAPI_ENTRY(Touch, 2), // pfnTouch
+ DLLAPI_ENTRY(Blocked, 2), // pfnBlocked
+ DLLAPI_ENTRY(KeyValue, 4), // pfnKeyValue
+ DLLAPI_ENTRY(Save, 4), // pfnSave
+ DLLAPI_ENTRY(Restore, 4), // pfnRestore
+ DLLAPI_ENTRY(SetAbsBox, 2), // pfnSetAbsBox
+ DLLAPI_ENTRY(SaveWriteFields, 4), // pfnSaveWriteFields
+ DLLAPI_ENTRY(SaveReadFields, 4), // pfnSaveReadFields
+ DLLAPI_ENTRY(SaveGlobalState, 4), // pfnSaveGlobalState
+ DLLAPI_ENTRY(RestoreGlobalState, 4), // pfnRestoreGlobalState
+ DLLAPI_ENTRY(ResetGlobalState, 4), // pfnResetGlobalState
+ DLLAPI_ENTRY(ClientConnect, 1), // pfnClientConnect
+ DLLAPI_ENTRY(ClientDisconnect, 1), // pfnClientDisconnect
+ DLLAPI_ENTRY(ClientKill, 2), // pfnClientKill
+ DLLAPI_ENTRY(ClientPutInServer, 1), // pfnClientPutInServer
+ DLLAPI_ENTRY(ClientCommand, 2), // pfnClientCommand
+ DLLAPI_ENTRY(ClientUserInfoChanged, 2), // pfnClientUserInfoChanged
+ DLLAPI_ENTRY(ServerActivate, 1), // pfnServerActivate
+ DLLAPI_ENTRY(ServerDeactivate, 1), // pfnServerDeactivate
+ DLLAPI_ENTRY(PlayerPreThink, 3), // pfnPlayerPreThink
+ DLLAPI_ENTRY(PlayerPostThink, 3), // pfnPlayerPostThink
+ DLLAPI_ENTRY(StartFrame, 4), // pfnStartFrame
+ DLLAPI_ENTRY(ParmsNewLevel, 4), // pfnParmsNewLevel
+ DLLAPI_ENTRY(ParmsChangeLevel, 4), // pfnParmsChangeLevel
+ DLLAPI_ENTRY(GetGameDescription, 3), // pfnGetGameDescription
+ DLLAPI_ENTRY(PlayerCustomization, 4), // pfnPlayerCustomization
+ DLLAPI_ENTRY(SpectatorConnect, 3), // pfnSpectatorConnect
+ DLLAPI_ENTRY(SpectatorDisconnect, 3), // pfnSpectatorDisconnect
+ DLLAPI_ENTRY(SpectatorThink, 3), // pfnSpectatorThink
+ DLLAPI_ENTRY(Sys_Error, 4), // pfnSys_Error
+ DLLAPI_ENTRY(PM_Move, 3), // pfnPM_Move
+ DLLAPI_ENTRY(PM_Init, 1), // pfnPM_Init
+ DLLAPI_ENTRY(PM_FindTextureType, 3), // pfnPM_FindTextureType
+ DLLAPI_ENTRY(SetupVisibility, 3), // pfnSetupVisibility
+ DLLAPI_ENTRY(UpdateClientData, 3), // pfnUpdateClientData
+ DLLAPI_ENTRY(AddToFullPack, 3), // pfnAddToFullPack
+ DLLAPI_ENTRY(CreateBaseline, 4), // pfnCreateBaseline
+ DLLAPI_ENTRY(RegisterEncoders, 4), // pfnRegisterEncoders
+ DLLAPI_ENTRY(GetWeaponData, 3), // pfnGetWeaponData
+ DLLAPI_ENTRY(CmdStart, 3), // pfnCmdStart
+ DLLAPI_ENTRY(CmdEnd, 3), // pfnCmdEnd
+ DLLAPI_ENTRY(ConnectionlessPacket, 4), // pfnConnectionlessPacket
+ DLLAPI_ENTRY(GetHullBounds, 3), // pfnGetHullBounds
+ DLLAPI_ENTRY(CreateInstancedBaselines, 4), // pfnCreateInstancedBaselines
+ DLLAPI_ENTRY(InconsistentFile, 3), // pfnInconsistentFile
+ DLLAPI_ENTRY(AllowLagCompensation, 4), // pfnAllowLagCompensation
- { mFALSE, 0, nullptr },
+ { 0, "", 0 },
};
newapi_info_t newapi_info = {
- { mFALSE, 16, "OnFreeEntPrivateData" }, // pfnOnFreeEntPrivateData
- { mFALSE, 3, "GameShutdown" }, // pfnGameShutdown
- { mFALSE, 14, "ShouldCollide" }, // pfnShouldCollide
- { mFALSE, 3, "CvarValue" }, // pfnCvarValue
- { mFALSE, 3, "CvarValue2" }, // pfnCvarValue2
+ NEWAPI_ENTRY(OnFreeEntPrivateData, 3), // pfnOnFreeEntPrivateData
+ NEWAPI_ENTRY(GameShutdown, 3), // pfnGameShutdown
+ NEWAPI_ENTRY(ShouldCollide, 3), // pfnShouldCollide
+ NEWAPI_ENTRY(CvarValue, 2), // pfnCvarValue
+ NEWAPI_ENTRY(CvarValue2, 2), // pfnCvarValue2
- { mFALSE, 0, nullptr },
+ { 0, "", 0 },
};
engine_info_t engine_info = {
- { mFALSE, 13, "PrecacheModel" }, // pfnPrecacheModel
- { mFALSE, 13, "PrecacheSound" }, // pfnPrecacheSound
- { mFALSE, 18, "SetModel" }, // pfnSetModel
- { mFALSE, 34, "ModelIndex" }, // pfnModelIndex
- { mFALSE, 10, "ModelFrames" }, // pfnModelFrames
- { mFALSE, 14, "SetSize" }, // pfnSetSize
- { mFALSE, 9, "ChangeLevel" }, // pfnChangeLevel
- { mFALSE, 9, "GetSpawnParms" }, // pfnGetSpawnParms
- { mFALSE, 9, "SaveSpawnParms" }, // pfnSaveSpawnParms
- { mFALSE, 9, "VecToYaw" }, // pfnVecToYaw
- { mFALSE, 14, "VecToAngles" }, // pfnVecToAngles
- { mFALSE, 9, "MoveToOrigin" }, // pfnMoveToOrigin
- { mFALSE, 9, "ChangeYaw" }, // pfnChangeYaw
- { mFALSE, 9, "ChangePitch" }, // pfnChangePitch
- { mFALSE, 32, "FindEntityByString" }, // pfnFindEntityByString
- { mFALSE, 9, "GetEntityIllum" }, // pfnGetEntityIllum
- { mFALSE, 9, "FindEntityInSphere" }, // pfnFindEntityInSphere
- { mFALSE, 19, "FindClientInPVS" }, // pfnFindClientInPVS
- { mFALSE, 9, "EntitiesInPVS" }, // pfnEntitiesInPVS
- { mFALSE, 40, "MakeVectors" }, // pfnMakeVectors
- { mFALSE, 9, "AngleVectors" }, // pfnAngleVectors
- { mFALSE, 13, "CreateEntity" }, // pfnCreateEntity
- { mFALSE, 13, "RemoveEntity" }, // pfnRemoveEntity
- { mFALSE, 13, "CreateNamedEntity" }, // pfnCreateNamedEntity
- { mFALSE, 9, "MakeStatic" }, // pfnMakeStatic
- { mFALSE, 9, "EntIsOnFloor" }, // pfnEntIsOnFloor
- { mFALSE, 9, "DropToFloor" }, // pfnDropToFloor
- { mFALSE, 9, "WalkMove" }, // pfnWalkMove
- { mFALSE, 14, "SetOrigin" }, // pfnSetOrigin
- { mFALSE, 12, "EmitSound" }, // pfnEmitSound
- { mFALSE, 12, "EmitAmbientSound" }, // pfnEmitAmbientSound
- { mFALSE, 20, "TraceLine" }, // pfnTraceLine
- { mFALSE, 9, "TraceToss" }, // pfnTraceToss
- { mFALSE, 9, "TraceMonsterHull" }, // pfnTraceMonsterHull
- { mFALSE, 9, "TraceHull" }, // pfnTraceHull
- { mFALSE, 9, "TraceModel" }, // pfnTraceModel
- { mFALSE, 15, "TraceTexture" }, // pfnTraceTexture // CS: when moving
- { mFALSE, 9, "TraceSphere" }, // pfnTraceSphere
- { mFALSE, 9, "GetAimVector" }, // pfnGetAimVector
- { mFALSE, 9, "ServerCommand" }, // pfnServerCommand
- { mFALSE, 9, "ServerExecute" }, // pfnServerExecute
- { mFALSE, 11, "engClientCommand" }, // pfnClientCommand // d'oh, ClientCommand in dllapi too
- { mFALSE, 9, "ParticleEffect" }, // pfnParticleEffect
- { mFALSE, 9, "LightStyle" }, // pfnLightStyle
- { mFALSE, 9, "DecalIndex" }, // pfnDecalIndex
- { mFALSE, 15, "PointContents" }, // pfnPointContents // CS: when moving
- { mFALSE, 22, "MessageBegin" }, // pfnMessageBegin
- { mFALSE, 22, "MessageEnd" }, // pfnMessageEnd
- { mFALSE, 30, "WriteByte" }, // pfnWriteByte
- { mFALSE, 23, "WriteChar" }, // pfnWriteChar
- { mFALSE, 24, "WriteShort" }, // pfnWriteShort
- { mFALSE, 23, "WriteLong" }, // pfnWriteLong
- { mFALSE, 23, "WriteAngle" }, // pfnWriteAngle
- { mFALSE, 23, "WriteCoord" }, // pfnWriteCoord
- { mFALSE, 25, "WriteString" }, // pfnWriteString
- { mFALSE, 23, "WriteEntity" }, // pfnWriteEntity
- { mFALSE, 9, "CVarRegister" }, // pfnCVarRegister
- { mFALSE, 21, "CVarGetFloat" }, // pfnCVarGetFloat
- { mFALSE, 9, "CVarGetString" }, // pfnCVarGetString
- { mFALSE, 10, "CVarSetFloat" }, // pfnCVarSetFloat
- { mFALSE, 9, "CVarSetString" }, // pfnCVarSetString
- { mFALSE, 15, "AlertMessage" }, // pfnAlertMessage
- { mFALSE, 17, "EngineFprintf" }, // pfnEngineFprintf
- { mFALSE, 14, "PvAllocEntPrivateData" }, // pfnPvAllocEntPrivateData
- { mFALSE, 9, "PvEntPrivateData" }, // pfnPvEntPrivateData
- { mFALSE, 9, "FreeEntPrivateData" }, // pfnFreeEntPrivateData
- { mFALSE, 9, "SzFromIndex" }, // pfnSzFromIndex
- { mFALSE, 10, "AllocString" }, // pfnAllocString
- { mFALSE, 9, "GetVarsOfEnt" }, // pfnGetVarsOfEnt
- { mFALSE, 14, "PEntityOfEntOffset" }, // pfnPEntityOfEntOffset
- { mFALSE, 19, "EntOffsetOfPEntity" }, // pfnEntOffsetOfPEntity
- { mFALSE, 14, "IndexOfEdict" }, // pfnIndexOfEdict
- { mFALSE, 17, "PEntityOfEntIndex" }, // pfnPEntityOfEntIndex
- { mFALSE, 9, "FindEntityByVars" }, // pfnFindEntityByVars
- { mFALSE, 14, "GetModelPtr" }, // pfnGetModelPtr
- { mFALSE, 9, "RegUserMsg" }, // pfnRegUserMsg
- { mFALSE, 9, "AnimationAutomove" }, // pfnAnimationAutomove
- { mFALSE, 9, "GetBonePosition" }, // pfnGetBonePosition
- { mFALSE, 9, "FunctionFromName" }, // pfnFunctionFromName
- { mFALSE, 9, "NameForFunction" }, // pfnNameForFunction
- { mFALSE, 9, "ClientPrintf" }, // pfnClientPrintf
- { mFALSE, 9, "ServerPrint" }, // pfnServerPrint
- { mFALSE, 13, "Cmd_Args" }, // pfnCmd_Args
- { mFALSE, 13, "Cmd_Argv" }, // pfnCmd_Argv
- { mFALSE, 13, "Cmd_Argc" }, // pfnCmd_Argc
- { mFALSE, 9, "GetAttachment" }, // pfnGetAttachment
- { mFALSE, 9, "CRC32_Init" }, // pfnCRC32_Init
- { mFALSE, 9, "CRC32_ProcessBuffer" }, // pfnCRC32_ProcessBuffer
- { mFALSE, 9, "CRC32_ProcessByte" }, // pfnCRC32_ProcessByte
- { mFALSE, 9, "CRC32_Final" }, // pfnCRC32_Final
- { mFALSE, 16, "RandomLong" }, // pfnRandomLong
- { mFALSE, 14, "RandomFloat" }, // pfnRandomFloat // CS: when firing
- { mFALSE, 14, "SetView" }, // pfnSetView
- { mFALSE, 9, "Time" }, // pfnTime
- { mFALSE, 9, "CrosshairAngle" }, // pfnCrosshairAngle
- { mFALSE, 10, "LoadFileForMe" }, // pfnLoadFileForMe
- { mFALSE, 10, "FreeFile" }, // pfnFreeFile
- { mFALSE, 9, "EndSection" }, // pfnEndSection
- { mFALSE, 9, "CompareFileTime" }, // pfnCompareFileTime
- { mFALSE, 9, "GetGameDir" }, // pfnGetGameDir
- { mFALSE, 9, "Cvar_RegisterVariable" }, // pfnCvar_RegisterVariable
- { mFALSE, 9, "FadeClientVolume" }, // pfnFadeClientVolume
- { mFALSE, 14, "SetClientMaxspeed" }, // pfnSetClientMaxspeed
- { mFALSE, 9, "CreateFakeClient" }, // pfnCreateFakeClient
- { mFALSE, 9, "RunPlayerMove" }, // pfnRunPlayerMove
- { mFALSE, 9, "NumberOfEntities" }, // pfnNumberOfEntities
- { mFALSE, 17, "GetInfoKeyBuffer" }, // pfnGetInfoKeyBuffer
- { mFALSE, 13, "InfoKeyValue" }, // pfnInfoKeyValue
- { mFALSE, 9, "SetKeyValue" }, // pfnSetKeyValue
- { mFALSE, 12, "SetClientKeyValue" }, // pfnSetClientKeyValue
- { mFALSE, 9, "IsMapValid" }, // pfnIsMapValid
- { mFALSE, 9, "StaticDecal" }, // pfnStaticDecal
- { mFALSE, 9, "PrecacheGeneric" }, // pfnPrecacheGeneric
- { mFALSE, 10, "GetPlayerUserId" }, // pfnGetPlayerUserId
- { mFALSE, 9, "BuildSoundMsg" }, // pfnBuildSoundMsg
- { mFALSE, 9, "IsDedicatedServer" }, // pfnIsDedicatedServer
- { mFALSE, 9, "CVarGetPointer" }, // pfnCVarGetPointer
- { mFALSE, 9, "GetPlayerWONId" }, // pfnGetPlayerWONId
- { mFALSE, 9, "Info_RemoveKey" }, // pfnInfo_RemoveKey
- { mFALSE, 15, "GetPhysicsKeyValue" }, // pfnGetPhysicsKeyValue
- { mFALSE, 14, "SetPhysicsKeyValue" }, // pfnSetPhysicsKeyValue
- { mFALSE, 15, "GetPhysicsInfoString" }, // pfnGetPhysicsInfoString
- { mFALSE, 13, "PrecacheEvent" }, // pfnPrecacheEvent
- { mFALSE, 9, "PlaybackEvent" }, // pfnPlaybackEvent
- { mFALSE, 31, "SetFatPVS" }, // pfnSetFatPVS
- { mFALSE, 31, "SetFatPAS" }, // pfnSetFatPAS
- { mFALSE, 50, "CheckVisibility" }, // pfnCheckVisibility
- { mFALSE, 37, "DeltaSetField" }, // pfnDeltaSetField
- { mFALSE, 38, "DeltaUnsetField" }, // pfnDeltaUnsetField
- { mFALSE, 9, "DeltaAddEncoder" }, // pfnDeltaAddEncoder
- { mFALSE, 45, "GetCurrentPlayer" }, // pfnGetCurrentPlayer
- { mFALSE, 14, "CanSkipPlayer" }, // pfnCanSkipPlayer
- { mFALSE, 9, "DeltaFindField" }, // pfnDeltaFindField
- { mFALSE, 37, "DeltaSetFieldByIndex" }, // pfnDeltaSetFieldByIndex
- { mFALSE, 38, "DeltaUnsetFieldByIndex" }, // pfnDeltaUnsetFieldByIndex
- { mFALSE, 9, "SetGroupMask" }, // pfnSetGroupMask
- { mFALSE, 9, "engCreateInstancedBaseline" }, // pfnCreateInstancedBaseline // d'oh, CreateInstancedBaseline in dllapi too
- { mFALSE, 9, "Cvar_DirectSet" }, // pfnCvar_DirectSet
- { mFALSE, 9, "ForceUnmodified" }, // pfnForceUnmodified
- { mFALSE, 9, "GetPlayerStats" }, // pfnGetPlayerStats
- { mFALSE, 3, "AddServerCommand" }, // pfnAddServerCommand
+ ENGAPI_ENTRY(PrecacheModel, 2), // pfnPrecacheModel
+ ENGAPI_ENTRY(PrecacheSound, 2), // pfnPrecacheSound
+ ENGAPI_ENTRY(SetModel, 2), // pfnSetModel
+ ENGAPI_ENTRY(ModelIndex, 2), // pfnModelIndex
+ ENGAPI_ENTRY(ModelFrames, 3), // pfnModelFrames
+ ENGAPI_ENTRY(SetSize, 2), // pfnSetSize
+ ENGAPI_ENTRY(ChangeLevel, 2), // pfnChangeLevel
+ ENGAPI_ENTRY(GetSpawnParms, 4), // pfnGetSpawnParms
+ ENGAPI_ENTRY(SaveSpawnParms, 4), // pfnSaveSpawnParms
+ ENGAPI_ENTRY(VecToYaw, 3), // pfnVecToYaw
+ ENGAPI_ENTRY(VecToAngles, 3), // pfnVecToAngles
+ ENGAPI_ENTRY(MoveToOrigin, 3), // pfnMoveToOrigin
+ ENGAPI_ENTRY(ChangeYaw, 3), // pfnChangeYaw
+ ENGAPI_ENTRY(ChangePitch, 3), // pfnChangePitch
+ ENGAPI_ENTRY(FindEntityByString, 2), // pfnFindEntityByString
+ ENGAPI_ENTRY(GetEntityIllum, 4), // pfnGetEntityIllum
+ ENGAPI_ENTRY(FindEntityInSphere, 2), // pfnFindEntityInSphere
+ ENGAPI_ENTRY(FindClientInPVS, 2), // pfnFindClientInPVS
+ ENGAPI_ENTRY(EntitiesInPVS, 2), // pfnEntitiesInPVS
+ ENGAPI_ENTRY(MakeVectors, 3), // pfnMakeVectors
+ ENGAPI_ENTRY(AngleVectors, 3), // pfnAngleVectors
+ ENGAPI_ENTRY(CreateEntity, 2), // pfnCreateEntity
+ ENGAPI_ENTRY(RemoveEntity, 2), // pfnRemoveEntity
+ ENGAPI_ENTRY(CreateNamedEntity, 2), // pfnCreateNamedEntity
+ ENGAPI_ENTRY(MakeStatic, 2), // pfnMakeStatic
+ ENGAPI_ENTRY(EntIsOnFloor, 2), // pfnEntIsOnFloor
+ ENGAPI_ENTRY(DropToFloor, 2), // pfnDropToFloor
+ ENGAPI_ENTRY(WalkMove, 2), // pfnWalkMove
+ ENGAPI_ENTRY(SetOrigin, 2), // pfnSetOrigin
+ ENGAPI_ENTRY(EmitSound, 2), // pfnEmitSound
+ ENGAPI_ENTRY(EmitAmbientSound, 2), // pfnEmitAmbientSound
+ ENGAPI_ENTRY(TraceLine, 2), // pfnTraceLine
+ ENGAPI_ENTRY(TraceToss, 2), // pfnTraceToss
+ ENGAPI_ENTRY(TraceMonsterHull, 2), // pfnTraceMonsterHull
+ ENGAPI_ENTRY(TraceHull, 2), // pfnTraceHull
+ ENGAPI_ENTRY(TraceModel, 2), // pfnTraceModel
+ ENGAPI_ENTRY(TraceTexture, 2), // pfnTraceTexture // CS: when moving
+ ENGAPI_ENTRY(TraceSphere, 2), // pfnTraceSphere
+ ENGAPI_ENTRY(GetAimVector, 2), // pfnGetAimVector
+ ENGAPI_ENTRY(ServerCommand, 3), // pfnServerCommand
+ ENGAPI_ENTRY(ServerExecute, 3), // pfnServerExecute
+ ENGAPI_ENTRY(ClientCommand, 3), // pfnClientCommand // d'oh, ClientCommand in dllapi too
+ ENGAPI_ENTRY(ParticleEffect, 4), // pfnParticleEffect
+ ENGAPI_ENTRY(LightStyle, 2), // pfnLightStyle
+ ENGAPI_ENTRY(DecalIndex, 2), // pfnDecalIndex
+ ENGAPI_ENTRY(PointContents, 2), // pfnPointContents // CS: when moving
+ ENGAPI_ENTRY(MessageBegin, 3), // pfnMessageBegin
+ ENGAPI_ENTRY(MessageEnd, 3), // pfnMessageEnd
+ ENGAPI_ENTRY(WriteByte, 3), // pfnWriteByte
+ ENGAPI_ENTRY(WriteChar, 3), // pfnWriteChar
+ ENGAPI_ENTRY(WriteShort, 3), // pfnWriteShort
+ ENGAPI_ENTRY(WriteLong, 3), // pfnWriteLong
+ ENGAPI_ENTRY(WriteAngle, 3), // pfnWriteAngle
+ ENGAPI_ENTRY(WriteCoord, 3), // pfnWriteCoord
+ ENGAPI_ENTRY(WriteString, 3), // pfnWriteString
+ ENGAPI_ENTRY(WriteEntity, 3), // pfnWriteEntity
+ ENGAPI_ENTRY(CVarRegister, 2), // pfnCVarRegister
+ ENGAPI_ENTRY(CVarGetFloat, 2), // pfnCVarGetFloat
+ ENGAPI_ENTRY(CVarGetString, 2), // pfnCVarGetString
+ ENGAPI_ENTRY(CVarSetFloat, 2), // pfnCVarSetFloat
+ ENGAPI_ENTRY(CVarSetString, 2), // pfnCVarSetString
+ ENGAPI_ENTRY(AlertMessage, 3), // pfnAlertMessage
+ ENGAPI_ENTRY(EngineFprintf, 3), // pfnEngineFprintf
+ ENGAPI_ENTRY(PvAllocEntPrivateData, 2), // pfnPvAllocEntPrivateData
+ ENGAPI_ENTRY(PvEntPrivateData, 2), // pfnPvEntPrivateData
+ ENGAPI_ENTRY(FreeEntPrivateData, 2), // pfnFreeEntPrivateData
+ ENGAPI_ENTRY(SzFromIndex, 3), // pfnSzFromIndex
+ ENGAPI_ENTRY(AllocString, 3), // pfnAllocString
+ ENGAPI_ENTRY(GetVarsOfEnt, 2), // pfnGetVarsOfEnt
+ ENGAPI_ENTRY(PEntityOfEntOffset, 3), // pfnPEntityOfEntOffset
+ ENGAPI_ENTRY(EntOffsetOfPEntity, 3), // pfnEntOffsetOfPEntity
+ ENGAPI_ENTRY(IndexOfEdict, 3), // pfnIndexOfEdict
+ ENGAPI_ENTRY(PEntityOfEntIndex, 3), // pfnPEntityOfEntIndex
+ ENGAPI_ENTRY(FindEntityByVars, 3), // pfnFindEntityByVars
+ ENGAPI_ENTRY(GetModelPtr, 3), // pfnGetModelPtr
+ ENGAPI_ENTRY(RegUserMsg, 3), // pfnRegUserMsg
+ ENGAPI_ENTRY(AnimationAutomove, 2), // pfnAnimationAutomove
+ ENGAPI_ENTRY(GetBonePosition, 2), // pfnGetBonePosition
+ ENGAPI_ENTRY(FunctionFromName, 4), // pfnFunctionFromName
+ ENGAPI_ENTRY(NameForFunction, 4), // pfnNameForFunction
+ ENGAPI_ENTRY(ClientPrintf, 3), // pfnClientPrintf
+ ENGAPI_ENTRY(ServerPrint, 3), // pfnServerPrint
+ ENGAPI_ENTRY(Cmd_Args, 3), // pfnCmd_Args
+ ENGAPI_ENTRY(Cmd_Argv, 3), // pfnCmd_Argv
+ ENGAPI_ENTRY(Cmd_Argc, 3), // pfnCmd_Argc
+ ENGAPI_ENTRY(GetAttachment, 2), // pfnGetAttachment
+ ENGAPI_ENTRY(CRC32_Init, 4), // pfnCRC32_Init
+ ENGAPI_ENTRY(CRC32_ProcessBuffer, 4), // pfnCRC32_ProcessBuffer
+ ENGAPI_ENTRY(CRC32_ProcessByte, 4), // pfnCRC32_ProcessByte
+ ENGAPI_ENTRY(CRC32_Final, 4), // pfnCRC32_Final
+ ENGAPI_ENTRY(RandomLong, 3), // pfnRandomLong
+ ENGAPI_ENTRY(RandomFloat, 3), // pfnRandomFloat // CS: when firing
+ ENGAPI_ENTRY(SetView, 2), // pfnSetView
+ ENGAPI_ENTRY(Time, 2), // pfnTime
+ ENGAPI_ENTRY(CrosshairAngle, 2), // pfnCrosshairAngle
+ ENGAPI_ENTRY(LoadFileForMe, 4), // pfnLoadFileForMe
+ ENGAPI_ENTRY(FreeFile, 4), // pfnFreeFile
+ ENGAPI_ENTRY(EndSection, 4), // pfnEndSection
+ ENGAPI_ENTRY(CompareFileTime, 4), // pfnCompareFileTime
+ ENGAPI_ENTRY(GetGameDir, 3), // pfnGetGameDir
+ ENGAPI_ENTRY(Cvar_RegisterVariable, 2), // pfnCvar_RegisterVariable
+ ENGAPI_ENTRY(FadeClientVolume, 2), // pfnFadeClientVolume
+ ENGAPI_ENTRY(SetClientMaxspeed, 3), // pfnSetClientMaxspeed
+ ENGAPI_ENTRY(CreateFakeClient, 2), // pfnCreateFakeClient
+ ENGAPI_ENTRY(RunPlayerMove, 3), // pfnRunPlayerMove
+ ENGAPI_ENTRY(NumberOfEntities, 2), // pfnNumberOfEntities
+ ENGAPI_ENTRY(GetInfoKeyBuffer, 2), // pfnGetInfoKeyBuffer
+ ENGAPI_ENTRY(InfoKeyValue, 2), // pfnInfoKeyValue
+ ENGAPI_ENTRY(SetKeyValue, 2), // pfnSetKeyValue
+ ENGAPI_ENTRY(SetClientKeyValue, 2), // pfnSetClientKeyValue
+ ENGAPI_ENTRY(IsMapValid, 2), // pfnIsMapValid
+ ENGAPI_ENTRY(StaticDecal, 2), // pfnStaticDecal
+ ENGAPI_ENTRY(PrecacheGeneric, 2), // pfnPrecacheGeneric
+ ENGAPI_ENTRY(GetPlayerUserId, 2), // pfnGetPlayerUserId
+ ENGAPI_ENTRY(BuildSoundMsg, 2), // pfnBuildSoundMsg
+ ENGAPI_ENTRY(IsDedicatedServer, 2), // pfnIsDedicatedServer
+ ENGAPI_ENTRY(CVarGetPointer, 3), // pfnCVarGetPointer
+ ENGAPI_ENTRY(GetPlayerWONId, 4), // pfnGetPlayerWONId
+ ENGAPI_ENTRY(Info_RemoveKey, 2), // pfnInfo_RemoveKey
+ ENGAPI_ENTRY(GetPhysicsKeyValue, 2), // pfnGetPhysicsKeyValue
+ ENGAPI_ENTRY(SetPhysicsKeyValue, 2), // pfnSetPhysicsKeyValue
+ ENGAPI_ENTRY(GetPhysicsInfoString, 2), // pfnGetPhysicsInfoString
+ ENGAPI_ENTRY(PrecacheEvent, 2), // pfnPrecacheEvent
+ ENGAPI_ENTRY(PlaybackEvent, 2), // pfnPlaybackEvent
+ ENGAPI_ENTRY(SetFatPVS, 2), // pfnSetFatPVS
+ ENGAPI_ENTRY(SetFatPAS, 2), // pfnSetFatPAS
+ ENGAPI_ENTRY(CheckVisibility, 2), // pfnCheckVisibility
+ ENGAPI_ENTRY(DeltaSetField, 3), // pfnDeltaSetField
+ ENGAPI_ENTRY(DeltaUnsetField, 3), // pfnDeltaUnsetField
+ ENGAPI_ENTRY(DeltaAddEncoder, 3), // pfnDeltaAddEncoder
+ ENGAPI_ENTRY(GetCurrentPlayer, 2), // pfnGetCurrentPlayer
+ ENGAPI_ENTRY(CanSkipPlayer, 2), // pfnCanSkipPlayer
+ ENGAPI_ENTRY(DeltaFindField, 3), // pfnDeltaFindField
+ ENGAPI_ENTRY(DeltaSetFieldByIndex, 3), // pfnDeltaSetFieldByIndex
+ ENGAPI_ENTRY(DeltaUnsetFieldByIndex, 3), // pfnDeltaUnsetFieldByIndex
+ ENGAPI_ENTRY(SetGroupMask, 2), // pfnSetGroupMask
+ ENGAPI_ENTRY(CreateInstancedBaseline, 3), // pfnCreateInstancedBaseline // d'oh, CreateInstancedBaseline in dllapi too
+ ENGAPI_ENTRY(Cvar_DirectSet, 2), // pfnCvar_DirectSet
+ ENGAPI_ENTRY(ForceUnmodified, 2), // pfnForceUnmodified
+ ENGAPI_ENTRY(GetPlayerStats, 2), // pfnGetPlayerStats
+ ENGAPI_ENTRY(AddServerCommand, 2), // pfnAddServerCommand
- { mFALSE, 9, "Voice_GetClientListening" }, // Voice_GetClientListening
- { mFALSE, 9, "Voice_SetClientListening" }, // Voice_SetClientListening
- { mFALSE, 9, "GetPlayerAuthId" }, // pfnGetPlayerAuthId
- { mFALSE, 30, "SequenceGet" }, // pfnSequenceGet
+ ENGAPI_ENTRY(Voice_GetClientListening, 2), // Voice_GetClientListening
+ ENGAPI_ENTRY(Voice_SetClientListening, 2), // Voice_SetClientListening
+ ENGAPI_ENTRY(GetPlayerAuthId, 2), // pfnGetPlayerAuthId
+ ENGAPI_ENTRY(SequenceGet, 2), // pfnSequenceGet
- { mFALSE, 30, "SequencePickSentence" }, // pfnSequencePickSentence
- { mFALSE, 30, "GetFileSize" }, // pfnGetFileSize
- { mFALSE, 30, "GetApproxWavePlayLen" }, // pfnGetApproxWavePlayLen
- { mFALSE, 30, "IsCareerMatch" }, // pfnIsCareerMatch
- { mFALSE, 30, "GetLocalizedStringLength" }, // pfnGetLocalizedStringLength
- { mFALSE, 30, "RegisterTutorMessageShown" }, // pfnRegisterTutorMessageShown
- { mFALSE, 30, "GetTimesTutorMessageShown" }, // pfnGetTimesTutorMessageShown
- { mFALSE, 30, "ProcessTutorMessageDecayBuffer" }, // pfnProcessTutorMessageDecayBuffer
- { mFALSE, 30, "ConstructTutorMessageDecayBuffer" }, // pfnConstructTutorMessageDecayBuffer
- { mFALSE, 9, "ResetTutorMessageDecayData" }, // pfnResetTutorMessageDecayData
+ ENGAPI_ENTRY(SequencePickSentence, 2), // pfnSequencePickSentence
+ ENGAPI_ENTRY(GetFileSize, 4), // pfnGetFileSize
+ ENGAPI_ENTRY(GetApproxWavePlayLen, 4), // pfnGetApproxWavePlayLen
+ ENGAPI_ENTRY(IsCareerMatch, 4), // pfnIsCareerMatch
+ ENGAPI_ENTRY(GetLocalizedStringLength, 4), // pfnGetLocalizedStringLength
+ ENGAPI_ENTRY(RegisterTutorMessageShown, 4), // pfnRegisterTutorMessageShown
+ ENGAPI_ENTRY(GetTimesTutorMessageShown, 4), // pfnGetTimesTutorMessageShown
+ ENGAPI_ENTRY(ProcessTutorMessageDecayBuffer, 4), // pfnProcessTutorMessageDecayBuffer
+ ENGAPI_ENTRY(ConstructTutorMessageDecayBuffer, 4), // pfnConstructTutorMessageDecayBuffer
+ ENGAPI_ENTRY(ResetTutorMessageDecayData, 4), // pfnResetTutorMessageDecayData
- { mFALSE, 3, "QueryClientCvarValue" }, //pfnQueryClientCvarValue
- { mFALSE, 3, "QueryClientCvarValue2" }, //pfnQueryClientCvarValue2
- { mFALSE, 8, "CheckParm" }, //pfnCheckParm
+ ENGAPI_ENTRY(QueryClientCvarValue, 2), //pfnQueryClientCvarValue
+ ENGAPI_ENTRY(QueryClientCvarValue2, 2), //pfnQueryClientCvarValue2
+ ENGAPI_ENTRY(EngCheckParm, 2), //pfnCheckParm
// end
- { mFALSE, 0, NULL },
+ { 0, "", 0 },
};
diff --git a/metamod/src/api_info.h b/metamod/src/api_info.h
index 63ae60f..eda530c 100644
--- a/metamod/src/api_info.h
+++ b/metamod/src/api_info.h
@@ -7,9 +7,9 @@
struct api_info_t
{
- mBOOL trace; // if true, log info about this function
- int loglevel; // level at which to log info about this function
- const char *name; // string representation of function name
+ size_t offset;
+ const char *name;
+ size_t loglevel;
};
// DLL api functions
diff --git a/metamod/src/callback_jit.cpp b/metamod/src/callback_jit.cpp
new file mode 100644
index 0000000..c38c41d
--- /dev/null
+++ b/metamod/src/callback_jit.cpp
@@ -0,0 +1,369 @@
+#include "precompiled.h"
+
+CJit g_jit;
+
+class CUniqueLabel
+{
+public:
+ CUniqueLabel(const char* name) : m_name(name)
+ {
+ m_name += m_unique_index++;
+ }
+
+ operator std::string&()
+ {
+ return m_name;
+ }
+
+private:
+ std::string m_name;
+ static size_t m_unique_index;
+};
+size_t CUniqueLabel::m_unique_index;
+
+class CForwardCallbackJIT : public jitasm::function
+{
+public:
+ CForwardCallbackJIT(jitdata_t *jitdata);
+ void naked_main();
+ void call_func(jitasm::Frontend::Reg32 addr);
+
+private:
+ jitdata_t* m_jitdata;
+
+ enum
+ {
+ mg_mres = 0,
+ mg_prev_mres = 4,
+ mg_status = 8,
+ mg_orig_ret = 12,
+ mg_over_ret = 16,
+ };
+};
+
+CForwardCallbackJIT::CForwardCallbackJIT(jitdata_t* jitdata) : m_jitdata(jitdata)
+{
+}
+
+void CForwardCallbackJIT::naked_main()
+{
+ // prologue
+ push(ebp);
+ mov(ebp, esp);
+ push(ebx);
+
+ enum // stack map
+ {
+ orig_ret = 0,
+ over_ret = 4
+ };
+
+ auto globals = ebx;
+ auto mg_backup = m_jitdata->has_ret ? 8 : 0;
+ auto framesize = mg_backup + sizeof(meta_globals_t);
+
+ if (m_jitdata->has_varargs) {
+ sub(esp, framesize += MAX_STRBUF_LEN);
+
+ // format varargs
+ lea(edx, dword_ptr[ebp + 8 + m_jitdata->args_count * 4]); // varargs ptr
+ lea(eax, dword_ptr[esp + mg_backup + sizeof(meta_globals_t)]); // buf ptr
+ mov(ecx, size_t(vsnprintf));
+
+ push(edx);
+ push(dword_ptr[ebp + 8 + (m_jitdata->args_count - 1) * 4]); // last arg of pfn (format)
+ push(MAX_STRBUF_LEN);
+ push(eax);
+ call(ecx);
+ add(esp, 4 * sizeof(int));
+ }
+ else
+ sub(esp, framesize);
+
+ // setup globals ptr
+ mov(globals, size_t(&g_metaGlobals));
+ movups(xmm0, xmmword_ptr[globals]);
+ mov(eax, dword_ptr[globals + 16]);
+ movups(xmmword_ptr[esp + mg_backup], xmm0);
+ mov(dword_ptr[esp + mg_backup + 16], eax);
+
+ // call metamod's pre hook if present
+ if (m_jitdata->mm_hook && m_jitdata->mm_hook_time == P_PRE) {
+ mov(ecx, m_jitdata->mm_hook);
+ call_func(ecx);
+ }
+
+ // setup meta globals
+ mov(dword_ptr[globals + mg_mres], MRES_UNSET);
+
+ // setup retval pointers
+ if (m_jitdata->has_ret) {
+ lea(eax, dword_ptr[esp + over_ret]);
+ mov(dword_ptr[globals + mg_orig_ret], esp);
+ mov(dword_ptr[globals + mg_over_ret], eax);
+ }
+
+ // call pre
+ for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
+ auto plug = &m_jitdata->plugins[i];
+ size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->table_offset);
+
+ // plugin don't want any hooks from that table
+ if (!fn_table)
+ continue;
+
+ CUniqueLabel go_next_plugin("go_next_plugin");
+
+ // check status and handler set
+ cmp(byte_ptr[size_t(&plug->status)], PL_RUNNING);
+ mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
+ jnz(go_next_plugin);
+ jecxz(go_next_plugin);
+
+ if (hookid++) {
+ mov(eax, dword_ptr[globals + mg_mres]);
+ mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
+ mov(dword_ptr[globals + mg_prev_mres], eax);
+ }
+ else { // init
+ xor_(eax, eax);
+ mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
+ mov(dword_ptr[globals + mg_prev_mres], eax); // MRES_UNSET
+ mov(dword_ptr[globals + mg_status], eax); // NULL
+ }
+
+ call_func(ecx);
+
+ mov(edx, dword_ptr[globals + mg_mres]);
+ mov(ecx, dword_ptr[globals + mg_status]);
+ cmp(edx, ecx);
+ cmovg(ecx, edx);
+ mov(dword_ptr[globals + mg_status], ecx);
+
+ if (m_jitdata->has_ret) {
+ mov(ecx, dword_ptr[esp + over_ret]);
+ cmp(edx, MRES_SUPERCEDE);
+ cmovz(ecx, eax);
+ mov(dword_ptr[esp + over_ret], ecx);
+ }
+
+ L(go_next_plugin);
+ }
+
+ // call original if need
+ cmp(dword_ptr[globals + mg_status], MRES_SUPERCEDE);
+ jz("skip_original");
+ {
+ if (m_jitdata->pfn_original) {
+ mov(ecx, m_jitdata->pfn_original);
+ call_func(ecx);
+ }
+
+ if (m_jitdata->has_ret) {
+ if (m_jitdata->pfn_original)
+ mov(dword_ptr[esp + orig_ret], eax);
+ else
+ mov(dword_ptr[esp + orig_ret], TRUE); // for should collide :/
+
+ jmp("skip_supercede");
+ }
+ }
+ L("skip_original");
+ {
+ if (m_jitdata->has_ret) {
+ // if supercede
+ mov(eax, dword_ptr[esp + over_ret]);
+ mov(dword_ptr[esp + orig_ret], eax);
+
+ L("skip_supercede");
+ }
+ }
+ L("skip_all");
+
+ // call post
+ for (int i = 0, hookid = 0; i < m_jitdata->plugins_count; i++) {
+ auto plug = &m_jitdata->plugins[i];
+ size_t fn_table = *(size_t *)(size_t(plug) + m_jitdata->post_table_offset);
+
+ // plugin don't want any hooks from that table
+ if (!fn_table)
+ continue;
+
+ CUniqueLabel go_next_plugin("go_next_plugin");
+
+ // check status and handler set
+ cmp(byte_ptr[size_t(&plug->status)], PL_RUNNING);
+ mov(ecx, dword_ptr[fn_table + m_jitdata->pfn_offset]);
+ jnz(go_next_plugin);
+ jecxz(go_next_plugin);
+
+ if (hookid++) {
+ mov(eax, dword_ptr[globals + mg_mres]);
+ mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
+ mov(dword_ptr[globals + mg_prev_mres], eax);
+ }
+ else { // init
+ xor_(eax, eax);
+ mov(dword_ptr[globals + mg_mres], MRES_IGNORED);
+ mov(dword_ptr[globals + mg_prev_mres], eax); // MRES_UNSET
+ mov(dword_ptr[globals + mg_status], eax); // NULL
+ }
+
+ call_func(ecx);
+
+ mov(edx, dword_ptr[globals + mg_mres]);
+ mov(ecx, dword_ptr[globals + mg_status]);
+ cmp(ecx, edx);
+ cmovl(ecx, edx);
+ mov(dword_ptr[globals + mg_status], ecx);
+
+ if (m_jitdata->has_ret) {
+ cmp(edx, MRES_SUPERCEDE);
+ mov(ecx, dword_ptr[esp + over_ret]);
+ cmovz(ecx, eax);
+ mov(dword_ptr[esp + over_ret], ecx);
+ }
+
+ L(go_next_plugin);
+ }
+
+ // call metamod's post hook if present
+ if (m_jitdata->mm_hook && m_jitdata->mm_hook_time == P_POST) {
+ mov(ecx, m_jitdata->mm_hook);
+ call_func(ecx);
+ }
+
+ movups(xmm0, xmmword_ptr[esp + mg_backup]);
+ mov(eax, dword_ptr[esp + mg_backup + 16]);
+ movups(xmmword_ptr[globals], xmm0);
+ mov(dword_ptr[globals + 16], eax);
+
+ if (m_jitdata->has_ret) {
+ mov(eax, dword_ptr[esp + orig_ret]);
+ cmp(dword_ptr[globals + mg_status], MRES_OVERRIDE);
+ cmovz(eax, dword_ptr[esp + over_ret]);
+ }
+
+ if (framesize) {
+ add(esp, framesize);
+ }
+
+ // epilogue
+ pop(ebx);
+ pop(ebp);
+ ret();
+}
+
+void CForwardCallbackJIT::call_func(jitasm::Frontend::Reg32 addr)
+{
+ const size_t normal_args_count = m_jitdata->args_count - (m_jitdata->has_varargs ? 1u : 0u);
+ const size_t strbuf_stack_offset = (m_jitdata->has_ret ? 8u : 0u) + sizeof(meta_globals_t);
+
+ // push formatted buf
+ if (m_jitdata->has_varargs) {
+ lea(eax, dword_ptr[esp + strbuf_stack_offset]);
+ push(eax);
+ }
+
+ // push normal args
+ for (size_t j = normal_args_count; j > 0; j--)
+ push(dword_ptr[ebp + 8 + (j - 1) * 4]);
+
+ // call
+ call(addr);
+
+ // pop stack
+ if (m_jitdata->args_count)
+ add(esp, m_jitdata->args_count * 4);
+}
+
+class CSimpleJmp : public jitasm::function
+{
+public:
+ CSimpleJmp(size_t addr/*, size_t hook, size_t hook_time, size_t ret_backup*/);
+ void naked_main();
+
+private:
+ size_t m_addr;
+ /*size_t m_hook;
+ size_t m_hook_time;
+ size_t m_ret_backup;*/
+};
+
+CSimpleJmp::CSimpleJmp(size_t addr/*, size_t hook, size_t hook_time, size_t ret_backup*/) : m_addr(addr)/*, m_hook(hook), m_hook_time(hook_time), m_ret_backup(ret_backup)*/
+{
+}
+
+void CSimpleJmp::naked_main()
+{
+ /*if (m_hook && m_hook_time == P_PRE) {
+ mov(ecx, m_hook);
+ pop(dword_ptr[m_ret_backup]);
+ call(ecx);
+ push(dword_ptr[m_ret_backup]);
+ }*/
+
+ jmp(dword_ptr[m_addr]);
+
+ /*if (m_hook && m_hook_time == P_POST) {
+ mov(ecx, m_hook);
+ pop(dword_ptr[m_ret_backup]);
+ call(ecx);
+ push(dword_ptr[m_ret_backup]);
+ }*/
+}
+
+size_t CJit::compile_callback(jitdata_t* jitdata)
+{
+ if (!is_hook_needed(jitdata)) {
+ return jitdata->pfn_original;
+ }
+
+ CForwardCallbackJIT callback(jitdata);
+ callback.Assemble();
+
+ auto code = callback.GetCode();
+ auto codeSize = callback.GetCodeSize();
+ auto ptr = m_allocator.allocate(codeSize);
+
+ return (size_t)memcpy(ptr, code, codeSize);
+}
+
+size_t CJit::compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/)
+{
+ CSimpleJmp jmp(ptr_to_func/*, hook, hook_time, size_t(m_static_allocator.allocate(sizeof(int)))*/);
+ jmp.Assemble();
+
+ auto code = jmp.GetCode();
+ auto codeSize = jmp.GetCodeSize();
+ auto ptr = m_static_allocator.allocate(codeSize);
+
+ return (size_t)memcpy(ptr, code, codeSize);
+}
+
+void CJit::clear_callbacks()
+{
+ m_allocator.deallocate_all();
+}
+
+bool CJit::is_hook_needed(jitdata_t* jitdata)
+{
+ if (jitdata->mm_hook)
+ return true;
+
+ if (!jitdata->plugins)
+ return false;
+
+ for (int i = 0, hookid = 0; i < jitdata->plugins_count; i++) {
+ auto plug = &jitdata->plugins[i];
+
+ const size_t fn_table = *(size_t *)(size_t(plug) + jitdata->table_offset);
+ const size_t fn_table_post = *(size_t *)(size_t(plug) + jitdata->post_table_offset);
+
+ if (fn_table || fn_table_post) {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/metamod/src/callback_jit.h b/metamod/src/callback_jit.h
new file mode 100644
index 0000000..ebddde8
--- /dev/null
+++ b/metamod/src/callback_jit.h
@@ -0,0 +1,95 @@
+#pragma once
+
+#define CDATA_ENTRY(s, x, p, h) {#x, offsetof(s, x), getArgsCount(decltype(s##::##x)()), !is_void(decltype(s##::##x)()), is_varargs(decltype(s##::##x)()), p, h}
+
+struct jitdata_t
+{
+ size_t pfn_original;
+ uint8 args_count;
+ bool has_ret;
+ bool has_varargs;
+ uint8 mm_hook_time;
+ size_t pfn_offset; // from fn table
+ size_t mm_hook;
+
+ MPlugin* plugins;
+ int plugins_count;
+ size_t table_offset; // from MPlugin
+ size_t post_table_offset; // from MPlugin
+};
+
+struct compile_data_t
+{
+ const char* name;
+ size_t offset;
+ uint8 args_count;
+ bool has_ret;
+ bool has_varargs;
+ uint8 mm_hook_time;
+ size_t mm_hook;
+};
+
+template
+size_t getArgsCount(ret_t (*)(t_args...))
+{
+ return sizeof...(t_args);
+}
+
+template
+size_t getArgsCount(ret_t (*)(t_args..., ...))
+{
+ return sizeof...(t_args);
+}
+
+template
+bool is_void(void (*)(t_args...))
+{
+ return true;
+}
+
+template
+bool is_void(void (*)(t_args..., ...))
+{
+ return true;
+}
+
+template
+bool is_void(ret_t (*)(t_args..., ...))
+{
+ return false;
+}
+
+template
+bool is_void(ret_t (*)(t_args...))
+{
+ return false;
+}
+
+template
+bool is_varargs(ret_t (*)(t_args...))
+{
+ return false;
+}
+
+template
+bool is_varargs(ret_t (*)(t_args..., ...))
+{
+ return true;
+}
+
+class CJit
+{
+public:
+ size_t compile_callback(jitdata_t* jitdata);
+ size_t compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/);
+ void clear_callbacks();
+
+private:
+ static bool is_hook_needed(jitdata_t* jitdata);
+
+private:
+ execmem_allocator m_allocator;
+ execmem_allocator m_static_allocator;
+};
+
+extern CJit g_jit;
diff --git a/metamod/src/commands_meta.cpp b/metamod/src/commands_meta.cpp
index 18b6e20..3712b16 100644
--- a/metamod/src/commands_meta.cpp
+++ b/metamod/src/commands_meta.cpp
@@ -201,7 +201,7 @@ void cmd_meta_refresh()
}
META_LOG("Refreshing the plugins on demand...");
- if (g_plugins->refresh(PT_ANYTIME) != mTRUE)
+ if (g_plugins->refresh(PT_ANYTIME) != true)
{
META_LOG("Refresh failed.");
}
diff --git a/metamod/src/conf_meta.cpp b/metamod/src/conf_meta.cpp
index 0b7b45b..b492472 100644
--- a/metamod/src/conf_meta.cpp
+++ b/metamod/src/conf_meta.cpp
@@ -1,8 +1,6 @@
#include "precompiled.h"
-MConfig::MConfig()
- : list(nullptr), filename(nullptr), debuglevel(0),
- plugins_file(nullptr), exec_cfg(nullptr)
+MConfig::MConfig() : debuglevel(0), plugins_file(nullptr), exec_cfg(nullptr), list(nullptr), filename(nullptr)
{
}
@@ -19,7 +17,7 @@ option_t *MConfig::find(const char* lookup) const
{
for (auto optp = list; optp->name; optp++)
{
- if (!Q_strcmp(optp->name, lookup)) {
+ if (!strcmp(optp->name, lookup)) {
return optp;
}
}
@@ -27,16 +25,16 @@ option_t *MConfig::find(const char* lookup) const
RETURN_ERRNO(NULL, ME_NOTFOUND);
}
-mBOOL MConfig::set(const char* key, const char* value)
+bool MConfig::set(const char* key, const char* value) const
{
option_t* optp = find(key);
if (optp)
return set(optp, value);
- RETURN_ERRNO(mFALSE, ME_NOTFOUND);
+ RETURN_ERRNO(false, ME_NOTFOUND);
}
-mBOOL MConfig::set(option_t* setp, const char* setstr)
+bool MConfig::set(option_t* setp, const char* setstr)
{
char pathbuf[PATH_MAX ];
int* optval = (int *) setp->dest;
@@ -45,7 +43,7 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
// SETOPT_FN optcmd = (SETOPT_FN) setp->dest;
if (!setstr)
- return mTRUE;
+ return true;
switch (setp->type)
{
@@ -53,7 +51,7 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
if (!isdigit(setstr[0]))
{
META_ERROR("option '%s' invalid format '%s'", setp->name, setstr);
- RETURN_ERRNO(mFALSE, ME_FORMAT);
+ RETURN_ERRNO(false, ME_FORMAT);
}
*optval = Q_atoi(setstr);
META_DEBUG(3, ("set config int: %s = %d", setp->name, *optval));
@@ -71,7 +69,7 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
{
META_ERROR("option '%s' invalid format '%s'", setp->name,
setstr);
- RETURN_ERRNO(mFALSE, ME_FORMAT);
+ RETURN_ERRNO(false, ME_FORMAT);
}
META_DEBUG(3, ("set config bool: %s = %s", setp->name, *optval ? "true" : "false"));
break;
@@ -90,13 +88,13 @@ mBOOL MConfig::set(option_t* setp, const char* setstr)
break;
default:
META_ERROR("unrecognized config type '%d'", setp->type);
- RETURN_ERRNO(mFALSE, ME_ARGUMENT);
+ RETURN_ERRNO(false, ME_ARGUMENT);
}
- return mTRUE;
+ return true;
}
-mBOOL MConfig::load(const char* fn)
+bool MConfig::load(const char* fn)
{
FILE* fp;
char loadfile[PATH_MAX ];
@@ -113,7 +111,7 @@ mBOOL MConfig::load(const char* fn)
if (!fp)
{
META_ERROR("unable to open config file '%s': %s", loadfile, strerror(errno));
- RETURN_ERRNO(mFALSE, ME_NOFILE);
+ RETURN_ERRNO(false, ME_NOFILE);
}
META_DEBUG(2, ("Loading from config file: %s", loadfile));
@@ -149,7 +147,7 @@ mBOOL MConfig::load(const char* fn)
filename = Q_strdup(loadfile);
fclose(fp);
- return mTRUE;
+ return true;
}
void MConfig::show() const
diff --git a/metamod/src/conf_meta.h b/metamod/src/conf_meta.h
index e5865c4..3b8d949 100644
--- a/metamod/src/conf_meta.h
+++ b/metamod/src/conf_meta.h
@@ -32,8 +32,8 @@ public:
char *exec_cfg; // ie metaexec.cfg, exec.cfg
void init(option_t *global_options);
- mBOOL load(const char *filename);
- mBOOL set(const char *key, const char *value);
+ bool load(const char *filename);
+ bool set(const char *key, const char *value) const;
void show() const;
private:
@@ -41,7 +41,7 @@ private:
char *filename;
option_t *find(const char *lookup) const;
- static mBOOL set(option_t *setp, const char *value);
+ static bool set(option_t *setp, const char *value);
// Private; to satisfy -Weffc++ "has pointer data members but does
// not override" copy/assignment constructor.
void operator=(const MConfig &src);
diff --git a/metamod/src/dllapi.cpp b/metamod/src/dllapi.cpp
index e41dbf3..f850a78 100644
--- a/metamod/src/dllapi.cpp
+++ b/metamod/src/dllapi.cpp
@@ -1,178 +1,38 @@
#include "precompiled.h"
-// Original DLL routines, functions returning "void".
-#define META_DLLAPI_HANDLE_void(FN_TYPE, pfnName, pfn_args) \
- SETUP_API_CALLS_void(FN_TYPE, pfnName, dllapi_info); \
- CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, dllapi_table); \
- CALL_GAME_API_void(pfnName, pfn_args, dllapi_table); \
- CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, dllapi_post_table);
+#define CDATA_DLL_H(x, p, h) CDATA_ENTRY(DLL_FUNCTIONS, x, p, size_t(h))
+#define CDATA_DLL(x) CDATA_ENTRY(DLL_FUNCTIONS, x, P_PRE, 0u)
+#define CDATA_NEWDLL_H(x, p, h) CDATA_ENTRY(NEW_DLL_FUNCTIONS, x, p, size_t(h))
+#define CDATA_NEWDLL(x) CDATA_ENTRY(NEW_DLL_FUNCTIONS, x, P_PRE, 0u)
-// Original DLL routines, functions returning an actual value.
-#define META_DLLAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \
- SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, dllapi_info); \
- CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, dllapi_table); \
- CALL_GAME_API(pfnName, pfn_args, dllapi_table); \
- CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, dllapi_post_table);
+DLL_FUNCTIONS sFunctionTable;
+DLL_FUNCTIONS sFunctionTable_jit;
+DLL_FUNCTIONS *pHookedDllFunctions = &sFunctionTable;
+NEW_DLL_FUNCTIONS sNewFunctionTable;
+NEW_DLL_FUNCTIONS sNewFunctionTable_jit;
+NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
-
-// The "new" api routines (just 3 right now), functions returning "void".
-#define META_NEWAPI_HANDLE_void(FN_TYPE, pfnName, pfn_args) \
- SETUP_API_CALLS_void(FN_TYPE, pfnName, newapi_info); \
- CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, newapi_table); \
- CALL_GAME_API_void(pfnName, pfn_args, newapi_table); \
- CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, newapi_post_table);
-
-// The "new" api routines (just 3 right now), functions returning an actual value.
-#define META_NEWAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \
- SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, newapi_info); \
- CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, newapi_table); \
- CALL_GAME_API(pfnName, pfn_args, newapi_table); \
- CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, newapi_post_table);
-
-void mm_GameDLLInit(void)
+void mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
{
- META_DLLAPI_HANDLE_void(FN_GAMEINIT, pfnGameInit, ());
- RETURN_API_void();
-}
-
-int mm_DispatchSpawn(edict_t *pent)
-{
- // Success == 0, Failure == -1 ?
- META_DLLAPI_HANDLE(int, 0, FN_DISPATCHSPAWN, pfnSpawn, (pent));
- RETURN_API();
-}
-
-void mm_DispatchThink(edict_t *pent)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHTHINK, pfnThink, (pent));
- RETURN_API_void();
-}
-
-void mm_DispatchUse(edict_t *pentUsed, edict_t *pentOther)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHUSE, pfnUse, (pentUsed, pentOther));
- RETURN_API_void();
-}
-
-void mm_DispatchTouch(edict_t *pentTouched, edict_t *pentOther)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHTOUCH, pfnTouch, (pentTouched, pentOther));
- RETURN_API_void();
-}
-
-void mm_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHBLOCKED, pfnBlocked, (pentBlocked, pentOther));
- RETURN_API_void();
-}
-
-void mm_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHKEYVALUE, pfnKeyValue, (pentKeyvalue, pkvd));
- RETURN_API_void();
-}
-
-void mm_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHSAVE, pfnSave, (pent, pSaveData));
- RETURN_API_void();
-}
-
-int mm_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity)
-{
- // Success == 0, Failure == -1 ?
- META_DLLAPI_HANDLE(int, 0, FN_DISPATCHRESTORE, pfnRestore, (pent, pSaveData, globalEntity));
- RETURN_API();
-}
-
-void mm_DispatchObjectCollsionBox(edict_t *pent)
-{
- META_DLLAPI_HANDLE_void(FN_DISPATCHOBJECTCOLLISIONBOX, pfnSetAbsBox, (pent));
- RETURN_API_void();
-}
-
-void mm_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
-{
- META_DLLAPI_HANDLE_void(FN_SAVEWRITEFIELDS, pfnSaveWriteFields, (pSaveData, pname, pBaseData, pFields, fieldCount));
- RETURN_API_void();
-}
-
-void mm_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount)
-{
- META_DLLAPI_HANDLE_void(FN_SAVEREADFIELDS, pfnSaveReadFields, (pSaveData, pname, pBaseData, pFields, fieldCount));
- RETURN_API_void();
-}
-
-void mm_SaveGlobalState(SAVERESTOREDATA *pSaveData)
-{
- META_DLLAPI_HANDLE_void(FN_SAVEGLOBALSTATE, pfnSaveGlobalState, (pSaveData));
- RETURN_API_void();
-}
-
-void mm_RestoreGlobalState(SAVERESTOREDATA *pSaveData)
-{
- META_DLLAPI_HANDLE_void(FN_RESTOREGLOBALSTATE, pfnRestoreGlobalState, (pSaveData));
- RETURN_API_void();
-}
-
-void mm_ResetGlobalState(void)
-{
- META_DLLAPI_HANDLE_void(FN_RESETGLOBALSTATE, pfnResetGlobalState, ());
- RETURN_API_void();
-}
-
-BOOL mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
-{
- g_Players.clear_player_cvar_query(pEntity);
- META_DLLAPI_HANDLE(BOOL, TRUE, FN_CLIENTCONNECT, pfnClientConnect, (pEntity, pszName, pszAddress, szRejectReason));
- RETURN_API();
+ g_players.clear_player_cvar_query(pEntity);
}
void mm_ClientDisconnect(edict_t *pEntity)
{
- g_Players.clear_player_cvar_query(pEntity);
- META_DLLAPI_HANDLE_void(FN_CLIENTDISCONNECT, pfnClientDisconnect, (pEntity));
- RETURN_API_void();
-}
-
-void mm_ClientKill(edict_t *pEntity)
-{
- META_DLLAPI_HANDLE_void(FN_CLIENTKILL, pfnClientKill, (pEntity));
- RETURN_API_void();
-}
-
-void mm_ClientPutInServer(edict_t *pEntity)
-{
- META_DLLAPI_HANDLE_void(FN_CLIENTPUTINSERVER, pfnClientPutInServer, (pEntity));
- RETURN_API_void();
+ g_players.clear_player_cvar_query(pEntity);
}
void mm_ClientCommand(edict_t *pEntity)
{
- if (!Q_strcmp(CMD_ARGV(0), "meta"))
- {
+ if (!strcmp(CMD_ARGV(0), "meta")) {
client_meta(pEntity);
}
-
- META_DLLAPI_HANDLE_void(FN_CLIENTCOMMAND, pfnClientCommand, (pEntity));
- RETURN_API_void();
-}
-
-void mm_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer)
-{
- META_DLLAPI_HANDLE_void(FN_CLIENTUSERINFOCHANGED, pfnClientUserInfoChanged, (pEntity, infobuffer));
- RETURN_API_void();
-}
-
-void mm_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
-{
- META_DLLAPI_HANDLE_void(FN_SERVERACTIVATE, pfnServerActivate, (pEdictList, edictCount, clientMax));
- RETURN_API_void();
}
void mm_ServerDeactivate(void)
{
- META_DLLAPI_HANDLE_void(FN_SERVERDEACTIVATE, pfnServerDeactivate, ());
+ sFunctionTable_jit.pfnServerDeactivate();
+
// Update loaded plugins. Look for new plugins in inifile, as well as
// any plugins waiting for a changelevel to load.
//
@@ -189,270 +49,84 @@ void mm_ServerDeactivate(void)
g_plugins->refresh(PT_CHANGELEVEL);
g_plugins->unpause_all();
// g_plugins->retry_all(PT_CHANGELEVEL);
- g_Players.clear_all_cvar_queries();
+ g_players.clear_all_cvar_queries();
requestid_counter = 0;
- RETURN_API_void();
}
-void mm_PlayerPreThink(edict_t *pEntity)
+compile_data_t g_dllfunc_cdata[] =
{
- META_DLLAPI_HANDLE_void(FN_PLAYERPRETHINK, pfnPlayerPreThink, (pEntity));
- RETURN_API_void();
-}
+ CDATA_DLL(pfnGameInit), // pfnGameInit() Initialize the game (one-time call after loading of game .dll)
+ CDATA_DLL(pfnSpawn), // pfnSpawn()
+ CDATA_DLL(pfnThink), // pfnThink()
+ CDATA_DLL(pfnUse), // pfnUse()
+ CDATA_DLL(pfnTouch), // pfnTouch()
+ CDATA_DLL(pfnBlocked), // pfnBlocked()
+ CDATA_DLL(pfnKeyValue), // pfnKeyValue()
+ CDATA_DLL(pfnSave), // pfnSave()
+ CDATA_DLL(pfnRestore), // pfnRestore()
+ CDATA_DLL(pfnSetAbsBox), // pfnSetAbsBox()
-void mm_PlayerPostThink(edict_t *pEntity)
-{
- META_DLLAPI_HANDLE_void(FN_PLAYERPOSTTHINK, pfnPlayerPostThink, (pEntity));
- RETURN_API_void();
-}
+ CDATA_DLL(pfnSaveWriteFields), // pfnSaveWriteFields()
+ CDATA_DLL(pfnSaveReadFields), // pfnSaveReadFields()
-void mm_StartFrame(void)
-{
- META_DLLAPI_HANDLE_void(FN_STARTFRAME, pfnStartFrame, ());
- RETURN_API_void();
-}
+ CDATA_DLL(pfnSaveGlobalState), // pfnSaveGlobalState()
+ CDATA_DLL(pfnRestoreGlobalState), // pfnRestoreGlobalState()
+ CDATA_DLL(pfnResetGlobalState), // pfnResetGlobalState()
-void mm_ParmsNewLevel(void)
-{
- META_DLLAPI_HANDLE_void(FN_PARMSNEWLEVEL, pfnParmsNewLevel, ());
- RETURN_API_void();
-}
+ CDATA_DLL_H(pfnClientConnect, P_PRE, mm_ClientConnect), // pfnClientConnect() (wd) Client has connected
+ CDATA_DLL_H(pfnClientDisconnect, P_PRE, mm_ClientDisconnect), // pfnClientDisconnect() (wd) Player has left the game
+ CDATA_DLL(pfnClientKill), // pfnClientKill() (wd) Player has typed "kill"
+ CDATA_DLL(pfnClientPutInServer), // pfnClientPutInServer() (wd) Client is entering the game
+ CDATA_DLL_H(pfnClientCommand, P_PRE, mm_ClientCommand),
+ CDATA_DLL(pfnClientUserInfoChanged), // pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure
+ CDATA_DLL(pfnServerActivate), // pfnServerActivate() (wd) Server is starting a new map
+ CDATA_DLL(pfnServerDeactivate), // pfnServerDeactivate() (wd) Server is leaving the map (shutdown), or changelevel); SDK2
-void mm_ParmsChangeLevel(void)
-{
- META_DLLAPI_HANDLE_void(FN_PARMSCHANGELEVEL, pfnParmsChangeLevel, ());
- RETURN_API_void();
-}
+ CDATA_DLL(pfnPlayerPreThink), // pfnPlayerPreThink()
+ CDATA_DLL(pfnPlayerPostThink), // pfnPlayerPostThink()
-const char *mm_GetGameDescription(void)
-{
- META_DLLAPI_HANDLE(const char *, NULL, FN_GETGAMEDESCRIPTION, pfnGetGameDescription, ());
- RETURN_API();
-}
+ CDATA_DLL(pfnStartFrame), // pfnStartFrame()
+ CDATA_DLL(pfnParmsNewLevel), // pfnParmsNewLevel()
+ CDATA_DLL(pfnParmsChangeLevel), // pfnParmsChangeLevel()
-void mm_PlayerCustomization(edict_t *pEntity, customization_t *pCust)
-{
- META_DLLAPI_HANDLE_void(FN_PLAYERCUSTOMIZATION, pfnPlayerCustomization, (pEntity, pCust));
- RETURN_API_void();
-}
+ CDATA_DLL(pfnGetGameDescription), // pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2"), "Half-Life"
+ CDATA_DLL(pfnPlayerCustomization), // pfnPlayerCustomization() Notifies .dll of new customization for player.
-void mm_SpectatorConnect(edict_t *pEntity)
-{
- META_DLLAPI_HANDLE_void(FN_SPECTATORCONNECT, pfnSpectatorConnect, (pEntity));
- RETURN_API_void();
-}
+ CDATA_DLL(pfnSpectatorConnect), // pfnSpectatorConnect() Called when spectator joins server
+ CDATA_DLL(pfnSpectatorDisconnect), // pfnSpectatorDisconnect() Called when spectator leaves the server
+ CDATA_DLL(pfnSpectatorThink), // pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t)
-void mm_SpectatorDisconnect(edict_t *pEntity)
-{
- META_DLLAPI_HANDLE_void(FN_SPECTATORDISCONNECT, pfnSpectatorDisconnect, (pEntity));
- RETURN_API_void();
-}
+ CDATA_DLL(pfnSys_Error), // pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2
-void mm_SpectatorThink(edict_t *pEntity)
-{
- META_DLLAPI_HANDLE_void(FN_SPECTATORTHINK, pfnSpectatorThink, (pEntity));
- RETURN_API_void();
-}
+ CDATA_DLL(pfnPM_Move), // pfnPM_Move() (wd) SDK2
+ CDATA_DLL(pfnPM_Init), // pfnPM_Init() Server version of player movement initialization; (wd) SDK2
+ CDATA_DLL(pfnPM_FindTextureType), // pfnPM_FindTextureType() (wd) SDK2
-void mm_Sys_Error(const char *error_string)
-{
- META_DLLAPI_HANDLE_void(FN_SYS_ERROR, pfnSys_Error, (error_string));
- RETURN_API_void();
-}
-
-void mm_PM_Move (struct playermove_s *ppmove, int server)
-{
- META_DLLAPI_HANDLE_void(FN_PM_MOVE, pfnPM_Move, (ppmove, server));
- RETURN_API_void();
-}
-
-void mm_PM_Init(struct playermove_s *ppmove)
-{
- META_DLLAPI_HANDLE_void(FN_PM_INIT, pfnPM_Init, (ppmove));
- RETURN_API_void();
-}
-
-char mm_PM_FindTextureType(char *name)
-{
- META_DLLAPI_HANDLE(char, '\0', FN_PM_FINDTEXTURETYPE, pfnPM_FindTextureType, (name));
- RETURN_API();
-}
-
-void mm_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas)
-{
- META_DLLAPI_HANDLE_void(FN_SETUPVISIBILITY, pfnSetupVisibility, (pViewEntity, pClient, pvs, pas));
- RETURN_API_void();
-}
-
-void mm_UpdateClientData (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd)
-{
- META_DLLAPI_HANDLE_void(FN_UPDATECLIENTDATA, pfnUpdateClientData, (ent, sendweapons, cd));
- RETURN_API_void();
-}
-
-int mm_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet)
-{
- META_DLLAPI_HANDLE(int, 0, FN_ADDTOFULLPACK, pfnAddToFullPack, (state, e, ent, host, hostflags, player, pSet));
- RETURN_API();
-}
-
-void mm_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs)
-{
- META_DLLAPI_HANDLE_void(FN_CREATEBASELINE, pfnCreateBaseline, (player, eindex, baseline, entity, playermodelindex, player_mins, player_maxs));
- RETURN_API_void();
-}
-
-void mm_RegisterEncoders(void)
-{
- META_DLLAPI_HANDLE_void(FN_REGISTERENCODERS, pfnRegisterEncoders, ());
- RETURN_API_void();
-}
-
-int mm_GetWeaponData(struct edict_s *player, struct weapon_data_s *info)
-{
- META_DLLAPI_HANDLE(int, 0, FN_GETWEAPONDATA, pfnGetWeaponData, (player, info));
- RETURN_API();
-}
-
-void mm_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed)
-{
- META_DLLAPI_HANDLE_void(FN_CMDSTART, pfnCmdStart, (player, cmd, random_seed));
- RETURN_API_void();
-}
-
-void mm_CmdEnd (const edict_t *player)
-{
- META_DLLAPI_HANDLE_void(FN_CMDEND, pfnCmdEnd, (player));
- RETURN_API_void();
-}
-
-int mm_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size)
-{
- META_DLLAPI_HANDLE(int, 0, FN_CONNECTIONLESSPACKET, pfnConnectionlessPacket, (net_from, args, response_buffer, response_buffer_size));
- RETURN_API();
-}
-
-int mm_GetHullBounds(int hullnumber, float *mins, float *maxs)
-{
- META_DLLAPI_HANDLE(int, 0, FN_GETHULLBOUNDS, pfnGetHullBounds, (hullnumber, mins, maxs));
- RETURN_API();
-}
-
-void mm_CreateInstancedBaselines (void)
-{
- META_DLLAPI_HANDLE_void(FN_CREATEINSTANCEDBASELINES, pfnCreateInstancedBaselines, ());
- RETURN_API_void();
-}
-
-int mm_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message)
-{
- META_DLLAPI_HANDLE(int, 0, FN_INCONSISTENTFILE, pfnInconsistentFile, (player, filename, disconnect_message));
- RETURN_API();
-}
-
-int mm_AllowLagCompensation(void)
-{
- META_DLLAPI_HANDLE(int, 0, FN_ALLOWLAGCOMPENSATION, pfnAllowLagCompensation, ());
- RETURN_API();
-}
-
-void mm_OnFreeEntPrivateData(edict_t *pEnt)
-{
- META_NEWAPI_HANDLE_void(FN_ONFREEENTPRIVATEDATA, pfnOnFreeEntPrivateData, (pEnt));
- RETURN_API_void();
-}
-
-void mm_GameShutdown(void)
-{
- META_NEWAPI_HANDLE_void(FN_GAMESHUTDOWN, pfnGameShutdown, ());
- RETURN_API_void();
-}
-
-int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther)
-{
- META_NEWAPI_HANDLE(int, 1, FN_SHOULDCOLLIDE, pfnShouldCollide, (pentTouched, pentOther));
- RETURN_API();
-}
-
-void mm_CvarValue(const edict_t *pEdict, const char *value)
-{
- g_Players.clear_player_cvar_query(pEdict);
- META_NEWAPI_HANDLE_void(FN_CVARVALUE, pfnCvarValue, (pEdict, value));
- RETURN_API_void();
-}
-
-void mm_CvarValue2(const edict_t *pEdict, int requestID, const char *cvarName, const char *value)
-{
- META_NEWAPI_HANDLE_void(FN_CVARVALUE2, pfnCvarValue2, (pEdict, requestID, cvarName, value));
- RETURN_API_void();
-}
-
-// "(wd)" indicates my comments on the functions
-DLL_FUNCTIONS sFunctionTable =
-{
- mm_GameDLLInit, // pfnGameInit() Initialize the game (one-time call after loading of game .dll)
- mm_DispatchSpawn, // pfnSpawn()
- mm_DispatchThink, // pfnThink()
- mm_DispatchUse, // pfnUse()
- mm_DispatchTouch, // pfnTouch()
- mm_DispatchBlocked, // pfnBlocked()
- mm_DispatchKeyValue, // pfnKeyValue()
- mm_DispatchSave, // pfnSave()
- mm_DispatchRestore, // pfnRestore()
- mm_DispatchObjectCollsionBox, // pfnSetAbsBox()
-
- mm_SaveWriteFields, // pfnSaveWriteFields()
- mm_SaveReadFields, // pfnSaveReadFields()
-
- mm_SaveGlobalState, // pfnSaveGlobalState()
- mm_RestoreGlobalState, // pfnRestoreGlobalState()
- mm_ResetGlobalState, // pfnResetGlobalState()
-
- mm_ClientConnect, // pfnClientConnect() (wd) Client has connected
- mm_ClientDisconnect, // pfnClientDisconnect() (wd) Player has left the game
- mm_ClientKill, // pfnClientKill() (wd) Player has typed "kill"
- mm_ClientPutInServer, // pfnClientPutInServer() (wd) Client is entering the game
- mm_ClientCommand, // pfnClientCommand() (wd) Player has sent a command (typed, or from a bind)
- mm_ClientUserInfoChanged, // pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure
- mm_ServerActivate, // pfnServerActivate() (wd) Server is starting a new map
- mm_ServerDeactivate, // pfnServerDeactivate() (wd) Server is leaving the map (shutdown, or changelevel); SDK2
-
- mm_PlayerPreThink, // pfnPlayerPreThink()
- mm_PlayerPostThink, // pfnPlayerPostThink()
-
- mm_StartFrame, // pfnStartFrame()
- mm_ParmsNewLevel, // pfnParmsNewLevel()
- mm_ParmsChangeLevel, // pfnParmsChangeLevel()
-
- mm_GetGameDescription, // pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2", "Half-Life"
- mm_PlayerCustomization, // pfnPlayerCustomization() Notifies .dll of new customization for player.
-
- mm_SpectatorConnect, // pfnSpectatorConnect() Called when spectator joins server
- mm_SpectatorDisconnect, // pfnSpectatorDisconnect() Called when spectator leaves the server
- mm_SpectatorThink, // pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t)
-
- mm_Sys_Error, // pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2
-
- mm_PM_Move, // pfnPM_Move() (wd) SDK2
- mm_PM_Init, // pfnPM_Init() Server version of player movement initialization; (wd) SDK2
- mm_PM_FindTextureType, // pfnPM_FindTextureType() (wd) SDK2
-
- mm_SetupVisibility, // pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2
- mm_UpdateClientData, // pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2
- mm_AddToFullPack, // pfnAddToFullPack() (wd) SDK2
- mm_CreateBaseline, // pfnCreateBaseline() Tweak entity baseline for network encoding, allows setup of player baselines, too.; (wd) SDK2
- mm_RegisterEncoders, // pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2
- mm_GetWeaponData, // pfnGetWeaponData() (wd) SDK2
- mm_CmdStart, // pfnCmdStart() (wd) SDK2
- mm_CmdEnd, // pfnCmdEnd() (wd) SDK2
- mm_ConnectionlessPacket, // pfnConnectionlessPacket() (wd) SDK2
- mm_GetHullBounds, // pfnGetHullBounds() (wd) SDK2
- mm_CreateInstancedBaselines, // pfnCreateInstancedBaselines() (wd) SDK2
- mm_InconsistentFile, // pfnInconsistentFile() (wd) SDK2
- mm_AllowLagCompensation, // pfnAllowLagCompensation() (wd) SDK2
+ CDATA_DLL(pfnSetupVisibility), // pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2
+ CDATA_DLL(pfnUpdateClientData), // pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2
+ CDATA_DLL(pfnAddToFullPack), // pfnAddToFullPack() (wd) SDK2
+ CDATA_DLL(pfnCreateBaseline), // pfnCreateBaseline() Tweak entity baseline for network encoding), allows setup of player baselines), too.; (wd) SDK2
+ CDATA_DLL(pfnRegisterEncoders), // pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2
+ CDATA_DLL(pfnGetWeaponData), // pfnGetWeaponData() (wd) SDK2
+ CDATA_DLL(pfnCmdStart), // pfnCmdStart() (wd) SDK2
+ CDATA_DLL(pfnCmdEnd), // pfnCmdEnd() (wd) SDK2
+ CDATA_DLL(pfnConnectionlessPacket), // pfnConnectionlessPacket() (wd) SDK2
+ CDATA_DLL(pfnGetHullBounds), // pfnGetHullBounds() (wd) SDK2
+ CDATA_DLL(pfnCreateInstancedBaselines), // pfnCreateInstancedBaselines() (wd) SDK2
+ CDATA_DLL(pfnInconsistentFile), // pfnInconsistentFile() (wd) SDK2
+ CDATA_DLL(pfnAllowLagCompensation), // pfnAllowLagCompensation() (wd) SDK2
};
-DLL_FUNCTIONS *pHookedDllFunctions = &sFunctionTable;
+compile_data_t g_newdllfunc_cdata[] =
+{
+ CDATA_NEWDLL(pfnOnFreeEntPrivateData), // pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor.
+ CDATA_NEWDLL(pfnGameShutdown), // pfnGameShutdown()
+ CDATA_NEWDLL(pfnShouldCollide), // pfnShouldCollide()
+
+ CDATA_NEWDLL(pfnCvarValue), // pfnCvarValue() (fz) Use mm_CvarValue2 instead
+ CDATA_NEWDLL(pfnCvarValue2) // pfnCvarValue2() (fz) When pfnQueryClientCvarValue2() completes it will call
+ // pfnCvarValue2() with the request ID supplied earlier, the name of the cvar requested and the value of that cvar.
+};
// It's not clear what the difference is between GetAPI and GetAPI2; they
// both appear to return the exact same function table.
@@ -477,7 +151,7 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
META_ERROR("GetEntityAPI called with null pFunctionTable");
return FALSE;
}
- else if (interfaceVersion != INTERFACE_VERSION)
+ if (interfaceVersion != INTERFACE_VERSION)
{
META_ERROR("GetEntityAPI version mismatch; requested=%d ours=%d", interfaceVersion, INTERFACE_VERSION);
return FALSE;
@@ -496,7 +170,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
META_ERROR("GetEntityAPI2 called with null pFunctionTable");
return FALSE;
}
- else if (*interfaceVersion != INTERFACE_VERSION)
+ if (*interfaceVersion != INTERFACE_VERSION)
{
META_ERROR("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION);
//! Tell engine what version we had, so it can figure out who is out of date.
@@ -504,33 +178,10 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
return FALSE;
}
- Q_memcpy(pFunctionTable, &sFunctionTable, sizeof(DLL_FUNCTIONS));
+ memcpy(pFunctionTable, &sFunctionTable, sizeof(DLL_FUNCTIONS));
return TRUE;
}
-// I could find _no_ documentation or examples for the intended use of
-// NEW_DLL_FUNCTIONS. I wouldn't have even _known_ about the
-// GetNewDLLFunctions() function except for the reference in Adminmod.. It
-// appears to be new with SDK 2.0.
-//
-// Obviously, it seems to provide additional functions to the engine, but
-// it's unclear why a new table and interface were added, rather than
-// appending new functions to the GetAPI table/interface.
-//
-// Interestingly, it appears to be called by the engine _before_ GetAPI.
-
-meta_new_dll_functions_t sNewFunctionTable (
- &mm_OnFreeEntPrivateData, // pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor.
- &mm_GameShutdown, // pfnGameShutdown()
- &mm_ShouldCollide, // pfnShouldCollide()
-
- &mm_CvarValue, // pfnCvarValue() (fz) Use mm_CvarValue2 instead
- &mm_CvarValue2 // pfnCvarValue2() (fz) When pfnQueryClientCvarValue2() completes it will call
- // pfnCvarValue2() with the request ID supplied earlier, the name of the cvar requested and the value of that cvar.
-);
-
-NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
-
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
META_DEBUG(6, ("called: GetNewDLLFunctions; version=%d", *interfaceVersion));
@@ -547,7 +198,7 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *in
META_ERROR("GetNewDLLFunctions called with null pNewFunctionTable");
return FALSE;
}
- else if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION)
+ if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION)
{
META_ERROR("GetNewDLLFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, NEW_DLL_FUNCTIONS_VERSION);
//! Tell engine what version we had, so it can figure out who is out of date.
@@ -555,6 +206,76 @@ C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *in
return FALSE;
}
- sNewFunctionTable.copy_to(pNewFunctionTable);
+ memcpy(pNewFunctionTable, &sNewFunctionTable, sizeof(NEW_DLL_FUNCTIONS));
return TRUE;
}
+
+void compile_dllfunc_callbacks()
+{
+ jitdata_t jitdata;
+ jitdata.plugins = g_plugins ? g_plugins->plist : nullptr;
+ jitdata.plugins_count = g_plugins ? g_plugins->endlist : 0;
+ jitdata.table_offset = offsetof(MPlugin, dllapi_table);
+ jitdata.post_table_offset = offsetof(MPlugin, dllapi_post_table);
+
+ for (auto& cd : g_dllfunc_cdata) {
+ jitdata.pfn_original = *(size_t *)(size_t(GameDLL.funcs.dllapi_table) + cd.offset);
+ jitdata.args_count = cd.args_count;
+ jitdata.has_ret = cd.has_ret;
+ jitdata.has_varargs = cd.has_varargs;
+ jitdata.pfn_offset = cd.offset;
+ jitdata.mm_hook_time = cd.mm_hook_time;
+ jitdata.mm_hook = cd.mm_hook;
+
+ *(size_t *)(size_t(&sFunctionTable) + cd.offset) = g_jit.compile_callback(&jitdata);
+ }
+}
+
+void compile_newdllfunc_callbacks()
+{
+ jitdata_t jitdata;
+ jitdata.plugins = g_plugins ? g_plugins->plist : nullptr;
+ jitdata.plugins_count = g_plugins ? g_plugins->endlist : 0;
+ jitdata.table_offset = offsetof(MPlugin, newapi_table);
+ jitdata.post_table_offset = offsetof(MPlugin, newapi_post_table);
+
+ for (auto& cd : g_newdllfunc_cdata) {
+ jitdata.pfn_original = *(size_t *)(size_t(GameDLL.funcs.newapi_table) + cd.offset);
+ jitdata.args_count = cd.args_count;
+ jitdata.has_ret = cd.has_ret;
+ jitdata.has_varargs = cd.has_varargs;
+ jitdata.pfn_offset = cd.offset;
+ jitdata.mm_hook_time = cd.mm_hook_time;
+ jitdata.mm_hook = cd.mm_hook;
+
+ *(size_t *)(size_t(&sNewFunctionTable) + cd.offset) = g_jit.compile_callback(&jitdata);
+ }
+}
+
+void compile_gamedll_tramps()
+{
+ // we compile simple static functions that will call dynamic callbacks
+ for (auto& cd : g_dllfunc_cdata) {
+ *(size_t *)(size_t(&sFunctionTable) + cd.offset) = g_jit.compile_tramp(size_t(&sFunctionTable_jit) + cd.offset);
+ }
+
+ // use direct hook
+ sFunctionTable.pfnServerDeactivate = mm_ServerDeactivate;
+
+ for (auto& cd : g_newdllfunc_cdata) {
+ *(size_t *)(size_t(&sNewFunctionTable) + cd.offset) = g_jit.compile_tramp(size_t(&sNewFunctionTable_jit) + cd.offset);
+ }
+}
+
+void compile_gamedll_callbacks()
+{
+ static bool initialized = false;
+
+ if (!initialized) {
+ compile_gamedll_tramps();
+ initialized = true;
+ }
+
+ compile_dllfunc_callbacks();
+ compile_newdllfunc_callbacks();
+}
diff --git a/metamod/src/dllapi.h b/metamod/src/dllapi.h
index 567523f..6a75e14 100644
--- a/metamod/src/dllapi.h
+++ b/metamod/src/dllapi.h
@@ -3,6 +3,8 @@
#include "sdk_util.h"
#include "osdep.h"
+typedef void (*FN_GAMEINIT)();
+
// Typedefs for these are provided in SDK engine/eiface.h, but I didn't
// like the names (APIFUNCTION, APIFUNCTION2, NEW_DLL_FUNCTIONS_FN).
typedef int (*GETENTITYAPI_FN)(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion);
@@ -13,114 +15,4 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion);
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion);
-extern void mm_GameDLLInit();
-extern int mm_DispatchSpawn(edict_t *pent);
-extern void mm_DispatchThink(edict_t *pent);
-extern void mm_DispatchUse(edict_t *pentUsed, edict_t *pentOther);
-extern void mm_DispatchTouch(edict_t *pentTouched, edict_t *pentOther);
-extern void mm_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther);
-extern void mm_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd);
-extern void mm_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData);
-extern int mm_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
-extern void mm_DispatchObjectCollisionBox(edict_t *pent);
-extern void mm_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
-extern void mm_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
-extern void mm_SaveGlobalState(SAVERESTOREDATA *pSaveData);
-extern void mm_RestoreGlobalState(SAVERESTOREDATA *pSaveData);
-extern void mm_ResetGlobalState();
-extern BOOL mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]);
-extern void mm_ClientDisconnect(edict_t *pEntity);
-extern void mm_ClientKill(edict_t *pEntity);
-extern void mm_ClientPutInServer(edict_t *pEntity);
-extern void mm_ClientCommand(edict_t *pEntity);
-extern void mm_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer);
-extern void mm_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
-extern void mm_ServerDeactivate();
-extern void mm_PlayerPreThink(edict_t *pEntity);
-extern void mm_PlayerPostThink(edict_t *pEntity);
-extern void mm_StartFrame();
-extern void mm_ParmsNewLevel();
-extern void mm_ParmsChangeLevel();
-extern const char *mm_GetGameDescription();
-extern void mm_PlayerCustomization(edict_t *pEntity, customization_t *pCust);
-extern void mm_SpectatorConnect (edict_t *pEntity);
-extern void mm_SpectatorDisconnect (edict_t *pEntity);
-extern void mm_SpectatorThink (edict_t *pEntity);
-extern void mm_Sys_Error(const char *error_string);
-extern void mm_PM_Move(struct playermove_s *ppmove, int server);
-extern void mm_PM_Init(struct playermove_s *ppmove);
-extern char mm_PM_FindTextureType (const char *name);
-extern void mm_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas);
-extern void mm_UpdateClientData (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
-extern int mm_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet);
-extern void mm_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs);
-extern void mm_RegisterEncoders();
-extern int mm_GetWeaponData(struct edict_s *player, struct weapon_data_s *info);
-extern void mm_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed);
-extern void mm_CmdEnd (const edict_t *player);
-extern int mm_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size);
-extern int mm_GetHullBounds(int hullnumber, float *mins, float *maxs);
-extern void mm_CreateInstancedBaselines ();
-extern int mm_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message);
-extern int mm_AllowLagCompensation();
-extern void mm_OnFreeEntPrivateData(edict_t pEnt);
-extern void mm_GameShutdown();
-extern int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther);
-extern void mm_CvarValue(const edict_t *pEnt, const char *value);
-extern void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
-
-typedef void (*FN_GAMEINIT)();
-typedef int (*FN_DISPATCHSPAWN)(edict_t *pent);
-typedef void (*FN_DISPATCHTHINK)(edict_t *pent);
-typedef void (*FN_DISPATCHUSE)(edict_t *pentUsed, edict_t *pentOther);
-typedef void (*FN_DISPATCHTOUCH)(edict_t *pentTouched, edict_t *pentOther);
-typedef void (*FN_DISPATCHBLOCKED)(edict_t *pentBlocked, edict_t *pentOther);
-typedef void (*FN_DISPATCHKEYVALUE)(edict_t *pentKeyvalue, KeyValueData *pkvd);
-typedef void (*FN_DISPATCHSAVE)(edict_t *pent, SAVERESTOREDATA *pSaveData);
-typedef int (*FN_DISPATCHRESTORE)(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity);
-typedef void (*FN_DISPATCHOBJECTCOLLISIONBOX)(edict_t *pent);
-typedef void (*FN_SAVEWRITEFIELDS)(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
-typedef void (*FN_SAVEREADFIELDS)(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount);
-typedef void (*FN_SAVEGLOBALSTATE)(SAVERESTOREDATA *pSaveData);
-typedef void (*FN_RESTOREGLOBALSTATE)(SAVERESTOREDATA *pSaveData);
-typedef void (*FN_RESETGLOBALSTATE)();
-typedef BOOL (*FN_CLIENTCONNECT)(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ]);
-typedef void (*FN_CLIENTDISCONNECT)(edict_t *pEntity);
-typedef void (*FN_CLIENTKILL)(edict_t *pEntity);
-typedef void (*FN_CLIENTPUTINSERVER)(edict_t *pEntity);
-typedef void (*FN_CLIENTCOMMAND)(edict_t *pEntity);
-typedef void (*FN_CLIENTUSERINFOCHANGED)(edict_t *pEntity, char *infobuffer);
-typedef void (*FN_SERVERACTIVATE)(edict_t *pEdictList, int edictCount, int clientMax);
-typedef void (*FN_SERVERDEACTIVATE)();
-typedef void (*FN_PLAYERPRETHINK)(edict_t *pEntity);
-typedef void (*FN_PLAYERPOSTTHINK)(edict_t *pEntity);
-typedef void (*FN_STARTFRAME)();
-typedef void (*FN_PARMSNEWLEVEL)();
-typedef void (*FN_PARMSCHANGELEVEL)();
-typedef const char *(*FN_GETGAMEDESCRIPTION)();
-typedef void (*FN_PLAYERCUSTOMIZATION)(edict_t *pEntity, customization_t *pCust);
-typedef void (*FN_SPECTATORCONNECT) (edict_t *pEntity);
-typedef void (*FN_SPECTATORDISCONNECT) (edict_t *pEntity);
-typedef void (*FN_SPECTATORTHINK) (edict_t *pEntity);
-typedef void (*FN_SYS_ERROR)(const char *error_string);
-typedef void (*FN_PM_MOVE)(struct playermove_s *ppmove, int server);
-typedef void (*FN_PM_INIT)(struct playermove_s *ppmove);
-typedef char (*FN_PM_FINDTEXTURETYPE)(char *name);
-typedef void (*FN_SETUPVISIBILITY)(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas);
-typedef void (*FN_UPDATECLIENTDATA) (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd);
-typedef int (*FN_ADDTOFULLPACK)(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet);
-typedef void (*FN_CREATEBASELINE)(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs);
-typedef void (*FN_REGISTERENCODERS)();
-typedef int (*FN_GETWEAPONDATA)(struct edict_s *player, struct weapon_data_s *info);
-typedef void (*FN_CMDSTART)(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed);
-typedef void (*FN_CMDEND) (const edict_t *player);
-typedef int (*FN_CONNECTIONLESSPACKET)(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size);
-typedef int (*FN_GETHULLBOUNDS)(int hullnumber, float *mins, float *maxs);
-typedef void (*FN_CREATEINSTANCEDBASELINES) ();
-typedef int (*FN_INCONSISTENTFILE)(const edict_t *player, const char *filename, char *disconnect_message);
-typedef int (*FN_ALLOWLAGCOMPENSATION)();
-typedef void (*FN_ONFREEENTPRIVATEDATA)(edict_t *pEnt);
-typedef void (*FN_GAMESHUTDOWN)();
-typedef int (*FN_SHOULDCOLLIDE)(edict_t *pentTouched, edict_t *pentOther);
-typedef void (*FN_CVARVALUE)(const edict_t *pEnt, const char *value); //! Obsolete! Use FN_CVARVALUE2 instead
-typedef void (*FN_CVARVALUE2)(const edict_t *pEnt, int requestID, const char *cvarName, const char *value);
+void compile_gamedll_callbacks();
diff --git a/metamod/src/engine_api.cpp b/metamod/src/engine_api.cpp
index 7f3bd5c..702a26d 100644
--- a/metamod/src/engine_api.cpp
+++ b/metamod/src/engine_api.cpp
@@ -1,552 +1,26 @@
#include "precompiled.h"
-// g_engine routines, functions returning "void".
-#define META_ENGINE_HANDLE_void(FN_TYPE, pfnName, pfn_args) \
- SETUP_API_CALLS_void(FN_TYPE, pfnName, engine_info); \
- CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, engine_table); \
- CALL_ENGINE_API_void(pfnName, pfn_args); \
- CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, engine_post_table);
+#define CDATA_ENG_H(x, p, h) CDATA_ENTRY(enginefuncs_t, x, p, size_t(h))
+#define CDATA_ENG(x) CDATA_ENTRY(enginefuncs_t, x, P_PRE, 0u)
-// g_engine routines, functions returning an actual value.
-#define META_ENGINE_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \
- SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, engine_info); \
- CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, engine_table); \
- CALL_ENGINE_API(pfnName, pfn_args); \
- CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, engine_post_table);
+meta_enginefuncs_t meta_engfuncs; // static addresses for gamedll
+meta_enginefuncs_t meta_engfuncs_jit; // dynamic jit callbacks
-
-// g_engine routines, printf-style functions returning "void".
-#define META_ENGINE_HANDLE_void_varargs(FN_TYPE, pfnName, pfn_arg, fmt_arg) \
- SETUP_API_CALLS_void(FN_TYPE, pfnName, engine_info); \
- char buf[MAX_STRBUF_LEN]; \
- va_list ap; \
- META_DEBUG(loglevel, ("In %s: fmt=%s", pfn_string, fmt_arg)); \
- va_start(ap, fmt_arg); \
- Q_vsnprintf(buf, sizeof(buf), fmt_arg, ap); \
- va_end(ap); \
- CALL_PLUGIN_API_void(P_PRE, pfnName, (pfn_arg, "%s", buf), engine_table); \
- CALL_ENGINE_API_void(pfnName, (pfn_arg, "%s", buf)); \
- CALL_PLUGIN_API_void(P_POST, pfnName, (pfn_arg, "%s", buf), engine_post_table);
-
-// g_engine routines, printf-style functions returning an actual value.
-#define META_ENGINE_HANDLE_varargs(ret_t, ret_init, FN_TYPE, pfnName, pfn_arg, fmt_arg) \
- SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, engine_info); \
- char buf[MAX_STRBUF_LEN]; \
- va_list ap; \
- META_DEBUG(loglevel, ("In %s: fmt=%s", pfn_string, fmt_arg)); \
- va_start(ap, fmt_arg); \
- Q_vsnprintf(buf, sizeof(buf), fmt_arg, ap); \
- va_end(ap); \
- CALL_PLUGIN_API(P_PRE, ret_init, pfnName, (pfn_arg, "%s", buf), MRES_SUPERCEDE, engine_table); \
- CALL_ENGINE_API(pfnName, (pfn_arg, "%s", buf)); \
- CALL_PLUGIN_API(P_POST, ret_init, pfnName, (pfn_arg, "%s", buf), MRES_OVERRIDE, engine_post_table);
-
-int mm_PrecacheModel(const char *s)
-{
- META_ENGINE_HANDLE(int, 0, FN_PRECACHEMODEL, pfnPrecacheModel, (s));
- RETURN_API()
-}
-
-int mm_PrecacheSound(const char *s)
-{
- META_ENGINE_HANDLE(int, 0, FN_PRECACHESOUND, pfnPrecacheSound, (s));
- RETURN_API()
-}
-
-void mm_SetModel(edict_t *e, const char *m)
-{
- META_ENGINE_HANDLE_void(FN_SETMODEL, pfnSetModel, (e, m));
- RETURN_API_void()
-}
-
-int mm_ModelIndex(const char *m)
-{
- META_ENGINE_HANDLE(int, 0, FN_MODELINDEX, pfnModelIndex, (m));
- RETURN_API()
-}
-
-int mm_ModelFrames(int modelIndex)
-{
- META_ENGINE_HANDLE(int, 0, FN_MODELFRAMES, pfnModelFrames, (modelIndex));
- RETURN_API()
-}
-
-void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax)
-{
- META_ENGINE_HANDLE_void(FN_SETSIZE, pfnSetSize, (e, rgflMin, rgflMax));
- RETURN_API_void()
-}
-
-void mm_ChangeLevel(const char *s1, const char *s2)
-{
- META_ENGINE_HANDLE_void(FN_CHANGELEVEL, pfnChangeLevel, (s1, s2));
- RETURN_API_void()
-}
-
-void mm_GetSpawnParms(edict_t *ent)
-{
- META_ENGINE_HANDLE_void(FN_GETSPAWNPARMS, pfnGetSpawnParms, (ent));
- RETURN_API_void()
-}
-
-void mm_SaveSpawnParms(edict_t *ent)
-{
- META_ENGINE_HANDLE_void(FN_SAVESPAWNPARMS, pfnSaveSpawnParms, (ent));
- RETURN_API_void()
-}
-
-float mm_VecToYaw(const float *rgflVector)
-{
- META_ENGINE_HANDLE(float, 0.0, FN_VECTOYAW, pfnVecToYaw, (rgflVector));
- RETURN_API()
-}
-
-void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut)
-{
- META_ENGINE_HANDLE_void(FN_VECTOANGLES, pfnVecToAngles, (rgflVectorIn, rgflVectorOut));
- RETURN_API_void()
-}
-
-void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType)
-{
- META_ENGINE_HANDLE_void(FN_MOVETOORIGIN, pfnMoveToOrigin, (ent, pflGoal, dist, iMoveType));
- RETURN_API_void()
-}
-
-void mm_ChangeYaw(edict_t *ent)
-{
- META_ENGINE_HANDLE_void(FN_CHANGEYAW, pfnChangeYaw, (ent));
- RETURN_API_void()
-}
-
-void mm_ChangePitch(edict_t *ent)
-{
- META_ENGINE_HANDLE_void(FN_CHANGEPITCH, pfnChangePitch, (ent));
- RETURN_API_void()
-}
-
-edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYBYSTRING, pfnFindEntityByString, (pEdictStartSearchAfter, pszField, pszValue));
- RETURN_API()
-}
-
-int mm_GetEntityIllum(edict_t *pEnt)
-{
- META_ENGINE_HANDLE(int, 0, FN_GETENTITYILLUM, pfnGetEntityIllum, (pEnt));
- RETURN_API()
-}
-
-edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYINSPHERE, pfnFindEntityInSphere, (pEdictStartSearchAfter, org, rad));
- RETURN_API()
-}
-
-edict_t *mm_FindClientInPVS(edict_t *pEdict)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDCLIENTINPVS, pfnFindClientInPVS, (pEdict));
- RETURN_API()
-}
-
-edict_t *mm_EntitiesInPVS(edict_t *pplayer)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_ENTITIESINPVS, pfnEntitiesInPVS, (pplayer));
- RETURN_API()
-}
-
-void mm_MakeVectors(const float *rgflVector)
-{
- META_ENGINE_HANDLE_void(FN_MAKEVECTORS, pfnMakeVectors, (rgflVector));
- RETURN_API_void()
-}
-
-void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up)
-{
- META_ENGINE_HANDLE_void(FN_ANGLEVECTORS, pfnAngleVectors, (rgflVector, forward, right, up));
- RETURN_API_void()
-}
-
-edict_t *mm_CreateEntity()
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATEENTITY, pfnCreateEntity, ());
- RETURN_API()
-}
-
-void mm_RemoveEntity(edict_t *e)
-{
- META_ENGINE_HANDLE_void(FN_REMOVEENTITY, pfnRemoveEntity, (e));
- RETURN_API_void()
-}
-
-edict_t *mm_CreateNamedEntity(int className)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATENAMEDENTITY, pfnCreateNamedEntity, (className));
- RETURN_API()
-}
-
-void mm_MakeStatic(edict_t *ent)
-{
- META_ENGINE_HANDLE_void(FN_MAKESTATIC, pfnMakeStatic, (ent));
- RETURN_API_void()
-}
-
-int mm_EntIsOnFloor(edict_t *e)
-{
- META_ENGINE_HANDLE(int, 0, FN_ENTISONFLOOR, pfnEntIsOnFloor, (e));
- RETURN_API()
-}
-
-int mm_DropToFloor(edict_t *e)
-{
- META_ENGINE_HANDLE(int, 0, FN_DROPTOFLOOR, pfnDropToFloor, (e));
- RETURN_API()
-}
-
-int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode)
-{
- META_ENGINE_HANDLE(int, 0, FN_WALKMOVE, pfnWalkMove, (ent, yaw, dist, iMode));
- RETURN_API()
-}
-
-void mm_SetOrigin(edict_t *e, const float *rgflOrigin)
-{
- META_ENGINE_HANDLE_void(FN_SETORIGIN, pfnSetOrigin, (e, rgflOrigin));
- RETURN_API_void()
-}
-
-void mm_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch)
-{
- META_ENGINE_HANDLE_void(FN_EMITSOUND, pfnEmitSound, (entity, channel, sample, volume, attenuation, fFlags, pitch));
- RETURN_API_void()
-}
-
-void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch)
-{
- META_ENGINE_HANDLE_void(FN_EMITAMBIENTSOUND, pfnEmitAmbientSound, (entity, pos, samp, vol, attenuation, fFlags, pitch));
- RETURN_API_void()
-}
-
-void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr)
-{
- META_ENGINE_HANDLE_void(FN_TRACELINE, pfnTraceLine, (v1, v2, fNoMonsters, pentToSkip, ptr));
- RETURN_API_void()
-}
-
-void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr)
-{
- META_ENGINE_HANDLE_void(FN_TRACETOSS, pfnTraceToss, (pent, pentToIgnore, ptr));
- RETURN_API_void()
-}
-
-int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr)
-{
- META_ENGINE_HANDLE(int, 0, FN_TRACEMONSTERHULL, pfnTraceMonsterHull, (pEdict, v1, v2, fNoMonsters, pentToSkip, ptr));
- RETURN_API()
-}
-
-void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr)
-{
- META_ENGINE_HANDLE_void(FN_TRACEHULL, pfnTraceHull, (v1, v2, fNoMonsters, hullNumber, pentToSkip, ptr));
- RETURN_API_void()
-}
-
-void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr)
-{
- META_ENGINE_HANDLE_void(FN_TRACEMODEL, pfnTraceModel, (v1, v2, hullNumber, pent, ptr));
- RETURN_API_void()
-}
-
-const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_TRACETEXTURE, pfnTraceTexture, (pTextureEntity, v1, v2));
- RETURN_API()
-}
-
-void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr)
-{
- META_ENGINE_HANDLE_void(FN_TRACESPHERE, pfnTraceSphere, (v1, v2, fNoMonsters, radius, pentToSkip, ptr));
- RETURN_API_void()
-}
-
-void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn)
-{
- META_ENGINE_HANDLE_void(FN_GETAIMVECTOR, pfnGetAimVector, (ent, speed, rgflReturn));
- RETURN_API_void()
-}
-
-void mm_ServerCommand(char *str)
-{
- META_ENGINE_HANDLE_void(FN_SERVERCOMMAND, pfnServerCommand, (str));
- RETURN_API_void()
-}
-
-void mm_ServerExecute()
-{
- META_ENGINE_HANDLE_void(FN_SERVEREXECUTE, pfnServerExecute, ());
- RETURN_API_void()
-}
-
-void mm_engClientCommand(edict_t *pEdict, char *szFmt, ...)
-{
- META_ENGINE_HANDLE_void_varargs(FN_CLIENTCOMMAND_ENG, pfnClientCommand, pEdict, szFmt);
- RETURN_API_void()
-}
-
-void mm_ParticleEffect(const float *org, const float *dir, float color, float count)
-{
- META_ENGINE_HANDLE_void(FN_PARTICLEEFFECT, pfnParticleEffect, (org, dir, color, count));
- RETURN_API_void()
-}
-
-void mm_LightStyle(int style, char *val)
-{
- META_ENGINE_HANDLE_void(FN_LIGHTSTYLE, pfnLightStyle, (style, val));
- RETURN_API_void()
-}
-
-int mm_DecalIndex(const char *name)
-{
- META_ENGINE_HANDLE(int, 0, FN_DECALINDEX, pfnDecalIndex, (name));
- RETURN_API()
-}
-
-int mm_PointContents(const float *rgflVector)
-{
- META_ENGINE_HANDLE(int, 0, FN_POINTCONTENTS, pfnPointContents, (rgflVector));
- RETURN_API()
-}
-
-void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
-{
- META_ENGINE_HANDLE_void(FN_MESSAGEBEGIN, pfnMessageBegin, (msg_dest, msg_type, pOrigin, ed));
- RETURN_API_void()
-}
-
-void mm_MessageEnd()
-{
- META_ENGINE_HANDLE_void(FN_MESSAGEEND, pfnMessageEnd, ());
- RETURN_API_void()
-}
-
-void mm_WriteByte(int iValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITEBYTE, pfnWriteByte, (iValue));
- RETURN_API_void()
-}
-
-void mm_WriteChar(int iValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITECHAR, pfnWriteChar, (iValue));
- RETURN_API_void()
-}
-
-void mm_WriteShort(int iValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITESHORT, pfnWriteShort, (iValue));
- RETURN_API_void()
-}
-
-void mm_WriteLong(int iValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITELONG, pfnWriteLong, (iValue));
- RETURN_API_void()
-}
-
-void mm_WriteAngle(float flValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITEANGLE, pfnWriteAngle, (flValue));
- RETURN_API_void()
-}
-
-void mm_WriteCoord(float flValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITECOORD, pfnWriteCoord, (flValue));
- RETURN_API_void()
-}
-
-void mm_WriteString(const char *sz)
-{
- META_ENGINE_HANDLE_void(FN_WRITESTRING, pfnWriteString, (sz));
- RETURN_API_void()
-}
-
-void mm_WriteEntity(int iValue)
-{
- META_ENGINE_HANDLE_void(FN_WRITEENTITY, pfnWriteEntity, (iValue));
- RETURN_API_void()
-}
-
-void mm_CVarRegister(cvar_t *pCvar)
-{
- META_ENGINE_HANDLE_void(FN_CVARREGISTER, pfnCVarRegister, (pCvar));
- RETURN_API_void()
-}
-
-float mm_CVarGetFloat(const char *szVarName)
+void mm_QueryClientCvarValue(const edict_t* pEdict, const char* cvarName)
{
- META_ENGINE_HANDLE(float, 0.0, FN_CVARGETFLOAT, pfnCVarGetFloat, (szVarName));
- RETURN_API()
+ g_players.set_player_cvar_query(pEdict, cvarName);
}
-const char *mm_CVarGetString(const char *szVarName)
+void mm_RegUserMsg(const char* pszName, int iSize)
{
- META_ENGINE_HANDLE(const char *, NULL, FN_CVARGETSTRING, pfnCVarGetString, (szVarName));
- RETURN_API()
-}
-
-void mm_CVarSetFloat(const char *szVarName, float flValue)
-{
- META_ENGINE_HANDLE_void(FN_CVARSETFLOAT, pfnCVarSetFloat, (szVarName, flValue));
- RETURN_API_void()
-}
-
-void mm_CVarSetString(const char *szVarName, const char *szValue)
-{
- META_ENGINE_HANDLE_void(FN_CVARSETSTRING, pfnCVarSetString, (szVarName, szValue));
- RETURN_API_void()
-}
-
-void mm_AlertMessage(ALERT_TYPE atype, const char *szFmt, ...)
-{
-#ifndef UNFINISHED
- META_ENGINE_HANDLE_void_varargs(FN_ALERTMESSAGE, pfnAlertMessage, atype, szFmt);
-#else
- // Expand macro, since we need to do extra work here.
- // usual setup
-
- SETUP_API_CALLS_void(FN_ALERTMESSAGE, pfnAlertMessage, engine_info);
- char buf[MAX_STRBUF_LEN];
- va_list ap;
-
- META_DEBUG(loglevel, ("In %s: fmt=%s", pfn_string, szFmt));
- va_start(ap, szFmt);
- int len = Q_vsnprintf(buf, sizeof(buf), szFmt, ap) + 1;
- va_end(ap);
-
- // pass logmsg string to log parsing thread
- /// qmsg = Q_strdup(buf);
- char *qmsg = (char *)Q_malloc(len * sizeof(char));
- if (!qmsg)
- META_ERROR("malloc failed for logmsg to thread queue");
- else
- {
- STRNCPY(qmsg, buf, len);
- LogQueue->push(qmsg);
- }
-
- // usual passing to plugins/engine
- CALL_PLUGIN_API_void(P_PRE, pfnAlertMessage, (atype, "%s", buf), engine_table);
- CALL_ENGINE_API_void(pfnAlertMessage, (atype, "%s", buf));
- CALL_PLUGIN_API_void(P_POST, pfnAlertMessage, (atype, "%s", buf), engine_post_table);
-#endif // UNFINISHED
-
- // usual return.
- RETURN_API_void()
-}
-
-void mm_EngineFprintf(void *pfile, const char *szFmt, ...)
-{
- META_ENGINE_HANDLE_void_varargs(FN_ENGINEFPRINTF, pfnEngineFprintf, pfile, szFmt);
- RETURN_API_void()
-}
-
-void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb)
-{
- META_ENGINE_HANDLE(void *, NULL, FN_PVALLOCENTPRIVATEDATA, pfnPvAllocEntPrivateData, (pEdict, cb));
- RETURN_API()
-}
-
-void *mm_PvEntPrivateData(edict_t *pEdict)
-{
- META_ENGINE_HANDLE(void *, NULL, FN_PVENTPRIVATEDATA, pfnPvEntPrivateData, (pEdict));
- RETURN_API()
-}
-
-void mm_FreeEntPrivateData(edict_t *pEdict)
-{
- META_ENGINE_HANDLE_void(FN_FREEENTPRIVATEDATA, pfnFreeEntPrivateData, (pEdict));
- RETURN_API_void()
-}
-
-const char *mm_SzFromIndex(int iString)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_SZFROMINDEX, pfnSzFromIndex, (iString));
- RETURN_API()
-}
-
-int mm_AllocString(const char *szValue)
-{
- META_ENGINE_HANDLE(int, 0, FN_ALLOCSTRING, pfnAllocString, (szValue));
- RETURN_API()
-}
-
-struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict)
-{
- META_ENGINE_HANDLE(struct entvars_s *, NULL, FN_GETVARSOFENT, pfnGetVarsOfEnt, (pEdict));
- RETURN_API()
-}
-
-edict_t *mm_PEntityOfEntOffset(int iEntOffset)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_PENTITYOFENTOFFSET, pfnPEntityOfEntOffset, (iEntOffset));
- RETURN_API()
-}
-
-int mm_EntOffsetOfPEntity(const edict_t *pEdict)
-{
- META_ENGINE_HANDLE(int, 0, FN_ENTOFFSETOFPENTITY, pfnEntOffsetOfPEntity, (pEdict));
- RETURN_API()
-}
-
-int mm_IndexOfEdict(const edict_t *pEdict)
-{
- META_ENGINE_HANDLE(int, 0, FN_INDEXOFEDICT, pfnIndexOfEdict, (pEdict));
- RETURN_API()
-}
-
-edict_t *mm_PEntityOfEntIndex(int iEntIndex)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_PENTITYOFENTINDEX, pfnPEntityOfEntIndex, (iEntIndex));
- RETURN_API()
-}
-
-edict_t *mm_FindEntityByVars(struct entvars_s *pvars)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYBYVARS, pfnFindEntityByVars, (pvars));
- RETURN_API()
-}
-
-void *mm_GetModelPtr(edict_t *pEdict)
-{
- META_ENGINE_HANDLE(void *, NULL, FN_GETMODELPTR, pfnGetModelPtr, (pEdict));
- RETURN_API()
-}
-
-int mm_RegUserMsg(const char *pszName, int iSize)
-{
- int imsgid;
- MRegMsg *nmsg = nullptr;
- META_ENGINE_HANDLE(int, 0, FN_REGUSERMSG, pfnRegUserMsg, (pszName, iSize));
-
- // Expand the macro, since we need to do extra work.
- /// RETURN_API()
- if (--CALL_API_count > 0)
- PublicMetaGlobals = backup_meta_globals;
-
- if (status == MRES_OVERRIDE)
- {
- META_DEBUG(loglevel, ("Returning (override) %s()", pfn_string));
- imsgid = override_ret;
- }
- else
- imsgid = orig_ret;
+ /*__asm int 3;
// Add the msgid, name, and size to our saved list, if we haven't
// already.
- nmsg = g_regMsgs->find(imsgid);
- if (nmsg)
- {
- if (FStrEq(pszName, nmsg->name))
+ auto imsgid = *(int *)(g_metaGlobals.status == MRES_OVERRIDE ? g_metaGlobals.override_ret : g_metaGlobals.orig_ret);
+ auto nmsg = g_regMsgs->find(imsgid);
+
+ if (nmsg) {
+ if (!strcmp(pszName, nmsg->name))
// This name/msgid pair was already registered.
META_DEBUG(3, ("user message registered again: name=%s, msgid=%d", pszName, imsgid));
else
@@ -554,719 +28,252 @@ int mm_RegUserMsg(const char *pszName, int iSize)
META_ERROR("user message id reused: msgid=%d, oldname=%s, newname=%s", imsgid, nmsg->name, pszName);
}
else
- g_regMsgs->add(pszName, imsgid, iSize);
+ g_regMsgs->add(pszName, imsgid, iSize);*/
+}
+
+compile_data_t g_engfuncs_cdata[] =
+{
+ CDATA_ENG(pfnPrecacheModel), // pfnPrecacheModel()
+ CDATA_ENG(pfnPrecacheSound), // pfnPrecacheSound()
+ CDATA_ENG(pfnSetModel), // pfnSetModel()
+ CDATA_ENG(pfnModelIndex), // pfnModelIndex()
+ CDATA_ENG(pfnModelFrames), // pfnModelFrames()
+
+ CDATA_ENG(pfnSetSize), // pfnSetSize()
+ CDATA_ENG(pfnChangeLevel), // pfnChangeLevel()
+ CDATA_ENG(pfnGetSpawnParms), // pfnGetSpawnParms()
+ CDATA_ENG(pfnSaveSpawnParms), // pfnSaveSpawnParms()
+
+ CDATA_ENG(pfnVecToYaw), // pfnVecToYaw()
+ CDATA_ENG(pfnVecToAngles), // pfnVecToAngles()
+ CDATA_ENG(pfnMoveToOrigin), // pfnMoveToOrigin()
+ CDATA_ENG(pfnChangeYaw), // pfnChangeYaw()
+ CDATA_ENG(pfnChangePitch), // pfnChangePitch()
+
+ CDATA_ENG(pfnFindEntityByString), // pfnFindEntityByString()
+ CDATA_ENG(pfnGetEntityIllum), // pfnGetEntityIllum()
+ CDATA_ENG(pfnFindEntityInSphere), // pfnFindEntityInSphere()
+ CDATA_ENG(pfnFindClientInPVS), // pfnFindClientInPVS()
+ CDATA_ENG(pfnEntitiesInPVS), // pfnEntitiesInPVS()
+
+ CDATA_ENG(pfnMakeVectors), // pfnMakeVectors()
+ CDATA_ENG(pfnAngleVectors), // pfnAngleVectors()
- return imsgid;
-}
-
-void mm_AnimationAutomove(const edict_t *pEdict, float flTime)
-{
- META_ENGINE_HANDLE_void(FN_ANIMATIONAUTOMOVE, pfnAnimationAutomove, (pEdict, flTime));
- RETURN_API_void()
-}
-
-void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles)
-{
- META_ENGINE_HANDLE_void(FN_GETBONEPOSITION, pfnGetBonePosition, (pEdict, iBone, rgflOrigin, rgflAngles));
- RETURN_API_void()
-}
-
-uint32 mm_FunctionFromName(const char *pName)
-{
- META_ENGINE_HANDLE(uint32, 0, FN_FUNCTIONFROMNAME, pfnFunctionFromName, (pName));
- RETURN_API()
-}
-
-const char *mm_NameForFunction(uint32 function)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_NAMEFORFUNCTION, pfnNameForFunction, (function));
- RETURN_API()
-}
-
-// JOHN: engine callbacks so game DLL can print messages to individual clients
-void mm_ClientPrintf(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg)
-{
- META_ENGINE_HANDLE_void(FN_CLIENTPRINTF, pfnClientPrintf, (pEdict, ptype, szMsg));
- RETURN_API_void()
-}
-
-void mm_ServerPrint(const char *szMsg)
-{
- META_ENGINE_HANDLE_void(FN_SERVERPRINT, pfnServerPrint, (szMsg));
- RETURN_API_void()
-}
-
-// these 3 added so game DLL can easily access client 'cmd' strings
-const char *mm_Cmd_Args()
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_CMD_ARGS, pfnCmd_Args, ());
- RETURN_API()
-}
-
-const char *mm_Cmd_Argv(int argc)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_CMD_ARGV, pfnCmd_Argv, (argc));
- RETURN_API()
-}
-
-int mm_Cmd_Argc()
-{
- META_ENGINE_HANDLE(int, 0, FN_CMD_ARGC, pfnCmd_Argc, ());
- RETURN_API()
-}
-
-void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles)
-{
- META_ENGINE_HANDLE_void(FN_GETATTACHMENT, pfnGetAttachment, (pEdict, iAttachment, rgflOrigin, rgflAngles));
- RETURN_API_void()
-}
-
-void mm_CRC32_Init(CRC32_t *pulCRC)
-{
- META_ENGINE_HANDLE_void(FN_CRC32_INIT, pfnCRC32_Init, (pulCRC));
- RETURN_API_void()
-}
-void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len)
-{
- META_ENGINE_HANDLE_void(FN_CRC32_PROCESSBUFFER, pfnCRC32_ProcessBuffer, (pulCRC, p, len));
- RETURN_API_void()
-}
-void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch)
-{
- META_ENGINE_HANDLE_void(FN_CRC32_PROCESSBYTE, pfnCRC32_ProcessByte, (pulCRC, ch));
- RETURN_API_void()
-}
-CRC32_t mm_CRC32_Final(CRC32_t pulCRC)
-{
- META_ENGINE_HANDLE(CRC32_t, 0, FN_CRC32_FINAL, pfnCRC32_Final, (pulCRC));
- RETURN_API()
-}
-
-int32 mm_RandomLong(int32 lLow, int32 lHigh)
-{
- META_ENGINE_HANDLE(int32, 0, FN_RANDOMLONG, pfnRandomLong, (lLow, lHigh));
- RETURN_API()
-}
-
-float mm_RandomFloat(float flLow, float flHigh)
-{
- META_ENGINE_HANDLE(float, 0.0, FN_RANDOMFLOAT, pfnRandomFloat, (flLow, flHigh));
- RETURN_API()
-}
-
-void mm_SetView(const edict_t *pClient, const edict_t *pViewent)
-{
- META_ENGINE_HANDLE_void(FN_SETVIEW, pfnSetView, (pClient, pViewent));
- RETURN_API_void()
-}
-
-float mm_Time()
-{
- META_ENGINE_HANDLE(float, 0.0, FN_TIME, pfnTime, ());
- RETURN_API()
-}
-
-void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw)
-{
- META_ENGINE_HANDLE_void(FN_CROSSHAIRANGLE, pfnCrosshairAngle, (pClient, pitch, yaw));
- RETURN_API_void()
-}
-
-byte *mm_LoadFileForMe(char *filename, int *pLength)
-{
- META_ENGINE_HANDLE(byte *, NULL, FN_LOADFILEFORME, pfnLoadFileForMe, (filename, pLength));
- RETURN_API()
-}
-
-void mm_FreeFile(void *buffer)
-{
- META_ENGINE_HANDLE_void(FN_FREEFILE, pfnFreeFile, (buffer));
- RETURN_API_void()
-}
-
-// trigger_endsection
-void mm_EndSection(const char *pszSectionName)
-{
- META_ENGINE_HANDLE_void(FN_ENDSECTION, pfnEndSection, (pszSectionName));
- RETURN_API_void()
-}
-
-int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare)
-{
- META_ENGINE_HANDLE(int, 0, FN_COMPAREFILETIME, pfnCompareFileTime, (filename1, filename2, iCompare));
- RETURN_API()
-}
-
-void mm_GetGameDir(char *szGetGameDir)
-{
- META_ENGINE_HANDLE_void(FN_GETGAMEDIR, pfnGetGameDir, (szGetGameDir));
- RETURN_API_void()
-}
-
-void mm_Cvar_RegisterVariable(cvar_t *variable)
-{
- META_ENGINE_HANDLE_void(FN_CVAR_REGISTERVARIABLE, pfnCvar_RegisterVariable, (variable));
- RETURN_API_void()
-}
-
-void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds)
-{
- META_ENGINE_HANDLE_void(FN_FADECLIENTVOLUME, pfnFadeClientVolume, (pEdict, fadePercent, fadeOutSeconds, holdTime, fadeInSeconds));
- RETURN_API_void()
-}
-
-void mm_SetClientMaxspeed(edict_t *pEdict, float fNewMaxspeed)
-{
- META_ENGINE_HANDLE_void(FN_SETCLIENTMAXSPEED, pfnSetClientMaxspeed, (pEdict, fNewMaxspeed));
- RETURN_API_void()
-}
-
-// returns NULL if fake client can't be created
-edict_t *mm_CreateFakeClient(const char *netname)
-{
- META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATEFAKECLIENT, pfnCreateFakeClient, (netname));
- RETURN_API()
-}
-
-void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec)
-{
- META_ENGINE_HANDLE_void(FN_RUNPLAYERMOVE, pfnRunPlayerMove, (fakeclient, viewangles, forwardmove, sidemove, upmove, buttons, impulse, msec));
- RETURN_API_void()
-}
-
-int mm_NumberOfEntities()
-{
- META_ENGINE_HANDLE(int, 0, FN_NUMBEROFENTITIES, pfnNumberOfEntities, ());
- RETURN_API()
-}
-
-// passing in NULL gets the serverinfo
-char *mm_GetInfoKeyBuffer(edict_t *e)
-{
- META_ENGINE_HANDLE(char *, NULL, FN_GETINFOKEYBUFFER, pfnGetInfoKeyBuffer, (e));
- RETURN_API()
-}
-
-char *mm_InfoKeyValue(char *infobuffer, const char *key)
-{
- META_ENGINE_HANDLE(char *, NULL, FN_INFOKEYVALUE, pfnInfoKeyValue, (infobuffer, key));
- RETURN_API()
-}
-
-void mm_SetKeyValue(char *infobuffer, const char *key, const char *value)
-{
- META_ENGINE_HANDLE_void(FN_SETKEYVALUE, pfnSetKeyValue, (infobuffer, key, value));
- RETURN_API_void()
-}
-
-void mm_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value)
-{
- META_ENGINE_HANDLE_void(FN_SETCLIENTKEYVALUE, pfnSetClientKeyValue, (clientIndex, infobuffer, key, value));
- RETURN_API_void()
-}
-
-int mm_IsMapValid(char *filename)
-{
- META_ENGINE_HANDLE(int, 0, FN_ISMAPVALID, pfnIsMapValid, (filename));
- RETURN_API()
-}
-
-void mm_StaticDecal(const float *origin, int decalIndex, int entityIndex, int modelIndex)
-{
- META_ENGINE_HANDLE_void(FN_STATICDECAL, pfnStaticDecal, (origin, decalIndex, entityIndex, modelIndex));
- RETURN_API_void()
-}
-
-int mm_PrecacheGeneric(char *s)
-{
- META_ENGINE_HANDLE(int, 0, FN_PRECACHEGENERIC, pfnPrecacheGeneric, (s));
- RETURN_API()
-}
-
-// returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
-int mm_GetPlayerUserId(edict_t *e)
-{
- META_ENGINE_HANDLE(int, 0, FN_GETPLAYERUSERID, pfnGetPlayerUserId, (e));
- RETURN_API()
-}
-
-void mm_BuildSoundMsg(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
-{
- META_ENGINE_HANDLE_void(FN_BUILDSOUNDMSG, pfnBuildSoundMsg, (entity, channel, sample, volume, attenuation, fFlags, pitch, msg_dest, msg_type, pOrigin, ed));
- RETURN_API_void()
-}
-
-// is this a dedicated server?
-int mm_IsDedicatedServer()
-{
- META_ENGINE_HANDLE(int, 0, FN_ISDEDICATEDSERVER, pfnIsDedicatedServer, ());
- RETURN_API()
-}
-
-cvar_t *mm_CVarGetPointer(const char *szVarName)
-{
- META_ENGINE_HANDLE(cvar_t *, NULL, FN_CVARGETPOINTER, pfnCVarGetPointer, (szVarName));
- RETURN_API()
-}
-
-// returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
-unsigned int mm_GetPlayerWONId(edict_t *e)
-{
- META_ENGINE_HANDLE(unsigned int, 0, FN_GETPLAYERWONID, pfnGetPlayerWONId, (e));
- RETURN_API()
-}
-
-// YWB 8/1/99 TFF Physics additions
-void mm_Info_RemoveKey(char *s, const char *key)
-{
- META_ENGINE_HANDLE_void(FN_INFO_REMOVEKEY, pfnInfo_RemoveKey, (s, key));
- RETURN_API_void()
-}
-
-const char *mm_GetPhysicsKeyValue(const edict_t *pClient, const char *key)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_GETPHYSICSKEYVALUE, pfnGetPhysicsKeyValue, (pClient, key));
- RETURN_API()
-}
-
-void mm_SetPhysicsKeyValue(const edict_t *pClient, const char *key, const char *value)
-{
- META_ENGINE_HANDLE_void(FN_SETPHYSICSKEYVALUE, pfnSetPhysicsKeyValue, (pClient, key, value));
- RETURN_API_void()
-}
-
-const char *mm_GetPhysicsInfoString(const edict_t *pClient)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_GETPHYSICSINFOSTRING, pfnGetPhysicsInfoString, (pClient));
- RETURN_API()
-}
-
-unsigned short mm_PrecacheEvent(int type, const char *psz)
-{
- META_ENGINE_HANDLE(unsigned short, 0, FN_PRECACHEEVENT, pfnPrecacheEvent, (type, psz));
- RETURN_API()
-}
-
-void mm_PlaybackEvent(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2)
-{
- META_ENGINE_HANDLE_void(FN_PLAYBACKEVENT, pfnPlaybackEvent, (flags, pInvoker, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2));
- RETURN_API_void()
-}
-
-unsigned char *mm_SetFatPVS(float *org)
-{
- META_ENGINE_HANDLE(unsigned char *, 0, FN_SETFATPVS, pfnSetFatPVS, (org));
- RETURN_API()
-}
-
-unsigned char *mm_SetFatPAS(float *org)
-{
- META_ENGINE_HANDLE(unsigned char *, 0, FN_SETFATPAS, pfnSetFatPAS, (org));
- RETURN_API()
-}
-
-int mm_CheckVisibility(edict_t *entity, unsigned char *pset)
-{
- META_ENGINE_HANDLE(int, 0, FN_CHECKVISIBILITY, pfnCheckVisibility, (entity, pset));
- RETURN_API()
-}
-
-void mm_DeltaSetField(struct delta_s *pFields, const char *fieldname)
-{
- META_ENGINE_HANDLE_void(FN_DELTASETFIELD, pfnDeltaSetField, (pFields, fieldname));
- RETURN_API_void()
-}
-
-void mm_DeltaUnsetField(struct delta_s *pFields, const char *fieldname)
-{
- META_ENGINE_HANDLE_void(FN_DELTAUNSETFIELD, pfnDeltaUnsetField, (pFields, fieldname));
- RETURN_API_void()
-}
-
-void mm_DeltaAddEncoder(char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to))
-{
- META_ENGINE_HANDLE_void(FN_DELTAADDENCODER, pfnDeltaAddEncoder, (name, conditionalencode));
- RETURN_API_void()
-}
-
-int mm_GetCurrentPlayer()
-{
- META_ENGINE_HANDLE(int, 0, FN_GETCURRENTPLAYER, pfnGetCurrentPlayer, ());
- RETURN_API()
-}
-
-int mm_CanSkipPlayer(const edict_t *player)
-{
- META_ENGINE_HANDLE(int, 0, FN_CANSKIPPLAYER, pfnCanSkipPlayer, (player));
- RETURN_API()
-}
-
-int mm_DeltaFindField(struct delta_s *pFields, const char *fieldname)
-{
- META_ENGINE_HANDLE(int, 0, FN_DELTAFINDFIELD, pfnDeltaFindField, (pFields, fieldname));
- RETURN_API()
-}
-
-void mm_DeltaSetFieldByIndex(struct delta_s *pFields, int fieldNumber)
-{
- META_ENGINE_HANDLE_void(FN_DELTASETFIELDBYINDEX, pfnDeltaSetFieldByIndex, (pFields, fieldNumber));
- RETURN_API_void()
-}
-
-void mm_DeltaUnsetFieldByIndex(struct delta_s *pFields, int fieldNumber)
-{
- META_ENGINE_HANDLE_void(FN_DELTAUNSETFIELDBYINDEX, pfnDeltaUnsetFieldByIndex, (pFields, fieldNumber));
- RETURN_API_void()
-}
-
-void mm_SetGroupMask(int mask, int op)
-{
- META_ENGINE_HANDLE_void(FN_SETGROUPMASK, pfnSetGroupMask, (mask, op));
- RETURN_API_void()
-}
-
-int mm_engCreateInstancedBaseline(int classname, struct entity_state_s *baseline)
-{
- META_ENGINE_HANDLE(int, 0, FN_CREATEINSTANCEDBASELINE, pfnCreateInstancedBaseline, (classname, baseline));
- RETURN_API()
-}
-
-void mm_Cvar_DirectSet(struct cvar_s *var, const char *value)
-{
- META_ENGINE_HANDLE_void(FN_CVAR_DIRECTSET, pfnCvar_DirectSet, (var, value));
- RETURN_API_void()
-}
-
-// Forces the client and server to be running with the same version of the specified file (e.g., a player model).
-// Calling this has no effect in single player
-void mm_ForceUnmodified(FORCE_TYPE type, float *mins, float *maxs, const char *filename)
-{
- META_ENGINE_HANDLE_void(FN_FORCEUNMODIFIED, pfnForceUnmodified, (type, mins, maxs, filename));
- RETURN_API_void()
-}
-
-void mm_GetPlayerStats(const edict_t *pClient, int *ping, int *packet_loss)
-{
- META_ENGINE_HANDLE_void(FN_GETPLAYERSTATS, pfnGetPlayerStats, (pClient, ping, packet_loss));
- RETURN_API_void()
-}
-
-void mm_AddServerCommand(char *cmd_name, void (*function)())
-{
- META_ENGINE_HANDLE_void(FN_ADDSERVERCOMMAND, pfnAddServerCommand, (cmd_name, function));
- RETURN_API_void()
-}
-
-// For voice communications, set which clients hear eachother.
-// NOTE: these functions take player entity indices (starting at 1).
-qboolean mm_Voice_GetClientListening(int iReceiver, int iSender)
-{
- META_ENGINE_HANDLE(qboolean, false, FN_VOICE_GETCLIENTLISTENING, pfnVoice_GetClientListening, (iReceiver, iSender));
- RETURN_API()
-}
-
-qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen)
-{
- META_ENGINE_HANDLE(qboolean, false, FN_VOICE_SETCLIENTLISTENING, pfnVoice_SetClientListening, (iReceiver, iSender, bListen));
- RETURN_API()
-}
-
-const char *mm_GetPlayerAuthId(edict_t *e)
-{
- META_ENGINE_HANDLE(const char *, NULL, FN_GETPLAYERAUTHID, pfnGetPlayerAuthId, (e));
- RETURN_API()
-}
-
-sequenceEntry_s *mm_SequenceGet(const char *fileName, const char *entryName)
-{
- META_ENGINE_HANDLE(sequenceEntry_s *, NULL, FN_SEQUENCEGET, pfnSequenceGet, (fileName, entryName));
- RETURN_API()
-}
-
-sentenceEntry_s *mm_SequencePickSentence(const char *groupName, int pickMethod, int *picked)
-{
- META_ENGINE_HANDLE(sentenceEntry_s *, NULL, FN_SEQUENCEPICKSENTENCE, pfnSequencePickSentence, (groupName, pickMethod, picked));
- RETURN_API()
-}
-
-int mm_GetFileSize(char *filename)
-{
- META_ENGINE_HANDLE(int, 0, FN_GETFILESIZE, pfnGetFileSize, (filename));
- RETURN_API()
-}
-
-unsigned int mm_GetApproxWavePlayLen(const char *filepath)
-{
- META_ENGINE_HANDLE(unsigned int, 0, FN_GETAPPROXWAVEPLAYLEN, pfnGetApproxWavePlayLen, (filepath));
- RETURN_API()
-}
-
-int mm_IsCareerMatch()
-{
- META_ENGINE_HANDLE(int, 0, FN_ISCAREERMATCH, pfnIsCareerMatch, ());
- RETURN_API()
-}
-
-int mm_GetLocalizedStringLength(const char *label)
-{
- META_ENGINE_HANDLE(int, 0, FN_GETLOCALIZEDSTRINGLENGTH, pfnGetLocalizedStringLength, (label));
- RETURN_API()
-}
-
-void mm_RegisterTutorMessageShown(int mid)
-{
- META_ENGINE_HANDLE_void(FN_REGISTERTUTORMESSAGESHOWN, pfnRegisterTutorMessageShown, (mid));
- RETURN_API_void()
-}
-
-int mm_GetTimesTutorMessageShown(int mid)
-{
- META_ENGINE_HANDLE(int, 0, FN_GETTIMESTUTORMESSAGESHOWN, pfnGetTimesTutorMessageShown, (mid));
- RETURN_API()
-}
-
-void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength)
-{
- META_ENGINE_HANDLE_void(FN_PROCESSTUTORMESSAGEDECAYBUFFER, pfnProcessTutorMessageDecayBuffer, (buffer, bufferLength));
- RETURN_API_void()
-}
-
-void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength)
-{
- META_ENGINE_HANDLE_void(FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER, pfnConstructTutorMessageDecayBuffer, (buffer, bufferLength));
- RETURN_API_void()
-}
-
-void mm_ResetTutorMessageDecayData()
-{
- META_ENGINE_HANDLE_void(FN_RESETTUTORMESSAGEDECAYDATA, pfnResetTutorMessageDecayData, ());
- RETURN_API_void()
-}
-
-void mm_QueryClientCvarValue(const edict_t *pEdict, const char *cvarName)
-{
- g_Players.set_player_cvar_query(pEdict, cvarName);
-
- META_ENGINE_HANDLE_void(FN_QUERYCLIENTCVARVALUE, pfnQueryClientCvarValue, (pEdict, cvarName));
- RETURN_API_void();
-}
-
-void mm_QueryClientCvarValue2(const edict_t *pEdict, const char *cvarName, int requestId)
-{
- META_ENGINE_HANDLE_void(FN_QUERYCLIENTCVARVALUE2, pfnQueryClientCvarValue2, (pEdict, cvarName, requestId));
- RETURN_API_void();
-}
-
-int mm_EngCheckParm(const char *pchCmdLineToken, char **ppnext)
-{
- META_ENGINE_HANDLE(int, 0, FN_CHECKPARM, pfnEngCheckParm, (pchCmdLineToken, ppnext));
- RETURN_API();
-}
-
-enginefuncs_t _engfuncs =
-{
- &mm_PrecacheModel, // pfnPrecacheModel()
- &mm_PrecacheSound, // pfnPrecacheSound()
- &mm_SetModel, // pfnSetModel()
- &mm_ModelIndex, // pfnModelIndex()
- &mm_ModelFrames, // pfnModelFrames()
-
- &mm_SetSize, // pfnSetSize()
- &mm_ChangeLevel, // pfnChangeLevel()
- &mm_GetSpawnParms, // pfnGetSpawnParms()
- &mm_SaveSpawnParms, // pfnSaveSpawnParms()
-
- &mm_VecToYaw, // pfnVecToYaw()
- &mm_VecToAngles, // pfnVecToAngles()
- &mm_MoveToOrigin, // pfnMoveToOrigin()
- &mm_ChangeYaw, // pfnChangeYaw()
- &mm_ChangePitch, // pfnChangePitch()
-
- &mm_FindEntityByString, // pfnFindEntityByString()
- &mm_GetEntityIllum, // pfnGetEntityIllum()
- &mm_FindEntityInSphere, // pfnFindEntityInSphere()
- &mm_FindClientInPVS, // pfnFindClientInPVS()
- &mm_EntitiesInPVS, // pfnEntitiesInPVS()
-
- &mm_MakeVectors, // pfnMakeVectors()
- &mm_AngleVectors, // pfnAngleVectors()
-
- &mm_CreateEntity, // pfnCreateEntity()
- &mm_RemoveEntity, // pfnRemoveEntity()
- &mm_CreateNamedEntity, // pfnCreateNamedEntity()
-
- &mm_MakeStatic, // pfnMakeStatic()
- &mm_EntIsOnFloor, // pfnEntIsOnFloor()
- &mm_DropToFloor, // pfnDropToFloor()
-
- &mm_WalkMove, // pfnWalkMove()
- &mm_SetOrigin, // pfnSetOrigin()
-
- &mm_EmitSound, // pfnEmitSound()
- &mm_EmitAmbientSound, // pfnEmitAmbientSound()
-
- &mm_TraceLine, // pfnTraceLine()
- &mm_TraceToss, // pfnTraceToss()
- &mm_TraceMonsterHull, // pfnTraceMonsterHull()
- &mm_TraceHull, // pfnTraceHull()
- &mm_TraceModel, // pfnTraceModel()
- &mm_TraceTexture, // pfnTraceTexture()
- &mm_TraceSphere, // pfnTraceSphere()
- &mm_GetAimVector, // pfnGetAimVector()
-
- &mm_ServerCommand, // pfnServerCommand()
- &mm_ServerExecute, // pfnServerExecute()
- &mm_engClientCommand, // pfnClientCommand() // D'oh, ClientCommand in dllapi too.
-
- &mm_ParticleEffect, // pfnParticleEffect()
- &mm_LightStyle, // pfnLightStyle()
- &mm_DecalIndex, // pfnDecalIndex()
- &mm_PointContents, // pfnPointContents()
-
- &mm_MessageBegin, // pfnMessageBegin()
- &mm_MessageEnd, // pfnMessageEnd()
-
- &mm_WriteByte, // pfnWriteByte()
- &mm_WriteChar, // pfnWriteChar()
- &mm_WriteShort, // pfnWriteShort()
- &mm_WriteLong, // pfnWriteLong()
- &mm_WriteAngle, // pfnWriteAngle()
- &mm_WriteCoord, // pfnWriteCoord()
- &mm_WriteString, // pfnWriteString()
- &mm_WriteEntity, // pfnWriteEntity()
-
- &mm_CVarRegister, // pfnCVarRegister()
- &mm_CVarGetFloat, // pfnCVarGetFloat()
- &mm_CVarGetString, // pfnCVarGetString()
- &mm_CVarSetFloat, // pfnCVarSetFloat()
- &mm_CVarSetString, // pfnCVarSetString()
-
- &mm_AlertMessage, // pfnAlertMessage()
- &mm_EngineFprintf, // pfnEngineFprintf()
-
- &mm_PvAllocEntPrivateData, // pfnPvAllocEntPrivateData()
- &mm_PvEntPrivateData, // pfnPvEntPrivateData()
- &mm_FreeEntPrivateData, // pfnFreeEntPrivateData()
-
- &mm_SzFromIndex, // pfnSzFromIndex()
- &mm_AllocString, // pfnAllocString()
-
- &mm_GetVarsOfEnt, // pfnGetVarsOfEnt()
- &mm_PEntityOfEntOffset, // pfnPEntityOfEntOffset()
- &mm_EntOffsetOfPEntity, // pfnEntOffsetOfPEntity()
- &mm_IndexOfEdict, // pfnIndexOfEdict()
- &mm_PEntityOfEntIndex, // pfnPEntityOfEntIndex()
- &mm_FindEntityByVars, // pfnFindEntityByVars()
- &mm_GetModelPtr, // pfnGetModelPtr()
-
- &mm_RegUserMsg, // pfnRegUserMsg()
-
- &mm_AnimationAutomove, // pfnAnimationAutomove()
- &mm_GetBonePosition, // pfnGetBonePosition()
-
- &mm_FunctionFromName, // pfnFunctionFromName()
- &mm_NameForFunction, // pfnNameForFunction()
-
- &mm_ClientPrintf, // pfnClientPrintf() // JOHN: engine callbacks so game DLL can print messages to individual clients
- &mm_ServerPrint, // pfnServerPrint()
-
- &mm_Cmd_Args, // pfnCmd_Args() // these 3 added
- &mm_Cmd_Argv, // pfnCmd_Argv() // so game DLL can easily
- &mm_Cmd_Argc, // pfnCmd_Argc() // access client 'cmd' strings
-
- &mm_GetAttachment, // pfnGetAttachment()
-
- &mm_CRC32_Init, // pfnCRC32_Init()
- &mm_CRC32_ProcessBuffer, // pfnCRC32_ProcessBuffer()
- &mm_CRC32_ProcessByte, // pfnCRC32_ProcessByte()
- &mm_CRC32_Final, // pfnCRC32_Final()
-
- &mm_RandomLong, // pfnRandomLong()
- &mm_RandomFloat, // pfnRandomFloat()
-
- &mm_SetView, // pfnSetView()
- &mm_Time, // pfnTime()
- &mm_CrosshairAngle, // pfnCrosshairAngle()
-
- &mm_LoadFileForMe, // pfnLoadFileForMe()
- &mm_FreeFile, // pfnFreeFile()
-
- &mm_EndSection, // pfnEndSection() // trigger_endsection
- &mm_CompareFileTime, // pfnCompareFileTime()
- &mm_GetGameDir, // pfnGetGameDir()
- &mm_Cvar_RegisterVariable, // pfnCvar_RegisterVariable()
- &mm_FadeClientVolume, // pfnFadeClientVolume()
- &mm_SetClientMaxspeed, // pfnSetClientMaxspeed()
- &mm_CreateFakeClient, // pfnCreateFakeClient() // returns NULL if fake client can't be created
- &mm_RunPlayerMove, // pfnRunPlayerMove()
- &mm_NumberOfEntities, // pfnNumberOfEntities()
-
- &mm_GetInfoKeyBuffer, // pfnGetInfoKeyBuffer() // passing in NULL gets the serverinfo
- &mm_InfoKeyValue, // pfnInfoKeyValue()
- &mm_SetKeyValue, // pfnSetKeyValue()
- &mm_SetClientKeyValue, // pfnSetClientKeyValue()
-
- &mm_IsMapValid, // pfnIsMapValid()
- &mm_StaticDecal, // pfnStaticDecal()
- &mm_PrecacheGeneric, // pfnPrecacheGeneric()
- &mm_GetPlayerUserId, // pfnGetPlayerUserId() // returns the server assigned userid for this player.
- &mm_BuildSoundMsg, // pfnBuildSoundMsg()
- &mm_IsDedicatedServer, // pfnIsDedicatedServer() // is this a dedicated server?
- &mm_CVarGetPointer, // pfnCVarGetPointer()
- &mm_GetPlayerWONId, // pfnGetPlayerWONId() // returns the server assigned WONid for this player.
-
- &mm_Info_RemoveKey, // pfnInfo_RemoveKey()
- &mm_GetPhysicsKeyValue, // pfnGetPhysicsKeyValue()
- &mm_SetPhysicsKeyValue, // pfnSetPhysicsKeyValue()
- &mm_GetPhysicsInfoString, // pfnGetPhysicsInfoString()
- &mm_PrecacheEvent, // pfnPrecacheEvent()
- &mm_PlaybackEvent, // pfnPlaybackEvent()
-
- &mm_SetFatPVS, // pfnSetFatPVS()
- &mm_SetFatPAS, // pfnSetFatPAS()
-
- &mm_CheckVisibility, // pfnCheckVisibility()
-
- &mm_DeltaSetField, // pfnDeltaSetField()
- &mm_DeltaUnsetField, // pfnDeltaUnsetField()
- &mm_DeltaAddEncoder, // pfnDeltaAddEncoder()
- &mm_GetCurrentPlayer, // pfnGetCurrentPlayer()
- &mm_CanSkipPlayer, // pfnCanSkipPlayer()
- &mm_DeltaFindField, // pfnDeltaFindField()
- &mm_DeltaSetFieldByIndex, // pfnDeltaSetFieldByIndex()
- &mm_DeltaUnsetFieldByIndex, // pfnDeltaUnsetFieldByIndex()
-
- &mm_SetGroupMask, // pfnSetGroupMask()
-
- &mm_engCreateInstancedBaseline, // pfnCreateInstancedBaseline() // D'oh, CreateInstancedBaseline in dllapi too.
- &mm_Cvar_DirectSet, // pfnCvar_DirectSet()
-
- &mm_ForceUnmodified, // pfnForceUnmodified()
-
- &mm_GetPlayerStats, // pfnGetPlayerStats()
-
- &mm_AddServerCommand, // pfnAddServerCommand()
-
- &mm_Voice_GetClientListening, // pfnVoice_GetClientListening()
- &mm_Voice_SetClientListening, // pfnVoice_SetClientListening()
-
- &mm_GetPlayerAuthId, // pfnGetPlayerAuthId()
-
- &mm_SequenceGet, // pfnSequenceGet()
- &mm_SequencePickSentence, // pfnSequencePickSentence()
- &mm_GetFileSize, // pfnGetFileSize()
- &mm_GetApproxWavePlayLen, // pfnGetApproxWavePlayLen()
- &mm_IsCareerMatch, // pfnIsCareerMatch()
- &mm_GetLocalizedStringLength, // pfnGetLocalizedStringLength()
- &mm_RegisterTutorMessageShown, // pfnRegisterTutorMessageShown()
- &mm_GetTimesTutorMessageShown, // pfnGetTimesTutorMessageShown()
- &mm_ProcessTutorMessageDecayBuffer, // pfnProcessTutorMessageDecayBuffer()
- &mm_ConstructTutorMessageDecayBuffer, // pfnConstructTutorMessageDecayBuffer()
- &mm_ResetTutorMessageDecayData, // pfnResetTutorMessageDecayData()
-
- &mm_QueryClientCvarValue, // pfnQueryClientCvarValue()
- &mm_QueryClientCvarValue2, // pfnQueryClientCvarValue2()
- &mm_EngCheckParm // pfnCheckParm()
+ CDATA_ENG(pfnCreateEntity), // pfnCreateEntity()
+ CDATA_ENG(pfnRemoveEntity), // pfnRemoveEntity()
+ CDATA_ENG(pfnCreateNamedEntity), // pfnCreateNamedEntity()
+
+ CDATA_ENG(pfnMakeStatic), // pfnMakeStatic()
+ CDATA_ENG(pfnEntIsOnFloor), // pfnEntIsOnFloor()
+ CDATA_ENG(pfnDropToFloor), // pfnDropToFloor()
+
+ CDATA_ENG(pfnWalkMove), // pfnWalkMove()
+ CDATA_ENG(pfnSetOrigin), // pfnSetOrigin()
+
+ CDATA_ENG(pfnEmitSound), // pfnEmitSound()
+ CDATA_ENG(pfnEmitAmbientSound), // pfnEmitAmbientSound()
+
+ CDATA_ENG(pfnTraceLine), // pfnTraceLine()
+ CDATA_ENG(pfnTraceToss), // pfnTraceToss()
+ CDATA_ENG(pfnTraceMonsterHull), // pfnTraceMonsterHull()
+ CDATA_ENG(pfnTraceHull), // pfnTraceHull()
+ CDATA_ENG(pfnTraceModel), // pfnTraceModel()
+ CDATA_ENG(pfnTraceTexture), // pfnTraceTexture()
+ CDATA_ENG(pfnTraceSphere), // pfnTraceSphere()
+ CDATA_ENG(pfnGetAimVector), // pfnGetAimVector()
+
+ CDATA_ENG(pfnServerCommand), // pfnServerCommand()
+ CDATA_ENG(pfnServerExecute), // pfnServerExecute()
+ CDATA_ENG(pfnClientCommand), // pfnClientCommand() // D'oh, ClientCommand in dllapi too.
+
+ CDATA_ENG(pfnParticleEffect), // pfnParticleEffect()
+ CDATA_ENG(pfnLightStyle), // pfnLightStyle()
+ CDATA_ENG(pfnDecalIndex), // pfnDecalIndex()
+ CDATA_ENG(pfnPointContents), // pfnPointContents()
+
+ CDATA_ENG(pfnMessageBegin), // pfnMessageBegin()
+ CDATA_ENG(pfnMessageEnd), // pfnMessageEnd()
+
+ CDATA_ENG(pfnWriteByte), // pfnWriteByte()
+ CDATA_ENG(pfnWriteChar), // pfnWriteChar()
+ CDATA_ENG(pfnWriteShort), // pfnWriteShort()
+ CDATA_ENG(pfnWriteLong), // pfnWriteLong()
+ CDATA_ENG(pfnWriteAngle), // pfnWriteAngle()
+ CDATA_ENG(pfnWriteCoord), // pfnWriteCoord()
+ CDATA_ENG(pfnWriteString), // pfnWriteString()
+ CDATA_ENG(pfnWriteEntity), // pfnWriteEntity()
+
+ CDATA_ENG(pfnCVarRegister), // pfnCVarRegister()
+ CDATA_ENG(pfnCVarGetFloat), // pfnCVarGetFloat()
+ CDATA_ENG(pfnCVarGetString), // pfnCVarGetString()
+ CDATA_ENG(pfnCVarSetFloat), // pfnCVarSetFloat()
+ CDATA_ENG(pfnCVarSetString), // pfnCVarSetString()
+
+ CDATA_ENG(pfnAlertMessage), // pfnAlertMessage()
+ CDATA_ENG(pfnEngineFprintf), // pfnEngineFprintf()
+
+ CDATA_ENG(pfnPvAllocEntPrivateData), // pfnPvAllocEntPrivateData()
+ CDATA_ENG(pfnPvEntPrivateData), // pfnPvEntPrivateData()
+ CDATA_ENG(pfnFreeEntPrivateData), // pfnFreeEntPrivateData()
+
+ CDATA_ENG(pfnSzFromIndex), // pfnSzFromIndex()
+ CDATA_ENG(pfnAllocString), // pfnAllocString()
+
+ CDATA_ENG(pfnGetVarsOfEnt), // pfnGetVarsOfEnt()
+ CDATA_ENG(pfnPEntityOfEntOffset), // pfnPEntityOfEntOffset()
+ CDATA_ENG(pfnEntOffsetOfPEntity), // pfnEntOffsetOfPEntity()
+ CDATA_ENG(pfnIndexOfEdict), // pfnIndexOfEdict()
+ CDATA_ENG(pfnPEntityOfEntIndex), // pfnPEntityOfEntIndex()
+ CDATA_ENG(pfnFindEntityByVars), // pfnFindEntityByVars()
+ CDATA_ENG(pfnGetModelPtr), // pfnGetModelPtr()
+
+ CDATA_ENG_H(pfnRegUserMsg, P_POST, mm_RegUserMsg), // pfnRegUserMsg()
+
+ CDATA_ENG(pfnAnimationAutomove), // pfnAnimationAutomove()
+ CDATA_ENG(pfnGetBonePosition), // pfnGetBonePosition()
+
+ CDATA_ENG(pfnFunctionFromName), // pfnFunctionFromName()
+ CDATA_ENG(pfnNameForFunction), // pfnNameForFunction()
+
+ CDATA_ENG(pfnClientPrintf), // pfnClientPrintf() // JOHN: engine callbacks so game DLL can print messages to individual clients
+ CDATA_ENG(pfnServerPrint), // pfnServerPrint()
+
+ CDATA_ENG(pfnCmd_Args), // pfnCmd_Args() // these 3 added
+ CDATA_ENG(pfnCmd_Argv), // pfnCmd_Argv() // so game DLL can easily
+ CDATA_ENG(pfnCmd_Argc), // pfnCmd_Argc() // access client 'cmd' strings
+
+ CDATA_ENG(pfnGetAttachment), // pfnGetAttachment()
+
+ CDATA_ENG(pfnCRC32_Init), // pfnCRC32_Init()
+ CDATA_ENG(pfnCRC32_ProcessBuffer), // pfnCRC32_ProcessBuffer()
+ CDATA_ENG(pfnCRC32_ProcessByte), // pfnCRC32_ProcessByte()
+ CDATA_ENG(pfnCRC32_Final), // pfnCRC32_Final()
+
+ CDATA_ENG(pfnRandomLong), // pfnRandomLong()
+ CDATA_ENG(pfnRandomFloat), // pfnRandomFloat()
+
+ CDATA_ENG(pfnSetView), // pfnSetView()
+ CDATA_ENG(pfnTime), // pfnTime()
+ CDATA_ENG(pfnCrosshairAngle), // pfnCrosshairAngle()
+
+ CDATA_ENG(pfnLoadFileForMe), // pfnLoadFileForMe()
+ CDATA_ENG(pfnFreeFile), // pfnFreeFile()
+
+ CDATA_ENG(pfnEndSection), // pfnEndSection() // trigger_endsection
+ CDATA_ENG(pfnCompareFileTime), // pfnCompareFileTime()
+ CDATA_ENG(pfnGetGameDir), // pfnGetGameDir()
+ CDATA_ENG(pfnCvar_RegisterVariable), // pfnCvar_RegisterVariable()
+ CDATA_ENG(pfnFadeClientVolume), // pfnFadeClientVolume()
+ CDATA_ENG(pfnSetClientMaxspeed), // pfnSetClientMaxspeed()
+ CDATA_ENG(pfnCreateFakeClient), // pfnCreateFakeClient() // returns NULL if fake client can't be created
+ CDATA_ENG(pfnRunPlayerMove), // pfnRunPlayerMove()
+ CDATA_ENG(pfnNumberOfEntities), // pfnNumberOfEntities()
+
+ CDATA_ENG(pfnGetInfoKeyBuffer), // pfnGetInfoKeyBuffer() // passing in NULL gets the serverinfo
+ CDATA_ENG(pfnInfoKeyValue), // pfnInfoKeyValue()
+ CDATA_ENG(pfnSetKeyValue), // pfnSetKeyValue()
+ CDATA_ENG(pfnSetClientKeyValue), // pfnSetClientKeyValue()
+
+ CDATA_ENG(pfnIsMapValid), // pfnIsMapValid()
+ CDATA_ENG(pfnStaticDecal), // pfnStaticDecal()
+ CDATA_ENG(pfnPrecacheGeneric), // pfnPrecacheGeneric()
+ CDATA_ENG(pfnGetPlayerUserId), // pfnGetPlayerUserId() // returns the server assigned userid for this player.
+ CDATA_ENG(pfnBuildSoundMsg), // pfnBuildSoundMsg()
+ CDATA_ENG(pfnIsDedicatedServer), // pfnIsDedicatedServer() // is this a dedicated server?
+ CDATA_ENG(pfnCVarGetPointer), // pfnCVarGetPointer()
+ CDATA_ENG(pfnGetPlayerWONId), // pfnGetPlayerWONId() // returns the server assigned WONid for this player.
+
+ CDATA_ENG(pfnInfo_RemoveKey), // pfnInfo_RemoveKey()
+ CDATA_ENG(pfnGetPhysicsKeyValue), // pfnGetPhysicsKeyValue()
+ CDATA_ENG(pfnSetPhysicsKeyValue), // pfnSetPhysicsKeyValue()
+ CDATA_ENG(pfnGetPhysicsInfoString), // pfnGetPhysicsInfoString()
+ CDATA_ENG(pfnPrecacheEvent), // pfnPrecacheEvent()
+ CDATA_ENG(pfnPlaybackEvent), // pfnPlaybackEvent()
+
+ CDATA_ENG(pfnSetFatPVS), // pfnSetFatPVS()
+ CDATA_ENG(pfnSetFatPAS), // pfnSetFatPAS()
+
+ CDATA_ENG(pfnCheckVisibility), // pfnCheckVisibility()
+
+ CDATA_ENG(pfnDeltaSetField), // pfnDeltaSetField()
+ CDATA_ENG(pfnDeltaUnsetField), // pfnDeltaUnsetField()
+ CDATA_ENG(pfnDeltaAddEncoder), // pfnDeltaAddEncoder()
+ CDATA_ENG(pfnGetCurrentPlayer), // pfnGetCurrentPlayer()
+ CDATA_ENG(pfnCanSkipPlayer), // pfnCanSkipPlayer()
+ CDATA_ENG(pfnDeltaFindField), // pfnDeltaFindField()
+ CDATA_ENG(pfnDeltaSetFieldByIndex), // pfnDeltaSetFieldByIndex()
+ CDATA_ENG(pfnDeltaUnsetFieldByIndex), // pfnDeltaUnsetFieldByIndex()
+
+ CDATA_ENG(pfnSetGroupMask), // pfnSetGroupMask()
+
+ CDATA_ENG(pfnCreateInstancedBaseline), // pfnCreateInstancedBaseline() // D'oh, CreateInstancedBaseline in dllapi too.
+ CDATA_ENG(pfnCvar_DirectSet), // pfnCvar_DirectSet()
+
+ CDATA_ENG(pfnForceUnmodified), // pfnForceUnmodified()
+
+ CDATA_ENG(pfnGetPlayerStats), // pfnGetPlayerStats()
+
+ CDATA_ENG(pfnAddServerCommand), // pfnAddServerCommand()
+
+ CDATA_ENG(pfnVoice_GetClientListening), // pfnVoice_GetClientListening()
+ CDATA_ENG(pfnVoice_SetClientListening), // pfnVoice_SetClientListening()
+
+ CDATA_ENG(pfnGetPlayerAuthId), // pfnGetPlayerAuthId()
+
+ CDATA_ENG(pfnSequenceGet), // pfnSequenceGet()
+ CDATA_ENG(pfnSequencePickSentence), // pfnSequencePickSentence()
+ CDATA_ENG(pfnGetFileSize), // pfnGetFileSize()
+ CDATA_ENG(pfnGetApproxWavePlayLen), // pfnGetApproxWavePlayLen()
+ CDATA_ENG(pfnIsCareerMatch), // pfnIsCareerMatch()
+ CDATA_ENG(pfnGetLocalizedStringLength), // pfnGetLocalizedStringLength()
+ CDATA_ENG(pfnRegisterTutorMessageShown), // pfnRegisterTutorMessageShown()
+ CDATA_ENG(pfnGetTimesTutorMessageShown), // pfnGetTimesTutorMessageShown()
+ CDATA_ENG(pfnProcessTutorMessageDecayBuffer), // pfnProcessTutorMessageDecayBuffer()
+ CDATA_ENG(pfnConstructTutorMessageDecayBuffer), // pfnConstructTutorMessageDecayBuffer()
+ CDATA_ENG(pfnResetTutorMessageDecayData), // pfnResetTutorMessageDecayData()
+
+ CDATA_ENG_H(pfnQueryClientCvarValue, P_PRE, mm_QueryClientCvarValue), // pfnQueryClientCvarValue()
+ CDATA_ENG(pfnQueryClientCvarValue2), // pfnQueryClientCvarValue2()
+ CDATA_ENG(pfnEngCheckParm) // pfnCheckParm()*/
};
-meta_enginefuncs_t meta_engfuncs(&_engfuncs);
+void compile_engfuncs_callbacks()
+{
+ jitdata_t jitdata;
+ jitdata.plugins = g_plugins ? g_plugins->plist : nullptr;
+ jitdata.plugins_count = g_plugins ? g_plugins->endlist : 0;
+ jitdata.table_offset = offsetof(MPlugin, engine_table);
+ jitdata.post_table_offset = offsetof(MPlugin, engine_post_table);
+
+ for (auto& cd : g_engfuncs_cdata) {
+ jitdata.pfn_original = *(size_t *)(size_t(&g_engfuncs) + cd.offset);
+ jitdata.args_count = cd.args_count;
+ jitdata.has_ret = cd.has_ret;
+ jitdata.has_varargs = cd.has_varargs;
+ jitdata.pfn_offset = cd.offset;
+ jitdata.mm_hook_time = cd.mm_hook_time;
+ jitdata.mm_hook = cd.mm_hook;
+
+ *(size_t *)(size_t(&meta_engfuncs_jit) + cd.offset) = g_jit.compile_callback(&jitdata);
+ }
+}
+
+void compile_engine_tramps()
+{
+ // we compile simple static functions that will call dynamic callbacks
+ for (auto& cd : g_engfuncs_cdata) {
+ *(size_t *)(size_t(&meta_engfuncs) + cd.offset) = g_jit.compile_tramp(size_t(&meta_engfuncs_jit) + cd.offset/*, cd.mm_hook, cd.mm_hook_time*/);
+ }
+}
+
+void compile_engine_callbacks()
+{
+ static bool initialized = false;
+
+ if (!initialized) {
+ compile_engine_tramps();
+ initialized = true;
+ }
+
+ compile_engfuncs_callbacks();
+}
diff --git a/metamod/src/engine_api.h b/metamod/src/engine_api.h
index a805384..702cb7d 100644
--- a/metamod/src/engine_api.h
+++ b/metamod/src/engine_api.h
@@ -18,359 +18,4 @@ typedef int (*GET_ENGINE_FUNCTIONS_FN)(enginefuncs_t *pengfuncsFromEngine, int *
extern enginefuncs_t meta_engfuncs;
#endif
-extern int mm_PrecacheModel(const char *s);
-extern int mm_PrecacheSound(const char *s);
-extern void mm_SetModel(edict_t *e, const char *m);
-extern int mm_ModelIndex(const char *m);
-extern int mm_ModelFrames(int modelIndex);
-
-extern void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax);
-extern void mm_ChangeLevel(const char *s1, const char *s2);
-extern void mm_GetSpawnParms(edict_t *ent);
-extern void mm_SaveSpawnParms(edict_t *ent);
-
-extern float mm_VecToYaw(const float *rgflVector);
-extern void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut);
-extern void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType);
-extern void mm_ChangeYaw(edict_t *ent);
-extern void mm_ChangePitch(edict_t *ent);
-
-extern edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue);
-extern int mm_GetEntityIllum(edict_t *pEnt);
-extern edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad);
-extern edict_t *mm_FindClientInPVS(edict_t *pEdict);
-extern edict_t *mm_EntitiesInPVS(edict_t *pplayer);
-
-extern void mm_MakeVectors(const float *rgflVector);
-extern void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up);
-
-extern edict_t *mm_CreateEntity();
-extern void mm_RemoveEntity(edict_t *e);
-extern edict_t *mm_CreateNamedEntity(int className);
-
-extern void mm_MakeStatic(edict_t *ent);
-extern int mm_EntIsOnFloor(edict_t *e);
-extern int mm_DropToFloor(edict_t *e);
-
-extern int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode);
-extern void mm_SetOrigin(edict_t *e, const float *rgflOrigin);
-
-extern void mm_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch);
-extern void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
-
-extern void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
-extern void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr);
-extern int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
-extern void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
-extern void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
-extern const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2);
-extern void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
-extern void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn);
-
-extern void mm_ServerCommand(const char *str);
-extern void mm_ServerExecute();
-extern void ClientCommand(edict_t *pEdict, const char *szFmt, ...);
-
-extern void mm_ParticleEffect(const float *org, const float *dir, float color, float count);
-extern void mm_LightStyle(int style, const char *val);
-extern int mm_DecalIndex(const char *name);
-extern int mm_PointContents(const float *rgflVector);
-
-extern void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
-extern void mm_MessageEnd();
-
-extern void mm_WriteByte(int iValue);
-extern void mm_WriteChar(int iValue);
-extern void mm_WriteShort(int iValue);
-extern void mm_WriteLong(int iValue);
-extern void mm_WriteAngle(float flValue);
-extern void mm_WriteCoord(float flValue);
-extern void mm_WriteString(const char *sz);
-extern void mm_WriteEntity(int iValue);
-
-extern void mm_CVarRegister(cvar_t *pCvar);
-extern float mm_CVarGetFloat(const char *szVarName);
-extern const char *mm_CVarGetString(const char *szVarName);
-extern void mm_CVarSetFloat(const char *szVarName, float flValue);
-extern void mm_CVarSetString(const char *szVarName, const char *szValue);
-
-extern void mm_AlertMessage(ALERT_TYPE atype, const char *szFmt, ...);
-extern void mm_EngineFprintf(void *pfile, const char *szFmt, ...);
-extern void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb);
-extern void *mm_PvEntPrivateData(edict_t *pEdict);
-extern void mm_FreeEntPrivateData(edict_t *pEdict);
-
-extern const char *mm_SzFromIndex(int iString);
-extern int mm_AllocString(const char *szValue);
-
-extern struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict);
-extern edict_t *mm_PEntityOfEntOffset(int iEntOffset);
-extern int mm_EntOffsetOfPEntity(const edict_t *pEdict);
-extern int mm_IndexOfEdict(const edict_t *pEdict);
-extern edict_t *mm_PEntityOfEntIndex(int iEntIndex);
-extern edict_t *mm_FindEntityByVars(struct entvars_s *pvars);
-extern void *mm_GetModelPtr(edict_t *pEdict);
-
-extern int mm_RegUserMsg(const char *pszName, int iSize);
-
-extern void mm_AnimationAutomove(const edict_t *pEdict, float flTime);
-extern void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles);
-
-extern uint32 mm_FunctionFromName(const char *pName);
-extern const char *mm_NameForFunction(uint32 function);
-
-extern void mm_ClientPrintf(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg); //! JOHN: engine callbacks so game DLL can print messages to individual clients
-extern void mm_ServerPrint(const char *szMsg);
-
-extern const char *mm_Cmd_Args(); //! these 3 added
-extern const char *mm_Cmd_Argv(int argc); //! so game DLL can easily
-extern int mm_Cmd_Argc(); //! access client 'cmd' strings
-
-extern void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles);
-
-extern void mm_CRC32_Init(CRC32_t *pulCRC);
-extern void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len);
-extern void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch);
-extern CRC32_t mm_CRC32_Final(CRC32_t pulCRC);
-
-extern int32 mm_RandomLong(int32 lLow, int32 lHigh);
-extern float mm_RandomFloat(float flLow, float flHigh);
-
-extern void mm_SetView(const edict_t *pClient, const edict_t *pViewent);
-extern float mm_Time();
-extern void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw);
-
-extern byte *mm_LoadFileForMe(const char *filename, int *pLength);
-extern void mm_FreeFile(void *buffer);
-
-extern void mm_EndSection(const char *pszSectionName); //! trigger_endsection
-extern int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare);
-extern void mm_GetGameDir(char *szGetGameDir);
-extern void mm_Cvar_RegisterVariable(cvar_t *variable);
-extern void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
-extern void mm_SetClientMaxspeed(const edict_t *pEdict, float fNewMaxspeed);
-extern edict_t *mm_CreateFakeClient(const char *netname); //! returns NULL if fake client can't be created
-extern void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec);
-extern int mm_NumberOfEntities();
-
-extern char *mm_GetInfoKeyBuffer(edict_t *e); //! passing in NULL gets the serverinfo
-extern char *mm_InfoKeyValue(char *infobuffer, const char *key);
-extern void mm_SetKeyValue(char *infobuffer, const char *key, const char *value);
-extern void mm_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value);
-
-extern int mm_IsMapValid(char *filename);
-extern void mm_StaticDecal(const float *origin, int decalIndex, int entityIndex, int modelIndex);
-extern int mm_PrecacheGeneric(const char *s);
-extern int mm_GetPlayerUserId(edict_t *e); //! returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
-extern void mm_BuildSoundMsg(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
-extern int mm_IsDedicatedServer();//! is this a dedicated server?
-extern cvar_t *mm_CVarGetPointer(const char *szVarName);
-extern unsigned int mm_GetPlayerWONId(edict_t *e); //! returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients
-
-// 8/1/99 TFF Physics additions
-extern void mm_Info_RemoveKey(char *s, const char *key);
-extern const char *mm_GetPhysicsKeyValue(const edict_t *pClient, const char *key);
-extern void mm_SetPhysicsKeyValue(const edict_t *pClient, const char *key, const char *value);
-extern const char *mm_GetPhysicsInfoString(const edict_t *pClient);
-extern unsigned short mm_PrecacheEvent(int type, const char *psz);
-extern void mm_PlaybackEvent(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
-extern unsigned char *mm_SetFatPVS(float *org);
-extern unsigned char *mm_SetFatPAS(float *org);
-extern int mm_CheckVisibility(edict_t *entity, unsigned char *pset);
-
-extern void mm_DeltaSetField(struct delta_s *pFields, const char *fieldname);
-extern void mm_DeltaUnsetField(struct delta_s *pFields, const char *fieldname);
-extern void mm_DeltaAddEncoder(const char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to));
-extern int mm_GetCurrentPlayer();
-extern int mm_CanSkipPlayer(const edict_t *player);
-extern int mm_DeltaFindField(struct delta_s *pFields, const char *fieldname);
-extern void mm_DeltaSetFieldByIndex(struct delta_s *pFields, int fieldNumber);
-extern void mm_DeltaUnsetFieldByIndex(struct delta_s *pFields, int fieldNumber);
-extern void mm_SetGroupMask(int mask, int op);
-extern int CreateInstancedBaseline(int classname, struct entity_state_s *baseline);
-extern void mm_Cvar_DirectSet(struct cvar_s *var, const char *value);
-
-// Forces the client and server to be running with the same version of the specified file e.g., a player model).
-// Calling this has no effect in single player
-extern void mm_ForceUnmodified(FORCE_TYPE type, float *mins, float *maxs, const char *filename);
-extern void mm_GetPlayerStats(const edict_t *pClient, int *ping, int *packet_loss);
-
-extern void mm_AddServerCommand(const char *cmd_name, void (*function)());
-extern qboolean mm_Voice_GetClientListening(int iReceiver, int iSender);
-extern qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen);
-extern const char *mm_pfnGetPlayerAuthId(edict_t *e);
-extern sequenceEntry_s *mm_SequenceGet(const char *fileName, const char *entryName);
-extern sentenceEntry_s *mm_SequencePickSentence(const char *groupName, int pickMethod, int *picked);
-extern int mm_GetFileSize(const char *filename);
-extern unsigned int mm_GetApproxWavePlayLen(const char *filepath);
-extern int mm_IsCareerMatch();
-extern int mm_GetLocalizedStringLength(const char *label);
-extern void mm_RegisterTutorMessageShown(int mid);
-extern int mm_GetTimesTutorMessageShown(int mid);
-extern void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength);
-extern void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength);
-extern void mm_ResetTutorMessageDecayData();
-
-extern void mm_QueryClientCvarValue(const edict_t *pEdict, const char *cvarName); //! Obsolete! Use mm_QueryClientCvarValue2 instead
-extern void mm_QueryClientCvarValue2(const edict_t *pEdict, const char *cvarName, int requestID);
-extern int mm_EngCheckParm(const char *pchCmdLineToken, char **ppnext);
-
-// Typedefs for the above functions:
-typedef int (*FN_PRECACHEMODEL)(const char *s);
-typedef int (*FN_PRECACHESOUND)(const char *s);
-typedef void (*FN_SETMODEL)(edict_t *e, const char *m);
-typedef int (*FN_MODELINDEX)(const char *m);
-typedef int (*FN_MODELFRAMES)(int modelIndex);
-typedef void (*FN_SETSIZE)(edict_t *e, const float *rgflMin, const float *rgflMax);
-typedef void (*FN_CHANGELEVEL)(const char *s1, const char *s2);
-typedef void (*FN_GETSPAWNPARMS)(edict_t *ent);
-typedef void (*FN_SAVESPAWNPARMS)(edict_t *ent);
-typedef float (*FN_VECTOYAW)(const float *rgflVector);
-typedef void (*FN_VECTOANGLES)(const float *rgflVectorIn, float *rgflVectorOut);
-typedef void (*FN_MOVETOORIGIN)(edict_t *ent, const float *pflGoal, float dist, int iMoveType);
-typedef void (*FN_CHANGEYAW)(edict_t *ent);
-typedef void (*FN_CHANGEPITCH)(edict_t *ent);
-typedef edict_t *(*FN_FINDENTITYBYSTRING)(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue);
-typedef int (*FN_GETENTITYILLUM)(edict_t *pEnt);
-typedef edict_t *(*FN_FINDENTITYINSPHERE)(edict_t *pEdictStartSearchAfter, const float *org, float rad);
-typedef edict_t *(*FN_FINDCLIENTINPVS)(edict_t *pEdict);
-typedef edict_t *(*FN_ENTITIESINPVS)(edict_t *pplayer);
-typedef void (*FN_MAKEVECTORS)(const float *rgflVector);
-typedef void (*FN_ANGLEVECTORS)(const float *rgflVector, float *forward, float *right, float *up);
-typedef edict_t *(*FN_CREATEENTITY)();
-typedef void (*FN_REMOVEENTITY)(edict_t *e);
-typedef edict_t *(*FN_CREATENAMEDENTITY)(int className);
-typedef void (*FN_MAKESTATIC)(edict_t *ent);
-typedef int (*FN_ENTISONFLOOR)(edict_t *e);
-typedef int (*FN_DROPTOFLOOR)(edict_t *e);
-typedef int (*FN_WALKMOVE)(edict_t *ent, float yaw, float dist, int iMode);
-typedef void (*FN_SETORIGIN)(edict_t *e, const float *rgflOrigin);
-typedef void (*FN_EMITSOUND)(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch);
-typedef void (*FN_EMITAMBIENTSOUND)(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch);
-typedef void (*FN_TRACELINE)(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
-typedef void (*FN_TRACETOSS)(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr);
-typedef int (*FN_TRACEMONSTERHULL)(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr);
-typedef void (*FN_TRACEHULL)(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr);
-typedef void (*FN_TRACEMODEL)(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr);
-typedef const char *(*FN_TRACETEXTURE)(edict_t *pTextureEntity, const float *v1, const float *v2);
-typedef void (*FN_TRACESPHERE)(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr);
-typedef void (*FN_GETAIMVECTOR)(edict_t *ent, float speed, float *rgflReturn);
-typedef void (*FN_SERVERCOMMAND)(char *str);
-typedef void (*FN_SERVEREXECUTE)();
-typedef void (*FN_CLIENTCOMMAND_ENG)(edict_t *pEdict, char *szFmt, ...);
-typedef void (*FN_PARTICLEEFFECT)(const float *org, const float *dir, float color, float count);
-typedef void (*FN_LIGHTSTYLE)(int style, char *val);
-typedef int (*FN_DECALINDEX)(const char *name);
-typedef int (*FN_POINTCONTENTS)(const float *rgflVector);
-typedef void (*FN_MESSAGEBEGIN)(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
-typedef void (*FN_MESSAGEEND)();
-typedef void (*FN_WRITEBYTE)(int iValue);
-typedef void (*FN_WRITECHAR)(int iValue);
-typedef void (*FN_WRITESHORT)(int iValue);
-typedef void (*FN_WRITELONG)(int iValue);
-typedef void (*FN_WRITEANGLE)(float flValue);
-typedef void (*FN_WRITECOORD)(float flValue);
-typedef void (*FN_WRITESTRING)(const char *sz);
-typedef void (*FN_WRITEENTITY)(int iValue);
-typedef void (*FN_CVARREGISTER)(cvar_t *pCvar);
-typedef float (*FN_CVARGETFLOAT)(const char *szVarName);
-typedef const char *(*FN_CVARGETSTRING)(const char *szVarName);
-typedef void (*FN_CVARSETFLOAT)(const char *szVarName, float flValue);
-typedef void (*FN_CVARSETSTRING)(const char *szVarName, const char *szValue);
-typedef void (*FN_ALERTMESSAGE)(ALERT_TYPE atype, const char *szFmt, ...);
-typedef void (*FN_ENGINEFPRINTF)(void *pfile, const char *szFmt, ...);
-typedef void *(*FN_PVALLOCENTPRIVATEDATA)(edict_t *pEdict, int32 cb);
-typedef void *(*FN_PVENTPRIVATEDATA)(edict_t *pEdict);
-typedef void (*FN_FREEENTPRIVATEDATA)(edict_t *pEdict);
-typedef const char *(*FN_SZFROMINDEX)(int iString);
-typedef int (*FN_ALLOCSTRING)(const char *szValue);
-typedef struct entvars_s *(*FN_GETVARSOFENT)(edict_t *pEdict);
-typedef edict_t *(*FN_PENTITYOFENTOFFSET)(int iEntOffset);
-typedef int (*FN_ENTOFFSETOFPENTITY)(const edict_t *pEdict);
-typedef int (*FN_INDEXOFEDICT)(const edict_t *pEdict);
-typedef edict_t *(*FN_PENTITYOFENTINDEX)(int iEntIndex);
-typedef edict_t *(*FN_FINDENTITYBYVARS)(struct entvars_s *pvars);
-typedef void *(*FN_GETMODELPTR)(edict_t *pEdict);
-typedef int (*FN_REGUSERMSG)(const char *pszName, int iSize);
-typedef void (*FN_ANIMATIONAUTOMOVE)(const edict_t *pEdict, float flTime);
-typedef void (*FN_GETBONEPOSITION)(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles);
-typedef uint32 (*FN_FUNCTIONFROMNAME)(const char *pName);
-typedef const char *(*FN_NAMEFORFUNCTION)(uint32 function);
-typedef void (*FN_CLIENTPRINTF)(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg);
-typedef void (*FN_SERVERPRINT)(const char *szMsg);
-typedef const char *(*FN_CMD_ARGS)();
-typedef const char *(*FN_CMD_ARGV)(int argc);
-typedef int (*FN_CMD_ARGC)();
-typedef void (*FN_GETATTACHMENT)(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles);
-typedef void (*FN_CRC32_INIT)(CRC32_t *pulCRC);
-typedef void (*FN_CRC32_PROCESSBUFFER)(CRC32_t *pulCRC, void *p, int len);
-typedef void (*FN_CRC32_PROCESSBYTE)(CRC32_t *pulCRC, unsigned char ch);
-typedef CRC32_t (*FN_CRC32_FINAL)(CRC32_t pulCRC);
-typedef int32 (*FN_RANDOMLONG)(int32 lLow, int32 lHigh);
-typedef float (*FN_RANDOMFLOAT)(float flLow, float flHigh);
-typedef void (*FN_SETVIEW)(const edict_t *pClient, const edict_t *pViewent);
-typedef float (*FN_TIME)();
-typedef void (*FN_CROSSHAIRANGLE)(const edict_t *pClient, float pitch, float yaw);
-typedef byte *(*FN_LOADFILEFORME)(char *filename, int *pLength);
-typedef void (*FN_FREEFILE)(void *buffer);
-typedef void (*FN_ENDSECTION)(const char *pszSectionName);
-typedef int (*FN_COMPAREFILETIME)(char *filename1, char *filename2, int *iCompare);
-typedef void (*FN_GETGAMEDIR)(char *szGetGameDir);
-typedef void (*FN_CVAR_REGISTERVARIABLE)(cvar_t *variable);
-typedef void (*FN_FADECLIENTVOLUME)(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds);
-typedef void (*FN_SETCLIENTMAXSPEED)(edict_t *pEdict, float fNewMaxspeed);
-typedef edict_t *(*FN_CREATEFAKECLIENT)(const char *netname);
-typedef void (*FN_RUNPLAYERMOVE)(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec);
-typedef int (*FN_NUMBEROFENTITIES)();
-typedef char *(*FN_GETINFOKEYBUFFER)(edict_t *e);
-typedef char *(*FN_INFOKEYVALUE)(char *infobuffer, const char *key);
-typedef void (*FN_SETKEYVALUE)(char *infobuffer, const char *key, const char *value);
-typedef void (*FN_SETCLIENTKEYVALUE)(int clientIndex, char *infobuffer, const char *key, const char *value);
-typedef int (*FN_ISMAPVALID)(char *filename);
-typedef void (*FN_STATICDECAL)(const float *origin, int decalIndex, int entityIndex, int modelIndex);
-typedef int (*FN_PRECACHEGENERIC)(char *s);
-typedef int (*FN_GETPLAYERUSERID)(edict_t *e);
-typedef void (*FN_BUILDSOUNDMSG)(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
-typedef int (*FN_ISDEDICATEDSERVER)();
-typedef cvar_t *(*FN_CVARGETPOINTER)(const char *szVarName);
-typedef unsigned int (*FN_GETPLAYERWONID)(edict_t *e);
-typedef void (*FN_INFO_REMOVEKEY)(char *s, const char *key);
-typedef const char *(*FN_GETPHYSICSKEYVALUE)(const edict_t *pClient, const char *key);
-typedef void (*FN_SETPHYSICSKEYVALUE)(const edict_t *pClient, const char *key, const char *value);
-typedef const char *(*FN_GETPHYSICSINFOSTRING)(const edict_t *pClient);
-typedef unsigned short (*FN_PRECACHEEVENT)(int type, const char *psz);
-typedef void (*FN_PLAYBACKEVENT)(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2);
-typedef unsigned char *(*FN_SETFATPVS)(float *org);
-typedef unsigned char *(*FN_SETFATPAS)(float *org);
-typedef int (*FN_CHECKVISIBILITY)(edict_t *entity, unsigned char *pset);
-typedef void (*FN_DELTASETFIELD)(struct delta_s *pFields, const char *fieldname);
-typedef void (*FN_DELTAUNSETFIELD)(struct delta_s *pFields, const char *fieldname);
-typedef void (*FN_DELTAADDENCODER)(char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to));
-typedef int (*FN_GETCURRENTPLAYER)();
-typedef int (*FN_CANSKIPPLAYER)(const edict_t *player);
-typedef int (*FN_DELTAFINDFIELD)(struct delta_s *pFields, const char *fieldname);
-typedef void (*FN_DELTASETFIELDBYINDEX)(struct delta_s *pFields, int fieldNumber);
-typedef void (*FN_DELTAUNSETFIELDBYINDEX)(struct delta_s *pFields, int fieldNumber);
-typedef void (*FN_SETGROUPMASK)(int mask, int op);
-typedef int (*FN_CREATEINSTANCEDBASELINE)(int classname, struct entity_state_s *baseline);
-typedef void (*FN_CVAR_DIRECTSET)(struct cvar_s *var, const char *value);
-typedef void (*FN_FORCEUNMODIFIED)(FORCE_TYPE type, float *mins, float *maxs, const char *filename);
-typedef void (*FN_GETPLAYERSTATS)(const edict_t *pClient, int *ping, int *packet_loss);
-typedef void (*FN_ADDSERVERCOMMAND)(char *cmd_name, void (*function)());
-typedef qboolean (*FN_VOICE_GETCLIENTLISTENING)(int iReceiver, int iSender);
-typedef qboolean (*FN_VOICE_SETCLIENTLISTENING)(int iReceiver, int iSender, qboolean bListen);
-typedef const char *(*FN_GETPLAYERAUTHID)(edict_t *e);
-typedef sequenceEntry_s *(*FN_SEQUENCEGET)(const char *fileName, const char *entryName);
-typedef sentenceEntry_s *(*FN_SEQUENCEPICKSENTENCE)(const char *groupName, int pickMethod, int *picked);
-typedef int (*FN_GETFILESIZE)(char *filename);
-typedef unsigned int (*FN_GETAPPROXWAVEPLAYLEN)(const char *filepath);
-typedef int (*FN_ISCAREERMATCH)();
-typedef int (*FN_GETLOCALIZEDSTRINGLENGTH)(const char *label);
-typedef void (*FN_REGISTERTUTORMESSAGESHOWN)(int mid);
-typedef int (*FN_GETTIMESTUTORMESSAGESHOWN)(int mid);
-typedef void (*FN_PROCESSTUTORMESSAGEDECAYBUFFER)(int *buffer, int bufferLength);
-typedef void (*FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER)(int *buffer, int bufferLength);
-typedef void (*FN_RESETTUTORMESSAGEDECAYDATA)();
-typedef void (*FN_QUERYCLIENTCVARVALUE)(const edict_t *pEdict, const char *cvarName); // Use FN_QUERYCLIENTCVARVALUE2 instead
-typedef void (*FN_QUERYCLIENTCVARVALUE2)(const edict_t *pEdict, const char *cvarName, int requestID);
-typedef int (*FN_CHECKPARM)(const char *pchCmdLineToken, char **ppnext);
+void compile_engine_callbacks();
diff --git a/metamod/src/game_support.cpp b/metamod/src/game_support.cpp
index 86ef3bb..2dd35a9 100644
--- a/metamod/src/game_support.cpp
+++ b/metamod/src/game_support.cpp
@@ -10,7 +10,7 @@ const game_modinfo_t known_games[] = {
// Previously enumerated in this sourcefile, the list is now kept in a
// separate file, generated based on game information stored in a
// convenient db.
- { "cstrike", "cs.so", "mp.dll", "Counter-Strike" },
+ { "cstrike", "cs.so", "mp.dll", "Counter-Strike" },
{ "czero", "cs.so", "mp.dll", "Counter-Strike:Condition Zero" },
// End of list terminator:
@@ -22,7 +22,7 @@ inline const game_modinfo_t *lookup_game(const char *name)
{
for (auto& known : known_games)
{
- if (known.name && Q_stricmp(known.name, name))
+ if (known.name && !Q_stricmp(known.name, name))
return &known;
}
@@ -31,13 +31,13 @@ inline const game_modinfo_t *lookup_game(const char *name)
}
// Installs gamedll from Steam cache
-mBOOL install_gamedll(char *from, const char *to)
+bool install_gamedll(char *from, const char *to)
{
int length_in;
int length_out;
if (!from)
- return mFALSE;
+ return false;
if (!to)
to = from;
@@ -52,7 +52,7 @@ mBOOL install_gamedll(char *from, const char *to)
{
META_DEBUG(3, ("Installing gamedll from cache: Failed to create file %s: %s", to, strerror(errno)) );
FREE_FILE(cachefile);
- return mFALSE;
+ return false;
}
length_out = Q_write(fd, cachefile, length_in);
@@ -68,7 +68,7 @@ mBOOL install_gamedll(char *from, const char *to)
if (length_out >= 0)
_unlink(to);
- return mFALSE;
+ return false;
}
META_LOG("Installed gamedll %s from cache.", to);
@@ -76,10 +76,10 @@ mBOOL install_gamedll(char *from, const char *to)
else
{
META_DEBUG(3, ("Failed to install gamedll from cache: file %s not found in cache.", from));
- return mFALSE;
+ return false;
}
- return mTRUE;
+ return true;
}
// Set all the fields in the gamedll struct, - based either on an entry in
@@ -88,7 +88,7 @@ mBOOL install_gamedll(char *from, const char *to)
//
// meta_errno values:
// - ME_NOTFOUND couldn't recognize game
-mBOOL setup_gamedll(gamedll_t *gamedll)
+bool setup_gamedll(gamedll_t *gamedll)
{
const game_modinfo_t *known;
const char *knownfn = nullptr;
@@ -121,7 +121,7 @@ mBOOL setup_gamedll(gamedll_t *gamedll)
else
{
// Neither known-list found a gamedll.
- RETURN_ERRNO(mFALSE, ME_NOTFOUND);
+ RETURN_ERRNO(false, ME_NOTFOUND);
}
Q_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
@@ -141,5 +141,5 @@ mBOOL setup_gamedll(gamedll_t *gamedll)
gamedll->desc = known->desc;
META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file);
- return mTRUE;
+ return true;
}
diff --git a/metamod/src/game_support.h b/metamod/src/game_support.h
index e564570..9c89d2d 100644
--- a/metamod/src/game_support.h
+++ b/metamod/src/game_support.h
@@ -13,4 +13,4 @@ struct game_modinfo_t
const char *desc; // our long-name description
};
-mBOOL setup_gamedll(gamedll_t *gamedll);
+bool setup_gamedll(gamedll_t *gamedll);
diff --git a/metamod/src/h_export.cpp b/metamod/src/h_export.cpp
index a2d517b..789fd1b 100644
--- a/metamod/src/h_export.cpp
+++ b/metamod/src/h_export.cpp
@@ -57,31 +57,3 @@ void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, globalvars_t *pG
// Load plugins, load game dll.
metamod_startup();
}
-
-// Avoid linking to libstdc++
-#if defined(linux)
-extern "C" void __cxa_pure_virtual(void)
-{
-}
-
-void *operator new(size_t size)
-{
- return Q_malloc(size);
-}
-
-void *operator new[](size_t size)
-{
- return Q_malloc(size);
-}
-
-void operator delete(void *ptr)
-{
- Q_free(ptr);
-}
-
-void operator delete[](void * ptr)
-{
- Q_free(ptr);
-}
-#endif
-
diff --git a/metamod/src/jitasm.h b/metamod/src/jitasm.h
new file mode 100644
index 0000000..f74840d
--- /dev/null
+++ b/metamod/src/jitasm.h
@@ -0,0 +1,8968 @@
+// Copyright (c) 2009-2011, Hikaru Inoue, Akihiro Yamasaki,
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * The names of the contributors may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+#ifndef JITASM_H
+#define JITASM_H
+
+#if defined(_WIN32)
+#define JITASM_WIN // Windows
+#endif
+
+#if (defined(_WIN64) && (defined(_M_AMD64) || defined(_M_X64))) || defined(__x86_64__)
+#define JITASM64
+#endif
+
+#if defined(__GNUC__)
+#define JITASM_GCC
+#endif
+
+#if !defined(JITASM_MMINTRIN)
+ #if !defined(__GNUC__) || defined(__MMX__)
+ #define JITASM_MMINTRIN 1
+ #else
+ #define JITASM_MMINTRIN 0
+ #endif
+#endif
+#if !defined(JITASM_XMMINTRIN)
+ #if !defined(__GNUC__) || defined(__SSE__)
+ #define JITASM_XMMINTRIN 1
+ #else
+ #define JITASM_XMMINTRIN 0
+ #endif
+#endif
+#if !defined(JITASM_EMMINTRIN)
+ #if !defined(__GNUC__) || defined(__SSE2__)
+ #define JITASM_EMMINTRIN 1
+ #else
+ #define JITASM_EMMINTRIN 0
+ #endif
+#endif
+
+
+#include
+#include
+#include
+#include