#include "stdafx.h"
#include "WireframeMod.h"
#include "UI/GUIManager.h"
#include "Hookers/D3DHooker.h"
using namespace Dargon;
using namespace Dargon::Hookers;
using namespace Dargon::UI;
using namespace Dargon::Mods;
using namespace Dargon::Mods::Graphics;
#define WIREFRAME_ENABLE_COMMAND_NAME "Dargon.Mods.Wireframe.Enable"
//-------------------------------------------------------------------------------------------------
// IDargonRuntimeMod Implementation
//-------------------------------------------------------------------------------------------------
/// <summary>
/// Constructor for the Wireframe Mod. Nothing really happens here.
/// </summary>
WireframeMod::WireframeMod()
{
m_modEnabled = false;
m_wireframeTriggered = false;
}
/// <summary>
/// Destructor for the Wireframe Mod. Nothing really happens here.
/// </summary>
WireframeMod::~WireframeMod()
{
}
/// <summary>
/// Initialization method for the Wireframe Mod.
/// Adds event handlers for DrawPrimative variants.
/// Registers Command Handlers
/// </summary>
bool WireframeMod::Initialize()
{
GUIManager::WriteLine("Wireframe Modification is initializing.");
IConsoleCommandHandler* pEnableCommandHandler = (IConsoleCommandHandler*)new WireframeModEnableCommandHandler(this);
GUIManager::RegisterConsoleCommandHandler(pEnableCommandHandler);
InputHooker::AddKeyEventHandler(&KeyEventHandler);
return true;
}
/// <summary>
/// Prints out the internal state of this object,
/// including whether or not wireframe is enabled.
/// </summary>
void WireframeMod::PrintDebugInformation(ostream& outputStream)
{
outputStream << "Wireframe Mod { Enabled: " << m_modEnabled << ", Triggered: " << m_wireframeTriggered << " }";
}
/// <summary>
/// Exit-Handling method for the Dargon Runtime Mod.
/// No state is saved between games for the Wireframe mod, at the moment.
/// </summary>
bool WireframeMod::Exit()
{
return true;
}
//-------------------------------------------------------------------------------------------------
// IInputListener Implementation
//-------------------------------------------------------------------------------------------------
void WireframeMod::KeyEventHandler(KeyEventArgs* pEventArgs)
{
if(pEventArgs->GetEventType() == KET_KEYDOWN)
{
if(pEventArgs->GetVKey() == VK_LWIN)
m_wireframeTriggered = !m_wireframeTriggered;
}
}
//-------------------------------------------------------------------------------------------------
// Event Handlers
//-------------------------------------------------------------------------------------------------
/// <summary>
/// Before DrawPrimative is called, we check to see if we're rendering transformed
/// vertices. If so, we allow them to be rendered in the solid fill-mode.
/// If Dargon itself is rendering, then we do not go into wireframe mode.
/// If we're rendering untransformed vertices, we render them in wireframe, as they are
/// assumed to be in some form of world space.
///
/// As a result, the HUD remains rendered properly.
/// </summary>
HRESULT WINAPI WireframeMod::PreDrawPrimativeHandler(IDirect3DDevice9* m_pDevice, D3DPRIMITIVETYPE primitiveType, UINT startVertex, UINT primitiveCount)
{
DWORD fvf;
m_pDevice->GetFVF(&fvf);
if((fvf & D3DFVF_XYZRHW) > 0) //It's a transformed vertex buffer, so we assume it to be a HUD element.
{
m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
}else if(GUIManager::IsWireframeEnabled()) //It's an untransformed vertex buffer, so we assume it to be a world element.
{
m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
}
/// <summary>
/// After rendering, we set the Direct3D Device's fill-mode back to solid.
/// </summary>
HRESULT WINAPI WireframeMod::PostDrawPrimativeHandler(IDirect3DDevice9* m_pDevice, D3DPRIMITIVETYPE primitiveType, UINT startVertex, UINT primitiveCount)
{
//Restore render state to solid.
m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
}
/// <summary>
/// For the purposes of the Wireframe Mod, Draw Primative and Draw Indexed Primative do the same thing.
/// </summary>
HRESULT WINAPI WireframeMod::PreDrawIndexedPrimative(IDirect3DDevice9* m_pDevice, D3DPRIMITIVETYPE primitiveType, INT baseVertexIndex, UINT minVertexIndex, UINT numVertices, UINT startIndex, UINT primCount)
{
PreDrawPrimativeHandler(m_pDevice, primitiveType, startIndex, primCount);
}
/// <summary>
/// For the purposes of the Wireframe Mod, Draw Primative and Draw Indexed Primative do the same thing.
/// </summary>
HRESULT WINAPI WireframeMod::PostDrawIndexedPrimative(IDirect3DDevice9* m_pDevice, D3DPRIMITIVETYPE primitiveType, INT baseVertexIndex, UINT minVertexIndex, UINT numVertices, UINT startIndex, UINT primCount)
{
PostDrawPrimativeHandler(m_pDevice, primitiveType, startIndex, primCount);
}
//-------------------------------------------------------------------------------------------------
// Console Command Handler Implementations
//-------------------------------------------------------------------------------------------------
/// <summary>
/// Wireframe Mod Enable Command Handler Constructor - Simply stores a pointer to the associated mod
/// </summary>
WireframeMod::WireframeModEnableCommandHandler::WireframeModEnableCommandHandler(WireframeMod* pMod)
{
this->m_pWireframeMod = pMod;
}
/// <summary>
/// Destructor for the Wireframe Mod Enable Command Handler, which does nothing.
/// </summary>
WireframeMod::WireframeModEnableCommandHandler::~WireframeModEnableCommandHandler()
{
}
/// <summary>
/// Returns the name of the mod as defined in WIREFRAME_ENABLE_COMMAND_NAME
/// </summary>
string WireframeMod::WireframeModEnableCommandHandler::GetName() const
{
return WIREFRAME_ENABLE_COMMAND_NAME;
}
/// <summary>
/// Returns how to use run the given command
/// </summary>
string WireframeMod::WireframeModEnableCommandHandler::GetInputFormat() const
{
return GetName() + " [boolean Enable]";
}
/// <summary>
/// Returns a comment for the given Wireframe Mod Enable Command Handler
/// </summary>
string WireframeMod::WireframeModEnableCommandHandler::GetComment() const
{
return "This command is used to enable or disable the Wireframe Mod, which, if enabled, \
makes the game's world elements render in wireframe";
}
/// <summary>
/// Gets the Wireframe Mod associated with this command.
/// </summary>
IDargonRuntimeMod* WireframeMod::WireframeModEnableCommandHandler::GetAssociatedMod() const
{
return this->m_pWireframeMod;
}
/// <summary>
/// Runs the Console Command with the given arguments.
/// </summary>
void WireframeMod::WireframeModEnableCommandHandler::Run(int argc, string* argv)
{
bool enableWireframe = false;
if(argc == 1 && Parser::ParseBoolean(argv[0], &enableWireframe)) //Try to parse boolean. If fails, throw
{
stringstream ss;
ss << "Setting Wireframe Enabled to " << argv[0] << "(Parsed as: " << enableWireframe << ")";
m_pWireframeMod->m_modEnabled = enableWireframe;
GUIManager::WriteLine(ss.str());
}else{
GUIManager::WriteLine("RendererEnableWireframe Help:");
GUIManager::WriteLine(" Format: RendererEnableWireframe [boolean value]");
GUIManager::WriteLine(" Parameters: ");
GUIManager::WriteLine(" value: Whether or not to enable wireframe rendering.");
}
}