Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor debugoverlay.cpp (fix smart pistol lines) #538

Merged
merged 12 commits into from
Oct 30, 2023
228 changes: 218 additions & 10 deletions NorthstarDLL/client/debugoverlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ enum OverlayType_t
OVERLAY_BOX = 0,
OVERLAY_SPHERE,
OVERLAY_LINE,
OVERLAY_SMARTAMMO,
OVERLAY_TRIANGLE,
OVERLAY_SWEPT_BOX,
// [Fifty]: the 2 bellow i did not confirm, rest are good
OVERLAY_BOX2,
OVERLAY_CAPSULE
};
Expand All @@ -31,7 +33,7 @@ struct OverlayBase_t
int m_nServerCount; // Latch server count, too
float m_flEndTime; // When does this box go away
OverlayBase_t* m_pNextOverlay;
void* m_pUnk;
__int64 m_pUnk;
};

struct OverlayLine_t : public OverlayBase_t
Expand Down Expand Up @@ -67,25 +69,116 @@ struct OverlayBox_t : public OverlayBase_t
int a;
};

static HMODULE sEngineModule;
struct OverlayTriangle_t : public OverlayBase_t
{
OverlayTriangle_t()
{
m_Type = OVERLAY_TRIANGLE;
}

typedef void (*RenderLineType)(Vector3 v1, Vector3 v2, Color c, bool bZBuffer);
Vector3 p1;
Vector3 p2;
Vector3 p3;
int r;
int g;
int b;
int a;
bool noDepthTest;
};

struct OverlaySweptBox_t : public OverlayBase_t
{
OverlaySweptBox_t()
{
m_Type = OVERLAY_SWEPT_BOX;
}

Vector3 start;
Vector3 end;
Vector3 mins;
Vector3 maxs;
QAngle angles;
int r;
int g;
int b;
int a;
};

struct OverlaySphere_t : public OverlayBase_t
{
OverlaySphere_t()
{
m_Type = OVERLAY_SPHERE;
}

Vector3 vOrigin;
float flRadius;
int nTheta;
int nPhi;
int r;
int g;
int b;
int a;
bool m_bWireframe;
};

typedef bool (*OverlayBase_t__IsDeadType)(OverlayBase_t* a1);
static OverlayBase_t__IsDeadType OverlayBase_t__IsDead;
typedef void (*OverlayBase_t__DestroyOverlayType)(OverlayBase_t* a1);
static OverlayBase_t__DestroyOverlayType OverlayBase_t__DestroyOverlay;

static ConVar* Cvar_enable_debug_overlays;

LPCRITICAL_SECTION s_OverlayMutex;

// Render Line
typedef void (*RenderLineType)(const Vector3& v1, const Vector3& v2, Color c, bool bZBuffer);
static RenderLineType RenderLine;
typedef void (*RenderBoxType)(Vector3 vOrigin, QAngle angles, Vector3 vMins, Vector3 vMaxs, Color c, bool bZBuffer, bool bInsideOut);

// Render box
typedef void (*RenderBoxType)(
const Vector3& vOrigin, const QAngle& angles, const Vector3& vMins, const Vector3& vMaxs, Color c, bool bZBuffer, bool bInsideOut);
static RenderBoxType RenderBox;

// Render wireframe box
static RenderBoxType RenderWireframeBox;

// Render swept box
typedef void (*RenderWireframeSweptBoxType)(
const Vector3& vStart, const Vector3& vEnd, const QAngle& angles, const Vector3& vMins, const Vector3& vMaxs, Color c, bool bZBuffer);
RenderWireframeSweptBoxType RenderWireframeSweptBox;

// Render Triangle
typedef void (*RenderTriangleType)(const Vector3& p1, const Vector3& p2, const Vector3& p3, Color c, bool bZBuffer);
static RenderTriangleType RenderTriangle;

// Render Axis
typedef void (*RenderAxisType)(const Vector3& vOrigin, float flScale, bool bZBuffer);
static RenderAxisType RenderAxis;

// I dont know
typedef void (*RenderUnknownType)(const Vector3& vUnk, float flUnk, bool bUnk);
static RenderUnknownType RenderUnknown;

// Render Sphere
typedef void (*RenderSphereType)(const Vector3& vCenter, float flRadius, int nTheta, int nPhi, Color c, bool bZBuffer);
static RenderSphereType RenderSphere;

OverlayBase_t** s_pOverlays;

int* g_nRenderTickCount;
int* g_nOverlayTickCount;

// clang-format off
AUTOHOOK(DrawOverlay, engine.dll + 0xABCB0,
void, __fastcall, (OverlayBase_t * pOverlay))
// clang-format on
{
EnterCriticalSection((LPCRITICAL_SECTION)((char*)sEngineModule + 0x10DB0A38)); // s_OverlayMutex

void* pMaterialSystem = *(void**)((char*)sEngineModule + 0x14C675B0);
EnterCriticalSection(s_OverlayMutex);

switch (pOverlay->m_Type)
{
case OVERLAY_SMARTAMMO:
case OVERLAY_LINE:
{
OverlayLine_t* pLine = static_cast<OverlayLine_t*>(pOverlay);
Expand Down Expand Up @@ -119,21 +212,136 @@ void, __fastcall, (OverlayBase_t * pOverlay))
}
}
break;
case OVERLAY_TRIANGLE:
{
OverlayTriangle_t* pTriangle = static_cast<OverlayTriangle_t*>(pOverlay);
RenderTriangle(
pTriangle->p1,
pTriangle->p2,
pTriangle->p3,
Color(pTriangle->r, pTriangle->g, pTriangle->b, pTriangle->a),
pTriangle->noDepthTest);
}
LeaveCriticalSection((LPCRITICAL_SECTION)((char*)sEngineModule + 0x10DB0A38));
break;
case OVERLAY_SWEPT_BOX:
{
OverlaySweptBox_t* pBox = static_cast<OverlaySweptBox_t*>(pOverlay);
RenderWireframeSweptBox(
pBox->start, pBox->end, pBox->angles, pBox->mins, pBox->maxs, Color(pBox->r, pBox->g, pBox->b, pBox->a), false);
}
break;
case OVERLAY_SPHERE:
{
OverlaySphere_t* pSphere = static_cast<OverlaySphere_t*>(pOverlay);
RenderSphere(
pSphere->vOrigin,
pSphere->flRadius,
pSphere->nTheta,
pSphere->nPhi,
Color(pSphere->r, pSphere->g, pSphere->b, pSphere->a),
false);
}
break;
default:
{
spdlog::warn("Unimplemented overlay type {}", pOverlay->m_Type);
}
break;
}

LeaveCriticalSection(s_OverlayMutex);
}

// clang-format off
AUTOHOOK(DrawAllOverlays, engine.dll + 0xAB780,
void, __fastcall, (bool bRender))
// clang-format on
{
EnterCriticalSection(s_OverlayMutex);

OverlayBase_t* pCurrOverlay = *s_pOverlays; // rbx
OverlayBase_t* pPrevOverlay = nullptr; // rsi
OverlayBase_t* pNextOverlay = nullptr; // rdi

int m_nCreationTick; // eax
bool bShouldDraw; // zf
int m_pUnk; // eax

while (pCurrOverlay)
{
if (OverlayBase_t__IsDead(pCurrOverlay))
{
if (pPrevOverlay)
{
pPrevOverlay->m_pNextOverlay = pCurrOverlay->m_pNextOverlay;
}
else
{
*s_pOverlays = pCurrOverlay->m_pNextOverlay;
}

pNextOverlay = pCurrOverlay->m_pNextOverlay;
OverlayBase_t__DestroyOverlay(pCurrOverlay);
pCurrOverlay = pNextOverlay;
}
else
{
if (pCurrOverlay->m_nCreationTick == -1)
{
m_pUnk = pCurrOverlay->m_pUnk;

if (m_pUnk == -1)
{
bShouldDraw = true;
}
else
{
bShouldDraw = m_pUnk == *g_nOverlayTickCount;
}
}
else
{
bShouldDraw = pCurrOverlay->m_nCreationTick == *g_nRenderTickCount;
}

if (bShouldDraw && bRender && (Cvar_enable_debug_overlays->GetBool() || pCurrOverlay->m_Type == OVERLAY_SMARTAMMO))
ASpoonPlaysGames marked this conversation as resolved.
Show resolved Hide resolved
{
DrawOverlay(pCurrOverlay);
}

pPrevOverlay = pCurrOverlay;
pCurrOverlay = pCurrOverlay->m_pNextOverlay;
}
}

LeaveCriticalSection(s_OverlayMutex);
}

ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", DebugOverlay, ConVar, (CModule module))
{
AUTOHOOK_DISPATCH()

OverlayBase_t__IsDead = module.Offset(0xACAC0).RCast<OverlayBase_t__IsDeadType>();
OverlayBase_t__DestroyOverlay = module.Offset(0xAB680).RCast<OverlayBase_t__DestroyOverlayType>();

RenderLine = module.Offset(0x192A70).RCast<RenderLineType>();
RenderBox = module.Offset(0x192520).RCast<RenderBoxType>();
RenderWireframeBox = module.Offset(0x193DA0).RCast<RenderBoxType>();
sEngineModule = reinterpret_cast<HMODULE>(module.m_nAddress);
RenderWireframeSweptBox = module.Offset(0x1945A0).RCast<RenderWireframeSweptBoxType>();
RenderTriangle = module.Offset(0x193940).RCast<RenderTriangleType>();
RenderAxis = module.Offset(0x1924D0).RCast<RenderAxisType>();
RenderSphere = module.Offset(0x194170).RCast<RenderSphereType>();
RenderUnknown = module.Offset(0x1924E0).RCast<RenderUnknownType>();

s_OverlayMutex = module.Offset(0x10DB0A38).RCast<LPCRITICAL_SECTION>();

s_pOverlays = module.Offset(0x10DB0968).RCast<OverlayBase_t**>();

g_nRenderTickCount = module.Offset(0x10DB0984).RCast<int*>();
g_nOverlayTickCount = module.Offset(0x10DB0980).RCast<int*>();

// not in g_pCVar->FindVar by this point for whatever reason, so have to get from memory
ConVar* Cvar_enable_debug_overlays = module.Offset(0x10DB0990).RCast<ConVar*>();
Cvar_enable_debug_overlays = module.Offset(0x10DB0990).RCast<ConVar*>();
Cvar_enable_debug_overlays->SetValue(false);
Cvar_enable_debug_overlays->m_pszDefaultValue = (char*)"0";
Cvar_enable_debug_overlays->AddFlags(FCVAR_CHEAT);
Expand Down