Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS

Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
This commit is contained in:
Cyd
2026-06-24 21:28:16 -05:00
commit 2b8ca921cb
66341 changed files with 7923174 additions and 0 deletions
@@ -0,0 +1,917 @@
#include "MW4Headers.hpp"
#include "AI_DebugRenderer.hpp"
#include <Adept\EntityManager.hpp>
#include <Adept\CameraComponent.hpp>
#include <Adept\VideoRenderer.hpp>
#include "CombatAI.hpp"
#include "MWDamageObject.hpp"
#include <MW4\MWMission.hpp>
#include <ElementRenderer\StateChange.hpp>
#include "AIUtils.hpp"
#include "MWPlayer.hpp"
#include "VehicleInterface.hpp"
#include <stdlib.h>
#include "rail_move.hpp"
#include "Flag.hpp"
#include <GameOS\ToolOS.hpp>
using namespace MW4AI;
using namespace MechWarrior4;
extern MW4AI::CPathManager *g_PathManager;
const Stuff::Scalar max_distance_from_camera_to_draw = 500.0f;
const Stuff::Scalar max_distance_from_camera_to_draw_squared = max_distance_from_camera_to_draw * max_distance_from_camera_to_draw;
const int max_line_cloud_points = 500;
const int wheel_move_pixels = 32;
const int max_wheel_move_pixels = 1000;
const unsigned int max_spew_files = 2000;
DebugRenderer* DebugRenderer::m_Instance = 0;
MechWarrior4::CombatAI* GetCombatAI(MechWarrior4::MWObject& v)
{
Verify(&v != 0);
if ((v.GetAI() == 0) ||
(v.GetAI()->IsDerivedFrom(CombatAI::DefaultData) == false))
{
return (0);
}
CombatAI* combat_ai = Cast_Object(CombatAI*,v.GetAI());
Check_Object(combat_ai);
return (combat_ai);
}
MechWarrior4::CombatAI* GetCombatAI()
{
if (Adept::Player::GetInstance() == 0)
{
return (0);
}
MechWarrior4::MWPlayer* p = Cast_Object(MechWarrior4::MWPlayer*,Adept::Player::GetInstance());
if (p == 0)
{
return (0);
}
Check_Object(p);
if ((p->GetInterface() == 0) ||
(p->GetInterface()->vehicle == 0))
{
return (0);
}
return (GetCombatAI(*(p->GetInterface()->vehicle)));
}
DebugRenderer::DebugRenderer()
: m_AIStatsRendering(STATS_NONE)
, m_DrawingMovementLines(false)
, m_DrawingMovementPaths(false)
, m_DamageInfoRendering(false)
, m_PointCount(0)
, m_DeadReckoningRenderTime(0)
, m_ShowNumPathRequests(false)
, m_WheelDelta(0)
, m_LastDiagnosticSpewFileIndex(0)
{
Verify(m_Instance == 0);
m_Instance = this;
gos_PushCurrentHeap(ElementRenderer::g_Heap);
m_LineCloud = new ElementRenderer::LineCloudElement(max_line_cloud_points);
gos_PopCurrentHeap();
m_LineCloud->SetDataPointers(&m_PointCount, m_PointData, m_ColorData);
m_LineCloud->m_localOBB.localToParent = LinearMatrix4D::Identity;
m_LineCloud->m_localOBB.sphereRadius = -1;
Mission::GetInstance()->GetElement()->AttachChild(m_LineCloud);
}
DebugRenderer::~DebugRenderer()
{
Verify(m_Instance != 0);
m_Instance = 0;
}
void DebugRenderer::Execute()
{
#ifdef _ARMOR
try
{
#endif
ResetLinesToDraw();
if ((GetAIStatsRendering() != STATS_NONE) ||
(GetDamageInfoRendering() == true))
{
DrawAIStatsAndDamageInfo();
}
if ((GetMovementLineRendering() == true) ||
(GetDeadReckoningRendering() == true))
{
DrawLines();
}
if (GetMovementPathRendering() == true)
{
DrawMovementPaths();
}
if (GetShowNumPathRequests() == true)
{
DrawNumPathRequests();
}
if (GetDiagnosticsRendering() == true)
{
DrawDiagnostics();
}
#ifdef _ARMOR
}
catch (...)
{
}
#endif
}
void DebugRenderer::DrawAIStatsAndDamageInfo()
{
Verify((GetAIStatsRendering() != STATS_NONE) || (GetDamageInfoRendering() == true));
#ifdef LAB_ONLY
if ((Adept::EntityManager::GetInstance() == 0) ||
(Adept::VideoRenderer::Instance == 0))
{
return;
}
Check_Object(Adept::EntityManager::GetInstance());
Check_Object(Adept::VideoRenderer::Instance);
CameraComponent* camera = Adept::VideoRenderer::Instance->GetSceneCamera();
if ((camera == 0) ||
(camera->GetElement() == 0))
{
return;
}
Check_Object(camera);
Point3D camera_pos = (Point3D)camera->GetElement()->GetLocalToWorld();
HGOSFONT3D font = gos_LoadFont("Assets\\Graphics\\arial8.tga", 0);
gos_TextSetAttributes(font,0x8FFF0000,1.0f,false,true,false,false);
std::vector<Adept::Entity*> entities_to_consider;
NameTable *table = NameTable::GetInstance();
int size(table->nameTableArray[NameTable::VehicleArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data = &table->nameTableArray [NameTable::VehicleArray][i];
Adept::Entity* ent = data->dataPointer->GetCurrent ();
if ((ent != 0) &&
(ent->IsDerivedFrom(MWObject::DefaultData) == true))
{
entities_to_consider.push_back(Cast_Object(MWObject*,ent));
}
}}
if (Adept::NameTable::GetInstance() != 0)
{
{
int last = Adept::NameTable::GetInstance()->GetLength(Adept::NameTable::BuildingArray);
{for (int i = 0;
i < last;
++i)
{
NameTableEntry* entry = Adept::NameTable::GetInstance()->FindEntry(Adept::NameTable::BuildingArray,i);
if ((entry != 0) &&
(entry->dataPointer->GetCurrent() != 0))
{
Adept::Entity* entity = entry->dataPointer->GetCurrent();
if (entity->IsDerivedFrom(MWObject::DefaultData) == true)
{
MWObject* mwobject = Cast_Object(MWObject*,entity);
if (mwobject->GetAI() != 0)
{
entities_to_consider.push_back(mwobject);
}
}
}
}}
}
{
int last = Adept::NameTable::GetInstance()->GetLength(Adept::NameTable::TurretArray);
{for (int i = 0;
i < last;
++i)
{
NameTableEntry* entry = Adept::NameTable::GetInstance()->FindEntry(Adept::NameTable::TurretArray,i);
if ((entry != 0) &&
(entry->dataPointer->GetCurrent() != 0))
{
Adept::Entity* entity = entry->dataPointer->GetCurrent();
if (entity->IsDerivedFrom(MWObject::DefaultData) == true)
{
entities_to_consider.push_back(entity);
}
}
}}
}
}
{
int size(Adept::NameTable::GetInstance()->nameTableArray[NameTable::FlagArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data = &Adept::NameTable::GetInstance()->nameTableArray [NameTable::FlagArray][i];
Adept::Entity* ent = data->dataPointer->GetCurrent();
if ((ent != 0) &&
(ent->IsDerivedFrom(Flag::DefaultData) == true))
{
entities_to_consider.push_back(ent);
}
}}
}
{for (std::vector<Adept::Entity*>::const_iterator i = entities_to_consider.begin();
i != entities_to_consider.end();
++i)
{
Point3D pos = (Point3D)(*i)->GetLocalToWorld();
Vector3D delta_from_camera;
delta_from_camera.Subtract(pos,camera_pos);
delta_from_camera.y = 0;
if (delta_from_camera.GetLengthSquared() > max_distance_from_camera_to_draw_squared)
{
continue;
}
Stuff::Vector2DOf<Stuff::Scalar> screen_pos;
if (WorldToScreenCoords(pos,screen_pos) == false)
{
continue;
}
screen_pos.x *= Environment.screenWidth;
screen_pos.y *= Environment.screenHeight;
if ((screen_pos.x >= Environment.screenWidth) ||
(screen_pos.y >= Environment.screenHeight))
{
continue;
}
if (PositionIsInFrontOfCamera(pos) == false)
{
continue;
}
int alpha = 0xFF000000 - ((int)((DistanceFromCamera(pos) * 200.0f) / max_distance_from_camera_to_draw) << 24);
int color = 0;
switch ((*i)->objectID & 0x00000007)
{
case 1: color = 0x008F8F8F; break;
case 2: color = 0x0000008F; break;
case 3: color = 0x00008F00; break;
case 4: color = 0x008F0000; break;
case 5: color = 0x008F008F; break;
case 6: color = 0x00008F8F; break;
case 7: color = 0x008F8F00; break;
}
gos_TextSetAttributes(font,alpha + color,1.0f,false,true,false,false);
gos_TextSetRegion((int)screen_pos.x,(int)screen_pos.y,Environment.screenWidth,Environment.screenHeight);
gos_TextSetPosition((int)screen_pos.x,(int)screen_pos.y);
std::string s;
if ((*i)->IsDerivedFrom(MWObject::DefaultData) == true)
{
MWObject* mwobject = Cast_Object(MWObject*,*i);
if ((GetAIStatsRendering() == STATS_ALL) ||
((GetAIStatsRendering() == STATS_CURRENT_VEHICLE) && (mwobject->GetAI() == GetCombatAI())))
{
mwobject->AddStatsToString(s);
if (mwobject->GetAI() != 0)
{
mwobject->GetAI()->AddStatsToString(s);
}
}
if (GetDamageInfoRendering() == true)
{
mwobject->AddDamageInfoToString(s);
}
}
else
{
if ((*i)->IsDerivedFrom(Flag::DefaultData) == true)
{
Flag* flag = Cast_Object(Flag*,*i);
flag->AddStatsToString(s);
}
}
gos_TextDraw(s.c_str());
gos_TextSetAttributes(font,0xFFFF0000,1.0f,false,true,false,false);
}}
gos_DeleteFont(font);
#endif
}
void DebugRenderer::DrawNumPathRequests()
{
#ifdef LAB_ONLY
Verify(GetShowNumPathRequests() == true);
HGOSFONT3D font = gos_LoadFont("Assets\\Graphics\\arial8.tga", 0);
gos_TextSetAttributes(font,0xFFFFFFFF,1.0f,false,true,false,false);
gos_TextSetRegion(0,0,Environment.screenWidth,Environment.screenHeight);
gos_TextSetPosition(10,2);
std::string s = "Path Requests: ";
s += IntToString(MW4AI::g_PathManager->GetNumPathRequests());
gos_TextDraw(s.c_str());
gos_DeleteFont(font);
#endif
}
bool DebugRenderer::PositionIsInFrontOfCamera(const Stuff::Point3D& pos) const
{
if (Adept::VideoRenderer::Instance == 0)
{
return (false);
}
CameraComponent* camera = Adept::VideoRenderer::Instance->GetSceneCamera();
if ((camera == 0) ||
(camera->GetElement() == 0))
{
return (false);
}
Check_Object(camera);
Stuff::LinearMatrix4D matrix = camera->GetElement()->GetLocalToWorld();
if (pos == (Stuff::Point3D)matrix)
{
return (true);
}
return (GetSquaredDistToMatrixForward(pos,matrix) < GetSquaredDistToMatrixBackward(pos,matrix));
}
Stuff::Scalar DebugRenderer::DistanceFromCamera(const Stuff::Point3D& pos) const
{
if (Adept::VideoRenderer::Instance == 0)
{
return (false);
}
CameraComponent* camera = Adept::VideoRenderer::Instance->GetSceneCamera();
if ((camera == 0) ||
(camera->GetElement() == 0))
{
return (false);
}
Check_Object(camera);
Stuff::Vector3D delta;
delta.Subtract((Stuff::Point3D)camera->GetElement()->GetLocalToWorld(),pos);
return (delta.GetApproximateLength());
}
void DebugRenderer::DrawLines()
{
Verify(GetMovementLineRendering() == true);
#ifdef LAB_ONLY
NameTable *table = NameTable::GetInstance();
int size(table->nameTableArray[NameTable::VehicleArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data = &table->nameTableArray [NameTable::VehicleArray][i];
Adept::Entity* ent = data->dataPointer->GetCurrent ();
if ((ent != 0) &&
(ent->IsDestroyed() == false) &&
(ent->IsDerivedFrom(MWObject::DefaultData) == true))
{
MWObject* v = Cast_Object(MWObject*,ent);
Verify(v != 0);
Check_Object(v);
if ((GetMovementLineRendering() == true) &&
(GetCombatAI(*v) != 0))
{
std::vector<Stuff::Point3D> points;
GetCombatAI(*v)->GetDirectPath(points);
if (points.size() > 0)
{
// points[0].y += 8.0f;
// points[1].y += 8.0f;
AddPointsToLinesToDraw(points,Stuff::RGBAColor(0xFF,0,0,0));
}
}
if (GetDeadReckoningRendering() == true)
{
std::vector<Stuff::Point3D> points;
points.push_back((Stuff::Point3D)v->GetLocalToWorld());
Stuff::Point3D temp;
points.push_back(v->EstimateFuturePosition(&temp, (Scalar)m_DeadReckoningRenderTime));
points[0].y += 6.0f;
points[1].y += 6.0f;
AddPointsToLinesToDraw(points,Stuff::RGBAColor(0,0,0xFF,0));
}
}
}}
DrawLineCloud();
#endif
}
void DebugRenderer::DrawLineCloud()
{
#ifdef LAB_ONLY
gos_PushCurrentHeap(ElementRenderer::g_Heap);
if (m_PointCount > 0)
{
{for (int i = 0;
i < m_PointCount;
++i)
{
Scalar length = m_PointData[i].GetLengthSquared();
if (length > m_LineCloud->m_localOBB.sphereRadius)
{
m_LineCloud->m_localOBB.sphereRadius = length;
}
}}
m_LineCloud->NeedNewBounds();
m_LineCloud->NeedMatrixSync();
ElementRenderer::StateChange *state = new ElementRenderer::StateChange();
Check_Object(state);
state->DisableZBufferCompare();
m_LineCloud->AdoptStateChange(state);
m_LineCloud->Sync();
}
gos_PopCurrentHeap();
#endif
}
void DebugRenderer::DrawMovementPaths()
{
Verify(GetMovementPathRendering() == true);
#ifdef LAB_ONLY
NameTable *table = NameTable::GetInstance();
int size(table->nameTableArray[NameTable::VehicleArray].GetLength());
{for (int i = 0;
i < size;
++i)
{
NameTableEntry *data = &table->nameTableArray [NameTable::VehicleArray][i];
Adept::Entity* ent = data->dataPointer->GetCurrent ();
if ((ent != 0) &&
(ent->IsDerivedFrom(Vehicle::DefaultData) == true))
{
Check_Object(ent);
Vehicle* v = Cast_Object(Vehicle*,ent);
Verify(v != 0);
Check_Object(v);
if (GetCombatAI(*v) != 0)
{
MW4AI::CRailPath* cur_path = GetCombatAI(*v)->getCurPath();
if (cur_path != 0)
{
Stuff::Point3D my_pos(v->GetLocalToWorld());
std::vector<Stuff::Point3D> path;
cur_path->PointList(path);
if (path.size () == 0)
continue;
path.insert(path.begin(),my_pos);
{for (int i = 1;
i < path.size();
++i)
{
std::vector<Stuff::Point3D> path2;
path2.push_back(path[i-1]);
path2.push_back(path[i]);
path2[0].y = my_pos.y + 7.0f;
path2[1].y = my_pos.y + 7.0f;
AddPointsToLinesToDraw(path2,Stuff::RGBAColor(0,0xFF,0,0));
}}
}
}
}
}}
DrawLineCloud();
#endif
}
DebugRenderer::STATS_RENDERING DebugRenderer::GetAIStatsRendering() const
{
return (m_AIStatsRendering);
}
void DebugRenderer::SetAIStatsRendering(DebugRenderer::STATS_RENDERING fDrawStats)
{
m_AIStatsRendering = fDrawStats;
}
bool DebugRenderer::GetDamageInfoRendering() const
{
return (m_DamageInfoRendering);
}
void DebugRenderer::SetDamageInfoRendering(bool fDrawDamageInfo)
{
m_DamageInfoRendering = fDrawDamageInfo;
}
bool DebugRenderer::GetMovementLineRendering() const
{
return (m_DrawingMovementLines);
}
void DebugRenderer::SetMovementLineRendering(bool fDrawMovementLines)
{
m_DrawingMovementLines = fDrawMovementLines;
}
bool DebugRenderer::GetMovementPathRendering() const
{
return (m_DrawingMovementPaths);
}
void DebugRenderer::SetMovementPathRendering(bool fDrawMovementPaths)
{
m_DrawingMovementPaths = fDrawMovementPaths;
}
DebugRenderer* DebugRenderer::GetInstance()
{
return (m_Instance);
}
bool DebugRenderer::WorldToScreenCoords(const Stuff::Point3D& world_coords,
Stuff::Vector2DOf<Stuff::Scalar>& screen_coords) const
{
if (Adept::VideoRenderer::Instance == 0)
{
return (false);
}
CameraComponent* camera = Adept::VideoRenderer::Instance->GetSceneCamera();
if ((camera == 0) ||
(camera->GetElement() == 0))
{
return (false);
}
Check_Object(camera);
camera->ComputeCursor(&screen_coords,world_coords);
return (true);
}
void DebugRenderer::ResetLinesToDraw()
{
m_PointCount = 0;
}
void DebugRenderer::AddPointsToLinesToDraw(const std::vector<Stuff::Point3D>& points, const Stuff::RGBAColor& color)
{
if (m_PointCount >= max_line_cloud_points)
{
return;
}
{for (std::vector<Stuff::Point3D>::const_iterator i = points.begin();
i != points.end();
++i)
{
m_PointData[m_PointCount] = *i;
// m_PointData[m_PointCount].y += 8.0f;
m_ColorData[m_PointCount] = color;
++m_PointCount;
if (m_PointCount >= max_line_cloud_points)
{
return;
}
}}
}
void DebugRenderer::SetDeadReckoningRenderTime(Stuff::Time time)
{
m_DeadReckoningRenderTime = time;
}
Stuff::Time DebugRenderer::GetDeadReckoningRenderTime() const
{
return (m_DeadReckoningRenderTime);
}
bool DebugRenderer::GetDeadReckoningRendering() const
{
return (m_DeadReckoningRenderTime > 0);
}
bool DebugRenderer::GetShowNumPathRequests() const
{
return (m_ShowNumPathRequests);
}
void DebugRenderer::SetShowNumPathRequests(bool fShow)
{
m_ShowNumPathRequests = fShow;
}
bool DebugRenderer::GetDiagnosticsRendering() const
{
if ((MWMission::GetInstance() == 0) ||
(MWMission::GetInstance()->IsDerivedFrom(MWMission::DefaultData) == false))
{
return (false);
}
Check_Object(MWMission::GetInstance());
MWMission *mission = Cast_Object(MWMission*,MWMission::GetInstance());
return (mission->GetDiagnosticsInterface().GetEnabled());
}
bool EraseSpewFile(unsigned int index)
{
std::string s = "AISpew\\spew.";
std::string suffix = IntToString(index);
while (suffix.size() < 4)
{
suffix = "0" + suffix;
}
s += suffix;
if (gos_DoesFileExist(s.c_str()) == true)
{
gos_DeleteFile(s.c_str());
return (true);
}
return (false);
}
void EraseExistingSpewFiles()
{
bool erased0 = EraseSpewFile(0);
bool erasedmax = EraseSpewFile(max_spew_files);
if ((erased0 == false) &&
(erasedmax == false))
{
return;
}
unsigned int i = 1;
bool previous = false;
while (i < max_spew_files)
{
previous = EraseSpewFile(i);
++i;
}
if (erasedmax == true)
{
++i;
}
if (previous == true)
{
while (EraseSpewFile(i) == true)
{
++i;
}
}
}
void SpewEntityInfo(Adept::Entity& entity, std::string& string, bool include_geometry_info = false)
{
string += "ObjectID: ";
string += IntToString(entity.objectID);
string += "; Name: ";
string += entity.instanceName;
if (include_geometry_info == true)
{
string += "\n Position: (";
Stuff::Point3D pos(entity.GetLocalToWorld());
string += ScalarToString(pos.x);
string += ",";
string += ScalarToString(pos.y);
string += ",";
string += ScalarToString(pos.z);
string += ")";
if (entity.IsDerivedFrom(MechWarrior4::Vehicle::DefaultData) == true)
{
MechWarrior4::Vehicle* v = Cast_Object(MechWarrior4::Vehicle*,&entity);
Check_Object(v);
string += "; Velocity: ";
string += ScalarToString(v->currentSpeedMPS);
string += " mps";
}
else
{
string += "; [not a vehicle]";
}
}
}
void SpewToDiagnosticFile(const std::string& spew_output, unsigned int index)
{
std::string text_to_spew = "Last Compile Date/Time: ";
text_to_spew += __DATE__;
text_to_spew += ", ";
text_to_spew += __TIME__;
text_to_spew += "\nSpewed at gos_GetElapsedTime() = ";
text_to_spew += ScalarToString((Stuff::Scalar)gos_GetElapsedTime());
text_to_spew += "\n";
CombatAI* combat_ai = GetCombatAI();
if (combat_ai != 0)
{
text_to_spew += "Vehicle AI ";
SpewEntityInfo(*combat_ai,text_to_spew);
text_to_spew += "\n\nVehicle ";
SpewEntityInfo(combat_ai->GetSelf(),text_to_spew,true);
text_to_spew += "\n\n";
combat_ai->AddStatsToString(text_to_spew);
if (combat_ai->Target() != 0)
{
text_to_spew += "\n\nTarget ";
SpewEntityInfo(*(combat_ai->Target()),text_to_spew,true);
}
else
{
text_to_spew += "\nNo target.";
}
}
text_to_spew += "\n\n";
text_to_spew += spew_output;
std::string s = "AISpew\\spew.";
std::string suffix = IntToString(index);
while (suffix.size() < 4)
{
suffix = "0" + suffix;
}
s += suffix;
HGOSFILE hGOSfile;
gos_OpenFile(&hGOSfile,s.c_str(),READWRITE);
gos_WriteFile(hGOSfile,text_to_spew.c_str(),text_to_spew.size());
gos_CloseFile(hGOSfile);
}
void DebugRenderer::DrawDiagnostics()
{
#ifdef LAB_ONLY
if ((MWMission::GetInstance() == 0) ||
(MWMission::GetInstance()->IsDerivedFrom(MWMission::DefaultData) == false))
{
return;
}
int wheelDelta = 0;
gos_GetMouseInfo(0,0,0,0,&wheelDelta,0);
if (wheelDelta != 0)
{
if (wheelDelta < 0)
{
m_WheelDelta += wheel_move_pixels;
if (m_WheelDelta > max_wheel_move_pixels)
{
m_WheelDelta = max_wheel_move_pixels;
}
}
else
{
m_WheelDelta -= wheel_move_pixels;
if (m_WheelDelta < 0)
{
m_WheelDelta = 0;
}
}
}
Check_Object(MWMission::GetInstance());
MWMission *mission = Cast_Object(MWMission*,MWMission::GetInstance());
std::string s;
mission->GetDiagnosticsInterface().GetSpew(s);
if (s.size() == 0)
{
return;
}
if (DiagnosticsInterface::GetInstance().GetFileSpewing() == true)
{
if (m_LastDiagnosticSpewFileIndex == 0)
{
EraseExistingSpewFiles();
gos_CreateDirectory("AISpew");
}
if (m_LastDiagnosticSpewFileIndex >= max_spew_files)
{
EraseSpewFile(m_LastDiagnosticSpewFileIndex - max_spew_files);
}
if (s != m_LastDiagnosticSpew)
{
SpewToDiagnosticFile(s,m_LastDiagnosticSpewFileIndex);
++m_LastDiagnosticSpewFileIndex;
}
}
HGOSFONT3D font = gos_LoadFont("Assets\\Graphics\\arial8.tga", 0);
gos_TextSetAttributes(font,0xFF000000,1.0f,false,true,false,false);
gos_TextSetRegion(10,10,Environment.screenWidth,Environment.screenHeight);
gos_TextSetPosition(10,10 - m_WheelDelta);
gos_TextDraw(s.c_str());
gos_DeleteFont(font);
m_LastDiagnosticSpew = s;
#endif
}