/* ** 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 . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: GameInfoWindow.cpp //////////////////////////////////////////////////////////////////////// // Author: Chris Huybregts, Feb 2002 // Description: Game Info window callbacks /////////////////////////////////////////////////////////////////////////////////////////////////// // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine #include "GameClient/WindowLayout.h" #include "GameClient/MapUtil.h" #include "GameClient/Shell.h" #include "GameClient/GameWindowManager.h" #include "GameClient/GadgetListBox.h" #include "GameClient/GadgetStaticText.h" #include "GameClient/GameText.h" #include "GameClient/GameInfoWindow.h" #include "Common/MultiplayerSettings.h" #include "Common/PlayerTemplate.h" #include "GameNetwork/GameInfo.h" #include "GameNetwork/LANAPI.h" #ifdef _INTERNAL // for occasional debugging... //#pragma optimize("", off) //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") #endif static GameWindow *parent = NULL; static GameWindow *staticTextGameName = NULL; static GameWindow *staticTextMapName = NULL; static GameWindow *listBoxPlayers = NULL; static GameWindow *winCrates = NULL; static GameWindow *winSuperWeapons = NULL; static GameWindow *winFreeForAll = NULL; static NameKeyType parentID = NAMEKEY_INVALID; static NameKeyType staticTextGameNameID = NAMEKEY_INVALID; static NameKeyType staticTextMapNameID = NAMEKEY_INVALID; static NameKeyType listBoxPlayersID = NAMEKEY_INVALID; static NameKeyType winCratesID = NAMEKEY_INVALID; static NameKeyType winSuperWeaponsID = NAMEKEY_INVALID; static NameKeyType winFreeForAllID = NAMEKEY_INVALID; static WindowLayout *gameInfoWindowLayout = NULL; // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////// void CreateLANGameInfoWindow( GameWindow *sizeAndPosWin ) { if( !gameInfoWindowLayout ) gameInfoWindowLayout = TheWindowManager->winCreateLayout( AsciiString( "Menus/GameInfoWindow.wnd" ) ); gameInfoWindowLayout->runInit(); gameInfoWindowLayout->bringForward(); gameInfoWindowLayout->hide( TRUE ); if( !parent || !sizeAndPosWin ) return; Int x, y, width, height; sizeAndPosWin->winGetScreenPosition(&x,&y); parent->winSetPosition(x,y); sizeAndPosWin->winGetSize( &width, &height ); parent->winSetSize(width, height); } void DestroyGameInfoWindow(void) { if (gameInfoWindowLayout) { gameInfoWindowLayout->destroyWindows(); gameInfoWindowLayout->deleteInstance(); gameInfoWindowLayout = NULL; } } void RefreshGameInfoWindow(GameInfo *gameInfo, UnicodeString gameName) { static const Image *randomIcon = TheMappedImageCollection->findImageByName("GameinfoRANDOM"); static const Image *observerIcon = TheMappedImageCollection->findImageByName("GameinfoOBSRVR"); if(!gameInfoWindowLayout || !gameInfo ) return; parent->winHide( FALSE ); parent->winBringToTop(); // Set the game name GadgetStaticTextSetText(staticTextGameName, ((LANGameInfo *)gameInfo)->getPlayerName(0)); // set the map name UnicodeString map; AsciiString asciiMap = gameInfo->getMap(); asciiMap.toLower(); std::map::iterator it = TheMapCache->find(asciiMap); if (it != TheMapCache->end()) { map = it->second.m_displayName; } else { // can happen if the map will have to be transferred... so use the leaf name (srj) const char *noPath = gameInfo->getMap().reverseFind('\\'); if (noPath) { ++noPath; } else { noPath = gameInfo->getMap().str(); } map.translate(noPath); } GadgetStaticTextSetText(staticTextMapName,map); // fill in the player list GadgetListBoxReset(listBoxPlayers); Int numColors = TheMultiplayerSettings->getNumColors(); Color white = GameMakeColor(255,255,255,255); // Color grey = GameMakeColor(188,188,188,255); for (Int i = 0; i < MAX_SLOTS; i ++) { Color playerColor = white; Int color = -1; Int addedRow; GameSlot *slot = gameInfo->getSlot(i); if(!slot || (slot->isOccupied() == FALSE)) continue; color = slot->getColor(); if(color > -1 && color < numColors) { MultiplayerColorDefinition *def = TheMultiplayerSettings->getColor(color); playerColor = def->getColor(); } if(slot->isAI()) { switch(slot->getState()) { case SLOT_EASY_AI: { addedRow = GadgetListBoxAddEntryText(listBoxPlayers,TheGameText->fetch("GUI:EasyAI"),playerColor,-1, 1); break; } case SLOT_MED_AI: { addedRow = GadgetListBoxAddEntryText(listBoxPlayers,TheGameText->fetch("GUI:MediumAI"),playerColor,-1, 1); break; } case SLOT_BRUTAL_AI: { addedRow = GadgetListBoxAddEntryText(listBoxPlayers,TheGameText->fetch("GUI:HardAI"),playerColor,-1, 1); break; } default: break; } } else if(slot->isHuman()) { addedRow = GadgetListBoxAddEntryText(listBoxPlayers, slot->getName(),playerColor,-1,1); } Int playerTemplate = slot->getPlayerTemplate(); if(playerTemplate == PLAYERTEMPLATE_OBSERVER) { GadgetListBoxAddEntryImage(listBoxPlayers, observerIcon,addedRow, 0, 22,25); } else if(playerTemplate < 0 || playerTemplate >= ThePlayerTemplateStore->getPlayerTemplateCount()) { ///< @todo: When we get art that shows player's side, then we'll actually draw the art instead of putting in text GadgetListBoxAddEntryImage(listBoxPlayers, randomIcon,addedRow, 0, 22,25); //GadgetListBoxAddEntryText(listBoxPlayers,TheGameText->fetch("GUI:???"),playerColor,addedRow, 0); } else { const PlayerTemplate *fact = ThePlayerTemplateStore->getNthPlayerTemplate(playerTemplate); GadgetListBoxAddEntryImage(listBoxPlayers, fact->getSideIconImage(),addedRow, 0, 22,25); //GadgetListBoxAddEntryText(listBoxPlayers,fact->getDisplayName(),playerColor,addedRow, 0); } } } void HideGameInfoWindow(Bool hide) { if(!parent) return; parent->winHide(hide); } //------------------------------------------------------------------------------------------------- /** Initialize the GameInfoWindow */ //------------------------------------------------------------------------------------------------- void GameInfoWindowInit( WindowLayout *layout, void *userData ) { parentID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:ParentGameInfo" ); staticTextGameNameID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:StaticTextGameName" ); staticTextMapNameID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:StaticTextMapName" ); listBoxPlayersID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:ListBoxPlayers" ); winCratesID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:WinCrates" ); winSuperWeaponsID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:WinSuperWeapons" ); winFreeForAllID = TheNameKeyGenerator->nameToKey( "GameInfoWindow.wnd:WinFreeForAll" ); parent = TheWindowManager->winGetWindowFromId( NULL, parentID ); staticTextGameName = TheWindowManager->winGetWindowFromId( parent, staticTextGameNameID ); staticTextMapName = TheWindowManager->winGetWindowFromId( parent, staticTextMapNameID ); listBoxPlayers = TheWindowManager->winGetWindowFromId( parent, listBoxPlayersID ); winCrates = TheWindowManager->winGetWindowFromId( parent, winCratesID ); winSuperWeapons = TheWindowManager->winGetWindowFromId( parent, winSuperWeaponsID ); winFreeForAll = TheWindowManager->winGetWindowFromId( parent, winFreeForAllID ); GadgetStaticTextSetText(staticTextGameName,UnicodeString.TheEmptyString); GadgetStaticTextSetText(staticTextMapName,UnicodeString.TheEmptyString); GadgetListBoxReset(listBoxPlayers); } // end MapSelectMenuInit //------------------------------------------------------------------------------------------------- /** GameInfo window system callback */ //------------------------------------------------------------------------------------------------- WindowMsgHandledType GameInfoWindowSystem( GameWindow *window, UnsignedInt msg, WindowMsgData mData1, WindowMsgData mData2 ) { switch( msg ) { // might use these later // GameWindow *control = (GameWindow *)mData1; // Int controlID = control->winGetWindowId(); // -------------------------------------------------------------------------------------------- case GWM_CREATE: { break; } // end create //--------------------------------------------------------------------------------------------- case GWM_DESTROY: { break; } // end case // -------------------------------------------------------------------------------------------- case GWM_INPUT_FOCUS: { // if we're givin the opportunity to take the keyboard focus we must say we want it if( mData1 == TRUE ) *(Bool *)mData2 = TRUE; return MSG_HANDLED; } // end input //--------------------------------------------------------------------------------------------- default: return MSG_IGNORED; } // end switch return MSG_HANDLED; } // end MapSelectMenuSystem