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>
624 lines
15 KiB
C++
624 lines
15 KiB
C++
#include "munga.h"
|
|
#pragma hdrstop
|
|
|
|
#include "mission.h"
|
|
#include "namelist.h"
|
|
#include "notation.h"
|
|
#include "graph2d.h"
|
|
|
|
//#############################################################################
|
|
//####################### MissionHostData ###############################
|
|
//#############################################################################
|
|
|
|
MissionHostData::MissionHostData(
|
|
const CString &address_string,
|
|
HostType host_type
|
|
):
|
|
addressString(address_string),
|
|
hostType(host_type)
|
|
{
|
|
}
|
|
|
|
MissionHostData::~MissionHostData()
|
|
{
|
|
}
|
|
|
|
//#############################################################################
|
|
//########################### Mission ###################################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Mission::LoadOrdinalBitmaps(NotationFile *notation_file)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Load ordinal bitmaps from egg
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Check(notation_file);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Make an entrylist of all the bitmap names
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
NameList *ord_namelist = notation_file->MakeEntryList("ordinals", "bitmap");
|
|
if (!ord_namelist)
|
|
{
|
|
Warn("No Ordinal Bitmaps in Egg \n");
|
|
return;
|
|
}
|
|
Register_Object(ord_namelist);
|
|
NameList::Entry *ord_entry = ord_namelist->GetFirstEntry();
|
|
BitMap *new_bitmap;
|
|
int index(0);
|
|
while(ord_entry)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get the bitmap pageName
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
++index;
|
|
CString ord_bitmap_name = ord_entry->GetChar();
|
|
new_bitmap = new BitMap(notation_file, ord_bitmap_name);
|
|
|
|
Register_Object(new_bitmap);
|
|
ordinalBitmapChain.AddValue(new_bitmap, index);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~
|
|
// Increment the index
|
|
//~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
ord_entry = ord_entry->GetNextEntry();
|
|
}
|
|
|
|
Unregister_Object(ord_namelist);
|
|
delete ord_namelist;
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Mission::LoadTeamBitmaps(NotationFile *notation_file)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Load team bitmaps from egg
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Check(notation_file);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Make an entrylist of all the team names
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
NameList *team_namelist = notation_file->MakeEntryList("teams", "team");
|
|
if (!team_namelist)
|
|
{
|
|
return;
|
|
}
|
|
Register_Object(team_namelist);
|
|
NameList::Entry *team_entry = team_namelist->GetFirstEntry();
|
|
BitMap *new_bitmap;
|
|
int index(0);
|
|
while(team_entry)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get the team pageName
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CString team_name = team_entry->GetChar();
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get the Team Bitmap Page Name
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
const char *team_bitmap_name;
|
|
notation_file->GetEntry(
|
|
team_name,
|
|
"bitmap",
|
|
&team_bitmap_name
|
|
);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~
|
|
// Create the bitMap
|
|
//~~~~~~~~~~~~~~~~~~
|
|
//
|
|
new_bitmap = new BitMap(notation_file, team_bitmap_name);
|
|
Register_Object(new_bitmap);
|
|
teamBitmapChain.AddValue(new_bitmap, index);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~
|
|
// Increment the index
|
|
//~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
++index;
|
|
team_entry = team_entry->GetNextEntry();
|
|
}
|
|
Unregister_Object(team_namelist);
|
|
delete team_namelist;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Mission::LoadNameBitmaps(NotationFile *notation_file)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Load name bitmaps from egg
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Check(notation_file);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Make an entrylist of all the large bitmap names
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
NameList *large_namelist = notation_file->MakeEntryList("largebitmap", "bitmap");
|
|
if (!large_namelist)
|
|
{
|
|
Warn("No Large NameBitmaps in Egg \n");
|
|
return;
|
|
}
|
|
Register_Object(large_namelist);
|
|
NameList::Entry *large_entry = large_namelist->GetFirstEntry();
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Make an entrylist of all the small bitmap names
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
NameList *small_namelist = notation_file->MakeEntryList("smallbitmap", "bitmap");
|
|
if (!small_namelist)
|
|
{
|
|
Warn("No Small NameBitmaps in Egg \n");
|
|
return;
|
|
}
|
|
Register_Object(small_namelist);
|
|
NameList::Entry *small_entry = small_namelist->GetFirstEntry();
|
|
|
|
BitMap *new_bitmap;
|
|
CString large_bitmap_name, small_bitmap_name;
|
|
int index(0);
|
|
while(large_entry && small_entry)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create the large Name bitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
++index;
|
|
large_bitmap_name = large_entry->GetChar();
|
|
new_bitmap = new BitMap(notation_file, large_bitmap_name);
|
|
Register_Object(new_bitmap);
|
|
largeNameBitmapChain.AddValue(new_bitmap, index);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Create the small Name bitmap
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
small_bitmap_name = small_entry->GetChar();
|
|
new_bitmap = new BitMap(notation_file, small_bitmap_name);
|
|
Register_Object(new_bitmap);
|
|
smallNameBitmapChain.AddValue(new_bitmap, index);
|
|
|
|
small_entry = small_entry->GetNextEntry();
|
|
large_entry = large_entry->GetNextEntry();
|
|
}
|
|
|
|
Unregister_Object(large_namelist);
|
|
delete large_namelist;
|
|
|
|
Unregister_Object(small_namelist);
|
|
delete small_namelist;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
Mission::LoadLandmarkBitmaps(NotationFile *notation_file)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Load Landmark bitmaps from egg
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Check(notation_file);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Make an entrylist of all the landmark names
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
NameList *landmark_namelist = notation_file->MakeEntryList("landmarks", "landmark");
|
|
if (!landmark_namelist)
|
|
{
|
|
return;
|
|
}
|
|
Register_Object(landmark_namelist);
|
|
NameList::Entry *landmark_entry = landmark_namelist->GetFirstEntry();
|
|
BitMap *new_bitmap;
|
|
int index(0);
|
|
while(landmark_entry)
|
|
{
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get the landmark pageName
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
CString landmark_name = landmark_entry->GetChar();
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Get the landmark Bitmap Page Name
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
const char *landmark_bitmap_name;
|
|
notation_file->GetEntry(
|
|
landmark_name,
|
|
"bitmap",
|
|
&landmark_bitmap_name
|
|
);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~
|
|
// Create the bitMap
|
|
//~~~~~~~~~~~~~~~~~~
|
|
//
|
|
new_bitmap = new BitMap(notation_file, landmark_bitmap_name);
|
|
Register_Object(new_bitmap);
|
|
landmarkBitmapChain.AddValue(new_bitmap, index);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~
|
|
// Increment the index
|
|
//~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
++index;
|
|
landmark_entry = landmark_entry->GetNextEntry();
|
|
}
|
|
Unregister_Object(landmark_namelist);
|
|
delete landmark_namelist;
|
|
}
|
|
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Mission::Mission(
|
|
NotationFile *notation_file,
|
|
ResourceFile *resources
|
|
):
|
|
missionHostSocket(NULL),
|
|
largeNameBitmapChain(NULL, True),
|
|
smallNameBitmapChain(NULL, True),
|
|
ordinalBitmapChain(NULL, True),
|
|
teamBitmapChain(NULL, True),
|
|
landmarkBitmapChain(NULL, True),
|
|
scenarioRoleChain(NULL, True)
|
|
{
|
|
Check(notation_file);
|
|
Check(resources);
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// NULL out All allocated variables
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
colorName = NULL;
|
|
badgeName = NULL;
|
|
dropZoneName = NULL;
|
|
gameModel = NULL;
|
|
missionTime = NULL;
|
|
missionWeather = NULL;
|
|
scenarioName = NULL;
|
|
positionName = NULL;
|
|
//
|
|
//-----------------
|
|
// Get the map name
|
|
//-----------------
|
|
//
|
|
Logical ret;
|
|
const char *map_name;
|
|
|
|
ret = notation_file->GetEntry("mission", "map", &map_name);
|
|
if (!ret)
|
|
{
|
|
DEBUG_STREAM << "ERROR: no map in egg!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
|
|
//
|
|
//-----------------------
|
|
// Get the mission length
|
|
//-----------------------
|
|
//
|
|
gameLength = 0.0;
|
|
notation_file->GetEntry("mission", "length", &gameLength);
|
|
|
|
//
|
|
//------------------------
|
|
// Get the map resource id
|
|
//------------------------
|
|
//
|
|
ResourceDescription *map =
|
|
resources->FindResourceDescription(
|
|
map_name,
|
|
ResourceDescription::MakeMessageStreamResourceType
|
|
);
|
|
if (!map)
|
|
{
|
|
DEBUG_STREAM << "ERROR: Couldn't find map in resource file!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
Check(map);
|
|
mapID = map->resourceID;
|
|
|
|
//
|
|
//----------------------------------
|
|
// Get the existance map resource id
|
|
//----------------------------------
|
|
//
|
|
map =
|
|
resources->FindResourceDescription(
|
|
map_name,
|
|
ResourceDescription::ExistanceBoxStreamResourceType
|
|
);
|
|
if (!map)
|
|
{
|
|
DEBUG_STREAM << "ERROR: Couldn't find existance map in resource file!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
Check(map);
|
|
existanceMapID = map->resourceID;
|
|
|
|
//
|
|
//---------------------------------------------
|
|
// Get the mission time, weather, and scenario
|
|
//--------------------------------------------
|
|
//
|
|
const char *mission_time;
|
|
const char *mission_weather;
|
|
const char *mission_scenario;
|
|
|
|
ret = notation_file->GetEntry("mission", "time", &mission_time);
|
|
if (!ret)
|
|
{
|
|
DEBUG_STREAM << "ERROR: no time in egg!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
|
|
ret = notation_file->GetEntry("mission", "weather", &mission_weather);
|
|
if (!ret)
|
|
{
|
|
DEBUG_STREAM << "ERROR: no weather in egg!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
|
|
ret = notation_file->GetEntry("mission", "scenario", &mission_scenario);
|
|
if (!ret)
|
|
{
|
|
DEBUG_STREAM << "ERROR: no scenario in egg!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
|
|
int length;
|
|
|
|
length = strlen(mission_time) + 1;
|
|
missionTime = new char[length];
|
|
Register_Pointer(missionTime); // safer to register BEFORE using
|
|
Str_Copy(missionTime, mission_time, length);
|
|
|
|
length = strlen(mission_weather) + 1;
|
|
missionWeather = new char[length];
|
|
Register_Pointer(missionWeather); // safer to register BEFORE using
|
|
Str_Copy(missionWeather, mission_weather, length);
|
|
|
|
length = strlen(mission_scenario) + 1;
|
|
scenarioName = new char[length];
|
|
Register_Pointer(scenarioName); // safer to register BEFORE using
|
|
Str_Copy(scenarioName, mission_scenario, length);
|
|
|
|
//
|
|
//--------------------------
|
|
// Get the mission host data
|
|
//--------------------------
|
|
//
|
|
NameList *entry_list;
|
|
NameList::Entry *entry;
|
|
|
|
playerCount = 0;
|
|
entry_list = notation_file->MakeEntryList("pilots", "pilot");
|
|
Register_Object(entry_list);
|
|
entry = entry_list->GetFirstEntry();
|
|
while (entry != NULL)
|
|
{
|
|
Check(entry);
|
|
|
|
//
|
|
// Get the host address character string
|
|
//
|
|
char *host_address_pointer = entry->GetChar();
|
|
Check_Pointer(host_address_pointer);
|
|
|
|
//
|
|
// Create the host address string
|
|
//
|
|
CString host_address_string(host_address_pointer);
|
|
Check(&host_address_string);
|
|
|
|
//
|
|
// Get the host type
|
|
//
|
|
int host_type;
|
|
|
|
ret = notation_file->GetEntry(
|
|
host_address_pointer,
|
|
"hostType",
|
|
&host_type
|
|
);
|
|
if (!ret)
|
|
{
|
|
DEBUG_STREAM << "ERROR: no host type in egg!\n" << std::flush;
|
|
PostQuitMessage(AbortExitCodeID);
|
|
}
|
|
|
|
//
|
|
// Create the mission host data
|
|
//
|
|
MissionHostData *mission_host_data;
|
|
|
|
mission_host_data =
|
|
new MissionHostData(
|
|
host_address_string,
|
|
(HostType)host_type
|
|
);
|
|
Register_Object(mission_host_data);
|
|
|
|
//
|
|
// Add to the host socket
|
|
//
|
|
missionHostSocket.Add(mission_host_data);
|
|
++playerCount;
|
|
|
|
entry = entry->GetNextEntry();
|
|
}
|
|
#if DEBUG_LEVEL>0
|
|
SChainIteratorOf<MissionHostData*> iterator(&missionHostSocket);
|
|
Check(&iterator);
|
|
Verify(iterator.GetSize() > 0);
|
|
#endif
|
|
Unregister_Object(entry_list);
|
|
delete entry_list;
|
|
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Load all the Bitmaps from the Notation File
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
LoadOrdinalBitmaps(notation_file);
|
|
LoadNameBitmaps(notation_file);
|
|
//LoadTeamBitmaps(notation_file);
|
|
//LoadLandmarkBitmaps(notation_file);
|
|
|
|
positionName = NULL;
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Mission::~Mission()
|
|
{
|
|
Check(this);
|
|
|
|
//
|
|
// Delete mission host data
|
|
//
|
|
SChainIteratorOf<MissionHostData*> iterator(&missionHostSocket);
|
|
Check(&iterator);
|
|
iterator.DeletePlugs();
|
|
|
|
//
|
|
// Delete the text fields
|
|
//
|
|
if (gameModel)
|
|
{
|
|
Unregister_Pointer(gameModel);
|
|
delete[] gameModel;
|
|
}
|
|
if (dropZoneName)
|
|
{
|
|
Unregister_Pointer(dropZoneName);
|
|
delete[] dropZoneName;
|
|
}
|
|
if (colorName)
|
|
{
|
|
Unregister_Pointer(colorName);
|
|
delete[] colorName;
|
|
}
|
|
if (badgeName)
|
|
{
|
|
Unregister_Pointer(badgeName);
|
|
delete[] badgeName;
|
|
}
|
|
if (positionName)
|
|
{
|
|
Unregister_Pointer(positionName);
|
|
delete[] positionName;
|
|
}
|
|
if (missionTime)
|
|
{
|
|
Unregister_Pointer(missionTime);
|
|
delete[] missionTime;
|
|
}
|
|
if (missionWeather)
|
|
{
|
|
Unregister_Pointer(missionWeather);
|
|
delete[] missionWeather;
|
|
}
|
|
if (scenarioName)
|
|
{
|
|
Unregister_Pointer(scenarioName);
|
|
delete[] scenarioName;
|
|
}
|
|
//
|
|
//~~~~~~~~~~~~~~~~~~~~~~~
|
|
// delete all the bitmaps
|
|
//~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
VChainIteratorOf<BitMap*,int> small_iterator(smallNameBitmapChain);
|
|
small_iterator.DeletePlugs();
|
|
|
|
VChainIteratorOf<BitMap*,int> large_iterator(largeNameBitmapChain);
|
|
large_iterator.DeletePlugs();
|
|
|
|
VChainIteratorOf<BitMap*,int> ordinal_iterator(ordinalBitmapChain);
|
|
ordinal_iterator.DeletePlugs();
|
|
|
|
VChainIteratorOf<BitMap*,int> team_iterator(teamBitmapChain);
|
|
team_iterator.DeletePlugs();
|
|
|
|
VChainIteratorOf<BitMap*,int> landmark_iterator(landmarkBitmapChain);
|
|
landmark_iterator.DeletePlugs();
|
|
|
|
|
|
VChainIteratorOf<ScenarioRole*, CString> role_iterator(scenarioRoleChain);
|
|
role_iterator.DeletePlugs();
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
void
|
|
Mission::SetPlayerData(
|
|
NotationFile * //notation_file
|
|
)
|
|
{
|
|
}
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
Logical
|
|
Mission::TestInstance() const
|
|
{
|
|
Check(&missionHostSocket);
|
|
return True;
|
|
}
|
|
|
|
//#############################################################################
|
|
//###################### Mission_HostIterator ###########################
|
|
//#############################################################################
|
|
|
|
Mission_HostIterator::Mission_HostIterator(Mission *mission):
|
|
SChainIteratorOf<MissionHostData*>(&mission->missionHostSocket)
|
|
{
|
|
}
|
|
|
|
Mission_HostIterator::~Mission_HostIterator()
|
|
{
|
|
}
|