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,660 @@
|
||||
#include "munga.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "controls.h"
|
||||
#include "app.h"
|
||||
|
||||
#if defined(DEBUG)
|
||||
# define Test_Tell(n) DEBUG_STREAM << n
|
||||
#else
|
||||
# define Test_Tell(n)
|
||||
#endif
|
||||
|
||||
//############################################################################
|
||||
//####################### ControlsInstance #############################
|
||||
//############################################################################
|
||||
|
||||
ControlsInstance::ControlsInstance(
|
||||
ClassID class_ID,
|
||||
ModeMask mode_mask,
|
||||
Plug *dependant
|
||||
):
|
||||
Node(class_ID),
|
||||
dependantPlug(this)
|
||||
{
|
||||
Check_Pointer(this);
|
||||
modeMask = mode_mask;
|
||||
dependantPlug.Add(dependant);
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
ControlsInstance::~ControlsInstance()
|
||||
{
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsInstance::Update(void *)
|
||||
{
|
||||
Fail("ControlsInstance::Update not overridden!");
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
ControlsInstance::ReleaseLinkHandler(
|
||||
Socket*,
|
||||
Plug*
|
||||
)
|
||||
{
|
||||
Unregister_Object(this);
|
||||
delete this;
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//######################### ControlsMappingGroup #############################
|
||||
//############################################################################
|
||||
|
||||
//
|
||||
// The ControlsMappingGroup object maintains a group of ControlInstances.
|
||||
//
|
||||
// ControlsMappingGroup.Update() will call ControlsInstance.Update()
|
||||
// for each instance in the group.
|
||||
//
|
||||
|
||||
ControlsMappingGroup::ControlsMappingGroup():
|
||||
Node(ControlsMappingGroup::ControlsMappingGroupClassID),
|
||||
instanceList(this)
|
||||
{
|
||||
Check_Pointer(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
ControlsMappingGroup::~ControlsMappingGroup()
|
||||
{
|
||||
Check(this);
|
||||
Remove(0); // remove all mappings
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void ControlsMappingGroup::Remove(ModeMask mode_mask)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
ChainIteratorOf<ControlsInstance*>
|
||||
i(instanceList);
|
||||
|
||||
ControlsInstance
|
||||
*controls_instance;
|
||||
|
||||
while ((controls_instance=i.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(controls_instance);
|
||||
//---------------------------------------------
|
||||
// Remove mapping bit(s)
|
||||
//---------------------------------------------
|
||||
controls_instance->modeMask &= ~mode_mask;
|
||||
//---------------------------------------------
|
||||
// If no bits left, delete mapping
|
||||
//---------------------------------------------
|
||||
if (controls_instance->modeMask == (ModeMask)0)
|
||||
{
|
||||
Unregister_Object(controls_instance);
|
||||
delete controls_instance;
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsMappingGroup::Update(void *data_source, ModeMask mode_mask)
|
||||
{
|
||||
Check(this);
|
||||
Check_Pointer(data_source);
|
||||
|
||||
ChainIteratorOf<ControlsInstance*>
|
||||
i(instanceList);
|
||||
|
||||
ControlsInstance
|
||||
*controls_instance;
|
||||
|
||||
while ((controls_instance=i.ReadAndNext()) != NULL)
|
||||
{
|
||||
//------------------------------------------------
|
||||
// Process only if at least one mode bit matches
|
||||
//------------------------------------------------
|
||||
Check(controls_instance);
|
||||
if (controls_instance->modeMask & mode_mask)
|
||||
{
|
||||
controls_instance->Update(data_source);
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
Logical
|
||||
ControlsMappingGroup::CurrentFilterStatus(ModeMask mode_mask)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
ChainIteratorOf<ControlsInstance*>
|
||||
i(instanceList);
|
||||
|
||||
ControlsInstance
|
||||
*controls_instance;
|
||||
|
||||
while ((controls_instance=i.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(controls_instance);
|
||||
|
||||
if (controls_instance->modeMask & mode_mask)
|
||||
{
|
||||
Check_Fpu();
|
||||
return True;
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
return False;
|
||||
}
|
||||
|
||||
//############################################################################
|
||||
//########################### ControlsManager ################################
|
||||
//############################################################################
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Class derivation
|
||||
//---------------------------------------------------------------------------
|
||||
Derivation* ControlsManager::GetClassDerivations()
|
||||
{
|
||||
static Derivation classDerivations(Receiver::GetClassDerivations(), "ControlsManager");
|
||||
return &classDerivations;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ControlsManager::nextOwnerID=0;
|
||||
|
||||
ControlsManager
|
||||
*ControlsManager::headControlsManager = NULL;
|
||||
|
||||
//
|
||||
//############################################################################
|
||||
// ControlsManager
|
||||
//
|
||||
// Creator method
|
||||
//----------------------------------------------------------------------------
|
||||
// Enter: virtualDataPtr
|
||||
//############################################################################
|
||||
//
|
||||
ControlsManager::ControlsManager(
|
||||
ClassID class_ID,
|
||||
SharedData &shared_data
|
||||
):
|
||||
Receiver(
|
||||
class_ID,
|
||||
shared_data
|
||||
)
|
||||
{
|
||||
activeDestination = NULL;
|
||||
activeReceiver = NULL;
|
||||
activeMessageID = (Receiver::MessageID) 0;
|
||||
activeDependant = NULL;
|
||||
//----------------------------------------------------
|
||||
// Add this object to the chain
|
||||
//----------------------------------------------------
|
||||
nextControlsManager = headControlsManager;
|
||||
headControlsManager = this;
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
//############################################################################
|
||||
// ~ControlsManager
|
||||
//
|
||||
// Destructor method
|
||||
//############################################################################
|
||||
//
|
||||
ControlsManager::~ControlsManager()
|
||||
{
|
||||
//----------------------------------------------------
|
||||
// Unlink this object from the chain
|
||||
//----------------------------------------------------
|
||||
ControlsManager
|
||||
*controls_manager,
|
||||
*previous_controls_manager(NULL);
|
||||
|
||||
//
|
||||
// Search for 'this' in the chain
|
||||
//
|
||||
for(
|
||||
controls_manager = headControlsManager;
|
||||
controls_manager != NULL;
|
||||
controls_manager = controls_manager->nextControlsManager
|
||||
)
|
||||
{
|
||||
if (controls_manager == this)
|
||||
{
|
||||
//
|
||||
// Found! head of list?
|
||||
//
|
||||
if (previous_controls_manager == NULL)
|
||||
{
|
||||
headControlsManager = nextControlsManager;
|
||||
}
|
||||
//
|
||||
// Not head, remove from chain
|
||||
//
|
||||
else
|
||||
{
|
||||
previous_controls_manager->nextControlsManager =
|
||||
nextControlsManager;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Keep track of 'previous' object
|
||||
//
|
||||
previous_controls_manager = controls_manager;
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsManager::Remove(ModeMask /*mode_mask*/)
|
||||
{
|
||||
Fail("ControlsManager::Remove should not be called!\n");
|
||||
}
|
||||
|
||||
void
|
||||
ControlsManager::Execute()
|
||||
{
|
||||
Fail("ControlsManager::Execute should not be called!\n");
|
||||
}
|
||||
|
||||
void
|
||||
ControlsManager::StartMappableButtonsConfigure(
|
||||
void *active_direct_target,
|
||||
Receiver *target,
|
||||
Plug *dependant,
|
||||
Receiver::MessageID active_message_id,
|
||||
ModeMask remove_mode_mask,
|
||||
ModeMask add_mode_mask
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
activeReceiver = target;
|
||||
activeMessageID = active_message_id;
|
||||
activeDestination = active_direct_target;
|
||||
activeDependant = dependant;
|
||||
|
||||
Check(application);
|
||||
ModeManager
|
||||
*mode_manager = application->GetModeManager();
|
||||
Check(mode_manager);
|
||||
|
||||
mode_manager->RemoveModeMask(remove_mode_mask);
|
||||
mode_manager->AddModeMask(add_mode_mask);
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsManager::StopMappableButtonsConfigure(
|
||||
ModeMask remove_mode_mask,
|
||||
ModeMask add_mode_mask
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
|
||||
Check(application);
|
||||
ModeManager
|
||||
*mode_manager = application->GetModeManager();
|
||||
Check(mode_manager);
|
||||
|
||||
mode_manager->RemoveModeMask(remove_mode_mask);
|
||||
mode_manager->AddModeMask(add_mode_mask);
|
||||
|
||||
activeDestination = NULL;
|
||||
activeReceiver = NULL;
|
||||
activeMessageID = (Receiver::MessageID) 0;
|
||||
activeDependant = NULL;
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsManager::AddOrEraseMappableButton(
|
||||
int /*button_number*/,
|
||||
ModeMask /*mode_mask*/
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
//############################################################################
|
||||
// TestInstance
|
||||
//
|
||||
//############################################################################
|
||||
//
|
||||
Logical
|
||||
ControlsManager::TestInstance() const
|
||||
{
|
||||
return IsDerivedFrom(*GetClassDerivations());
|
||||
}
|
||||
|
||||
//
|
||||
//############################################################################
|
||||
// Shutdown
|
||||
//
|
||||
//############################################################################
|
||||
//
|
||||
void
|
||||
ControlsManager::Shutdown()
|
||||
{
|
||||
ControlsManager
|
||||
*controls_manager;
|
||||
|
||||
for(
|
||||
controls_manager = headControlsManager;
|
||||
controls_manager != NULL;
|
||||
controls_manager = controls_manager->nextControlsManager
|
||||
)
|
||||
{
|
||||
controls_manager->LocalShutdown();
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsManager::LocalShutdown()
|
||||
{
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//#########################################################################
|
||||
//############################# ControlsString ############################
|
||||
//#########################################################################
|
||||
int
|
||||
ControlsString::nextID = 1;
|
||||
|
||||
ControlsString::ControlsString(
|
||||
const char *new_string,
|
||||
int keypad_unit_number,
|
||||
Receiver *receiver_pointer,
|
||||
Receiver::MessageID message_id,
|
||||
int user_code
|
||||
):
|
||||
Node(RegisteredClass::ControlsStringClassID)
|
||||
{
|
||||
Test_Tell(
|
||||
"ControlsString creator('" new_string <<
|
||||
"'," << keypad_unit_number <<
|
||||
"," << receiver_pointer <<
|
||||
"," << message_id <<
|
||||
")\n"
|
||||
);
|
||||
Check_Pointer(this);
|
||||
Check_Pointer(new_string);
|
||||
Check(receiver_pointer);
|
||||
|
||||
//----------------------------------------------
|
||||
// Assign unique ID
|
||||
//----------------------------------------------
|
||||
id = nextID++;
|
||||
matchStringPointer = new_string;
|
||||
keypadUnitNumber = keypad_unit_number;
|
||||
//----------------------------------------------
|
||||
// Save message data
|
||||
//----------------------------------------------
|
||||
receiverPointer = receiver_pointer;
|
||||
messageID = message_id;
|
||||
userCode = user_code;
|
||||
//----------------------------------------------
|
||||
// Clear the buffer
|
||||
//----------------------------------------------
|
||||
string[0] = '\0';
|
||||
stringLength = 0;
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
ControlsString::~ControlsString()
|
||||
{
|
||||
Test_Tell("ControlsString destructor\n");
|
||||
Check(this);
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
Logical
|
||||
ControlsString::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
void
|
||||
ControlsString::Update(int keypad_unit_number, ControlsKey new_key)
|
||||
{
|
||||
Test_Tell(
|
||||
"ControlsString::Update(" << keypad_unit_number <<
|
||||
"," << new_key <<
|
||||
"\n"
|
||||
);
|
||||
Check(this);
|
||||
|
||||
//----------------------------------------------
|
||||
// Update only if proper keyboard unit
|
||||
//----------------------------------------------
|
||||
if (keypad_unit_number == keypadUnitNumber)
|
||||
{
|
||||
//--------------------------------------
|
||||
// Get string length
|
||||
//--------------------------------------
|
||||
Check_Pointer(matchStringPointer);
|
||||
int
|
||||
length = strlen(matchStringPointer);
|
||||
if (length > maxStringLength)
|
||||
{
|
||||
length = maxStringLength;
|
||||
}
|
||||
|
||||
if (stringLength > length) // in case matchString changes
|
||||
{
|
||||
stringLength = length;
|
||||
string[stringLength] = '\0';
|
||||
}
|
||||
//--------------------------------------
|
||||
// Update string buffer
|
||||
//--------------------------------------
|
||||
if (stringLength < length)
|
||||
{
|
||||
string[stringLength++] = (char) new_key;
|
||||
string[stringLength] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (length > 1)
|
||||
{
|
||||
memmove(&string[0],&string[1], length-1);
|
||||
}
|
||||
string[length-1] = (char) new_key;
|
||||
}
|
||||
Test_Tell("string=" << string << "\n");
|
||||
//--------------------------------------
|
||||
// Check for match
|
||||
//--------------------------------------
|
||||
if (strnicmp(string, matchStringPointer, length) == 0)
|
||||
{
|
||||
Test_Tell(
|
||||
"ControlsString::Update, '" << matchStringPointer <<
|
||||
"' matched!\n"
|
||||
);
|
||||
//--------------------------------------
|
||||
// Match found, send message
|
||||
//--------------------------------------
|
||||
Check(receiverPointer);
|
||||
Check(application);
|
||||
|
||||
ControlsStringMessage
|
||||
message(messageID, this->userCode);
|
||||
receiverPointer->Dispatch(&message);
|
||||
//--------------------------------------
|
||||
// Clear the string
|
||||
//--------------------------------------
|
||||
string[0] = '\0';
|
||||
stringLength = 0;
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//#########################################################################
|
||||
//######################## ControlsStringManager ##########################
|
||||
//#########################################################################
|
||||
ControlsStringManager::ControlsStringManager() :
|
||||
Node(RegisteredClass::ControlsStringManagerClassID),
|
||||
instanceList(this)
|
||||
{
|
||||
Test_Tell("ControlsStringManager creator\n");
|
||||
Check_Pointer(this);
|
||||
}
|
||||
|
||||
ControlsStringManager::~ControlsStringManager()
|
||||
{
|
||||
Test_Tell("ControlsStringManager destructor\n");
|
||||
Check(this);
|
||||
//----------------------------------------------
|
||||
// Remove all ControlStrings
|
||||
//----------------------------------------------
|
||||
Remove(0);
|
||||
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
Logical
|
||||
ControlsStringManager::TestInstance() const
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
||||
ControlsStringID
|
||||
ControlsStringManager::Add(
|
||||
const char *new_string,
|
||||
int keypad_unit_number,
|
||||
Receiver *receiver_pointer,
|
||||
Receiver::MessageID message_id,
|
||||
int user_code
|
||||
)
|
||||
{
|
||||
Test_Tell("ControlsStringManager::Add(" << new_string <<
|
||||
"," << keypad_unit_number <<
|
||||
"," << receiver_pointer <<
|
||||
"," << message_id <<
|
||||
"\n"
|
||||
);
|
||||
Check(this);
|
||||
Check_Pointer(new_string);
|
||||
Check(receiver_pointer);
|
||||
|
||||
//----------------------------------------------
|
||||
// Create the ControlsString
|
||||
//----------------------------------------------
|
||||
ControlsString
|
||||
*string_item = new ControlsString(
|
||||
new_string,
|
||||
keypad_unit_number,
|
||||
receiver_pointer,
|
||||
message_id,
|
||||
user_code
|
||||
);
|
||||
Check(string_item);
|
||||
Register_Object(string_item);
|
||||
//----------------------------------------------
|
||||
// Add to the instance list
|
||||
//----------------------------------------------
|
||||
instanceList.Add(string_item);
|
||||
//----------------------------------------------
|
||||
// return the new string's (unique) ID
|
||||
//----------------------------------------------
|
||||
Check_Fpu();
|
||||
return string_item->id;
|
||||
}
|
||||
|
||||
void
|
||||
ControlsStringManager::Remove(ControlsStringID string_id)
|
||||
{
|
||||
Test_Tell("ControlsStringManager::Remove(" << string_id << ")\n");
|
||||
Check(this);
|
||||
|
||||
ChainIteratorOf<ControlsString*>
|
||||
i(instanceList);
|
||||
|
||||
ControlsString
|
||||
*controls_string;
|
||||
|
||||
//----------------------------------------------
|
||||
// Search for the given ID (or universal match)
|
||||
//----------------------------------------------
|
||||
while ((controls_string=i.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(controls_string);
|
||||
if (
|
||||
(string_id == 0) ||
|
||||
(controls_string->id == string_id)
|
||||
)
|
||||
{
|
||||
Unregister_Object(controls_string);
|
||||
delete controls_string;
|
||||
//------------------------------------------
|
||||
// If this is not a 'universal' remove,
|
||||
// we're done (ID's are unique)
|
||||
//------------------------------------------
|
||||
if (string_id != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
void
|
||||
ControlsStringManager::Update(
|
||||
int keypad_unit_number,
|
||||
ControlsKey new_key
|
||||
)
|
||||
{
|
||||
Test_Tell("ControlsStringManager::Update(" << keypad_unit_number <<
|
||||
"," << new_key <<
|
||||
")\n"
|
||||
);
|
||||
Check(this);
|
||||
|
||||
//--------------------------------------
|
||||
// Update all matching string items
|
||||
//--------------------------------------
|
||||
ChainIteratorOf<ControlsString*>
|
||||
i(instanceList);
|
||||
|
||||
ControlsString
|
||||
*controls_string;
|
||||
|
||||
while ((controls_string=i.ReadAndNext()) != NULL)
|
||||
{
|
||||
Check(controls_string);
|
||||
controls_string->Update(keypad_unit_number, new_key);
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
|
||||
#if defined(TEST_CLASS)
|
||||
#include "controls.tcp"
|
||||
#endif
|
||||
Reference in New Issue
Block a user