Files
RP411/MUNGA/ICOM.cpp
T
CydandClaude Opus 4.8 4abbf8879f 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>
2026-06-30 07:59:51 -05:00

476 lines
9.6 KiB
C++

#include "munga.h"
#pragma hdrstop
#include "icom.h"
#include "app.h"
// #define LOCAL_TEST
#if defined(LOCAL_TEST)
# define Test_Tell(n) Tell(n << flush);
#else
# define Test_Tell(n)
#endif
//##########################################################################
//############################# Icom #################################
//##########################################################################
Icom::Icom(
HostID host_id,
int unit_number
):
Plug(IcomClassID)
{
Test_Tell("Icom::Icom(" << host_id << ", " << unit_number << ")\n");
Check_Pointer(this);
//--------------------------------------
// Initialize values
//--------------------------------------
hostID = host_id;
unitNumber = unit_number;
channel = undefinedChannel;
channelBeforePA = undefinedChannel;
PTTStatus = False;
PACaptive = False;
Check_Fpu();
}
Icom::~Icom()
{
Test_Tell("Icom::~Icom()\n");
Check(this);
//--------------------------------------
// Cleanup before deletion
//--------------------------------------
SetPTTStatusValue(False);
SetChannelValue(undefinedChannel);
//--------------------------------------
// The plug automatically unlinks
// from the Icom Manager upon deletion.
//--------------------------------------
Check_Fpu();
}
Logical
Icom::TestInstance() const
{
Plug::TestInstance();
Check_Fpu();
return True;
}
//--------------------------------------------------------------------------
void
Icom::SetChannel(int new_channel)
{
Test_Tell("Icom::SetChannel(" << new_channel << ")\n");
Check(this);
//--------------------------------------
// Broadcast the change
// (nonexclusive broadcast: we receive
// and process this msg locally)
//--------------------------------------
IcomManager::IMMessage
message;
message.BuildChannelMessage(
IcomManager::ChannelMessageID,
hostID,
unitNumber,
new_channel
);
Check(application);
application->BroadcastEvent(
DefaultEventPriority,
NetworkClient::IcomManagerClientID,
&message
);
Check_Fpu();
}
void
Icom::SetChannelValue(int new_channel)
{
Test_Tell("Icom::SetChannelValue(" << new_channel << ")\n");
Check(this);
//--------------------------------------
// Set local value
//--------------------------------------
channel = new_channel;
Check_Fpu();
}
int
Icom::GetChannel()
{
Check(this);
Check_Fpu();
return channel;
}
//--------------------------------------------------------------------------
void
Icom::SetPTTStatus(Logical new_ptt)
{
Test_Tell("Icom::SetPTTStatus(" << new_ptt << ")\n");
Check(this);
//---------------------------------------
// Disallow talking during public address
//---------------------------------------
if (!PACaptive)
{
//--------------------------------------
// Broadcast change
// (nonexclusive broadcast: we receive
// and process this msg locally)
//--------------------------------------
IcomManager::IMMessage
message;
message.BuildPTTMessage(
IcomManager::PTTMessageID,
hostID,
unitNumber,
new_ptt
);
Check(application);
application->BroadcastEvent(
DefaultEventPriority,
NetworkClient::IcomManagerClientID,
&message
);
}
Check_Fpu();
}
void
Icom::SetPTTStatusValue(Logical new_ptt)
{
Test_Tell("Icom::SetPTTStatusValue(" << new_ptt << ")\n");
Check(this);
//---------------------------------------
// Disallow talking during public address
//---------------------------------------
if (!PACaptive)
{
PTTStatus = new_ptt;
}
Check_Fpu();
}
Logical
Icom::GetPTTStatus()
{
Check(this);
Check_Fpu();
return PTTStatus;
}
//--------------------------------------------------------------------------
void
Icom::SetPACaptive(Logical new_pa)
{
Test_Tell("Icom::SetPACaptive(" << new_pa << ")\n");
Check(this);
//--------------------------------------
// Broadcast the change
// (nonexclusive broadcast: we receive
// and process this msg locally)
//--------------------------------------
IcomManager::IMMessage
message;
message.BuildPAMessage(
IcomManager::PAMessageID,
hostID,
unitNumber,
new_pa
);
Check(application);
application->BroadcastEvent(
DefaultEventPriority,
NetworkClient::IcomManagerClientID,
&message
);
Check_Fpu();
}
void
Icom::SetPACaptiveValue(Logical new_pa)
{
Test_Tell("Icom::SetPACaptiveValue(" << new_pa << ")\n");
Check(this);
if (new_pa == True)
{
if (PACaptive == False)
{
channelBeforePA = channel;
}
//--------------------------------------
// Force PTT off during public address
//--------------------------------------
if (PTTStatus == True)
{
SetPTTStatusValue(False);
}
}
else
{
//--------------------------------------
// Return to previous channel
//--------------------------------------
SetChannelValue(channelBeforePA);
}
PACaptive = new_pa;
Check_Fpu();
}
Logical
Icom::GetPACaptive()
{
Check(this);
Check_Fpu();
return PACaptive;
}
//##########################################################################
//######################### IcomManager ##############################
//##########################################################################
//--------------------------------------------------------------------------
// Virtual Data support
//
Derivation* IcomManager::GetClassDerivations()
{
static Derivation classDerivations(NetworkClient::GetClassDerivations(), "IcomManager");
return &classDerivations;
}
IcomManager::SharedData
IcomManager::DefaultData(
IcomManager::GetClassDerivations(),
IcomManager::GetMessageHandlers()
);
//--------------------------------------------------------------------------
// Creator
//
IcomManager::IcomManager(
SharedData &shared_data
):
NetworkClient(IcomManagerClassID, shared_data, IcomManagerClientID),
instanceList(this)
{
Test_Tell("IcomManager::IcomManager()\n");
Check_Pointer(this);
//--------------------------------
// Initialize unit number service
//--------------------------------
nextUnitNumber = 0;
Check_Fpu();
}
//--------------------------------------------------------------------------
// Destructor
//
IcomManager::~IcomManager()
{
Test_Tell("IcomManager::~IcomManager()\n");
Check(this);
Shutdown();
Check_Fpu();
}
//--------------------------------------------------------------------------
Logical
IcomManager::TestInstance() const
{
return IsDerivedFrom(*GetClassDerivations());
}
//--------------------------------------------------------------------------
void
IcomManager::LoadMission(Mission */*mission*/)
{
Check(this);
Check_Fpu();
}
//--------------------------------------------------------------------------
void
IcomManager::Shutdown()
{
Check(this);
Icom
*icom;
ChainIteratorOf<Icom*>
i(instanceList);
//------------------------------------------
// Delete all icom objects
//------------------------------------------
while ((icom=i.ReadAndNext()) != NULL)
{
Check(icom);
Unregister_Object(icom);
delete icom;
}
Check_Fpu();
}
//--------------------------------------------------------------------------
void
IcomManager::Execute()
{
Check(this);
Fail("IcomManager::Execute() should not be called directly!\n");
}
//--------------------------------------------------------------------------
Icom *
IcomManager::MakeIcom(HostID host_id, int unit_number)
{
Test_Tell(
"IcomManager::MakeIcom(" << host_id <<
", " << unit_number <<
")\n"
);
Check(this);
//------------------------------------------
// Create, register icom object
//------------------------------------------
Icom
*icom = new Icom(host_id, unit_number);
Check(icom);
Register_Object(icom);
//------------------------------------------
// Add to global list
//------------------------------------------
instanceList.Add(icom);
Check_Fpu();
return icom;
}
//------------------------------------------------------------------------
void
IcomManager::SetPAState(int pa_channel)
{
Test_Tell("IcomManager::SetPAState(" << pa_channel << ")\n");
Check(this);
Icom
*icom;
ChainIteratorOf<Icom*>
i(instanceList);
if (pa_channel == Icom::undefinedChannel)
{
//------------------------------------------
// Release all icom objects from PA state
//------------------------------------------
while ((icom=i.ReadAndNext()) != NULL)
{
Check(icom);
icom->SetPACaptive(False);
}
}
else
{
//------------------------------------------
// Force all icom objects to PA state
//------------------------------------------
while ((icom=i.ReadAndNext()) != NULL)
{
Check(icom);
icom->SetPACaptive(True);
icom->SetChannel(pa_channel);
}
}
Check_Fpu();
}
//------------------------------------------------------------------------
Icom*
IcomManager::FindIcom(HostID host_id, int unit_number)
{
Check(this);
ChainIteratorOf<Icom*>
i(instanceList);
Icom
*icom;
while ((icom=i.ReadAndNext()) != NULL)
{
Check(icom);
if (icom->hostID == host_id)
{
if (icom->unitNumber == unit_number)
{
Check_Fpu();
return icom;
}
}
}
Check_Fpu();
return NULL;
}
void
IcomManager::ReceiveNetworkPacket(
NetworkPacket */*packet*/,
Receiver::Message *packet_message
)
{
Test_Tell("IcomManager::ReceiveNetworkPacket(...)\n");
Check(this);
Check(packet_message);
Verify(packet_message->messageID >= 0);
Verify(packet_message->messageID < NextMessageID);
IMMessage
*message = (IMMessage *) packet_message;
Icom
*icom = FindIcom(message->hostID, message->unitNumber);
if (icom != NULL)
{
Check(icom);
switch (message->messageID)
{
case ChannelMessageID:
icom->SetChannelValue(message->data.channelNumber);
break;
case PTTMessageID:
icom->SetPTTStatusValue(message->data.PTTStatus);
break;
case PAMessageID:
icom->SetPACaptiveValue(message->data.PAStatus);
break;
}
}
Check_Fpu();
}