mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Added FPS counter
This commit is contained in:
parent
7fb383c810
commit
cf51e14cf5
8 changed files with 109 additions and 383 deletions
|
@ -29,14 +29,10 @@ key up events are sent even if in console mode
|
|||
|
||||
*/
|
||||
|
||||
field_t historyEditLines[COMMAND_HISTORY];
|
||||
|
||||
int nextHistoryLine; // the last line in the history buffer, not masked
|
||||
int historyLine; // the line being displayed from history buffer
|
||||
// will be <= nextHistoryLine
|
||||
|
||||
field_t g_consoleField;
|
||||
field_t chatField;
|
||||
qboolean chat_team;
|
||||
|
||||
int chat_playerNum;
|
||||
|
@ -1198,136 +1194,3 @@ Key_SetCatcher
|
|||
void Key_SetCatcher( int catcher ) {
|
||||
keyCatchers = catcher;
|
||||
}
|
||||
|
||||
// This must not exceed MAX_CMD_LINE
|
||||
#define MAX_CONSOLE_SAVE_BUFFER 1024
|
||||
#define CONSOLE_HISTORY_FILE "omhistory"
|
||||
static char consoleSaveBuffer[ MAX_CONSOLE_SAVE_BUFFER ];
|
||||
static int consoleSaveBufferSize = 0;
|
||||
|
||||
/*
|
||||
================
|
||||
CL_LoadConsoleHistory
|
||||
|
||||
Load the console history from cl_consoleHistory
|
||||
================
|
||||
*/
|
||||
void CL_LoadConsoleHistory( void )
|
||||
{
|
||||
const char *token;
|
||||
char *text_p;
|
||||
int i, numChars, numLines = 0;
|
||||
fileHandle_t f;
|
||||
|
||||
consoleSaveBufferSize = FS_FOpenFileRead( CONSOLE_HISTORY_FILE, &f, qfalse, qtrue );
|
||||
if( !f )
|
||||
{
|
||||
Com_Printf( "Couldn't read %s.\n", CONSOLE_HISTORY_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
if( consoleSaveBufferSize <= MAX_CONSOLE_SAVE_BUFFER &&
|
||||
FS_Read( consoleSaveBuffer, consoleSaveBufferSize, f ) == consoleSaveBufferSize )
|
||||
{
|
||||
text_p = consoleSaveBuffer;
|
||||
|
||||
for( i = COMMAND_HISTORY - 1; i >= 0; i-- )
|
||||
{
|
||||
if( !*( token = COM_Parse( &text_p ) ) )
|
||||
break;
|
||||
|
||||
historyEditLines[ i ].cursor = atoi( token );
|
||||
|
||||
if( !*( token = COM_Parse( &text_p ) ) )
|
||||
break;
|
||||
|
||||
historyEditLines[ i ].scroll = atoi( token );
|
||||
|
||||
if( !*( token = COM_Parse( &text_p ) ) )
|
||||
break;
|
||||
|
||||
numChars = atoi( token );
|
||||
text_p++;
|
||||
if( numChars > ( strlen( consoleSaveBuffer ) - ( text_p - consoleSaveBuffer ) ) )
|
||||
{
|
||||
Com_DPrintf( S_COLOR_YELLOW "WARNING: probable corrupt history\n" );
|
||||
break;
|
||||
}
|
||||
Com_Memcpy( historyEditLines[ i ].buffer,
|
||||
text_p, numChars );
|
||||
historyEditLines[ i ].buffer[ numChars ] = '\0';
|
||||
text_p += numChars;
|
||||
|
||||
numLines++;
|
||||
}
|
||||
|
||||
memmove( &historyEditLines[ 0 ], &historyEditLines[ i + 1 ],
|
||||
numLines * sizeof( field_t ) );
|
||||
for( i = numLines; i < COMMAND_HISTORY; i++ )
|
||||
Field_Clear( &historyEditLines[ i ] );
|
||||
|
||||
historyLine = nextHistoryLine = numLines;
|
||||
}
|
||||
else
|
||||
Com_Printf( "Couldn't read %s.\n", CONSOLE_HISTORY_FILE );
|
||||
|
||||
FS_FCloseFile( f );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_SaveConsoleHistory
|
||||
|
||||
Save the console history into the cvar cl_consoleHistory
|
||||
so that it persists across invocations of q3
|
||||
================
|
||||
*/
|
||||
void CL_SaveConsoleHistory( void )
|
||||
{
|
||||
int i;
|
||||
int lineLength, saveBufferLength, additionalLength;
|
||||
fileHandle_t f;
|
||||
|
||||
consoleSaveBuffer[ 0 ] = '\0';
|
||||
|
||||
i = ( nextHistoryLine - 1 ) % COMMAND_HISTORY;
|
||||
do
|
||||
{
|
||||
if( historyEditLines[ i ].buffer[ 0 ] )
|
||||
{
|
||||
lineLength = strlen( historyEditLines[ i ].buffer );
|
||||
saveBufferLength = strlen( consoleSaveBuffer );
|
||||
|
||||
//ICK
|
||||
additionalLength = lineLength + strlen( "999 999 999 " );
|
||||
|
||||
if( saveBufferLength + additionalLength < MAX_CONSOLE_SAVE_BUFFER )
|
||||
{
|
||||
Q_strcat( consoleSaveBuffer, MAX_CONSOLE_SAVE_BUFFER,
|
||||
va( "%d %d %d %s ",
|
||||
historyEditLines[ i ].cursor,
|
||||
historyEditLines[ i ].scroll,
|
||||
lineLength,
|
||||
historyEditLines[ i ].buffer ) );
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
i = ( i - 1 + COMMAND_HISTORY ) % COMMAND_HISTORY;
|
||||
}
|
||||
while( i != ( nextHistoryLine - 1 ) % COMMAND_HISTORY );
|
||||
|
||||
consoleSaveBufferSize = strlen( consoleSaveBuffer );
|
||||
|
||||
f = FS_FOpenFileWrite( CONSOLE_HISTORY_FILE );
|
||||
if( !f )
|
||||
{
|
||||
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
|
||||
return;
|
||||
}
|
||||
|
||||
if( FS_Write( consoleSaveBuffer, consoleSaveBufferSize, f ) < consoleSaveBufferSize )
|
||||
Com_Printf( "Couldn't write %s.\n", CONSOLE_HISTORY_FILE );
|
||||
|
||||
FS_FCloseFile( f );
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ void CL_ShutdownUI( void );
|
|||
//
|
||||
extern inventory_t client_inv;
|
||||
extern bind_t client_bind;
|
||||
extern cvar_t* cl_greenfps;
|
||||
|
||||
const char *CvarGetForUI( const char *name, const char *defval );
|
||||
void UI_ClearState( void );
|
||||
|
|
|
@ -126,7 +126,72 @@ void View3D::DrawFPS
|
|||
)
|
||||
|
||||
{
|
||||
// FIXME: stub
|
||||
char string[128];
|
||||
|
||||
setFont("verdana-14");
|
||||
if (fps->integer == 2)
|
||||
{
|
||||
re.SetColor(UBlack);
|
||||
re.DrawBox(
|
||||
0.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
|
||||
m_frame.pos.x + m_frame.size.width,
|
||||
m_font->getHeight(qfalse) * 4.0
|
||||
);
|
||||
}
|
||||
|
||||
sprintf(string, "FPS %4.1f", currentfps);
|
||||
if (currentfps > 23.94) {
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
} else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
} else if (currentfps > 18.0) {
|
||||
m_font->setColor(UYellow);
|
||||
} else {
|
||||
// low fps
|
||||
m_font->setColor(URed);
|
||||
}
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
// Draw elements count
|
||||
if (cl_greenfps->integer) {
|
||||
m_font->setColor(UGreen);
|
||||
}
|
||||
else {
|
||||
m_font->setColor(UWhite);
|
||||
}
|
||||
|
||||
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
|
||||
|
||||
|
||||
m_font->Print(
|
||||
m_font->getHeight(qfalse) * 10.0,
|
||||
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
|
||||
string,
|
||||
-1,
|
||||
qfalse
|
||||
);
|
||||
|
||||
m_font->setColor(UBlack);
|
||||
}
|
||||
|
||||
void View3D::DrawProf
|
||||
|
|
|
@ -578,9 +578,6 @@ void Con_PageDown( void );
|
|||
void Con_Top( void );
|
||||
void Con_Bottom( void );
|
||||
|
||||
void CL_LoadConsoleHistory( void );
|
||||
void CL_SaveConsoleHistory( void );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
//
|
||||
|
|
|
@ -34,17 +34,6 @@ typedef struct {
|
|||
extern qboolean key_overstrikeMode;
|
||||
extern qkey_t keys[K_LASTKEY];
|
||||
|
||||
// NOTE TTimo the declaration of field_t and Field_Clear is now in qcommon/qcommon.h
|
||||
void Field_KeyDownEvent( field_t *edit, int key );
|
||||
void Field_CharEvent( field_t *edit, int ch );
|
||||
void Field_Draw(fontInfo_t *font, field_t *edit, int x, int y, int width, qboolean showCursor, qboolean noColorEscape );
|
||||
void Field_BigDraw(fontInfo_t *font, field_t *edit, int x, int y, int width, qboolean showCursor, qboolean noColorEscape );
|
||||
|
||||
#define COMMAND_HISTORY 32
|
||||
extern field_t historyEditLines[COMMAND_HISTORY];
|
||||
|
||||
extern field_t g_consoleField;
|
||||
extern field_t chatField;
|
||||
extern int anykeydown;
|
||||
extern qboolean chat_team;
|
||||
extern int chat_playerNum;
|
||||
|
|
|
@ -31,6 +31,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
// FPS
|
||||
#include <chrono>
|
||||
|
||||
#include <tiki.h>
|
||||
|
||||
qboolean CL_FinishedIntro(void);
|
||||
|
@ -72,7 +75,6 @@ fileHandle_t com_journalDataFile; // config files are written here
|
|||
cvar_t *paused;
|
||||
cvar_t *config;
|
||||
cvar_t *fps;
|
||||
float currentfps;
|
||||
cvar_t *com_speeds;
|
||||
cvar_t *developer;
|
||||
cvar_t *com_dedicated;
|
||||
|
@ -126,6 +128,18 @@ static char *rd_buffer;
|
|||
static int rd_buffersize;
|
||||
static void (*rd_flush)( char *buffer );
|
||||
|
||||
#define MAX_FPS_TIMES 16
|
||||
|
||||
using fps_clock_t = std::chrono::high_resolution_clock;
|
||||
using fps_time_t = fps_clock_t::time_point;
|
||||
using fps_delta_t = fps_clock_t::duration;
|
||||
|
||||
static int fpsindex;
|
||||
static fps_delta_t fpstimes[MAX_FPS_TIMES];
|
||||
static fps_delta_t fpstotal;
|
||||
static fps_time_t fpslasttime;
|
||||
float currentfps;
|
||||
|
||||
void Com_BeginRedirect (char *buffer, int buffersize, void (*flush)( char *) )
|
||||
{
|
||||
if (!buffer || !buffersize || !flush)
|
||||
|
@ -1752,6 +1766,22 @@ void Com_Frame( void ) {
|
|||
com_frameNumber, all, sv, ev, cl, time_game, time_frontend, time_backend );
|
||||
}
|
||||
|
||||
if (fps->integer) {
|
||||
fps_time_t fpstime = fps_clock_t::now();
|
||||
fps_delta_t delta = fpstime - fpslasttime;
|
||||
|
||||
fpstotal = (fpstime - fpslasttime) + (fpstotal - fpstimes[fpsindex]);
|
||||
fpstimes[fpsindex] = fpstime - fpslasttime;
|
||||
fpsindex = (fpsindex + 1) % MAX_FPS_TIMES;
|
||||
fpslasttime = fpstime;
|
||||
|
||||
if (fpstotal.count()) {
|
||||
currentfps = 16.0 / std::chrono::duration<long double>(fpstotal).count();
|
||||
} else {
|
||||
currentfps = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// trace optimization tracking
|
||||
//
|
||||
|
@ -1893,23 +1923,10 @@ command line completion
|
|||
===========================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
Field_Clear
|
||||
==================
|
||||
*/
|
||||
void Field_Clear( field_t *edit ) {
|
||||
memset(edit->buffer, 0, MAX_EDIT_LINE);
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
static const char *completionString;
|
||||
static char shortestMatch[MAX_TOKEN_CHARS];
|
||||
static int matchCount;
|
||||
// field we are working on, passed to Field_AutoComplete(&g_consoleCommand for instance)
|
||||
static field_t *completionField;
|
||||
|
||||
/*
|
||||
===============
|
||||
FindMatches
|
||||
|
@ -1968,200 +1985,4 @@ static void PrintCvarMatches( const char *s ) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_FindFirstSeparator
|
||||
===============
|
||||
*/
|
||||
static char *Field_FindFirstSeparator( char *s )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < strlen( s ); i++ )
|
||||
{
|
||||
if( s[ i ] == ';' )
|
||||
return &s[ i ];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef DEDICATED
|
||||
/*
|
||||
===============
|
||||
Field_CompleteKeyname
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteKeyname( void )
|
||||
{
|
||||
matchCount = 0;
|
||||
shortestMatch[ 0 ] = 0;
|
||||
|
||||
Key_KeynameCompletion( FindMatches );
|
||||
|
||||
if( matchCount == 0 )
|
||||
return;
|
||||
|
||||
Q_strncpyz( &completionField->buffer[ strlen( completionField->buffer ) -
|
||||
strlen( completionString ) ], shortestMatch,
|
||||
sizeof( completionField->buffer ) );
|
||||
completionField->cursor = ( int )strlen( completionField->buffer );
|
||||
|
||||
if( matchCount == 1 )
|
||||
{
|
||||
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
|
||||
completionField->cursor++;
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf( "]%s\n", completionField->buffer );
|
||||
|
||||
Key_KeynameCompletion( PrintMatches );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_CompleteFilename
|
||||
===============
|
||||
*/
|
||||
static void Field_CompleteFilename( const char *dir,
|
||||
const char *ext, qboolean stripExt )
|
||||
{
|
||||
size_t pos;
|
||||
|
||||
matchCount = 0;
|
||||
shortestMatch[ 0 ] = 0;
|
||||
|
||||
FS_FilenameCompletion( dir, ext, stripExt, FindMatches );
|
||||
|
||||
if( matchCount == 0 )
|
||||
return;
|
||||
|
||||
pos = strlen( completionField->buffer ) - strlen( completionString );
|
||||
Q_strncpyz( &completionField->buffer[ pos ], shortestMatch,
|
||||
sizeof( completionField->buffer ) - pos );
|
||||
completionField->cursor = ( int )strlen( completionField->buffer );
|
||||
|
||||
if( matchCount == 1 )
|
||||
{
|
||||
Q_strcat( completionField->buffer, sizeof( completionField->buffer ), " " );
|
||||
completionField->cursor++;
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf( "]%s\n", completionField->buffer );
|
||||
|
||||
FS_FilenameCompletion( dir, ext, stripExt, PrintMatches );
|
||||
}
|
||||
|
||||
static void keyConcatArgs(void) {
|
||||
int i;
|
||||
char* arg;
|
||||
|
||||
for (i = 1; i < Cmd_Argc(); i++) {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
|
||||
arg = Cmd_Argv(i);
|
||||
while (*arg) {
|
||||
if (*arg == ' ') {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
}
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), Cmd_Argv(i));
|
||||
if (*arg == ' ') {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ConcatRemaining(const char* src, const char* start) {
|
||||
const char* str;
|
||||
|
||||
str = strstr(src, start);
|
||||
if (!str) {
|
||||
keyConcatArgs();
|
||||
return;
|
||||
}
|
||||
|
||||
str += strlen(start);
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), str);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_CompleteCommand
|
||||
|
||||
perform Tab expansion
|
||||
NOTE TTimo this was originally client code only
|
||||
moved to common code when writing tty console for *nix dedicated server
|
||||
===============
|
||||
*/
|
||||
void Field_CompleteCommand(field_t* field) {
|
||||
field_t temp;
|
||||
|
||||
completionField = field;
|
||||
|
||||
// only look at the first token for completion purposes
|
||||
Cmd_TokenizeString(completionField->buffer);
|
||||
|
||||
completionString = Cmd_Argv(0);
|
||||
if (completionString[0] == '\\' || completionString[0] == '/') {
|
||||
completionString++;
|
||||
}
|
||||
matchCount = 0;
|
||||
shortestMatch[0] = 0;
|
||||
|
||||
if (strlen(completionString) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Cmd_CommandCompletion(FindMatches);
|
||||
Cvar_CommandCompletion(FindMatches);
|
||||
|
||||
if (matchCount == 0) {
|
||||
return; // no matches
|
||||
}
|
||||
|
||||
Com_Memcpy(&temp, completionField, sizeof(field_t));
|
||||
|
||||
if (matchCount == 1) {
|
||||
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
|
||||
if (Cmd_Argc() == 1) {
|
||||
Q_strcat(completionField->buffer, sizeof(completionField->buffer), " ");
|
||||
}
|
||||
else {
|
||||
ConcatRemaining(temp.buffer, completionString);
|
||||
}
|
||||
completionField->cursor = strlen(completionField->buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Com_sprintf(completionField->buffer, sizeof(completionField->buffer), "\\%s", shortestMatch);
|
||||
completionField->cursor = strlen(completionField->buffer);
|
||||
ConcatRemaining(temp.buffer, completionString);
|
||||
|
||||
Com_Printf("]%s\n", completionField->buffer);
|
||||
|
||||
// run through again, printing matches
|
||||
Cmd_CommandCompletion(PrintMatches);
|
||||
Cvar_CommandCompletion(PrintMatches);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Field_AutoComplete
|
||||
|
||||
Perform Tab expansion
|
||||
===============
|
||||
*/
|
||||
void Field_AutoComplete( field_t *field )
|
||||
{
|
||||
completionField = field;
|
||||
|
||||
Field_CompleteCommand(field);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -798,26 +798,6 @@ MISC
|
|||
/*
|
||||
==============================================================
|
||||
|
||||
Edit fields and command line history/completion
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
|
||||
#define MAX_EDIT_LINE 256
|
||||
typedef struct {
|
||||
int cursor;
|
||||
int scroll;
|
||||
int widthInChars;
|
||||
char buffer[MAX_EDIT_LINE];
|
||||
} field_t;
|
||||
|
||||
void Field_Clear( field_t *edit );
|
||||
void Field_CompleteCommand( field_t *edit );
|
||||
void Field_AutoComplete( field_t *edit );
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
MISC
|
||||
|
||||
==============================================================
|
||||
|
@ -882,10 +862,10 @@ void Com_StartupVariable( const char *match );
|
|||
// only a set with the exact name. Only used during startup.
|
||||
|
||||
|
||||
extern float currentfps;
|
||||
extern cvar_t *paused;
|
||||
extern cvar_t *config;
|
||||
extern cvar_t *fps;
|
||||
extern float currentfps;
|
||||
extern cvar_t *developer;
|
||||
extern cvar_t *com_dedicated;
|
||||
extern cvar_t *com_speeds;
|
||||
|
|
|
@ -42,6 +42,16 @@ R_PerformanceCounters
|
|||
=====================
|
||||
*/
|
||||
void R_PerformanceCounters( void ) {
|
||||
if (fps->integer) {
|
||||
ri.SetPerformanceCounters(
|
||||
backEnd.pc.c_totalIndexes / 3,
|
||||
backEnd.pc.c_vertexes,
|
||||
R_SumOfUsedImages(pc_save.c_totalIndexes / 3, pc_save.c_vertexes),
|
||||
pc_save.c_totalIndexes / 3,
|
||||
pc_save.c_vertexes,
|
||||
backEnd.pc.c_characterlights
|
||||
);
|
||||
}
|
||||
if ( !r_speeds->integer ) {
|
||||
// clear the counters even if we aren't printing
|
||||
Com_Memset( &tr.pc, 0, sizeof( tr.pc ) );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue