mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
710
Code/Commando/inputconfigmgr.cpp
Normal file
710
Code/Commando/inputconfigmgr.cpp
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : Combat *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/commando/inputconfigmgr.cpp $*
|
||||
* *
|
||||
* Author:: Patrick Smith *
|
||||
* *
|
||||
* $Modtime:: 1/09/02 11:40a $*
|
||||
* *
|
||||
* $Revision:: 6 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "inputconfigmgr.h"
|
||||
#include "dlgcontrols.h"
|
||||
#include "input.h"
|
||||
#include "rawfile.h"
|
||||
#include "ffactory.h"
|
||||
#include "registry.h"
|
||||
#include "chunkio.h"
|
||||
#include "debug.h"
|
||||
#include "translatedb.h"
|
||||
#include "string_ids.h"
|
||||
#include "slavemaster.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Local constants
|
||||
////////////////////////////////////////////////////////////////
|
||||
static const char *CFG_DICTIONARY_FILENAME = "CONFIG.DAT";
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Registry key names
|
||||
////////////////////////////////////////////////////////////////
|
||||
//static const char *REGISTRY_SUB_KEY = "Software\\Westwood\\Renegade\\Input";
|
||||
static const char *REG_CURRENT_CONFIG = "Current Config";
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Static member initialization
|
||||
////////////////////////////////////////////////////////////////
|
||||
DynamicVectorClass<InputConfigClass> InputConfigMgrClass::ConfigList;
|
||||
int InputConfigMgrClass::CurrentConfigIndex = -1;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Save/load constants
|
||||
////////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
CHUNKID_CONFIG_LIST = 0x07181105,
|
||||
CHUNKID_VARIABLES,
|
||||
CHUNKID_CONFIG_OBJ,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VARID_CURRENT_CONFIG = 1,
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Initialize (void)
|
||||
{
|
||||
//
|
||||
// Build the configuration list and load the current configuration
|
||||
//
|
||||
Load ();
|
||||
Load_Current_Configuration ();
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shutdown
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Shutdown (void)
|
||||
{
|
||||
//
|
||||
// Save our current configuration list
|
||||
//
|
||||
if (!SlaveMaster.Am_I_Slave()) {
|
||||
Save ();
|
||||
}
|
||||
|
||||
//
|
||||
// Reset our data
|
||||
//
|
||||
ConfigList.Delete_All ();
|
||||
CurrentConfigIndex = -1;
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Current_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
bool
|
||||
InputConfigMgrClass::Get_Current_Configuration (InputConfigClass &config)
|
||||
{
|
||||
if (CurrentConfigIndex < 0 || CurrentConfigIndex >= ConfigList.Count ()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Simply index into the config list and return the object to the caller
|
||||
//
|
||||
config = ConfigList[CurrentConfigIndex];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load_Current_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Load_Current_Configuration (void)
|
||||
{
|
||||
if (CurrentConfigIndex < 0 || CurrentConfigIndex >= ConfigList.Count ()) {
|
||||
|
||||
//
|
||||
// The current configuration is invalid, so load the
|
||||
// default configuration
|
||||
//
|
||||
Load_Default_Configuration ();
|
||||
} else {
|
||||
|
||||
//
|
||||
// Load this configuration
|
||||
//
|
||||
Load_Configuration (ConfigList[CurrentConfigIndex]);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Save_Current_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Save_Current_Configuration (void)
|
||||
{
|
||||
if (CurrentConfigIndex < 0 || CurrentConfigIndex >= ConfigList.Count ()) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Save this configuration
|
||||
//
|
||||
Save_Configuration (ConfigList[CurrentConfigIndex]);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
int
|
||||
InputConfigMgrClass::Add_Configuration (const WCHAR *display_name)
|
||||
{
|
||||
//
|
||||
// Get a filename for the configuration
|
||||
//
|
||||
StringClass filename;
|
||||
Get_Unique_Config_Filename (filename);
|
||||
|
||||
//
|
||||
// Build a new input config object
|
||||
//
|
||||
InputConfigClass config;
|
||||
config.Set_Display_Name (display_name);
|
||||
config.Set_Filename (filename);
|
||||
config.Set_Is_Custom (true);
|
||||
|
||||
//
|
||||
// Add the object to our list
|
||||
//
|
||||
CurrentConfigIndex = ConfigList.Add (config);
|
||||
|
||||
//
|
||||
// Now save the current configuration to this file
|
||||
//
|
||||
Save_Configuration (config);
|
||||
return CurrentConfigIndex;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Delete_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Delete_Configuration (int index)
|
||||
{
|
||||
if (index < 0 || index >= ConfigList.Count ()) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Reset the current configuration (if necessary)
|
||||
//
|
||||
bool load_default = false;
|
||||
if (index == CurrentConfigIndex) {
|
||||
CurrentConfigIndex = -1;
|
||||
load_default = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the local path of the configuration files
|
||||
//
|
||||
StringClass config_path;
|
||||
Get_Config_Path (config_path);
|
||||
|
||||
StringClass full_path;
|
||||
full_path.Format ("%s\\%s", config_path, ConfigList[index].Get_Filename ());
|
||||
|
||||
//
|
||||
// Delete the configuration file
|
||||
//
|
||||
::DeleteFile (full_path);
|
||||
|
||||
//
|
||||
// Now remove this entry from the list
|
||||
//
|
||||
ConfigList.Delete (index);
|
||||
|
||||
//
|
||||
// Load the default configuration is we just deleted the current configuration
|
||||
//
|
||||
if (load_default) {
|
||||
Load_Default_Configuration ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Delete_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Delete_Configuration (const char *filename)
|
||||
{
|
||||
//
|
||||
// Try to find the configuration in our list
|
||||
//
|
||||
int index = Find_Configuration (filename);
|
||||
if (index != -1) {
|
||||
|
||||
//
|
||||
// We've found the conversation, so delete it
|
||||
//
|
||||
Delete_Configuration (index);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Find_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
int
|
||||
InputConfigMgrClass::Find_Configuration (const char *filename)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
for (int index = 0; index < ConfigList.Count (); index ++) {
|
||||
|
||||
//
|
||||
// Is this the entry we're looking for?
|
||||
//
|
||||
if (::lstrcmpi (ConfigList[index].Get_Filename (), filename) == 0) {
|
||||
retval = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load_Default_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Load_Default_Configuration (void)
|
||||
{
|
||||
for (int index = 0; index < ConfigList.Count (); index ++) {
|
||||
|
||||
//
|
||||
// Is this the default configuration?
|
||||
//
|
||||
if (ConfigList[index].Is_Default ()) {
|
||||
Load_Configuration (ConfigList[index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Load_Configuration (const InputConfigClass &config)
|
||||
{
|
||||
//
|
||||
// Anytime we loada configuration, it becomes our current config
|
||||
//
|
||||
CurrentConfigIndex = Find_Configuration (config.Get_Filename ());
|
||||
|
||||
//
|
||||
// Load the configuration into memory
|
||||
//
|
||||
Input::Load_Configuration (config.Get_Filename ());
|
||||
|
||||
//
|
||||
// Reload the UI (if necessary)
|
||||
//
|
||||
if (ControlsMenuClass::Get_Instance () != NULL) {
|
||||
ControlsMenuClass::Get_Instance ()->Reload ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Save_Configuration
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Save_Configuration (const InputConfigClass &config)
|
||||
{
|
||||
//
|
||||
// We can only save custom configurations
|
||||
//
|
||||
if (config.Is_Custom ()) {
|
||||
|
||||
//
|
||||
// Anytime we save a configuration, it becomes our current config...
|
||||
//
|
||||
CurrentConfigIndex = Find_Configuration (config.Get_Filename ());
|
||||
Input::Save_Configuration (config.Get_Filename ());
|
||||
|
||||
//
|
||||
// Update the copy of this config in our internal list
|
||||
//
|
||||
if (CurrentConfigIndex != -1) {
|
||||
ConfigList[CurrentConfigIndex] = config;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// Make a name for a new configuration
|
||||
//
|
||||
WideStringClass new_name = TRANSLATE (IDS_MENU_CUSTOM);
|
||||
new_name += config.Get_Display_Name ();
|
||||
|
||||
//
|
||||
// Add a new configuration to list (this saves the new
|
||||
// configuration as well)
|
||||
//
|
||||
Add_Configuration (new_name);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Unique_Config_Filename
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Get_Unique_Config_Filename (StringClass &filename)
|
||||
{
|
||||
//
|
||||
// Get the local path of the configuration files
|
||||
//
|
||||
StringClass config_path;
|
||||
Get_Config_Path (config_path);
|
||||
|
||||
int slot = 1;
|
||||
|
||||
StringClass full_path;
|
||||
do
|
||||
{
|
||||
//
|
||||
// Build this filename
|
||||
//
|
||||
filename.Format ("input%.2d.cfg", slot ++);
|
||||
|
||||
//
|
||||
// Check to see if this file exists
|
||||
//
|
||||
full_path.Format ("%s\\%s", (const char *)config_path, filename);
|
||||
|
||||
} while (::GetFileAttributes (full_path) != 0xFFFFFFFF);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Save
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Save (void)
|
||||
{
|
||||
FileClass *file = _TheFileFactory->Get_File (CFG_DICTIONARY_FILENAME);
|
||||
WWASSERT (file != NULL);
|
||||
if (file == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the file for writing
|
||||
//
|
||||
file->Open (FileClass::WRITE);
|
||||
ChunkSaveClass csave(file);
|
||||
|
||||
//
|
||||
// Save the config list to its own chunk
|
||||
//
|
||||
csave.Begin_Chunk (CHUNKID_CONFIG_LIST);
|
||||
Save_Config_List (csave);
|
||||
csave.End_Chunk ();
|
||||
|
||||
//
|
||||
// Save the
|
||||
//
|
||||
csave.Begin_Chunk (CHUNKID_VARIABLES);
|
||||
Save_Variables (csave);
|
||||
csave.End_Chunk ();
|
||||
|
||||
//
|
||||
// Close the file
|
||||
//
|
||||
file->Close ();
|
||||
_TheFileFactory->Return_File (file);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Load (void)
|
||||
{
|
||||
FileClass *file = _TheFileFactory->Get_File (CFG_DICTIONARY_FILENAME);
|
||||
WWASSERT (file != NULL);
|
||||
if (file == NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Open the file for reading
|
||||
//
|
||||
file->Open (FileClass::READ);
|
||||
ChunkLoadClass cload(file);
|
||||
|
||||
//
|
||||
// Read all the chunks stored in this file
|
||||
//
|
||||
while (cload.Open_Chunk ()) {
|
||||
switch(cload.Cur_Chunk_ID ()) {
|
||||
|
||||
case CHUNKID_CONFIG_LIST:
|
||||
Load_Config_List (cload);
|
||||
break;
|
||||
|
||||
case CHUNKID_VARIABLES:
|
||||
Load_Variables (cload);
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug_Say (("Unrecognized InputConfigMgrClass Chunk ID\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
cload.Close_Chunk ();
|
||||
}
|
||||
|
||||
//
|
||||
// If the configuration list is empty, then add the default
|
||||
// configuration file to the list
|
||||
//
|
||||
if (ConfigList.Count () == 0) {
|
||||
InputConfigClass config;
|
||||
config.Set_Display_Name (TRANSLATE (IDS_MENU_DEFAULT_SETTINGS));
|
||||
config.Set_Filename (DEFAULT_INPUT_FILENAME);
|
||||
config.Set_Is_Custom (false);
|
||||
config.Set_Is_Default (true);
|
||||
ConfigList.Add (config);
|
||||
CurrentConfigIndex = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Close the file
|
||||
//
|
||||
file->Close ();
|
||||
_TheFileFactory->Return_File (file);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Save_Config_List
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Save_Config_List (ChunkSaveClass &csave)
|
||||
{
|
||||
for (int index = 0; index < ConfigList.Count (); index ++) {
|
||||
|
||||
//
|
||||
// Save this configuration object to its own chunk
|
||||
//
|
||||
csave.Begin_Chunk (CHUNKID_CONFIG_OBJ);
|
||||
ConfigList[index].Save (csave);
|
||||
csave.End_Chunk ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load_Config_List
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Load_Config_List (ChunkLoadClass &cload)
|
||||
{
|
||||
//
|
||||
// Read all the sub-chunks
|
||||
//
|
||||
while (cload.Open_Chunk ()) {
|
||||
switch (cload.Cur_Chunk_ID ()) {
|
||||
|
||||
case CHUNKID_CONFIG_OBJ:
|
||||
{
|
||||
//
|
||||
// Load this configuration object
|
||||
//
|
||||
InputConfigClass config;
|
||||
config.Load (cload);
|
||||
|
||||
//
|
||||
// Add the object to our list
|
||||
//
|
||||
ConfigList.Add (config);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Debug_Say (("Unrecognized InputConfigMgrClass::Load_Config_List Chunk ID\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
cload.Close_Chunk ();
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Save_Variables
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Save_Variables (ChunkSaveClass &csave)
|
||||
{
|
||||
//
|
||||
// Determine what the filename of the current configuration is
|
||||
//
|
||||
StringClass filename;
|
||||
if (CurrentConfigIndex != -1) {
|
||||
filename = ConfigList[CurrentConfigIndex].Get_Filename ();
|
||||
} else {
|
||||
filename = DEFAULT_INPUT_FILENAME;
|
||||
}
|
||||
|
||||
WRITE_MICRO_CHUNK_WWSTRING (csave, VARID_CURRENT_CONFIG, filename);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Load_Variables
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Load_Variables (ChunkLoadClass &cload)
|
||||
{
|
||||
StringClass filename;
|
||||
|
||||
//
|
||||
// Read all the microchunks
|
||||
//
|
||||
while (cload.Open_Micro_Chunk ()) {
|
||||
switch(cload.Cur_Micro_Chunk_ID ()) {
|
||||
READ_MICRO_CHUNK_WWSTRING (cload, VARID_CURRENT_CONFIG, filename);
|
||||
}
|
||||
|
||||
cload.Close_Micro_Chunk ();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Store the index of this configuration
|
||||
//
|
||||
CurrentConfigIndex = Find_Configuration (filename);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get_Config_Path
|
||||
//
|
||||
////////////////////////////////////////////////////////////////
|
||||
void
|
||||
InputConfigMgrClass::Get_Config_Path (StringClass &full_path)
|
||||
{
|
||||
//
|
||||
// Lookup the path of the executable
|
||||
//
|
||||
char path[MAX_PATH] = { 0 };
|
||||
::GetModuleFileName (NULL, path, sizeof (path));
|
||||
|
||||
//
|
||||
// Strip off the filename
|
||||
//
|
||||
char *filename_portion = ::strrchr (path, '\\');
|
||||
if (filename_portion != NULL) {
|
||||
filename_portion[0] = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Build the full path from the EXE's directory
|
||||
//
|
||||
full_path.Format ("%s\\data\\config", path);
|
||||
return ;
|
||||
}
|
||||
Reference in New Issue
Block a user