| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468 |
- /*
- ** 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/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Commando/textdisplay.cpp $*
- * *
- * $Author:: Steve_t $*
- * *
- * $Modtime:: 1/02/02 2:27a $*
- * *
- * $Revision:: 55 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "textdisplay.h"
- #include "font3d.h"
- #include "assets.h"
- #include "render2D.h"
- #include "timemgr.h"
- #include "_globals.h"
- #include "registry.h"
- #include "wwprofile.h"
- #include "combat.h"
- #include "ccamera.h"
- #include "render2Dsentence.h"
- #include "wwmemlog.h"
- #include "consolemode.h"
- /*
- ** TextDisplayLine
- */
- TextDisplayLine::TextDisplayLine( const WideStringClass & text, unsigned long color ) :
- Time( 0 ),
- LineCount( 0 ),
- Text( text ),
- Color( color )
- {
- for( const WCHAR * ch = text; *ch; ch++ ) {
- if ( *ch == (WCHAR)'\n' ) {
- LineCount++;
- }
- }
- }
- /*
- ** TextDisplayGameMode
- */
- TextDisplayGameModeClass * TextDisplayGameModeClass::Instance = NULL;
- void TextDisplayGameModeClass::Init()
- {
- if (!ConsoleBox.Is_Exclusive()) {
- // Build Fonts
- WWASSERT(WW3DAssetManager::Get_Instance() != NULL);
- Font = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( "FONT8x8.TGA" );
- WWASSERT(Font != NULL);
- SET_REF_OWNER( Font );
- MonoFont = WW3DAssetManager::Get_Instance()->Get_Font3DInstance( "FONT8x8.TGA" );
- WWASSERT(MonoFont != NULL);
- SET_REF_OWNER( MonoFont );
- MonoFont->Set_Mono_Spaced();
- // Update Instance
- WWASSERT( TextDisplayGameModeClass::Instance == NULL );
- TextDisplayGameModeClass::Instance = this;
- DisplayVisWarning = false;
- MaxScrollLines = 30;
- ScrollLinesPersistTime = 10;
- Load_Registry_Keys();
- Display = new Render2DTextClass(Font);
- Display->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
- VerboseDisplay = new Render2DTextClass(Font);
- VerboseDisplay->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
- StatisticsDisplay = new Render2DTextClass(MonoFont);
- StatisticsDisplay->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
- RendererLines.Reset_Active();
- RendererColors.Reset_Active();
- TextChanged=true;
- VerboseTextChanged=true;
- DisplayY=0.0f;
- }
- return ;
- }
- void TextDisplayGameModeClass::Shutdown()
- {
- if (!ConsoleBox.Is_Exclusive()) {
- Save_Registry_Keys();
- Flush();
- delete StatisticsDisplay;
- StatisticsDisplay=NULL;
- delete VerboseDisplay;
- VerboseDisplay=NULL;
- delete Display;
- Display=NULL;
- REF_PTR_RELEASE( Font );
- REF_PTR_RELEASE( MonoFont );
- // Update Instance
- WWASSERT( TextDisplayGameModeClass::Instance == this );
- TextDisplayGameModeClass::Instance = NULL;
- }
- }
- /*
- **
- */
- void TextDisplayGameModeClass::Load_Registry_Keys(void)
- {
- RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
- WWASSERT( registry );
- if ( registry->Is_Valid() ) {
- MaxScrollLines = registry->Get_Int( "MaxScrollLines", MaxScrollLines );
- ScrollLinesPersistTime = registry->Get_Float( "ScrollLinesPersistTime", ScrollLinesPersistTime );
- }
- delete registry;
- }
- void TextDisplayGameModeClass::Save_Registry_Keys(void)
- {
- RegistryClass * registry = new RegistryClass( APPLICATION_SUB_KEY_NAME_OPTIONS );
- WWASSERT( registry );
- if ( registry->Is_Valid() ) {
- registry->Set_Int( "MaxScrollLines", MaxScrollLines );
- registry->Set_Float( "ScrollLinesPersistTime", ScrollLinesPersistTime );
- }
- delete registry;
- }
- /*
- **
- */
- void TextDisplayGameModeClass::Think()
- {
- WWPROFILE( "TextDisplay Think" );
- if (Font == NULL) {
- return;
- }
- // Update time on all scroll lines
- SLNode<TextDisplayLine> *linenode;
- for ( linenode = ScrollLines.Head(); linenode; linenode = linenode->Next() ) {
- TextDisplayLine *line = linenode->Data();
- line->Update_Time( TimeManager::Get_Frame_Seconds() );
- }
- // never have more than 2 over the max number
- while ( ScrollLines.Get_Count() && (Count_Scroll_Lines() >= MaxScrollLines + 2) ) {
- delete ScrollLines.Remove_Head();
- }
- // if there are lines to remove by count or time
- if ( ScrollLines.Get_Count() &&
- ((ScrollLines.Head()->Data()->Update_Time(0) > ScrollLinesPersistTime) ||
- (Count_Scroll_Lines() > MaxScrollLines) ) ) {
- // bump scroll position
- float char_height = Font->Char_Height();
- VerticalScroll += TimeManager::Get_Frame_Seconds() * char_height * 4;
- if ( VerticalScroll >= char_height ) {
- // top line is hidden, remove it
- VerticalScroll -= char_height;
- int lines = Count_Scroll_Lines();
- while ( ScrollLines.Get_Count() && (Count_Scroll_Lines() >= lines) ) {
- delete ScrollLines.Remove_Head();
- }
- }
- }
- // if no more need to be removed, clear scroll
- if ( ScrollLines.Get_Count() &&
- ((ScrollLines.Head()->Data()->Update_Time(0) > ScrollLinesPersistTime) ||
- (Count_Scroll_Lines() > MaxScrollLines) ) ) {
- } else {
- VerticalScroll = 0;
- }
- }
- void TextDisplayGameModeClass::Render()
- {
- WWMEMLOG(MEM_GAMEDATA);
- WWPROFILE( "TextDisplay Render" );
- if (Font == NULL) {
- return;
- }
- // Verbose help first
- if (VerboseTextChanged) {
- VerboseTextChanged=false;
- VerboseDisplay->Reset();
- VerboseDisplay->Set_Location( Vector2( 0, 0 ) );
- VerboseDisplay->Draw_Text( VerboseHelpText, 0xFF00FFFF );
- }
- VerboseDisplay->Render();
- // Then statistics
- StatisticsDisplayManager::Render( StatisticsDisplay );
- // And then the rest of the text...
- bool changed=TextChanged;
- TextChanged=false;
- if ( DisplayVisWarning && StatisticsDisplayManager::Is_Current_Display( "fps" ) ) {
- changed=true;
- }
- // never have more than 2 over the max number
- while ( ScrollLines.Get_Count() && (Count_Scroll_Lines() >= MaxScrollLines + 2) ) {
- delete ScrollLines.Remove_Head();
- changed=true;
- }
- // Check if the text lines have changed
- SLNode<TextDisplayLine> *linenode;
- if (!changed) {
- int j=0;
- WWASSERT(RendererLines.Count()==RendererColors.Count());
- for ( linenode = ScrollLines.Head(); linenode; linenode = linenode->Next(), j++ ) {
- if (j>=RendererLines.Count()) {
- changed=true;
- break;
- }
- if (RendererColors[j]!=linenode->Data()->Color || RendererLines[j]!=linenode->Data()->Text) {
- changed=true;
- break;
- }
- }
- }
- float y=WWMath::Floor( -VerticalScroll );
- if (y==0.0f && DisplayY!=0.0f) changed=true;
- float delta=y-DisplayY;
- DisplayY=y;
- if (!changed) {
- if (delta!=0.0f) Display->Move(Vector2(0.0f,delta));
- Display->Render();
- return;
- }
- // Display
- Display->Reset();
- // Cache the lines that are rendered
- RendererLines.Reset_Active();
- RendererColors.Reset_Active();
- for ( linenode = ScrollLines.Head(); linenode; linenode = linenode->Next() ) {
- Display->Draw_Text( linenode->Data()->Text, linenode->Data()->Color );
- RendererLines.Add(linenode->Data()->Text);
- RendererColors.Add(linenode->Data()->Color);
- }
- Display->Draw_Text( InputText );
- Display->Draw_Text( HelpText );
- if ( DisplayVisWarning && StatisticsDisplayManager::Is_Current_Display( "fps" ) ) {
- Vector2 pos = (Render2DClass::Get_Screen_Resolution().Upper_Left() + Render2DClass::Get_Screen_Resolution().Lower_Left()) * 0.5f;
- Display->Set_Location( pos );
- Display->Draw_Text( "Vis Sector Not Found!", 0xFF0000FF );
- }
- Display->Render();
- }
- void TextDisplayGameModeClass::Flush( void )
- {
- while ( ScrollLines.Get_Count() ) {
- delete ScrollLines.Remove_Head();
- }
- }
- int TextDisplayGameModeClass::Count_Scroll_Lines( void )
- {
- int count = 0;
- SLNode<TextDisplayLine> *linenode;
- for ( linenode = ScrollLines.Head(); linenode; linenode = linenode->Next() ) {
- count += linenode->Data()->Get_Line_Count();
- }
- return count;
- }
- /*
- ** Printing
- */
- void TextDisplayGameModeClass::Print( const char * string, const Vector4 & color )
- {
- if (Font == NULL) {
- return;
- }
- unsigned long col=(unsigned(color[0]*255.0f)<<24)|(unsigned(color[1]*255.0f)<<16)|(unsigned(color[2]*255.0f)<<8)|(unsigned(color[3]*255.0f));
- WideStringClass wide_string;
- wide_string.Convert_From( string );
- TextDisplayLine * line = new TextDisplayLine( wide_string, col );
- ScrollLines.Add_Tail( line );
- }
- void TextDisplayGameModeClass::Print( const WideStringClass & string, const Vector4 & color )
- {
- if (Font == NULL) {
- return;
- }
- unsigned long col=(unsigned(color[0]*255.0f)<<24)|(unsigned(color[1]*255.0f)<<16)|(unsigned(color[2]*255.0f)<<8)|(unsigned(color[3]*255.0f));
- TextDisplayLine * line = new TextDisplayLine( string, col );
- ScrollLines.Add_Tail( line );
- }
- void TextDisplayGameModeClass::Print( const char * string, const Vector3 & color )
- {
- if (Font == NULL) {
- return;
- }
- //TSS unsigned long col=(unsigned(color[0]*255.0f)<<24)|(unsigned(color[1]*255.0f)<<16)|(unsigned(color[2]*255.0f)<<8)|0xff;
- unsigned long col=(unsigned(color[0]*255.0f)<<16)|(unsigned(color[1]*255.0f)<<8)|(unsigned(color[2]*255.0f))|0xFF000000;
- WideStringClass wide_string;
- wide_string.Convert_From( string );
- TextDisplayLine * line = new TextDisplayLine( wide_string, col );
- ScrollLines.Add_Tail( line );
- }
- void TextDisplayGameModeClass::Print( const WideStringClass & string, const Vector3 & color )
- {
- if (Font == NULL) {
- return;
- }
- //TSS unsigned long col=(unsigned(color[0]*255.0f)<<24)|(unsigned(color[1]*255.0f)<<16)|(unsigned(color[2]*255.0f)<<8)|0xff;
- unsigned long col=(unsigned(color[0]*255.0f)<<16)|(unsigned(color[1]*255.0f)<<8)|(unsigned(color[2]*255.0f))|0xFF000000;
- TextDisplayLine * line = new TextDisplayLine( string, col );
- ScrollLines.Add_Tail( line );
- }
- void TextDisplayGameModeClass::Print_System( const char * format, ... )
- {
- va_list arg_list;
- va_start (arg_list, format);
- StringClass string;
- string.Format_Args( format, arg_list );
- va_end (arg_list);
- Print( string, Vector4( 1,1,0,1 ) );
- }
- void TextDisplayGameModeClass::Print_System( const WideStringClass & string )
- {
- Print( string, Vector4( 1,1,0,1 ) );
- }
- void TextDisplayGameModeClass::Print_Informational( const char * format, ... )
- {
- va_list arg_list;
- va_start (arg_list, format);
- StringClass string;
- string.Format_Args( format, arg_list );
- va_end (arg_list);
- Print( string, Vector4( 0.7f,0.7f,0.7f,1.0f ) );
- }
- void TextDisplayGameModeClass::Print_Informational( const WideStringClass & string )
- {
- Print( string, Vector4( 0.7f,0.7f,0.7f,1.0f ) );
- }
- /*
- ** TextDebugDisplayHandler
- */
- void TextDebugDisplayHandlerClass::Display_Text( const char * string, const Vector4 & color )
- {
- if (Get_Text_Display() != NULL) {
- Get_Text_Display()->Print( string, color );
- }
- }
- void TextDebugDisplayHandlerClass::Display_Text( const WideStringClass & string, const Vector4 & color )
- {
- if (Get_Text_Display() != NULL) {
- Get_Text_Display()->Print( string, color );
- }
- }
- /*
- ** StatisticsDisplay
- */
- static float _StatsScrollOffset = 0;
- static StringClass _StatsTitle;
- static StringClass _StatsText;
- static unsigned long _StatsColor = 0xFFFFFFFF;
- static Vector2 _StatsLocation( 0,0 );
- void StatisticsDisplayManager::Render(Render2DTextClass * renderer)
- {
- if (WWDEBUG_TRIGGER(WWDEBUG_TRIGGER_GENERIC0)) {
- _StatsScrollOffset -= 32.0f;
- }
- if (WWDEBUG_TRIGGER(WWDEBUG_TRIGGER_GENERIC1)) {
- _StatsScrollOffset += 32.0f;
- }
- renderer->Reset();
- renderer->Set_Location( _StatsLocation );
- renderer->Draw_Text( _StatsText, _StatsColor );
- renderer->Render();
- }
- void StatisticsDisplayManager::Set_Display( const char * title )
- {
- _StatsScrollOffset = 0;
- _StatsTitle = title;
- _StatsText = "";
- }
- bool StatisticsDisplayManager::Is_Current_Display( const char* title) // Returns true if "title" is currently active
- {
- return !stricmp( _StatsTitle, title );
- }
- void StatisticsDisplayManager::Set_Stat( const char * title, const char * text, unsigned long color, const Vector2& location )
- {
- if ( Is_Current_Display( title ) ) {
- _StatsText = text;
- _StatsColor = color;
- if ( location.Y == -240 ) {
- // Handle default case
- Vector2 pos = (Render2DClass::Get_Screen_Resolution().Upper_Left() + Render2DClass::Get_Screen_Resolution().Upper_Right()) * 0.5f;
- _StatsLocation = pos;
- } else {
- _StatsLocation = location;
- }
- }
- }
|