codemp/ui/ui_atoms.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 /**********************************************************************
00004         UI_ATOMS.C
00005 
00006         User interface building blocks and support functions.
00007 **********************************************************************/
00008 #include "ui_local.h"
00009 
00010 qboolean                m_entersound;           // after a frame, so caching won't disrupt the sound
00011 
00012 // these are here so the functions in q_shared.c can link
00013 #ifndef UI_HARD_LINKED
00014 
00015 void QDECL Com_Error( int level, const char *error, ... ) {
00016         va_list         argptr;
00017         char            text[1024];
00018 
00019         va_start (argptr, error);
00020         vsprintf (text, error, argptr);
00021         va_end (argptr);
00022 
00023         trap_Error( va("%s", text) );
00024 }
00025 
00026 void QDECL Com_Printf( const char *msg, ... ) {
00027         va_list         argptr;
00028         char            text[1024];
00029 
00030         va_start (argptr, msg);
00031         vsprintf (text, msg, argptr);
00032         va_end (argptr);
00033 
00034         trap_Print( va("%s", text) );
00035 }
00036 
00037 #endif
00038 
00039 qboolean newUI = qfalse;
00040 
00041 
00042 /*
00043 =================
00044 UI_ClampCvar
00045 =================
00046 */
00047 float UI_ClampCvar( float min, float max, float value )
00048 {
00049         if ( value < min ) return min;
00050         if ( value > max ) return max;
00051         return value;
00052 }
00053 
00054 /*
00055 =================
00056 UI_StartDemoLoop
00057 =================
00058 */
00059 void UI_StartDemoLoop( void ) {
00060         trap_Cmd_ExecuteText( EXEC_APPEND, "d1\n" );
00061 }
00062 
00063 
00064 char *UI_Argv( int arg ) {
00065         static char     buffer[MAX_STRING_CHARS];
00066 
00067         trap_Argv( arg, buffer, sizeof( buffer ) );
00068 
00069         return buffer;
00070 }
00071 
00072 
00073 char *UI_Cvar_VariableString( const char *var_name ) {
00074         static char     buffer[MAX_STRING_CHARS];
00075 
00076         trap_Cvar_VariableStringBuffer( var_name, buffer, sizeof( buffer ) );
00077 
00078         return buffer;
00079 }
00080 
00081 
00082 
00083 void UI_SetBestScores(postGameInfo_t *newInfo, qboolean postGame) {
00084         trap_Cvar_Set("ui_scoreAccuracy",     va("%i%%", newInfo->accuracy));
00085         trap_Cvar_Set("ui_scoreImpressives",    va("%i", newInfo->impressives));
00086         trap_Cvar_Set("ui_scoreExcellents",     va("%i", newInfo->excellents));
00087         trap_Cvar_Set("ui_scoreDefends",                        va("%i", newInfo->defends));
00088         trap_Cvar_Set("ui_scoreAssists",                        va("%i", newInfo->assists));
00089         trap_Cvar_Set("ui_scoreGauntlets",              va("%i", newInfo->gauntlets));
00090         trap_Cvar_Set("ui_scoreScore",                          va("%i", newInfo->score));
00091         trap_Cvar_Set("ui_scorePerfect",                        va("%i", newInfo->perfects));
00092         trap_Cvar_Set("ui_scoreTeam",                                   va("%i to %i", newInfo->redScore, newInfo->blueScore));
00093         trap_Cvar_Set("ui_scoreBase",                                   va("%i", newInfo->baseScore));
00094         trap_Cvar_Set("ui_scoreTimeBonus",              va("%i", newInfo->timeBonus));
00095         trap_Cvar_Set("ui_scoreSkillBonus",             va("%i", newInfo->skillBonus));
00096         trap_Cvar_Set("ui_scoreShutoutBonus",   va("%i", newInfo->shutoutBonus));
00097         trap_Cvar_Set("ui_scoreTime",                                   va("%02i:%02i", newInfo->time / 60, newInfo->time % 60));
00098         trap_Cvar_Set("ui_scoreCaptures",               va("%i", newInfo->captures));
00099   if (postGame) {
00100                 trap_Cvar_Set("ui_scoreAccuracy2",     va("%i%%", newInfo->accuracy));
00101                 trap_Cvar_Set("ui_scoreImpressives2",   va("%i", newInfo->impressives));
00102                 trap_Cvar_Set("ui_scoreExcellents2",    va("%i", newInfo->excellents));
00103                 trap_Cvar_Set("ui_scoreDefends2",                       va("%i", newInfo->defends));
00104                 trap_Cvar_Set("ui_scoreAssists2",                       va("%i", newInfo->assists));
00105                 trap_Cvar_Set("ui_scoreGauntlets2",             va("%i", newInfo->gauntlets));
00106                 trap_Cvar_Set("ui_scoreScore2",                                 va("%i", newInfo->score));
00107                 trap_Cvar_Set("ui_scorePerfect2",                       va("%i", newInfo->perfects));
00108                 trap_Cvar_Set("ui_scoreTeam2",                                  va("%i to %i", newInfo->redScore, newInfo->blueScore));
00109                 trap_Cvar_Set("ui_scoreBase2",                                  va("%i", newInfo->baseScore));
00110                 trap_Cvar_Set("ui_scoreTimeBonus2",             va("%i", newInfo->timeBonus));
00111                 trap_Cvar_Set("ui_scoreSkillBonus2",            va("%i", newInfo->skillBonus));
00112                 trap_Cvar_Set("ui_scoreShutoutBonus2",  va("%i", newInfo->shutoutBonus));
00113                 trap_Cvar_Set("ui_scoreTime2",                                  va("%02i:%02i", newInfo->time / 60, newInfo->time % 60));
00114                 trap_Cvar_Set("ui_scoreCaptures2",              va("%i", newInfo->captures));
00115         }
00116 }
00117 
00118 void UI_LoadBestScores(const char *map, int game) {
00119         char            fileName[MAX_QPATH];
00120         fileHandle_t f;
00121         postGameInfo_t newInfo;
00122         memset(&newInfo, 0, sizeof(postGameInfo_t));
00123         Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game);
00124         if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
00125                 int size = 0;
00126                 trap_FS_Read(&size, sizeof(int), f);
00127                 if (size == sizeof(postGameInfo_t)) {
00128                         trap_FS_Read(&newInfo, sizeof(postGameInfo_t), f);
00129                 }
00130                 trap_FS_FCloseFile(f);
00131         }
00132         UI_SetBestScores(&newInfo, qfalse);
00133 
00134         Com_sprintf(fileName, MAX_QPATH, "demos/%s_%d.dm_%d", map, game, (int)trap_Cvar_VariableValue("protocol"));
00135         uiInfo.demoAvailable = qfalse;
00136         if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
00137                 uiInfo.demoAvailable = qtrue;
00138                 trap_FS_FCloseFile(f);
00139         } 
00140 }
00141 
00142 /*
00143 ===============
00144 UI_ClearScores
00145 ===============
00146 */
00147 void UI_ClearScores() {
00148         char    gameList[4096];
00149         char *gameFile;
00150         int             i, len, count, size;
00151         fileHandle_t f;
00152         postGameInfo_t newInfo;
00153 
00154         count = trap_FS_GetFileList( "games", "game", gameList, sizeof(gameList) );
00155 
00156         size = sizeof(postGameInfo_t);
00157         memset(&newInfo, 0, size);
00158 
00159         if (count > 0) {
00160                 gameFile = gameList;
00161                 for ( i = 0; i < count; i++ ) {
00162                         len = strlen(gameFile);
00163                         if (trap_FS_FOpenFile(va("games/%s",gameFile), &f, FS_WRITE) >= 0) {
00164                                 trap_FS_Write(&size, sizeof(int), f);
00165                                 trap_FS_Write(&newInfo, size, f);
00166                                 trap_FS_FCloseFile(f);
00167                         }
00168                         gameFile += len + 1;
00169                 }
00170         }
00171         
00172         UI_SetBestScores(&newInfo, qfalse);
00173 
00174 }
00175 
00176 
00177 
00178 static void     UI_Cache_f() {
00179         int i;
00180         Display_CacheAll();
00181         if (trap_Argc() == 2) {
00182                 for (i = 0; i < uiInfo.q3HeadCount; i++)
00183                 {
00184                         trap_Print( va("model %s\n", uiInfo.q3HeadNames[i]) );
00185                 }
00186         }
00187 }
00188 
00189 /*
00190 =======================
00191 UI_CalcPostGameStats
00192 =======================
00193 */
00194 static void UI_CalcPostGameStats() {
00195         char            map[MAX_QPATH];
00196         char            fileName[MAX_QPATH];
00197         char            info[MAX_INFO_STRING];
00198         fileHandle_t f;
00199         int size, game, time, adjustedTime;
00200         postGameInfo_t oldInfo;
00201         postGameInfo_t newInfo;
00202         qboolean newHigh = qfalse;
00203 
00204         trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
00205         Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) );
00206         game = atoi(Info_ValueForKey(info, "g_gametype"));
00207 
00208         // compose file name
00209         Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game);
00210         // see if we have one already
00211         memset(&oldInfo, 0, sizeof(postGameInfo_t));
00212         if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
00213         // if so load it
00214                 size = 0;
00215                 trap_FS_Read(&size, sizeof(int), f);
00216                 if (size == sizeof(postGameInfo_t)) {
00217                         trap_FS_Read(&oldInfo, sizeof(postGameInfo_t), f);
00218                 }
00219                 trap_FS_FCloseFile(f);
00220         }                                        
00221 
00222         newInfo.accuracy = atoi(UI_Argv(3));
00223         newInfo.impressives = atoi(UI_Argv(4));
00224         newInfo.excellents = atoi(UI_Argv(5));
00225         newInfo.defends = atoi(UI_Argv(6));
00226         newInfo.assists = atoi(UI_Argv(7));
00227         newInfo.gauntlets = atoi(UI_Argv(8));
00228         newInfo.baseScore = atoi(UI_Argv(9));
00229         newInfo.perfects = atoi(UI_Argv(10));
00230         newInfo.redScore = atoi(UI_Argv(11));
00231         newInfo.blueScore = atoi(UI_Argv(12));
00232         time = atoi(UI_Argv(13));
00233         newInfo.captures = atoi(UI_Argv(14));
00234 
00235         newInfo.time = (time - trap_Cvar_VariableValue("ui_matchStartTime")) / 1000;
00236         adjustedTime = uiInfo.mapList[ui_currentMap.integer].timeToBeat[game];
00237         if (newInfo.time < adjustedTime) { 
00238                 newInfo.timeBonus = (adjustedTime - newInfo.time) * 10;
00239         } else {
00240                 newInfo.timeBonus = 0;
00241         }
00242 
00243         if (newInfo.redScore > newInfo.blueScore && newInfo.blueScore <= 0) {
00244                 newInfo.shutoutBonus = 100;
00245         } else {
00246                 newInfo.shutoutBonus = 0;
00247         }
00248 
00249         newInfo.skillBonus = trap_Cvar_VariableValue("g_spSkill");
00250         if (newInfo.skillBonus <= 0) {
00251                 newInfo.skillBonus = 1;
00252         }
00253         newInfo.score = newInfo.baseScore + newInfo.shutoutBonus + newInfo.timeBonus;
00254         newInfo.score *= newInfo.skillBonus;
00255 
00256         // see if the score is higher for this one
00257         newHigh = (newInfo.redScore > newInfo.blueScore && newInfo.score > oldInfo.score);
00258 
00259         if  (newHigh) {
00260                 // if so write out the new one
00261                 uiInfo.newHighScoreTime = uiInfo.uiDC.realTime + 20000;
00262                 if (trap_FS_FOpenFile(fileName, &f, FS_WRITE) >= 0) {
00263                         size = sizeof(postGameInfo_t);
00264                         trap_FS_Write(&size, sizeof(int), f);
00265                         trap_FS_Write(&newInfo, sizeof(postGameInfo_t), f);
00266                         trap_FS_FCloseFile(f);
00267                 }
00268         }
00269 
00270         if (newInfo.time < oldInfo.time) {
00271                 uiInfo.newBestTime = uiInfo.uiDC.realTime + 20000;
00272         }
00273  
00274         // put back all the ui overrides
00275         trap_Cvar_Set("capturelimit", UI_Cvar_VariableString("ui_saveCaptureLimit"));
00276         trap_Cvar_Set("fraglimit", UI_Cvar_VariableString("ui_saveFragLimit"));
00277         trap_Cvar_Set("duel_fraglimit", UI_Cvar_VariableString("ui_saveDuelLimit"));
00278         trap_Cvar_Set("cg_drawTimer", UI_Cvar_VariableString("ui_drawTimer"));
00279         trap_Cvar_Set("g_doWarmup", UI_Cvar_VariableString("ui_doWarmup"));
00280         trap_Cvar_Set("g_Warmup", UI_Cvar_VariableString("ui_Warmup"));
00281         trap_Cvar_Set("sv_pure", UI_Cvar_VariableString("ui_pure"));
00282         trap_Cvar_Set("g_friendlyFire", UI_Cvar_VariableString("ui_friendlyFire"));
00283 
00284         UI_SetBestScores(&newInfo, qtrue);
00285         UI_ShowPostGame(newHigh);
00286 
00287 
00288 }
00289 
00290 
00291 /*
00292 =================
00293 UI_ConsoleCommand
00294 =================
00295 */
00296 qboolean UI_ConsoleCommand( int realTime ) {
00297         char    *cmd;
00298 
00299         uiInfo.uiDC.frameTime = realTime - uiInfo.uiDC.realTime;
00300         uiInfo.uiDC.realTime = realTime;
00301 
00302         cmd = UI_Argv( 0 );
00303 
00304         // ensure minimum menu data is available
00305         //Menu_Cache();
00306 
00307         if ( Q_stricmp (cmd, "ui_test") == 0 ) {
00308                 UI_ShowPostGame(qtrue);
00309         }
00310 
00311         if ( Q_stricmp (cmd, "ui_report") == 0 ) {
00312                 UI_Report();
00313                 return qtrue;
00314         }
00315         
00316         if ( Q_stricmp (cmd, "ui_load") == 0 ) {
00317                 UI_Load();
00318                 return qtrue;
00319         }
00320 
00321         if ( Q_stricmp (cmd, "ui_opensiegemenu" ) == 0 ) 
00322         {
00323                 if ( trap_Cvar_VariableValue ( "g_gametype" ) == GT_SIEGE )
00324                 {
00325                         Menus_CloseAll();
00326                         if (Menus_ActivateByName(UI_Argv(1)))
00327                         {
00328                                 trap_Key_SetCatcher( KEYCATCH_UI );
00329                         }
00330                 }
00331                 return qtrue;
00332         }
00333 
00334         if ( Q_stricmp (cmd, "ui_openmenu" ) == 0 ) 
00335         {
00336                 //if ( trap_Cvar_VariableValue ( "developer" ) )
00337                 {
00338                         Menus_CloseAll();
00339                         if (Menus_ActivateByName(UI_Argv(1)))
00340                         {
00341                                 trap_Key_SetCatcher( KEYCATCH_UI );
00342                         }
00343                         return qtrue;
00344                 }
00345         }
00346 
00347         /*
00348         if ( Q_stricmp (cmd, "remapShader") == 0 ) {
00349                 if (trap_Argc() == 4) {
00350                         char shader1[MAX_QPATH];
00351                         char shader2[MAX_QPATH];
00352                         Q_strncpyz(shader1, UI_Argv(1), sizeof(shader1));
00353                         Q_strncpyz(shader2, UI_Argv(2), sizeof(shader2));
00354                         trap_R_RemapShader(shader1, shader2, UI_Argv(3));
00355                         return qtrue;
00356                 }
00357         }
00358         */
00359 
00360         if ( Q_stricmp (cmd, "postgame") == 0 ) {
00361                 UI_CalcPostGameStats();
00362                 return qtrue;
00363         }
00364 
00365         if ( Q_stricmp (cmd, "ui_cache") == 0 ) {
00366                 UI_Cache_f();
00367                 return qtrue;
00368         }
00369 
00370         if ( Q_stricmp (cmd, "ui_teamOrders") == 0 ) {
00371                 //UI_TeamOrdersMenu_f();
00372                 return qtrue;
00373         }
00374 
00375 
00376         if ( Q_stricmp (cmd, "ui_cdkey") == 0 ) {
00377                 //UI_CDKeyMenu_f();
00378                 return qtrue;
00379         }
00380 
00381         return qfalse;
00382 }
00383 
00384 /*
00385 =================
00386 UI_Shutdown
00387 =================
00388 */
00389 void UI_Shutdown( void ) {
00390 }
00391 
00392 
00393 void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ) {
00394         qhandle_t       hShader;
00395 
00396         hShader = trap_R_RegisterShaderNoMip( picname );
00397         trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
00398 }
00399 
00400 void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ) {
00401         float   s0;
00402         float   s1;
00403         float   t0;
00404         float   t1;
00405 
00406         if( w < 0 ) {   // flip about vertical
00407                 w  = -w;
00408                 s0 = 1;
00409                 s1 = 0;
00410         }
00411         else {
00412                 s0 = 0;
00413                 s1 = 1;
00414         }
00415 
00416         if( h < 0 ) {   // flip about horizontal
00417                 h  = -h;
00418                 t0 = 1;
00419                 t1 = 0;
00420         }
00421         else {
00422                 t0 = 0;
00423                 t1 = 1;
00424         }
00425         
00426         trap_R_DrawStretchPic( x, y, w, h, s0, t0, s1, t1, hShader );
00427 }
00428 
00429 /*
00430 ================
00431 UI_FillRect
00432 
00433 Coordinates are 640*480 virtual values
00434 =================
00435 */
00436 void UI_FillRect( float x, float y, float width, float height, const float *color ) {
00437         trap_R_SetColor( color );
00438 
00439         trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00440 
00441         trap_R_SetColor( NULL );
00442 }
00443 
00444 void UI_DrawSides(float x, float y, float w, float h) {
00445         trap_R_DrawStretchPic( x, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00446         trap_R_DrawStretchPic( x + w - 1, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00447 }
00448 
00449 void UI_DrawTopBottom(float x, float y, float w, float h) {
00450         trap_R_DrawStretchPic( x, y, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00451         trap_R_DrawStretchPic( x, y + h - 1, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
00452 }
00453 /*
00454 ================
00455 UI_DrawRect
00456 
00457 Coordinates are 640*480 virtual values
00458 =================
00459 */
00460 void UI_DrawRect( float x, float y, float width, float height, const float *color ) {
00461         trap_R_SetColor( color );
00462 
00463   UI_DrawTopBottom(x, y, width, height);
00464   UI_DrawSides(x, y, width, height);
00465 
00466         trap_R_SetColor( NULL );
00467 }
00468 
00469 void UI_SetColor( const float *rgba ) {
00470         trap_R_SetColor( rgba );
00471 }
00472 
00473 void UI_UpdateScreen( void ) {
00474         trap_UpdateScreen();
00475 }
00476 
00477 
00478 void UI_DrawTextBox (int x, int y, int width, int lines)
00479 {
00480         UI_FillRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorBlack );
00481         UI_DrawRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorWhite );
00482 }
00483 
00484 qboolean UI_CursorInRect (int x, int y, int width, int height)
00485 {
00486         if (uiInfo.uiDC.cursorx < x ||
00487                 uiInfo.uiDC.cursory < y ||
00488                 uiInfo.uiDC.cursorx > x+width ||
00489                 uiInfo.uiDC.cursory > y+height)
00490                 return qfalse;
00491 
00492         return qtrue;
00493 }