Files
RP412/MUNGA/DOORFRAM.cpp
T
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

279 lines
6.5 KiB
C++

#include "munga.h"
#pragma hdrstop
#include "boxsolid.h"
#include "fileutil.h"
#include "doorfram.h"
#include "door.h"
#include "app.h"
#include "notation.h"
#include "namelist.h"
//#############################################################################
// Shared Data Support
//
Derivation* DoorFrame::GetClassDerivations()
{ static Derivation classDerivations(UnscalableTerrain::GetClassDerivations(), "DoorFrame");
return &classDerivations;
}
DoorFrame::SharedData
DoorFrame::DefaultData(
DoorFrame::GetClassDerivations(),
DoorFrame::GetMessageHandlers(),
DoorFrame::GetAttributeIndex(),
DoorFrame::StateCount,
(Entity::MakeHandler)DoorFrame::Make
);
//#############################################################################
// Test Support
//
Logical
DoorFrame::TestInstance() const
{
return IsDerivedFrom(*GetClassDerivations());
}
//#############################################################################
// Construction and Destruction
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DoorFrame::DoorFrame(
DoorFrame::MakeMessage *creation_message,
DoorFrame::SharedData &virtual_data
):
UnscalableTerrain(creation_message, virtual_data)
{
Check_Pointer(this);
Check(creation_message);
Check(&virtual_data);
SetValidFlag();
SetPerformance(&DoorFrame::DoNothing);
//
// Get the subsystem_resource from the resource file
//
Check(application);
ResourceDescription *subsystem_resource =
application->GetResourceFile()->SearchList(
resourceID,
ResourceDescription::SubsystemModelStreamResourceType
);
Check(subsystem_resource);
subsystem_resource->Lock();
Check_Pointer(subsystem_resource->resourceAddress);
MemoryStream subsystem_stream(
subsystem_resource->resourceAddress,
subsystem_resource->resourceSize);
subsystemCount = *(int*)subsystem_stream.GetPointer();
subsystem_stream.AdvancePointer(sizeof(int));
Verify(subsystemCount);
//
// Set up Subsystems
//
subsystemArray = new (Subsystem(*[subsystemCount]));
Register_Pointer(subsystemArray);
//
// Attach the doors as defined in the mod file
//
for (int ii=BasicSubsystemCount; ii<subsystemCount; ++ii)
{
Door::SubsystemResource *subsystem_resource =
(Door::SubsystemResource *)subsystem_stream.GetPointer();
subsystemArray[ii] = new Door(this, ii, subsystem_resource);
Register_Object(subsystemArray[ii]);
subsystem_stream.AdvancePointer(subsystem_resource->subsystemModelSize);
}
subsystem_resource->Unlock();
Check(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DoorFrame*
DoorFrame::Make(DoorFrame::MakeMessage *creation_message)
{
return new DoorFrame(creation_message);
}
Logical
DoorFrame::CreateMakeMessage(
MakeMessage *creation_message,
NotationFile *model_file,
const ResourceDirectories *directories
)
{
Check(creation_message);
Check(model_file);
if (
!UnscalableTerrain::CreateMakeMessage(
creation_message,
model_file,
directories
)
)
{
return false;
}
creation_message->classToCreate = RegisteredClass::DoorFrameClassID;
creation_message->instanceFlags =
MasterInstance|DynamicFlag|MapFlag|TrappedFlag;
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
DoorFrame::~DoorFrame()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceDescription::ResourceID
DoorFrame::CreateSubsystemStream(
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories
)
{
Check(resource_file);
Check_Pointer(model_name);
Check(model_file);
Check_Pointer(directories);
//
//-------------------
// Find the .sub file
//-------------------
//
const char* entry_data;
if (
!model_file->GetEntry(
"gamedata",
"Subsystems",
&entry_data
)
)
{
std::cerr << model_name << " is missing .sub file specification!\n";
return -1;
}
char *sub_filename = MakePathedFilename(directories->modelDirectory, entry_data);
Register_Pointer(sub_filename);
NotationFile *sub_file = new NotationFile(sub_filename);
Register_Object(sub_file);
NameList *sub_namelist = sub_file->MakePageList();
Register_Object(sub_namelist);
int subsystem_count = sub_file->PageCount();
if (!subsystem_count)
{
std::cerr << sub_filename << " empty of missing!\n";
Dump_And_Die:
Unregister_Pointer(sub_filename);
delete sub_filename;
Unregister_Object(sub_file);
delete sub_file;
Unregister_Object(sub_namelist);
delete sub_namelist;
return -1;
}
int buf_size =
subsystem_count * sizeof(Door::SubsystemResource) + sizeof(int);
char *buffer = new char[buf_size];
Register_Pointer(buffer);
MemoryStream subsystem_stream(buffer, buf_size);
*(int*)subsystem_stream.GetPointer() = subsystem_count;
subsystem_stream.AdvancePointer(sizeof(int));
NameList::Entry *sub_entry = sub_namelist->GetFirstEntry();
while(sub_entry)
{
char subsystem_name[32];
Str_Copy(subsystem_name, sub_entry->GetName(), sizeof(subsystem_name));
const char *sub_type;
if(!sub_file->GetEntry(
subsystem_name,
"Type",
&sub_type
)
)
{
std::cerr << model_name << ':' << subsystem_name << " missing Type!\n";
Dump_And_Die_2:
Unregister_Pointer(buffer);
delete[] buffer;
goto Dump_And_Die;
}
Subsystem::SubsystemResource *sub_res =
(Subsystem::SubsystemResource*)subsystem_stream.GetPointer();
if (!strcmp(sub_type, "DoorClassID"))
{
if (
Door::CreateStreamedSubsystem(
model_file,
model_name,
subsystem_name,
(Door::SubsystemResource*)sub_res,
sub_file,
directories,
resource_file
) == -1
)
{
goto Dump_And_Die_2;
}
}
else
{
std::cerr << model_name << ':' << subsystem_name
<< " has an unknown component type of " << sub_type << std::endl;
goto Dump_And_Die_2;
}
subsystem_stream.AdvancePointer(sub_res->subsystemModelSize);
sub_entry = sub_entry->GetNextEntry();
}
ResourceDescription *res_desc = resource_file->
ResourceFile::AddResourceMemoryStream(
model_name,
ResourceDescription::SubsystemModelStreamResourceType,
1,
ResourceDescription::Preload,
&subsystem_stream
);
ResourceDescription::ResourceID res_id;
if(!res_desc)
{
res_id = ResourceDescription::NullResourceID;
}
else
{
res_id = res_desc->resourceID;
}
Unregister_Pointer(sub_filename);
delete sub_filename;
Unregister_Object(sub_file);
delete sub_file;
Unregister_Object(sub_namelist);
delete sub_namelist;
Unregister_Pointer(buffer);
delete[] buffer;
return res_id;
}