Archival snapshot of the Virtual World Entertainment Tesla cockpit software, 1994-1996: MUNGA engine and L4 pod layer source (Borland C++ 5.0), BT/RP game code, and game content (models, audio, maps, gauges, Division renderer data). Includes third-party libraries: Division dVS/DPL graphics, HMI SOS audio, WATTCP networking. Files are preserved byte-for-byte (.gitattributes disables all line-ending conversion). README.md documents the layout, target hardware, and toolchain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
270 lines
7.0 KiB
C++
270 lines
7.0 KiB
C++
//===========================================================================//
|
|
// File: memstrm.cpp //
|
|
// Project: MUNGA Brick: Resource Manager //
|
|
// Contents: Implementation Details of resource management //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
|
|
// PROPRIETARY AND CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include <munga.hpp>
|
|
#pragma hdrstop
|
|
|
|
#if !defined(MEMSTRM_HPP)
|
|
#include <memstrm.hpp>
|
|
#endif
|
|
|
|
//#############################################################################
|
|
//########################## MemoryStream ###############################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MemoryStream::MemoryStream(
|
|
void *stream_start,
|
|
size_t stream_size,
|
|
size_t initial_offset
|
|
)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
streamStart = (char*)stream_start;
|
|
streamSize = stream_size;
|
|
Verify(initial_offset <= stream_size);
|
|
currentPosition = streamStart + initial_offset;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MemoryStream&
|
|
MemoryStream::ReadBytes(
|
|
void *ptr,
|
|
size_t number_of_bytes
|
|
)
|
|
{
|
|
Check(this);
|
|
Check_Pointer(ptr);
|
|
Verify(number_of_bytes > 0);
|
|
Verify(GetBytesRemaining() >= number_of_bytes);
|
|
|
|
Mem_Copy(ptr, GetPointer(), number_of_bytes, number_of_bytes);
|
|
AdvancePointer(number_of_bytes);
|
|
return *this;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MemoryStream&
|
|
MemoryStream::WriteBytes(
|
|
const void *ptr,
|
|
size_t number_of_bytes
|
|
)
|
|
{
|
|
Check(this);
|
|
Check_Pointer(ptr);
|
|
Verify(number_of_bytes > 0)
|
|
|
|
Mem_Copy(GetPointer(), ptr, number_of_bytes, GetBytesRemaining());
|
|
AdvancePointer(number_of_bytes);
|
|
return *this;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MemoryStream&
|
|
MemoryStream_Write(
|
|
MemoryStream *stream,
|
|
istream *input
|
|
)
|
|
{
|
|
Check(stream);
|
|
Check_Pointer(input);
|
|
|
|
Verify(!input->bad());
|
|
input->clear();
|
|
|
|
//
|
|
//--------------------------------------------------------
|
|
// If we are reading a binary stream, read it in one chunk
|
|
//--------------------------------------------------------
|
|
//
|
|
#if defined(LBE4)
|
|
if (input->flags() & ios::binary)
|
|
{
|
|
#endif
|
|
input->seekg(0, ios::end);
|
|
int len=input->tellg();
|
|
input->clear();
|
|
input->seekg(0);
|
|
|
|
if (!stream->AllocateBytes(len))
|
|
{
|
|
Fail("Not enough memory remaining in stream!");
|
|
}
|
|
input->read((char*)stream->GetPointer(), len);
|
|
stream->AdvancePointer(len);
|
|
#if defined(LBE4)
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------------------------
|
|
// Read a text file character by character if we are a DOS machine
|
|
//----------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
input->clear();
|
|
input->seekg(0);
|
|
unsigned char byte;
|
|
|
|
while (input->get(byte))
|
|
{
|
|
*stream << byte;
|
|
}
|
|
}
|
|
#endif
|
|
return *stream;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MemoryStream&
|
|
MemoryStream_Write(
|
|
MemoryStream *stream,
|
|
const MemoryStream *input_stream
|
|
)
|
|
{
|
|
Check(stream);
|
|
Check(input_stream);
|
|
|
|
return
|
|
stream->WriteBytes(
|
|
input_stream->GetPointer(),
|
|
input_stream->GetBytesRemaining()
|
|
);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Logical
|
|
MemoryStream::TestInstance() const
|
|
{
|
|
return size_t(currentPosition - streamStart) <= streamSize;
|
|
}
|
|
|
|
//#############################################################################
|
|
//###################### DynamicMemoryStream ############################
|
|
//#############################################################################
|
|
|
|
//
|
|
// calculate the allocation size for stream
|
|
//
|
|
inline size_t
|
|
Calculate_Buffer_Size(size_t needed)
|
|
{
|
|
return (needed+0x80)&~0x7F;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
DynamicMemoryStream::DynamicMemoryStream(size_t stream_size):
|
|
MemoryStream(NULL, stream_size)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
streamSize = Calculate_Buffer_Size(stream_size);
|
|
streamStart = new char[streamSize];
|
|
Register_Pointer(streamStart);
|
|
|
|
currentPosition = streamStart;
|
|
streamLength = 0L;
|
|
ownsStream = True;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
DynamicMemoryStream::DynamicMemoryStream(
|
|
void *stream_start,
|
|
size_t stream_size,
|
|
size_t initial_offset
|
|
):
|
|
MemoryStream(stream_start, stream_size, initial_offset)
|
|
{
|
|
Check_Pointer(this);
|
|
ownsStream = False;
|
|
streamLength = stream_size;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
DynamicMemoryStream::~DynamicMemoryStream()
|
|
{
|
|
Check(this);
|
|
if (ownsStream)
|
|
{
|
|
Unregister_Pointer(streamStart);
|
|
delete[] streamStart;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Logical
|
|
DynamicMemoryStream::AllocateBytes(size_t count)
|
|
{
|
|
Check(this);
|
|
|
|
if (ownsStream && MemoryStream::GetBytesRemaining() < count)
|
|
{
|
|
size_t current_offset = currentPosition - streamStart;
|
|
size_t new_stream_size =
|
|
streamSize + count - MemoryStream::GetBytesRemaining() + 1;
|
|
new_stream_size = Calculate_Buffer_Size(new_stream_size);
|
|
char *new_stream_start = new char[new_stream_size];
|
|
Register_Pointer(new_stream_start);
|
|
|
|
Mem_Copy(new_stream_start, streamStart, streamSize, new_stream_size);
|
|
Unregister_Pointer(streamStart);
|
|
delete[] streamStart;
|
|
streamStart = new_stream_start;
|
|
streamSize = new_stream_size;
|
|
currentPosition = streamStart + current_offset;
|
|
}
|
|
return True;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MemoryStream&
|
|
DynamicMemoryStream::WriteBytes(
|
|
const void *ptr,
|
|
size_t number_of_bytes
|
|
)
|
|
{
|
|
Check(this);
|
|
Check_Pointer(ptr);
|
|
Verify(number_of_bytes > 0)
|
|
|
|
//
|
|
//--------------------------------------------------------------------
|
|
// If we own the stream, and we don't have enough memory to accept the
|
|
// write, copy the buffer and make a new stream that is bigger
|
|
//--------------------------------------------------------------------
|
|
//
|
|
AllocateBytes(number_of_bytes);
|
|
Mem_Copy(
|
|
GetPointer(),
|
|
ptr,
|
|
number_of_bytes,
|
|
MemoryStream::GetBytesRemaining()
|
|
);
|
|
AdvancePointer(number_of_bytes);
|
|
|
|
streamLength = Max(streamLength, GetBytesUsed());
|
|
return *this;
|
|
}
|
|
|