//Anything above this #include will be ignored by the compiler #include "../qcommon/exe_headers.h" // console.c #include "client.h" #include "../qcommon/stringed_ingame.h" #include "../qcommon/game_version.h" #include "../cgame/cg_local.h" #include "../client/cl_data.h" #include "../renderer/tr_font.h" int g_console_field_width = 78; console_t con; cvar_t *con_conspeed; cvar_t *con_notifytime; #define DEFAULT_CONSOLE_WIDTH 78 /* ================ Con_Clear_f ================ */ void Con_Clear_f (void) { int i; for ( i = 0 ; i < CON_TEXTSIZE ; i++ ) { con.text[i] = (ColorIndex(COLOR_WHITE)<<8) | ' '; } Con_Bottom(); // go to end } /* ================ Con_ClearNotify ================ */ void Con_ClearNotify( void ) { int i; for ( i = 0 ; i < NUM_CON_TIMES ; i++ ) { con.times[i] = 0; } } /* ================ Con_CheckResize If the line width has changed, reformat the buffer. ================ */ void Con_CheckResize (void) { int i, j, width, oldwidth, oldtotallines, numlines, numchars; MAC_STATIC short tbuf[CON_TEXTSIZE]; // width = (SCREEN_WIDTH / SMALLCHAR_WIDTH) - 2; width = (cls.glconfig.vidWidth / SMALLCHAR_WIDTH) - 2; if (width == con.linewidth) return; if (width < 1) // video hasn't been initialized yet { con.xadjust = 1; con.yadjust = 1; width = DEFAULT_CONSOLE_WIDTH; con.linewidth = width; con.totallines = CON_TEXTSIZE / con.linewidth; for(i=0; i= 0 && !silent ) { con.times[con.current % NUM_CON_TIMES] = cls.realtime; } else { con.times[con.current % NUM_CON_TIMES] = 0; } con.x = 0; if (con.display == con.current) con.display++; con.current++; for(i=0; iinteger ) { return; } if (!con.initialized) { con.color[0] = con.color[1] = con.color[2] = con.color[3] = 1.0f; con.linewidth = -1; Con_CheckResize (); con.initialized = qtrue; } color = ColorIndex(COLOR_WHITE); #ifdef _XBOX // client to use if(ClientManager::splitScreenMode == qtrue) { y = con.current % con.totallines; con.text[y*con.linewidth+con.x] = (ClientManager::ActiveClientNum() << 8) | '@'; con.x++; } #endif while ( (c = (unsigned char) *txt) != 0 ) { if ( Q_IsColorString( (unsigned char*) txt ) ) { color = ColorIndex( *(txt+1) ); txt += 2; continue; } // count word length for (l=0 ; l< con.linewidth ; l++) { if ( txt[l] <= ' ') { break; } } // word wrap if (l != con.linewidth && (con.x + l >= con.linewidth) ) { Con_Linefeed(silent); } txt++; switch (c) { case '\n': Con_Linefeed (silent); break; case '\r': con.x = 0; break; default: // display character and advance y = con.current % con.totallines; con.text[y*con.linewidth+con.x] = (short) ((color << 8) | c); con.x++; if (con.x >= con.linewidth) { Con_Linefeed(silent); con.x = 0; } break; } } // mark time for transparent overlay if (con.current >= 0 && !silent ) { con.times[con.current % NUM_CON_TIMES] = cls.realtime; } else { con.times[con.current % NUM_CON_TIMES] = 0; } } /* ============================================================================== DRAWING ============================================================================== */ /* ================ Con_DrawInput Draw the editline after a ] prompt ================ */ void Con_DrawInput (void) { /* int y; if ( cls.state != CA_DISCONNECTED && !(cls.keyCatchers & KEYCATCH_CONSOLE ) ) { return; } y = con.vislines - ( SMALLCHAR_HEIGHT * (re.Language_IsAsian() ? 1.5 : 2) ); re.SetColor( con.color ); SCR_DrawSmallChar( (int)(con.xadjust + 1 * SMALLCHAR_WIDTH), y, ']' ); Field_Draw( &kg.g_consoleField, (int)(con.xadjust + 2 * SMALLCHAR_WIDTH), y, SCREEN_WIDTH - 3 * SMALLCHAR_WIDTH, qtrue ); */ } /* ================ Con_DrawNotify Draws the last few lines of output transparently over the game top ================ */ void Con_DrawNotify (void) { int x, y; short *text; int i; int time; int currentColor; int xStart; char lineBuf[256]; int lineLen; currentColor = 7; #ifdef _XBOX int curClient = ClientManager::ActiveClientNum(); #endif // Implicitly checks for split screen mode: if( ClientManager::ActiveClientNum() == 1 ) y = 250; else y = 40; for ( i = con.current-NUM_CON_TIMES+1; i <= con.current; i++ ) { if (/*cl->snap.ps.pm_type != PM_INTERMISSION &&*/ cls.keyCatchers & (KEYCATCH_UI | KEYCATCH_CGAME) ) continue; if(cg->scoreBoardShowing) continue; if (i < 0) continue; time = con.times[i % NUM_CON_TIMES]; if (time == 0) continue; time = cls.realtime - time; if (time > con_notifytime->value*1000) continue; text = con.text + (i % con.totallines)*con.linewidth; xStart = cl_conXOffset->integer + con.xadjust + 58; // Some arbitrary nonsense lineBuf[0] = 0; lineLen = 0; // Scan through characters: for (x = 0 ; x < con.linewidth ; x++) { #ifdef _XBOX if(ClientManager::splitScreenMode == qtrue) { if ( ( ((char)text[x]) == '@') ) { curClient = (text[x] >> 8)&7; if (curClient < 0 || curClient >= ClientManager::NumClients()) // Safety check curClient = 0; //st--; continue; } } #endif // New color: if ( ( (text[x]>>8)&7 ) != currentColor ) { // Draw whatever we've copied thus far: lineBuf[lineLen] = 0; RE_Font_DrawString( xStart, y, lineBuf, g_color_table[currentColor], 1, -1, 1.0f ); xStart += RE_Font_StrLenPixels( lineBuf, 1, 1.0f ); // Switch colors, and reset lineBuf: currentColor = (text[x]>>8)&7; lineBuf[0] = 0; lineLen = 0; } // All other characters just get copied into lineBuf: lineBuf[lineLen++] = (text[x] & 0xFF); } if (curClient != ClientManager::ActiveClientNum()) continue; if(ClientManager::splitScreenMode == qtrue && cg->showScores == qtrue) continue; // Draw whatever we left in lineBuf from the last iteration: lineBuf[lineLen] = 0; RE_Font_DrawString( xStart, y, lineBuf, g_color_table[currentColor], 1, -1, 1.0f ); y += RE_Font_HeightPixels( 1, 1.0f ); } } /* ================== Con_DrawConsole ================== */ void Con_DrawConsole( void ) { // check for console width changes from a vid mode change Con_CheckResize (); // Xbox - always just run in notify mode Con_DrawNotify(); } //================================================================ void Con_PageUp( void ) { con.display -= 2; if ( con.current - con.display >= con.totallines ) { con.display = con.current - con.totallines + 1; } } void Con_PageDown( void ) { con.display += 2; if (con.display > con.current) { con.display = con.current; } } void Con_Top( void ) { con.display = con.totallines; if ( con.current - con.display >= con.totallines ) { con.display = con.current - con.totallines + 1; } } void Con_Bottom( void ) { con.display = con.current; } void Con_Close( void ) { if ( !com_cl_running->integer ) { return; } Field_Clear( &kg.g_consoleField ); Con_ClearNotify (); cls.keyCatchers &= ~KEYCATCH_CONSOLE; con.finalFrac = 0; // none visible con.displayFrac = 0; }