Imports the current Win32 source for the pod-racing game 'Red Planet', built on the MUNGA engine and its L4 (Win32/DirectX) platform layer: - MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend - RP / RP_L4: Red Planet game logic and Win32 application - DivLoader, Setup1: asset loader and installer project - lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies Removed stale Subversion metadata and added .gitignore/.gitattributes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
312 lines
7.6 KiB
C++
312 lines
7.6 KiB
C++
#include "munga.h"
|
|
#pragma hdrstop
|
|
|
|
#include "spooler.h"
|
|
#include "filestrm.h"
|
|
|
|
//#############################################################################
|
|
//############################## SpoolFile ################################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SpoolFile::SpoolFile(
|
|
void *stream_start,
|
|
size_t stream_size,
|
|
size_t initial_offset
|
|
):
|
|
MemoryStream(stream_start, stream_size, initial_offset)
|
|
{
|
|
spoolState = Empty;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SpoolFile::SpoolFile(SpoolFile& spool):
|
|
MemoryStream(
|
|
spool.streamStart,
|
|
spool.streamSize,
|
|
spool.GetBytesUsed()
|
|
)
|
|
{
|
|
spoolState = spool.spoolState;
|
|
Verify(spoolState == Playing);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SpoolFile::~SpoolFile()
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
SpoolFile::SaveAs(const char *file_name)
|
|
{
|
|
FileStream output(file_name, True);
|
|
size_t length = GetBytesUsed();
|
|
output << length;
|
|
Rewind();
|
|
output.WriteBytes(GetPointer(), length);
|
|
output.Close();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
SpoolFile::Read(const char *file_name)
|
|
{
|
|
FileStream input(file_name);
|
|
if (!input.IsFileOpened())
|
|
{
|
|
spoolState = Empty;
|
|
return;
|
|
}
|
|
|
|
//
|
|
//-------------------------------
|
|
// Figure out how big the file is
|
|
//-------------------------------
|
|
//
|
|
size_t spool_size = 0;
|
|
input >> spool_size;
|
|
if (spool_size > GetBytesRemaining() || !spool_size)
|
|
{
|
|
spoolState = Empty;
|
|
}
|
|
|
|
//
|
|
//-----------
|
|
// Read it in
|
|
//-----------
|
|
//
|
|
else
|
|
{
|
|
input.ReadBytes(streamStart, spool_size);
|
|
streamSize = spool_size;
|
|
Rewind();
|
|
spoolState = Stored;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
SpoolFile::SpoolPacket(NetworkPacket *packet)
|
|
{
|
|
Check(this);
|
|
Check_Pointer(packet);
|
|
|
|
//
|
|
//-------------------------------------------------------------------------
|
|
// Check to see if we are out of spool space. For now, if it happens, just
|
|
// die
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
int length =
|
|
packet->messageData.messageLength + sizeof(NetworkPacketHeader);
|
|
int remaining = GetBytesRemaining();
|
|
if (remaining < length)
|
|
{
|
|
DEBUG_STREAM << "Error: Spool file ran out of memory!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------------
|
|
// Copy into the memory stream, and advance the pointer
|
|
//-----------------------------------------------------
|
|
//
|
|
Mem_Copy(GetPointer(), packet, length, remaining);
|
|
AdvancePointer(length);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
NetworkPacket*
|
|
SpoolFile::NextPacket()
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
// Check to see if anything is left in the spool. If only a partial message
|
|
// remains, die from an error
|
|
//-------------------------------------------------------------------------
|
|
//
|
|
if (!GetBytesRemaining())
|
|
{
|
|
return NULL;
|
|
}
|
|
NetworkPacket *packet = (NetworkPacket*)GetPointer();
|
|
int length =
|
|
packet->messageData.messageLength + sizeof(NetworkPacketHeader);
|
|
if (GetBytesRemaining() < length)
|
|
{
|
|
DEBUG_STREAM << "Error: Partial packet in spool file!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------------
|
|
// Copy into the memory stream, and advance the pointer
|
|
//-----------------------------------------------------
|
|
//
|
|
AdvancePointer(length);
|
|
return (NetworkPacket*)GetPointer();
|
|
}
|
|
|
|
//#############################################################################
|
|
//################# MissionReviewApplicationManager #####################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MissionReviewApplicationManager::MissionReviewApplicationManager(
|
|
HINSTANCE hInstance,
|
|
HWND hWnd,
|
|
Scalar frame_rate,
|
|
int spool_count,
|
|
size_t spool_size
|
|
):
|
|
ApplicationManager(hInstance, hWnd, frame_rate)
|
|
{
|
|
//
|
|
//--------------------------------------------------------
|
|
// Allocate the space for the spool files and buffer table
|
|
//--------------------------------------------------------
|
|
//
|
|
spoolCount = spool_count;
|
|
spoolSize = spool_size;
|
|
spoolBuffers = new char* [spoolCount];
|
|
Register_Pointer(spoolBuffers);
|
|
spoolFiles = new SpoolFile* [spoolCount];
|
|
Register_Pointer(spoolFiles);
|
|
|
|
//
|
|
//--------------------------------------------------------
|
|
// Allocate each spool buffer, and initial the spool files to none
|
|
//--------------------------------------------------------
|
|
//
|
|
for (int i=0; i<spoolCount; ++i)
|
|
{
|
|
spoolBuffers[i] = new char[spoolSize];
|
|
Register_Pointer(spoolBuffers[i]);
|
|
spoolFiles[i] = new SpoolFile(spoolBuffers[i], spoolSize);
|
|
Register_Object(spoolFiles[i]);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MissionReviewApplicationManager::~MissionReviewApplicationManager()
|
|
{
|
|
for (int i=0; i<spoolCount; ++i)
|
|
{
|
|
if (spoolFiles[i])
|
|
{
|
|
Unregister_Object(spoolFiles[i]);
|
|
delete spoolFiles[i];
|
|
}
|
|
Unregister_Pointer(spoolBuffers[i]);
|
|
delete spoolBuffers[i];
|
|
}
|
|
Unregister_Pointer(spoolFiles);
|
|
delete spoolFiles;
|
|
Unregister_Pointer(spoolBuffers);
|
|
delete spoolBuffers;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SpoolFile*
|
|
MissionReviewApplicationManager::GetEmptySpoolFile()
|
|
{
|
|
for (int i=0; i<spoolCount; ++i)
|
|
{
|
|
if (spoolFiles[i]->spoolState == SpoolFile::Empty)
|
|
{
|
|
spoolFiles[i]->spoolState = SpoolFile::Spooling;
|
|
return spoolFiles[i];
|
|
}
|
|
}
|
|
|
|
Fail("No spool files available!");
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
SpoolFile*
|
|
MissionReviewApplicationManager::GetStoredSpoolFile(CString spoolFileName)
|
|
{
|
|
for (int i=0; i<spoolCount; ++i)
|
|
{
|
|
if (spoolFiles[i]->spoolState == SpoolFile::Empty)
|
|
{
|
|
spoolFiles[i]->Read(spoolFileName);
|
|
if (spoolFiles[i]->spoolState == SpoolFile::Stored)
|
|
{
|
|
spoolFiles[i]->spoolState = SpoolFile::Playing;
|
|
return spoolFiles[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MissionReviewApplicationManager::StoreSpoolFile(SpoolFile *spool_file)
|
|
{
|
|
for (int i=0; i<spoolCount; ++i)
|
|
{
|
|
if (spoolFiles[i] == spool_file)
|
|
{
|
|
Verify(spoolFiles[i]->spoolState == SpoolFile::Spooling);
|
|
spoolFiles[i]->spoolState = SpoolFile::Stored;
|
|
|
|
struct tm newtime;
|
|
__int64 ltime;
|
|
|
|
// get local time
|
|
_time64(<ime);
|
|
|
|
// get UTC time
|
|
_gmtime64_s(&newtime, <ime);
|
|
|
|
char filename[2056];
|
|
sprintf(filename, "SPOOLS\\%.4i_%.2i_%.2i_%.2i%.2i%.2i.spl", newtime.tm_year + 1900, newtime.tm_mon + 1, newtime.tm_mday, newtime.tm_hour, newtime.tm_min, newtime.tm_sec);
|
|
|
|
spoolFiles[i]->SaveAs(filename);
|
|
|
|
// now copy the new file over to last.spl
|
|
CopyFileA(filename, "last.spl", FALSE);
|
|
|
|
spoolFiles[i]->Rewind();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MissionReviewApplicationManager::ReleaseSpoolFile(SpoolFile *spool_file)
|
|
{
|
|
for (int i=0; i<spoolCount; ++i)
|
|
{
|
|
if (spoolFiles[i] == spool_file)
|
|
{
|
|
Verify(spoolFiles[i]->spoolState != SpoolFile::Spooling);
|
|
spoolFiles[i]->spoolState = SpoolFile::Empty;
|
|
spoolFiles[i]->Rewind();
|
|
return;
|
|
}
|
|
}
|
|
}
|