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>
194 lines
6.8 KiB
C++
194 lines
6.8 KiB
C++
#pragma once
|
|
|
|
#include "namelist.h"
|
|
#include "scalar.h"
|
|
|
|
class NotationFile;
|
|
class NotationFile__Notation;
|
|
class NotationFile__NotePage;
|
|
class NameList;
|
|
class AlphaNameList;
|
|
|
|
inline Logical Comment_Line(const char *p) { return ((*p == ';') || (*p == '#') || (*p == '/' && *(p+1) == '/')); }
|
|
|
|
class NotationFile SIGNATURED
|
|
{
|
|
friend class NotationFile__NotePage;
|
|
friend class NotationFile__Notation;
|
|
|
|
public:
|
|
typedef NotationFile__Notation Notation;
|
|
typedef NotationFile__NotePage NotePage;
|
|
|
|
private:
|
|
char *fileName;
|
|
NotePage *firstNotePage, *lastNotePage;
|
|
long pageCount, cleanPageCount;
|
|
Logical dirtyFlag;
|
|
NotePage *saveNotePage;
|
|
Enumeration operationModes;
|
|
|
|
enum WriteMode
|
|
{
|
|
//--------------------------------------------
|
|
// NOTE: These numbers are not arbitrary!
|
|
// See code before changing or adding values.
|
|
//--------------------------------------------
|
|
Size_Only = 0,
|
|
Disk_File = 1,
|
|
Text_Memory = 2,
|
|
Binary_Memory = 3 // not implemented yet
|
|
};
|
|
|
|
public:
|
|
|
|
#if 0
|
|
enum Mode
|
|
{
|
|
// Access Modes:
|
|
EXCLUSIVE = 0,
|
|
SHARED = 1,
|
|
// Error Modes:
|
|
QUIET = 0,
|
|
FATAL = 2,
|
|
// Default Modes:
|
|
DEFAULT = (EXCLUSIVE | QUIET)
|
|
};
|
|
#endif
|
|
|
|
enum OperationModes
|
|
{
|
|
RawOperationModes = 0x0000,
|
|
SkipBlanksListMode = 0x0001,
|
|
CleanPageListMode = 0x0002,
|
|
CleanEntryListMode = 0x0004,
|
|
IgnorePageCaseMode = 0x0008,
|
|
IgnoreEntryCaseMode = 0x0010,
|
|
DefaultOperationModes = (SkipBlanksListMode),
|
|
CleanListMode = (CleanPageListMode | CleanEntryListMode),
|
|
IgnoreCaseMode = (IgnorePageCaseMode | IgnoreEntryCaseMode),
|
|
RelaxedOperationModes = (CleanListMode | IgnoreCaseMode)
|
|
};
|
|
|
|
NotationFile(const char *filename = NULL, Enumeration operation_modes = DefaultOperationModes);
|
|
~NotationFile();
|
|
|
|
Enumeration GetModes() { Check(this); return operationModes; }
|
|
Enumeration PutModes(Enumeration operation_modes) { Check(this); return (operationModes = operation_modes); }
|
|
Enumeration SetMode(Enumeration operation_modes) { Check(this); return (operationModes |= operation_modes); }
|
|
Enumeration ClearMode(Enumeration operation_modes) { Check(this); return (operationModes &= ~operation_modes); }
|
|
Logical IsDirty() const { Check(this); return dirtyFlag; }
|
|
Logical IsEmpty() const { Check(this); return (pageCount == 0L); }
|
|
const char *GetFileName() const { Check(this); return fileName; }
|
|
long PageCount() const { Check(this); return ((operationModes & CleanPageListMode) ? cleanPageCount:pageCount); }
|
|
Logical PageExists(const char *pagename);
|
|
long EntryCount(const char *pagename);
|
|
|
|
NotePage* SetPage(const char *pagename, const char *comment = NULL);
|
|
NotePage* AppendPage(const char *pagename, const char *comment = NULL);
|
|
|
|
int GetEntry(const char *pagename, const char *entryname, const char **contents);
|
|
int GetEntry(const char *pagename, const char *entryname, int *value);
|
|
int GetEntry(const char *pagename, const char *entryname, Scalar *value);
|
|
int GetEntry(const char *pagename, const char *entryname, double *value);
|
|
int GetLogicalEntry(const char *pagename, const char *entryname, Logical *value);
|
|
|
|
void SetEntry(const char *pagename, const char *entryname, int value);
|
|
void SetEntry(const char *pagename, const char *entryname, Scalar value);
|
|
void SetEntry(const char *pagename, const char *entryname, double value);
|
|
void SetEntry(const char *pagename, const char *entryname, const char *contents);
|
|
void SetLogicalEntry(const char *pagename, const char *entryname, Logical value);
|
|
|
|
void AppendEntry(const char *pagename, const char *entryname, const char *contents);
|
|
void AppendEntry(const char *pagename, const char *entryname, int value);
|
|
void AppendEntry(const char *pagename, const char *entryname, Scalar value);
|
|
void AppendEntry(const char *pagename, const char *entryname, double value);
|
|
void AppendLogicalEntry(const char *pagename, const char *entryname, Logical value);
|
|
|
|
NameList* MakeEntryList(const char *pagename, const char *entryname_prefix = NULL);
|
|
NameList* MakeEntryList(NotationFile::NotePage *notepage, const char *entryname_prefix = NULL);
|
|
NameList* MakePageList(const char *pagename_prefix = NULL);
|
|
|
|
AlphaNameList* MakeAlphaEntryList(const char *pagename, const char *entryname_prefix = NULL);
|
|
AlphaNameList* MakeAlphaEntryList(NotationFile::NotePage *notepage, const char *entryname_prefix = NULL);
|
|
AlphaNameList* MakeAlphaPageList(const char *pagename_prefix = NULL);
|
|
|
|
void DeleteEntry(const char *pagename, const char *entryname);
|
|
void DeletePage(const char *pagename);
|
|
void ReadFile(const char *filename);
|
|
void ReadText(char *start, long length);
|
|
Logical WriteFile(const char *filename = NULL);
|
|
long SizeOfText();
|
|
long WriteText(char *buffer, long size);
|
|
void Abort();
|
|
|
|
void DeleteStandardPages();
|
|
void MarkLabOnly();
|
|
Logical IsMarkedLabOnly() { Check(this); return PageExists("LAB_ONLY"); }
|
|
|
|
private:
|
|
void AppendNotePage(NotePage *notepage);
|
|
Logical FindNotePage(const char *pagename, NotePage **notepage);
|
|
Logical FindNotePage(const char *pagename, NotePage **notepage, NotePage **prevpage);
|
|
void SetDirty() { Check(this); dirtyFlag = true; }
|
|
void DeletePage(NotePage *notepage, NotePage *prev);
|
|
void Read(char *buffer);
|
|
long Write(std::ostream &stream, WriteMode mode = Disk_File);
|
|
|
|
public:
|
|
Logical TestInstance() const;
|
|
static Logical TestClass();
|
|
};
|
|
|
|
class NotationFile__Notation SIGNATURED
|
|
{
|
|
friend class NotationFile;
|
|
friend class NotationFile__NotePage;
|
|
|
|
private:
|
|
NotationFile::Notation *nextNotation;
|
|
char *notationName, *notationEntry;
|
|
Logical cleanNotation;
|
|
|
|
NotationFile__Notation()
|
|
{
|
|
nextNotation = NULL;
|
|
notationName = notationEntry = NULL;
|
|
cleanNotation = false;
|
|
}
|
|
~NotationFile__Notation();
|
|
|
|
void SetName(const char *entryname, long *clean_notation_count);
|
|
void SetEntry(const char *contents);
|
|
const char* GetName() const { Check(this); return notationName; }
|
|
const char* GetEntry() const { Check(this); return notationEntry; }
|
|
long WriteNotation(std::ostream &stream, NotationFile::WriteMode mode) const;
|
|
Logical TestInstance() const;
|
|
};
|
|
|
|
class NotationFile__NotePage SIGNATURED
|
|
{
|
|
friend class NotationFile;
|
|
|
|
private:
|
|
NotationFile *notationFile;
|
|
NotationFile::NotePage *nextNotePage;
|
|
NotationFile::Notation *firstNotation, *lastNotation;
|
|
long notationCount, cleanNotationCount;
|
|
char *pageName, *pageComment;
|
|
Logical cleanPage;
|
|
|
|
NotationFile__NotePage(NotationFile *notation_file);
|
|
~NotationFile__NotePage();
|
|
|
|
void SetName(const char *pagename, long *clean_page_count);
|
|
void SetComment(const char *comment);
|
|
const char *GetName() const { Check(this); return pageName; }
|
|
void AppendNote(NotationFile::Notation *note);
|
|
Logical FindNote(const char *entryname, NotationFile::Notation **note);
|
|
Logical FindNote(const char *entryname, NotationFile::Notation **note, NotationFile::Notation **prev);
|
|
void UpdateNote(NotationFile::Notation *note);
|
|
void DeleteNote(const char *entryname);
|
|
long WriteNote(std::ostream &stream, NotationFile::WriteMode mode) const;
|
|
Logical TestInstance() const;
|
|
}; |