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>
638 lines
14 KiB
C++
638 lines
14 KiB
C++
#include "munga.h"
|
|
#pragma hdrstop
|
|
|
|
#include "tool.h"
|
|
#include "fileutil.h"
|
|
#include "dropzone.h"
|
|
#include "camship.h"
|
|
#include "doorfram.h"
|
|
#include "eyecandy.h"
|
|
#include "explode.h"
|
|
#include "gaugalrm.h"
|
|
#include "cultural.h"
|
|
#include "scnrole.h"
|
|
#include "namelist.h"
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ApplicationTool::CreateModelResource(
|
|
ModelData &model_resources,
|
|
const char *model_class,
|
|
ResourceFile *resource_file,
|
|
const char *model_name,
|
|
NotationFile *model_file,
|
|
const ResourceDirectories *directories
|
|
)
|
|
{
|
|
if (!stricmp(model_class,"CameraShipClassID"))
|
|
{
|
|
model_resources.subsystemResourceID =
|
|
CameraShip::CreateModelResource(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
else if (!stricmp(model_class,"DoorFrameClassID"))
|
|
{
|
|
model_resources.subsystemResourceID =
|
|
DoorFrame::CreateSubsystemStream(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
else if(!stricmp(model_class,"EyeCandyClassID"))
|
|
{
|
|
model_resources.subsystemResourceID =
|
|
EyeCandy::CreateModelResource(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
else if(!stricmp(model_class,"ExplosionClassID"))
|
|
{
|
|
model_resources.gameResourceID =
|
|
Explosion::CreateModelResource(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
else if (!stricmp(model_class, "CulturalIconClassID"))
|
|
{
|
|
model_resources.gameResourceID =
|
|
CulturalIcon::CreateModelResource(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
model_resources.damageZoneResourceID =
|
|
CulturalIcon::CreateDamageZoneStream(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
else if (!stricmp(model_class, "LandmarkClassID"))
|
|
{
|
|
model_resources.gameResourceID =
|
|
Landmark::CreateModelResource(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
model_resources.damageZoneResourceID =
|
|
Landmark::CreateDamageZoneStream(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
else if(!stricmp(model_class,"ScenarioRoleClassID"))
|
|
{
|
|
model_resources.gameResourceID =
|
|
ScenarioRole::CreateModelResource(
|
|
resource_file,
|
|
model_name,
|
|
model_file,
|
|
directories
|
|
);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Logical
|
|
ApplicationTool::WriteModels(
|
|
NotationFile *notation_file,
|
|
NotationFile *ops_file,
|
|
StreamableResourceFile *file,
|
|
const char *model_name,
|
|
const ResourceDirectories *resource_directories,
|
|
int resource_id
|
|
)
|
|
{
|
|
//
|
|
//------------------------------------------------
|
|
// If model is already in resource then we're done
|
|
//------------------------------------------------
|
|
//
|
|
ResourceDescription *res_description = file->FindResourceDescription(
|
|
model_name,
|
|
ResourceDescription::ModelListResourceType
|
|
);
|
|
if (res_description)
|
|
{
|
|
return True;
|
|
}
|
|
|
|
//
|
|
//----------------------------------------
|
|
// Initialize model data and ops file info
|
|
//----------------------------------------
|
|
//
|
|
ModelData model;
|
|
model.videoResourceID = -1;
|
|
model.audioResourceID = -1;
|
|
model.collisionID = -1;
|
|
model.gameResourceID = -1;
|
|
model.subsystemResourceID = -1;
|
|
model.controlsMappingsResourceID = -1;
|
|
model.skeletonResourceID = -1;
|
|
model.damageZoneResourceID = -1;
|
|
model.gaugeImageResourceID =-1;
|
|
model.gaugeAlarmResourceID =-1;
|
|
model.gaugeMissionReviewResourceID =-1;
|
|
model.explosionTableResourceID = -1;
|
|
|
|
const char *ops_name;
|
|
ops_file->GetEntry("resource", "res name", &ops_name);
|
|
|
|
//
|
|
//------------------------------------------------
|
|
// Find the geometry file and make an entry for it
|
|
//------------------------------------------------
|
|
//
|
|
model.videoResourceID =
|
|
platformTool->CreateModelVideoStreamResource(
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------------
|
|
// Find the audio file and make and entry for it
|
|
//--------------------------------------------------
|
|
//
|
|
model.audioResourceID =
|
|
platformTool->CreateModelAudioStreamResource(
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories
|
|
);
|
|
|
|
const char *model_class;
|
|
if (notation_file->GetEntry("gamedata","class",&model_class))
|
|
{
|
|
CreateModelResource(
|
|
model,
|
|
model_class,
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories
|
|
);
|
|
}
|
|
|
|
//
|
|
//----------------------------------------------
|
|
// Find the animations and make entries for them
|
|
//----------------------------------------------
|
|
//
|
|
|
|
char animation_name[200];
|
|
|
|
if(notation_file->PageExists("animations"))
|
|
{
|
|
NameList *animationnames =
|
|
notation_file->MakeEntryList("animations", "animation");
|
|
Register_Object(animationnames);
|
|
NameList::Entry *animationentry = animationnames->GetFirstEntry();
|
|
|
|
while (animationentry)
|
|
{
|
|
strcpy(animation_name, animationentry->GetChar());
|
|
|
|
char *filename2 =
|
|
MakePathedFilename(
|
|
resource_directories->animationDirectory,
|
|
animation_name
|
|
);
|
|
Register_Pointer(filename2);
|
|
|
|
if(verboseMode)
|
|
{
|
|
Tell("Opening Animation : " << filename2 << std::endl);
|
|
}
|
|
|
|
NotationFile *new_notation_file = new NotationFile(filename2);
|
|
Register_Object(new_notation_file);
|
|
|
|
|
|
labOnly |= new_notation_file->IsMarkedLabOnly();
|
|
|
|
const char *anim_p = StripExtension(StripDirectory(animation_name));
|
|
const char *temp_pointer = animationentry->GetName();
|
|
|
|
if (new_notation_file->PageCount())
|
|
{
|
|
if(strstr(temp_pointer, "transition"))
|
|
{
|
|
|
|
if (verboseMode)
|
|
{
|
|
std::cout << "Type Transition" << std::endl;
|
|
}
|
|
|
|
if (!WriteAnimationTransition(new_notation_file, file, anim_p))
|
|
{
|
|
|
|
std::cout << "Error - Animation did not work : " << filename2 << std::endl;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(verboseMode)
|
|
{
|
|
std::cout << "Type Cycle" << std::endl;
|
|
}
|
|
if (!WriteAnimationCycle(new_notation_file, file, anim_p))
|
|
{
|
|
|
|
std::cout << "Error - Animation did not work : " << filename2 << std::endl;
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::cout << filename2 << " does not exist " << std::endl;
|
|
}
|
|
|
|
Unregister_Pointer(filename2);
|
|
delete filename2;
|
|
|
|
Unregister_Object(new_notation_file);
|
|
delete new_notation_file;
|
|
|
|
animationentry = animationentry->GetNextEntry();
|
|
}
|
|
|
|
Unregister_Object(animationnames);
|
|
delete animationnames;
|
|
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------
|
|
// Find the collision file and make and entry for it
|
|
//--------------------------------------------------
|
|
//
|
|
const char *entry_data;
|
|
if (notation_file->GetEntry("collision","name",&entry_data))
|
|
{
|
|
Check_Pointer(entry_data);
|
|
|
|
Logical convert_boxes = False;
|
|
const char *dummy;
|
|
|
|
if (notation_file->GetEntry("collision","convertboxes",&dummy))
|
|
{
|
|
convert_boxes = True;
|
|
}
|
|
else if (!stricmp(model_class, "LandmarkClassID"))
|
|
{
|
|
convert_boxes = True;
|
|
}
|
|
else if(!stricmp(model_class,"CulturalIconClassID"))
|
|
{
|
|
convert_boxes = True;
|
|
}
|
|
|
|
|
|
model.collisionID =
|
|
BoxedSolidResource::CreateBoxedSolidStream(
|
|
entry_data,
|
|
file,
|
|
resource_directories,
|
|
convert_boxes
|
|
);
|
|
}
|
|
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// Find the controls mapping page and build a list of all the control
|
|
// mappings there
|
|
//-------------------------------------------------------------------
|
|
//
|
|
if (notation_file->PageExists("ControlMappings"))
|
|
{
|
|
NameList *mapping_list = notation_file->MakeEntryList("ControlMappings");
|
|
Register_Object(mapping_list);
|
|
NameList::Entry *entry = mapping_list->GetFirstEntry();
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Count the number of mapping files, and build a list big enough to hold
|
|
// all of the mappings
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
int count=0;
|
|
while (entry)
|
|
{
|
|
++count;
|
|
entry = entry->GetNextEntry();
|
|
}
|
|
if (!count)
|
|
{
|
|
Unregister_Object(mapping_list);
|
|
delete mapping_list;
|
|
goto Make_Directory;
|
|
}
|
|
ResourceDescription::ResourceID *mappings =
|
|
new ResourceDescription::ResourceID[count];
|
|
Register_Pointer(mappings);
|
|
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// Step through the list, reading each of the specified control files
|
|
//-------------------------------------------------------------------
|
|
//
|
|
entry = mapping_list->GetFirstEntry();
|
|
count = 0;
|
|
while (entry)
|
|
{
|
|
mappings[count] = -1;
|
|
char *ctl_filename =
|
|
MakePathedFilename(
|
|
resource_directories->modelDirectory,
|
|
entry->GetChar()
|
|
);
|
|
Register_Pointer(ctl_filename);
|
|
|
|
NotationFile *ctl_file = new NotationFile(ctl_filename);
|
|
Register_Object(ctl_file);
|
|
if (!ctl_file->PageCount())
|
|
{
|
|
std::cout << model_name << " unable to open " << ctl_filename << "!\n";
|
|
Unwind_1:
|
|
Unregister_Object(ctl_file);
|
|
delete ctl_file;
|
|
Unregister_Pointer(ctl_filename);
|
|
delete[] ctl_filename;
|
|
Unregister_Pointer(mappings);
|
|
delete[] mappings;
|
|
Unregister_Object(mapping_list);
|
|
delete mapping_list;
|
|
goto Make_Directory;
|
|
}
|
|
|
|
//
|
|
//-----------------------------
|
|
// Find out which model to call
|
|
//-----------------------------
|
|
//
|
|
mappings[count] =
|
|
CreateControlMappingStream(
|
|
model_class,
|
|
entry->GetName(),
|
|
ctl_file,
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories,
|
|
platformTool
|
|
);
|
|
if (mappings[count] == -1)
|
|
{
|
|
std::cout << model_name << " unable to process " << entry->GetName()
|
|
<< " control mapping!\n";
|
|
goto Unwind_1;
|
|
}
|
|
Unregister_Object(ctl_file);
|
|
delete ctl_file;
|
|
Unregister_Pointer(ctl_filename);
|
|
delete[] ctl_filename;
|
|
++count;
|
|
entry = entry->GetNextEntry();
|
|
}
|
|
|
|
res_description = file->AddResourceList(
|
|
model_name,
|
|
ResourceDescription::ControlMappingsListResourceType,
|
|
1,
|
|
ResourceDescription::LoadOnDemandFlag,
|
|
mappings,
|
|
count
|
|
);
|
|
|
|
|
|
Verify(res_description);
|
|
model.controlsMappingsResourceID = res_description->resourceID;
|
|
Unregister_Object(mapping_list);
|
|
Unregister_Pointer(mappings);
|
|
delete mapping_list;
|
|
delete[] mappings;
|
|
}
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// Find the gaugeMissionReview page and save the pertinent data
|
|
//-------------------------------------------------------------------
|
|
//
|
|
model.gaugeMissionReviewResourceID =
|
|
platformTool->CreateModelGaugeMissionReviewStreamResource(
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories
|
|
);
|
|
//
|
|
//-----------------------------------------------
|
|
// Find GaugeImage File and make an entry for it
|
|
//-----------------------------------------------
|
|
//
|
|
model.gaugeImageResourceID =
|
|
platformTool->CreateModelGaugeImageStreamResource(
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories
|
|
);
|
|
//
|
|
//------------------------------------------------
|
|
// Find Gauge alarm file and make an entry for it
|
|
//------------------------------------------------
|
|
//
|
|
{
|
|
GaugeAlarmManager
|
|
*gaugeAlarmManager = platformTool->gaugeAlarmManager;
|
|
|
|
if (gaugeAlarmManager == NULL)
|
|
{
|
|
model.gaugeAlarmResourceID = -1;
|
|
}
|
|
else
|
|
{
|
|
Check(gaugeAlarmManager);
|
|
|
|
model.gaugeAlarmResourceID =
|
|
gaugeAlarmManager->CreateModelGaugeAlarmStreamResource(
|
|
file,
|
|
model_name,
|
|
notation_file,
|
|
resource_directories
|
|
);
|
|
}
|
|
}
|
|
//
|
|
//-------------------------------------------
|
|
// Make a directory for the model information
|
|
//-------------------------------------------
|
|
//
|
|
Make_Directory:
|
|
int *model_data = new int[20];
|
|
Register_Pointer(model_data);
|
|
int i = 0;
|
|
if (model.videoResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.videoResourceID;
|
|
}
|
|
if (model.audioResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.audioResourceID;
|
|
}
|
|
if (model.collisionID >= 0)
|
|
{
|
|
model_data[i++] = model.collisionID;
|
|
}
|
|
if (model.gameResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.gameResourceID;
|
|
}
|
|
if (model.subsystemResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.subsystemResourceID;
|
|
}
|
|
if (model.skeletonResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.skeletonResourceID;
|
|
}
|
|
if (model.controlsMappingsResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.controlsMappingsResourceID;
|
|
}
|
|
if (model.damageZoneResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.damageZoneResourceID;
|
|
}
|
|
if (model.gaugeImageResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.gaugeImageResourceID;
|
|
}
|
|
if (model.gaugeAlarmResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.gaugeAlarmResourceID;
|
|
}
|
|
if (model.gaugeMissionReviewResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.gaugeMissionReviewResourceID;
|
|
}
|
|
if (model.explosionTableResourceID >= 0)
|
|
{
|
|
model_data[i++] = model.explosionTableResourceID;
|
|
}
|
|
|
|
res_description =
|
|
file->FindResourceDescription(
|
|
model_name,
|
|
ResourceDescription::ModelListResourceType
|
|
);
|
|
|
|
if (!res_description)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
if (resource_id == -1)
|
|
{
|
|
file->AddResourceList(
|
|
model_name,
|
|
ResourceDescription::ModelListResourceType,
|
|
1,
|
|
ResourceDescription::Preload,
|
|
model_data,
|
|
i
|
|
);
|
|
}
|
|
else
|
|
{
|
|
|
|
ResourceDescription
|
|
*res_des = file->FindResourceDescription(resource_id);
|
|
|
|
if (!res_des)
|
|
{
|
|
file->AddResourceList(
|
|
model_name,
|
|
ResourceDescription::ModelListResourceType,
|
|
1,
|
|
ResourceDescription::Preload,
|
|
model_data,
|
|
i,
|
|
resource_id
|
|
);
|
|
}
|
|
else
|
|
{
|
|
DEBUG_STREAM << model_name << " : " << resource_id << std::endl << std::flush;
|
|
Fail("Duplicate Resource Number");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (resource_id == -1)
|
|
{
|
|
file->AddResource(
|
|
model_name,
|
|
ResourceDescription::ModelListResourceType,
|
|
1,
|
|
ResourceDescription::Preload,
|
|
&i,
|
|
sizeof(i)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
ResourceDescription
|
|
*res_des = file->FindResourceDescription(resource_id);
|
|
|
|
if (!res_des)
|
|
{
|
|
file->AddResource(
|
|
model_name,
|
|
ResourceDescription::ModelListResourceType,
|
|
1,
|
|
ResourceDescription::Preload,
|
|
&i,
|
|
sizeof(i),
|
|
resource_id
|
|
);
|
|
}
|
|
else
|
|
{
|
|
DEBUG_STREAM << model_name << " : " << resource_id << std::endl << std::flush;
|
|
Fail("Duplicate Resource Number");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Unregister_Pointer(model_data);
|
|
delete model_data;
|
|
return True;
|
|
}
|