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:
@@ -0,0 +1,697 @@
|
||||
#include "munga.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "hostmgr.h"
|
||||
#include "interest.h"
|
||||
#include "app.h"
|
||||
#include "entity.h"
|
||||
|
||||
//#############################################################################
|
||||
//######################### HostManager #################################
|
||||
//#############################################################################
|
||||
|
||||
//
|
||||
// HACK - EntitySocketHashSize should come from somewhere else
|
||||
//
|
||||
const CollectionSize EntitySocketHashSize = 500;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// HostManager data
|
||||
//
|
||||
HostManager::SharedData
|
||||
HostManager::DefaultData(
|
||||
HostManager::GetClassDerivations(),
|
||||
HostManager::GetMessageHandlers()
|
||||
);
|
||||
|
||||
Derivation* HostManager::GetClassDerivations()
|
||||
{
|
||||
static Derivation classDerivations(NetworkClient::GetClassDerivations(), "HostManager");
|
||||
return &classDerivations;
|
||||
}
|
||||
|
||||
const Receiver::HandlerEntry
|
||||
HostManager::MessageHandlerEntries[]=
|
||||
{
|
||||
{
|
||||
HostManager::NewHostMessageID,
|
||||
"NewHost",
|
||||
(HostManager::Handler)&Receiver::DefaultMessageHandler // HACK
|
||||
},
|
||||
{
|
||||
HostManager::HostUpdateMessageID,
|
||||
"HostUpdate",
|
||||
(HostManager::Handler)&Receiver::DefaultMessageHandler // HACK
|
||||
},
|
||||
{
|
||||
HostManager::EntityTransferOwnershipMessageID,
|
||||
"EntityTransferOwnership",
|
||||
(HostManager::Handler)&HostManager::EntityTransferOwnershipHandler
|
||||
},
|
||||
{
|
||||
HostManager::EntityNewOwnershipMessageID,
|
||||
"EntityNewOwnership",
|
||||
(HostManager::Handler)&HostManager::EntityNewOwnershipHandler
|
||||
}
|
||||
};
|
||||
|
||||
Receiver::MessageHandlerSet& HostManager::GetMessageHandlers()
|
||||
{
|
||||
static Receiver::MessageHandlerSet messageHandlers(ELEMENTS(HostManager::MessageHandlerEntries), HostManager::MessageHandlerEntries, Receiver::GetMessageHandlers());
|
||||
return messageHandlers;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// HostManager
|
||||
//#############################################################################
|
||||
//
|
||||
HostManager::HostManager():
|
||||
NetworkClient(HostManagerClassID, DefaultData, HostManagerClientID),
|
||||
remoteHostSocket(NULL, True),
|
||||
allHostSocket(NULL, True),
|
||||
entityIndexSocket(EntitySocketHashSize, NULL, True)
|
||||
{
|
||||
localHost = NULL;
|
||||
allHostIterator = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
HostManager::~HostManager()
|
||||
{
|
||||
if (allHostIterator != NULL)
|
||||
{
|
||||
Unregister_Object(allHostIterator);
|
||||
delete allHostIterator;
|
||||
allHostIterator = NULL;
|
||||
}
|
||||
|
||||
Verify(localHost == NULL);
|
||||
|
||||
#if DEBUG_LEVEL>0
|
||||
{
|
||||
TableIteratorOf<Host*, HostID> iterator(&remoteHostSocket);
|
||||
Check(&iterator);
|
||||
Verify(iterator.GetSize() == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_LEVEL>0
|
||||
{
|
||||
HashIteratorOf<Entity*, EntityID> iterator(&entityIndexSocket);
|
||||
Check(&iterator);
|
||||
Verify(iterator.GetSize() == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
HostManager::TestInstance() const
|
||||
{
|
||||
if (!IsDerivedFrom(*GetClassDerivations()))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
if (localHost != NULL)
|
||||
{
|
||||
Check(localHost)
|
||||
}
|
||||
if (allHostIterator != NULL)
|
||||
{
|
||||
Check(allHostIterator)
|
||||
}
|
||||
Check(&remoteHostSocket);
|
||||
Check(&allHostSocket);
|
||||
Check(&lastEntityID);
|
||||
Check(&entityIndexSocket);
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// Shutdown
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::Shutdown()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
#if 0 // HACK - Partial Implementation
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// For (each transferrable entity)
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// Find new host for ownership
|
||||
//
|
||||
|
||||
//
|
||||
// Send transfer entity ownership to that host
|
||||
//
|
||||
#else
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Delete all of the entities
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
if (localHost != NULL)
|
||||
{
|
||||
Check(localHost);
|
||||
Host::AllEntityIterator iterator(localHost);
|
||||
Check(&iterator);
|
||||
iterator.DeletePlugs();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// AdoptLocalHost
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::AdoptLocalHost(Host *local_host)
|
||||
{
|
||||
Check(this);
|
||||
Check(local_host);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Verify that the local host is currently unassigned and then assign it
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Verify(lastEntityID == EntityID::Null);
|
||||
Verify(localHost == NULL);
|
||||
localHost = local_host;
|
||||
|
||||
EntityID entity_ID(local_host->GetHostID());
|
||||
lastEntityID = entity_ID;
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Add the local host to the all host socket
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
allHostSocket.AddValue(local_host, local_host->GetHostID());
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// OrphanLocalHost
|
||||
//#############################################################################
|
||||
//
|
||||
Host*
|
||||
HostManager::OrphanLocalHost()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Unassign the local host
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Host *local_host = localHost;
|
||||
localHost = NULL;
|
||||
lastEntityID = EntityID::Null;
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Remove the local host from the all host socket
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
if (local_host != NULL)
|
||||
{
|
||||
Check(local_host);
|
||||
PlugIterator remover(local_host);
|
||||
remover.RemoveSocket(&allHostSocket);
|
||||
}
|
||||
return local_host;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// AdoptRemoteHost
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::AdoptRemoteHost(Host *remote_host)
|
||||
{
|
||||
Check(this);
|
||||
Check(remote_host);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Add to the remote and all host socket
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
remoteHostSocket.AddValue(remote_host, remote_host->GetHostID());
|
||||
allHostSocket.AddValue(remote_host, remote_host->GetHostID());
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// OrphanRemoteHost
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::OrphanRemoteHost(Host *remote_host)
|
||||
{
|
||||
Check(this);
|
||||
Check(remote_host);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Remove from the remote and all host socket
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
{
|
||||
PlugIterator remover(remote_host);
|
||||
remover.RemoveSocket(&remoteHostSocket);
|
||||
}
|
||||
{
|
||||
PlugIterator remover(remote_host);
|
||||
remover.RemoveSocket(&allHostSocket);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// GetLocalHostID
|
||||
//#############################################################################
|
||||
//
|
||||
HostID
|
||||
HostManager::GetLocalHostID()
|
||||
{
|
||||
Check(this);
|
||||
Check(localHost);
|
||||
return localHost->GetHostID();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// GetRemoteHost
|
||||
//#############################################################################
|
||||
//
|
||||
Host*
|
||||
HostManager::GetRemoteHost(HostID host_ID)
|
||||
{
|
||||
Check(this);
|
||||
Verify(host_ID >= FirstLegalHostID);
|
||||
|
||||
return remoteHostSocket.Find(host_ID);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// GetConsoleHost
|
||||
//#############################################################################
|
||||
//
|
||||
Host*
|
||||
HostManager::GetConsoleHost()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
Host *host;
|
||||
TableIteratorOf<Host*, HostID> iterator(&remoteHostSocket);
|
||||
|
||||
Check(&iterator);
|
||||
while ((host = iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(host);
|
||||
if (host->GetHostType() == ConsoleHostType)
|
||||
return host;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// FindHost
|
||||
//#############################################################################
|
||||
//
|
||||
Host* HostManager::FindHost(SOCKADDR_IN &net_address)
|
||||
{
|
||||
Host *host;
|
||||
TableIteratorOf<Host*, HostID> iterator(&allHostSocket);
|
||||
|
||||
while ((host = iterator.ReadAndNext()) != NULL)
|
||||
if (*host->GetNetworkAddress() == net_address)
|
||||
return host;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// MakeUniqueEntityID
|
||||
//#############################################################################
|
||||
//
|
||||
EntityID
|
||||
HostManager::MakeUniqueEntityID()
|
||||
{
|
||||
Check(this);
|
||||
Verify(lastEntityID != EntityID::Null);
|
||||
|
||||
return (lastEntityID += 1);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// NotifyOfEntityCreation
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::NotifyOfEntityCreation(
|
||||
Entity *entity,
|
||||
Entity::MakeMessage *creation_message
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(entity);
|
||||
Check(creation_message);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// The host keeps track of all entities
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Check(localHost);
|
||||
localHost->AddEntity(entity);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Link the entity to our index
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Verify(entity->GetEntityID() != EntityID::Null);
|
||||
Check(&entityIndexSocket);
|
||||
entityIndexSocket.AddValue(entity, entity->GetEntityID());
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Call interest manager
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Check(application);
|
||||
Check(application->GetInterestManager());
|
||||
application->GetInterestManager()->NotifyOfEntityCreation(
|
||||
entity,
|
||||
creation_message
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// NotifyOfReplacementEntityCreation
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::NotifyOfReplacementEntityCreation(
|
||||
Entity*,
|
||||
EntityID,
|
||||
ClassID,
|
||||
LWord
|
||||
)
|
||||
{
|
||||
Fail("HostManager::NotifyOfReplacementEntityCreation - under construction");
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// NotifyOfEntityDestruction
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::NotifyOfEntityDestruction(Entity *entity)
|
||||
{
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Perform any additional processing here...
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Notify interest manager of the destruction
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Check(application);
|
||||
Check(application->GetInterestManager());
|
||||
application->GetInterestManager()->NotifyOfEntityDestruction(entity);
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// IdentifyNewMapEntityHost
|
||||
//#############################################################################
|
||||
//
|
||||
HostID
|
||||
HostManager::IdentifyNewMapEntityHost(
|
||||
EntityID
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// HACK - Partial Implementation, since the entity IDs are not yet
|
||||
// precomputed several assumptions are made. 1) The map stream read by each
|
||||
// pilot is identical. 2) All of the hosts are connected at the point that
|
||||
// the stream is read. => Therefore, it is easy to allocate the entities to
|
||||
// each host.
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Verify that legal map entity hosts exist
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
#if DEBUG_LEVEL>0
|
||||
{
|
||||
TableIteratorOf<Host*, HostID> iterator(&allHostSocket);
|
||||
Host *host;
|
||||
CollectionSize legal_map_entity_hosts = 0;
|
||||
|
||||
while ((host = iterator.ReadAndNext()) != NULL)
|
||||
{
|
||||
if (host->GetHostType() == GameMachineHostType)
|
||||
{
|
||||
legal_map_entity_hosts++;
|
||||
}
|
||||
}
|
||||
Verify(legal_map_entity_hosts > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Check the host iterator
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
if (allHostIterator == NULL)
|
||||
{
|
||||
allHostIterator = new TableIteratorOf<Host*, HostID>(&allHostSocket);
|
||||
Register_Object(allHostIterator);
|
||||
}
|
||||
Check(allHostIterator);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Get a legal map entity host
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Host *map_entity_host;
|
||||
Logical is_legal_map_entity_host = False;
|
||||
|
||||
do
|
||||
{
|
||||
if ((map_entity_host = allHostIterator->GetCurrent()) == NULL)
|
||||
{
|
||||
allHostIterator->First();
|
||||
map_entity_host = allHostIterator->GetCurrent();
|
||||
}
|
||||
Check(map_entity_host);
|
||||
if (map_entity_host->GetHostType() == GameMachineHostType)
|
||||
{
|
||||
is_legal_map_entity_host = True;
|
||||
}
|
||||
else
|
||||
{
|
||||
allHostIterator->Next();
|
||||
}
|
||||
}
|
||||
while (!is_legal_map_entity_host);
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Move to the next host
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
allHostIterator->Next();
|
||||
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
// Return the map entity host ID
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
Check(map_entity_host);
|
||||
Verify(map_entity_host->GetHostType() == GameMachineHostType);
|
||||
Verify(map_entity_host->GetHostID() != NullHostID);
|
||||
|
||||
return map_entity_host->GetHostID();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// EntityTransferOwnership
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::EntityTransferOwnershipHandler(
|
||||
EntityTransferOwnershipMessage*
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
//
|
||||
// Find replicant for this entity
|
||||
//
|
||||
|
||||
//
|
||||
// If (replicant found)
|
||||
//
|
||||
//
|
||||
// Morph the replicant into the master replicant
|
||||
//
|
||||
|
||||
//
|
||||
// If (the replicant was not found)
|
||||
//
|
||||
//
|
||||
// Make a transferred master entity
|
||||
//
|
||||
|
||||
//
|
||||
// Broadcast new entity ownership
|
||||
//
|
||||
#else
|
||||
Fail("HostManager::EntityTransferOwnershipHandler - under construction");
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// EntityNewOwnership
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
HostManager::EntityNewOwnershipHandler(
|
||||
EntityNewOwnershipMessage*
|
||||
)
|
||||
{
|
||||
#if 0
|
||||
//
|
||||
// If (this host is the owner host)
|
||||
//
|
||||
//
|
||||
// Return
|
||||
//
|
||||
|
||||
//
|
||||
// Find the replicant for this entity
|
||||
//
|
||||
//
|
||||
// If (found the replicant)
|
||||
//
|
||||
//
|
||||
// Point it at the new owner
|
||||
//
|
||||
#else
|
||||
Fail("HostManager::EntityNewOwnershipHandler - under construction");
|
||||
#endif
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__AllEntityIterator ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
HostManager__AllEntityIterator::HostManager__AllEntityIterator(
|
||||
HostManager *host_manager
|
||||
):
|
||||
Host__AllEntityIterator(host_manager->localHost)
|
||||
{
|
||||
}
|
||||
|
||||
HostManager__AllEntityIterator::~HostManager__AllEntityIterator()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~ HostManager__DynamicMasterEntityIterator ~~~~~~~~~~~~~~~~~
|
||||
|
||||
HostManager__DynamicMasterEntityIterator::
|
||||
HostManager__DynamicMasterEntityIterator(
|
||||
HostManager *host_manager
|
||||
):
|
||||
Host__DynamicMasterEntityIterator(host_manager->localHost)
|
||||
{
|
||||
}
|
||||
|
||||
HostManager__DynamicMasterEntityIterator::
|
||||
~HostManager__DynamicMasterEntityIterator()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~ HostManager__DynamicReplicantEntityIterator ~~~~~~~~~~~~~~~
|
||||
|
||||
HostManager__DynamicReplicantEntityIterator::
|
||||
HostManager__DynamicReplicantEntityIterator(
|
||||
HostManager *host_manager
|
||||
):
|
||||
Host__DynamicReplicantEntityIterator(host_manager->localHost)
|
||||
{
|
||||
}
|
||||
|
||||
HostManager__DynamicReplicantEntityIterator::
|
||||
~HostManager__DynamicReplicantEntityIterator()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__RemoteHostIterator ~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
HostManager__RemoteHostIterator::HostManager__RemoteHostIterator(
|
||||
HostManager *host_manager
|
||||
):
|
||||
TableIteratorOf<Host*, HostID>(&host_manager->remoteHostSocket)
|
||||
{
|
||||
}
|
||||
|
||||
HostManager__RemoteHostIterator::~HostManager__RemoteHostIterator()
|
||||
{
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~ HostManager__AllHostIterator ~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
HostManager__AllHostIterator::HostManager__AllHostIterator(
|
||||
HostManager *host_manager
|
||||
):
|
||||
TableIteratorOf<Host*, HostID>(&host_manager->allHostSocket)
|
||||
{
|
||||
}
|
||||
|
||||
HostManager__AllHostIterator::~HostManager__AllHostIterator()
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined(TEST_CLASS)
|
||||
#include "host.tcp"
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user