/* ** 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: W3DDisplayStringManager.cpp ////////////////////////////////////////////////////////////// // Created: Colin Day, July 2001 // Desc: Display string Manager for W3D /////////////////////////////////////////////////////////////////////////////////////////////////// #include #include "Common/Debug.h" #include "GameClient/GameClient.h" #include "GameClient/GameText.h" #include "GameClient/DisplayString.h" #include "GameClient/DrawGroupInfo.h" #include "GameClient/GlobalLanguage.h" #include "W3DDevice/GameClient/W3DDisplayStringManager.h" /////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------------------------- W3DDisplayStringManager::W3DDisplayStringManager( void ) { for (Int i = 0; i < 10; ++i) { m_groupNumeralStrings[i] = NULL; } m_formationLetterDisplayString = NULL; } //------------------------------------------------------------------------------------------------- W3DDisplayStringManager::~W3DDisplayStringManager( void ) { for (Int i = 0; i < 10; ++i) { if (m_groupNumeralStrings[i]) freeDisplayString(m_groupNumeralStrings[i]); m_groupNumeralStrings[i] = NULL; } if (m_formationLetterDisplayString) freeDisplayString( m_formationLetterDisplayString ); m_formationLetterDisplayString = NULL; } //------------------------------------------------------------------------------------------------- void W3DDisplayStringManager::postProcessLoad( void ) { // Get the font. GameFont *font = TheFontLibrary->getFont( TheDrawGroupInfo->m_fontName, TheDrawGroupInfo->m_fontSize, TheDrawGroupInfo->m_fontIsBold ); for (Int i = 0; i < 10; ++i) { m_groupNumeralStrings[i] = newDisplayString(); m_groupNumeralStrings[i]->setFont(font); AsciiString displayNumber; displayNumber.format("NUMBER:%d", i); m_groupNumeralStrings[i]->setText(TheGameText->fetch(displayNumber)); } m_formationLetterDisplayString = newDisplayString(); m_formationLetterDisplayString->setFont(font); AsciiString displayLetter; displayLetter.format("LABEL:FORMATION"); m_formationLetterDisplayString->setText(TheGameText->fetch(displayLetter)); } //------------------------------------------------------------------------------------------------- /** Allocate a new display string and tie it to the master list so we * can keep track of it */ //------------------------------------------------------------------------------------------------- DisplayString *W3DDisplayStringManager::newDisplayString( void ) { DisplayString *newString = newInstance(W3DDisplayString); // sanity if( newString == NULL ) { DEBUG_LOG(( "newDisplayString: Could not allcoate new W3D display string\n" )); assert( 0 ); return NULL; } // end if // assign a default font if (TheGlobalLanguageData && TheGlobalLanguageData->m_defaultDisplayStringFont.name.isNotEmpty()) { newString->setFont(TheFontLibrary->getFont( TheGlobalLanguageData->m_defaultDisplayStringFont.name, TheGlobalLanguageData->m_defaultDisplayStringFont.size, TheGlobalLanguageData->m_defaultDisplayStringFont.bold) ); } else newString->setFont( TheFontLibrary->getFont( AsciiString("Times New Roman"), 12, FALSE ) ); // link string to list link( newString ); // return our new string return newString; } // end newDisplayString //------------------------------------------------------------------------------------------------- /** Remove a display string from the master list and delete the data */ //------------------------------------------------------------------------------------------------- void W3DDisplayStringManager::freeDisplayString( DisplayString *string ) { // sanity if( string == NULL ) return; // unlink unLink( string ); // if the string happens to fall where our current checkpoint was, set the checkpoint to null if ( m_currentCheckpoint == string) { m_currentCheckpoint = NULL; } // free data string->deleteInstance(); } // end freeDisplayString //------------------------------------------------------------------------------------------------- /** Update method for our display string Manager ... if it's been too * long since the last time a string has been rendered, we will free * the rendering resources of the string, if it needs to render again * the DisplayString will have to rebuild the rendering data before * the draw will work */ //------------------------------------------------------------------------------------------------- void W3DDisplayStringManager::update( void ) { // call base in case we add something later DisplayStringManager::update(); W3DDisplayString *string = static_cast(m_stringList); // if the m_currentCheckpoint is valid, use it for the starting point for the search if (m_currentCheckpoint) { string = static_cast(m_currentCheckpoint); } UnsignedInt currFrame = TheGameClient->getFrame(); const UnsignedInt w3dCleanupTime = 60; /** any string not rendered after this many frames will have its render resources freed */ int numStrings = 10; // looping through all the strings eats up a lot of ambient time. Instead, // loop through 10 (arbitrarily chosen) or till the end is hit. while ( numStrings-- && string) { // // has this string "expired" in terms of using resources, a string // with a resource frame of zero isn't using any resources at all // if( string->m_lastResourceFrame != 0 && currFrame - string->m_lastResourceFrame > w3dCleanupTime ) { // free the resources string->m_textRenderer.Reset(); string->m_textRendererHotKey.Reset(); // // mark data in the string as changed so that if it needs to // be drawn again it will know to reconstruct the render data // string->m_textChanged = TRUE; // // set the last resource frame to zero, this allows us to ignore it // in future cleanup passes of this update routine // string->m_lastResourceFrame = 0; } // end if // move to next string string = static_cast(string->next()); } // end while // reset the starting point for our next search m_currentCheckpoint = string; } // end update //------------------------------------------------------------------------------------------------- DisplayString *W3DDisplayStringManager::getGroupNumeralString( Int numeral ) { if (numeral < 0 || numeral > 9) { DEBUG_CRASH(("Numeral '%d' out of range.\n", numeral)); return m_groupNumeralStrings[0]; } return m_groupNumeralStrings[numeral]; }