Files
BT411/engine/MUNGA/CSTR.h
arcattackandClaude Opus 4.8 7b7d465e5e Initial commit: bt411 -- standalone Windows BattleTech (Tesla 4.10 port)
Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.

Layout:
  engine/   MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
            work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
            models) + image codec; the minimal rp/ headers the audio HAL needs
  game/     reconstructed BT logic + surviving-original BT source + fwd shims
            + WinMain launcher
  content/  full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
  docs/     format specs + reconstruction ledgers
  reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
  tools/    MP console emulator + map/resource scanners

One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 21:03:40 -05:00

644 lines
15 KiB
C++

#pragma once
#include "style.h"
//namespace Munga
//{
class CStringRepresentation;
class CString;
class MemoryStream;
class StringRepresentation;
class pString;
class pcString;
typedef StringRepresentation& rString;
typedef const StringRepresentation& rcString;
class StringRepresentation
{
private:
char firstByte;
StringRepresentation();
StringRepresentation(rcString string);
public:
const char& operator[](size_t index) const
{
Check(this);
return (&firstByte)[index];
}
char& operator[](size_t index)
{
Check(this);
return (&firstByte)[index];
}
operator const char*() const
{
Check(this);
return &firstByte;
}
operator char*()
{
Check(this);
return &firstByte;
}
size_t GetLength() const
{
Check(this);
return strlen(&firstByte);
}
public:
rString operator=(const char* string)
{
Check(this);
Check_Pointer(string);
strcpy(&firstByte, string);
return *this;
}
rString operator=(rcString string)
{
Check(this);
Check(&string);
strcpy(&firstByte, &string.firstByte);
return *this;
}
rString operator=(char byte)
{
Check(this);
firstByte = byte;
return *this;
}
rString operator+=(const char* string)
{
Check(this);
Check_Pointer(string);
strcat(&firstByte, string);
return *this;
}
rString operator+=(char chr);
public:
int Compare(const char *string) const { return strcmp(&firstByte, string); }
int Compare(const char *string, size_t length) const { return strncmp(&firstByte, string, length); }
int CaselessCompare(const char *string) const { return stricmp(&firstByte, string); }
int CaselessCompare(const char *string, size_t length) const { return strnicmp(&firstByte, string, length); }
Logical operator<(const char* string) const { return Compare(string) < 0; }
Logical operator<=(const char* string) const { return Compare(string) <= 0; }
Logical operator>(const char* string) const { return Compare(string) > 0; }
Logical operator>=(const char* string) const { return Compare(string) >= 0; }
Logical operator==(const char* string) const { return Compare(string) == 0; }
Logical operator!=(const char* string) const { return Compare(string) != 0; }
Logical operator<(char chr) const { return firstByte < chr; }
Logical operator<=(char chr) const { return firstByte <= chr; }
Logical operator>(char chr) const { return firstByte > chr; }
Logical operator>=(char chr) const { return firstByte >= chr; }
Logical operator==(char chr) const { return firstByte == chr; }
Logical operator!=(char chr) const { return firstByte != chr; }
public:
friend std::ostream& operator <<(std::ostream &strm, rcString str) { return strm << &str.firstByte; }
friend MemoryStream& MemoryStream_Read(MemoryStream* stream, StringRepresentation *str);
friend MemoryStream& MemoryStream_Write(MemoryStream* stream, const StringRepresentation *str);
public:
#if defined(USE_SIGNATURE)
friend int Is_Signature_Bad(const StringRepresentation *p);
#endif
Logical TestInstance() const { return true; }
};
class pString SIGNATURED
{
friend class pcString;
protected:
StringRepresentation* stringText;
public:
pString(char *string = NULL) { stringText = (StringRepresentation*)string; }
pString(rString string) { stringText = &string; }
pString(const pString& string) { stringText = string.stringText; }
public:
pString& operator= (char *string)
{
stringText = (StringRepresentation*)string;
return *this;
}
pString& operator= (rString string)
{
stringText = &string;
return *this;
}
pString& operator= (const pString& string)
{
stringText = string.stringText;
return *this;
}
public:
pString& operator++()
{
++SKIPPY_CAST(char*, stringText);
return *this;
}
pString operator++(int) { return pString(SKIPPY_CAST(char*,stringText)++); }
pString& operator--()
{
--SKIPPY_CAST(char*,stringText);
return *this;
}
pString operator--(int) { return pString(SKIPPY_CAST(char*, stringText)--); }
public:
rString operator*() const { return *stringText; }
StringRepresentation* operator->() const { return stringText; }
char& operator[](size_t index) const
{
Check(this);
return (*stringText)[index];
}
operator char*() const
{
Check(this);
return (char*)stringText;
}
Logical operator!() const { return !stringText; }
char** GetTextPtr() { return (char**)&stringText; }
public:
friend MemoryStream& MemoryStream_Read(MemoryStream* stream, pString str) { return MemoryStream_Read(stream, str.stringText); }
public:
Logical TestInstance() const { return true; }
};
class pcString SIGNATURED
{
protected:
const StringRepresentation* stringText;
public:
pcString(const char *string = NULL) { stringText = (const StringRepresentation*)string; }
pcString(rcString string) { stringText = &string; }
pcString(const pString& string) { stringText = string.stringText; }
pcString(const pcString& string) { stringText = string.stringText; }
public:
pcString& operator=(const char *string)
{
stringText = (const StringRepresentation*)string;
return *this;
}
pcString& operator=(rcString string)
{
stringText = &string;
return *this;
}
pcString& operator=(const pString& string)
{
stringText = string.stringText;
return *this;
}
pcString& operator=(const pcString& string)
{
stringText = string.stringText;
return *this;
}
public:
pcString& operator++()
{
++SKIPPY_CAST(const char*, stringText);
return *this;
}
pcString operator++(int) { return pcString(SKIPPY_CAST(const char*, stringText)++); }
pcString& operator--()
{
--SKIPPY_CAST(const char*, stringText);
return *this;
}
pcString operator--(int) { return pcString(SKIPPY_CAST(const char*, stringText)--); }
public:
rcString operator*() const { return *stringText; }
const StringRepresentation* operator->() const { return stringText; }
const char& operator[](size_t index) const
{
Check(this);
return (*stringText)[index];
}
operator const char*() const
{
Check(this);
return (const char*)stringText;
}
Logical operator!() const { return !stringText; }
const char** GetTextPtr() { return (const char**)&stringText; }
public:
Logical TestInstance() const { return true; }
};
void Convert_From_Ascii(const char* str, char* value);
void Convert_From_Ascii(const char* str, Byte* value);
void Convert_From_Ascii(const char* str, short* value);
void Convert_From_Ascii(const char* str, Word* value);
void Convert_From_Ascii(const char* str, int* value);
void Convert_From_Ascii(const char* str, unsigned* value);
void Convert_From_Ascii(const char* str, long* value);
void Convert_From_Ascii(const char* str, LWord* value);
class CStringRepresentation SIGNATURED
{
friend CString;
friend CString operator + (const CString &str1, const CString &str2);
friend CString operator + (const CString &str1, char ch);
friend MemoryStream& MemoryStream_Read(MemoryStream* stream, CString *str);
friend void Convert_From_Ascii(const char *str, CString *value);
friend CStringRepresentation operator + (const CStringRepresentation &str1, const CStringRepresentation &str2);
friend CStringRepresentation operator + (const CStringRepresentation &str1, char ch);
private:
CStringRepresentation();
CStringRepresentation(const CStringRepresentation &str);
CStringRepresentation(const char *cstr);
public:
~CStringRepresentation();
Logical TestInstance() const;
private:
size_t Length() const;
size_t Size() const;
private:
operator char*() const;
CStringRepresentation operator = (const CStringRepresentation &str);
CStringRepresentation operator = (const char *cstr);
void operator += (const CStringRepresentation &str);
void operator += (char ch);
int Compare(const CStringRepresentation &str) const;
int operator < (const CStringRepresentation &str) const;
int operator > (const CStringRepresentation &str) const;
int operator <= (const CStringRepresentation &str) const;
int operator >= (const CStringRepresentation &str) const;
int operator == (const CStringRepresentation &str) const;
int operator != (const CStringRepresentation &str) const;
char operator [] (size_t pos) const;
CStringRepresentation GetNthToken(size_t nth_token, char *delimiters = NULL) const;
#if 0
void ToUpper();
void ToLower();
#endif
friend std::ostream& operator << (std::ostream &strm, const CStringRepresentation &str);
friend MemoryStream& MemoryStream_Read(MemoryStream* stream, CStringRepresentation *str);
friend MemoryStream& MemoryStream_Write(MemoryStream* stream, const CStringRepresentation& str);
friend void Convert_From_Ascii(const char *str, CStringRepresentation *value);
private:
void IncrementReferenceCount();
void DecrementReferenceCount();
private:
static size_t allocationIncrement;
static size_t CalculateSize(size_t needed);
size_t stringSize;
size_t stringLength;
char *stringText;
int referenceCount;
};
inline size_t CStringRepresentation::Length() const
{
Check(this);
return stringLength;
}
inline size_t CStringRepresentation::Size() const
{
Check(this);
return stringSize;
}
inline CStringRepresentation::operator char *() const
{
Check(this);
return stringText;
}
inline void CStringRepresentation::operator += (const CStringRepresentation &str)
{
Check(this);
*this = *this + str;
}
inline void CStringRepresentation::operator +=(char ch)
{
Check(this);
*this = *this + ch;
}
inline int CStringRepresentation::operator <(const CStringRepresentation &str) const
{
return (Compare(str) < 0);
}
inline int CStringRepresentation::operator >(const CStringRepresentation &str) const
{
return (Compare(str) > 0);
}
inline int CStringRepresentation::operator <=(const CStringRepresentation &str) const
{
return !(Compare(str) > 0);
}
inline int CStringRepresentation::operator >=(const CStringRepresentation &str) const
{
return !(Compare(str) < 0);
}
inline int CStringRepresentation::operator ==(const CStringRepresentation &str) const
{
return (Compare(str) == 0);
}
inline int CStringRepresentation::operator !=(const CStringRepresentation &str) const
{
return (Compare(str) != 0);
}
inline char CStringRepresentation::operator [](size_t pos) const
{
Check(this);
return (pos >= stringLength) ? ('\x00') : (stringText[pos]);
}
inline std::ostream& operator << (std::ostream &strm, const CStringRepresentation &str)
{
Check(&str);
strm << str.stringText;
return strm;
}
inline void CStringRepresentation::IncrementReferenceCount()
{
Check(this);
Verify(referenceCoutn >= 0);
referenceCount++;
}
inline void CStringRepresentation::DecrementReferenceCount()
{
Check(this);
Verify(referenceCount > 0);
if (--referenceCount == 0)
{
Unregister_Object(this);
delete this;
}
}
class CString SIGNATURED
{
public:
CString();
CString(const CString &str);
CString(const char *cstr);
~CString();
Logical TestInstance() const;
static Logical TestClass();
public:
size_t Length() const;
size_t Size() const;
public:
operator char*() const;
CString operator = (const CString &str);
CString operator = (const char *cstr);
friend CString operator + (const CString &str1, const CString &str2);
friend CString operator + (const CString &str1, char ch);
void operator += (const CString &str);
void operator += (char ch);
int Compare(const CString &str) const;
int operator < (const CString &str) const;
int operator > (const CString &str) const;
int operator <= (const CString &str) const;
int operator >= (const CString &str) const;
int operator == (const CString &str) const;
int operator != (const CString &str) const;
char operator [] (size_t pos) const;
CString GetNthToken(size_t nth_token, char *delimiters = NULL) const;
friend std::ostream& operator << (std::ostream &strm, const CString &str);
friend MemoryStream& MemoryStream_Read(MemoryStream* stream, CString *str);
friend MemoryStream& MemoryStream_Write(MemoryStream* stream, const CString* str);
friend void Convert_From_Ascii(const char *str, CString *value);
private:
CStringRepresentation *representation;
};
inline CString::CString()
{
representation = new CStringRepresentation;
Register_Object(representation);
representation->IncrementReferenceCount();
Verify(representation->referenceCount == 1);
}
inline CString::CString(const CString &str)
{
Check(&str);
representation = str.representation;
Check(representation);
representation->IncrementReferenceCount();
}
inline CString::CString(const char *cstr)
{
representation = new CStringRepresentation(cstr);
Register_Object(representation);
representation->IncrementReferenceCount();
Verify(representation->referenceCount == 1);
}
inline CString::~CString()
{
Check(representation);
representation->DecrementReferenceCount();
}
inline Logical CString::TestInstance() const
{
Check(representation);
return true;
}
inline size_t CString::Length() const
{
Check(representation);
return representation->Length();
}
inline size_t CString::Size() const
{
Check(representation);
return representation->Size();
}
inline CString::operator char *() const
{
Check(representation);
return representation->stringText;
}
inline CString operator + (const CString &str1, const CString &str2)
{
Check(&str1);
Check(&str2);
CStringRepresentation temp = *str1.representation + *str2.representation;
return CString(temp.stringText);
}
inline CString operator + (const CString &str1, char ch)
{
Check(&str1);
CStringRepresentation temp = *str1.representation + ch;
return CString(temp.stringText);
}
inline void CString::operator +=(const CString &str)
{
Check(this);
Check(&str);
*this = *this + str;
}
inline void CString::operator +=(char ch)
{
Check(this);
*this = *this + ch;
}
inline int CString::Compare(const CString &str) const
{
Check(&str);
Check(representation);
return representation->Compare(*str.representation);
}
inline int CString::operator <(const CString &str) const
{
return (Compare(str) < 0);
}
inline int CString::operator >(const CString &str) const
{
return (Compare(str) > 0);
}
inline int CString::operator <=(const CString &str) const
{
return !(Compare(str) > 0);
}
inline int CString::operator >=(const CString &str) const
{
return !(Compare(str) < 0);
}
inline int CString::operator ==(const CString &str) const
{
return (Compare(str) == 0);
}
inline int CString::operator !=(const CString &str) const
{
return (Compare(str) != 0);
}
inline char CString::operator [](size_t pos) const
{
Check(representation);
return (*representation)[pos];
}
inline CString CString::GetNthToken(size_t nth_token, char *delimiters) const
{
Check(representation);
CStringRepresentation temp = representation->GetNthToken(nth_token, delimiters);
return CString(temp.stringText);
}
inline std::ostream& operator << (std::ostream &strm, const CString &str)
{
Check(&str);
strm << *str.representation;
return strm;
}
inline MemoryStream& MemoryStream_Write(MemoryStream* stream, const CString* str)
{
return MemoryStream_Write(stream, *str->representation);
}
//}