Skip to content

Commit

Permalink
Add instance and portal drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
TheIndra55 committed Feb 4, 2024
1 parent 2d1683c commit 347d611
Show file tree
Hide file tree
Showing 9 changed files with 365 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/Hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "modules/ModLoader.h"
#include "modules/Patches.h"
#include "modules/Frontend.h"
#include "modules/Draw.h"
#include "modules/camera/FreeCamera.h"

#include "cdc/render/PCDeviceManager.h"
Expand Down Expand Up @@ -138,6 +139,7 @@ void Hook::RegisterModules()
RegisterModule<LevelModule>();
RegisterModule<Frontend>();
RegisterModule<Render>();
RegisterModule<Draw>();
#else
RegisterModule<ScriptLog>();
#endif
Expand Down
20 changes: 20 additions & 0 deletions src/instance/Enemy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

class EnemyHealth
{
public:
float m_hitPoints;
float m_damageSinceMove;
};

class EnemyData
{
public:
#ifdef TR7
char pad1[5040];
#else
char pad1[5280];
#endif

EnemyHealth m_health;
};
38 changes: 37 additions & 1 deletion src/level/Level.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include "cdc/math/Vector.h"

struct Intro;
struct StreamUnitPortal;
struct Signal;
struct Instance;
struct KDNode;
struct StreamUnit;

struct IndexedFace
{
Expand All @@ -20,6 +20,18 @@ struct IndexedFace
unsigned __int8 materialType;
};

struct SignalFace
{
unsigned __int16 i0;
unsigned __int16 i1;
unsigned __int16 i2;

char adjacencyFlags;
char collisionFlags;

unsigned __int16 id;
};

struct MeshVertex
{
__int16 x;
Expand Down Expand Up @@ -79,6 +91,24 @@ struct TerrainGroup
char pad1[116];
};

struct StreamUnitPortal
{
char tolevelname[30];

__int16 toSignalID;
__int16 MSignalID;
__int16 streamID;

unsigned __int16* closeVertList;
float activeDistance;
StreamUnit* toStreamUnit;

cdc::Vector3 min;
cdc::Vector3 max;
cdc::Vector3 quad[4];
cdc::Vector3 normal;
};

struct Terrain
{
__int16 UnitChangeFlags;
Expand Down Expand Up @@ -108,4 +138,10 @@ struct Level
void* splineCameraData;

void* relocModule; // Pointer to script executable

char pad2[84];

void* pCdcPlannerData;
void* pAreaDBase;
void* pUnitData;
};
232 changes: 232 additions & 0 deletions src/modules/Draw.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#include <string>
#include <imgui.h>

#include "Draw.h"
#include "render/Font.h"
#include "render/Draw.h"
#include "game/Game.h"
#include "instance/Instances.h"
#include "instance/Enemy.h"

void Draw::OnMenu()
{
if (ImGui::BeginMenu("Draw"))
{
ImGui::MenuItem("Draw instances", nullptr, &m_drawInstances);
ImGui::MenuItem("Draw markup", nullptr, &m_drawMarkUp);
ImGui::MenuItem("Draw enemy route", nullptr, &m_drawEnemyRouting);
ImGui::MenuItem("Draw collision", nullptr, &m_drawCollision);
ImGui::MenuItem("Draw portals", nullptr, &m_drawPortals);
ImGui::MenuItem("Draw signals", nullptr, &m_drawSignals);

ImGui::EndMenu();
}
}

void Draw::OnFrame()
{
auto gameTracker = Game::GetGameTracker();
auto level = gameTracker->level;

if (m_drawInstances || m_drawEnemyRouting)
{
DrawInstances();
}

if (m_drawMarkUp)
{
DrawMarkUp();
}

if (level)
{
if (m_drawCollision)
{
DrawCollision(level);
}

if (m_drawPortals)
{
DrawPortals(level);
}

if (m_drawSignals)
{
DrawSignals(level);
}
}
}

void Draw::OnDraw()
{
if (m_drawInstances)
{
ImGui::Begin("Draw options");

// Filter
ImGui::InputText("Filter", m_filter, sizeof(m_filter));

// Options
ImGui::Checkbox("Draw intro", &m_drawIntro);
ImGui::Checkbox("Draw family", &m_drawFamily);
ImGui::Checkbox("Draw animations", &m_drawAnimation);
ImGui::Checkbox("Draw health", &m_drawHealth);

ImGui::End();
}
}

void Draw::DrawInstances()
{
// Iterate through all instances
Instances::Iterate([this](Instance* instance)
{
// Draw the instance info
if (m_drawInstances)
{
DrawInstance(instance);
}

// Draw the route
if (m_drawEnemyRouting)
{
DrawEnemyRoute(instance);
}
});
}

void Draw::DrawInstance(Instance* instance)
{
auto name = instance->object->name;
auto data = (ObjectData*)instance->data;

// Check filter
if (strlen(m_filter) > 0 && strstr(name, m_filter) == 0)
{
return;
}

cdc::Vector3 position;
TRANS_RotTransPersVectorf(&instance->position, &position);

// Check if the instance position is on screen
if (position.z > 16.f)
{
auto font = Font::GetMainFont();
auto heigth = font->GetHeight();

// Draw the instance name
font->SetCursor(position.x, position.y);
font->Print("%s", name);

// Draw intro
if (m_drawIntro)
{
position.y += heigth;

font->SetCursor(position.x, position.y);
font->Print("Intro: %d", instance->introUniqueID);
}

// Draw family
if (m_drawFamily && data)
{
position.y += heigth;

font->SetCursor(position.x, position.y);
font->Print("Family: %d", data->family);
}

// Draw enemy health
if (m_drawHealth && data && data->family == 0xDAF0)
{
position.y += heigth;

auto extraData = (EnemyData*)instance->extraData;

font->SetCursor(position.x, position.y);
font->Print("Health: %g", extraData->m_health.m_hitPoints);
}

// Draw animations
if (m_drawAnimation)
{
// Draw all allocated sections
for (int section = 0; section < instance->animComponent->mAnimProcessor->mSectionsAllocated; section++)
{
// Go to the next line
position.y += heigth;
font->SetCursor(position.x, position.y);

// Query the current animation
auto currentAnim = G2EmulationInstanceQueryAnimation(instance, section);

// Can be null for some reason
if (instance->object->animList)
{
// (Section): (Anim index) (Anim ID)
font->Print("Anim %d: %d (%X)", section, currentAnim, instance->object->animList[currentAnim].animationID);
}
else
{
font->Print("Anim %d: %d", section, currentAnim);
}
}
}
}
}

void Draw::DrawEnemyRoute(Instance* instance)
{
auto data = (ObjectData*)instance->data;

// Check if the instance is an enemy
if (!data || data->family != 0xDAF0)
{
return;
}
}

void Draw::DrawMarkUp()
{
}

void Draw::DrawCollision(Level* level)
{
}

void Draw::DrawCollision(TerrainGroup* terrainGroup)
{
}

void Draw::DrawPortals(Level* level)
{
auto terrain = level->terrain;
auto font = Font::GetMainFont();

for (int i = 0; i < terrain->numStreamUnitPortals; i++)
{
auto portal = &terrain->streamUnitPortals[i];
auto position = portal->min;

position += &portal->max;
position /= 2;

TRANS_RotTransPersVectorf(&position, &position);

// Check if the portal is on screen
if (position.z > 16.f)
{
// Draw the portal destination
font->SetCursor(position.x, position.y);
font->PrintCentered("Portal to %s", portal->tolevelname);

// Draw the portal bounds
DrawPlane(&portal->min, &portal->max, RGBA(0, 0, 255, 10));
}
}
}

void Draw::DrawSignals(Level* level)
{
}
39 changes: 39 additions & 0 deletions src/modules/Draw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include "Module.h"

struct Level;
struct Instance;
struct TerrainGroup;

class Draw : public Module
{
private:
bool m_drawInstances = false;
bool m_drawMarkUp = false;
bool m_drawEnemyRouting = false;
bool m_drawCollision = false;
bool m_drawPortals = false;
bool m_drawSignals = false;

bool m_drawIntro = false;
bool m_drawFamily = false;
bool m_drawHealth = false;
bool m_drawAnimation = false;

char m_filter[100] = "";

void DrawInstances();
void DrawInstance(Instance* instance);
void DrawEnemyRoute(Instance* instance);
void DrawMarkUp();
void DrawCollision(Level* level);
void DrawCollision(TerrainGroup* group);
void DrawPortals(Level* level);
void DrawSignals(Level* level);

public:
void OnMenu();
void OnDraw();
void OnFrame();
};
Loading

0 comments on commit 347d611

Please sign in to comment.