Merge pull request #115 from Mauler125/nvidia_reflex_markers

NVIDIA latency marker implementation
This commit is contained in:
Kawe Mazidjatari 2023-12-25 19:39:14 +01:00 committed by GitHub
commit 8791745ad4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1651 additions and 315 deletions

View File

@ -28,6 +28,8 @@ ConVar* fps_max_rt = nullptr;
ConVar* fps_max_rt_tolerance = nullptr;
ConVar* fps_max_rt_sleep_threshold = nullptr;
ConVar* fps_max_gfx = nullptr;
ConVar* in_syncRT = nullptr;
#endif // !DEDICATED
ConVar* base_tickinterval_sp = nullptr;
@ -75,6 +77,7 @@ ConVar* r_visualizetraces_duration = nullptr;
ConVar* gfx_nvnUseLowLatency = nullptr;
ConVar* gfx_nvnUseLowLatencyBoost = nullptr;
ConVar* gfx_nvnUseMarkersToOptimize = nullptr;
#endif // !DEDICATED
ConVar* stream_overlay = nullptr;
@ -337,8 +340,9 @@ void ConVar_StaticInit(void)
fps_max_rt_sleep_threshold = ConVar::StaticCreate("fps_max_rt_sleep_threshold", "0.016666667", FCVAR_RELEASE, "Frame limiter starts to sleep when frame time exceeds this threshold.", true, 0.f, false, 0.f, nullptr, nullptr);
fps_max_gfx = ConVar::StaticCreate("fps_max_gfx", "0", FCVAR_RELEASE, "Frame rate limiter using NVIDIA Reflex Low Latency SDK. -1 indicates use the desktop refresh. 0 is disabled.", true, -1.f, true, 295.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseLowLatency = ConVar::StaticCreate("gfx_nvnUseLowLatency" , "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency SDK." , false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseLowLatencyBoost = ConVar::StaticCreate("gfx_nvnUseLowLatencyBoost", "0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseLowLatency = ConVar::StaticCreate("gfx_nvnUseLowLatency" , "1", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency SDK." , false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseLowLatencyBoost = ConVar::StaticCreate("gfx_nvnUseLowLatencyBoost" , "0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Enables NVIDIA Reflex Low Latency Boost.", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
gfx_nvnUseMarkersToOptimize = ConVar::StaticCreate("gfx_nvnUseMarkersToOptimize", "0", FCVAR_RELEASE | FCVAR_ARCHIVE, "Use NVIDIA Reflex Low Latency markers to optimize (requires Low Latency Boost to be enabled).", false, 0.f, false, 0.f, &GFX_NVN_Changed_f, nullptr);
#endif // !DEDICATED
//-------------------------------------------------------------------------
@ -563,6 +567,7 @@ void ConVar_InitShipped(void)
#ifndef DEDICATED
miles_language = g_pCVar->FindVar("miles_language");
rui_defaultDebugFontFace = g_pCVar->FindVar("rui_defaultDebugFontFace");
in_syncRT = g_pCVar->FindVar("in_syncRT");
r_visualizetraces = g_pCVar->FindVar("r_visualizetraces");
r_visualizetraces_duration = g_pCVar->FindVar("r_visualizetraces_duration");
#endif // !DEDICATED

View File

@ -19,6 +19,8 @@ extern ConVar* fps_max_rt;
extern ConVar* fps_max_rt_tolerance;
extern ConVar* fps_max_rt_sleep_threshold;
extern ConVar* fps_max_gfx;
extern ConVar* in_syncRT;
#endif // !DEDICATED
extern ConVar* base_tickinterval_sp;
@ -66,6 +68,7 @@ extern ConVar* r_visualizetraces_duration;
extern ConVar* gfx_nvnUseLowLatency;
extern ConVar* gfx_nvnUseLowLatencyBoost;
extern ConVar* gfx_nvnUseMarkersToOptimize;
#endif // !DEDICATED
extern ConVar* stream_overlay;

View File

@ -0,0 +1,52 @@
//========= Copyright 1996-2004, Valve LLC, All rights reserved. ============
//
// Purpose: Win32 replacements for XBox.
//
//=============================================================================
#if !defined( XBOXSTUBS_H ) && !defined( _X360 )
#define XBOXSTUBS_H
typedef enum
{
XK_BUTTON_UP,
XK_BUTTON_DOWN,
XK_BUTTON_LEFT,
XK_BUTTON_RIGHT,
XK_BUTTON_START,
XK_BUTTON_BACK,
XK_BUTTON_STICK1,
XK_BUTTON_STICK2,
XK_BUTTON_A,
XK_BUTTON_B,
XK_BUTTON_X,
XK_BUTTON_Y,
XK_BUTTON_LEFT_SHOULDER,
XK_BUTTON_RIGHT_SHOULDER,
XK_XBUTTON_LTRIGGER_PARTIAL,
XK_XBUTTON_LTRIGGER_FULL,
XK_XBUTTON_RTRIGGER_PARTIAL,
XK_XBUTTON_RTRIGGER_FULL,
XK_STICK1_UP,
XK_STICK1_DOWN,
XK_STICK1_LEFT,
XK_STICK1_RIGHT,
XK_STICK2_UP,
XK_STICK2_DOWN,
XK_STICK2_LEFT,
XK_STICK2_RIGHT,
XK_UP_DOWN,
XK_LEFT_RIGHT,
XK_MAX_KEYS,
} xKey_t;
#endif // XBOXSTUBS_H

View File

@ -96,13 +96,15 @@
#include "engine/sys_utils.h"
#ifndef DEDICATED
#include "engine/sys_getmodes.h"
#include "engine/gl_rmain.h"
#include "engine/sys_mainwind.h"
#include "engine/matsys_interface.h"
#include "engine/gl_rmain.h"
#include "engine/gl_matsysiface.h"
#include "engine/gl_drawlights.h"
#include "engine/gl_screen.h"
#include "engine/gl_rsurf.h"
#include "engine/debugoverlay.h"
#include "engine/keys.h"
#endif // !DEDICATED
#include "vscript/languages/squirrel_re/include/squirrel.h"
#include "vscript/languages/squirrel_re/include/sqvm.h"
@ -581,6 +583,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VGL_RMain);
REGISTER(VMatSys_Interface);
REGISTER(VGL_MatSysIFace);
REGISTER(VGL_DrawLights);
REGISTER(VGL_Screen);
#endif // !DEDICATED
@ -591,6 +594,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VGL_RSurf);
REGISTER(VDebugOverlay); // !TODO: This also needs to be exposed to server dll!!!
REGISTER(VKeys);
#endif // !DEDICATED
// VScript

View File

@ -60,6 +60,7 @@
#include "tier0/module.h"
#include "tier0/basetypes.h"
#include "tier0/platform.h"
#include "tier0/platwindow.h"
#include "tier0/annotations.h"
#include "tier0/commonmacros.h"
#include "tier0/memalloc.h"
@ -67,6 +68,7 @@
#include "tier0/dbg.h"
// Tier1 includes.
#include "tier1/tier1.h"
#include "tier1/cvar.h"
#include "tier1/cmd.h"
#include "common/global.h"

View File

@ -26,9 +26,16 @@ add_sources( SOURCE_GROUP "Debug"
"debugoverlay.h"
)
add_sources( SOURCE_GROUP "Input"
"keys.cpp"
"keys.h"
)
add_sources( SOURCE_GROUP "Render"
"framelimit.cpp"
"framelimit.h"
"gl_drawlights.cpp"
"gl_drawlights.h"
"gl_matsysiface.h"
"gl_model_private.h"
"gl_rmain.cpp"
@ -187,6 +194,7 @@ add_sources( SOURCE_GROUP "Common"
"${ENGINE_SOURCE_DIR}/common/qlimits.h"
"${ENGINE_SOURCE_DIR}/common/sdkdefs.h"
"${ENGINE_SOURCE_DIR}/common/x86defs.h"
"${ENGINE_SOURCE_DIR}/common/xbox/xboxstubs.h"
)
file( GLOB ENGINE_PUBLIC_HEADERS

View File

@ -15,15 +15,71 @@
#include "geforce/reflex.h"
#include "vengineclient_impl.h"
#include "cdll_engine_int.h"
#include "materialsystem/cmaterialsystem.h"
/*****************************************************************************/
#ifndef DEDICATED
//-----------------------------------------------------------------------------
// Purpose: pre frame stage notify hook
//-----------------------------------------------------------------------------
void FrameStageNotify_Pre(const ClientFrameStage_t frameStage)
{
switch (frameStage)
{
case ClientFrameStage_t::FRAME_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_END:
break;
case ClientFrameStage_t::FRAME_RENDER_START:
break;
case ClientFrameStage_t::FRAME_RENDER_END:
break;
case ClientFrameStage_t::FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE:
break;
}
}
//-----------------------------------------------------------------------------
// Purpose: post frame stage notify hook
//-----------------------------------------------------------------------------
void FrameStageNotify_Post(const ClientFrameStage_t frameStage)
{
switch (frameStage)
{
case ClientFrameStage_t::FRAME_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_START:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END:
break;
case ClientFrameStage_t::FRAME_NET_UPDATE_END:
break;
case ClientFrameStage_t::FRAME_RENDER_START:
break;
case ClientFrameStage_t::FRAME_RENDER_END:
GFX_SetLatencyMarker(D3D11Device(), SIMULATION_END, MaterialSystem()->GetCurrentFrameCount());
break;
case ClientFrameStage_t::FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE:
break;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CHLClient::FrameStageNotify(CHLClient* pHLClient, ClientFrameStage_t frameStage)
{
FrameStageNotify_Pre(frameStage);
CHLClient_FrameStageNotify(pHLClient, frameStage);
FrameStageNotify_Post(frameStage);
}
//-----------------------------------------------------------------------------

View File

@ -0,0 +1,13 @@
#include "gl_drawlights.h"
void DrawLightSprites(void* unkType)
{
v_DrawLightSprites(unkType);
}
void VGL_DrawLights::Detour(const bool bAttach) const
{
// Enable if needed.
//DetourSetup(&v_DrawLightSprites, &DrawLightSprites, bAttach);
}

View File

@ -0,0 +1,23 @@
#pragma once
inline CMemory p_DrawLightSprites;
inline void(*v_DrawLightSprites)(void*);
///////////////////////////////////////////////////////////////////////////////
class VGL_DrawLights : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("DrawLightSprites", p_DrawLightSprites.GetPtr());
}
virtual void GetFun(void) const
{
p_DrawLightSprites = g_GameDll.FindPatternSIMD("48 8B C4 55 57 48 8D 68 A1 48 81 EC ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ??");
v_DrawLightSprites = p_DrawLightSprites.RCast<void(*)(void*)>();
}
virtual void GetVar(void) const { }
virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const;
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -6,7 +6,16 @@
//===========================================================================//
#include "core/stdafx.h"
#include "tier1/cvar.h"
#include "windows/id3dx.h"
#include "geforce/reflex.h"
#include "engine/gl_rsurf.h"
#include <materialsystem/cmaterialsystem.h>
void* R_DrawDepthOfField(const float scalar)
{
GFX_SetLatencyMarker(D3D11Device(), RENDERSUBMIT_START, MaterialSystem()->GetCurrentFrameCount());
return V_DrawDepthOfField(scalar);
}
void* R_DrawWorldMeshes(void* baseEntity, void* renderContext, DrawWorldLists_t worldLists)
{
@ -34,6 +43,7 @@ void* R_DrawWorldMeshesDepthAtTheEnd(void* ptr1, void* ptr2, void* ptr3, DrawWor
void VGL_RSurf::Detour(const bool bAttach) const
{
DetourSetup(&V_DrawDepthOfField, &R_DrawDepthOfField, bAttach);
DetourSetup(&V_DrawWorldMeshes, &R_DrawWorldMeshes, bAttach);
DetourSetup(&V_DrawWorldMeshesDepthOnly, &R_DrawWorldMeshesDepthOnly, bAttach);
DetourSetup(&V_DrawWorldMeshesDepthAtTheEnd, &R_DrawWorldMeshesDepthAtTheEnd, bAttach);

View File

@ -1,6 +1,9 @@
#pragma once
#include "public/ivrenderview.h"
inline CMemory P_DrawDepthOfField;
inline void*(*V_DrawDepthOfField)(const float scalar);
inline CMemory P_DrawWorldMeshes;
inline void*(*V_DrawWorldMeshes)(void* baseEntity, void* renderContext, DrawWorldLists_t worldLists);
@ -15,12 +18,14 @@ class VGL_RSurf : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("R_DrawDepthOfField", P_DrawDepthOfField.GetPtr());
LogFunAdr("R_DrawWorldMeshes", P_DrawWorldMeshes.GetPtr());
LogFunAdr("R_DrawWorldMeshesDepthOnly", P_DrawWorldMeshesDepthOnly.GetPtr());
LogFunAdr("R_DrawWorldMeshesDepthAtTheEnd", P_DrawWorldMeshesDepthAtTheEnd.GetPtr());
}
virtual void GetFun(void) const
{
P_DrawDepthOfField = g_GameDll.FindPatternSIMD("48 83 EC 48 0F 28 E8");
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
P_DrawWorldMeshes = g_GameDll.FindPatternSIMD("48 8B C4 48 89 48 08 53 48 83 EC 70");
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
@ -29,6 +34,7 @@ class VGL_RSurf : public IDetour
P_DrawWorldMeshesDepthOnly = g_GameDll.FindPatternSIMD("40 56 57 B8 ?? ?? ?? ??");
P_DrawWorldMeshesDepthAtTheEnd = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9");
V_DrawDepthOfField = P_DrawDepthOfField.RCast<void* (*)(const float)>();
V_DrawWorldMeshes = P_DrawWorldMeshes.RCast<void* (*)(void*, void*, DrawWorldLists_t)>(); /*48 8B C4 48 89 48 08 53 57 41 55*/
V_DrawWorldMeshesDepthOnly = P_DrawWorldMeshesDepthOnly.RCast<void* (*)(void*, DrawWorldLists_t)>(); /*40 56 57 B8 ?? ?? ?? ??*/
V_DrawWorldMeshesDepthAtTheEnd = P_DrawWorldMeshesDepthAtTheEnd.RCast<void* (*)(void*, void*, void*, DrawWorldLists_t)>(); /*48 89 5C 24 ?? 48 89 74 24 ? 57 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 41 8B F9*/

View File

@ -9,7 +9,10 @@
#include "tier0/frametask.h"
#include "engine/host.h"
#ifndef DEDICATED
#include "windows/id3dx.h"
#include "geforce/reflex.h"
#include "vgui/vgui_debugpanel.h"
#include <materialsystem/cmaterialsystem.h>
#endif // !DEDICATED
CCommonHostState* g_pCommonHostState = nullptr;
@ -30,6 +33,23 @@ void CCommonHostState::SetWorldModel(model_t* pModel)
}
}
/*
==================
Host_CountRealTimePackets
Counts the number of
packets in non-prescaled
clock frames (does not
count for bots or Terminal
Services environments)
==================
*/
void Host_CountRealTimePackets()
{
v_Host_CountRealTimePackets();
GFX_SetLatencyMarker(D3D11Device(), SIMULATION_START, MaterialSystem()->GetCurrentFrameCount());
}
/*
==================
_Host_RunFrame
@ -77,6 +97,7 @@ void _Host_Error(const char* error, ...)
void VHost::Detour(const bool bAttach) const
{
DetourSetup(&v_Host_RunFrame, &_Host_RunFrame, bAttach);
DetourSetup(&v_Host_CountRealTimePackets, &Host_CountRealTimePackets, bAttach);
#ifndef DEDICATED // Dedicated already logs this!
DetourSetup(&v_Host_Error, &_Host_Error, bAttach);

View File

@ -4,8 +4,11 @@
inline CMemory p_Host_RunFrame;
inline void(*v_Host_RunFrame)(void* unused, float time);
//inline CMemory p_Host_RunFrame_Render; // DEDICATED PATCH!
//inline void(*v_Host_RunFrame_Render)(void);
inline CMemory p_Host_RunFrame_Render;
inline void(*v_Host_RunFrame_Render)(void);
inline CMemory p_Host_CountRealTimePackets;
inline void(*v_Host_CountRealTimePackets)(void);
inline CMemory p_Host_ShouldRun;
inline bool(*v_Host_ShouldRun)();
@ -54,7 +57,8 @@ class VHost : public IDetour
virtual void GetAdr(void) const
{
LogFunAdr("_Host_RunFrame", p_Host_RunFrame.GetPtr());
//LogFunAdr("_Host_RunFrame_Render", p_Host_RunFrame_Render.GetPtr());
LogFunAdr("_Host_RunFrame_Render", p_Host_RunFrame_Render.GetPtr());
LogFunAdr("Host_CountRealTimePackets", p_Host_CountRealTimePackets.GetPtr());
LogFunAdr("Host_ShouldRun", p_Host_ShouldRun.GetPtr());
LogFunAdr("Host_Error", p_Host_Error.GetPtr());
//LogFunAdr("VCR_EnterPausedState", p_VCR_EnterPausedState.GetPtr());
@ -69,16 +73,18 @@ class VHost : public IDetour
{
p_Host_RunFrame = g_GameDll.FindPatternSIMD("48 8B C4 48 89 58 18 48 89 70 20 F3 0F 11 48 ??");
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
//p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 33 FF");
p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 33 FF");
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
//p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 34");
p_Host_RunFrame_Render = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 85 C9 75 34");
#endif
p_Host_CountRealTimePackets = g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 65 48 8B 04 25 ?? ?? ?? ?? 33 DB");
p_Host_ShouldRun = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 05 ?? ?? ?? ?? 83 78 6C 00 75 07 B0 01");
p_Host_Error = g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 48 89 54 24 ?? 4C 89 44 24 ?? 4C 89 4C 24 ?? 53 57 48 81 EC ?? ?? ?? ??");
//p_VCR_EnterPausedState = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 65 48 8B 04 25 ?? ?? ?? ?? BB ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ??");
v_Host_RunFrame = p_Host_RunFrame.RCast<void(*)(void*, float)>();
//v_Host_RunFrame_Render = p_Host_Error.RCast<void(*)(void)>();
v_Host_RunFrame_Render = p_Host_RunFrame_Render.RCast<void(*)(void)>();
v_Host_CountRealTimePackets = p_Host_CountRealTimePackets.RCast<void(*)(void)>();
v_Host_ShouldRun = p_Host_ShouldRun.RCast<bool(*)()>();
v_Host_Error = p_Host_Error.RCast<void(*)(const char*, ...)>();
//v_VCR_EnterPausedState = p_VCR_EnterPausedState.RCast<void(*)(void)>();

View File

@ -19,7 +19,13 @@ extern EngineParms_t* g_pEngineParms;
/* ==== HOST ============================================================================================================================================================ */
inline CMemory p_Host_Init;
inline void*(*v_Host_Init)(bool* bDedicated);
inline void(*v_Host_Init)();
inline CMemory p_Host_Init_DuringVideo;
inline void(*v_Host_Init_DuringVideo)(bool* bDedicated);
inline CMemory p_Host_Init_PostVideo;
inline void(*v_Host_Init_PostVideo)(bool* bDedicated);
inline CMemory p_Host_Shutdown;
inline void(*v_Host_Shutdown)();
@ -52,6 +58,8 @@ class VHostCmd : public IDetour
virtual void GetAdr(void) const
{
LogFunAdr("Host_Init", p_Host_Init.GetPtr());
LogFunAdr("Host_Init_DuringVideo", p_Host_Init_DuringVideo.GetPtr());
LogFunAdr("Host_Init_PostVideo", p_Host_Init_PostVideo.GetPtr());
LogFunAdr("Host_Shutdown", p_Host_Shutdown.GetPtr());
LogFunAdr("Host_Disconnect", p_Host_Disconnect.GetPtr());
LogFunAdr("Host_NewGame", p_Host_NewGame.GetPtr());
@ -65,26 +73,30 @@ class VHostCmd : public IDetour
}
virtual void GetFun(void) const
{
p_Host_Init = g_GameDll.FindPatternSIMD("88 4C 24 08 53 55 56 57 48 83 EC 68");
#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1)
p_Host_Init = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9 FF 15 ?? ?? ?? ??");
p_Host_Init_DuringVideo = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9 FF 15 ?? ?? ?? ??");
p_Host_NewGame = g_GameDll.FindPatternSIMD("48 8B C4 56 41 54 41 57 48 81 EC ?? ?? ?? ?? F2 0F 10 05 ?? ?? ?? ??");
p_Host_Disconnect = g_GameDll.FindPatternSIMD("48 83 EC 38 48 89 7C 24 ?? 0F B6 F9");
p_Host_ChangeLevel = g_GameDll.FindPatternSIMD("40 53 56 41 56 48 81 EC ?? ?? ?? ?? 49 8B D8");
p_SetLaunchOptions = g_GameDll.FindPatternSIMD("48 89 6C 24 ?? 57 48 83 EC 20 48 8B E9 48 8B 0D ?? ?? ?? ??");
#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3)
p_Host_Init = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9");
p_Host_Init_DuringVideo = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9");
p_Host_NewGame = g_GameDll.FindPatternSIMD("48 8B C4 ?? 41 54 41 55 48 81 EC 70 04 ?? ?? F2 0F 10 05 ?? ?? ?? 0B");
p_Host_Disconnect = g_GameDll.FindPatternSIMD("40 53 48 83 EC 30 0F B6 D9");
p_Host_ChangeLevel = g_GameDll.FindPatternSIMD("40 56 57 41 56 48 81 EC ?? ?? ?? ??");
p_SetLaunchOptions = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 57 48 83 EC 20 48 8B 1D ?? ?? ?? ?? 48 8B E9 48 85 DB");
#endif
p_Host_Init_PostVideo = g_GameDll.FindPatternSIMD("48 8B C4 41 56 48 81 EC ?? ?? ?? ?? 45 33 F6");
p_Host_Shutdown = g_GameDll.FindPatternSIMD("48 8B C4 48 83 EC ?? 80 3D ?? ?? ?? ?? ?? 0F 85 ?? ?? ?? ?? 8B 15 ?? ?? ?? ??");
p_Host_Status_PrintClient = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 60 48 8B A9 ?? ?? ?? ??");
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
p_DFS_InitializeFeatureFlagDefinitions = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 40 38 3D ?? ?? ?? ?? 48 8D 15 ?? ?? ?? ?? 48 8B CE").FollowNearCallSelf();
v_DFS_InitializeFeatureFlagDefinitions = p_DFS_InitializeFeatureFlagDefinitions.RCast<bool (*)(const char*)>(); /*48 8B C4 55 53 48 8D 68 E8*/
#endif // !(GAMEDLL_S0) || !(GAMEDLL_S1) || !(GAMEDLL_S2)
v_Host_Init = p_Host_Init.RCast<void* (*)(bool*)>(); /*48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9*/
v_Host_Init = p_Host_Init.RCast<void (*)()>();
v_Host_Init_DuringVideo = p_Host_Init_DuringVideo.RCast<void (*)(bool*)>(); /*48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 2B E0 48 8B D9*/
v_Host_Init_PostVideo = p_Host_Init_PostVideo.RCast<void (*)(bool*)>();
v_Host_Shutdown = p_Host_Shutdown.RCast<void (*)()>();
v_Host_NewGame = p_Host_NewGame.RCast<bool (*)(char*, char*, bool, char, LARGE_INTEGER)>(); /*48 8B C4 ?? 41 54 41 55 48 81 EC 70 04 00 00 F2 0F 10 05 ?? ?? ?? 0B*/
v_Host_Disconnect = p_Host_Disconnect.RCast<void (*)(bool)>();

36
src/engine/keys.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "keys.h"
#include "windows/id3dx.h"
#include "geforce/reflex.h"
#include <materialsystem/cmaterialsystem.h>
KeyInfo_t* g_pKeyInfo = nullptr;
ButtonCode_t* g_pKeyEventTicks = nullptr;
short* g_nKeyEventCount = nullptr;
bool Input_Event(const InputEvent_t& inputEvent, const int noKeyUpCheck)
{
bool runTriggerMarker = inputEvent.m_nData == ButtonCode_t::MOUSE_LEFT;
const KeyInfo_t& keyInfo = g_pKeyInfo[inputEvent.m_nData];
if (noKeyUpCheck)
{
const int v = (inputEvent.m_nType & 0xFFFFFFFD) == 0;
if (keyInfo.m_nKeyDownTarget == v)
runTriggerMarker = false;
}
if (runTriggerMarker && (inputEvent.m_nType != IE_ButtonReleased || keyInfo.m_bTrapKeyUp))
{
GFX_SetLatencyMarker(D3D11Device(), TRIGGER_FLASH, MaterialSystem()->GetCurrentFrameCount());
}
return v_Input_Event(inputEvent, noKeyUpCheck);
}
///////////////////////////////////////////////////////////////////////////////
void VKeys::Detour(const bool bAttach) const
{
DetourSetup(&v_Input_Event, &Input_Event, bAttach);
}

81
src/engine/keys.h Normal file
View File

@ -0,0 +1,81 @@
#ifndef ENGINE_KEYS_H
#define ENGINE_KEYS_H
#include "inputsystem/ButtonCode.h"
//-----------------------------------------------------------------------------
// Keypress event
//-----------------------------------------------------------------------------
struct KeyEvent_t
{
const char* m_pCommand;
int m_nTick;
bool m_bDown;
};
//-----------------------------------------------------------------------------
// Current keypress state
//-----------------------------------------------------------------------------
struct KeyInfo_t
{
enum
{
KEY_TAPPED_BIND = 0,
KEY_HELD_BIND,
KEY_BIND_COUNT
};
const char* m_pKeyBinding[KEY_BIND_COUNT];
int m_nKeyUpTarget;
int m_nKeyDownTarget;
uint32_t m_nEventTick; // When was the event issued?
int unknown;
short m_nEventNumber; // The event number.
bool m_bKeyDown;
bool m_bEventIsButtonKey; // Is the event a button key (< ButtonCode_t::KEY_LAST)
bool m_bTrapKeyUp;
bool m_bBoundSecondKey; // Is the key bound to the second row?
short paddingMaybe;
};
inline bool (*v_Input_Event)(const InputEvent_t& inputEvent, const int noKeyUpCheck);
inline bool(*v_Key_Event)(const KeyEvent_t& keyEvent);
extern KeyInfo_t* g_pKeyInfo; // ARRAYSIZE = ButtonCode_t::BUTTON_CODE_LAST
extern ButtonCode_t* g_pKeyEventTicks; // ARRAYSIZE = ButtonCode_t::BUTTON_CODE_LAST
extern short* g_nKeyEventCount;
class VKeys : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("Input_Event", reinterpret_cast<uintptr_t>(v_Input_Event));
LogFunAdr("Key_Event", reinterpret_cast<uintptr_t>(v_Key_Event));
LogVarAdr("g_pKeyInfo", reinterpret_cast<uintptr_t>(g_pKeyInfo));
LogVarAdr("g_pKeyEventTicks", reinterpret_cast<uintptr_t>(g_pKeyEventTicks));
LogVarAdr("g_nKeyEventCount", reinterpret_cast<uintptr_t>(g_nKeyEventCount));
}
virtual void GetFun(void) const
{
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 56", v_Input_Event);
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 4C 63 41 08", v_Key_Event);
}
virtual void GetVar(void) const
{
g_pKeyInfo = g_GameDll.FindPatternSIMD("48 83 EC 28 33 D2 48 8D 0D ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 C0 C6 05 ?? ?? ?? ?? ??")
.FindPatternSelf("48 8D 0D", CMemory::Direction::DOWN, 40).ResolveRelativeAddressSelf(3, 7).RCast<KeyInfo_t*>();
CMemory l_EngineApi_PumpMessages = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 81 EC ?? ?? ?? ?? 45 33 C9");
// NOTE: g_nKeyEventCount's pattern is found earlier, thus searched for earlier to offset base for g_pKeyEventTicks.
g_nKeyEventCount = l_EngineApi_PumpMessages.FindPatternSelf("0F B7 15").ResolveRelativeAddressSelf(3, 7).RCast<short*>();
g_pKeyEventTicks = l_EngineApi_PumpMessages.FindPatternSelf("48 8D 35").ResolveRelativeAddressSelf(3, 7).RCast<ButtonCode_t*>();
}
virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const;
};
#endif // ENGINE_KEYS_H

View File

@ -17,6 +17,8 @@
#include "engine/traceinit.h"
#ifndef DEDICATED
#include "engine/sys_mainwind.h"
#include "inputsystem/inputsystem.h"
#include "vgui/vgui_baseui_interface.h"
#include "materialsystem/cmaterialsystem.h"
#include "windows/id3dx.h"
#include "client/vengineclient_impl.h"
@ -162,7 +164,61 @@ void CEngineAPI::VSetStartupInfo(CEngineAPI* pEngineAPI, StartupInfo_t* pStartup
void CEngineAPI::PumpMessages()
{
#ifndef DEDICATED
CEngineAPI_PumpMessages();
MSG msg;
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
if (in_syncRT->GetBool())
(*g_fnSyncRTWithIn)();
g_pInputSystem->PollInputState(v_UIInputEventHandler);
g_pGame->DispatchAllStoredGameMessages();
#endif // !DEDICATED
}
void CEngineAPI::UpdateLowLatencyParameters()
{
#ifndef DEDICATED
const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool();
const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool();
const bool bUseMarkersToOptimize = gfx_nvnUseMarkersToOptimize->GetBool();
float fpsMax = fps_max_gfx->GetFloat();
if (fpsMax == -1.0f)
{
const float globalFps = fps_max->GetFloat();
// Make sure the global fps limiter is 'unlimited'
// before we let the gfx frame limiter cap it to
// the desktop's refresh rate; not adhering to
// this will result in a major performance drop.
if (globalFps == 0.0f)
fpsMax = g_pGame->GetTVRefreshRate();
else
fpsMax = 0.0f; // Don't let NVIDIA limit the frame rate.
}
GFX_UpdateLowLatencyParameters(D3D11Device(), bUseLowLatencyMode,
bUseLowLatencyBoost, bUseMarkersToOptimize, fpsMax);
#endif // !DEDICATED
}
void CEngineAPI::RunLowLatencyFrame()
{
#ifndef DEDICATED
if (GFX_IsLowLatencySDKEnabled())
{
if (GFX_HasPendingLowLatencyParameterUpdates())
{
UpdateLowLatencyParameters();
}
GFX_RunLowLatencyFrame(D3D11Device());
}
#endif // !DEDICATED
}
@ -171,57 +227,35 @@ void CEngineAPI::PumpMessages()
//-----------------------------------------------------------------------------
bool CEngineAPI::MainLoop()
{
#ifndef DEDICATED
bool bRunLowLatency = false;
#endif // !DEDICATED
// Main message pump
while (true)
{
// Pump messages unless someone wants to quit
if (g_pEngine->GetQuitting() != IEngine::QUIT_NOTQUITTING)
{
if (g_pEngine->GetQuitting() != IEngine::QUIT_TODESKTOP)
if (g_pEngine->GetQuitting() != IEngine::QUIT_TODESKTOP) {
return true;
}
return false;
}
#ifndef DEDICATED
if (GFX_IsLowLatencySDKEnabled())
{
if (GFX_HasPendingLowLatencyParameterUpdates())
{
const bool bUseLowLatencyMode = gfx_nvnUseLowLatency->GetBool();
const bool bUseLowLatencyBoost = gfx_nvnUseLowLatencyBoost->GetBool();
float fpsMax = fps_max_gfx->GetFloat();
if (fpsMax == -1.0f)
{
const float globalFps = fps_max->GetFloat();
// Make sure the global fps limiter is 'unlimited'
// before we let the gfx frame limiter cap it to
// the desktop's refresh rate; not adhering to
// this will result in a major performance drop.
if (globalFps == 0.0f)
fpsMax = g_pGame->GetTVRefreshRate();
else
fpsMax = 0.0f; // Don't let NVIDIA limit the frame rate.
}
GFX_UpdateLowLatencyParameters(D3D11Device(), bUseLowLatencyMode,
bUseLowLatencyBoost, false, fpsMax);
}
GFX_RunLowLatencyFrame(D3D11Device());
if (bRunLowLatency) {
CEngineAPI::RunLowLatencyFrame();
}
CEngineAPI::PumpMessages();
#endif // !DEDICATED
if (g_pEngine->Frame())
{
#ifndef DEDICATED
// Only increment frame number if we ran an actual engine frame.
GFX_IncrementFrameNumber();
// Only run reflex if we ran an actual engine frame.
bRunLowLatency = true;
#endif // !DEDICATED
}
}

View File

@ -5,13 +5,13 @@
class CEngineAPI : public IEngineAPI
{
public:
virtual bool Connect(CreateInterfaceFn factory) = 0;
virtual bool Connect(const CreateInterfaceFn factory) = 0;
virtual void Disconnect() = 0;
virtual void* QueryInterface(const char* pInterfaceName) = 0;
virtual void* QueryInterface(const char* const pInterfaceName) = 0;
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
virtual AppSystemTier_t GetTier() = 0;
virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0;
virtual void Reconnect(const CreateInterfaceFn factory, const char* const pInterfaceName) = 0;
// This function must be called before init
virtual bool SetStartupInfo(StartupInfo_t& info) = 0;
@ -35,6 +35,9 @@ public:
static void VSetStartupInfo(CEngineAPI* pEngineAPI, StartupInfo_t* pStartupInfo);
static void PumpMessages();
static void RunLowLatencyFrame();
static void UpdateLowLatencyParameters();
static bool MainLoop();
//private:
void* m_hEditorHWnd;

View File

@ -9,6 +9,7 @@
#include "windows/input.h"
#include "engine/sys_mainwind.h"
#include "engine/sys_engine.h"
#include "engine/keys.h"
#include "gameui/IConsole.h"
#include "gameui/IBrowser.h"
@ -97,7 +98,7 @@ int CGame::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
//-----------------------------------------------------------------------------
// Purpose: gets the window rect
//-----------------------------------------------------------------------------
void CGame::GetWindowRect(int* x, int* y, int* w, int* h)
void CGame::GetWindowRect(int* const x, int* const y, int* const w, int* const h) const
{
if (x)
{
@ -117,6 +118,41 @@ void CGame::GetWindowRect(int* x, int* y, int* w, int* h)
}
}
//-----------------------------------------------------------------------------
// Purpose: dispatch key event
//-----------------------------------------------------------------------------
void CGame::DispatchKeyEvent(const uint64_t msTime, const ButtonCode_t buttonCode) const
{
const float duration = buttonCode == KEY_XBUTTON_BACK ? 1.0f : 0.2f;
KeyInfo_t& keyInfo = g_pKeyInfo[buttonCode];
if (keyInfo.m_bKeyDown && ((msTime - keyInfo.m_nEventTick) * 0.001f) >= duration)
{
KeyEvent_t keyEvent;
keyEvent.m_pCommand = keyInfo.m_pKeyBinding[KeyInfo_t::KEY_HELD_BIND];
keyEvent.m_nTick = buttonCode;
keyEvent.m_bDown = true;
v_Key_Event(keyEvent);
keyInfo.m_bKeyDown = true;
}
}
//-----------------------------------------------------------------------------
// Purpose: dispatch all the queued up messages
//-----------------------------------------------------------------------------
void CGame::DispatchAllStoredGameMessages() const
{
const uint64_t ticks = Plat_MSTime();
const short eventCount = *g_nKeyEventCount;
for (short i = 0; i < eventCount; i++)
{
DispatchKeyEvent(ticks, g_pKeyEventTicks[i]);
}
}
///////////////////////////////////////////////////////////////////////////////
void VGame::Detour(const bool bAttach) const
{

View File

@ -5,6 +5,7 @@
//===========================================================================//
#ifndef SYS_MAINWIND_H
#define SYS_MAINWIND_H
#include "inputsystem/iinputsystem.h"
inline CMemory p_CGame__AttachToWindow;
inline void (*v_CGame__AttachToWindow)(void);
@ -25,7 +26,7 @@ public:
inline HWND GetWindow() const { return m_hWindow; }
void GetWindowRect(int* x, int* y, int* w, int* h);
void GetWindowRect(int* const x, int* const y, int* const w, int* const h) const;
inline int GetDesktopWidth() const { return m_iDesktopWidth; }
inline int GetDesktopHeight() const { return m_iDesktopHeight; }
@ -33,6 +34,9 @@ public:
inline float GetTVRefreshRate() const // Avoid stutter on TV's running on broadcast frame rates.
{ return ((float)m_iDesktopRefreshRate == 59.0f || (float)m_iDesktopRefreshRate == 60.0f) ? 59.939999f : (float)m_iDesktopRefreshRate; }
void DispatchKeyEvent(const uint64_t msTime, const ButtonCode_t buttonCode) const;
void DispatchAllStoredGameMessages() const;
private:
HWND m_hWindow;
HINSTANCE m_hInstance;

View File

@ -16,10 +16,6 @@ bool s_ReflexModeInfoUpToDate = false;
// If not, the Low Latency SDK will not run.
NvAPI_Status s_ReflexModeUpdateStatus = NvAPI_Status::NVAPI_OK;
// Static frame number counter for latency markers.
NvU64 s_ReflexFrameNumber = 0;
NvU64 s_ReflexLastFrameNumber = 0;
//-----------------------------------------------------------------------------
// Purpose: enable/disable low latency SDK
// Input : enable -
@ -75,23 +71,6 @@ bool GFX_ParameterUpdateWasSuccessful(void)
return s_ReflexModeUpdateStatus == NvAPI_Status::NVAPI_OK;
}
//-----------------------------------------------------------------------------
// Purpose: gets the reflex frame number
// Output : int
//-----------------------------------------------------------------------------
NvU64 GFX_GetFrameNumber(void)
{
return s_ReflexFrameNumber;
}
//-----------------------------------------------------------------------------
// Purpose: increments the reflex frame number
//-----------------------------------------------------------------------------
void GFX_IncrementFrameNumber(void)
{
++s_ReflexFrameNumber;
}
//-----------------------------------------------------------------------------
// Purpose: updates the low latency parameters
// Input : *device -
@ -100,7 +79,7 @@ void GFX_IncrementFrameNumber(void)
// useMarkersToOptimize -
// maxFramesPerSecond -
//-----------------------------------------------------------------------------
void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMode,
void GFX_UpdateLowLatencyParameters(IUnknown* const device, const bool useLowLatencyMode,
const bool useLowLatencyBoost, const bool useMarkersToOptimize,
const float maxFramesPerSecond)
{
@ -125,18 +104,12 @@ void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMo
// Purpose: runs a frame of the low latency sdk
// Input : *device -
//-----------------------------------------------------------------------------
void GFX_RunLowLatencyFrame(IUnknown* device)
void GFX_RunLowLatencyFrame(IUnknown* const device)
{
Assert(device);
const NvU64 currentFrameNumber = GFX_GetFrameNumber();
if (s_ReflexLastFrameNumber == currentFrameNumber)
return;
if (GFX_ParameterUpdateWasSuccessful())
NvAPI_D3D_Sleep(device);
s_ReflexLastFrameNumber = currentFrameNumber;
}
//-----------------------------------------------------------------------------
@ -145,18 +118,21 @@ void GFX_RunLowLatencyFrame(IUnknown* device)
// frameNumber -
// markerType -
//-----------------------------------------------------------------------------
void GFX_SetLatencyMarker(IUnknown* device,
const NV_LATENCY_MARKER_TYPE markerType)
void GFX_SetLatencyMarker(IUnknown* const device,
const NV_LATENCY_MARKER_TYPE markerType, const NvU64 frameID)
{
Assert(device);
if (!GFX_IsLowLatencySDKEnabled())
return;
if (GFX_IsLowLatencySDKEnabled())
{
NV_LATENCY_MARKER_PARAMS params = {};
params.version = NV_LATENCY_MARKER_PARAMS_VER1;
params.frameID = frameID;
params.markerType = markerType;
NV_LATENCY_MARKER_PARAMS params = {};
params.version = NV_LATENCY_MARKER_PARAMS_VER1;
params.frameID = s_ReflexFrameNumber;
params.markerType = markerType;
NvAPI_D3D_SetLatencyMarker(device, &params);
}
NvAPI_D3D_SetLatencyMarker(device, &params);
// PCLStats is supported on non-NVIDIA hardware.
PCLSTATS_MARKER(markerType, frameID);
}

View File

@ -7,9 +7,6 @@ bool GFX_IsLowLatencySDKEnabled(void);
void GFX_MarkLowLatencyParametersOutOfDate(void);
bool GFX_HasPendingLowLatencyParameterUpdates(void);
NvU64 GFX_GetFrameNumber(void);
void GFX_IncrementFrameNumber(void);
void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMode,
const bool useLowLatencyBoost, const bool useMarkersToOptimize,
const float maxFramesPerSecond);
@ -17,6 +14,6 @@ void GFX_UpdateLowLatencyParameters(IUnknown* device, const bool useLowLatencyMo
void GFX_RunLowLatencyFrame(IUnknown* device);
void GFX_SetLatencyMarker(IUnknown* device,
const NV_LATENCY_MARKER_TYPE markerType);
const NV_LATENCY_MARKER_TYPE markerType, const NvU64 frameID);
#endif // GFSDK_REFLEX_H

View File

@ -9,7 +9,10 @@ add_sources( SOURCE_GROUP "Private"
)
add_sources( SOURCE_GROUP "Public"
"${ENGINE_SOURCE_DIR}/public/inputsystem/iinputsystem.h"
"${ENGINE_SOURCE_DIR}/public/inputsystem/AnalogCode.h"
"${ENGINE_SOURCE_DIR}/public/inputsystem/ButtonCode.h"
"${ENGINE_SOURCE_DIR}/public/inputsystem/InputEnums.h"
)
end_sources()

View File

@ -6,48 +6,73 @@
#include "core/stdafx.h"
#include "vpc/IAppSystem.h"
#include "windows/id3dx.h"
#include "geforce/reflex.h"
#include "inputsystem/inputsystem.h"
#include <materialsystem/cmaterialsystem.h>
//-----------------------------------------------------------------------------
// Enables/disables input
//-----------------------------------------------------------------------------
void CInputSystem::EnableInput(bool bEnabled)
////-----------------------------------------------------------------------------
//// Enables/disables input
////-----------------------------------------------------------------------------
//void CInputSystem::EnableInput(bool bEnabled)
//{
// const static int index = 10;
// CallVFunc<void>(index, this, bEnabled);
//}
//
////-----------------------------------------------------------------------------
//// Enables/disables the inputsystem windows message pump
////-----------------------------------------------------------------------------
//void CInputSystem::EnableMessagePump(bool bEnabled)
//{
// const static int index = 11;
// CallVFunc<void>(index, this, bEnabled);
//}
//
////-----------------------------------------------------------------------------
//// Poll current state
////-----------------------------------------------------------------------------
//bool CInputSystem::IsButtonDown(ButtonCode_t Button)
//{
// const static int index = 13;
// return CallVFunc<bool>(index, this, Button);
//}
//
////-----------------------------------------------------------------------------
//// Convert back + forth between ButtonCode/AnalogCode + strings
////-----------------------------------------------------------------------------
//bool CInputSystem::ButtonCodeToString(ButtonCode_t Button)
//{
// const static int index = 25;
// return CallVFunc<bool>(index, this, Button);
//}
//ButtonCode_t CInputSystem::StringToButtonCode(const char* pString)
//{
// const static int index = 26;
// return CallVFunc<ButtonCode_t>(index, this, pString);
//}
LRESULT CInputSystem::WindowProc(void* unused, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
const static int index = 10;
CallVFunc<void>(index, this, bEnabled);
if (g_pInputSystem->m_bEnabled &&
((hwnd == g_pInputSystem->m_hAttachedHWnd) || (uMsg == WM_ACTIVATEAPP)) &&
(uMsg != WM_CLOSE))
{
if (PCLSTATS_IS_PING_MSG_ID(uMsg))
{
GFX_SetLatencyMarker(D3D11Device(), PC_LATENCY_PING, MaterialSystem()->GetCurrentFrameCount());
}
}
return v_CInputSystem__WindowProc(unused, hwnd, uMsg, wParam, lParam);
}
//-----------------------------------------------------------------------------
// Enables/disables the inputsystem windows message pump
//-----------------------------------------------------------------------------
void CInputSystem::EnableMessagePump(bool bEnabled)
{
const static int index = 11;
CallVFunc<void>(index, this, bEnabled);
}
//-----------------------------------------------------------------------------
// Poll current state
//-----------------------------------------------------------------------------
bool CInputSystem::IsButtonDown(ButtonCode_t Button)
void VInputSystem::Detour(const bool bAttach) const
{
const static int index = 13;
return CallVFunc<bool>(index, this, Button);
}
//-----------------------------------------------------------------------------
// Convert back + forth between ButtonCode/AnalogCode + strings
//-----------------------------------------------------------------------------
bool CInputSystem::ButtonCodeToString(ButtonCode_t Button)
{
const static int index = 25;
return CallVFunc<bool>(index, this, Button);
}
ButtonCode_t CInputSystem::StringToButtonCode(const char* pString)
{
const static int index = 26;
return CallVFunc<ButtonCode_t>(index, this, pString);
DetourSetup(&v_CInputSystem__WindowProc, &CInputSystem::WindowProc, bAttach);
}
///////////////////////////////////////////////////////////////////////////////
CInputSystem* g_pInputSystem = nullptr;
CInputSystem* g_pInputSystem = nullptr;
bool(**g_fnSyncRTWithIn)(void) = nullptr;

View File

@ -1,40 +1,197 @@
#pragma once
#include "core/stdafx.h"
#include "inputsystem/ButtonCode.h"
#include "inputsystem/iinputsystem.h"
#include "mathlib/bitvec.h"
#include "tier1/utlstringmap.h"
#include <Xinput.h>
class CInputSystem
//-----------------------------------------------------------------------------
// Implementation of the input system
//-----------------------------------------------------------------------------
class CInputSystem : public CTier1AppSystem< IInputSystem >
{
public:
void EnableInput(bool bEnabled); // @0x14039F100 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
void EnableMessagePump(bool bEnabled); // @0x14039F110 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
bool IsButtonDown(ButtonCode_t Button); // @0x1403A0140 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
bool ButtonCodeToString(ButtonCode_t Button);
ButtonCode_t StringToButtonCode(const char* pString);
// !!!interface implemented in engine!!!
public:
// Hook statics:
static LRESULT WindowProc(void* unused, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
char pad_0000[16]; //0x0000
public:
bool m_bEnabled; //0x0010 IsInputEnabled variable.
bool m_bPumpEnabled; //0x0011 EnabledMessagePump variable.
enum
{
INPUT_STATE_QUEUED = 0,
INPUT_STATE_CURRENT,
INPUT_STATE_COUNT,
BUTTON_EVENT_COUNT = 128
};
struct xdevice_t
{
struct xvibration_t
{
float leftMainMotor;
float rightMainMotor;
float leftTriggerMotor;
float rightTriggerMotor;
};
struct unkownhiddevice_t
{
struct state_t
{
SRWLOCK lock;
char unk0[56];
xvibration_t vibration;
char unk1[48];
};
// Name might be incorrect!
state_t states[INPUT_STATE_COUNT];
HANDLE hThread0;
HANDLE hthread1;
};
int userId;
char active;
XINPUT_STATE states[INPUT_STATE_COUNT];
int newState;
xKey_t lastStickKeys[MAX_JOYSTICK_AXES-2]; // -2 as U and V aren't polled.
int unk0;
bool pendingRumbleUpdate;
_BYTE gap41[3];
xvibration_t vibration;
bool isXbox360Gamepad;
bool nonXboxDevice; // uses unknownHidDevice when set
_BYTE gap56[42];
unkownhiddevice_t unknownHidDevice;
_BYTE gap190[42];
};
static_assert(sizeof(xdevice_t) == 0x1C0);
struct appKey_t
{
int repeats;
int sample;
};
struct InputState_t
{
// Analog states
CBitVec<BUTTON_CODE_LAST> m_ButtonState;
int m_pAnalogValue[ANALOG_CODE_LAST];
};
HWND m_ChainedWndProc;
HWND m_hAttachedHWnd;
bool m_bEnabled;
bool m_bPumpEnabled;
bool m_bIsPolling;
bool m_bIMEComposing;
bool m_bMouseCursorVisible;
bool m_bJoystickCursorVisible;
bool m_bIsInGame; // Delay joystick polling if in-game.
// Current button state
InputState_t m_InputState[INPUT_STATE_COUNT];
// Current button state mutex
CRITICAL_SECTION m_InputStateMutex;
int unknown0;
short unknown1;
bool unknown2;
// Analog event mutex
CRITICAL_SECTION m_AnalogEventMutex;
int unknown3;
short unknown4;
bool unknown5;
// Analog events
InputEvent_t m_AnalogEvents[JOYSTICK_AXIS_BUTTON_COUNT];
int m_AnalogEventTypes[JOYSTICK_AXIS_BUTTON_COUNT];
// Button events
InputEvent_t m_Events[BUTTON_EVENT_COUNT];
// Current event
InputEvent_t m_CurrentEvent;
DWORD m_StartupTimeTick;
int m_nLastPollTick;
int m_nLastSampleTick;
int m_nLastAnalogPollTick;
int m_nLastAnalogSampleTick;
// Mouse wheel hack
UINT m_uiMouseWheel;
// Xbox controller info
int m_nJoystickCount;
appKey_t m_appXKeys[XUSER_MAX_COUNT][XK_MAX_KEYS];
char pad_unk[16];
xdevice_t m_XDevices[XUSER_MAX_COUNT];
// Used to determine whether to generate UI events
int m_nUIEventClientCount;
// Raw mouse input
bool m_bRawInputSupported;
CRITICAL_SECTION m_MouseAccumMutex;
int m_mouseRawAccumX;
int m_mouseRawAccumY;
_BYTE gap1785[8];
// Current mouse capture window
PlatWindow_t m_hCurrentCaptureWnd;
// For the 'SleepUntilInput' feature
HANDLE m_hEvent;
InputCursorHandle_t m_pDefaultCursors[INPUT_CURSOR_COUNT];
CUtlStringMap<InputCursorHandle_t> m_UserCursors;
CSysModule* m_pXInputDLL;
CSysModule* m_pRawInputDLL;
// NVNT falcon module
CSysModule* m_pNovintDLL; // Unused in R5?
bool m_bIgnoreLocalJoystick;
InputCursorHandle_t m_hCursor;
};
static_assert(sizeof(CInputSystem) == 0x18E8);
///////////////////////////////////////////////////////////////////////////////
inline LRESULT (*v_CInputSystem__WindowProc)(void* thisptr, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern CInputSystem* g_pInputSystem;
extern bool(**g_fnSyncRTWithIn)(void); // Belongs to an array of functions, see CMaterialSystem::MatsysMode_Init().
///////////////////////////////////////////////////////////////////////////////
class VInputSystem : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("CInputSystem::WindowProc", reinterpret_cast<uintptr_t>(v_CInputSystem__WindowProc));
LogVarAdr("g_pInputSystem", reinterpret_cast<uintptr_t>(g_pInputSystem));
LogVarAdr("g_fnSyncRTWithIn", reinterpret_cast<uintptr_t>(g_fnSyncRTWithIn));
}
virtual void GetFun(void) const
{
g_GameDll.FindPatternSIMD("48 89 4C 24 ?? 55 56 41 54 41 55 48 83 EC 48", v_CInputSystem__WindowProc);
}
virtual void GetFun(void) const { }
virtual void GetVar(void) const
{
g_pInputSystem = g_GameDll.FindPatternSIMD("48 83 EC 28 48 8B 0D ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 05 ?? ?? ?? ?? 48 85 C9 74 11")
.FindPatternSelf("48 89 05", CMemory::Direction::DOWN, 40).ResolveRelativeAddressSelf(0x3, 0x7).RCast<CInputSystem*>();
const CMemory l_EngineApi_PumpMessages = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 55 48 81 EC ?? ?? ?? ?? 45 33 C9");
g_fnSyncRTWithIn = l_EngineApi_PumpMessages.FindPattern("74 06").FindPatternSelf("FF 15").ResolveRelativeAddressSelf(2, 6).RCast<bool(**)(void)>();
}
virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const { }
virtual void Detour(const bool bAttach) const;
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -12,12 +12,13 @@
#include "engine/cmodel_bsp.h"
#include "geforce/reflex.h"
#ifndef MATERIALSYSTEM_NODX
#include "windows/id3dx.h"
#include "materialsystem/cmaterialglue.h"
#endif // !MATERIALSYSTEM_NODX
#include "materialsystem/cmaterialsystem.h"
#ifndef MATERIALSYSTEM_NODX
//PCLSTATS_DEFINE()
PCLSTATS_DEFINE()
#endif // MATERIALSYSTEM_NODX
//-----------------------------------------------------------------------------
@ -38,10 +39,10 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
// Initialize as usual.
GFX_EnableLowLatencySDK(!CommandLine()->CheckParm("-gfx_nvnDisableLowLatency"));
//if (GFX_IsLowLatencySDKEnabled())
//{
// PCLSTATS_INIT(0);
//}
if (GFX_IsLowLatencySDKEnabled())
{
PCLSTATS_INIT(0);
}
return CMaterialSystem__Init(thisptr);
#endif
@ -52,10 +53,10 @@ InitReturnVal_t CMaterialSystem::Init(CMaterialSystem* thisptr)
//-----------------------------------------------------------------------------
int CMaterialSystem::Shutdown(CMaterialSystem* thisptr)
{
//if (GFX_IsLowLatencySDKEnabled())
//{
// PCLSTATS_SHUTDOWN();
//}
if (GFX_IsLowLatencySDKEnabled())
{
PCLSTATS_SHUTDOWN();
}
return CMaterialSystem__Shutdown(thisptr);
}
@ -108,9 +109,29 @@ void* __fastcall DispatchDrawCall(int64_t a1, uint64_t a2, int a3, int a4, int64
return v_DispatchDrawCall(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14);
#endif
}
#endif // !MATERIALSYSTEM_NODX
#ifndef MATERIALSYSTEM_NODX
//---------------------------------------------------------------------------------
// Purpose: run IDXGISwapChain::Present
//---------------------------------------------------------------------------------
ssize_t SpinPresent(void)
{
// NOTE: -1 since we need to sync this with its corresponding frame, g_FrameNum
// gets incremented in CMaterialSystem::SwapBuffers, which is after the markers
// for simulation start/end and render submit start. The render thread (here)
// continues after to finish the frame.
const NvU64 frameID = (NvU64)MaterialSystem()->GetCurrentFrameCount() -1;
GFX_SetLatencyMarker(D3D11Device(), RENDERSUBMIT_END, frameID);
// TODO[ AMOS ]: move to actual Present runtime call? SpinPresent calls some
// other DX buffer copy API's before the actual Present calls is being made.
GFX_SetLatencyMarker(D3D11Device(), PRESENT_START, frameID);
const ssize_t val = v_SpinPresent();
GFX_SetLatencyMarker(D3D11Device(), PRESENT_END, frameID);
return val;
}
//-----------------------------------------------------------------------------
// Purpose: finds a material
// Input : *pMatSys -
@ -154,6 +175,7 @@ void VMaterialSystem::Detour(const bool bAttach) const
#ifndef MATERIALSYSTEM_NODX
DetourSetup(&v_StreamDB_Init, &StreamDB_Init, bAttach);
DetourSetup(&v_DispatchDrawCall, &DispatchDrawCall, bAttach);
DetourSetup(&v_SpinPresent, &SpinPresent, bAttach);
DetourSetup(&CMaterialSystem__FindMaterialEx, &CMaterialSystem::FindMaterialEx, bAttach);
#endif // !MATERIALSYSTEM_NODX
}

View File

@ -14,6 +14,13 @@ public:
static CMaterialGlue* FindMaterialEx(CMaterialSystem* pMatSys, const char* pMaterialName, uint8_t nMaterialType, int nUnk, bool bComplain);
static Vector2D GetScreenSize(CMaterialSystem* pMatSys = nullptr);
#endif // !MATERIALSYSTEM_NODX
// TODO: reverse the vftable!
inline int GetCurrentFrameCount()
{
const static int index = 74;
return CallVFunc<int>(index, this);
}
};
#ifndef MATERIALSYSTEM_NODX
@ -75,6 +82,9 @@ inline void*(*v_DispatchDrawCall)(int64_t a1, uint64_t a2, int a3, int a4, char
inline CMemory p_DispatchDrawCall;
inline void*(*v_DispatchDrawCall)(int64_t a1, uint64_t a2, int a3, int a4, int64_t a5, int a6, uint8_t a7, int64_t a8, uint32_t a9, uint32_t a10, int a11, __m128* a12, int a13, int64_t a14);
#endif
inline CMemory p_SpinPresent;
inline ssize_t(*v_SpinPresent)(void);
inline CMemory p_GetStreamOverlay;
inline void(*v_GetStreamOverlay)(const char* mode, char* buf, size_t bufSize);
@ -88,6 +98,13 @@ inline int* g_nUnfreeStreamingTextureMemory = nullptr;
inline int* g_nUnusableStreamingTextureMemory = nullptr;
#endif // !MATERIALSYSTEM_NODX
// TODO: move to materialsystem_global.h!
// TODO: reverse the vftable!
inline CMaterialSystem* MaterialSystem()
{
return g_pMaterialSystem;
}
///////////////////////////////////////////////////////////////////////////////
class VMaterialSystem : public IDetour
{
@ -100,9 +117,10 @@ class VMaterialSystem : public IDetour
#ifndef MATERIALSYSTEM_NODX
LogFunAdr("CMaterialSystem::FindMaterialEx", p_CMaterialSystem__FindMaterialEx.GetPtr());
LogFunAdr("CMaterialSystem::GetScreenSize", p_CMaterialSystem_GetScreenSize.GetPtr());
LogFunAdr("CMaterialSystem::DispatchDrawCall", p_DispatchDrawCall.GetPtr());
LogFunAdr("CMaterialSystem::GetStreamOverlay", p_GetStreamOverlay.GetPtr());
LogFunAdr("CMaterialSystem::DrawStreamOverlay", p_DrawStreamOverlay.GetPtr());
LogFunAdr("DispatchDrawCall", p_DispatchDrawCall.GetPtr());
LogFunAdr("SpinPresent", p_SpinPresent.GetPtr());
LogVarAdr("g_nTotalStreamingTextureMemory", reinterpret_cast<uintptr_t>(g_nTotalStreamingTextureMemory));
LogVarAdr("g_nUnfreeStreamingTextureMemory", reinterpret_cast<uintptr_t>(g_nUnfreeStreamingTextureMemory));
LogVarAdr("g_nUnusableStreamingTextureMemory", reinterpret_cast<uintptr_t>(g_nUnusableStreamingTextureMemory));
@ -134,6 +152,9 @@ class VMaterialSystem : public IDetour
p_DispatchDrawCall = g_GameDll.FindPatternSIMD("44 89 4C 24 ?? 44 89 44 24 ?? 48 89 4C 24 ?? 55 53 56");
v_DispatchDrawCall = p_DispatchDrawCall.RCast<void*(*)(int64_t, uint64_t, int, int, int64_t, int, uint8_t, int64_t, uint32_t, uint32_t, int, __m128*, int, int64_t )>();
#endif
p_SpinPresent = g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 8B 15 ?? ?? ?? ??");
v_SpinPresent = p_SpinPresent.RCast<ssize_t(*)(void)>();
p_GetStreamOverlay = g_GameDll.FindPatternSIMD("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 0F 84 ?? ?? ?? ?? 48 89 9C 24 ?? ?? ?? ??").FollowNearCallSelf();
v_GetStreamOverlay = p_GetStreamOverlay.RCast<void(*)(const char*, char*, size_t)>(); /*E8 ? ? ? ? 80 7C 24 ? ? 0F 84 ? ? ? ? 48 89 9C 24 ? ? ? ?*/
@ -151,7 +172,7 @@ class VMaterialSystem : public IDetour
s_pRenderContext = p_DispatchDrawCall.FindPattern("48 8B ?? ?? ?? ?? 01").ResolveRelativeAddressSelf(0x3, 0x7);
g_pMaterialAdapterMgr = p_CMaterialSystem__Disconnect.FindPattern("48 8D").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CMaterialDeviceMgr*>();
#endif // !MATERIALSYSTEM_NODX
g_pMaterialSystem = g_GameDll.FindPatternSIMD("48 8B 0D ?? ?? ?? ?? 48 85 C9 74 11 48 8B 01 48 8D 15 ?? ?? ?? ??").ResolveRelativeAddressSelf(0x3, 0x7).RCast<CMaterialSystem*>();
g_pMaterialSystem = g_GameDll.FindPatternSIMD("8B 41 28 85 C0 7F 18").FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(3, 7).RCast<CMaterialSystem*>();
}
virtual void GetCon(void) const
{

View File

@ -57,12 +57,12 @@ public:
virtual ~IAppSystem() = 0; // Prepended on each class derived class in assembly.
// Here's where the app systems get to learn about each other
virtual bool Connect(CreateInterfaceFn factory) = 0;
virtual bool Connect(const CreateInterfaceFn factory) = 0;
virtual void Disconnect() = 0;
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void* QueryInterface(const char* pInterfaceName) = 0;
virtual void* QueryInterface(const char* const pInterfaceName) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
@ -75,7 +75,7 @@ public:
virtual AppSystemTier_t GetTier() = 0;
// Reconnect to a particular interface
virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0;
virtual void Reconnect(const CreateInterfaceFn factory, const char* const pInterfaceName) = 0;
};
//-----------------------------------------------------------------------------
@ -88,12 +88,12 @@ public:
virtual ~CBaseAppSystem() = 0; // Prepended on each class derived class in assembly.
// Here's where the app systems get to learn about each other
virtual bool Connect(CreateInterfaceFn factory) = 0;
virtual bool Connect(const CreateInterfaceFn factory) = 0;
virtual void Disconnect() = 0;
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void* QueryInterface(const char* pInterfaceName) = 0;
virtual void* QueryInterface(const char* const pInterfaceName) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
@ -106,7 +106,15 @@ public:
virtual AppSystemTier_t GetTier() = 0;
// Reconnect to a particular interface
virtual void Reconnect(CreateInterfaceFn factory, const char* pInterfaceName) = 0;
virtual void Reconnect(const CreateInterfaceFn factory, const char* const pInterfaceName) = 0;
};
//-----------------------------------------------------------------------------
// Helper implementation of an IAppSystem for tier0
//-----------------------------------------------------------------------------
template< class IInterface >
class CTier0AppSystem : public CBaseAppSystem< IInterface >
{
};
#endif // IAPPSYSTEM_H

View File

@ -0,0 +1,36 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef ANALOGCODE_H
#define ANALOGCODE_H
#include "inputsystem/InputEnums.h"
//-----------------------------------------------------------------------------
// Macro to get at joystick codes
//-----------------------------------------------------------------------------
#define JOYSTICK_AXIS_INTERNAL( _joystick, _axis ) ( JOYSTICK_FIRST_AXIS + ((_joystick) * MAX_JOYSTICK_AXES) + (_axis) )
#define JOYSTICK_AXIS( _joystick, _axis ) ( (AnalogCode_t)JOYSTICK_AXIS_INTERNAL( _joystick, _axis ) )
//-----------------------------------------------------------------------------
// Enumeration for analog input devices. Includes joysticks, mousewheel, mouse
//-----------------------------------------------------------------------------
enum AnalogCode_t
{
ANALOG_CODE_INVALID = -1,
MOUSE_XY = 0, // Invoked when either x or y changes
MOUSE_WHEEL,
JOYSTICK_FIRST_AXIS,
JOYSTICK_LAST_AXIS = JOYSTICK_AXIS_INTERNAL(MAX_JOYSTICKS - 1, MAX_JOYSTICK_AXES - 1),
ANALOG_CODE_LAST,
};
#endif // ANALOGCODE_H

View File

@ -1,4 +1,6 @@
#pragma once
#include "InputEnums.h"
#include "common/xbox/xboxstubs.h"
#define JOYSTICK_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_BUTTON + ((_joystick) * JOYSTICK_MAX_BUTTON_COUNT) + (_button) )
#define JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) ( JOYSTICK_FIRST_POV_BUTTON + ((_joystick) * JOYSTICK_POV_BUTTON_COUNT) + (_button) )
@ -8,24 +10,6 @@
#define JOYSTICK_POV_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_POV_BUTTON_INTERNAL( _joystick, _button ) )
#define JOYSTICK_AXIS_BUTTON( _joystick, _button ) ( (ButtonCode_t)JOYSTICK_AXIS_BUTTON_INTERNAL( _joystick, _button ) )
// Buttons are not confirmed to be the same. They have been always the same throughout the source engine. Lets hope they did not change them.
enum
{
MAX_JOYSTICKS = MAX_SPLITSCREEN_CLIENTS,
MOUSE_BUTTON_COUNT = 5,
};
enum JoystickAxis_t
{
JOY_AXIS_X = 0,
JOY_AXIS_Y,
JOY_AXIS_Z,
JOY_AXIS_R,
JOY_AXIS_U,
JOY_AXIS_V,
MAX_JOYSTICK_AXES,
};
enum
{
JOYSTICK_MAX_BUTTON_COUNT = 32,
@ -150,8 +134,9 @@ enum ButtonCode_t
KEY_CAPSLOCKTOGGLE,
KEY_NUMLOCKTOGGLE,
KEY_SCROLLLOCKTOGGLE,
KEY_CREDITSIGN,
KEY_LAST = KEY_SCROLLLOCKTOGGLE,
KEY_LAST = KEY_CREDITSIGN,
KEY_COUNT = KEY_LAST - KEY_FIRST + 1,
// Mouse
@ -178,18 +163,17 @@ enum ButtonCode_t
JOYSTICK_FIRST_AXIS_BUTTON,
JOYSTICK_LAST_AXIS_BUTTON = JOYSTICK_AXIS_BUTTON_INTERNAL(MAX_JOYSTICKS - 1, JOYSTICK_AXIS_BUTTON_COUNT - 1),
JOYSTICK_LAST = JOYSTICK_LAST_AXIS_BUTTON,
// New in R5
JOYSTICK_UP_DOWN,
JOYSTICK_LEFT_RIGHT,
JOYSTICK_LAST = JOYSTICK_LEFT_RIGHT,
BUTTON_CODE_LAST,
BUTTON_CODE_COUNT = BUTTON_CODE_LAST - KEY_FIRST + 1,
// Helpers for XBox 360
KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons
KEY_XBUTTON_RIGHT,
KEY_XBUTTON_DOWN,
KEY_XBUTTON_LEFT,
KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons
KEY_XBUTTON_A = JOYSTICK_FIRST_BUTTON, // Buttons
KEY_XBUTTON_B,
KEY_XBUTTON_X,
KEY_XBUTTON_Y,
@ -200,15 +184,162 @@ enum ButtonCode_t
KEY_XBUTTON_STICK1,
KEY_XBUTTON_STICK2,
KEY_XBUTTON_INACTIVE_START,
KEY_XBUTTON_LTRIGGER_FULL,
KEY_XBUTTON_RTRIGGER_FULL,
KEY_XBUTTON_RELOAD,
KEY_XBUTTON_TRIGGER,
KEY_XBUTTON_PUMP_ACTION,
KEY_XBUTTON_ROLL_RIGHT,
KEY_XBUTTON_ROLL_LEFT,
KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE
KEY_XSTICK1_LEFT, // XAXIS NEGATIVE
KEY_XSTICK1_DOWN, // YAXIS POSITIVE
KEY_XSTICK1_UP, // YAXIS NEGATIVE
KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE
KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE
KEY_XSTICK2_RIGHT, // UAXIS POSITIVE
KEY_XSTICK2_LEFT, // UAXIS NEGATIVE
KEY_XSTICK2_DOWN, // VAXIS POSITIVE
KEY_XSTICK2_UP, // VAXIS NEGATIVE
};
KEY_XBUTTON_UP = JOYSTICK_FIRST_POV_BUTTON, // POV buttons
KEY_XBUTTON_RIGHT,
KEY_XBUTTON_DOWN,
KEY_XBUTTON_LEFT,
KEY_XSTICK1_RIGHT = JOYSTICK_FIRST_AXIS_BUTTON, // XAXIS POSITIVE
KEY_XSTICK1_LEFT, // XAXIS NEGATIVE
KEY_XSTICK1_DOWN, // YAXIS POSITIVE
KEY_XSTICK1_UP, // YAXIS NEGATIVE
KEY_XBUTTON_LTRIGGER, // ZAXIS POSITIVE
KEY_XBUTTON_RTRIGGER, // ZAXIS NEGATIVE
KEY_XSTICK2_RIGHT, // UAXIS POSITIVE
KEY_XSTICK2_LEFT, // UAXIS NEGATIVE
KEY_XSTICK2_DOWN, // VAXIS POSITIVE
KEY_XSTICK2_UP, // VAXIS NEGATIVE
};
//-----------------------------------------------------------------------------
// Inline helpers
//-----------------------------------------------------------------------------
inline bool IsAlpha( const ButtonCode_t code )
{
return ( code >= KEY_A ) && ( code <= KEY_Z );
}
inline bool IsAlphaNumeric( const ButtonCode_t code )
{
return ( code >= KEY_0 ) && ( code <= KEY_Z );
}
inline bool IsSpace( const ButtonCode_t code )
{
return ( code == KEY_ENTER ) || ( code == KEY_TAB ) || ( code == KEY_SPACE );
}
inline bool IsKeypad( const ButtonCode_t code )
{
return ( code >= MOUSE_FIRST ) && ( code <= KEY_PAD_DECIMAL );
}
inline bool IsPunctuation( const ButtonCode_t code )
{
return ( code >= KEY_0 ) && ( code <= KEY_SPACE ) && !IsAlphaNumeric( code ) && !IsSpace( code ) && !IsKeypad( code );
}
inline bool IsKeyCode( const ButtonCode_t code )
{
return ( code >= KEY_FIRST ) && ( code <= KEY_LAST );
}
inline bool IsMouseCode( const ButtonCode_t code )
{
return ( code >= MOUSE_FIRST ) && ( code <= MOUSE_LAST );
}
inline bool IsJoystickCode( const ButtonCode_t code )
{
return ( ( code >= JOYSTICK_FIRST ) && ( code <= JOYSTICK_LAST ) );
}
inline bool IsJoystickButtonCode( const ButtonCode_t code )
{
return ( code >= JOYSTICK_FIRST_BUTTON ) && ( code <= JOYSTICK_LAST_BUTTON );
}
inline bool IsJoystickPOVCode( const ButtonCode_t code )
{
return ( code >= JOYSTICK_FIRST_POV_BUTTON ) && ( code <= JOYSTICK_LAST_POV_BUTTON );
}
inline bool IsJoystickAxisCode( const ButtonCode_t code )
{
return ( code >= JOYSTICK_FIRST_AXIS_BUTTON ) && ( code <= JOYSTICK_LAST_AXIS_BUTTON );
}
inline ButtonCode_t GetBaseButtonCode( const ButtonCode_t code )
{
if ( IsJoystickButtonCode( code ) )
{
const int offset = ( code - JOYSTICK_FIRST_BUTTON ) % JOYSTICK_MAX_BUTTON_COUNT;
return (ButtonCode_t)( JOYSTICK_FIRST_BUTTON + offset );
}
if ( IsJoystickPOVCode( code ) )
{
const int offset = ( code - JOYSTICK_FIRST_POV_BUTTON ) % JOYSTICK_POV_BUTTON_COUNT;
return (ButtonCode_t)( JOYSTICK_FIRST_POV_BUTTON + offset );
}
if ( IsJoystickAxisCode( code ) )
{
const int offset = ( code - JOYSTICK_FIRST_AXIS_BUTTON ) % JOYSTICK_AXIS_BUTTON_COUNT;
return (ButtonCode_t)( JOYSTICK_FIRST_AXIS_BUTTON + offset );
}
return code;
}
inline int GetJoystickForCode( const ButtonCode_t code )
{
if ( !IsJoystickCode( code ) )
return 0;
if ( IsJoystickButtonCode( code ) )
{
const int offset = ( code - JOYSTICK_FIRST_BUTTON ) / JOYSTICK_MAX_BUTTON_COUNT;
return offset;
}
if ( IsJoystickPOVCode( code ) )
{
const int offset = ( code - JOYSTICK_FIRST_POV_BUTTON ) / JOYSTICK_POV_BUTTON_COUNT;
return offset;
}
if ( IsJoystickAxisCode( code ) )
{
const int offset = ( code - JOYSTICK_FIRST_AXIS_BUTTON ) / JOYSTICK_AXIS_BUTTON_COUNT;
return offset;
}
return 0;
}
inline ButtonCode_t ButtonCodeToJoystickButtonCode( ButtonCode_t code, int nDesiredJoystick )
{
if ( !IsJoystickCode( code ) || nDesiredJoystick == 0 )
return code;
nDesiredJoystick = clamp( nDesiredJoystick, 0, MAX_JOYSTICKS - 1 );
code = GetBaseButtonCode( code );
// Now upsample it
if ( IsJoystickButtonCode( code ) )
{
const int nOffset = code - JOYSTICK_FIRST_BUTTON;
return JOYSTICK_BUTTON( nDesiredJoystick, nOffset );
}
if ( IsJoystickPOVCode( code ) )
{
const int nOffset = code - JOYSTICK_FIRST_POV_BUTTON;
return JOYSTICK_POV_BUTTON( nDesiredJoystick, nOffset );
}
if ( IsJoystickAxisCode( code ) )
{
const int nOffset = code - JOYSTICK_FIRST_AXIS_BUTTON;
return JOYSTICK_AXIS_BUTTON( nDesiredJoystick, nOffset );
}
return code;
}

View File

@ -6,11 +6,91 @@
#ifndef INPUTENUMS_H
#define INPUTENUMS_H
// Standard maximum +/- value of a joystick axis
#define MAX_BUTTONSAMPLE 32768
#if !defined( _X360 )
#define INVALID_USER_ID -1
#else
#define INVALID_USER_ID XBX_INVALID_USER_ID
#endif
enum
{
#ifdef _PS3
MAX_JOYSTICKS = 7,
#else
MAX_JOYSTICKS = 4,
#endif
MOUSE_BUTTON_COUNT = 5,
MAX_NOVINT_DEVICES = 2,
};
enum JoystickAxis_t
{
JOY_AXIS_X = 0,
JOY_AXIS_Y,
JOY_AXIS_Z,
JOY_AXIS_R,
JOY_AXIS_U,
JOY_AXIS_V,
MAX_JOYSTICK_AXES,
};
enum JoystickDeadzoneIndex_t
{
JOYSTICK_DEADZONE_NONE = 0,
JOYSTICK_DEADZONE_XBOX360,
JOYSTICK_DEADZONE_XBOX1,
JOYSTICK_DEADZONE_OTHER
};
//-----------------------------------------------------------------------------
// Events
//-----------------------------------------------------------------------------
enum InputEventType_t
{
IE_ButtonPressed = 0, // m_nData contains a ButtonCode_t
IE_ButtonReleased, // m_nData contains a ButtonCode_t
IE_ButtonDoubleClicked, // m_nData contains a ButtonCode_t
IE_AnalogValueChanged, // m_nData contains an AnalogCode_t, m_nData2 contains the value
IE_FirstSystemEvent = 100,
IE_Quit = IE_FirstSystemEvent,
IE_ControllerInserted, // m_nData contains the controller ID
IE_ControllerUnplugged, // m_nData contains the controller ID
IE_Close,
IE_WindowSizeChanged, // m_nData contains width, m_nData2 contains height, m_nData3 = 0 if not minimized, 1 if minimized
IE_PS_CameraUnplugged, // m_nData contains code for type of disconnect.
IE_PS_Move_OutOfView, // m_nData contains bool (0, 1) for whether the move is now out of view (1) or in view (0)
IE_FirstUIEvent = 200,
IE_LocateMouseClick = IE_FirstUIEvent,
IE_SetCursor,
IE_KeyTyped,
IE_KeyCodeTyped,
IE_InputLanguageChanged,
IE_IMESetWindow,
IE_IMEStartComposition,
IE_IMEComposition,
IE_IMEEndComposition,
IE_IMEShowCandidates,
IE_IMEChangeCandidates,
IE_IMECloseCandidates,
IE_IMERecomputeModes,
IE_OverlayEvent,
IE_FirstVguiEvent = 1000, // Assign ranges for other systems that post user events here
IE_FirstAppEvent = 2000,
};
struct InputEvent_t
{
const char* m_pCommand;
int m_nTick;
bool m_bDown;
int m_nType; // Type of the event (see InputEventType_t)
int m_nTick; // Tick on which the event occurred
int m_nData; // Generic 32-bit data, what it contains depends on the event
int m_nData2; // Generic 32-bit data, what it contains depends on the event
int m_nData3; // Generic 32-bit data, what it contains depends on the event
};
#endif // INPUTENUMS_H

View File

@ -0,0 +1,153 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef IINPUTSYSTEM_H
#define IINPUTSYSTEM_H
#include "inputsystem/ButtonCode.h"
#include "inputsystem/AnalogCode.h"
#include "inputsystem/InputEnums.h"
///-----------------------------------------------------------------------------
/// A handle to a cursor icon
///-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE( InputCursorHandle_t );
#define INPUT_CURSOR_HANDLE_INVALID ( (InputCursorHandle_t)0 )
///-----------------------------------------------------------------------------
/// Input event callback
///-----------------------------------------------------------------------------
typedef bool ( *InputEventCallback_t ) ( const InputEvent_t& eventCallback );
///-----------------------------------------------------------------------------
/// An enumeration describing well-known cursor icons
///-----------------------------------------------------------------------------
enum InputStandardCursor_t
{
INPUT_CURSOR_NONE = 0,
INPUT_CURSOR_ARROW,
INPUT_CURSOR_IBEAM,
INPUT_CURSOR_HOURGLASS,
INPUT_CURSOR_CROSSHAIR,
INPUT_CURSOR_WAITARROW,
INPUT_CURSOR_UP,
INPUT_CURSOR_SIZE_NW_SE,
INPUT_CURSOR_SIZE_NE_SW,
INPUT_CURSOR_SIZE_W_E,
INPUT_CURSOR_SIZE_N_S,
INPUT_CURSOR_SIZE_ALL,
INPUT_CURSOR_NO,
INPUT_CURSOR_HAND,
INPUT_CURSOR_COUNT
};
//-----------------------------------------------------------------------------
// Main interface for input. This is a low-level interface
//-----------------------------------------------------------------------------
#define INPUTSYSTEM_INTERFACE_VERSION "InputSystemVersion001"
abstract_class IInputSystem : public IAppSystem
{
public:
/// Attach, detach input system from a particular window
/// This window should be the root window for the application
/// Only 1 window should be attached at any given time.
virtual void AttachToWindow( const void* const hWnd ) = 0;
virtual void DetachFromWindow( ) = 0;
/// Enables/disables input. PollInputState will not update current
/// button/analog states when it is called if the system is disabled.
virtual void EnableInput( const bool bEnable ) = 0;
/// Enables/disables the windows message pump. PollInputState will not.
/// Peek/Dispatch messages if this is disabled.
virtual void EnableMessagePump( const bool bEnable ) = 0;
/// Gets the time of the last polling in ms.
virtual int GetPollTick() const = 0;
/// Is a button down? "Buttons" are binary-state input devices (mouse buttons, keyboard keys).
virtual bool IsButtonDown( const ButtonCode_t code ) const = 0;
/// Returns the tick at which the button was pressed and released.
virtual int GetButtonPressedTick( const ButtonCode_t code ) const = 0;
/// Returns the joystick deadzone index for connected hardware.
virtual JoystickDeadzoneIndex_t GetJoystickDeadzoneIndex( ) const = 0;
/// DoNothing; VFTable padding.
virtual bool ReturnFalse( ) const = 0;
/// Polls the current input state.
virtual void PollInputState( const InputEventCallback_t eventCallback ) = 0;
/// Posts a user-defined event into the event queue; this is expected
/// to be called in overridden wndprocs connected to the root panel.
virtual void PostUserEvent( const InputEvent_t &event ) = 0;
virtual void PostUserEvent( const InputEventType_t type ) = 0;
/// Returns the number of joysticks
virtual int GetJoystickCount( ) const = 0;
/// Sample the joystick and append events to the input queue.
virtual void SampleDevices( void ) = 0;
virtual void SetRumble( const float fLeftMainMotor, const float fRightMainMotor, const float fLeftTriggerMotor, const float fRightTriggerMotor, const int userId = INVALID_USER_ID ) = 0;
virtual void StopRumble( const int userId = INVALID_USER_ID ) = 0;
/// Resets the input state.
virtual void ResetInputState() = 0;
/// Convert back + forth between ButtonCode/AnalogCode + strings.
virtual const char* ButtonCodeToString( const ButtonCode_t code ) const = 0;
virtual ButtonCode_t StringToButtonCode( const char* const pString ) const = 0;
/// Sleeps until input happens. Pass a negative number to sleep infinitely.
virtual void SleepUntilInput( const int nMaxSleepTimeMS = -1 ) = 0;
/// Convert back + forth between virtual codes + button codes
virtual ButtonCode_t VirtualKeyToButtonCode( const int nVirtualKey ) const = 0;
virtual int ButtonCodeToVirtualKey( const ButtonCode_t code ) const = 0;
/// Sets the cursor position.
virtual void SetCursorPosition( const int x, const int y ) = 0;
/// Tells the input system to generate UI-related events, defined
/// in inputsystem/inputenums.h (see IE_FirstUIEvent)
/// We could have multiple clients that care about UI-related events
/// so we refcount the clients with an Add/Remove strategy. If there
/// are no interested clients, the UI events are not generated.
virtual void AddUIEventListener() = 0;
virtual void RemoveUIEventListener() = 0;
/// Creates a cursor using one of the well-known cursor icons.
virtual InputCursorHandle_t GetStandardCursor( const InputStandardCursor_t id ) = 0;
/// Loads a cursor defined in a file.
virtual InputCursorHandle_t LoadCursorFromFile( const char* const pFileName, const char* const pPathID = NULL ) = 0;
/// Sets the cursor icon.
virtual void SetCursorIcon( const InputCursorHandle_t hCursor ) = 0;
/// Gets the cursor position.
virtual void GetCursorPosition( const int* const pX, const int* const pY ) = 0;
/// Mouse capture.
virtual void EnableMouseCapture( const PlatWindow_t hWnd ) = 0;
virtual void DisableMouseCapture( ) = 0;
// Mouse/Joystick cursor visibility, tell inputsystem when we hide stuff rather than querying the OS which is expensive on OSX.
virtual void SetMouseCursorVisible( const bool bVisible ) = 0;
virtual void SetJoystickCursorVisible( const bool bVisible ) = 0;
/// Reset the current cursor icon. Used to reset the icon in the case of alt+tabs where the cursor has been forced to a different
/// icon because it was outside of the client rect during the reload.
virtual void ResetCursorIcon() = 0;
// read and clear accumulated raw input values.
virtual void GetRawMouseAccumulators( int& accumX, int& accumY ) = 0;
};
#endif // IINPUTSYSTEM_H

View File

@ -28,6 +28,15 @@ public:
void LoadSections();
CMemory FindPatternSIMD(const char* szPattern, const ModuleSections_t* moduleSection = nullptr) const;
template<typename T>
inline void FindPatternSIMD(const char* szPattern,
T*& pMemPtrOut, const ModuleSections_t* moduleSection = nullptr) const
{
CMemory mem = FindPatternSIMD(szPattern, moduleSection);
pMemPtrOut = mem.RCast<T*>();
}
CMemory FindString(const char* szString, const ptrdiff_t occurrence = 1, bool nullTerminator = false) const;
CMemory FindStringReadOnly(const char* szString, bool nullTerminator) const;
CMemory FindFreeDataPage(const size_t nSize) const;

View File

@ -0,0 +1,82 @@
//===== Copyright <20> 1996-2009, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef PLATWINDOW_H
#define PLATWINDOW_H
#ifdef COMPILER_MSVC32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier0/basetypes.h"
//-----------------------------------------------------------------------------
// Window handle
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE( PlatWindow_t );
#define PLAT_WINDOW_INVALID ( (PlatWindow_t)0 )
//-----------------------------------------------------------------------------
// Window creation
//-----------------------------------------------------------------------------
enum WindowCreateFlags_t
{
WINDOW_CREATE_FULLSCREEN = 0x1,
WINDOW_CREATE_RESIZING = 0x2,
};
PLATFORM_INTERFACE PlatWindow_t Plat_CreateWindow( void *hInstance, const char *pTitle, int nWidth, int nHeight, int nFlags );
//-----------------------------------------------------------------------------
// Window title
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE void Plat_SetWindowTitle( PlatWindow_t hWindow, const char *pTitle );
//-----------------------------------------------------------------------------
// Window movement
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE void Plat_SetWindowPos( PlatWindow_t hWindow, int x, int y );
//-----------------------------------------------------------------------------
// Gets the desktop resolution
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE void Plat_GetDesktopResolution( int *pWidth, int *pHeight );
//-----------------------------------------------------------------------------
// Gets a window size
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE void Plat_GetWindowClientSize( PlatWindow_t hWindow, int *pWidth, int *pHeight );
//-----------------------------------------------------------------------------
// Is the window minimized?
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE bool Plat_IsWindowMinimized( PlatWindow_t hWindow );
//-----------------------------------------------------------------------------
// Gets the shell window in a console app
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE PlatWindow_t Plat_GetShellWindow( );
//-----------------------------------------------------------------------------
// Convert window -> Screen coordinates and back
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE void Plat_WindowToScreenCoords( PlatWindow_t hWnd, int &x, int &y );
PLATFORM_INTERFACE void Plat_ScreenToWindowCoords( PlatWindow_t hWnd, int &x, int &y );
#endif // PLATWINDOW_H

26
src/public/tier1/tier1.h Normal file
View File

@ -0,0 +1,26 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//===========================================================================//
#ifndef TIER1_H
#define TIER1_H
#include "appframework/IAppSystem.h"
//-----------------------------------------------------------------------------
// Helper empty implementation of an IAppSystem for tier2 libraries
//-----------------------------------------------------------------------------
template< class IInterface, int ConVarFlag = 0 >
class CTier1AppSystem : public CTier0AppSystem< IInterface >
{
public:
virtual bool Connect( const CreateInterfaceFn factory ) = 0;
virtual void Disconnect( ) = 0;
virtual void* QueryInterface( const char* const pInterfaceName ) = 0;
virtual InitReturnVal_t Init( ) = 0;
virtual void Shutdown( ) = 0;
virtual AppSystemTier_t GetTier( ) = 0;
virtual void Reconnect( const CreateInterfaceFn factory, const char* const pInterfaceName ) = 0;
};
#endif // TIER1_H

View File

@ -0,0 +1,185 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef UTLSTRINGMAP_H
#define UTLSTRINGMAP_H
#ifdef _WIN32
#pragma once
#endif
#include "utlsymbol.h"
template <class T>
class CUtlStringMap
{
public:
typedef UtlSymId_t IndexType_t;
CUtlStringMap( bool caseInsensitive = true, int initsize = 32 ) :
m_SymbolTable( 0, 32, caseInsensitive ),
m_Vector( initsize )
{
}
// Get data by the string itself:
T& operator[]( const char *pString )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString );
int index = ( int )( UtlSymId_t )symbol;
if( m_Vector.Count() <= index )
{
m_Vector.EnsureCount( index + 1 );
}
return m_Vector[index];
}
// Get data by the string's symbol table ID - only used to retrieve a pre-existing symbol, not create a new one!
T& operator[]( UtlSymId_t n )
{
Assert( n <= m_Vector.Count() );
return m_Vector[n];
}
const T& operator[]( UtlSymId_t n ) const
{
Assert( n <= m_Vector.Count() );
return m_Vector[n];
}
unsigned int Count() const
{
Assert( m_Vector.Count() == m_SymbolTable.GetNumStrings() );
return m_Vector.Count();
}
bool Defined( const char *pString ) const
{
return m_SymbolTable.Find( pString ) != UTL_INVAL_SYMBOL;
}
UtlSymId_t Find( const char *pString ) const
{
return m_SymbolTable.Find( pString );
}
UtlSymId_t AddString( const char *pString )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString );
int index = ( int )( UtlSymId_t )symbol;
if( m_Vector.Count() <= index )
{
m_Vector.EnsureCount( index + 1 );
}
return symbol;
}
/// Add a string to the map and also insert an item at
/// its location in the same operation. Returns the
/// newly created index (or the one that was just
/// overwritten, if pString already existed.)
UtlSymId_t Insert( const char *pString, const T &item )
{
CUtlSymbol symbol = m_SymbolTable.AddString( pString );
UtlSymId_t index = symbol; // implicit coercion
if ( m_Vector.Count() > index )
{
// this string is already in the dictionary.
}
else if ( m_Vector.Count() == index )
{
// this is the expected case when we've added one more to the tail.
m_Vector.AddToTail( item );
}
else // ( m_Vector.Count() < index )
{
// this is a strange shouldn't-happen case.
//AssertMsg( false, "CUtlStringMap insert unexpected entries." );
m_Vector.EnsureCount( index + 1 );
m_Vector[index] = item;
}
return index;
}
/// iterate, not in any particular order.
IndexType_t First() const
{
if ( Count() > 0 )
{
return 0;
}
else
{
return InvalidIndex();
}
}
static UtlSymId_t InvalidIndex()
{
return UTL_INVAL_SYMBOL;
}
// iterators (for uniformity with other map types)
inline UtlSymId_t Head() const
{
return m_SymbolTable.GetNumStrings() > 0 ? 0 : InvalidIndex();
}
inline UtlSymId_t Next( const UtlSymId_t &i ) const
{
UtlSymId_t n = i+1;
return n < m_SymbolTable.GetNumStrings() ? n : InvalidIndex();
}
int GetNumStrings( void ) const
{
return m_SymbolTable.GetNumStrings();
}
const char *String( int n ) const
{
return m_SymbolTable.String( n );
}
// Clear all of the data from the map
void Clear()
{
m_Vector.RemoveAll();
m_SymbolTable.RemoveAll();
}
void Purge()
{
m_Vector.Purge();
m_SymbolTable.RemoveAll();
}
void PurgeAndDeleteElements()
{
m_Vector.PurgeAndDeleteElements();
m_SymbolTable.RemoveAll();
}
private:
CUtlVector<T> m_Vector;
CUtlSymbolTable m_SymbolTable;
};
template< class T >
class CUtlStringMapAutoPurge : public CUtlStringMap < T >
{
public:
~CUtlStringMapAutoPurge( void )
{
this->PurgeAndDeleteElements();
}
};
#endif // UTLSTRINGMAP_H

View File

@ -196,60 +196,62 @@ private:
};
class CUtlSymbolTableMT : public CUtlSymbolTable
{
public:
CUtlSymbolTableMT( int growSize = 0, int initSize = 32, bool caseInsensitive = false )
: CUtlSymbolTable( growSize, initSize, caseInsensitive )
{
}
// TODO[ AMOS ]: implement CThreadSpinRWLock
CUtlSymbol AddString( const char* pString )
{
m_lock.LockForWrite();
CUtlSymbol result = CUtlSymbolTable::AddString( pString );
m_lock.UnlockWrite();
return result;
}
CUtlSymbol Find( const char* pString ) const
{
m_lock.LockForWrite();
CUtlSymbol result = CUtlSymbolTable::Find( pString );
m_lock.UnlockWrite();
return result;
}
const char* String( CUtlSymbol id ) const
{
m_lock.LockForRead();
const char *pszResult = CUtlSymbolTable::String( id );
m_lock.UnlockRead();
return pszResult;
}
const char * StringNoLock( CUtlSymbol id ) const
{
return CUtlSymbolTable::String( id );
}
void LockForRead()
{
m_lock.LockForRead();
}
void UnlockForRead()
{
m_lock.UnlockRead();
}
private:
#ifdef WIN32
mutable CThreadSpinRWLock m_lock;
#else
mutable CThreadRWLock m_lock;
#endif
};
//class CUtlSymbolTableMT : public CUtlSymbolTable
//{
//public:
// CUtlSymbolTableMT( int growSize = 0, int initSize = 32, bool caseInsensitive = false )
// : CUtlSymbolTable( growSize, initSize, caseInsensitive )
// {
// }
//
// CUtlSymbol AddString( const char* pString )
// {
// m_lock.LockForWrite();
// CUtlSymbol result = CUtlSymbolTable::AddString( pString );
// m_lock.UnlockWrite();
// return result;
// }
//
// CUtlSymbol Find( const char* pString ) const
// {
// m_lock.LockForWrite();
// CUtlSymbol result = CUtlSymbolTable::Find( pString );
// m_lock.UnlockWrite();
// return result;
// }
//
// const char* String( CUtlSymbol id ) const
// {
// m_lock.LockForRead();
// const char *pszResult = CUtlSymbolTable::String( id );
// m_lock.UnlockRead();
// return pszResult;
// }
//
// const char * StringNoLock( CUtlSymbol id ) const
// {
// return CUtlSymbolTable::String( id );
// }
//
// void LockForRead()
// {
// m_lock.LockForRead();
// }
//
// void UnlockForRead()
// {
// m_lock.UnlockRead();
// }
//
//private:
//#ifdef WIN32
// mutable CThreadSpinRWLock m_lock;
//#else
// mutable CThreadRWLock m_lock;
//#endif
//};
@ -268,68 +270,71 @@ typedef void* FileNameHandle_t;
// Symbol table for more efficiently storing filenames by breaking paths and filenames apart.
// Refactored from BaseFileSystem.h
class CUtlFilenameSymbolTable
{
// Internal representation of a FileHandle_t
// If we get more than 64K filenames, we'll have to revisit...
// Right now CUtlSymbol is a short, so this packs into an int/void * pointer size...
struct FileNameHandleInternal_t
{
FileNameHandleInternal_t()
{
COMPILE_TIME_ASSERT( sizeof( *this ) == sizeof( FileNameHandle_t ) );
COMPILE_TIME_ASSERT( sizeof( value ) == 4 );
value = 0;
#ifdef PLATFORM_64BITS
pad = 0;
#endif
}
// TODO[ AMOS ]: implement CThreadSpinRWLock
// We pack the path and file values into a single 32 bit value. We were running
// out of space with the two 16 bit values (more than 64k files) so instead of increasing
// the total size we split the underlying pool into two (paths and files) and
// use a smaller path string pool and a larger file string pool.
unsigned int value;
#ifdef PLATFORM_64BITS
// some padding to make sure we are the same size as FileNameHandle_t on 64 bit.
unsigned int pad;
#endif
static const unsigned int cNumBitsInPath = 12;
static const unsigned int cNumBitsInFile = 32 - cNumBitsInPath;
static const unsigned int cMaxPathValue = 1 << cNumBitsInPath;
static const unsigned int cMaxFileValue = 1 << cNumBitsInFile;
static const unsigned int cPathBitMask = cMaxPathValue - 1;
static const unsigned int cFileBitMask = cMaxFileValue - 1;
// Part before the final '/' character
unsigned int GetPath() const { return ((value >> cNumBitsInFile) & cPathBitMask); }
void SetPath( unsigned int path ) { Assert( path < cMaxPathValue ); value = ((value & cFileBitMask) | ((path & cPathBitMask) << cNumBitsInFile)); }
// Part after the final '/', including extension
unsigned int GetFile() const { return (value & cFileBitMask); }
void SetFile( unsigned int file ) { Assert( file < cMaxFileValue ); value = ((value & (cPathBitMask << cNumBitsInFile)) | (file & cFileBitMask)); }
};
public:
FileNameHandle_t FindOrAddFileName( const char *pFileName );
FileNameHandle_t FindFileName( const char *pFileName );
int PathIndex( const FileNameHandle_t &handle ) { return (( const FileNameHandleInternal_t * )&handle)->GetPath(); }
bool String( const FileNameHandle_t& handle, char *buf, int buflen );
void RemoveAll();
void SpewStrings();
bool SaveToBuffer( CUtlBuffer &buffer );
bool RestoreFromBuffer( CUtlBuffer &buffer );
private:
CCountedStringPoolBase<unsigned short> m_PathStringPool;
CCountedStringPoolBase<unsigned int> m_FileStringPool;
mutable CThreadSpinRWLock m_lock;
};
//class CUtlFilenameSymbolTable
//{
// // Internal representation of a FileHandle_t
// // If we get more than 64K filenames, we'll have to revisit...
// // Right now CUtlSymbol is a short, so this packs into an int/void * pointer size...
// struct FileNameHandleInternal_t
// {
// FileNameHandleInternal_t()
// {
// COMPILE_TIME_ASSERT( sizeof( *this ) == sizeof( FileNameHandle_t ) );
// COMPILE_TIME_ASSERT( sizeof( value ) == 4 );
// value = 0;
//
//#ifdef PLATFORM_64BITS
// pad = 0;
//#endif
// }
//
// // We pack the path and file values into a single 32 bit value. We were running
// // out of space with the two 16 bit values (more than 64k files) so instead of increasing
// // the total size we split the underlying pool into two (paths and files) and
// // use a smaller path string pool and a larger file string pool.
// unsigned int value;
//
//#ifdef PLATFORM_64BITS
// // some padding to make sure we are the same size as FileNameHandle_t on 64 bit.
// unsigned int pad;
//#endif
//
// static const unsigned int cNumBitsInPath = 12;
// static const unsigned int cNumBitsInFile = 32 - cNumBitsInPath;
//
// static const unsigned int cMaxPathValue = 1 << cNumBitsInPath;
// static const unsigned int cMaxFileValue = 1 << cNumBitsInFile;
//
// static const unsigned int cPathBitMask = cMaxPathValue - 1;
// static const unsigned int cFileBitMask = cMaxFileValue - 1;
//
// // Part before the final '/' character
// unsigned int GetPath() const { return ((value >> cNumBitsInFile) & cPathBitMask); }
// void SetPath( unsigned int path ) { Assert( path < cMaxPathValue ); value = ((value & cFileBitMask) | ((path & cPathBitMask) << cNumBitsInFile)); }
//
// // Part after the final '/', including extension
// unsigned int GetFile() const { return (value & cFileBitMask); }
// void SetFile( unsigned int file ) { Assert( file < cMaxFileValue ); value = ((value & (cPathBitMask << cNumBitsInFile)) | (file & cFileBitMask)); }
// };
//
//public:
// FileNameHandle_t FindOrAddFileName( const char *pFileName );
// FileNameHandle_t FindFileName( const char *pFileName );
// int PathIndex( const FileNameHandle_t &handle ) { return (( const FileNameHandleInternal_t * )&handle)->GetPath(); }
// bool String( const FileNameHandle_t& handle, char *buf, int buflen );
// void RemoveAll();
// void SpewStrings();
// bool SaveToBuffer( CUtlBuffer &buffer );
// bool RestoreFromBuffer( CUtlBuffer &buffer );
//
//private:
// CCountedStringPoolBase<unsigned short> m_PathStringPool;
// CCountedStringPoolBase<unsigned int> m_FileStringPool;
// mutable CThreadSpinRWLock m_lock;
//};
// This creates a simple class that includes the underlying CUtlSymbol
// as a private member and then instances a private symbol table to

View File

@ -1,6 +1,7 @@
#pragma once
#include <engine/server/sv_main.h>
#include <vguimatsurface/MatSystemSurface.h>
#include "inputsystem/iinputsystem.h"
enum class PaintMode_t
{
@ -85,6 +86,7 @@ inline void*(*CEngineVGui_RenderStart)(CMatSystemSurface* pMatSystemSurface);
inline CMemory p_CEngineVGui_RenderEnd;
inline void*(*CEngineVGui_RenderEnd)(void);
inline InputEventCallback_t v_UIInputEventHandler = nullptr;
inline CEngineVGui* g_pEngineVGui = nullptr;
///////////////////////////////////////////////////////////////////////////////
@ -95,6 +97,7 @@ class VEngineVGui : public IDetour
LogFunAdr("CEngineVGui::Paint", p_CEngineVGui_Paint.GetPtr());
LogFunAdr("CEngineVGui::RenderStart", p_CEngineVGui_RenderStart.GetPtr());
LogFunAdr("CEngineVGui::RenderEnd", p_CEngineVGui_RenderEnd.GetPtr());
LogFunAdr("UIInputEventHandler", reinterpret_cast<uintptr_t>(v_UIInputEventHandler));
LogVarAdr("g_pEngineVGui", reinterpret_cast<uintptr_t>(g_pEngineVGui));
}
virtual void GetFun(void) const
@ -114,6 +117,8 @@ class VEngineVGui : public IDetour
#endif
p_CEngineVGui_RenderEnd = g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ?? 48 8B 01");
CEngineVGui_RenderEnd = p_CEngineVGui_RenderEnd.RCast<void* (*)(void)>(); /*40 53 48 83 EC 20 48 8B 0D ?? ?? ?? ?? C6 05 ?? ?? ?? ?? ?? 48 8B 01*/
g_GameDll.FindPatternSIMD("40 53 48 83 EC 40 48 63 01", v_UIInputEventHandler);
}
virtual void GetVar(void) const
{

View File

@ -81,6 +81,6 @@ class VFactory : public IDetour
.FollowNearCallSelf().FindPatternSelf("48 8B 1D", CMemory::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<InterfaceReg**>();
}
virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const { }
virtual void Detour(const bool /*bAttach*/) const { }
};
///////////////////////////////////////////////////////////////////////////////