Files
BT411/engine/MUNGA/RESOURCE.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

410 lines
9.2 KiB
C++

#pragma once
#include "filestrm.h"
//##########################################################################
//#################### ResourceDirectories ###########################
//##########################################################################
struct ResourcePhysicalFormat;
class ResourceFile;
struct ResourceDirectories
{
const char *modelDirectory;
const char *mapDirectory;
const char *collisionDirectory;
const char *audioDirectory;
const char *videoDirectory;
const char *gaugeDirectory;
const char *animationDirectory;
};
//##########################################################################
//################### ResourceDescription ############################
//##########################################################################
class ResourceDescription SIGNATURED
{
friend class ResourceFile;
friend class StreamableResourceFile;
//##########################################################################
// Resource ID stuff
//
public:
typedef int ResourceID;
enum
{
NullResourceID = -1
};
ResourceID resourceID;
//##########################################################################
// Resource Lock stuff
//
public:
void Lock() { if (!lockCount++) LoadResource(); }
void Unlock() { --lockCount; }
Logical IsLocked() { return lockCount > 0; }
void ReleaseUnlockedResource();
protected:
int lockCount;
//##########################################################################
// Resource Type stuff
//
public:
typedef int ResourceType;
enum
{
NullResourceType,
//
// ONLY LIST RESOURCE TYPES HERE -- These Are Really OBSOLETE
//
ModelListResourceType,
MapListResourceType,
AudioStreamListResourceType,
VideoListResourceType,
SubsystemListResourceType,
ControlMappingsListResourceType,
DamageZoneListResourceType,
SkeletonListResourceType,
FirstNonListResourceType,
MaxListResourceType = FirstNonListResourceType - 1,
//
// ALL OTHER RESOURCE TYPES
//
BoxedSolidStreamResourceType = FirstNonListResourceType,
VideoModelResourceType,
StaticAudioStreamResourceType,
InternalAudioStreamResourceType,
ExternalAudioStreamResourceType,
MakeMessageStreamResourceType,
GameModelResourceType,
AnimationResourceType,
SubsystemModelStreamResourceType,
GaugeImageStreamResourceType,
ControlMappingStreamResourceType,
DamageZoneStreamResourceType,
SkeletonStreamResourceType,
DropZoneResourceType,
EnvironmentZoneResourceType,
InterestZoneResourceType,
VehicleTableResourceType,
ExistanceBoxStreamResourceType,
CameraStreamResourceType,
RegistryStaticObjectStreamResourceType,
DamageLookupTableStreamResourceType,
ExplosionTableStreamResourceType,
GaugeAlarmStreamResourceType,
GaugeMissionReviewStreamResourceType,
ScenarioRoleResourceType
};
ResourceType resourceType;
//##########################################################################
// Resource Name stuff
//
public:
enum
{
NameSize = 32
};
char resourceName[NameSize];
//##########################################################################
// Loading stuff
//
public:
enum
{
LoadedBit=0,
LoadOnDemandBit
};
enum
{
Preload = 0, // HACK - for backwards compatability
LoadedFlag = 1 << LoadedBit,
LoadOnDemandFlag = 1 << LoadOnDemandBit,
};
int downloadPriority;
LWord resourceFlags;
size_t offsetInFile;
void SetLoaded() { resourceFlags |= LoadedFlag; }
void SetNotLoaded() { resourceFlags &= ~LoadedFlag; }
Logical IsLoaded() { return (resourceFlags & LoadedFlag) != 0; }
void LoadOnDemand() { resourceFlags |= LoadOnDemandFlag; }
void MarkForPreload() { resourceFlags &= ~LoadOnDemandFlag; }
Logical IsPreloadable() { return (resourceFlags & LoadOnDemandFlag) == 0; }
//##########################################################################
// Construction and Destruction
//
protected:
ResourceDescription(
ResourceFile *file,
const char* name,
ResourceType type,
int priority,
LWord resource_flags,
const void* address,
size_t size,
ResourceID index=NullResourceID
);
~ResourceDescription();
void LoadResource();
protected:
ResourceFile *resourceFile;
//##########################################################################
// Resource Data stuff
//
public:
void *resourceAddress;
size_t resourceSize;
//##########################################################################
// Test stuff
//
public:
Logical TestInstance() const;
};
//##########################################################################
// Format in physical memory: FILE,ROM,CD...
//
struct ResourcePhysicalFormat
{
ResourceDescription::ResourceID
resourceID;
ResourceDescription::ResourceType
resourceType;
char
resourceName[32];
int
downloadPriority;
LWord
resourceFlags;
size_t
resourceOffset,
resourceLength;
};
inline MemoryStream&
MemoryStream_Read(
MemoryStream* stream,
ResourcePhysicalFormat *ptr
)
{return stream->ReadBytes(ptr, sizeof(*ptr));}
inline MemoryStream&
MemoryStream_Write(
MemoryStream* stream,
const ResourcePhysicalFormat *ptr
)
{return stream->WriteBytes(ptr, sizeof(*ptr));}
//##########################################################################
//####################### ResourceFile ###############################
//##########################################################################
class ResourceFile SIGNATURED
{
friend class ResourceDescription;
public:
//
//-----------------------------------------------------------------------
// Constructors & destructors
//-----------------------------------------------------------------------
//
ResourceFile();
~ResourceFile();
public:
//
//-----------------------------------------------------------------------
// Public data
//-----------------------------------------------------------------------
//
enum {
IndexBlockSize = 50
};
Byte
versionArray[4];
int
labOnly;
protected:
ResourceDescription**
resourceArray;
int
resourceArraySize;
ResourceDescription::ResourceID
lastPreallocatedResourceID,
maxResourceID;
virtual void
LoadResource(ResourceDescription* res)
{Check(res); res->SetLoaded();}
public:
//
//-----------------------------------------------------------------------
// Public interface
//-----------------------------------------------------------------------
//
ResourceDescription::ResourceID
GetMaxResourceID()
{Check(this); return maxResourceID;}
void
PreAllocateIDs(ResourceDescription::ResourceID last_id)
{
Verify(lastPreallocatedResourceID == ResourceDescription::NullResourceID);
lastPreallocatedResourceID = last_id;
}
ResourceDescription*
AddResource(
const char* name,
ResourceDescription::ResourceType type,
int priority,
LWord load_flag,
const void* address,
size_t size,
ResourceDescription::ResourceID index=-1
);
ResourceDescription*
AddResourceList(
const char* name,
ResourceDescription::ResourceType type,
int priority,
LWord load_flag,
const ResourceDescription::ResourceID* address,
int count,
ResourceDescription::ResourceID index=-1
);
ResourceDescription*
AddResourceMemoryStream(
const char* name,
ResourceDescription::ResourceType type,
int priority,
LWord load_flag,
MemoryStream* memory_stream,
ResourceDescription::ResourceID index=-1
);
void
DeleteResource(ResourceDescription *resource);
ResourceDescription*
FindResourceDescription(
const char* name,
ResourceDescription::ResourceType type,
ResourceDescription::ResourceID after=-1
);
ResourceDescription*
FindResourceDescription(
ResourceDescription::ResourceID index
);
ResourceDescription*
SearchList(
ResourceDescription::ResourceID list_id,
ResourceDescription::ResourceType type
);
ResourceDescription*
SearchList(
ResourceDescription::ResourceID list_id,
const char* name
);
void
ReleaseUnlockedResources();
void
ReportLockedResources();
//
//---------------------------------------------------------------------------
// Lab tests
//---------------------------------------------------------------------------
//
public:
Logical
TestInstance() const;
static Logical
TestClass();
};
//##########################################################################
//################### StreamableResourceFile #############################
//##########################################################################
class StreamableResourceFile:
public ResourceFile
{
public:
//
//------------------------------------------------------------------------
// Constructors & destructors
//------------------------------------------------------------------------
//
enum {
FileNameLength = 1024
};
StreamableResourceFile();
StreamableResourceFile(const char * name);
StreamableResourceFile(const char * name, Byte version_array[3], int match_level = 3);
~StreamableResourceFile();
protected:
void
LoadResource(ResourceDescription* res);
FileStream
diskFile;
//
//------------------------------------------------------------------------
// Public data
//------------------------------------------------------------------------
//
public:
char
resourceFilename[FileNameLength];
int
Open(const char *file_name);
int
Save();
int
SaveAs(const char* file_name);
Logical
TestInstance() const;
static Logical
TestClass();
};