Files
CydandClaude Fable 5 fdd9ac9d97 Initial import: Tesla Release 4.10 (Tesla:BattleTech & Tesla:Red Planet)
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>
2026-07-02 13:21:58 -05:00

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;
}