#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; iisubsystemModelSize); } 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; }