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>
This commit is contained in:
+577
@@ -0,0 +1,577 @@
|
||||
#include "rp.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "scorzone.h"
|
||||
#include "..\munga\fileutil.h"
|
||||
#include "..\munga\nttmgr.h"
|
||||
#include "..\munga\app.h"
|
||||
#include "..\munga\hostmgr.h"
|
||||
#include "..\munga\notation.h"
|
||||
|
||||
//#############################################################################
|
||||
//############################### ScoreZone #############################
|
||||
//#############################################################################
|
||||
|
||||
//#############################################################################
|
||||
// Shared Data Support
|
||||
//
|
||||
|
||||
Derivation* ScoreZone::GetClassDerivations()
|
||||
{
|
||||
static Derivation classDerivations(Entity::GetClassDerivations(), "ScoreZone");
|
||||
return &classDerivations;
|
||||
}
|
||||
|
||||
ScoreZone::SharedData
|
||||
ScoreZone::DefaultData(
|
||||
ScoreZone::GetClassDerivations(),
|
||||
ScoreZone::MessageHandlers,
|
||||
ScoreZone::GetAttributeIndex(),
|
||||
ScoreZone::StateCount,
|
||||
(Entity::MakeHandler)ScoreZone::Make
|
||||
);
|
||||
//#############################################################################
|
||||
// Attribute Support
|
||||
//
|
||||
|
||||
const ScoreZone::IndexEntry
|
||||
ScoreZone::AttributePointers[]=
|
||||
{
|
||||
ATTRIBUTE_ENTRY(ScoreZone, ScoreZoneType, scoreZoneType),
|
||||
ATTRIBUTE_ENTRY(ScoreZone, PointValue, pointValue)
|
||||
};
|
||||
|
||||
ScoreZone::AttributeIndexSet& ScoreZone::GetAttributeIndex()
|
||||
{
|
||||
static ScoreZone::AttributeIndexSet attributeIndex(ELEMENTS(ScoreZone::AttributePointers),
|
||||
ScoreZone::AttributePointers,
|
||||
Entity::GetAttributeIndex()
|
||||
);
|
||||
return attributeIndex;
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
// Message Support
|
||||
//
|
||||
const Receiver::HandlerEntry
|
||||
ScoreZone::MessageHandlerEntries[]=
|
||||
{
|
||||
MESSAGE_ENTRY(ScoreZone, ProcessScoreZoneRequest)
|
||||
};
|
||||
|
||||
Receiver::MessageHandlerSet
|
||||
ScoreZone::MessageHandlers(
|
||||
ELEMENTS(ScoreZone::MessageHandlerEntries),
|
||||
ScoreZone::MessageHandlerEntries,
|
||||
Entity::GetMessageHandlers()
|
||||
);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
|
||||
void
|
||||
ScoreZone::ProcessScoreZoneRequestMessageHandler(
|
||||
ProcessScoreZoneRequestMessage *message
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check_Pointer(message);
|
||||
|
||||
//
|
||||
//----------------------------------------
|
||||
// Make sure that the score zone is active
|
||||
//----------------------------------------
|
||||
//
|
||||
EntityGroup *score_zone_group;
|
||||
if (GetSimulationState() == Active)
|
||||
{
|
||||
//
|
||||
//-----------------------------------------------------------
|
||||
// If Sequential, hunt for ourselves in the sequential group
|
||||
//-----------------------------------------------------------
|
||||
//
|
||||
Check(application);
|
||||
EntityManager *entity_mgr = application->GetEntityManager();
|
||||
Check(entity_mgr);
|
||||
if (
|
||||
scoreZoneType == LocalSequential
|
||||
|| scoreZoneType == GlobalSequential
|
||||
)
|
||||
{
|
||||
int new_zone = sequenceNumber + 1;
|
||||
score_zone_group = entity_mgr->FindGroup("SequentialScoreZones");
|
||||
Check(score_zone_group);
|
||||
ChainIteratorOf<Node*> iterator(score_zone_group->groupMembers);
|
||||
ScoreZone
|
||||
*score_zone,
|
||||
*first_score_zone = NULL;
|
||||
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
// Store the first score zone in case we run off the end of the list
|
||||
//------------------------------------------------------------------
|
||||
//
|
||||
while ((score_zone = (ScoreZone*)iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(score_zone);
|
||||
if (score_zone->sequenceNumber == 1)
|
||||
{
|
||||
first_score_zone = score_zone;
|
||||
}
|
||||
if (score_zone->sequenceNumber == new_zone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!score_zone)
|
||||
{
|
||||
score_zone = first_score_zone;
|
||||
}
|
||||
|
||||
if (score_zone->GetSimulationState() == InActive)
|
||||
{
|
||||
score_zone->SetSimulationState(Active);
|
||||
score_zone_group = entity_mgr->FindGroup("ActiveScoreZones");
|
||||
Check(score_zone_group);
|
||||
score_zone_group->Add(score_zone);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------
|
||||
// Set the zone as inactive, remove ourselves from the active list
|
||||
//----------------------------------------------------------------
|
||||
//
|
||||
SetSimulationState(InActive);
|
||||
score_zone_group = entity_mgr->FindGroup("ActiveScoreZones");
|
||||
Check(score_zone_group);
|
||||
ChainIteratorOf<Node*> iterator(score_zone_group->groupMembers);
|
||||
ScoreZone *score_zone;
|
||||
while ((score_zone = (ScoreZone*)iterator.GetCurrent()) != NULL)
|
||||
{
|
||||
if (score_zone == this)
|
||||
{
|
||||
iterator.Remove();
|
||||
break;
|
||||
}
|
||||
iterator.Next();
|
||||
}
|
||||
|
||||
//
|
||||
//-----------------------------------
|
||||
// Send the points back to the player
|
||||
//-----------------------------------
|
||||
//
|
||||
ReplyMessage
|
||||
reply(
|
||||
message->replyMessageID,
|
||||
sizeof(ReplyMessage),
|
||||
pointValue
|
||||
);
|
||||
Check(application);
|
||||
HostManager *host = application->GetHostManager();
|
||||
Check(host);
|
||||
Entity *entity = host->GetEntityPointer(message->requestingEntity);
|
||||
Check(entity);
|
||||
entity->Dispatch(&reply);
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
void
|
||||
ScoreZone::Dispatch(Receiver::Message *message)
|
||||
{
|
||||
Check(this);
|
||||
Check(message);
|
||||
|
||||
ProcessScoreZoneRequestMessage *score_zone_message =
|
||||
(ProcessScoreZoneRequestMessage*) message;
|
||||
if (score_zone_message->messageID == ProcessScoreZoneRequestMessageID)
|
||||
{
|
||||
if (!extentBox.Contains(score_zone_message->linearPosition))
|
||||
{
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
}
|
||||
Entity::Dispatch(score_zone_message);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
// Construction and Destruction
|
||||
//
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
ScoreZone::ScoreZone(
|
||||
ScoreZone::MakeMessage *creation_message,
|
||||
ScoreZone::SharedData &virtual_data
|
||||
):
|
||||
Entity(creation_message, virtual_data)
|
||||
{
|
||||
Check_Pointer(this);
|
||||
Check_Pointer(creation_message);
|
||||
|
||||
SetValidFlag();
|
||||
|
||||
//-------------------------------------------------
|
||||
// Find the drop zone resource in the resource file
|
||||
//-------------------------------------------------
|
||||
ResourceFile
|
||||
*res_file = application->GetResourceFile();
|
||||
Check(res_file);
|
||||
ResourceDescription *res =
|
||||
res_file->SearchList(
|
||||
resourceID,
|
||||
ResourceDescription::GameModelResourceType
|
||||
);
|
||||
Check(res);
|
||||
res->Lock();
|
||||
|
||||
//
|
||||
// Get ScoreZone Info
|
||||
//
|
||||
sequenceNumber = creation_message->sequenceNumber;
|
||||
|
||||
ModelResource
|
||||
*score_res = (ModelResource*)res->resourceAddress;
|
||||
|
||||
scoreZoneType = score_res->scoreZoneType;
|
||||
pointValue = score_res->pointValue;
|
||||
extentBox = score_res->extentBox;
|
||||
|
||||
extentBox.minX += localOrigin.linearPosition.x;
|
||||
extentBox.minY += localOrigin.linearPosition.y;
|
||||
extentBox.minZ += localOrigin.linearPosition.z;
|
||||
|
||||
extentBox.maxX += localOrigin.linearPosition.x;
|
||||
extentBox.maxY += localOrigin.linearPosition.y;
|
||||
extentBox.maxZ += localOrigin.linearPosition.z;
|
||||
|
||||
SetSimulationState(InActive);
|
||||
|
||||
res->Unlock();
|
||||
//---------------------------------------------------------------------
|
||||
// Make the sequential score zone list. Only make the first sequential
|
||||
// score zone active
|
||||
//---------------------------------------------------------------------
|
||||
EntityManager *entity_manager = application->GetEntityManager();
|
||||
Check(entity_manager);
|
||||
EntityGroup *score_zones;
|
||||
|
||||
if (scoreZoneType == LocalSequential || scoreZoneType == GlobalSequential)
|
||||
{
|
||||
score_zones = entity_manager->UseGroup("SequentialScoreZones");
|
||||
Check(score_zones);
|
||||
score_zones->Add(this);
|
||||
if (sequenceNumber == 1)
|
||||
{
|
||||
goto Active_Zone;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//------------------------------------------------
|
||||
// If it isn't a sequential, always make it active
|
||||
//------------------------------------------------
|
||||
//
|
||||
else
|
||||
{
|
||||
Active_Zone:
|
||||
score_zones = entity_manager->UseGroup("ActiveScoreZones");
|
||||
Check(score_zones);
|
||||
SetSimulationState(Active);
|
||||
score_zones->Add(this);
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
ScoreZone*
|
||||
ScoreZone::Make(ScoreZone::MakeMessage *creation_message)
|
||||
{
|
||||
return new ScoreZone(creation_message);
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
ScoreZone::CreateMakeMessage(
|
||||
MakeMessage *creation_message,
|
||||
NotationFile *model_file,
|
||||
const ResourceDirectories *directories
|
||||
)
|
||||
{
|
||||
Check(creation_message);
|
||||
Check(model_file);
|
||||
|
||||
if (!Entity::CreateMakeMessage(creation_message, model_file, directories))
|
||||
{
|
||||
Check_Fpu();
|
||||
return False;
|
||||
}
|
||||
|
||||
creation_message->classToCreate = RegisteredClass::ScoreZoneClassID;
|
||||
creation_message->messageLength = sizeof(*creation_message);
|
||||
creation_message->instanceFlags =
|
||||
IndependantInstance|DynamicFlag|MapFlag|TrappedFlag;
|
||||
|
||||
char *p;
|
||||
creation_message->sequenceNumber = -1;
|
||||
if ((p = strtok(NULL, " ")) != NULL)
|
||||
{
|
||||
creation_message->sequenceNumber = atoi(p);
|
||||
}
|
||||
|
||||
Check_Fpu();
|
||||
return True;
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
ScoreZone::~ScoreZone()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
if (scoreZoneType == LocalSequential || scoreZoneType == GlobalSequential)
|
||||
{
|
||||
Check(application);
|
||||
EntityManager *entity_mgr = application->GetEntityManager();
|
||||
Check(entity_mgr);
|
||||
EntityGroup *score_zone_group =
|
||||
entity_mgr->FindGroup("SequentialScoreZones");
|
||||
if (score_zone_group)
|
||||
{
|
||||
ChainIteratorOf<Node*> iterator(score_zone_group->groupMembers);
|
||||
ScoreZone *score_zone = (ScoreZone*)iterator.GetCurrent();
|
||||
if (score_zone == this)
|
||||
{
|
||||
iterator.Remove();
|
||||
if (!iterator.GetCurrent())
|
||||
{
|
||||
entity_mgr->RemoveGroup(score_zone_group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
ResourceDescription::ResourceID
|
||||
ScoreZone::CreateModelResource(
|
||||
ResourceFile *resource_file,
|
||||
const char* model_name,
|
||||
NotationFile * model_file,
|
||||
const ResourceDirectories *directories,
|
||||
ModelResource *model
|
||||
)
|
||||
{
|
||||
Check(resource_file);
|
||||
Check_Pointer(model_name);
|
||||
Check_Pointer(directories);
|
||||
|
||||
//
|
||||
// If we were not provided a buffer to write the model data into, we must
|
||||
// create it ourselves. Then make sure that the model stuff is read in
|
||||
//
|
||||
ModelResource *local_model = model;
|
||||
if (!local_model)
|
||||
{
|
||||
local_model = new ModelResource;
|
||||
Register_Pointer(local_model);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Get PointValue assigned to this ScoreZone
|
||||
//
|
||||
if(
|
||||
!model_file->GetEntry(
|
||||
"gamedata",
|
||||
"PointValue",
|
||||
&local_model->pointValue
|
||||
)
|
||||
)
|
||||
{
|
||||
std::cerr << model_name << "Missing PointValue" << std::endl;
|
||||
Dump_And_Die:
|
||||
if (!model)
|
||||
{
|
||||
Unregister_Pointer(local_model);
|
||||
delete local_model;
|
||||
}
|
||||
Check_Fpu();
|
||||
return -1;
|
||||
}
|
||||
//
|
||||
// Get The ScoreZone Type
|
||||
//
|
||||
const char* score_zone_type;
|
||||
if(
|
||||
!model_file->GetEntry(
|
||||
"gamedata",
|
||||
"ScoreZoneType",
|
||||
&score_zone_type
|
||||
)
|
||||
)
|
||||
{
|
||||
std::cerr << model_name << "Missing ScoreZoneType" << std::endl;
|
||||
goto Dump_And_Die;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(strcmp(score_zone_type,"GlobalOneTime") == 0)
|
||||
{
|
||||
local_model->scoreZoneType = GlobalOneTime;
|
||||
}
|
||||
else
|
||||
if(strcmp(score_zone_type,"LocalOneTime") == 0)
|
||||
{
|
||||
local_model->scoreZoneType = LocalOneTime;
|
||||
}
|
||||
else
|
||||
if(strcmp(score_zone_type,"GlobalSequential") == 0)
|
||||
{
|
||||
local_model->scoreZoneType = GlobalSequential;
|
||||
}
|
||||
else
|
||||
if(strcmp(score_zone_type,"LocalSequential") == 0)
|
||||
{
|
||||
local_model->scoreZoneType = LocalSequential;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Read In the Extent Box from the solid file determined by the
|
||||
// collision data
|
||||
//
|
||||
const char* sld_entry;
|
||||
if(
|
||||
!model_file->GetEntry(
|
||||
"gamedata",
|
||||
"Extents",
|
||||
&sld_entry
|
||||
)
|
||||
)
|
||||
{
|
||||
std::cerr << model_name << "Missing .sld Specifications " << std::endl;
|
||||
goto Dump_And_Die;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *sld_filename =
|
||||
MakePathedFilename(directories->collisionDirectory, sld_entry);
|
||||
Register_Pointer(sld_filename);
|
||||
|
||||
NotationFile *sld_file = new NotationFile(sld_filename);
|
||||
Register_Object(sld_file);
|
||||
if(sld_file->PageCount() == 0)
|
||||
{
|
||||
std::cerr <<sld_filename<<" is has no Pages"<<std::endl;
|
||||
Unregister_Pointer(sld_filename);
|
||||
delete sld_filename;
|
||||
Unregister_Object(sld_file);
|
||||
delete sld_file;
|
||||
goto Dump_And_Die;
|
||||
}
|
||||
|
||||
NameList *sld_namelist = sld_file->MakeEntryList("volume 0","extm");
|
||||
Register_Object(sld_namelist);
|
||||
if (sld_namelist->EntryCount() == 0)
|
||||
{
|
||||
Dump_And_Die_2:
|
||||
Unregister_Pointer(sld_filename);
|
||||
delete sld_filename;
|
||||
Unregister_Object(sld_file);
|
||||
delete sld_file;
|
||||
Unregister_Object(sld_namelist);
|
||||
delete sld_namelist;
|
||||
goto Dump_And_Die;
|
||||
}
|
||||
NameList::Entry *extent_entry = sld_namelist->GetFirstEntry();
|
||||
while(extent_entry)
|
||||
{
|
||||
Scalar value = extent_entry->GetAtof();
|
||||
if (strcmp(extent_entry->GetName(),"extminX") == 0)
|
||||
{
|
||||
local_model->extentBox.minX = value;
|
||||
}
|
||||
else
|
||||
if (strcmp(extent_entry->GetName(),"extminY") == 0)
|
||||
{
|
||||
local_model->extentBox.minY = value;
|
||||
}
|
||||
else
|
||||
if (strcmp(extent_entry->GetName(),"extminZ") == 0)
|
||||
{
|
||||
local_model->extentBox.minZ = value;
|
||||
}
|
||||
else
|
||||
if (strcmp(extent_entry->GetName(),"extmaxX") == 0)
|
||||
{
|
||||
local_model->extentBox.maxX = value;
|
||||
}
|
||||
else
|
||||
if (strcmp(extent_entry->GetName(),"extmaxY") == 0)
|
||||
{
|
||||
local_model->extentBox.maxY = value;
|
||||
}
|
||||
else
|
||||
if (strcmp(extent_entry->GetName(),"extmaxZ") == 0)
|
||||
{
|
||||
local_model->extentBox.maxZ = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << sld_filename << "Improper Extent Format" << std::endl;
|
||||
goto Dump_And_Die_2;
|
||||
}
|
||||
extent_entry = extent_entry->GetNextEntry();
|
||||
}
|
||||
Unregister_Pointer(sld_filename);
|
||||
delete sld_filename;
|
||||
Unregister_Object(sld_file);
|
||||
delete sld_file;
|
||||
Unregister_Object(sld_namelist);
|
||||
delete sld_namelist;
|
||||
}
|
||||
//
|
||||
//---------------------------
|
||||
// Write out the new resource
|
||||
//---------------------------
|
||||
//
|
||||
if (!model)
|
||||
{
|
||||
ResourceDescription *new_res =
|
||||
resource_file->AddResource(
|
||||
model_name,
|
||||
ResourceDescription::GameModelResourceType,
|
||||
1,
|
||||
ResourceDescription::Preload,
|
||||
local_model,
|
||||
sizeof(*local_model)
|
||||
);
|
||||
Unregister_Pointer(local_model);
|
||||
delete local_model;
|
||||
Check(new_res);
|
||||
Check_Fpu();
|
||||
return new_res->resourceID;
|
||||
}
|
||||
else
|
||||
{
|
||||
Check_Fpu();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
Logical
|
||||
ScoreZone::TestInstance() const
|
||||
{
|
||||
return IsDerivedFrom(*GetClassDerivations());
|
||||
}
|
||||
Reference in New Issue
Block a user