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

898 lines
24 KiB
C++

//===========================================================================//
// File: MissionReview.cpp
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 07/11/2000 JSE Inital coding
//---------------------------------------------------------------------------//
// Copyright (C) 2000, Microsoft Corp. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#include "MW4Headers.hpp"
#include "MissionReview.hpp"
#include "MWMission.hpp"
#include "MWApplication.hpp"
#include "MWPlayer.hpp"
#include "Bucket.hpp"
#include <Adept\DamageObject.hpp>
#include <Adept\Map.hpp>
#if !defined(NO_MR)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MRPlayerData::MRPlayerData()
{
Reset();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MRPlayerData::Reset()
{
m_playerStatus = NoChange;
m_playerName = NULL;
m_position = Point3D::Identity;
m_yawRotation = 0.0f;
m_takenDamage = false;
m_firedWeapon = false;
m_alive = false;
m_scoreBucket1 = 0;
m_scoreBucket2 = 0;
m_scoreBucket3 = 0;
for (int i = 0; i < Damage_Zones; ++i)
{
m_damageLevel[i] = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MissionReview::MissionReview():
Plug(DefaultData)
{
m_missionLog = NULL;
m_nameLog = NULL;
for (int i = 0; i < Maximum_Players; ++i)
{
m_playBackLog[i] = NULL;
}
ClearLog();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MissionReview::~MissionReview()
{
ClearLog();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::ClearLog(void)
{
timeSinceLastSnapShot = 0.0;
m_playersInGame = 0;
m_bufferedSnapShots = 0;
m_totalSnapShots = 0;
m_snapShotFrequency = 0.0f;
for (int i = 0; i < Maximum_Players; ++i)
{
m_playerData[i].Reset();
if (m_playBackLog[i] != NULL)
{
delete[] m_playBackLog[i];
m_playBackLog[i] = NULL;
}
}
if (m_missionLog != NULL)
{
delete m_missionLog;
m_missionLog = NULL;
}
if (m_nameLog != NULL)
{
delete m_nameLog;
m_nameLog = NULL;
}
minExtents = Point3D::Identity;
maxExtents = Point3D::Identity;
missionName = "\0";
haveHeaderInfo = false;
m_mode = NoMode;
m_recording = false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::ReadyRecord()
{
ClearLog();
m_mode = RecordMode;
m_missionLog = new DynamicMemoryStream;
m_missionLog->AllocateBytes(1000000); // about one meg
m_nameLog = new DynamicMemoryStream;
m_nameLog->AllocateBytes(64000); // alot of friggin names...
}
void MissionReview::StartRecordingLog(Scalar frequency)
{
m_recording = true;
m_snapShotFrequency = frequency;
Mission *miss = Mission::GetInstance();
Check_Object(miss);
missionName = miss->GetModelName ();
Map::GetInstance()->GetMapExtents(&minExtents.z, &maxExtents.z, &minExtents.x, &maxExtents.z);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::StopRecordingLog(void)
{
Verify(m_mode == RecordMode);
m_nameLog->WriteByteAlign();
m_missionLog->WriteByteAlign();
m_nameLog->Rewind();
m_missionLog->Rewind();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::AddPlayer(const char *player_name, int id)
{
Verify(m_mode == RecordMode);
int token = AddToken;
m_nameLog->WriteBytes(&token, 1);
m_nameLog->WriteBytes(&m_bufferedSnapShots, 4);
m_nameLog->WriteBytes(&id, 1);
int size = strlen(player_name);
size++;
m_nameLog->WriteBytes(&size, 1);
m_nameLog->WriteBytes(player_name, size);
m_playerData[id].Reset();
m_playerData[id].m_playerName = player_name;
m_playerData[id].m_playerStatus = MRPlayerData::InToken;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::RemovePlayer(int id)
{
Verify(m_mode == RecordMode);
int token = RemoveToken;
m_nameLog->WriteBytes(&token, 1);
m_nameLog->WriteBytes(&m_bufferedSnapShots, 4);
m_nameLog->WriteBytes(&id, 1);
m_playerData[id].Reset();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::TakeSnapShot()
{
Verify(m_mode == RecordMode);
if (!m_recording)
return;
if ((gos_GetElapsedTime() - timeSinceLastSnapShot) < m_snapShotFrequency)
{
return;
}
timeSinceLastSnapShot = gos_GetElapsedTime();
++m_bufferedSnapShots;
m_totalSnapShots = m_bufferedSnapShots;
MWMission *mission = Cast_Object(MWMission*, Mission::GetInstance());
for (int i = 0; i < Maximum_Players; ++i)
{
if (m_playerData[i].m_playerStatus == MRPlayerData::InToken)
{
MWApplication *app = MWApplication::GetInstance();
Verify(app->servedConnectionData[i].clientConnected);
Verify(app->servedConnectionData[i].clientPlayer != NULL);
Verify(app->servedConnectionData[i].clientPlayer->vehicle != NULL);
m_playerData[i].m_alive = (app->servedConnectionData[i].clientPlayer->vehicle->executionState->GetState() != Entity::ExecutionStateEngine::NeverExecuteState)?1:0;
m_playerData[i].m_position = app->servedConnectionData[i].clientPlayer->vehicle->GetLocalToWorld();
YawPitchRange ypr;
if (app->servedConnectionData[i].clientPlayer->vehicle->GetClassID() == MechClassID)
{
Mech *mech = Cast_Object(Mech*,app->servedConnectionData[i].clientPlayer->vehicle);
Stuff::UnitVector3D vector;
mech->animationArray[mech->torsoAboveJointIndex]->GetLocalToWorld().GetLocalForwardInWorld(&vector);
ypr = vector;
//ypr = app->servedConnectionData[i].clientPlayer->vehicle->GetLocalToWorld();
m_playerData[i].m_yawRotation = ypr.yaw;
}
else
{
Stuff::UnitVector3D vector;
app->servedConnectionData[i].clientPlayer->vehicle->GetLocalToWorld().GetLocalForwardInWorld(&vector);
ypr = vector;
m_playerData[i].m_yawRotation = ypr.yaw;
}
CBucket *bucket = mission->m_BucketManager->PlayerBucket( app->servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID(), CBucketManager::CUSTOM);
if (bucket)
m_playerData[i].m_scoreBucket1 = bucket->Value();
else
m_playerData[i].m_scoreBucket1 = 0;
bucket = mission->m_BucketManager->PlayerBucket( app->servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID(), CBucketManager::KILLS);
if (bucket)
m_playerData[i].m_scoreBucket2 = bucket->Value();
else
m_playerData[i].m_scoreBucket2 = 0;
bucket = mission->m_BucketManager->PlayerBucket( app->servedConnectionData[i].clientPlayer->vehicle->GetReplicatorID(), CBucketManager::DEATHS);
if (bucket)
m_playerData[i].m_scoreBucket3 = bucket->Value();
else
m_playerData[i].m_scoreBucket3 = 0;
// weapon and damage bools are pre fed...
// read damage state...
int current_damage_object = 0;
if (app->servedConnectionData[i].clientPlayer->vehicle->IsDestroyed())
{
m_playerData[i].m_damageLevel[current_damage_object] = 1.0f;
}
else
{
m_playerData[i].m_damageLevel[current_damage_object] = 0.0f;
}
++current_damage_object;
DamageObject *damage_object;
Vehicle *vehicle = app->servedConnectionData[i].clientPlayer->GetVehicle();
SortedChainIteratorOf<DamageObject *, int> damage_iterator(&vehicle->damageObjects);
while((damage_object = damage_iterator.ReadAndNext()) != NULL)
{
Verify(current_damage_object < MRPlayerData::Damage_Zones);
Check_Object(damage_object);
m_playerData[i].m_damageLevel[current_damage_object] = damage_object->GetHighResDamageLevel();
++current_damage_object;
}
// write the player into the log...
Scalar min_z, max_z, min_x, max_x;
Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x);
m_missionLog->WriteScaledFloatToBits(m_playerData[i].m_position.x, min_x, max_x, XBitDepth);
m_missionLog->WriteScaledFloatToBits(m_playerData[i].m_position.z, min_z, max_z, YBitDepth);
m_missionLog->WriteScaledFloatToBits(m_playerData[i].m_yawRotation, -Stuff::Pi, Stuff::Pi, RotationBitDepth);
m_missionLog->WriteBits(&m_playerData[i].m_scoreBucket1, 32);
m_missionLog->WriteBits(&m_playerData[i].m_scoreBucket2, 32);
m_missionLog->WriteBits(&m_playerData[i].m_scoreBucket3, 32);
m_missionLog->WriteBit(m_playerData[i].m_takenDamage);
m_missionLog->WriteBit(m_playerData[i].m_firedWeapon);
m_missionLog->WriteBit(m_playerData[i].m_alive);
m_playerData[i].m_takenDamage = false;
m_playerData[i].m_firedWeapon = false;
for (int dz = 0; dz < MRPlayerData::Damage_Zones; ++dz)
{
m_missionLog->WriteScaledFloatToBits(m_playerData[i].m_damageLevel[dz], 0.0f, 1.0f, DamageBitDepth);
}
m_missionLog->WriteByteAlign();
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::SaveLog(const char *file_name)
{
Verify(m_mode == RecordMode);
Stuff::FileStream file_stream(file_name, Stuff::FileStream::WriteOnly);
DWORD token = 0xAAAAAAAA;
file_stream.WriteBytes(&token, 4);
file_stream << missionName;
file_stream << minExtents << maxExtents;
file_stream.WriteBytes(&m_totalSnapShots, 4);
file_stream.WriteBytes(&m_snapShotFrequency, 4);
int size = m_nameLog->GetBufferBytesUsed();
file_stream.WriteBytes(&size, 4);
if (size > 0)
{
file_stream.WriteBytes(m_nameLog->GetPointer(), m_nameLog->GetBufferBytesUsed());
}
size = m_missionLog->GetBufferBytesUsed();
file_stream.WriteBytes(&size, 4);
if (size > 0)
{
file_stream.WriteBytes(m_missionLog->GetPointer(), m_missionLog->GetBufferBytesUsed());
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::GetHeader(DynamicMemoryStream *stream)
{
DWORD token = 0xAAAAAAAA;
stream->WriteBytes(&token, 4);
*stream << missionName;
*stream << minExtents << maxExtents;
stream->WriteBytes(&m_totalSnapShots, 4);
stream->WriteBytes(&m_snapShotFrequency, 4);
int size = m_nameLog->GetBufferBytesUsed();
stream->WriteBytes(&size, 4);
if (size > 0)
{
stream->WriteBytes(m_nameLog->GetPointer(), m_nameLog->GetBufferBytesUsed());
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::GetDataLog(DynamicMemoryStream *stream)
{
m_missionLog->Rewind();
int size = m_missionLog->GetBufferBytesUsed();
stream->WriteBytes(&size, 4);
if (size > 0)
{
stream->WriteBytes(m_missionLog->GetPointer(), m_missionLog->GetBufferBytesUsed());
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MissionReview::HaveLog(void)
{
return haveHeaderInfo;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::StartLogBuffer(void)
{
ClearLog();
m_missionLog = new DynamicMemoryStream;
m_nameLog = new DynamicMemoryStream;
m_mode = PlayBackMode;
lastReadSnapShot = 0;
lastReadPlayer = 0;
lastByteRead = 0;
totalLogSize = 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::LoadLog(const char *file_name)
{
Verify(m_mode == PlayBackMode);
Stuff::FileStream file_stream(file_name);
if (ReadNames(&file_stream))
{
totalLogSize = 0;
file_stream.ReadBytes(&totalLogSize, 4);
//SPEW(("jerryeds", "SERVER TOTAL SIZE : %d", totalLogSize));
//SPEW(("jerryeds", "TOTAL SNAPSHOTS %d", m_totalSnapShots));
m_missionLog->WriteBytes(file_stream.GetPointer(), totalLogSize);
m_missionLog->Rewind();
// fill in the keyframe data...
for (int j = 0; j < m_totalSnapShots; ++j)
{
for (int i = 0; i < Maximum_Players; ++i)
{
if (m_playBackLog[i][j].m_playerStatus == MRPlayerData::InToken)
{
Scalar min_x = 0.0f;
Scalar max_x = 1.0f;
Scalar min_z = 0.0f;
Scalar max_z = 1.0f;
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_position.x, min_x, max_x, XBitDepth);
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_position.z, min_z, max_z, YBitDepth);
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_yawRotation, -Stuff::Pi, Stuff::Pi, RotationBitDepth);
m_missionLog->ReadBits(&m_playBackLog[i][j].m_scoreBucket1, 32);
m_missionLog->ReadBits(&m_playBackLog[i][j].m_scoreBucket2, 32);
m_missionLog->ReadBits(&m_playBackLog[i][j].m_scoreBucket3, 32);
m_missionLog->ReadBit(m_playBackLog[i][j].m_takenDamage);
m_missionLog->ReadBit(m_playBackLog[i][j].m_firedWeapon);
m_missionLog->ReadBit(m_playBackLog[i][j].m_alive);
// SPEW (("afarrier","%d pos=%5.2f, %5.2f",j,m_playBackLog[i][j].m_position.x,m_playBackLog[i][j].m_position.z));
// SPEW (("afarrier","%d yaw=%5.2f",j,m_playBackLog[i][j].m_yawRotation));
for (int dz = 0; dz < MRPlayerData::Damage_Zones; ++dz)
{
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_damageLevel[dz], 0.0f, 1.0f, DamageBitDepth);
}
m_missionLog->ReadByteAlign();
//SPEW(("jerryeds", "%d:%d -%d:%d - %d -%d:%d - %d- %f %f : %f", i, j, index, bit, data, index2, bit2, data2, m_playBackLog[i][j].m_position.x, m_playBackLog[i][j].m_position.y, m_playBackLog[i][j].m_yawRotation));
}
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool MissionReview::ReadNames(MemoryStream *stream)
{
Verify(m_mode == PlayBackMode);
if (stream->GetSize() > 20)
{
DWORD token;
stream->ReadBytes(&token, 4);
if (token == 0xAAAAAAAA)
{
haveHeaderInfo = true;
*stream >> missionName;
*stream >> minExtents >> maxExtents;
stream->ReadBytes(&m_totalSnapShots, 4);
m_bufferedSnapShots = m_totalSnapShots;
stream->ReadBytes(&m_snapShotFrequency, 4);
int size = 0;
stream->ReadBytes(&size, 4);
m_nameLog->AllocateBytes(size);
if (size > 0)
{
stream->ReadBytes(m_nameLog->GetPointer(), size);
}
for (int i = 0; i < Maximum_Players; ++i)
{
m_playBackLog[i] = new MRPlayerData[m_totalSnapShots];
}
// Fill in the name log data...
while(m_nameLog->GetBytesRemaining())
{
int token = 0;
m_nameLog->ReadBytes(&token, 1);
if (token == AddToken)
{
int snap_shot = 0;
int id = 0;
m_nameLog->ReadBytes(&snap_shot, 4);
m_nameLog->ReadBytes(&id, 1);
m_playBackLog[id][snap_shot].m_playerStatus = MRPlayerData::InToken;
int size = 0;
m_nameLog->ReadBytes(&size, 1);
m_playBackLog[id][snap_shot].m_playerName = (char *)m_nameLog->GetPointer();
m_nameLog->AdvancePointer(size);
}
else if (token == RemoveToken)
{
int snap_shot = 0;
int id = 0;
m_nameLog->ReadBytes(&snap_shot, 4);
m_nameLog->ReadBytes(&id, 1);
m_playBackLog[id][snap_shot].m_playerName = NULL;
m_playBackLog[id][snap_shot].m_playerStatus = MRPlayerData::OutToken;
}
else
{
STOP(("MISSION REVIEW LOG CORRUPT"));
}
}
//fill in the namelog gaps...
for (i = 0; i < Maximum_Players; ++i)
{
for (int j = 1; j < m_totalSnapShots; ++j)
{
if (m_playBackLog[i][j].m_playerStatus == MRPlayerData::NoChange)
{
m_playBackLog[i][j].m_playerStatus = m_playBackLog[i][j-1].m_playerStatus;
m_playBackLog[i][j].m_playerName = m_playBackLog[i][j-1].m_playerName;
}
}
}
return true;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::AddPartToLogBuffer(MemoryStream *log_part_stream)
{
Verify(m_mode == PlayBackMode);
if (m_nameLog->GetBufferBytesUsed() == 0)
{
//SPEW(("jerryeds", "SNAPSHOT-START"));
Verify(m_missionLog->GetBufferBytesUsed() == 0);
//m_nameLog->WriteBytes(log_part_stream->GetPointer(), log_part_stream->GetBytesRemaining());
//m_nameLog->Rewind();
ReadNames(log_part_stream);
}
else
{
//SPEW(("jerryeds", "ADDPART : %d", log_part_stream->GetBufferBytesUsed()));
Verify(m_nameLog->GetBufferBytesUsed() != 0);
// 12 + 12 + 5 + 32 + 32 + 1 + 1 + (12 * 4 )
// write the data
m_missionLog->SetPointer(m_missionLog->GetBufferBytesUsed());
m_missionLog->WriteBytes(log_part_stream->GetPointer(), log_part_stream->GetBufferBytesUsed());
// restore our last position
m_missionLog->SetPointer(lastByteRead);
//SPEW(("jerryeds", "SET LASTBYTE : %d", lastByteRead));
if (lastByteRead == 0)
{
totalLogSize = 0;
if (m_missionLog->GetBytesRemaining() > 4)
{
m_missionLog->ReadBytes(&totalLogSize, 4);
//SPEW(("jerryeds", "CLIENT TOTAL SIZE : %d", totalLogSize));
}
lastByteRead = 4;
}
//SPEW(("jerryeds", "REPORTED SIZE : %d, current size %d, packet size %d", totalLogSize, m_missionLog->GetBufferBytesUsed(), log_part_stream->GetBufferBytesUsed()));
//if (m_missionLog->GetBufferBytesUsed() >= totalLogSize)
{
int bits_per_sample = XBitDepth + YBitDepth + RotationBitDepth + 32 + 32 + 32 + 1 + 1 + 1 + (DamageBitDepth * MRPlayerData::Damage_Zones);
int bytes_per_sample;
if (bits_per_sample & 7)
{
bytes_per_sample = bits_per_sample >> 3;
++bytes_per_sample;
}
else
{
bytes_per_sample = bits_per_sample >> 3;
}
for (int j = lastReadSnapShot; j < m_totalSnapShots; ++j)
{
for (int i = lastReadPlayer; i < Maximum_Players; ++i)
{
if (m_missionLog->GetBytesRemaining() >= bytes_per_sample)
{
if (m_playBackLog[i][j].m_playerStatus == MRPlayerData::InToken)
{
Scalar min_x = 0.0f;
Scalar max_x = 1.0f;
Scalar min_z = 0.0f;
Scalar max_z = 1.0f;
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_position.x, min_x, max_x, XBitDepth);
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_position.z, min_z, max_z, YBitDepth);
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_yawRotation, -Stuff::Pi, Stuff::Pi, RotationBitDepth);
m_missionLog->ReadBits(&m_playBackLog[i][j].m_scoreBucket1, 32);
m_missionLog->ReadBits(&m_playBackLog[i][j].m_scoreBucket2, 32);
m_missionLog->ReadBits(&m_playBackLog[i][j].m_scoreBucket3, 32);
m_missionLog->ReadBit(m_playBackLog[i][j].m_takenDamage);
m_missionLog->ReadBit(m_playBackLog[i][j].m_firedWeapon);
m_missionLog->ReadBit(m_playBackLog[i][j].m_alive);
for (int dz = 0; dz < MRPlayerData::Damage_Zones; ++dz)
{
m_missionLog->ReadBitsToScaledFloat(m_playBackLog[i][j].m_damageLevel[dz], 0.0f, 1.0f, DamageBitDepth);
}
m_missionLog->ReadByteAlign();
//SPEW(("jerryeds", "%d:%d - %d:%d %d - %d:%d %d - %f %f : %f", i, j, index, bit, data ,index2, bit2, data2 ,m_playBackLog[i][j].m_position.x, m_playBackLog[i][j].m_position.y, m_playBackLog[i][j].m_yawRotation));
}
}
else
{
// save where we are...
lastReadSnapShot = j;
lastReadPlayer = i;
lastByteRead = m_missionLog->GetIndex();
//SPEW(("jerryeds","LAST READ %d:%d - BYTE - %d", i, j, lastByteRead));
// in case it evenly ends...
if (totalLogSize == m_missionLog->GetBufferBytesUsed())
{
Verify(m_missionLog->GetBytesRemaining() == 0);
m_bufferedSnapShots = m_totalSnapShots;
//SPEW(("jerryeds","END LOG"));
}
return;
}
}
lastReadPlayer = 0;
m_bufferedSnapShots = j;
//SPEW(("jerryeds", "SNAPSHOT %d", m_bufferedSnapShots));
}
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
char *MissionReview::GetMissionName()
{
return missionName;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::GetMapExtents(Point3D &min_extents, Point3D &max_extents)
{
min_extents = minExtents;
max_extents = maxExtents;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::GetLogTimes(Scalar &buffered_time, Scalar &total_time, Scalar &sample_rate)
{
Verify(m_mode == PlayBackMode);
buffered_time = m_bufferedSnapShots * m_snapShotFrequency;
total_time = m_totalSnapShots * m_snapShotFrequency;
sample_rate = m_snapShotFrequency;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void MissionReview::GetPlayerData(MRPlayerData *new_data, Scalar time, int player)
{
Verify(m_mode == PlayBackMode);
new_data->Reset();
int from_frame = 0;
int to_frame = 0;
Scalar lerp = 0.0f;
if (time < 0.0f || time >= (Scalar)(m_bufferedSnapShots*m_snapShotFrequency))
{
return;
}
if (m_bufferedSnapShots == 0)
{
return;
}
from_frame = (int)(time / m_snapShotFrequency);
to_frame = from_frame + 1;
Clamp(from_frame, 0, m_bufferedSnapShots-1);
Clamp(to_frame, 0, m_bufferedSnapShots-1);
if (m_playBackLog[player][to_frame].m_playerStatus != MRPlayerData::InToken || to_frame == from_frame)
{
//SPEWALWAYS(("jerryeds", "PLAYER : %d : FRAME : %d", player, to_frame));
new_data->m_playerStatus = m_playBackLog[player][to_frame].m_playerStatus;
new_data->m_playerName = m_playBackLog[player][to_frame].m_playerName;
new_data->m_scoreBucket1 = m_playBackLog[player][to_frame].m_scoreBucket1;
new_data->m_scoreBucket2 = m_playBackLog[player][to_frame].m_scoreBucket2;
new_data->m_scoreBucket3 = m_playBackLog[player][to_frame].m_scoreBucket3;
new_data->m_takenDamage = m_playBackLog[player][to_frame].m_takenDamage;
new_data->m_firedWeapon = m_playBackLog[player][to_frame].m_firedWeapon;
new_data->m_alive = m_playBackLog[player][to_frame].m_alive;
for (int i = 0; i < MRPlayerData::Damage_Zones; ++i)
{
new_data->m_damageLevel[i] = m_playBackLog[player][to_frame].m_damageLevel[i];
}
new_data->m_yawRotation = m_playBackLog[player][to_frame].m_yawRotation;
new_data->m_position = m_playBackLog[player][to_frame].m_position;
return;
}
new_data->m_playerStatus = m_playBackLog[player][from_frame].m_playerStatus;
new_data->m_playerName = m_playBackLog[player][from_frame].m_playerName;
new_data->m_scoreBucket1 = m_playBackLog[player][from_frame].m_scoreBucket1;
new_data->m_scoreBucket2 = m_playBackLog[player][from_frame].m_scoreBucket2;
new_data->m_scoreBucket3 = m_playBackLog[player][from_frame].m_scoreBucket3;
new_data->m_takenDamage = m_playBackLog[player][from_frame].m_takenDamage;
new_data->m_firedWeapon = m_playBackLog[player][from_frame].m_firedWeapon;
new_data->m_alive = m_playBackLog[player][from_frame].m_alive;
for (int i = 0; i < MRPlayerData::Damage_Zones; ++i)
{
new_data->m_damageLevel[i] = m_playBackLog[player][from_frame].m_damageLevel[i];
}
lerp = ( time - (from_frame*m_snapShotFrequency) ) / m_snapShotFrequency;
Radian rotation;
rotation.Lerp(m_playBackLog[player][from_frame].m_yawRotation, m_playBackLog[player][to_frame].m_yawRotation, lerp);
new_data->m_yawRotation = rotation.angle;
new_data->m_position.Lerp(m_playBackLog[player][from_frame].m_position, m_playBackLog[player][to_frame].m_position, lerp);
}
#endif // !defined(NO_MR)