Files
Cyd 2b8ca921cb 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.
2026-06-24 21:28:16 -05:00

606 lines
16 KiB
C++

#include "MW4Headers.hpp"
#if !defined(NO_MR)
#include "review_playback.hpp"
#include "missionreview.hpp"
#include "mwapplication.hpp"
#include "ShellScriptHeaders.hpp"
#include "..\missionlang\resource.h"
using namespace MechWarrior4;
namespace NMissionReview
{
Stuff::Scalar m_MapDispX; // display location of map
Stuff::Scalar m_MapDispY;
Stuff::Scalar m_MapDispWidth;
Stuff::Scalar m_MapDispHeight;
Stuff::Scalar m_MapTop; // map coord at topleft of screen
Stuff::Scalar m_MapLeft;
Stuff::Scalar m_MapWidth;
Stuff::Scalar m_MapHeight;
Stuff::Scalar m_MapScaleX; // screen coords to map coords
Stuff::Scalar m_MapScaleY;
Stuff::Scalar m_MapMeterDisplayX; // meters to display on the screen
Stuff::Scalar m_MapMeterDisplayY;
Stuff::Scalar m_MapTargetLeft,m_MapTargetTop;
int m_CenteredMech,m_LastCenteredMech;
bool m_Paused,m_CenteringX,m_CenteringY;
Stuff::Scalar m_CurrentTime = 0;
Stuff::Scalar m_LoadedTime = 0;
Stuff::Scalar m_TotalTime = 0;
Stuff::Scalar m_SampleRate = 0;
Stuff::Scalar m_PlayBackRate = 0;
Stuff::Time m_LastTime=0;
char m_ReviewMapTexture[128];
CReviewMap *m_ReviewMap = NULL;
CReviewTimeBar *m_ReviewTimeBar = NULL;
CReviewMech *m_ReviewMechs[16] = {
NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL
};
CReviewMap::CReviewMap()
{
char tempname[256];
if (m_ReviewMapTexture[0] == 0)
sprintf (tempname,"content\\textures\\review\\reviewmap.tga");
else
sprintf (tempname,"content\\textures\\%s.tga",m_ReviewMapTexture);
AddReviewTexture (tempname,0,0,0,256,256,256,256,false);
Location (Point3D (33,10,0.9f));
Size (Point3D (400.0f,400.0f,0.9f));
}
CReviewMap::~CReviewMap()
{
}
void CReviewMap::DrawImplementation(void)
{
Point3D loc,size;
DWORD color;
loc.x = m_MapDispX;
loc.y = m_MapDispY;
loc.z = 0.9f;
size.x = m_MapDispWidth;
size.y = m_MapDispHeight;
size.z = 0.9f;
color = MakeColor (0,0,0,255);
// my_DrawRect (0,0,800,600,color);
Scalar x1,y1,x2,y2;
x1 = m_MapLeft;
y1 = m_MapTop;
x2 = (m_MapLeft + m_MapMeterDisplayX);
y2 = (m_MapTop + m_MapMeterDisplayY);
x1 = x1 * (256.0f / m_MapWidth);
y1 = y1 * (256.0f / m_MapHeight);
x2 = x2 * (256.0f / m_MapWidth);
y2 = y2 * (256.0f / m_MapHeight);
m_ReviewTextures[0]->TopLeft (x1,y1);
m_ReviewTextures[0]->BottomRight (x2,y2);
color = MakeColor (128,255,255,255);
m_ReviewTextures[0]->BlendMode (gos_BlendDecal);
m_ReviewTextures[0]->Draw (loc,size,color,ReviewTexture::NO_FLIP);
}
CReviewMech::CReviewMech(int id)
{
Scalar x,y;
int i;
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",20,221,0,255,20); //all
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",0,27,203,59,232); //leftleg
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",1,27,174,59,203); //rightleg
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",2,27,87,59,116); //leftarm
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",3,27,116,59,145); //rightarm
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",4,27,58,59,87); //righttorso
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",5,27,29,59,58); //lefttorso
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",6,27,145,59,174); //centertorso
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",7,0,0,0,0); //blank rear?
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",8,27,0,59,29); //head
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",9,0,0,0,0); //special1
AddReviewTexture ("content\\textures\\HUD\\hud256.tga",10,0,0,0,0); //special2
Point3D size = m_ReviewTextures[20]->Size ();
m_ReviewTextures[20]->Origin (size.x/2.0f,size.y/2.0f);
m_ReviewTextures[20]->Clip (true);
m_MechID = id;
x = y = 0;
switch (m_MechID & 0x03)
{
case 0:
x = 438;
y = (Scalar) ((m_MechID/4) * 102) + 18;
break;
case 1:
x = 438+84;
y = (Scalar) ((m_MechID/4) * 102) + 18;
break;
case 2:
x = 438+84+84;
y = (Scalar) ((m_MechID/4) * 102) + 18;
break;
case 3:
x = 438+84+84+84;
y = (Scalar) ((m_MechID/4) * 102) + 18;
break;
}
Location (Point3D (x,y,0.9f));
Size (Point3D (79.0f,90.0f,0.9f));
m_Name = new HUDText ();
m_ScoreText1 = new HUDText ();
m_ScoreText2 = new HUDText ();
curx = 0;
cury = 0;
rot = 0;
m_Fired = false;
m_Hit = false;
m_DamageColors[0] = MakeColor(100, 225, 100, 225);
m_DamageColors[1] = MakeColor(225, 225, 0, 200);
m_DamageColors[2] = MakeColor(255, 150, 0, 175);
m_DamageColors[3] = MakeColor(255, 50, 0, 150);
m_DamageColors[4] = MakeColor(255, 50, 0, 125);
m_DamageColors[5] = MakeColor(0, 0, 0, 100);
for (i=0;i<11;i++)
{
m_DamageValues[i] = 0;
}
}
CReviewMech::~CReviewMech()
{
delete m_Name;
delete m_ScoreText1;
delete m_ScoreText2;
}
void CReviewMech::SetMechScore (int s1,int s2,int s3)
{
char text[50];
m_Score1 = s1;
m_Score2 = s2;
m_Score3 = s3;
sprintf (text,"%s:%d",MWApplication::GetInstance ()->GetLocString (IDS_SCOREHUD),s1);
m_ScoreText1->UpdateText (text);
sprintf (text,"%d/%d",s2,s3);
m_ScoreText2->UpdateText (text);
}
void CReviewMech::DrawImplementation(void)
{
DWORD color;
int i;
bool draw;
Point3D loc,size;
loc = Location ();
size = m_ReviewTextures[0]->Size ();
for (i=0;i<11;i++)
{
if (i==7)
continue;
if (i==9)
continue;
if (i==10)
continue;
Verify (m_ReviewTextures[i]);
if ((m_DamageValues[i] <= 5) && (m_DamageValues[i]>=0))
{
// if ((m_DamageValues[i] != 4) || (m_DamageFlash))
{
m_ReviewTextures[i]->Draw (Point3D (loc.x+25,loc.y+21,loc.z),size,m_DamageColors[m_DamageValues[i]]);
}
}
}
size = m_ReviewTextures[20]->Size ();
if (m_Fired)
color = MakeColor (255,255,0,250);
else if (m_Hit)
color = MakeColor (255,0,0,250);
else
color = MakeColor (0,255,0,250);
loc.x = (curx) * m_MapWidth ; // convert to map coords
loc.y = (cury) * m_MapHeight ;
draw = true;
if (loc.x < m_MapLeft)
draw = false;
if (loc.y < m_MapTop)
draw = false;
if (loc.x > (m_MapLeft+m_MapMeterDisplayX))
draw = false;
if (loc.y > (m_MapTop+m_MapMeterDisplayY))
draw = false;
loc.x -= m_MapLeft;
loc.y -= m_MapTop;
loc.x *= m_MapScaleX; // convert to screen coords
loc.y *= m_MapScaleY;
loc.x += m_MapDispX; // offset for map location on screen.
loc.y += m_MapDispY;
if ((loc.x < 0) || (loc.y < 0))
draw = false;
if ((loc.x > (m_MapDispX+m_MapDispWidth)) || (loc.y > (m_MapDispY+m_MapDispHeight)))
draw = false;
Scalar iconheight = size.y;
Scalar tx=0,ty=0;
if (draw)
{
m_ReviewTextures[20]->Rotate (Pi - rot);
m_ReviewTextures[20]->Scale (0.5f,0.5f);
m_ReviewTextures[20]->Draw (loc,size,color);
tx = loc.x;
ty = loc.y;
}
loc = Location ();
size = Size ();
color = MakeColor (128,128,128,250);
DWORD dx,dy;
Point3D textloc;
textloc.x = loc.x + (size.x/2.0f);
textloc.y = loc.y;
textloc.z = 0.9f;
m_Name->TopLeft (textloc.x-50.0f,textloc.y-1.9f);
m_Name->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
m_Name->Color (color);
m_Name->Justification (HUDText::LEFT_ALIGN);
m_Name->DrawSize (dx,dy);
textloc.x -= dx/2;
m_Name->Draw (textloc);
if (draw)
{
m_Name->Color (255,255,255,255);
textloc.x = tx-(dx/2);
textloc.y = ty + (iconheight/2) + 2;
m_Name->Draw (textloc);
}
textloc.x = loc.x + (size.x/2.0f);
textloc.y = loc.y + 60;
textloc.z = 0.9f;
m_ScoreText1->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
m_ScoreText1->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
m_ScoreText1->Color (color);
m_ScoreText1->Justification (HUDText::LEFT_ALIGN);
m_ScoreText1->DrawSize (dx,dy);
textloc.x -= dx/2;
m_ScoreText1->Draw (textloc);
textloc.x = loc.x + (size.x/2.0f);
textloc.y = loc.y + 75;
textloc.z = 0.9f;
m_ScoreText2->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
m_ScoreText2->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
m_ScoreText2->Color (color);
m_ScoreText2->Justification (HUDText::LEFT_ALIGN);
m_ScoreText2->DrawSize (dx,dy);
textloc.x -= dx/2;
m_ScoreText2->Draw (textloc);
}
CReviewTimeBar::CReviewTimeBar()
{
Location (Point3D (55.0f,422.0f,0.9f));
Size (Point3D (690.0f,20.0f,0.9f));
}
CReviewTimeBar::~CReviewTimeBar()
{
}
void CReviewTimeBar::DrawImplementation(void)
{
DWORD color;
Point3D loc,size;
loc = Location ();
size = Size ();
color = MakeColor (128,128,128,250);
my_DrawRect ((int) loc.x,(int) loc.y,(int) (loc.x+size.x),(int) (loc.y+size.y),color);
color = MakeColor (0,0,0,250);
DrawFrame ((int) loc.x,(int) loc.y,(int) (loc.x+size.x),(int) (loc.y+size.y),color);
if (m_TotalTime == 0)
loc.x = 0;
else
loc.x = (size.x-size.y) / m_TotalTime;
loc.x *= m_CurrentTime;
loc.x += 55.0f;
size.x = size.y;
if ((loc.x+size.x) > 745.0f)
loc.x = 745.0f - size.x;
color = MakeColor (0,250,0,250);
my_DrawRect ((int) loc.x,(int) loc.y,(int) (loc.x+size.x),(int) (loc.y+size.y),color);
color = MakeColor (0,0,0,250);
DrawFrame ((int) loc.x,(int) loc.y,(int) (loc.x+size.x),(int) (loc.y+size.y),color);
size = Size ();
if (m_TotalTime == 0)
loc.x = 0;
else
loc.x = (size.x) / m_TotalTime;
loc.x *= m_LoadedTime;
loc.x += 5.0f;
if ((loc.x) > 795.0f)
loc.x = 795.0f;
color = MakeColor (0,0,0,250);
DrawLine ((int) loc.x,(int) loc.y,(int) loc.x,(int) (loc.y+size.y),color);
}
void InitMissionReviewDisplay (void)
{
int i;
m_LastCenteredMech = -1;
m_MapDispX = 23;
m_MapDispY = 10;
m_MapDispWidth = 400.0f;
m_MapDispHeight = 400.0f;
m_MapTop = 0.0f;
m_MapLeft = 0.0f;
m_MapTargetLeft = 0.0f;
m_MapTargetTop = 0.0f;
m_MapWidth = 5120.0f;
m_MapHeight = 5120.0f;
m_Paused = false;
m_CenteringX = m_CenteringY = false;
m_CenteredMech = 0;
m_MapMeterDisplayX = 1000;
m_MapMeterDisplayY = 1000;
m_MapScaleX = m_MapDispWidth / m_MapMeterDisplayX;
m_MapScaleY = m_MapDispHeight / m_MapMeterDisplayY;
m_CurrentTime = 0;
m_LoadedTime = 0;
m_TotalTime = 0;
m_SampleRate = 0;
m_PlayBackRate = 1;
m_LastTime = gos_GetElapsedTime ();
MWApplication *app = MWApplication::GetInstance ();
Check_Object (app);
// m_ReviewLog = app->m_playLog;
Verify (app->m_playLog);
app->m_playLog->GetLogTimes (m_LoadedTime,m_TotalTime,m_SampleRate);
m_ReviewMap = new CReviewMap ();
m_ReviewMap->Show ();
m_ReviewTimeBar = new CReviewTimeBar ();
m_ReviewTimeBar->Show ();
for (i=0;i<16;i++)
{
m_ReviewMechs[i] = new CReviewMech (i);
m_ReviewMechs[i]->Show ();
}
}
void KillMissionReviewDisplay (void)
{
// m_ReviewLog = NULL;
delete m_ReviewMap;
m_ReviewMap = NULL;
delete m_ReviewTimeBar;
m_ReviewTimeBar = NULL;
int i;
for (i=0;i<16;i++)
{
delete m_ReviewMechs[i];
m_ReviewMechs[i] = NULL;
}
}
void PlayMissionReview (Stuff::Time time)
{
int i;
MWApplication *app = MWApplication::GetInstance ();
Check_Object (app);
if (!app->m_playLog)
{
return;
}
ReadKeyboard ();
app->m_playLog->GetLogTimes (m_LoadedTime,m_TotalTime,m_SampleRate);
if (!m_Paused)
{
m_CurrentTime += (Scalar) ((gos_GetElapsedTime () - m_LastTime) * m_PlayBackRate);
}
Max_Clamp (m_CurrentTime,m_LoadedTime);
m_LastTime = gos_GetElapsedTime ();
for (i=0;i<16;i++)
m_ReviewMechs[i]->Hide ();
if (m_LoadedTime != 0)
{
int currentmech = 0;
for (i = 0; i < Maximum_Players; ++i)
{
{
MRPlayerData player_data;
app->m_playLog->GetPlayerData(&player_data, m_CurrentTime, i);
if ((player_data.m_playerStatus == MRPlayerData::InToken) && (player_data.m_alive))
{
m_ReviewMechs[currentmech]->Show ();
m_ReviewMechs[currentmech]->SetMechCoord (1.0f-player_data.m_position.x,1.0f-player_data.m_position.z);
m_ReviewMechs[currentmech]->SetMechRot (player_data.m_yawRotation);
m_ReviewMechs[currentmech]->SetMechFired (player_data.m_firedWeapon);
m_ReviewMechs[currentmech]->SetMechHit (player_data.m_takenDamage);
m_ReviewMechs[currentmech]->SetMechDamageLevel (player_data.m_damageLevel);
m_ReviewMechs[currentmech]->SetMechName (player_data.m_playerName);
m_ReviewMechs[currentmech]->SetMechScore ((int) player_data.m_scoreBucket1,(int) player_data.m_scoreBucket2,(int) player_data.m_scoreBucket3);
if (currentmech == m_CenteredMech)
{
if (currentmech != m_LastCenteredMech)
{
m_MapLeft = (1.0f - player_data.m_position.x) * m_MapWidth;
m_MapTop = (1.0f - player_data.m_position.z) * m_MapHeight;
m_MapLeft -= (m_MapMeterDisplayX/2.0f);
m_MapTop -= (m_MapMeterDisplayY/2.0f);
m_LastCenteredMech = currentmech;
}
m_MapTargetLeft = (1.0f - player_data.m_position.x) * m_MapWidth;
m_MapTargetTop = (1.0f - player_data.m_position.z) * m_MapHeight;
m_MapTargetLeft -= (m_MapMeterDisplayX/2.0f);
m_MapTargetTop -= (m_MapMeterDisplayY/2.0f);
Min_Clamp (m_MapTargetTop,0);
Min_Clamp (m_MapTargetLeft,0);
Max_Clamp (m_MapTargetTop,m_MapHeight-m_MapMeterDisplayY);
Max_Clamp (m_MapTargetLeft,m_MapWidth-m_MapMeterDisplayX);
}
currentmech++;
}
}
}
}
if (!m_CenteringX)
{
if (abs ((int) (m_MapTargetLeft - m_MapLeft)) > 450)
{
m_CenteringX = true;
}
}
if (!m_CenteringY)
{
if (abs(int (m_MapTargetTop - m_MapTop)) > 450)
{
m_CenteringY = true;
}
}
if (m_CenteringX)
{
if (abs ((int) (m_MapTargetLeft - m_MapLeft)) < 5)
{
m_CenteringX = false;
}
else
{
Scalar delta = m_MapTargetLeft - m_MapLeft;
Clamp (delta,-10,10);
m_MapLeft+= delta;
}
}
if (m_CenteringY)
{
if (abs(int (m_MapTargetTop - m_MapTop)) < 5)
{
m_CenteringY = false;
}
else
{
Scalar delta = m_MapTargetTop - m_MapTop;
Clamp (delta,-10,10);
m_MapTop+= delta;
}
}
gos_PushRenderStates ();
HUDTexture::StartTexturePass ();
gos_SetRenderState (gos_State_Filter,gos_FilterBiLinear);
m_ReviewMap->Draw (true);
m_ReviewTimeBar->Draw (true);
for (i=0;i<16;i++)
m_ReviewMechs[i]->Draw (true);
HUDTexture::EndTexturePass ();
gos_PopRenderStates ();
}
int SpeedUp (void)
{
m_PlayBackRate++;
Clamp (m_PlayBackRate,1,10);
return 0;
}
int SlowDown (void)
{
m_PlayBackRate--;
Clamp (m_PlayBackRate,1,10);
return 0;
}
int Rewind (void)
{
m_CurrentTime = 0;
return 0;
}
int Pause (void)
{
m_Paused = !m_Paused;
return 0;
}
int CenterOn (void *data[], int count)
{
int id = *(INTARRAYPARAM(1));
if (!m_ReviewMechs[id]->Visible ())
return 0;
m_CenteredMech = id;
m_LastCenteredMech = -1;
return 0;
}
void ReadKeyboard (void)
{
#if 0
int keypress = gos_GetKey () & 255;
while (keypress)
{
switch (keypress)
{
case 'f':
SpeedUp ();
break;
case 's':
SlowDown ();
break;
case 'r':
Rewind ();
break;
case 'p':
Pause ();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
CenterOn (keypress - '0');
break;
}
keypress = gos_GetKey () & 255;
}
#endif
}
}
#endif // !defined(NO_MR)