2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code 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 .
Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2021-07-29 13:42:02 +00:00
# pragma hdrstop
2012-11-26 18:58:24 +00:00
# include "ConsoleHistory.h"
# include "../renderer/ResolutionScale.h"
# include "Common_local.h"
2020-03-29 15:12:11 +00:00
# include "../imgui/BFGimgui.h"
2012-11-26 18:58:24 +00:00
2023-03-10 18:25:56 +00:00
# include <sys/DeviceManager.h>
extern DeviceManager * deviceManager ;
2022-09-23 07:39:48 +00:00
2012-11-26 18:58:24 +00:00
# define CON_TEXTSIZE 0x30000
# define NUM_CON_TIMES 4
# define CONSOLE_FIRSTREPEAT 200
# define CONSOLE_REPEAT 100
# define COMMAND_HISTORY 64
2012-11-28 15:47:07 +00:00
struct overlayText_t
{
2012-11-26 18:58:24 +00:00
idStr text ;
justify_t justify ;
int time ;
} ;
// the console will query the cvar and command systems for
// command completion information
2012-11-28 15:47:07 +00:00
class idConsoleLocal : public idConsole
{
2012-11-26 18:58:24 +00:00
public :
virtual void Init ( ) ;
virtual void Shutdown ( ) ;
2012-11-28 15:47:07 +00:00
virtual bool ProcessEvent ( const sysEvent_t * event , bool forceAccept ) ;
2012-11-26 18:58:24 +00:00
virtual bool Active ( ) ;
virtual void ClearNotifyLines ( ) ;
2013-09-29 11:03:32 +00:00
virtual void Open ( ) ;
2012-11-26 18:58:24 +00:00
virtual void Close ( ) ;
2012-11-28 15:47:07 +00:00
virtual void Print ( const char * text ) ;
2012-11-26 18:58:24 +00:00
virtual void Draw ( bool forceFullScreen ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
virtual void PrintOverlay ( idOverlayHandle & handle , justify_t justify , const char * text , . . . ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
virtual idDebugGraph * CreateGraph ( int numItems ) ;
virtual void DestroyGraph ( idDebugGraph * graph ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
void Dump ( const char * toFile ) ;
2012-11-26 18:58:24 +00:00
void Clear ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
private :
2013-09-21 12:12:42 +00:00
void Resize ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
void KeyDownEvent ( int key ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
void Linefeed ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
void PageUp ( ) ;
void PageDown ( ) ;
void Top ( ) ;
void Bottom ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
void DrawInput ( ) ;
void DrawNotify ( ) ;
void DrawSolidConsole ( float frac ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
void Scroll ( ) ;
void SetDisplayFraction ( float frac ) ;
void UpdateDisplayFraction ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
void DrawTextLeftAlign ( float x , float & y , const char * text , . . . ) ;
void DrawTextRightAlign ( float x , float & y , const char * text , . . . ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
float DrawFPS ( float y ) ;
float DrawMemoryUsage ( float y ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
void DrawOverlayText ( float & leftY , float & rightY , float & centerY ) ;
2012-11-26 18:58:24 +00:00
void DrawDebugGraphs ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
//============================
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// allow these constants to be adjusted for HMD
int LOCALSAFE_LEFT ;
int LOCALSAFE_RIGHT ;
int LOCALSAFE_TOP ;
int LOCALSAFE_BOTTOM ;
int LOCALSAFE_WIDTH ;
int LOCALSAFE_HEIGHT ;
int LINE_WIDTH ;
int TOTAL_LINES ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
bool keyCatching ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
short text [ CON_TEXTSIZE ] ;
int current ; // line where next message will be printed
int x ; // offset in current line for next print
int display ; // bottom of console displays this line
int lastKeyEvent ; // time of last key event for scroll delay
int nextKeyEvent ; // keyboard repeat rate
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
float displayFrac ; // approaches finalFrac at con_speed
float finalFrac ; // 0.0 to 1.0 lines of console to display
int fracTime ; // time of last displayFrac update
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
int vislines ; // in scanlines
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
int times [ NUM_CON_TIMES ] ; // cls.realtime time the line was generated
2012-11-28 15:47:07 +00:00
// for transparent notify lines
2012-11-26 18:58:24 +00:00
idVec4 color ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idEditField historyEditLines [ COMMAND_HISTORY ] ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
int nextHistoryLine ; // the last line in the history buffer, not masked
int historyLine ; // the line being displayed from history buffer
2012-11-28 15:47:07 +00:00
// will be <= nextHistoryLine
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idEditField consoleField ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idList < overlayText_t > overlayText ;
2012-11-28 15:47:07 +00:00
idList < idDebugGraph * > debugGraphs ;
2019-11-11 19:27:44 +00:00
2013-09-21 12:12:42 +00:00
int lastVirtualScreenWidth ;
int lastVirtualScreenHeight ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
static idCVar con_speed ;
static idCVar con_notifyTime ;
static idCVar con_noPrint ;
} ;
static idConsoleLocal localConsole ;
2012-11-28 15:47:07 +00:00
idConsole * console = & localConsole ;
2012-11-26 18:58:24 +00:00
idCVar idConsoleLocal : : con_speed ( " con_speed " , " 3 " , CVAR_SYSTEM , " speed at which the console moves up and down " ) ;
idCVar idConsoleLocal : : con_notifyTime ( " con_notifyTime " , " 3 " , CVAR_SYSTEM , " time messages are displayed onscreen when console is pulled up " ) ;
# ifdef DEBUG
2019-11-11 19:27:44 +00:00
idCVar idConsoleLocal : : con_noPrint ( " con_noPrint " , " 0 " , CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT , " print on the console but not onscreen when console is pulled up " ) ;
2012-11-26 18:58:24 +00:00
# else
2019-11-11 19:27:44 +00:00
idCVar idConsoleLocal : : con_noPrint ( " con_noPrint " , " 1 " , CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT , " print on the console but not onscreen when console is pulled up " ) ;
2012-11-26 18:58:24 +00:00
# endif
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Misc stats
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawTextLeftAlign
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawTextLeftAlign ( float x , float & y , const char * text , . . . )
{
2012-11-26 18:58:24 +00:00
char string [ MAX_STRING_CHARS ] ;
va_list argptr ;
va_start ( argptr , text ) ;
idStr : : vsnPrintf ( string , sizeof ( string ) , text , argptr ) ;
va_end ( argptr ) ;
renderSystem - > DrawSmallStringExt ( x , y + 2 , string , colorWhite , true ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
}
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawTextRightAlign
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawTextRightAlign ( float x , float & y , const char * text , . . . )
{
2012-11-26 18:58:24 +00:00
char string [ MAX_STRING_CHARS ] ;
va_list argptr ;
va_start ( argptr , text ) ;
int i = idStr : : vsnPrintf ( string , sizeof ( string ) , text , argptr ) ;
va_end ( argptr ) ;
2023-06-20 16:24:24 +00:00
if ( i < 0 )
{
i = sizeof ( string ) - 1 ;
}
2012-11-26 18:58:24 +00:00
renderSystem - > DrawSmallStringExt ( x - i * SMALLCHAR_WIDTH , y + 2 , string , colorWhite , true ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
}
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawFPS
= = = = = = = = = = = = = = = = = =
*/
2022-04-23 14:34:22 +00:00
extern bool R_UseTemporalAA ( ) ;
2020-05-04 23:21:29 +00:00
# define FPS_FRAMES 6
# define FPS_FRAMES_HISTORY 90
2012-11-28 15:47:07 +00:00
float idConsoleLocal : : DrawFPS ( float y )
{
2022-11-18 15:47:29 +00:00
extern idCVar r_swapInterval ;
2021-09-28 07:58:48 +00:00
2020-05-04 15:22:51 +00:00
static float previousTimes [ FPS_FRAMES ] ;
2023-11-30 17:26:38 +00:00
static float previousCpuUsage [ FPS_FRAMES ] = { } ;
static float previousGpuUsage [ FPS_FRAMES ] = { } ;
2020-05-04 23:21:29 +00:00
static float previousTimesNormalized [ FPS_FRAMES_HISTORY ] ;
2023-11-30 17:26:38 +00:00
static int index = 0 ;
2012-11-26 18:58:24 +00:00
static int previous ;
2020-05-04 15:22:51 +00:00
static int valuesOffset = 0 ;
2019-11-11 19:27:44 +00:00
2020-05-04 23:21:29 +00:00
bool renderImGuiPerfWindow = ImGuiHook : : IsReadyToRender ( ) & & ( com_showFPS . GetInteger ( ) > 1 ) ;
2020-03-29 15:12:11 +00:00
2012-11-26 18:58:24 +00:00
// don't use serverTime, because that will be drifting to
// correct for internet lag changes, timescales, timedemos, etc
int t = Sys_Milliseconds ( ) ;
int frameTime = t - previous ;
previous = t ;
2019-11-11 19:27:44 +00:00
2020-03-29 15:12:11 +00:00
int fps = 0 ;
2023-11-30 17:26:38 +00:00
float cpuUsage = 0.0 ;
float gpuUsage = 0.0 ;
2020-03-29 15:12:11 +00:00
2020-05-04 15:22:51 +00:00
const float milliSecondsPerFrame = 1000.0f / com_engineHz_latched ;
2012-11-26 18:58:24 +00:00
previousTimes [ index % FPS_FRAMES ] = frameTime ;
2020-05-04 23:21:29 +00:00
previousTimesNormalized [ index % FPS_FRAMES_HISTORY ] = frameTime / milliSecondsPerFrame ;
valuesOffset = ( valuesOffset + 1 ) % FPS_FRAMES_HISTORY ;
2012-11-26 18:58:24 +00:00
index + + ;
2012-11-28 15:47:07 +00:00
if ( index > FPS_FRAMES )
{
2012-11-26 18:58:24 +00:00
// average multiple frames together to smooth changes out a bit
int total = 0 ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < FPS_FRAMES ; i + + )
{
2012-11-26 18:58:24 +00:00
total + = previousTimes [ i ] ;
2023-11-30 17:26:38 +00:00
cpuUsage + = previousCpuUsage [ i ] ;
gpuUsage + = previousGpuUsage [ i ] ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( ! total )
{
2012-11-26 18:58:24 +00:00
total = 1 ;
}
2020-03-29 15:12:11 +00:00
fps = 1000000 * FPS_FRAMES / total ;
2012-11-26 18:58:24 +00:00
fps = ( fps + 500 ) / 1000 ;
2023-11-30 17:26:38 +00:00
cpuUsage / = FPS_FRAMES ;
gpuUsage / = FPS_FRAMES ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
const char * s = va ( " %ifps " , fps ) ;
2012-11-26 18:58:24 +00:00
int w = strlen ( s ) * BIGCHAR_WIDTH ;
2019-11-11 19:27:44 +00:00
2020-05-04 23:21:29 +00:00
if ( com_showFPS . GetInteger ( ) = = 1 )
2020-03-29 15:12:11 +00:00
{
renderSystem - > DrawBigStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , s , colorWhite , true ) ;
}
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
y + = BIGCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2020-05-04 23:21:29 +00:00
// DG: "com_showFPS 1" means: show FPS only, like in classic doom3
if ( com_showFPS . GetInteger ( ) = = 1 )
2013-01-20 14:52:01 +00:00
{
return y ;
}
// DG end
2019-11-11 19:27:44 +00:00
2021-10-01 04:29:09 +00:00
// SRS - Shouldn't use these getters since they access and return int-sized variables measured in milliseconds
2021-10-08 18:51:08 +00:00
//const uint64 gameThreadTotalTime = commonLocal.GetGameThreadTotalTime();
2021-10-01 04:29:09 +00:00
//const uint64 gameThreadGameTime = commonLocal.GetGameThreadGameTime();
//const uint64 gameThreadRenderTime = commonLocal.GetGameThreadRenderTime();
const uint64 gameThreadTotalTime = commonLocal . mainFrameTiming . finishDrawTime - commonLocal . mainFrameTiming . startGameTime ;
const uint64 gameThreadGameTime = commonLocal . mainFrameTiming . finishGameTime - commonLocal . mainFrameTiming . startGameTime ;
const uint64 gameThreadRenderTime = commonLocal . mainFrameTiming . finishDrawTime - commonLocal . mainFrameTiming . finishGameTime ;
2020-03-29 16:19:03 +00:00
const uint64 rendererBackEndTime = commonLocal . GetRendererBackEndMicroseconds ( ) ;
const uint64 rendererShadowsTime = commonLocal . GetRendererShadowsMicroseconds ( ) ;
const uint64 rendererGPUTime = commonLocal . GetRendererGPUMicroseconds ( ) ;
2024-02-28 16:59:41 +00:00
const uint64 rendererGPUEarlyZTime = commonLocal . GetRendererGpuBeginDrawingMicroseconds ( ) + commonLocal . GetRendererGpuEarlyZMicroseconds ( ) + commonLocal . GetRendererGpuGeometryMicroseconds ( ) ;
2020-05-04 23:21:29 +00:00
const uint64 rendererGPU_SSAOTime = commonLocal . GetRendererGpuSSAOMicroseconds ( ) ;
const uint64 rendererGPU_SSRTime = commonLocal . GetRendererGpuSSRMicroseconds ( ) ;
const uint64 rendererGPUAmbientPassTime = commonLocal . GetRendererGpuAmbientPassMicroseconds ( ) ;
2022-04-23 14:34:22 +00:00
const uint64 rendererGPUShadowAtlasTime = commonLocal . GetRendererGpuShadowAtlasPassMicroseconds ( ) ;
2020-05-04 23:21:29 +00:00
const uint64 rendererGPUInteractionsTime = commonLocal . GetRendererGpuInteractionsMicroseconds ( ) ;
2024-02-28 16:59:41 +00:00
const uint64 rendererGPUShaderPassesTime = commonLocal . GetRendererGpuShaderPassMicroseconds ( ) + commonLocal . GetRendererGpuFogAllLightsMicroseconds ( ) + commonLocal . GetRendererGpuShaderPassPostMicroseconds ( ) + commonLocal . GetRendererGpuDrawGuiMicroseconds ( ) ;
const uint64 rendererGPU_TAATime = commonLocal . GetRendererGpuMotionVectorsMicroseconds ( ) + commonLocal . GetRendererGpuTAAMicroseconds ( ) ;
const uint64 rendererGPUToneMapPassTime = commonLocal . GetRendererGpuToneMapPassMicroseconds ( ) ;
const uint64 rendererGPUPostProcessingTime = commonLocal . GetRendererGpuPostProcessingMicroseconds ( ) + commonLocal . GetRendererGpuCrtPostProcessingMicroseconds ( ) ;
2021-09-27 21:56:45 +00:00
2022-11-18 15:47:29 +00:00
// SRS - Calculate max fps and max frame time based on glConfig.displayFrequency if vsync enabled and lower than engine Hz, otherwise use com_engineHz_latched
2023-02-22 20:11:13 +00:00
const int maxFPS = ( r_swapInterval . GetInteger ( ) > 0 & & glConfig . displayFrequency > 0 ? std : : min ( glConfig . displayFrequency , int ( com_engineHz_latched ) ) : com_engineHz_latched ) ;
2023-02-28 09:40:25 +00:00
const int maxTime = ( 1000.0 / maxFPS ) * 1050 ; // slight 5% tolerance offset to avoid flickering of the stats
2021-09-28 07:58:48 +00:00
2022-11-18 04:42:06 +00:00
// SRS - Frame idle and busy time calculations are based on direct frame-over-frame measurement relative to finishSyncTime
2023-02-22 20:11:13 +00:00
const int64 frameIdleTime = int64 ( commonLocal . mainFrameTiming . startGameTime ) - int64 ( commonLocal . mainFrameTiming . finishSyncTime ) ;
const int64 frameBusyTime = int64 ( commonLocal . frameTiming . finishSyncTime ) - int64 ( commonLocal . mainFrameTiming . startGameTime ) ;
2022-11-18 04:42:06 +00:00
2024-01-25 20:09:54 +00:00
// SRS - Frame sync time represents swap buffer synchronization + other frame time spent outside of game thread and renderer backend
const int64 gameThreadWaitTime = int64 ( commonLocal . mainFrameTiming . finishSyncTime_EndFrame ) - int64 ( commonLocal . mainFrameTiming . finishRenderTime ) ;
const int64 frameSyncTime = int64 ( commonLocal . frameTiming . finishSyncTime ) - int64 ( commonLocal . mainFrameTiming . startRenderTime + rendererBackEndTime ) - gameThreadWaitTime ;
2022-11-18 04:42:06 +00:00
// SRS - GPU idle time is simply the difference between measured frame-over-frame time and GPU busy time (directly from GPU timers)
2023-02-22 20:11:13 +00:00
const int64 rendererGPUIdleTime = frameBusyTime + frameIdleTime - rendererGPUTime ;
2019-11-11 19:27:44 +00:00
2024-01-25 20:09:54 +00:00
// SRS - Estimate CPU busy time measured from start of game thread until completion of game thread and renderer backend (including excess MoltenVK encoding time if applicable)
# if defined(__APPLE__) && defined( USE_MoltenVK )
const int64 rendererMvkEncodeTime = commonLocal . GetRendererMvkEncodeMicroseconds ( ) ;
const int64 rendererQueueSubmitTime = int64 ( commonLocal . mainFrameTiming . finishRenderTime - commonLocal . mainFrameTiming . startRenderTime ) - int64 ( rendererBackEndTime ) ;
const int64 rendererCPUBusyTime = int64 ( commonLocal . mainFrameTiming . finishSyncTime_EndFrame - commonLocal . mainFrameTiming . startGameTime ) + Min ( Max ( int64 ( 0 ) , rendererMvkEncodeTime - rendererQueueSubmitTime - gameThreadWaitTime ) , frameSyncTime - rendererQueueSubmitTime ) ;
# else
const int64 rendererCPUBusyTime = int64 ( commonLocal . mainFrameTiming . finishSyncTime_EndFrame - commonLocal . mainFrameTiming . startGameTime ) ;
# endif
2023-11-30 17:26:38 +00:00
// SRS - Save current CPU and GPU usage factors in ring buffer to calculate smoothed averages for future frames
2024-02-04 15:40:18 +00:00
previousCpuUsage [ ( index - 1 ) % FPS_FRAMES ] = float ( rendererCPUBusyTime ) / float ( frameBusyTime + frameIdleTime ) * 100.0 ;
previousGpuUsage [ ( index - 1 ) % FPS_FRAMES ] = float ( rendererGPUTime ) / float ( rendererGPUTime + rendererGPUIdleTime ) * 100.0 ;
2023-11-30 17:26:38 +00:00
2020-03-29 15:12:11 +00:00
# if 1
2020-05-04 15:22:51 +00:00
2020-03-29 15:12:11 +00:00
// RB: use ImGui to show more detailed stats about the scene loads
if ( ImGuiHook : : IsReadyToRender ( ) )
{
2020-05-04 23:21:29 +00:00
// start smaller
int32 statsWindowWidth = 320 ;
2024-02-28 16:59:41 +00:00
int32 statsWindowHeight = 330 ;
2020-05-04 23:21:29 +00:00
if ( com_showFPS . GetInteger ( ) > 2 )
{
2022-04-01 11:55:34 +00:00
statsWindowWidth + = 230 ;
2023-03-18 13:44:59 +00:00
statsWindowHeight + = 120 ;
2020-05-04 23:21:29 +00:00
}
2020-03-29 15:12:11 +00:00
ImVec2 pos ;
pos . x = renderSystem - > GetWidth ( ) - statsWindowWidth ;
pos . y = 0 ;
ImGui : : SetNextWindowPos ( pos ) ;
ImGui : : SetNextWindowSize ( ImVec2 ( statsWindowWidth , statsWindowHeight ) ) ;
2020-05-04 15:22:51 +00:00
static ImVec4 colorBlack = ImVec4 ( 0.00f , 0.00f , 0.00f , 1.00f ) ;
static ImVec4 colorWhite = ImVec4 ( 1.00f , 1.00f , 1.00f , 1.00f ) ;
static ImVec4 colorRed = ImVec4 ( 1.00f , 0.00f , 0.00f , 1.00f ) ;
static ImVec4 colorGreen = ImVec4 ( 0.00f , 1.00f , 0.00f , 1.00f ) ;
static ImVec4 colorBlue = ImVec4 ( 0.00f , 0.00f , 1.00f , 1.00f ) ;
static ImVec4 colorYellow = ImVec4 ( 1.00f , 1.00f , 0.00f , 1.00f ) ;
static ImVec4 colorMagenta = ImVec4 ( 1.00f , 0.00f , 1.00f , 1.00f ) ;
static ImVec4 colorCyan = ImVec4 ( 0.00f , 1.00f , 1.00f , 1.00f ) ;
static ImVec4 colorOrange = ImVec4 ( 1.00f , 0.50f , 0.00f , 1.00f ) ;
static ImVec4 colorPurple = ImVec4 ( 0.60f , 0.00f , 0.60f , 1.00f ) ;
static ImVec4 colorPink = ImVec4 ( 0.73f , 0.40f , 0.48f , 1.00f ) ;
static ImVec4 colorBrown = ImVec4 ( 0.40f , 0.35f , 0.08f , 1.00f ) ;
static ImVec4 colorLtGrey = ImVec4 ( 0.75f , 0.75f , 0.75f , 1.00f ) ;
static ImVec4 colorMdGrey = ImVec4 ( 0.50f , 0.50f , 0.50f , 1.00f ) ;
static ImVec4 colorDkGrey = ImVec4 ( 0.25f , 0.25f , 0.25f , 1.00f ) ;
2023-02-28 09:32:39 +00:00
static ImVec4 colorGold = ImVec4 ( 0.68f , 0.63f , 0.36f , 1.00f ) ;
2024-03-17 10:25:21 +00:00
static ImVec4 colorPastelMagenta = ImVec4 ( 1.0f , 0.5f , 1.0f , 1.00f ) ;
2020-05-04 15:22:51 +00:00
2020-03-29 15:12:11 +00:00
ImGui : : Begin ( " Performance Stats " ) ;
2022-09-23 07:39:48 +00:00
static const int gfxNumValues = 3 ;
static const char * gfxValues [ gfxNumValues ] =
{
" DX11 " ,
" DX12 " ,
" Vulkan " ,
} ;
const char * API = gfxValues [ int ( deviceManager - > GetGraphicsAPI ( ) ) ] ;
2020-05-04 15:22:51 +00:00
extern idCVar r_antiAliasing ;
2022-05-29 13:51:07 +00:00
# if ID_MSAA
2020-05-04 15:22:51 +00:00
static const int aaNumValues = 5 ;
2022-04-23 14:34:22 +00:00
2020-05-04 15:22:51 +00:00
static const char * aaValues [ aaNumValues ] =
2022-04-23 14:34:22 +00:00
{
" None " ,
" None " ,
" SMAA 1X " ,
" MSAA 2X " ,
" MSAA 4X " ,
} ;
static const char * taaValues [ aaNumValues ] =
2020-05-04 15:22:51 +00:00
{
" None " ,
2022-04-19 19:56:30 +00:00
" TAA " ,
" TAA + SMAA 1X " ,
2020-05-04 15:22:51 +00:00
" MSAA 2X " ,
" MSAA 4X " ,
} ;
2022-04-19 19:56:30 +00:00
compile_time_assert ( aaNumValues = = ( ANTI_ALIASING_MSAA_4X + 1 ) ) ;
2022-05-29 13:51:07 +00:00
# else
static const int aaNumValues = 2 ;
static const char * aaValues [ aaNumValues ] =
{
" None " ,
" None " ,
} ;
static const char * taaValues [ aaNumValues ] =
{
" None " ,
" TAA " ,
} ;
compile_time_assert ( aaNumValues = = ( ANTI_ALIASING_TAA + 1 ) ) ;
# endif
2020-05-04 15:22:51 +00:00
2022-04-23 14:34:22 +00:00
const char * aaMode = NULL ;
if ( R_UseTemporalAA ( ) )
{
aaMode = taaValues [ r_antiAliasing . GetInteger ( ) ] ;
}
else
{
aaMode = aaValues [ r_antiAliasing . GetInteger ( ) ] ;
}
2020-05-04 15:22:51 +00:00
idStr resolutionText ;
resolutionScale . GetConsoleText ( resolutionText ) ;
int width = renderSystem - > GetWidth ( ) ;
int height = renderSystem - > GetHeight ( ) ;
2020-05-04 23:21:29 +00:00
ImGui : : TextColored ( colorCyan , " API: %s, AA[%i, %i]: %s, %s " , API , width , height , aaMode , resolutionText . c_str ( ) ) ;
2020-05-04 15:22:51 +00:00
2024-03-17 10:25:21 +00:00
ImGui : : TextColored ( colorGold , " Device: %s " , deviceManager - > GetRendererString ( ) ) ;
ImGui : : TextColored ( colorPastelMagenta , " VRAM Usage: %llu MB " , commonLocal . GetRendererGpuMemoryMB ( ) ) ;
2023-02-28 09:32:39 +00:00
2023-03-18 13:44:59 +00:00
ImGui : : TextColored ( colorLtGrey , " GENERAL: views:%i draws:%i tris:%i " ,
2020-03-29 15:12:11 +00:00
commonLocal . stats_frontend . c_numViews ,
commonLocal . stats_backend . c_drawElements + commonLocal . stats_backend . c_shadowElements ,
2023-03-18 13:44:59 +00:00
( commonLocal . stats_backend . c_drawIndexes + commonLocal . stats_backend . c_shadowIndexes ) / 3 ) ;
2020-03-29 15:12:11 +00:00
2020-05-04 23:21:29 +00:00
if ( com_showFPS . GetInteger ( ) > 2 )
{
2023-03-18 13:44:59 +00:00
int atlasPercentage = idMath : : Ftoi ( 100.0f * ( commonLocal . stats_backend . c_shadowAtlasUsage / ( float ) Square ( r_shadowMapAtlasSize . GetInteger ( ) ) ) ) ;
ImGui : : TextColored ( colorLtGrey , " SHADOWS: atlas usage:%2i%% views:%i draws:%i tris:%i " ,
atlasPercentage ,
commonLocal . stats_backend . c_shadowViews ,
commonLocal . stats_backend . c_shadowElements ,
commonLocal . stats_backend . c_shadowIndexes / 3 ) ;
2021-09-28 02:58:32 +00:00
ImGui : : TextColored ( colorLtGrey , " DYNAMIC: callback:%-2i md5:%i dfrmVerts:%i dfrmTris:%i tangTris:%i guis:%i " ,
2020-05-04 23:21:29 +00:00
commonLocal . stats_frontend . c_entityDefCallbacks ,
commonLocal . stats_frontend . c_generateMd5 ,
commonLocal . stats_frontend . c_deformedVerts ,
commonLocal . stats_frontend . c_deformedIndexes / 3 ,
commonLocal . stats_frontend . c_tangentIndexes / 3 ,
commonLocal . stats_frontend . c_guiSurfs
) ;
//ImGui::Text( "Cull: %i box in %i box out\n",
// commonLocal.stats_frontend.c_box_cull_in, commonLocal.stats_frontend.c_box_cull_out );
2021-09-28 02:58:32 +00:00
ImGui : : TextColored ( colorLtGrey , " ADDMODEL: callback:%-2i createInteractions:%i createShadowVolumes:%i " ,
2020-05-04 23:21:29 +00:00
commonLocal . stats_frontend . c_entityDefCallbacks ,
commonLocal . stats_frontend . c_createInteractions ,
commonLocal . stats_frontend . c_createShadowVolumes ) ;
2021-09-28 02:58:32 +00:00
ImGui : : TextColored ( colorLtGrey , " viewEntities:%-3i shadowEntities:%-3i viewLights:%i \n " , commonLocal . stats_frontend . c_visibleViewEntities ,
2020-05-04 23:21:29 +00:00
commonLocal . stats_frontend . c_shadowViewEntities ,
commonLocal . stats_frontend . c_viewLights ) ;
2021-09-28 02:58:32 +00:00
ImGui : : TextColored ( colorLtGrey , " UPDATES: entityUpdates:%-3i entityRefs:%-3i lightUpdates:%-2i lightRefs:%i \n " ,
2020-05-04 23:21:29 +00:00
commonLocal . stats_frontend . c_entityUpdates , commonLocal . stats_frontend . c_entityReferences ,
commonLocal . stats_frontend . c_lightUpdates , commonLocal . stats_frontend . c_lightReferences ) ;
}
2020-03-29 15:12:11 +00:00
//ImGui::Text( "frameData: %i (%i)\n", frameData->frameMemoryAllocated.GetValue(), frameData->highWaterAllocated );
2020-05-04 23:21:29 +00:00
//ImGui::Spacing();
//ImGui::Spacing();
2020-03-29 15:12:11 +00:00
ImGui : : Spacing ( ) ;
2020-05-04 15:22:51 +00:00
2020-05-04 23:21:29 +00:00
if ( com_showFPS . GetInteger ( ) > 2 )
2020-05-04 15:22:51 +00:00
{
2023-11-30 17:26:38 +00:00
const char * overlay = va ( " Average FPS %-4i " , fps ) ;
2020-05-04 15:22:51 +00:00
2020-05-04 23:21:29 +00:00
ImGui : : PlotLines ( " Relative \n Frametime ms " , previousTimesNormalized , FPS_FRAMES_HISTORY , valuesOffset , overlay , - 10.0f , 10.0f , ImVec2 ( 0 , 50 ) ) ;
}
else
{
2023-02-22 20:11:13 +00:00
ImGui : : TextColored ( fps < maxFPS ? colorRed : colorYellow , " Average FPS %i " , fps ) ;
2020-05-04 15:22:51 +00:00
}
2020-03-29 15:12:11 +00:00
ImGui : : Spacing ( ) ;
2020-05-04 23:21:29 +00:00
ImGui : : TextColored ( colorMdGrey , " CPU GPU " ) ;
ImGui : : TextColored ( gameThreadTotalTime > maxTime ? colorRed : colorWhite , " Game+RF: %5llu us EarlyZ: %5llu us " , gameThreadTotalTime , rendererGPUEarlyZTime ) ;
ImGui : : TextColored ( gameThreadGameTime > maxTime ? colorRed : colorWhite , " Game: %5llu us SSAO: %5llu us " , gameThreadGameTime , rendererGPU_SSAOTime ) ;
ImGui : : TextColored ( gameThreadRenderTime > maxTime ? colorRed : colorWhite , " RF: %5llu us SSR: %5llu us " , gameThreadRenderTime , rendererGPU_SSRTime ) ;
2022-04-01 11:55:34 +00:00
ImGui : : TextColored ( rendererBackEndTime > maxTime ? colorRed : colorWhite , " RB: %5llu us Ambient Pass: %5llu us " , rendererBackEndTime , rendererGPUAmbientPassTime ) ;
2022-11-18 04:42:06 +00:00
ImGui : : TextColored ( rendererGPUShadowAtlasTime > maxTime ? colorRed : colorWhite , " Shadows: %5llu us Shadow Atlas: %5llu us " , rendererShadowsTime , rendererGPUShadowAtlasTime ) ;
2023-10-04 16:33:32 +00:00
# if defined(__APPLE__) && defined( USE_MoltenVK )
// SRS - For more recent versions of MoltenVK with enhanced performance statistics (v1.2.6 and later), display the Vulkan to Metal encoding thread time on macOS
ImGui : : TextColored ( rendererMvkEncodeTime > maxTime | | rendererGPUInteractionsTime > maxTime ? colorRed : colorWhite , " Encode: %5lld us Interactions: %5llu us " , rendererMvkEncodeTime , rendererGPUInteractionsTime ) ;
ImGui : : TextColored ( rendererGPUShaderPassesTime > maxTime ? colorRed : colorWhite , " Sync: %5lld us Shader Pass: %5llu us " , frameSyncTime , rendererGPUShaderPassesTime ) ;
# else
2023-02-23 06:39:28 +00:00
ImGui : : TextColored ( rendererGPUInteractionsTime > maxTime ? colorRed : colorWhite , " Sync: %5lld us Interactions: %5llu us " , frameSyncTime , rendererGPUInteractionsTime ) ;
2022-04-01 11:55:34 +00:00
ImGui : : TextColored ( rendererGPUShaderPassesTime > maxTime ? colorRed : colorWhite , " Shader Pass: %5llu us " , rendererGPUShaderPassesTime ) ;
2023-10-04 16:33:32 +00:00
# endif
2022-04-23 14:34:22 +00:00
ImGui : : TextColored ( rendererGPU_TAATime > maxTime ? colorRed : colorWhite , " TAA: %5llu us " , rendererGPU_TAATime ) ;
2024-03-17 10:25:21 +00:00
//ImGui::TextColored( rendererGPUToneMapPassTime > maxTime ? colorRed : colorWhite, " ToneMap: %5llu us", rendererGPUToneMapPassTime );
2020-05-04 23:21:29 +00:00
ImGui : : TextColored ( rendererGPUPostProcessingTime > maxTime ? colorRed : colorWhite , " PostFX: %5llu us " , rendererGPUPostProcessingTime ) ;
2023-02-23 06:39:28 +00:00
ImGui : : TextColored ( frameBusyTime > maxTime | | rendererGPUTime > maxTime ? colorRed : colorWhite , " Total: %5lld us Total: %5lld us " , frameBusyTime , rendererGPUTime ) ;
ImGui : : TextColored ( colorWhite , " Idle: %5lld us Idle: %5lld us " , frameIdleTime , rendererGPUIdleTime ) ;
2023-10-04 16:33:32 +00:00
// SRS - Show CPU and GPU overall usage statistics
2024-02-28 16:59:41 +00:00
//ImGui::TextColored( colorWhite, "Frame: %3.0f %% Frame: %3.0f %%", cpuUsage, gpuUsage );
2020-03-29 15:12:11 +00:00
ImGui : : End ( ) ;
}
return y ;
# else
// print the resolution scale so we can tell when we are at reduced resolution
idStr resolutionText ;
resolutionScale . GetConsoleText ( resolutionText ) ;
int w = resolutionText . Length ( ) * BIGCHAR_WIDTH ;
renderSystem - > DrawBigStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , resolutionText . c_str ( ) , colorWhite , true ) ;
2012-11-26 18:58:24 +00:00
y + = SMALLCHAR_HEIGHT + 4 ;
idStr timeStr ;
timeStr . Format ( " %sG+RF: %4d " , gameThreadTotalTime > maxTime ? S_COLOR_RED : " " , gameThreadTotalTime ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sG: %4d " , gameThreadGameTime > maxTime ? S_COLOR_RED : " " , gameThreadGameTime ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sRF: %4d " , gameThreadRenderTime > maxTime ? S_COLOR_RED : " " , gameThreadRenderTime ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sRB: %4.1f " , rendererBackEndTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererBackEndTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sSV: %4.1f " , rendererShadowsTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererShadowsTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sIDLE: %4.1f " , rendererGPUIdleTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererGPUIdleTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
y + = SMALLCHAR_HEIGHT + 4 ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
timeStr . Format ( " %sGPU: %4.1f " , rendererGPUTime > maxTime * 1000 ? S_COLOR_RED : " " , rendererGPUTime / 1000.0f ) ;
w = timeStr . LengthWithoutColors ( ) * SMALLCHAR_WIDTH ;
renderSystem - > DrawSmallStringExt ( LOCALSAFE_RIGHT - w , idMath : : Ftoi ( y ) + 2 , timeStr . c_str ( ) , colorWhite , false ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
return y + BIGCHAR_HEIGHT + 4 ;
2020-03-29 15:12:11 +00:00
# endif
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawMemoryUsage
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
float idConsoleLocal : : DrawMemoryUsage ( float y )
{
2012-11-26 18:58:24 +00:00
return y ;
}
//=========================================================================
/*
= = = = = = = = = = = = = =
Con_Clear_f
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
static void Con_Clear_f ( const idCmdArgs & args )
{
2012-11-26 18:58:24 +00:00
localConsole . Clear ( ) ;
}
/*
= = = = = = = = = = = = = =
Con_Dump_f
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
static void Con_Dump_f ( const idCmdArgs & args )
{
if ( args . Argc ( ) ! = 2 )
{
2012-11-26 18:58:24 +00:00
common - > Printf ( " usage: conDump <filename> \n " ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
idStr fileName = args . Argv ( 1 ) ;
fileName . DefaultFileExtension ( " .txt " ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
common - > Printf ( " Dumped console text to %s. \n " , fileName . c_str ( ) ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
localConsole . Dump ( fileName . c_str ( ) ) ;
}
/*
= = = = = = = = = = = = = =
idConsoleLocal : : Init
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Init ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
keyCatching = false ;
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
LOCALSAFE_LEFT = 0 ;
2013-09-21 12:12:42 +00:00
LOCALSAFE_RIGHT = SCREEN_WIDTH - LOCALSAFE_LEFT ;
2012-11-26 18:58:24 +00:00
LOCALSAFE_TOP = 24 ;
2013-09-21 12:12:42 +00:00
LOCALSAFE_BOTTOM = SCREEN_HEIGHT - LOCALSAFE_TOP ;
2012-11-26 18:58:24 +00:00
LOCALSAFE_WIDTH = LOCALSAFE_RIGHT - LOCALSAFE_LEFT ;
LOCALSAFE_HEIGHT = LOCALSAFE_BOTTOM - LOCALSAFE_TOP ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
LINE_WIDTH = ( ( LOCALSAFE_WIDTH / SMALLCHAR_WIDTH ) - 2 ) ;
2012-11-28 15:47:07 +00:00
TOTAL_LINES = ( CON_TEXTSIZE / LINE_WIDTH ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
lastKeyEvent = - 1 ;
nextKeyEvent = CONSOLE_FIRSTREPEAT ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
consoleField . Clear ( ) ;
consoleField . SetWidthInChars ( LINE_WIDTH ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < COMMAND_HISTORY ; i + + )
{
2012-11-26 18:58:24 +00:00
historyEditLines [ i ] . Clear ( ) ;
historyEditLines [ i ] . SetWidthInChars ( LINE_WIDTH ) ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
cmdSystem - > AddCommand ( " clear " , Con_Clear_f , CMD_FL_SYSTEM , " clears the console " ) ;
cmdSystem - > AddCommand ( " conDump " , Con_Dump_f , CMD_FL_SYSTEM , " dumps the console text to a file " ) ;
}
/*
= = = = = = = = = = = = = =
idConsoleLocal : : Shutdown
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Shutdown ( )
{
2012-11-26 18:58:24 +00:00
cmdSystem - > RemoveCommand ( " clear " ) ;
cmdSystem - > RemoveCommand ( " conDump " ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
debugGraphs . DeleteContents ( true ) ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Active
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idConsoleLocal : : Active ( )
{
2012-11-26 18:58:24 +00:00
return keyCatching ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : ClearNotifyLines
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : ClearNotifyLines ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < NUM_CON_TIMES ; i + + )
{
2012-11-26 18:58:24 +00:00
times [ i ] = 0 ;
}
}
/*
= = = = = = = = = = = = = = = =
2013-09-29 11:03:32 +00:00
idConsoleLocal : : Open
= = = = = = = = = = = = = = = =
*/
void idConsoleLocal : : Open ( )
{
if ( keyCatching )
2019-11-11 19:27:44 +00:00
{
return ; // already open
}
2013-09-29 11:03:32 +00:00
consoleField . ClearAutoComplete ( ) ;
consoleField . Clear ( ) ;
keyCatching = true ;
SetDisplayFraction ( 0.5f ) ;
}
/*
= = = = = = = = = = = = = = = =
2012-11-26 18:58:24 +00:00
idConsoleLocal : : Close
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Close ( )
{
2012-11-26 18:58:24 +00:00
keyCatching = false ;
SetDisplayFraction ( 0 ) ;
displayFrac = 0 ; // don't scroll to that point, go immediately
ClearNotifyLines ( ) ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Clear
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Clear ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < CON_TEXTSIZE ; i + + )
{
2021-02-25 18:30:07 +00:00
text [ i ] = ( idStr : : ColorIndex ( C_COLOR_WHITE ) < < 8 ) | ' ' ;
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
Bottom ( ) ; // go to end
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Dump
Save the console contents out to a file
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Dump ( const char * fileName )
{
2012-11-26 18:58:24 +00:00
int l , x , i ;
2012-11-28 15:47:07 +00:00
short * line ;
idFile * f ;
char * buffer = ( char * ) alloca ( LINE_WIDTH + 3 ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
f = fileSystem - > OpenFileWrite ( fileName ) ;
2012-11-28 15:47:07 +00:00
if ( ! f )
{
2012-11-26 18:58:24 +00:00
common - > Warning ( " couldn't open %s " , fileName ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// skip empty lines
l = current - TOTAL_LINES + 1 ;
2012-11-28 15:47:07 +00:00
if ( l < 0 )
{
2012-11-26 18:58:24 +00:00
l = 0 ;
}
2012-11-28 15:47:07 +00:00
for ( ; l < = current ; l + + )
2012-11-26 18:58:24 +00:00
{
line = text + ( l % TOTAL_LINES ) * LINE_WIDTH ;
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + + )
if ( ( line [ x ] & 0xff ) > ' ' )
2019-11-11 19:27:44 +00:00
{
2012-11-26 18:58:24 +00:00
break ;
2019-11-11 19:27:44 +00:00
}
2012-11-28 15:47:07 +00:00
if ( x ! = LINE_WIDTH )
2019-11-11 19:27:44 +00:00
{
2012-11-26 18:58:24 +00:00
break ;
2019-11-11 19:27:44 +00:00
}
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// write the remaining lines
2012-11-28 15:47:07 +00:00
for ( ; l < = current ; l + + )
{
2012-11-26 18:58:24 +00:00
line = text + ( l % TOTAL_LINES ) * LINE_WIDTH ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < LINE_WIDTH ; i + + )
{
2012-11-26 18:58:24 +00:00
buffer [ i ] = line [ i ] & 0xff ;
}
2012-11-28 15:47:07 +00:00
for ( x = LINE_WIDTH - 1 ; x > = 0 ; x - - )
{
if ( buffer [ x ] < = ' ' )
{
2012-11-26 18:58:24 +00:00
buffer [ x ] = 0 ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2012-11-28 15:47:07 +00:00
buffer [ x + 1 ] = ' \r ' ;
buffer [ x + 2 ] = ' \n ' ;
buffer [ x + 3 ] = 0 ;
2012-11-26 18:58:24 +00:00
f - > Write ( buffer , strlen ( buffer ) ) ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
fileSystem - > CloseFile ( f ) ;
}
2013-09-21 12:12:42 +00:00
/*
= = = = = = = = = = = = = =
idConsoleLocal : : Resize
= = = = = = = = = = = = = =
*/
void idConsoleLocal : : Resize ( )
{
if ( renderSystem - > GetVirtualWidth ( ) = = lastVirtualScreenWidth & & renderSystem - > GetVirtualHeight ( ) = = lastVirtualScreenHeight )
2019-11-11 19:27:44 +00:00
{
2013-09-21 12:12:42 +00:00
return ;
2019-11-11 19:27:44 +00:00
}
2013-09-21 12:12:42 +00:00
lastVirtualScreenWidth = renderSystem - > GetVirtualWidth ( ) ;
lastVirtualScreenHeight = renderSystem - > GetVirtualHeight ( ) ;
LOCALSAFE_RIGHT = renderSystem - > GetVirtualWidth ( ) - LOCALSAFE_LEFT ;
LOCALSAFE_BOTTOM = renderSystem - > GetVirtualHeight ( ) - LOCALSAFE_TOP ;
LOCALSAFE_WIDTH = LOCALSAFE_RIGHT - LOCALSAFE_LEFT ;
LOCALSAFE_HEIGHT = LOCALSAFE_BOTTOM - LOCALSAFE_TOP ;
}
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : PageUp
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : PageUp ( )
{
2012-11-26 18:58:24 +00:00
display - = 2 ;
2012-11-28 15:47:07 +00:00
if ( current - display > = TOTAL_LINES )
{
2012-11-26 18:58:24 +00:00
display = current - TOTAL_LINES + 1 ;
}
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : PageDown
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : PageDown ( )
{
2012-11-26 18:58:24 +00:00
display + = 2 ;
2012-11-28 15:47:07 +00:00
if ( display > current )
{
2012-11-26 18:58:24 +00:00
display = current ;
}
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Top
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Top ( )
{
2012-11-26 18:58:24 +00:00
display = 0 ;
}
/*
= = = = = = = = = = = = = = = =
idConsoleLocal : : Bottom
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Bottom ( )
{
2012-11-26 18:58:24 +00:00
display = current ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
CONSOLE LINE EDITING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = = = =
KeyDownEvent
Handles history and console scrollback
= = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : KeyDownEvent ( int key )
{
2012-11-26 18:58:24 +00:00
// Execute F key bindings
2012-11-28 15:47:07 +00:00
if ( key > = K_F1 & & key < = K_F12 )
{
2012-11-26 18:58:24 +00:00
idKeyInput : : ExecKeyBinding ( key ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// ctrl-L clears screen
2012-11-28 15:47:07 +00:00
if ( key = = K_L & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) )
{
2012-11-26 18:58:24 +00:00
Clear ( ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// enter finishes the line
2012-11-28 15:47:07 +00:00
if ( key = = K_ENTER | | key = = K_KP_ENTER )
{
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
common - > Printf ( " ]%s \n " , consoleField . GetBuffer ( ) ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_APPEND , consoleField . GetBuffer ( ) ) ; // valid command
cmdSystem - > BufferCommandText ( CMD_EXEC_APPEND , " \n " ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// copy line to history buffer
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( consoleField . GetBuffer ( ) [ 0 ] ! = ' \n ' & & consoleField . GetBuffer ( ) [ 0 ] ! = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
consoleHistory . AddToHistory ( consoleField . GetBuffer ( ) ) ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
consoleField . Clear ( ) ;
consoleField . SetWidthInChars ( LINE_WIDTH ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
const bool captureToImage = false ;
common - > UpdateScreen ( captureToImage ) ; // force an update, because the command
2012-11-28 15:47:07 +00:00
// may take some time
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// command completion
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( key = = K_TAB )
{
2012-11-26 18:58:24 +00:00
consoleField . AutoComplete ( ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// command history (ctrl-p ctrl-n for unix style)
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( ( key = = K_UPARROW ) | |
( key = = K_P & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) ) )
{
2012-11-26 18:58:24 +00:00
idStr hist = consoleHistory . RetrieveFromHistory ( true ) ;
2012-11-28 15:47:07 +00:00
if ( ! hist . IsEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
consoleField . SetBuffer ( hist ) ;
}
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( ( key = = K_DOWNARROW ) | |
( key = = K_N & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) ) )
{
2012-11-26 18:58:24 +00:00
idStr hist = consoleHistory . RetrieveFromHistory ( false ) ;
2012-11-28 15:47:07 +00:00
if ( ! hist . IsEmpty ( ) )
{
2012-11-26 18:58:24 +00:00
consoleField . SetBuffer ( hist ) ;
}
2012-12-21 03:52:56 +00:00
else // DG: if no more lines are in the history, show a blank line again
{
consoleField . Clear ( ) ;
} // DG end
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// console scrolling
2012-11-28 15:47:07 +00:00
if ( key = = K_PGUP )
{
2012-11-26 18:58:24 +00:00
PageUp ( ) ;
lastKeyEvent = eventLoop - > Milliseconds ( ) ;
nextKeyEvent = CONSOLE_FIRSTREPEAT ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( key = = K_PGDN )
{
2012-11-26 18:58:24 +00:00
PageDown ( ) ;
lastKeyEvent = eventLoop - > Milliseconds ( ) ;
nextKeyEvent = CONSOLE_FIRSTREPEAT ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( key = = K_MWHEELUP )
{
2012-11-26 18:58:24 +00:00
PageUp ( ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( key = = K_MWHEELDOWN )
{
2012-11-26 18:58:24 +00:00
PageDown ( ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// ctrl-home = top of console
2012-11-28 15:47:07 +00:00
if ( key = = K_HOME & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) )
{
2012-11-26 18:58:24 +00:00
Top ( ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// ctrl-end = bottom of console
2012-11-28 15:47:07 +00:00
if ( key = = K_END & & ( idKeyInput : : IsDown ( K_LCTRL ) | | idKeyInput : : IsDown ( K_RCTRL ) ) )
{
2012-11-26 18:58:24 +00:00
Bottom ( ) ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// pass to the normal editline routine
consoleField . KeyDownEvent ( key ) ;
}
/*
= = = = = = = = = = = = = =
Scroll
deals with scrolling text because we don ' t have key repeat
= = = = = = = = = = = = = =
*/
2022-03-14 09:00:30 +00:00
void idConsoleLocal : : Scroll ( )
2012-11-28 15:47:07 +00:00
{
if ( lastKeyEvent = = - 1 | | ( lastKeyEvent + 200 ) > eventLoop - > Milliseconds ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
// console scrolling
2012-11-28 15:47:07 +00:00
if ( idKeyInput : : IsDown ( K_PGUP ) )
{
2012-11-26 18:58:24 +00:00
PageUp ( ) ;
nextKeyEvent = CONSOLE_REPEAT ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( idKeyInput : : IsDown ( K_PGDN ) )
{
2012-11-26 18:58:24 +00:00
PageDown ( ) ;
nextKeyEvent = CONSOLE_REPEAT ;
return ;
}
}
/*
= = = = = = = = = = = = = =
SetDisplayFraction
Causes the console to start opening the desired amount .
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : SetDisplayFraction ( float frac )
{
2012-11-26 18:58:24 +00:00
finalFrac = frac ;
fracTime = Sys_Milliseconds ( ) ;
}
/*
= = = = = = = = = = = = = =
UpdateDisplayFraction
Scrolls the console up or down based on conspeed
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : UpdateDisplayFraction ( )
{
if ( con_speed . GetFloat ( ) < = 0.1f )
{
2012-11-26 18:58:24 +00:00
fracTime = Sys_Milliseconds ( ) ;
displayFrac = finalFrac ;
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// scroll towards the destination height
2012-11-28 15:47:07 +00:00
if ( finalFrac < displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac - = con_speed . GetFloat ( ) * ( Sys_Milliseconds ( ) - fracTime ) * 0.001f ;
2012-11-28 15:47:07 +00:00
if ( finalFrac > displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac = finalFrac ;
}
fracTime = Sys_Milliseconds ( ) ;
2012-11-28 15:47:07 +00:00
}
else if ( finalFrac > displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac + = con_speed . GetFloat ( ) * ( Sys_Milliseconds ( ) - fracTime ) * 0.001f ;
2012-11-28 15:47:07 +00:00
if ( finalFrac < displayFrac )
{
2012-11-26 18:58:24 +00:00
displayFrac = finalFrac ;
}
fracTime = Sys_Milliseconds ( ) ;
}
}
/*
= = = = = = = = = = = = = =
ProcessEvent
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idConsoleLocal : : ProcessEvent ( const sysEvent_t * event , bool forceAccept )
{
2012-11-26 18:58:24 +00:00
const bool consoleKey = event - > evType = = SE_KEY & & event - > evValue = = K_GRAVE & & com_allowConsole . GetBool ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// we always catch the console key event
2012-11-28 15:47:07 +00:00
if ( ! forceAccept & & consoleKey )
{
2012-11-26 18:58:24 +00:00
// ignore up events
2012-11-28 15:47:07 +00:00
if ( event - > evValue2 = = 0 )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
consoleField . ClearAutoComplete ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// a down event will toggle the destination lines
2012-11-28 15:47:07 +00:00
if ( keyCatching )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
Sys_GrabMouseCursor ( true ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
consoleField . Clear ( ) ;
keyCatching = true ;
2012-11-28 15:47:07 +00:00
if ( idKeyInput : : IsDown ( K_LSHIFT ) | | idKeyInput : : IsDown ( K_RSHIFT ) )
{
2012-11-26 18:58:24 +00:00
// if the shift key is down, don't open the console as much
SetDisplayFraction ( 0.2f ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
SetDisplayFraction ( 0.5f ) ;
}
}
return true ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// if we aren't key catching, dump all the other events
2012-11-28 15:47:07 +00:00
if ( ! forceAccept & & ! keyCatching )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// handle key and character events
2012-11-28 15:47:07 +00:00
if ( event - > evType = = SE_CHAR )
{
2012-11-26 18:58:24 +00:00
// never send the console key as a character
2012-11-28 15:47:07 +00:00
if ( event - > evValue ! = ' ` ' & & event - > evValue ! = ' ~ ' )
{
2012-11-26 18:58:24 +00:00
consoleField . CharEvent ( event - > evValue ) ;
}
return true ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( event - > evType = = SE_KEY )
{
2012-11-26 18:58:24 +00:00
// ignore up key events
2012-11-28 15:47:07 +00:00
if ( event - > evValue2 = = 0 )
{
2012-11-26 18:58:24 +00:00
return true ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
KeyDownEvent ( event - > evValue ) ;
return true ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// we don't handle things like mouse, joystick, and network packets
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
PRINTING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = =
Linefeed
= = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Linefeed ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// mark time for transparent overlay
2012-11-28 15:47:07 +00:00
if ( current > = 0 )
{
2012-11-26 18:58:24 +00:00
times [ current % NUM_CON_TIMES ] = Sys_Milliseconds ( ) ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
x = 0 ;
2012-11-28 15:47:07 +00:00
if ( display = = current )
{
2012-11-26 18:58:24 +00:00
display + + ;
}
current + + ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < LINE_WIDTH ; i + + )
{
int offset = ( ( unsigned int ) current % TOTAL_LINES ) * LINE_WIDTH + i ;
2021-02-25 18:30:07 +00:00
text [ offset ] = ( idStr : : ColorIndex ( C_COLOR_WHITE ) < < 8 ) | ' ' ;
2012-11-26 18:58:24 +00:00
}
}
/*
= = = = = = = = = = = = = = = =
Print
Handles cursor positioning , line wrapping , etc
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Print ( const char * txt )
{
2012-11-26 18:58:24 +00:00
int y ;
int c , l ;
int color ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( TOTAL_LINES = = 0 )
{
2012-11-26 18:58:24 +00:00
// not yet initialized
return ;
}
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
color = idStr : : ColorIndex ( C_COLOR_WHITE ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
while ( ( c = * ( const unsigned char * ) txt ) ! = 0 )
{
if ( idStr : : IsColor ( txt ) )
{
if ( * ( txt + 1 ) = = C_COLOR_DEFAULT )
{
2021-02-25 18:30:07 +00:00
color = idStr : : ColorIndex ( C_COLOR_WHITE ) ;
2012-11-28 15:47:07 +00:00
}
else
{
color = idStr : : ColorIndex ( * ( txt + 1 ) ) ;
2012-11-26 18:58:24 +00:00
}
txt + = 2 ;
continue ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
y = current % TOTAL_LINES ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// if we are about to print a new word, check to see
// if we should wrap to the new line
2012-11-28 15:47:07 +00:00
if ( c > ' ' & & ( x = = 0 | | text [ y * LINE_WIDTH + x - 1 ] < = ' ' ) )
{
2012-11-26 18:58:24 +00:00
// count word length
2012-11-28 15:47:07 +00:00
for ( l = 0 ; l < LINE_WIDTH ; l + + )
{
if ( txt [ l ] < = ' ' )
{
2012-11-26 18:58:24 +00:00
break ;
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// word wrap
2012-11-28 15:47:07 +00:00
if ( l ! = LINE_WIDTH & & ( x + l > = LINE_WIDTH ) )
{
2012-11-26 18:58:24 +00:00
Linefeed ( ) ;
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
txt + + ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
switch ( c )
{
2012-11-26 18:58:24 +00:00
case ' \n ' :
2012-11-28 15:47:07 +00:00
Linefeed ( ) ;
2012-11-26 18:58:24 +00:00
break ;
case ' \t ' :
2012-11-28 15:47:07 +00:00
do
{
text [ y * LINE_WIDTH + x ] = ( color < < 8 ) | ' ' ;
2012-11-26 18:58:24 +00:00
x + + ;
2012-11-28 15:47:07 +00:00
if ( x > = LINE_WIDTH )
{
2012-11-26 18:58:24 +00:00
Linefeed ( ) ;
x = 0 ;
}
2012-11-28 15:47:07 +00:00
}
while ( x & 3 ) ;
2012-11-26 18:58:24 +00:00
break ;
case ' \r ' :
x = 0 ;
break ;
default : // display character and advance
2012-11-28 15:47:07 +00:00
text [ y * LINE_WIDTH + x ] = ( color < < 8 ) | c ;
2012-11-26 18:58:24 +00:00
x + + ;
2012-11-28 15:47:07 +00:00
if ( x > = LINE_WIDTH )
{
2012-11-26 18:58:24 +00:00
Linefeed ( ) ;
x = 0 ;
}
break ;
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// mark time for transparent overlay
2012-11-28 15:47:07 +00:00
if ( current > = 0 )
{
2012-11-26 18:58:24 +00:00
times [ current % NUM_CON_TIMES ] = Sys_Milliseconds ( ) ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
DRAWING
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
DrawInput
Draw the editline after a ] prompt
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawInput ( )
{
2012-11-26 18:58:24 +00:00
int y , autoCompleteLength ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
y = vislines - ( SMALLCHAR_HEIGHT * 2 ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( consoleField . GetAutoCompleteLength ( ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
autoCompleteLength = strlen ( consoleField . GetBuffer ( ) ) - consoleField . GetAutoCompleteLength ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( autoCompleteLength > 0 )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( idVec4 ( 0.8f , 0.2f , 0.2f , 0.45f ) ,
2012-11-28 15:47:07 +00:00
LOCALSAFE_LEFT + 2 * SMALLCHAR_WIDTH + consoleField . GetAutoCompleteLength ( ) * SMALLCHAR_WIDTH ,
y + 2 , autoCompleteLength * SMALLCHAR_WIDTH , SMALLCHAR_HEIGHT - 2 ) ;
2012-11-26 18:58:24 +00:00
}
}
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( C_COLOR_WHITE ) ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + 1 * SMALLCHAR_WIDTH , y , ' ] ' ) ;
2019-11-11 19:27:44 +00:00
2013-09-21 12:12:42 +00:00
consoleField . Draw ( LOCALSAFE_LEFT + 2 * SMALLCHAR_WIDTH , y , renderSystem - > GetVirtualWidth ( ) - 3 * SMALLCHAR_WIDTH , true ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
DrawNotify
Draws the last few lines of output transparently over the game top
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawNotify ( )
{
2012-11-26 18:58:24 +00:00
int x , v ;
2012-11-28 15:47:07 +00:00
short * text_p ;
2012-11-26 18:58:24 +00:00
int i ;
int time ;
int currentColor ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( con_noPrint . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
currentColor = idStr : : ColorIndex ( C_COLOR_WHITE ) ;
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
v = 0 ;
2012-11-28 15:47:07 +00:00
for ( i = current - NUM_CON_TIMES + 1 ; i < = current ; i + + )
{
if ( i < 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
time = times [ i % NUM_CON_TIMES ] ;
2012-11-28 15:47:07 +00:00
if ( time = = 0 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
time = Sys_Milliseconds ( ) - time ;
2012-11-28 15:47:07 +00:00
if ( time > con_notifyTime . GetFloat ( ) * 1000 )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
text_p = text + ( i % TOTAL_LINES ) * LINE_WIDTH ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + + )
{
if ( ( text_p [ x ] & 0xff ) = = ' ' )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2012-11-28 15:47:07 +00:00
if ( idStr : : ColorIndex ( text_p [ x ] > > 8 ) ! = currentColor )
{
currentColor = idStr : : ColorIndex ( text_p [ x ] > > 8 ) ;
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
}
2012-11-28 15:47:07 +00:00
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + ( x + 1 ) * SMALLCHAR_WIDTH , v , text_p [ x ] & 0xff ) ;
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
v + = SMALLCHAR_HEIGHT ;
}
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
renderSystem - > SetColor ( colorWhite ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = =
DrawSolidConsole
Draws the console with the solid background
= = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawSolidConsole ( float frac )
{
2012-11-26 18:58:24 +00:00
int i , x ;
float y ;
int rows ;
2012-11-28 15:47:07 +00:00
short * text_p ;
2012-11-26 18:58:24 +00:00
int row ;
int lines ;
int currentColor ;
2019-11-11 19:27:44 +00:00
2013-09-21 12:12:42 +00:00
lines = idMath : : Ftoi ( renderSystem - > GetVirtualHeight ( ) * frac ) ;
2012-11-28 15:47:07 +00:00
if ( lines < = 0 )
{
2012-11-26 18:58:24 +00:00
return ;
}
2019-11-11 19:27:44 +00:00
2013-09-21 12:12:42 +00:00
if ( lines > renderSystem - > GetVirtualHeight ( ) )
2012-11-28 15:47:07 +00:00
{
2013-09-21 12:12:42 +00:00
lines = renderSystem - > GetVirtualHeight ( ) ;
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// draw the background
2013-09-21 12:12:42 +00:00
y = frac * renderSystem - > GetVirtualHeight ( ) - 2 ;
2012-11-28 15:47:07 +00:00
if ( y < 1.0f )
{
2012-11-26 18:58:24 +00:00
y = 0.0f ;
2012-11-28 15:47:07 +00:00
}
else
{
2013-09-21 12:12:42 +00:00
renderSystem - > DrawFilled ( idVec4 ( 0.0f , 0.0f , 0.0f , 0.75f ) , 0 , 0 , renderSystem - > GetVirtualWidth ( ) , y ) ;
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
renderSystem - > DrawFilled ( colorGold , 0 , y , renderSystem - > GetVirtualWidth ( ) , 2 ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// draw the version number
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
renderSystem - > SetColor ( colorGold ) ;
2019-11-11 19:27:44 +00:00
2016-01-18 23:04:13 +00:00
// RB begin
//idStr version = va( "%s.%i.%i", ENGINE_VERSION, BUILD_NUMBER, BUILD_NUMBER_MINOR );
2021-02-25 18:30:07 +00:00
idStr version = va ( " %s %s " , ENGINE_VERSION , BUILD_STRING ) ;
2016-01-18 23:04:13 +00:00
//idStr version = com_version.GetString();
// RB end
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
i = version . Length ( ) ;
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
# define VERSION_LINE_SPACE (SMALLCHAR_HEIGHT + 4)
for ( x = 0 ; x < i ; x + + )
{
renderSystem - > DrawSmallChar ( LOCALSAFE_WIDTH - ( i - x ) * SMALLCHAR_WIDTH ,
( lines - ( SMALLCHAR_HEIGHT + SMALLCHAR_HEIGHT / 4 ) ) - VERSION_LINE_SPACE - VERSION_LINE_SPACE , version [ x ] ) ;
}
// jmarshall
idStr branchVersion = va ( " Branch %s " , ENGINE_BRANCH ) ;
i = branchVersion . Length ( ) ;
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < i ; x + + )
{
renderSystem - > DrawSmallChar ( LOCALSAFE_WIDTH - ( i - x ) * SMALLCHAR_WIDTH ,
2021-02-25 18:30:07 +00:00
( lines - ( SMALLCHAR_HEIGHT + SMALLCHAR_HEIGHT / 2 ) ) - ( VERSION_LINE_SPACE - 2 ) , branchVersion [ x ] ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
idStr builddate = va ( " %s %s " , __DATE__ , __TIME__ ) ;
i = builddate . Length ( ) ;
for ( x = 0 ; x < i ; x + + )
{
renderSystem - > DrawSmallChar ( LOCALSAFE_WIDTH - ( i - x ) * SMALLCHAR_WIDTH ,
( lines - ( SMALLCHAR_HEIGHT + SMALLCHAR_HEIGHT / 2 ) ) , builddate [ x ] ) ;
}
// jmarshall end
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// draw the text
vislines = lines ;
2012-11-28 15:47:07 +00:00
rows = ( lines - SMALLCHAR_WIDTH ) / SMALLCHAR_WIDTH ; // rows of text to draw
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
y = lines - ( SMALLCHAR_HEIGHT * 3 ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// draw from the bottom up
2012-11-28 15:47:07 +00:00
if ( display ! = current )
{
2012-11-26 18:58:24 +00:00
// draw arrows to show the buffer is backscrolled
2021-02-25 18:30:07 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( C_COLOR_WHITE ) ) ;
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + = 4 )
{
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + ( x + 1 ) * SMALLCHAR_WIDTH , idMath : : Ftoi ( y ) , ' ^ ' ) ;
2012-11-26 18:58:24 +00:00
}
y - = SMALLCHAR_HEIGHT ;
rows - - ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
row = display ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( x = = 0 )
{
2012-11-26 18:58:24 +00:00
row - - ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
currentColor = idStr : : ColorIndex ( C_COLOR_WHITE ) ;
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < rows ; i + + , y - = SMALLCHAR_HEIGHT , row - - )
{
if ( row < 0 )
{
2012-11-26 18:58:24 +00:00
break ;
}
2012-11-28 15:47:07 +00:00
if ( current - row > = TOTAL_LINES )
{
2012-11-26 18:58:24 +00:00
// past scrollback wrap point
2012-11-28 15:47:07 +00:00
continue ;
2012-11-26 18:58:24 +00:00
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
text_p = text + ( row % TOTAL_LINES ) * LINE_WIDTH ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
for ( x = 0 ; x < LINE_WIDTH ; x + + )
{
if ( ( text_p [ x ] & 0xff ) = = ' ' )
{
2012-11-26 18:58:24 +00:00
continue ;
}
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( idStr : : ColorIndex ( text_p [ x ] > > 8 ) ! = currentColor )
{
currentColor = idStr : : ColorIndex ( text_p [ x ] > > 8 ) ;
2012-11-26 18:58:24 +00:00
renderSystem - > SetColor ( idStr : : ColorForIndex ( currentColor ) ) ;
}
2012-11-28 15:47:07 +00:00
renderSystem - > DrawSmallChar ( LOCALSAFE_LEFT + ( x + 1 ) * SMALLCHAR_WIDTH , idMath : : Ftoi ( y ) , text_p [ x ] & 0xff ) ;
2012-11-26 18:58:24 +00:00
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
// draw the input prompt, user text, and cursor if desired
DrawInput ( ) ;
2019-11-11 19:27:44 +00:00
2021-02-25 18:30:07 +00:00
renderSystem - > SetColor ( colorWhite ) ;
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = =
Draw
ForceFullScreen is used by the editor
= = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : Draw ( bool forceFullScreen )
{
2013-09-21 12:12:42 +00:00
Resize ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( forceFullScreen )
{
// if we are forced full screen because of a disconnect,
2012-11-26 18:58:24 +00:00
// we want the console closed when we go back to a session state
Close ( ) ;
// we are however catching keyboard input
keyCatching = true ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
Scroll ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
UpdateDisplayFraction ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
if ( forceFullScreen )
{
2012-11-26 18:58:24 +00:00
DrawSolidConsole ( 1.0f ) ;
2012-11-28 15:47:07 +00:00
}
else if ( displayFrac )
{
2012-11-26 18:58:24 +00:00
DrawSolidConsole ( displayFrac ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
// only draw the notify lines if the developer cvar is set,
// or we are a debug build
2012-11-28 15:47:07 +00:00
if ( ! con_noPrint . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
DrawNotify ( ) ;
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
float lefty = LOCALSAFE_TOP ;
float righty = LOCALSAFE_TOP ;
float centery = LOCALSAFE_TOP ;
2020-03-29 15:12:11 +00:00
2012-11-28 15:47:07 +00:00
if ( com_showFPS . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
righty = DrawFPS ( righty ) ;
}
2012-11-28 15:47:07 +00:00
if ( com_showMemoryUsage . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
righty = DrawMemoryUsage ( righty ) ;
}
2020-03-29 15:12:11 +00:00
2012-11-26 18:58:24 +00:00
DrawOverlayText ( lefty , righty , centery ) ;
DrawDebugGraphs ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
idConsoleLocal : : PrintOverlay
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : PrintOverlay ( idOverlayHandle & handle , justify_t justify , const char * text , . . . )
{
if ( handle . index > = 0 & & handle . index < overlayText . Num ( ) )
{
if ( overlayText [ handle . index ] . time = = handle . time )
{
2012-11-26 18:58:24 +00:00
return ;
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
char string [ MAX_PRINT_MSG ] ;
va_list argptr ;
va_start ( argptr , text ) ;
idStr : : vsnPrintf ( string , sizeof ( string ) , text , argptr ) ;
va_end ( argptr ) ;
2019-11-11 19:27:44 +00:00
2012-11-28 15:47:07 +00:00
overlayText_t & overlay = overlayText . Alloc ( ) ;
2012-11-26 18:58:24 +00:00
overlay . text = string ;
overlay . justify = justify ;
overlay . time = Sys_Milliseconds ( ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
handle . index = overlayText . Num ( ) - 1 ;
handle . time = overlay . time ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idConsoleLocal : : DrawOverlayText
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawOverlayText ( float & leftY , float & rightY , float & centerY )
{
for ( int i = 0 ; i < overlayText . Num ( ) ; i + + )
{
const idStr & text = overlayText [ i ] . text ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
int maxWidth = 0 ;
int numLines = 0 ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < text . Length ( ) ; j + + )
{
2012-11-26 18:58:24 +00:00
int width = 1 ;
2012-11-28 15:47:07 +00:00
for ( ; j < text . Length ( ) & & text [ j ] ! = ' \n ' ; j + + )
{
2012-11-26 18:58:24 +00:00
width + + ;
}
numLines + + ;
2012-11-28 15:47:07 +00:00
if ( width > maxWidth )
{
2012-11-26 18:58:24 +00:00
maxWidth = width ;
}
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idVec4 bgColor ( 0.0f , 0.0f , 0.0f , 0.75f ) ;
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
const float width = maxWidth * SMALLCHAR_WIDTH ;
const float height = numLines * ( SMALLCHAR_HEIGHT + 4 ) ;
const float bgAdjust = - 0.5f * SMALLCHAR_WIDTH ;
2012-11-28 15:47:07 +00:00
if ( overlayText [ i ] . justify = = JUSTIFY_LEFT )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( bgColor , LOCALSAFE_LEFT + bgAdjust , leftY , width , height ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_RIGHT )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( bgColor , LOCALSAFE_RIGHT - width + bgAdjust , rightY , width , height ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_CENTER_LEFT | | overlayText [ i ] . justify = = JUSTIFY_CENTER_RIGHT )
{
2012-11-26 18:58:24 +00:00
renderSystem - > DrawFilled ( bgColor , LOCALSAFE_LEFT + ( LOCALSAFE_WIDTH - width + bgAdjust ) * 0.5f , centerY , width , height ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
assert ( false ) ;
}
2019-11-11 19:27:44 +00:00
2012-11-26 18:58:24 +00:00
idStr singleLine ;
2012-11-28 15:47:07 +00:00
for ( int j = 0 ; j < text . Length ( ) ; j + = singleLine . Length ( ) + 1 )
{
2012-11-26 18:58:24 +00:00
singleLine = " " ;
2012-11-28 15:47:07 +00:00
for ( int k = j ; k < text . Length ( ) & & text [ k ] ! = ' \n ' ; k + + )
{
2012-11-26 18:58:24 +00:00
singleLine . Append ( text [ k ] ) ;
}
2012-11-28 15:47:07 +00:00
if ( overlayText [ i ] . justify = = JUSTIFY_LEFT )
{
2012-11-26 18:58:24 +00:00
DrawTextLeftAlign ( LOCALSAFE_LEFT , leftY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_RIGHT )
{
2012-11-26 18:58:24 +00:00
DrawTextRightAlign ( LOCALSAFE_RIGHT , rightY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_CENTER_LEFT )
{
2012-11-26 18:58:24 +00:00
DrawTextLeftAlign ( LOCALSAFE_LEFT + ( LOCALSAFE_WIDTH - width ) * 0.5f , centerY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( overlayText [ i ] . justify = = JUSTIFY_CENTER_RIGHT )
{
2012-11-26 18:58:24 +00:00
DrawTextRightAlign ( LOCALSAFE_LEFT + ( LOCALSAFE_WIDTH + width ) * 0.5f , centerY , " %s " , singleLine . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
assert ( false ) ;
}
}
}
overlayText . SetNum ( 0 ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idConsoleLocal : : CreateGraph
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
idDebugGraph * idConsoleLocal : : CreateGraph ( int numItems )
{
idDebugGraph * graph = new ( TAG_SYSTEM ) idDebugGraph ( numItems ) ;
2012-11-26 18:58:24 +00:00
debugGraphs . Append ( graph ) ;
return graph ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idConsoleLocal : : DestroyGraph
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DestroyGraph ( idDebugGraph * graph )
{
2012-11-26 18:58:24 +00:00
debugGraphs . Remove ( graph ) ;
delete graph ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
2012-11-28 15:47:07 +00:00
idConsoleLocal : : DrawDebugGraphs
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idConsoleLocal : : DrawDebugGraphs ( )
{
for ( int i = 0 ; i < debugGraphs . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
debugGraphs [ i ] - > Render ( renderSystem ) ;
}
2012-12-21 03:52:56 +00:00
}