| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- /*
- ** Command & Conquer Generals Zero Hour(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) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: Credits.cpp /////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- //
- // Electronic Arts Pacific.
- //
- // Confidential Information
- // Copyright (C) 2002 - All Rights Reserved
- //
- //-----------------------------------------------------------------------------
- //
- // created: Dec 2002
- //
- // Filename: Credits.cpp
- //
- // author: Chris Huybregts
- //
- // purpose: This is where all the credit texts is going to be held.
- //
- //-----------------------------------------------------------------------------
- ///////////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
- //-----------------------------------------------------------------------------
- // USER INCLUDES //////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- #include "Common/INI.h"
- #include "GameClient/Credits.h"
- #include "GameClient/DisplayStringManager.h"
- #include "GameClient/Display.h"
- #include "GameClient/GameText.h"
- #include "GameClient/GlobalLanguage.h"
- #ifdef _INTERNAL
- // for occasional debugging...
- //#pragma optimize("", off)
- //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
- #endif
- //-----------------------------------------------------------------------------
- // DEFINES ////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- CreditsManager *TheCredits = NULL;
- const FieldParse CreditsManager::m_creditsFieldParseTable[] =
- {
- { "ScrollRate", INI::parseInt, NULL, offsetof( CreditsManager, m_scrollRate ) },
- { "ScrollRateEveryFrames", INI::parseInt, NULL, offsetof( CreditsManager, m_scrollRatePerFrames ) },
- { "ScrollDown", INI::parseBool, NULL, offsetof( CreditsManager, m_scrollDown ) },
- { "TitleColor", INI::parseColorInt, NULL, offsetof( CreditsManager, m_titleColor ) },
- { "MinorTitleColor", INI::parseColorInt, NULL, offsetof( CreditsManager, m_positionColor ) },
- { "NormalColor", INI::parseColorInt, NULL, offsetof( CreditsManager, m_normalColor ) },
- { "Style", INI::parseLookupList, CreditStyleNames, offsetof( CreditsManager, m_currentStyle ) },
- { "Blank", CreditsManager::parseBlank, NULL, NULL },
- { "Text", CreditsManager::parseText, NULL, NULL },
- { NULL, NULL, NULL, 0 } // keep this last
- };
- //-----------------------------------------------------------------------------
- // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- void INI::parseCredits( INI *ini )
- {
- // find existing item if present
- DEBUG_ASSERTCRASH( TheCredits, ("parseCredits: TheCredits has not been ininialized yet.\n") );
- if( !TheCredits )
- return;
- // parse the ini definition
- ini->initFromINI( TheCredits, TheCredits->getFieldParse() );
- } // end parseCommandButtonDefinition
- CreditsLine::CreditsLine()
- {
- m_useSecond = FALSE;
- m_done = FALSE;
- m_style = CREDIT_STYLE_BLANK;
- m_displayString = NULL;
- m_secondDisplayString = NULL;
- }
- CreditsLine::~CreditsLine()
- {
- if(m_displayString)
- TheDisplayStringManager->freeDisplayString(m_displayString);
- if(m_secondDisplayString)
- TheDisplayStringManager->freeDisplayString(m_secondDisplayString);
-
- m_displayString = NULL;
- m_secondDisplayString = NULL;
- }
- CreditsManager::CreditsManager(void)
- {
- m_scrollRate = 1; // in pixels
- m_scrollRatePerFrames = 1;
- m_scrollDown = TRUE; // if TRUE text will come from the top to the bottom if False, it will go from the bottom up
- m_framesSinceStarted = 0;
- m_titleColor = m_positionColor = m_normalColor = GameMakeColor(255,255,255,255);
-
- m_currentStyle = CREDIT_STYLE_NORMAL;
- m_isFinished = FALSE;
- m_normalFontHeight = 10;
- }
- CreditsManager::~CreditsManager(void)
- {
- m_displayedCreditLineList.clear();
- CreditsLineList::iterator it =m_creditLineList.begin();
- while (it != m_creditLineList.end())
- {
- CreditsLine *cLine = *it;
- delete cLine;
- it = m_creditLineList.erase(it);
- }
- }
- void CreditsManager::init(void )
- {
- m_isFinished = FALSE;
- m_creditLineListIt = m_creditLineList.begin();
- m_framesSinceStarted = 0;
- }
- void CreditsManager::load(void )
- {
- INI ini;
- // Read from INI all the ControlBarSchemes
- ini.load( AsciiString( "Data\\INI\\Credits.ini" ), INI_LOAD_OVERWRITE, NULL );
- if(m_scrollRatePerFrames <=0)
- m_scrollRatePerFrames = 1;
- if(m_scrollRate <=0)
- m_scrollRate = 1;
-
- GameFont *font = TheFontLibrary->getFont(TheGlobalLanguageData->m_creditsNormalFont.name,
- TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size),
- TheGlobalLanguageData->m_creditsNormalFont.bold);
- m_normalFontHeight = font->height;
- }
- void CreditsManager::reset( void )
- {
- m_displayedCreditLineList.clear();
- m_isFinished = FALSE;
- m_creditLineListIt = m_creditLineList.begin();
- m_framesSinceStarted = 0;
- }
- void CreditsManager::update( void )
- {
- if(m_isFinished)
- return;
- m_framesSinceStarted++;
-
- if(m_framesSinceStarted%m_scrollRatePerFrames != 0)
- return;
-
- Int y = 0;
- Int yTest = 0;
- Int lastHeight = 0;
- Int start = m_scrollDown? 0:TheDisplay->getHeight();
- Int end =m_scrollDown? TheDisplay->getHeight():0;
- Int offsetStartMultiplyer = m_scrollDown? -1:0; // if we're scrolling from the top, we need to subtract the height
- Int offsetEndMultiplyer = m_scrollDown? 0:1;
- Int directionMultiplyer = m_scrollDown? 1:-1;
- CreditsLineList::iterator drawIt = m_displayedCreditLineList.begin();
- while (drawIt != m_displayedCreditLineList.end())
- {
- CreditsLine *cLine = *drawIt;
- y = cLine->m_pos.y = cLine->m_pos.y + (m_scrollRate * directionMultiplyer);
- lastHeight = cLine->m_height;
- yTest = y + ((lastHeight + CREDIT_SPACE_OFFSET) * offsetEndMultiplyer);
- if(((m_scrollDown && (yTest > end)) || (!m_scrollDown && (yTest < end))))
- {
- TheDisplayStringManager->freeDisplayString(cLine->m_displayString);
- TheDisplayStringManager->freeDisplayString(cLine->m_secondDisplayString);
- cLine->m_displayString = NULL;
- cLine->m_secondDisplayString = NULL;
- drawIt = m_displayedCreditLineList.erase(drawIt);
- }
- else
- drawIt++;
- }
-
- y= y + ((lastHeight + CREDIT_SPACE_OFFSET) * offsetStartMultiplyer);
-
- // is it time to add a new string?
- if(!((m_scrollDown && (yTest >= start)) || (!m_scrollDown && (yTest <= start))))
- return;
-
- if(m_displayedCreditLineList.size() == 0 && m_creditLineListIt == m_creditLineList.end())
- m_isFinished = TRUE;
-
- if(m_creditLineListIt == m_creditLineList.end())
- return;
- CreditsLine *cLine = *m_creditLineListIt;
- ICoord2D pos;
- switch (cLine->m_style)
- {
- case CREDIT_STYLE_TITLE:
- {
- cLine->m_color = m_titleColor;
-
- if(TheGlobalLanguageData&& !cLine->m_text.isEmpty())
- {
- DisplayString *ds = TheDisplayStringManager->newDisplayString();
- if(!ds)
- return;
- ds->setFont(TheFontLibrary->getFont(TheGlobalLanguageData->m_creditsTitleFont.name,
- TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsTitleFont.size),
- TheGlobalLanguageData->m_creditsTitleFont.bold));
- ds->setText(cLine->m_text);
- ds->getSize(&pos.x,&pos.y);
- cLine->m_height = pos.y;
- cLine->m_pos.x = TheDisplay->getWidth()/2 - pos.x/2 ;
- cLine->m_pos.y = start + (cLine->m_height * offsetStartMultiplyer);
- cLine->m_displayString = ds;
- }
- }
- break;
- case CREDIT_STYLE_POSITION:
- {
- cLine->m_color = m_positionColor;
-
- if(TheGlobalLanguageData && !cLine->m_text.isEmpty())
- {
- DisplayString *ds = TheDisplayStringManager->newDisplayString();
- if(!ds)
- return;
- ds->setFont(TheFontLibrary->getFont(TheGlobalLanguageData->m_creditsPositionFont.name,
- TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsPositionFont.size),
- TheGlobalLanguageData->m_creditsPositionFont.bold));
- ds->setText(cLine->m_text);
- ds->getSize(&pos.x,&pos.y);
- cLine->m_height = pos.y;
- cLine->m_pos.x = TheDisplay->getWidth()/2 - pos.x/2 ;
- cLine->m_pos.y = start + (cLine->m_height * offsetStartMultiplyer);
- cLine->m_displayString = ds;
- }
- }
- break;
- case CREDIT_STYLE_NORMAL:
- {
- cLine->m_color = m_normalColor;
-
- if(TheGlobalLanguageData && !cLine->m_text.isEmpty())
- {
- DisplayString *ds = TheDisplayStringManager->newDisplayString();
- if(!ds)
- return;
- ds->setFont(TheFontLibrary->getFont(TheGlobalLanguageData->m_creditsNormalFont.name,
- TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size),
- TheGlobalLanguageData->m_creditsNormalFont.bold));
- ds->setText(cLine->m_text);
- ds->getSize(&pos.x,&pos.y);
- cLine->m_height = pos.y;
- cLine->m_pos.x = TheDisplay->getWidth()/2 - pos.x/2 ;
- cLine->m_pos.y = start + (cLine->m_height * offsetStartMultiplyer);
- cLine->m_displayString = ds;
- }
- }
- break;
- case CREDIT_STYLE_COLUMN:
- {
- cLine->m_color = m_normalColor;
-
- if(TheGlobalLanguageData && !cLine->m_text.isEmpty())
- {
- DisplayString *ds = TheDisplayStringManager->newDisplayString();
- if(!ds)
- return;
- ds->setFont(TheFontLibrary->getFont(TheGlobalLanguageData->m_creditsNormalFont.name,
- TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size),
- TheGlobalLanguageData->m_creditsNormalFont.bold));
- ds->setText(cLine->m_text);
- ds->getSize(&pos.x,&pos.y);
- cLine->m_height = pos.y;
- cLine->m_pos.x = TheDisplay->getWidth()/2 - pos.x/2 ;
- cLine->m_pos.y = start + (cLine->m_height * offsetStartMultiplyer);
- cLine->m_displayString = ds;
- }
- if(TheGlobalLanguageData && !cLine->m_secondText.isEmpty())
- {
- DisplayString *ds = TheDisplayStringManager->newDisplayString();
- if(!ds)
- return;
- ds->setFont(TheFontLibrary->getFont(TheGlobalLanguageData->m_creditsNormalFont.name,
- TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size),
- TheGlobalLanguageData->m_creditsNormalFont.bold));
- ds->setText(cLine->m_secondText);
- ds->getSize(&pos.x,&pos.y);
- cLine->m_height = pos.y;
- cLine->m_pos.x = TheDisplay->getWidth()/2 - pos.x/2 ;
- cLine->m_pos.y = start + (cLine->m_height * offsetStartMultiplyer);
- cLine->m_secondDisplayString = ds;
-
- }
- }
- break;
- case CREDIT_STYLE_BLANK:
- {
- cLine->m_height = m_normalFontHeight;
- cLine->m_pos.y = start + (cLine->m_height * offsetStartMultiplyer);
- }
- break;
- }
- m_displayedCreditLineList.push_back(cLine);
- if(m_creditLineListIt != m_creditLineList.end())
- m_creditLineListIt++;
-
- }
- void CreditsManager::draw( void )
- {
- CreditsLineList::iterator drawIt = m_displayedCreditLineList.begin();
- while (drawIt != m_displayedCreditLineList.end())
- {
- CreditsLine *cLine = *drawIt;
- Int heightChunk = TheDisplay->getHeight()/3;
- Real perc = 0.0f;
- if(cLine->m_pos.y < heightChunk || cLine->m_pos.y > heightChunk * 2)
- {
- // adjust the color
- if( cLine->m_pos.y < 0 || cLine->m_pos.y > TheDisplay->getHeight())
- perc = 0.0f;
- else if( cLine->m_pos.y < heightChunk)
- perc = INT_TO_REAL(cLine->m_pos.y) / heightChunk;
- else
- perc = 1 - INT_TO_REAL(cLine->m_pos.y - 2*heightChunk) / heightChunk;
- }
- else
- perc = 1.0f;
- UnsignedByte r,g,b,a;
- GameGetColorComponents(cLine->m_color, &r, &g, &b, &a);
- Int color = GameMakeColor( r,g,b, a * perc);
- Int bColor= GameMakeColor( 0,0,0, a * perc);
- switch (cLine->m_style) {
- case CREDIT_STYLE_TITLE:
- case CREDIT_STYLE_POSITION:
- case CREDIT_STYLE_NORMAL:
- {
- if(cLine->m_displayString)
- cLine->m_displayString->draw(cLine->m_pos.x,cLine->m_pos.y,color, bColor, 1,1 );
- }
- break;
- case CREDIT_STYLE_COLUMN:
- {
- Int chunk = TheDisplay->getWidth()/3;
- ICoord2D pos;
- if(cLine->m_displayString)
- {
- cLine->m_displayString->getSize(&pos.x, &pos.y);
- cLine->m_displayString->draw(chunk - (pos.x/2),cLine->m_pos.y,color, bColor, 1,1 );
- }
- if(cLine->m_secondDisplayString)
- {
- cLine->m_secondDisplayString->getSize(&pos.x, &pos.y);
- cLine->m_secondDisplayString->draw(2*chunk - (pos.x/2),cLine->m_pos.y,color, bColor, 1,1 );
- }
- }
- break;
- }
- drawIt++;
- }
- }
- void CreditsManager::addBlank( void )
- {
- CreditsLine *cLine = new CreditsLine;
- cLine->m_style = CREDIT_STYLE_BLANK;
- m_creditLineList.push_back(cLine);
- }
- void CreditsManager::parseBlank( INI* ini, void *instance, void *store, const void *userData )
- {
- CreditsManager *cManager = (CreditsManager *)instance;
- cManager->addBlank();
- }
- void CreditsManager::parseText( INI* ini, void *instance, void *store, const void *userData )
- {
-
- AsciiString asciiString = ini->getNextQuotedAsciiString();
- CreditsManager *cManager = (CreditsManager *)instance;
- cManager->addText(asciiString);
- }
- void CreditsManager::addText( AsciiString text )
- {
- CreditsLine *cLine = new CreditsLine;
- switch (m_currentStyle)
- {
- case CREDIT_STYLE_TITLE:
- case CREDIT_STYLE_POSITION:
- case CREDIT_STYLE_NORMAL:
- {
- cLine->m_text = getUnicodeString(text);
- cLine->m_style = m_currentStyle;
- m_creditLineList.push_back(cLine);
- }
- break;
- case CREDIT_STYLE_COLUMN:
- {
- CreditsLineList::reverse_iterator rIt = m_creditLineList.rbegin();
- CreditsLine *rcLine = *rIt;
- if(rIt == m_creditLineList.rend() || rcLine->m_style != CREDIT_STYLE_COLUMN
- || (rcLine->m_style == CREDIT_STYLE_COLUMN && rcLine->m_done == TRUE))
- {
- cLine->m_text = getUnicodeString(text);
- cLine->m_style = CREDIT_STYLE_COLUMN;
- cLine->m_useSecond = TRUE;
- m_creditLineList.push_back(cLine);
- }
- else
- {
- rcLine->m_secondText = getUnicodeString(text);
- rcLine->m_done = TRUE;
- delete cLine;
- }
- }
- break;
- default:
- DEBUG_ASSERTCRASH( FALSE, ("CreditsManager::addText we tried to add a credit text with the wrong style before it. Style is %d\n", m_currentStyle) );
- delete cLine;
- }
- }
- //-----------------------------------------------------------------------------
- // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------------
- UnicodeString CreditsManager::getUnicodeString(AsciiString str)
- {
- UnicodeString uStr;
- if(str.compare("<BLANK>") == 0)
- return UnicodeString::TheEmptyString;
- if(str.find(':'))
- uStr = TheGameText->fetch(str);
- else
- uStr.translate(str);
- return uStr;
- }
|