/* ** Command & Conquer Generals(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 . */ // FILE: WinMain.cpp ////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- // // Westwood Studios Pacific. // // Confidential Information // Copyright (C) 2001 - All Rights Reserved // //----------------------------------------------------------------------------- // // Project: MapCacheBuilder // // File name: WinMain.cpp // // Created: Matthew D. Campbell, October 2002 // // Desc: Application entry point for the standalone MapCache Builder // //----------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////// // SYSTEM INCLUDES //////////////////////////////////////////////////////////// #include #include #include // USER INCLUDES ////////////////////////////////////////////////////////////// #include "Lib/BaseType.h" #include "Common/Debug.h" #include "Common/GameMemory.h" #include "Common/GlobalData.h" #include "Common/NameKeyGenerator.h" #include "Resource.h" #include "Common/ThingFactory.h" #include "Common/FileSystem.h" #include "Win32Device/Common/Win32LocalFileSystem.h" #include "Win32Device/Common/Win32BIGFileSystem.h" #include "Common/SubSystemInterface.h" #include "GameClient/MapUtil.h" #include "W3DDevice/Common/W3DModuleFactory.h" #include "Common/FileSystem.h" #include "Common/ArchiveFileSystem.h" #include "Common/LocalFileSystem.h" #include "Common/Debug.h" #include "Common/StackDump.h" #include "Common/GameMemory.h" #include "Common/Science.h" #include "Common/ThingFactory.h" #include "Common/INI.h" #include "Common/GameAudio.h" #include "Common/SpecialPower.h" #include "Common/TerrainTypes.h" #include "Common/DamageFX.h" #include "Common/Upgrade.h" #include "Common/ModuleFactory.h" #include "Common/PlayerTemplate.h" #include "Common/MultiplayerSettings.h" #include "GameLogic/Armor.h" #include "GameLogic/CaveSystem.h" #include "GameLogic/CrateSystem.h" #include "GameLogic/ObjectCreationList.h" #include "GameLogic/Weapon.h" #include "GameLogic/RankInfo.h" #include "GameLogic/SidesList.h" #include "GameLogic/ScriptEngine.h" #include "GameLogic/ScriptActions.h" #include "GameClient/Anim2D.h" #include "GameClient/GameText.h" #include "GameClient/ParticleSys.h" #include "GameClient/Water.h" #include "GameClient/TerrainRoads.h" #include "GameClient/FXList.h" #include "GameClient/VideoPlayer.h" #include "GameLogic/Locomotor.h" #include "W3DDevice/Common/W3DModuleFactory.h" #include "W3DDevice/GameClient/W3DParticleSys.h" #include "MilesAudioDevice/MilesAudioManager.h" #include #include "win32device/GameClient/Win32Mouse.h" #include "Win32Device/Common/Win32LocalFileSystem.h" #include "Win32Device/Common/Win32BIGFileSystem.h" // DEFINES //////////////////////////////////////////////////////////////////// // PRIVATE TYPES ////////////////////////////////////////////////////////////// #ifdef _INTERNAL // for occasional debugging... //#pragma optimize("", off) //#pragma message("************************************** WARNING, optimization disabled for debugging purposes") #endif // PRIVATE DATA /////////////////////////////////////////////////////////////// static SubsystemInterfaceList _TheSubsystemList; template void initSubsystem(SUBSYSTEM*& sysref, SUBSYSTEM* sys, const char* path1 = NULL, const char* path2 = NULL, const char* dirpath = NULL) { sysref = sys; _TheSubsystemList.initSubsystem(sys, path1, path2, dirpath, NULL); } /////////////////////////////////////////////////////////////////////////////// // PUBLIC DATA //////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// HINSTANCE ApplicationHInstance = NULL; ///< our application instance /// just to satisfy the game libraries we link to HWND ApplicationHWnd = NULL; char *gAppPrefix = "MC_"; // Where are the default string files? const Char *g_strFile = "data\\Generals.str"; const Char *g_csfFile = "data\\%s\\Generals.csf"; // PRIVATE PROTOTYPES ///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // PRIVATE FUNCTIONS ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // strtrim ==================================================================== /** Trim leading and trailing whitespace from a character string (in place). */ //============================================================================= static char* strtrim(char* buffer) { if (buffer != NULL) { // Strip leading white space from the string. char * source = buffer; while ((*source != 0) && ((unsigned char)*source <= 32)) { source++; } if (source != buffer) { strcpy(buffer, source); } // Clip trailing white space from the string. for (int index = strlen(buffer)-1; index >= 0; index--) { if ((*source != 0) && ((unsigned char)buffer[index] <= 32)) { buffer[index] = '\0'; } else { break; } } } return buffer; } static char *nextParam(char *newSource, char *seps) { static char *source = NULL; if (newSource) { source = newSource; } if (!source) { return NULL; } // find first separator char *first = source;//strpbrk(source, seps); if (first) { // go past initial spaces char *firstNonSpace = first; while (*firstNonSpace == ' ') ++firstNonSpace; first = firstNonSpace; // go past separator char *firstSep = strpbrk(first, seps); char firstChar[2] = {0,0}; if (firstSep == first) { firstChar[0] = *first; while (*first == firstChar[0]) first++; } // find end char *end; if (firstChar[0]) end = strpbrk(first, firstChar); else end = strpbrk(first, seps); // trim string & save next start pos if (end) { source = end+1; *end = 0; if (!*source) source = NULL; } else { source = NULL; } if (first && !*first) first = NULL; } return first; } /////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // WinMain ==================================================================== /** Application entry point */ //============================================================================= Int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, Int nCmdShow ) { // start the log DEBUG_INIT(DEBUG_FLAGS_DEFAULT); initMemoryManager(); try { // save application instance ApplicationHInstance = hInstance; // Set the current directory to the app directory. char buf[_MAX_PATH]; GetModuleFileName(NULL, buf, sizeof(buf)); char *pEnd = buf + strlen(buf); while (pEnd != buf) { if (*pEnd == '\\') { *pEnd = 0; break; } pEnd--; } ::SetCurrentDirectory(buf); /* ** Convert WinMain arguments to simple main argc and argv */ std::list argvSet; char *token; token = nextParam(lpCmdLine, "\" "); while (token != NULL) { char * str = strtrim(token); argvSet.push_back(str); DEBUG_LOG(("Adding '%s'\n", str)); token = nextParam(NULL, "\" "); } // not part of the subsystem list, because it should normally never be reset! TheNameKeyGenerator = new NameKeyGenerator; TheNameKeyGenerator->init(); TheFileSystem = new FileSystem; initSubsystem(TheLocalFileSystem, (LocalFileSystem*)new Win32LocalFileSystem); initSubsystem(TheArchiveFileSystem, (ArchiveFileSystem*)new Win32BIGFileSystem); INI ini; initSubsystem(TheWritableGlobalData, new GlobalData(), "Data\\INI\\Default\\GameData.ini", "Data\\INI\\GameData.ini"); initSubsystem(TheGameText, CreateGameTextInterface()); initSubsystem(TheScienceStore, new ScienceStore(), "Data\\INI\\Default\\Science.ini", "Data\\INI\\Science.ini"); initSubsystem(TheMultiplayerSettings, new MultiplayerSettings(), "Data\\INI\\Default\\Multiplayer.ini", "Data\\INI\\Multiplayer.ini"); initSubsystem(TheTerrainTypes, new TerrainTypeCollection(), "Data\\INI\\Default\\Terrain.ini", "Data\\INI\\Terrain.ini"); initSubsystem(TheTerrainRoads, new TerrainRoadCollection(), "Data\\INI\\Default\\Roads.ini", "Data\\INI\\Roads.ini"); initSubsystem(TheScriptEngine, (ScriptEngine*)(new ScriptEngine())); initSubsystem(TheAudio, (AudioManager*)new MilesAudioManager()); initSubsystem(TheVideoPlayer, (VideoPlayerInterface*)(new VideoPlayer())); initSubsystem(TheModuleFactory, (ModuleFactory*)(new W3DModuleFactory())); initSubsystem(TheSidesList, new SidesList()); initSubsystem(TheCaveSystem, new CaveSystem()); initSubsystem(TheRankInfoStore, new RankInfoStore(), NULL, "Data\\INI\\Rank.ini"); initSubsystem(ThePlayerTemplateStore, new PlayerTemplateStore(), "Data\\INI\\Default\\PlayerTemplate.ini", "Data\\INI\\PlayerTemplate.ini"); initSubsystem(TheSpecialPowerStore, new SpecialPowerStore(), "Data\\INI\\Default\\SpecialPower.ini", "Data\\INI\\SpecialPower.ini" ); initSubsystem(TheParticleSystemManager, (ParticleSystemManager*)(new W3DParticleSystemManager())); initSubsystem(TheFXListStore, new FXListStore(), "Data\\INI\\Default\\FXList.ini", "Data\\INI\\FXList.ini"); initSubsystem(TheWeaponStore, new WeaponStore(), NULL, "Data\\INI\\Weapon.ini"); initSubsystem(TheObjectCreationListStore, new ObjectCreationListStore(), "Data\\INI\\Default\\ObjectCreationList.ini", "Data\\INI\\ObjectCreationList.ini"); initSubsystem(TheLocomotorStore, new LocomotorStore(), NULL, "Data\\INI\\Locomotor.ini"); initSubsystem(TheDamageFXStore, new DamageFXStore(), NULL, "Data\\INI\\DamageFX.ini"); initSubsystem(TheArmorStore, new ArmorStore(), NULL, "Data\\INI\\Armor.ini"); initSubsystem(TheThingFactory, new ThingFactory(), "Data\\INI\\Default\\Object.ini", NULL, "Data\\INI\\Object"); initSubsystem(TheCrateSystem, new CrateSystem(), "Data\\INI\\Default\\Crate.ini", "Data\\INI\\Crate.ini"); initSubsystem(TheUpgradeCenter, new UpgradeCenter, "Data\\INI\\Default\\Upgrade.ini", "Data\\INI\\Upgrade.ini"); initSubsystem(TheAnim2DCollection, new Anim2DCollection ); //Init's itself. _TheSubsystemList.postProcessLoadAll(); TheWritableGlobalData->m_buildMapCache = TRUE; TheMapCache = new MapCache; // add in allowed maps for (std::list::const_iterator cit = argvSet.begin(); cit != argvSet.end(); ++cit) { DEBUG_LOG(("Adding shipping map: '%s'\n", cit->c_str())); TheMapCache->addShippingMap((*cit).c_str()); } TheMapCache->updateCache(); delete TheMapCache; TheMapCache = NULL; // load the dialog box //DialogBox( hInstance, (LPCTSTR)IMAGE_PACKER_DIALOG, // NULL, (DLGPROC)ImagePackerProc ); // delete TheGlobalData //delete TheGlobalData; //TheGlobalData = NULL; _TheSubsystemList.shutdownAll(); delete TheFileSystem; TheFileSystem = NULL; delete TheNameKeyGenerator; TheNameKeyGenerator = NULL; } catch (...) { DEBUG_CRASH(("Munkee munkee!")); } // close the log shutdownMemoryManager(); DEBUG_SHUTDOWN(); // all done return 0; } // end WinMain