jedioutcast/code/ui/ui_main.cpp
2013-04-04 13:24:26 -05:00

2590 lines
63 KiB
C++

// Copyright (C) 1999-2000 Id Software, Inc.
//
/*
=======================================================================
USER INTERFACE MAIN
=======================================================================
*/
// leave this at the top of all UI_xxxx files for PCH reasons...
//
#include "../server/exe_headers.h"
#include "ui_local.h"
#include "menudef.h"
#include "ui_shared.h"
#include "../qcommon/stv_version.h"
#define LISTBUFSIZE 10240
static struct
{
char listBuf[LISTBUFSIZE]; // The list of file names read in
// For scrolling through file names
int currentLine; // Index to currentSaveFileComments[] currently highlighted
int saveFileCnt; // Number of save files read in
int awaitingSave; // Flag to see if user wants to overwrite a game.
char *savegameMap;
int savegameFromFlag;
} s_savegame;
#define MAX_SAVELOADFILES 100
#define MAX_SAVELOADNAME 32
byte screenShotBuf[SG_SCR_WIDTH * SG_SCR_HEIGHT * 4];
typedef struct
{
char *currentSaveFileName; // file name of savegame
char currentSaveFileComments[iSG_COMMENT_SIZE]; // file comment
char currentSaveFileDateTimeString[iSG_COMMENT_SIZE]; // file time and date
time_t currentSaveFileDateTime;
char currentSaveFileMap[MAX_TOKEN_CHARS]; // map save game is from
} savedata_t;
static savedata_t s_savedata[MAX_SAVELOADFILES];
void UI_SetActiveMenu( const char* menuname,const char *menuID );
void ReadSaveDirectory (void);
qboolean Asset_Parse(char **buffer);
menuDef_t *Menus_FindByName(const char *p);
void Menus_HideItems(const char *menuName);
int Text_Height(const char *text, float scale, int iFontIndex );
int Text_Width(const char *text, float scale, int iFontIndex );
void _UI_DrawTopBottom(float x, float y, float w, float h, float size);
void _UI_DrawSides(float x, float y, float w, float h, float size);
void UI_CheckVid1Data(const char *menuTo,const char *warningMenuName);
void UI_GetVideoSetup ( void );
void UI_UpdateVideoSetup ( void );
void UI_LoadMenus(const char *menuFile, qboolean reset);
static void UI_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle, int iFontIndex);
static qboolean UI_OwnerDrawVisible(int flags);
int UI_OwnerDrawWidth(int ownerDraw, float scale);
static void UI_Update(const char *name);
void UI_UpdateCvars( void );
void UI_ResetDefaults( void );
static int gamecodetoui[] = {4,2,3,0,5,1,6};
uiInfo_t uiInfo;
static void UI_RegisterCvars( void );
void UI_Load(void);
typedef struct {
vmCvar_t *vmCvar;
char *cvarName;
char *defaultString;
int cvarFlags;
} cvarTable_t;
vmCvar_t ui_drawCrosshair;
vmCvar_t ui_drawCrosshairNames;
vmCvar_t ui_marks;
vmCvar_t ui_menuFiles;
vmCvar_t ui_smallFont;
vmCvar_t ui_bigFont;
vmCvar_t ui_hudFiles;
cvarTable_t cvarTable[] =
{
{ &ui_drawCrosshair, "cg_drawCrosshair", "1", CVAR_ARCHIVE },
{ &ui_marks, "cg_marks", "1", CVAR_ARCHIVE },
{ &ui_menuFiles, "ui_menuFiles", "ui/menus.txt", CVAR_ARCHIVE },
{ &ui_smallFont, "ui_smallFont", "0.25", CVAR_ARCHIVE},
{ &ui_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE},
{ &ui_hudFiles, "cg_hudFiles", "ui/jk2hud.txt",CVAR_ARCHIVE},
};
int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]);
void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, int iMaxPixelWidth, int style, int iFontIndex);
int Key_GetCatcher( void );
#define UI_FPS_FRAMES 4
void _UI_Refresh( int realtime )
{
static int index;
static int previousTimes[UI_FPS_FRAMES];
if ( !( Key_GetCatcher() & KEYCATCH_UI ) )
{
return;
}
extern void SP_CheckForLanguageUpdates(void);
SP_CheckForLanguageUpdates();
uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
uiInfo.uiDC.realTime = realtime;
previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
index++;
if ( index > UI_FPS_FRAMES )
{
int i, total;
// average multiple frames together to smooth changes out a bit
total = 0;
for ( i = 0 ; i < UI_FPS_FRAMES ; i++ )
{
total += previousTimes[i];
}
if ( !total )
{
total = 1;
}
uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total;
}
UI_UpdateCvars();
if (Menu_Count() > 0)
{
// paint all the menus
Menu_PaintAll();
// refresh server browser list
// UI_DoServerRefresh();
// refresh server status
// UI_BuildServerStatus(qfalse);
// refresh find player list
// UI_BuildFindPlayerList(qfalse);
}
// draw cursor
UI_SetColor( NULL );
if (Menu_Count() > 0)
{
if (uiInfo.uiDC.cursorShow == qtrue)
{
UI_DrawHandlePic( uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory, 48, 48, uiInfo.uiDC.Assets.cursor);
}
}
}
/*
================
vmMain
This is the only way control passes into the module.
This must be the very first function compiled into the .qvm file
================
*/
int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 )
{
return 0;
}
/*
================
Text_PaintChar
================
*/
/*
static void Text_PaintChar(float x, float y, float width, float height, float scale, float s, float t, float s2, float t2, qhandle_t hShader)
{
float w, h;
w = width * scale;
h = height * scale;
ui.R_DrawStretchPic((int)x, (int)y, w, h, s, t, s2, t2, hShader ); //make the coords (int) or else the chars bleed
}
*/
/*
================
Text_Paint
================
*/
// iMaxPixelWidth is 0 here for no limit (but gets converted to -1), else max printable pixel width relative to start pos
//
void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, int iMaxPixelWidth, int style, int iFontIndex)
{
if (iFontIndex == 0)
{
iFontIndex = uiInfo.uiDC.Assets.qhMediumFont;
}
// kludge.. convert JK2 menu styles to SOF2 printstring ctrl codes...
//
int iStyleOR = 0;
switch (style)
{
// case ITEM_TEXTSTYLE_NORMAL: iStyleOR = 0;break; // JK2 normal text
// case ITEM_TEXTSTYLE_BLINK: iStyleOR = STYLE_BLINK;break; // JK2 fast blinking
case ITEM_TEXTSTYLE_PULSE: iStyleOR = STYLE_BLINK;break; // JK2 slow pulsing
case ITEM_TEXTSTYLE_SHADOWED: iStyleOR = STYLE_DROPSHADOW;break; // JK2 drop shadow ( need a color for this )
case ITEM_TEXTSTYLE_OUTLINED: iStyleOR = STYLE_DROPSHADOW;break; // JK2 drop shadow ( need a color for this )
case ITEM_TEXTSTYLE_OUTLINESHADOWED: iStyleOR = STYLE_DROPSHADOW;break; // JK2 drop shadow ( need a color for this )
case ITEM_TEXTSTYLE_SHADOWEDMORE: iStyleOR = STYLE_DROPSHADOW;break; // JK2 drop shadow ( need a color for this )
}
ui.R_Font_DrawString( x, // int ox
y, // int oy
text, // const char *text
color, // paletteRGBA_c c
iStyleOR | iFontIndex, // const int iFontHandle
!iMaxPixelWidth?-1:iMaxPixelWidth, // iMaxPixelWidth (-1 = none)
scale // const float scale = 1.0f
);
}
/*
================
Text_PaintWithCursor
================
*/
// iMaxPixelWidth is 0 here for no-limit
void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int iMaxPixelWidth, int style, int iFontIndex)
{
Text_Paint(x, y, scale, color, text, iMaxPixelWidth, style, iFontIndex);
// now print the cursor as well...
//
char sTemp[1024];
int iCopyCount = min(strlen(text), cursorPos);
iCopyCount = min(iCopyCount,sizeof(sTemp));
// copy text into temp buffer for pixel measure...
//
strncpy(sTemp,text,iCopyCount);
sTemp[iCopyCount] = '\0';
int iNextXpos = ui.R_Font_StrLenPixels(sTemp, iFontIndex, scale );
Text_Paint(x+iNextXpos, y, scale, color, va("%c",cursor), iMaxPixelWidth, style|ITEM_TEXTSTYLE_BLINK, iFontIndex);
}
const char *UI_FeederItemText(float feederID, int index, int column, qhandle_t *handle)
{
*handle = -1;
if (feederID == FEEDER_SAVEGAMES)
{
if (column==0)
{
return s_savedata[index].currentSaveFileComments;
}
else
{
return s_savedata[index].currentSaveFileDateTimeString;
}
}
if (feederID == FEEDER_MODS)
{
return "";
}
/* if (feederID == FEEDER_MAPS)
{
int actual;
return UI_SelectedMap(index, &actual);
}
else if (feederID == FEEDER_MODS)
{
if (index >= 0 && index < uiInfo.modCount)
{
if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr)
{
return uiInfo.modList[index].modDescr;
}
else
{
return uiInfo.modList[index].modName;
}
}
}
else if (feederID == FEEDER_DEMOS)
{
if (index >= 0 && index < uiInfo.demoCount)
{
return uiInfo.demoList[index];
}
}
*/
return "";
}
qhandle_t UI_FeederItemImage(float feederID, int index)
{
if (feederID == FEEDER_SAVEGAMES)
{
/*
if (index >= 0 && index < uiInfo.characterCount)
{
if (uiInfo.characterList[index].headImage == -1)
{
uiInfo.characterList[index].headImage = trap_R_RegisterShaderNoMip(uiInfo.characterList[index].imageName);
}
return uiInfo.characterList[index].headImage;
}*/
}
/* else if (feederID == FEEDER_Q3HEADS)
{
if (index >= 0 && index < uiInfo.q3HeadCount)
{
return uiInfo.q3HeadIcons[index];
}
}
else if (feederID == FEEDER_ALLMAPS || feederID == FEEDER_MAPS)
{
int actual;
UI_SelectedMap(index, &actual);
index = actual;
if (index >= 0 && index < uiInfo.mapCount)
{
if (uiInfo.mapList[index].levelShot == -1)
{
uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName);
}
return uiInfo.mapList[index].levelShot;
}
}
*/
return 0;
}
/*
=================
CreateNextSaveName
=================
*/
static int CreateNextSaveName(char *fileName)
{
int i;
// Loop through all the save games and look for the first open name
for (i=0;i<MAX_SAVELOADFILES;i++)
{
Com_sprintf( fileName, MAX_SAVELOADNAME, "jkii%02d", i );
if (!ui.SG_GetSaveGameComment(fileName, NULL, NULL))
{
return qtrue;
}
}
return qfalse;
}
/*
===============
UI_DeferMenuScript
Return true if the menu script should be deferred for later
===============
*/
static qboolean UI_DeferMenuScript ( const char **args )
{
const char* name;
// Whats the reason for being deferred?
if (!String_Parse(args, &name))
{
return qfalse;
}
// Handle the custom cases
if ( !Q_stricmp ( name, "VideoSetup" ) )
{
const char* warningMenuName;
qboolean deferred;
// No warning menu specified
if ( !String_Parse(args, &warningMenuName) )
{
return qfalse;
}
// Defer if the video options were modified
deferred = Cvar_VariableIntegerValue( "ui_r_modified" ) ? qtrue : qfalse;
if ( deferred )
{
// Open the warning menu
Menus_OpenByName(warningMenuName);
}
return deferred;
}
return qfalse;
}
/*
===============
UI_RunMenuScript
===============
*/
static qboolean UI_RunMenuScript ( const char **args )
{
const char *name, *name2,*mapName,*menuName,*warningMenuName;
if (String_Parse(args, &name))
{
if (Q_stricmp(name, "resetdefaults") == 0)
{
UI_ResetDefaults();
}
else if (Q_stricmp(name, "saveControls") == 0)
{
Controls_SetConfig(qtrue);
}
else if (Q_stricmp(name, "loadControls") == 0)
{
Controls_GetConfig();
}
else if (Q_stricmp(name, "clearError") == 0)
{
Cvar_Set("com_errorMessage", "");
}
else if (Q_stricmp(name, "ReadSaveDirectory") == 0)
{
s_savegame.saveFileCnt = -1; //force a refresh at drawtime
// ReadSaveDirectory();
}
else if (Q_stricmp(name, "loadAuto") == 0)
{
Menus_CloseAll();
ui.Cmd_ExecuteText( EXEC_APPEND, "load auto\n");
}
else if (Q_stricmp(name, "loadgame") == 0)
{
if (s_savedata[s_savegame.currentLine].currentSaveFileName)// && (*s_file_desc_field.field.buffer))
{
Menus_CloseAll();
ui.Cmd_ExecuteText( EXEC_APPEND, va("load %s\n", s_savedata[s_savegame.currentLine].currentSaveFileName));
}
}
else if (Q_stricmp(name, "deletegame") == 0)
{
if (s_savedata[s_savegame.currentLine].currentSaveFileName) // A line was chosen
{
ui.Printf( va("%s\n","Attempting to delete game"));
ui.Cmd_ExecuteText( EXEC_NOW, va("wipe %s\n", s_savedata[s_savegame.currentLine].currentSaveFileName));
// ReadSaveDirectory(); //refresh
s_savegame.saveFileCnt = -1; //force a refresh at drawtime
}
}
else if (Q_stricmp(name, "savegame") == 0)
{
char fileName[MAX_SAVELOADNAME];
char description[64];
// Create a new save game
// if ( !s_savedata[s_savegame.currentLine].currentSaveFileName) // No line was chosen
{
CreateNextSaveName(fileName); // Get a name to save to
}
// else // Overwrite a current save game? Ask first.
{
// s_savegame.yes.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
// s_savegame.no.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
// strcpy(fileName,s_savedata[s_savegame.currentLine].currentSaveFileName);
// s_savegame.awaitingSave = qtrue;
// s_savegame.deletegame.generic.flags = QMF_GRAYED; // Turn off delete button
// break;
}
// Save description line
ui.Cvar_VariableStringBuffer("ui_gameDesc",description,sizeof(description));
ui.SG_StoreSaveGameComment(description);
ui.Cmd_ExecuteText( EXEC_APPEND, va("save %s\n", fileName));
s_savegame.saveFileCnt = -1; //force a refresh the next time around
}
// FIXME BOB - do we want this?
/*
else if (Q_stricmp(name, "LoadMods") == 0)
{
UI_LoadMods();
}
else if (Q_stricmp(name, "RunMod") == 0)
{
Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName);
Cbuf_ExecuteText( EXEC_APPEND, "vid_restart;" );
}
else if (Q_stricmp(name, "RunDemo") == 0)
{
Cbuf_ExecuteText( EXEC_APPEND, va("demo %s\n", uiInfo.demoList[uiInfo.demoIndex]));
} */
else if (Q_stricmp(name, "Quit") == 0)
{
Cbuf_ExecuteText( EXEC_NOW, "quit");
}
else if (Q_stricmp(name, "Controls") == 0)
{
Cvar_Set( "cl_paused", "1" );
trap_Key_SetCatcher( KEYCATCH_UI );
Menus_CloseAll();
Menus_ActivateByName("setup_menu2");
}
else if (Q_stricmp(name, "Leave") == 0)
{
Cbuf_ExecuteText( EXEC_APPEND, "disconnect\n" );
trap_Key_SetCatcher( KEYCATCH_UI );
Menus_CloseAll();
Menus_ActivateByName("mainMenu");
}
else if (Q_stricmp(name, "getvideosetup") == 0)
{
UI_GetVideoSetup ( );
}
else if (Q_stricmp(name, "updatevideosetup") == 0)
{
UI_UpdateVideoSetup ( );
}
else if (Q_stricmp(name, "nextDataPadForcePower") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "dpforcenext\n");
}
else if (Q_stricmp(name, "prevDataPadForcePower") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "dpforceprev\n");
}
else if (Q_stricmp(name, "nextDataPadWeapon") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "dpweapnext\n");
}
else if (Q_stricmp(name, "prevDataPadWeapon") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "dpweapprev\n");
}
else if (Q_stricmp(name, "nextDataPadInventory") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "dpinvnext\n");
}
else if (Q_stricmp(name, "prevDataPadInventory") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "dpinvprev\n");
}
else if (Q_stricmp(name, "checkvid1data") == 0) // Warn user data has changed before leaving screen?
{
String_Parse(args, &menuName);
String_Parse(args, &warningMenuName);
UI_CheckVid1Data(menuName,warningMenuName);
}
else if (Q_stricmp(name, "startgame") == 0)
{
Menus_CloseAll();
#ifdef FINAL_BUILD
ui.Cmd_ExecuteText( EXEC_APPEND, "map kejim_post\n");
#else
ui.Cmd_ExecuteText( EXEC_APPEND, "devmap kejim_post\n");
#endif
}
else if (Q_stricmp(name, "startmap") == 0)
{
Menus_CloseAll();
String_Parse(args, &mapName);
ui.Cmd_ExecuteText( EXEC_APPEND, va("map %s\n",mapName));
}
else if (Q_stricmp(name, "closeingame") == 0)
{
trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
trap_Key_ClearStates();
Cvar_Set( "cl_paused", "0" );
Menus_CloseAll();
Menus_ActivateByName("mainhud");
}
else if (Q_stricmp(name, "closedatapad") == 0)
{
trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
trap_Key_ClearStates();
Cvar_Set( "cl_paused", "0" );
Menus_CloseAll();
Menus_ActivateByName("mainhud");
Cvar_Set( "cg_updatedDataPadForcePower1", "0" );
Cvar_Set( "cg_updatedDataPadForcePower2", "0" );
Cvar_Set( "cg_updatedDataPadForcePower3", "0" );
Cvar_Set( "cg_updatedDataPadObjective", "0" );
}
else if (Q_stricmp(name, "glCustom") == 0)
{
Cvar_Set("ui_r_glCustom", "4");
}
else if (Q_stricmp(name, "update") == 0)
{
if (String_Parse(args, &name2))
{
UI_Update(name2);
}
else
{
Com_Printf("update missing cmd\n");
}
}
else
{
Com_Printf("unknown UI script %s\n", name);
}
}
return qtrue;
}
/*
=================
UI_GetValue
=================
*/
static float UI_GetValue(int ownerDraw)
{
return 0;
}
/*
=================
UI_StopCinematic
=================
*/
static void UI_StopCinematic(int handle)
{
if (handle >= 0)
{
trap_CIN_StopCinematic(handle);
}
else
{
handle = abs(handle);
if (handle == UI_MAPCINEMATIC)
{
// FIXME - BOB do we need this?
// if (uiInfo.mapList[ui_currentMap.integer].cinematic >= 0)
// {
// trap_CIN_StopCinematic(uiInfo.mapList[ui_currentMap.integer].cinematic);
// uiInfo.mapList[ui_currentMap.integer].cinematic = -1;
// }
}
else if (handle == UI_NETMAPCINEMATIC)
{
// FIXME - BOB do we need this?
// if (uiInfo.serverStatus.currentServerCinematic >= 0)
// {
// trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
// uiInfo.serverStatus.currentServerCinematic = -1;
// }
}
else if (handle == UI_CLANCINEMATIC)
{
// FIXME - BOB do we need this?
// int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
// if (i >= 0 && i < uiInfo.teamCount)
// {
// if (uiInfo.teamList[i].cinematic >= 0)
// {
// trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
// uiInfo.teamList[i].cinematic = -1;
// }
// }
}
}
}
static UI_HandleLoadSelection()
{
Cvar_Set("ui_SelectionOK", va("%d",(s_savegame.currentLine < s_savegame.saveFileCnt)) );
Cvar_Set("ui_gameDesc", s_savedata[s_savegame.currentLine].currentSaveFileComments ); // set comment
if (!ui.SG_GetSaveImage(s_savedata[s_savegame.currentLine].currentSaveFileName, &screenShotBuf))
{
memset( screenShotBuf,0,(SG_SCR_WIDTH * SG_SCR_HEIGHT * 4));
}
}
/*
=================
UI_FeederCount
=================
*/
static int UI_FeederCount(float feederID)
{
if (feederID == FEEDER_SAVEGAMES)
{
if (s_savegame.saveFileCnt == -1)
{
ReadSaveDirectory(); //refresh
UI_HandleLoadSelection();
}
return s_savegame.saveFileCnt;
}
else if (feederID == FEEDER_MODS)
{
return uiInfo.modCount;
}
else if (feederID == FEEDER_DEMOS)
{
return uiInfo.demoCount;
}
return 0;
}
/*
=================
UI_FeederSelection
=================
*/
static void UI_FeederSelection(float feederID, int index)
{
static char info[MAX_STRING_CHARS];
if (feederID == FEEDER_SAVEGAMES)
{
s_savegame.currentLine = index;
UI_HandleLoadSelection();
}
else if (feederID == FEEDER_MODS)
{
uiInfo.modIndex = index;
}
else if (feederID == FEEDER_CINEMATICS)
{
uiInfo.movieIndex = index;
if (uiInfo.previewMovie >= 0)
{
trap_CIN_StopCinematic(uiInfo.previewMovie);
}
uiInfo.previewMovie = -1;
}
else if (feederID == FEEDER_DEMOS)
{
uiInfo.demoIndex = index;
}
}
void Key_KeynumToStringBuf( int keynum, char *buf, int buflen );
void Key_GetBindingBuf( int keynum, char *buf, int buflen );
static qboolean UI_Crosshair_HandleKey(int flags, float *special, int key)
{
if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER)
{
if (key == K_MOUSE2)
{
uiInfo.currentCrosshair--;
} else {
uiInfo.currentCrosshair++;
}
if (uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
uiInfo.currentCrosshair = 0;
} else if (uiInfo.currentCrosshair < 0) {
uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1;
}
Cvar_Set("cg_drawCrosshair", va("%d", uiInfo.currentCrosshair));
return qtrue;
}
return qfalse;
}
static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key)
{
switch (ownerDraw)
{
case UI_CROSSHAIR:
UI_Crosshair_HandleKey(flags, special, key);
break;
default:
break;
}
return qfalse;
}
/*
=================
UI_Init
=================
*/
void _UI_Init( qboolean inGameLoad )
{
int start;
UI_RegisterCvars();
UI_InitMemory();
// cache redundant calulations
trap_GetGlconfig( &uiInfo.uiDC.glconfig );
// for 640x480 virtualized screen
uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0);
uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0);
if ( uiInfo.uiDC.glconfig.vidWidth * 480 > uiInfo.uiDC.glconfig.vidHeight * 640 )
{
// wide screen
uiInfo.uiDC.bias = 0.5 * ( uiInfo.uiDC.glconfig.vidWidth - ( uiInfo.uiDC.glconfig.vidHeight * (640.0/480.0) ) );
}
else
{
// no wide screen
uiInfo.uiDC.bias = 0;
}
Init_Display(&uiInfo.uiDC);
uiInfo.uiDC.drawText = &Text_Paint;
uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic;
uiInfo.uiDC.drawRect = &_UI_DrawRect;
uiInfo.uiDC.drawSides = &_UI_DrawSides;
uiInfo.uiDC.drawTextWithCursor = &Text_PaintWithCursor;
uiInfo.uiDC.executeText = &Cbuf_ExecuteText;
uiInfo.uiDC.drawTopBottom = &_UI_DrawTopBottom;
uiInfo.uiDC.feederCount = &UI_FeederCount;
uiInfo.uiDC.feederSelection = &UI_FeederSelection;
uiInfo.uiDC.fillRect = &UI_FillRect;
uiInfo.uiDC.getBindingBuf = &Key_GetBindingBuf;
uiInfo.uiDC.getCVarString = Cvar_VariableStringBuffer;
uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue;
uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
uiInfo.uiDC.getValue = &UI_GetValue;
uiInfo.uiDC.keynumToStringBuf = &Key_KeynumToStringBuf;
uiInfo.uiDC.modelBounds = &trap_R_ModelBounds;
uiInfo.uiDC.ownerDrawVisible = &UI_OwnerDrawVisible;
uiInfo.uiDC.ownerDrawWidth = &UI_OwnerDrawWidth;
uiInfo.uiDC.ownerDrawItem = &UI_OwnerDraw;
uiInfo.uiDC.Print = &Com_Printf;
uiInfo.uiDC.registerSound = &trap_S_RegisterSound;
uiInfo.uiDC.registerModel = ui.R_RegisterModel;
uiInfo.uiDC.clearScene = &trap_R_ClearScene;
uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
uiInfo.uiDC.renderScene = &trap_R_RenderScene;
uiInfo.uiDC.runScript = &UI_RunMenuScript;
uiInfo.uiDC.deferScript = &UI_DeferMenuScript;
uiInfo.uiDC.setBinding = &trap_Key_SetBinding;
uiInfo.uiDC.setColor = &UI_SetColor;
uiInfo.uiDC.setCVar = Cvar_Set;
uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound;
uiInfo.uiDC.stopCinematic = &UI_StopCinematic;
uiInfo.uiDC.textHeight = &Text_Height;
uiInfo.uiDC.textWidth = &Text_Width;
uiInfo.uiDC.feederItemImage = &UI_FeederItemImage;
uiInfo.uiDC.feederItemText = &UI_FeederItemText;
uiInfo.uiDC.ownerDrawHandleKey = &UI_OwnerDrawHandleKey;
UI_Load();
// String_Init();
uiInfo.uiDC.whiteShader = ui.R_RegisterShaderNoMip( "white" );
AssetCache();
start = Sys_Milliseconds();
uis.debugMode = qfalse;
Menus_CloseAll();
// sets defaults for ui temp cvars
uiInfo.effectsColor = (int)trap_Cvar_VariableValue("color")-1;
if (uiInfo.effectsColor < 0)
{
uiInfo.effectsColor = 0;
}
uiInfo.effectsColor = gamecodetoui[uiInfo.effectsColor];
uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair");
Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
Cvar_Set("cg_endcredits", "0"); // Reset value
// FIXME BOB - is this needed?
/*
uiInfo.serverStatus.currentServerCinematic = -1;
uiInfo.previewMovie = -1;
if (trap_Cvar_VariableValue("ui_TeamArenaFirstRun") == 0) {
Cvar_Set("s_volume", "0.8");
Cvar_Set("s_musicvolume", "0.5");
Cvar_Set("ui_TeamArenaFirstRun", "1");
}
Cvar_Register(NULL, "debug_protocol", "", 0 );
Cvar_Set("ui_actualNetGameType", va("%d", ui_netGameType.integer));
*/
}
/*
=================
UI_RegisterCvars
=================
*/
static void UI_RegisterCvars( void )
{
int i;
cvarTable_t *cv;
for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ )
{
Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags );
}
}
/*
=================
UI_ParseMenu
=================
*/
void UI_ParseMenu(const char *menuFile)
{
char *buffer,*holdBuffer,*token2;
int len;
// pc_token_t token;
Com_DPrintf("Parsing menu file:%s\n", menuFile);
len = PC_StartParseSession(menuFile,&buffer);
holdBuffer = buffer;
if (len<=0)
{
Com_Printf("UI_ParseMenu: Unable to load menu %s\n", menuFile);
return;
}
while ( 1 )
{
token2 = PC_ParseExt();
if (!*token2)
{
break;
}
/*
if ( menuCount == MAX_MENUS )
{
PC_ParseWarning("Too many menus!");
break;
}
*/
if ( *token2 == '{')
{
continue;
}
else if ( *token2 == '}' )
{
break;
}
else if (Q_stricmp(token2, "assetGlobalDef") == 0)
{
if (Asset_Parse(&holdBuffer))
{
continue;
}
else
{
break;
}
}
else if (Q_stricmp(token2, "menudef") == 0)
{
// start a new menu
Menu_New(holdBuffer);
continue;
}
PC_ParseWarning(va("Invalid keyword '%s'",token2));
}
PC_EndParseSession(buffer);
}
/*
=================
Load_Menu
Load current menu file
=================
*/
qboolean Load_Menu(const char **holdBuffer)
{
const char *token2;
token2 = COM_ParseExt( holdBuffer, qtrue );
if (!token2)
{
return qfalse;
}
if (*token2 != '{')
{
return qfalse;
}
while ( 1 )
{
token2 = COM_ParseExt( holdBuffer, qtrue );
if ((!token2) || (token2 == 0))
{
return qfalse;
}
if ( *token2 == '}' )
{
return qtrue;
}
//#ifdef _DEBUG
// extern void UI_Debug_AddMenuFilePath(const char *);
// UI_Debug_AddMenuFilePath(token2);
//#endif
UI_ParseMenu(token2);
}
return qfalse;
}
/*
=================
UI_LoadMenus
Load all menus based on the files listed in the data file in menuFile (default "ui/menus.txt")
=================
*/
void UI_LoadMenus(const char *menuFile, qboolean reset)
{
// pc_token_t token;
// int handle;
int start;
char *buffer;
const char *holdBuffer;
int len;
start = Sys_Milliseconds();
len = ui.FS_ReadFile(menuFile,(void **) &buffer);
if (len<1)
{
Com_Printf( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) );
len = ui.FS_ReadFile("ui/menus.txt",(void **) &buffer);
if (len<1)
{
Com_Error( ERR_FATAL, "%s", va("default menu file not found: ui/menus.txt, unable to continue!\n", menuFile ));
return;
}
}
if (reset)
{
Menu_Reset();
}
const char *token2;
holdBuffer = buffer;
while ( 1 )
{
token2 = COM_ParseExt( &holdBuffer, qtrue );
if (!*token2)
{
break;
}
if( *token2 == 0 || *token2 == '}') // End of the menus file
{
break;
}
if (*token2 == '{')
{
continue;
}
else if (Q_stricmp(token2, "loadmenu") == 0)
{
if (Load_Menu(&holdBuffer))
{
continue;
}
else
{
break;
}
}
else
{
Com_Printf("Unknown keyword '%s' in menus file %s\n", token2, menuFile);
}
}
Com_Printf("UI menu load time = %d milli seconds\n", Sys_Milliseconds() - start);
ui.FS_FreeFile( buffer ); //let go of the buffer
}
/*
=================
UI_Load
=================
*/
void UI_Load(void)
{
char lastName[1024];
menuDef_t *menu = Menu_GetFocused();
char *menuSet = UI_Cvar_VariableString("ui_menuFiles");
// sod it, parse every menu strip file until we find a gap in the sequence...
//
for (int i=0; i<10; i++)
{
if (!ui.SP_Register(va("menus%d",i), /*SP_REGISTER_REQUIRED|*/SP_REGISTER_MENU))
break;
}
if (menu && menu->window.name)
{
strcpy(lastName, menu->window.name);
}
if (menuSet == NULL || menuSet[0] == '\0')
{
menuSet = "ui/menus.txt";
}
String_Init();
// registeredFontCount = 0;
// UI_ParseGameInfo("gameinfo.txt");
///* UI_LoadArenas();
UI_LoadMenus(menuSet, qtrue);
// Menus_CloseAll();
}
/*
=================
Asset_Parse
=================
*/
qboolean Asset_Parse(char **buffer)
{
char *token;
char *tempStr;
int pointSize;
token = PC_ParseExt();
if (!token)
{
return qfalse;
}
if (*token != '{')
{
return qfalse;
}
while ( 1 )
{
token = PC_ParseExt();
if (!token)
{
return qfalse;
}
if (*token == '}')
{
return qtrue;
}
// font
if (Q_stricmp(token, "mediumFont") == 0)
{
if (!PC_ParseStringMem(&uiInfo.uiDC.Assets.fontStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'font'");
return qfalse;
}
if (PC_ParseInt(&pointSize))
{
PC_ParseWarning("Bad 2nd parameter for keyword 'font'");
return qfalse;
}
uiInfo.uiDC.Assets.qhMediumFont = UI_RegisterFont(uiInfo.uiDC.Assets.fontStr);
uiInfo.uiDC.Assets.fontRegistered = qtrue;
continue;
}
if (Q_stricmp(token, "smallFont") == 0)
{
if (!PC_ParseStringMem((const char **) &tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'smallFont'");
return qfalse;
}
if (PC_ParseInt(&pointSize))
{
PC_ParseWarning("Bad 2nd parameter for keyword 'smallFont'");
return qfalse;
}
uiInfo.uiDC.Assets.qhSmallFont = UI_RegisterFont(tempStr);
continue;
}
if (Q_stricmp(token, "bigFont") == 0)
{
if (!PC_ParseStringMem((const char **) &tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'bigFont'");
return qfalse;
}
if (PC_ParseInt(&pointSize))
{
PC_ParseWarning("Bad 2nd parameter for keyword 'bigFont'");
return qfalse;
}
// findmste
uiInfo.uiDC.Assets.qhBigFont = UI_RegisterFont(tempStr);//, pointSize, &uiInfo.uiDC.Assets.bigFont);
continue;
}
if (Q_stricmp(token, "stripedFile") == 0)
{
if (!PC_ParseStringMem((const char **) &tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'stripedFile'");
return qfalse;
}
char sTemp[1024];
Q_strncpyz( sTemp, tempStr, sizeof(sTemp) );
if (!ui.SP_Register(sTemp, /*SP_REGISTER_REQUIRED|*/SP_REGISTER_MENU))
{
PC_ParseWarning(va("(.SP file \"%s\" not found)",sTemp));
//return qfalse; // hmmm... dunno about this, don't want to break scripts for just missing subtitles
}
else
{
// extern void AddMenuPackageRetryKey(const char *);
// AddMenuPackageRetryKey(sTemp);
}
continue;
}
// gradientbar
if (Q_stricmp(token, "gradientbar") == 0)
{
if (!PC_ParseStringMem((const char **)&tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'gradientbar'");
return qfalse;
}
uiInfo.uiDC.Assets.gradientBar = ui.R_RegisterShaderNoMip(tempStr);
continue;
}
// enterMenuSound
if (Q_stricmp(token, "menuEnterSound") == 0)
{
if (!PC_ParseStringMem((const char **)&tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'menuEnterSound'");
return qfalse;
}
uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
// exitMenuSound
if (Q_stricmp(token, "menuExitSound") == 0)
{
if (!PC_ParseStringMem((const char **) &tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'menuExitSound'");
return qfalse;
}
uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
// itemFocusSound
if (Q_stricmp(token, "itemFocusSound") == 0)
{
if (!PC_ParseStringMem((const char **) &tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'itemFocusSound'");
return qfalse;
}
uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
// menuBuzzSound
if (Q_stricmp(token, "menuBuzzSound") == 0)
{
if (!PC_ParseStringMem((const char **) &tempStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'menuBuzzSound'");
return qfalse;
}
uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
if (Q_stricmp(token, "cursor") == 0)
{
if (!PC_ParseStringMem((const char **) &uiInfo.uiDC.Assets.cursorStr))
{
PC_ParseWarning("Bad 1st parameter for keyword 'cursor'");
return qfalse;
}
uiInfo.uiDC.Assets.cursor = ui.R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr);
continue;
}
if (Q_stricmp(token, "fadeClamp") == 0)
{
if (PC_ParseFloat(&uiInfo.uiDC.Assets.fadeClamp))
{
PC_ParseWarning("Bad 1st parameter for keyword 'fadeClamp'");
return qfalse;
}
continue;
}
if (Q_stricmp(token, "fadeCycle") == 0)
{
if (PC_ParseInt(&uiInfo.uiDC.Assets.fadeCycle))
{
PC_ParseWarning("Bad 1st parameter for keyword 'fadeCycle'");
return qfalse;
}
continue;
}
if (Q_stricmp(token, "fadeAmount") == 0)
{
if (PC_ParseFloat(&uiInfo.uiDC.Assets.fadeAmount))
{
PC_ParseWarning("Bad 1st parameter for keyword 'fadeAmount'");
return qfalse;
}
continue;
}
if (Q_stricmp(token, "shadowX") == 0)
{
if (PC_ParseFloat(&uiInfo.uiDC.Assets.shadowX))
{
PC_ParseWarning("Bad 1st parameter for keyword 'shadowX'");
return qfalse;
}
continue;
}
if (Q_stricmp(token, "shadowY") == 0)
{
if (PC_ParseFloat(&uiInfo.uiDC.Assets.shadowY))
{
PC_ParseWarning("Bad 1st parameter for keyword 'shadowY'");
return qfalse;
}
continue;
}
if (Q_stricmp(token, "shadowColor") == 0)
{
if (PC_ParseColor(&uiInfo.uiDC.Assets.shadowColor))
{
PC_ParseWarning("Bad 1st parameter for keyword 'shadowColor'");
return qfalse;
}
uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
continue;
}
}
PC_ParseWarning(va("Invalid keyword '%s'",token));
return qfalse;
}
/*
=================
UI_Update
=================
*/
static void UI_Update(const char *name)
{
int val = trap_Cvar_VariableValue(name);
if (Q_stricmp(name, "s_khz") == 0)
{
ui.Cmd_ExecuteText( EXEC_APPEND, "snd_restart\n" );
return;
}
if (Q_stricmp(name, "ui_SetName") == 0)
{
Cvar_Set( "name", UI_Cvar_VariableString("ui_Name"));
}
else if (Q_stricmp(name, "ui_setRate") == 0)
{
float rate = trap_Cvar_VariableValue("rate");
if (rate >= 5000)
{
Cvar_Set("cl_maxpackets", "30");
Cvar_Set("cl_packetdup", "1");
}
else if (rate >= 4000)
{
Cvar_Set("cl_maxpackets", "15");
Cvar_Set("cl_packetdup", "2"); // favor less prediction errors when there's packet loss
}
else
{
Cvar_Set("cl_maxpackets", "15");
Cvar_Set("cl_packetdup", "1"); // favor lower bandwidth
}
}
else if (Q_stricmp(name, "ui_GetName") == 0)
{
Cvar_Set( "ui_Name", UI_Cvar_VariableString("name"));
}
else if (Q_stricmp(name, "ui_r_colorbits") == 0)
{
switch (val)
{
case 0:
Cvar_SetValue( "ui_r_depthbits", 0 );
break;
case 16:
Cvar_SetValue( "ui_r_depthbits", 16 );
break;
case 32:
Cvar_SetValue( "ui_r_depthbits", 24 );
break;
}
}
else if (Q_stricmp(name, "ui_r_lodbias") == 0)
{
switch (val)
{
case 0:
Cvar_SetValue( "ui_r_subdivisions", 4 );
break;
case 1:
Cvar_SetValue( "ui_r_subdivisions", 12 );
break;
case 2:
Cvar_SetValue( "ui_r_subdivisions", 20 );
break;
}
}
else if (Q_stricmp(name, "ui_r_glCustom") == 0)
{
switch (val)
{
case 0: // high quality
Cvar_SetValue( "ui_r_fullScreen", 1 );
Cvar_SetValue( "ui_r_subdivisions", 4 );
Cvar_SetValue( "ui_r_lodbias", 0 );
Cvar_SetValue( "ui_r_colorbits", 32 );
Cvar_SetValue( "ui_r_depthbits", 24 );
Cvar_SetValue( "ui_r_picmip", 0 );
Cvar_SetValue( "ui_r_mode", 4 );
Cvar_SetValue( "ui_r_texturebits", 32 );
Cvar_SetValue( "ui_r_fastSky", 0 );
Cvar_SetValue( "ui_r_inGameVideo", 1 );
//Cvar_SetValue( "ui_cg_shadows", 2 );//stencil
Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
break;
case 1: // normal
Cvar_SetValue( "ui_r_fullScreen", 1 );
Cvar_SetValue( "ui_r_subdivisions", 4 );
Cvar_SetValue( "ui_r_lodbias", 0 );
Cvar_SetValue( "ui_r_colorbits", 0 );
Cvar_SetValue( "ui_r_depthbits", 24 );
Cvar_SetValue( "ui_r_picmip", 1 );
Cvar_SetValue( "ui_r_mode", 3 );
Cvar_SetValue( "ui_r_texturebits", 0 );
Cvar_SetValue( "ui_r_fastSky", 0 );
Cvar_SetValue( "ui_r_inGameVideo", 1 );
//Cvar_SetValue( "ui_cg_shadows", 2 );
Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
break;
case 2: // fast
Cvar_SetValue( "ui_r_fullScreen", 1 );
Cvar_SetValue( "ui_r_subdivisions", 12 );
Cvar_SetValue( "ui_r_lodbias", 1 );
Cvar_SetValue( "ui_r_colorbits", 0 );
Cvar_SetValue( "ui_r_depthbits", 0 );
Cvar_SetValue( "ui_r_picmip", 2 );
Cvar_SetValue( "ui_r_mode", 3 );
Cvar_SetValue( "ui_r_texturebits", 0 );
Cvar_SetValue( "ui_r_fastSky", 1 );
Cvar_SetValue( "ui_r_inGameVideo", 0 );
//Cvar_SetValue( "ui_cg_shadows", 1 );
Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
break;
case 3: // fastest
Cvar_SetValue( "ui_r_fullScreen", 1 );
Cvar_SetValue( "ui_r_subdivisions", 20 );
Cvar_SetValue( "ui_r_lodbias", 2 );
Cvar_SetValue( "ui_r_colorbits", 16 );
Cvar_SetValue( "ui_r_depthbits", 16 );
Cvar_SetValue( "ui_r_mode", 3 );
Cvar_SetValue( "ui_r_picmip", 3 );
Cvar_SetValue( "ui_r_texturebits", 16 );
Cvar_SetValue( "ui_r_fastSky", 1 );
Cvar_SetValue( "ui_r_inGameVideo", 0 );
//Cvar_SetValue( "ui_cg_shadows", 0 );
Cvar_Set( "ui_r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
break;
}
}
else if (Q_stricmp(name, "ui_mousePitch") == 0)
{
if (val == 0)
{
Cvar_SetValue( "m_pitch", 0.022f );
}
else
{
Cvar_SetValue( "m_pitch", -0.022f );
}
}
}
#define ASSET_SCROLLBAR "gfx/menus/scrollbar.tga"
#define ASSET_SCROLLBAR_ARROWDOWN "gfx/menus/scrollbar_arrow_dwn_a.tga"
#define ASSET_SCROLLBAR_ARROWUP "gfx/menus/scrollbar_arrow_up_a.tga"
#define ASSET_SCROLLBAR_ARROWLEFT "gfx/menus/scrollbar_arrow_left.tga"
#define ASSET_SCROLLBAR_ARROWRIGHT "gfx/menus/scrollbar_arrow_right.tga"
#define ASSET_SCROLL_THUMB "gfx/menus/scrollbar_thumb.tga"
/*
=================
AssetCache
=================
*/
void AssetCache(void)
{
// int n;
uiInfo.uiDC.Assets.scrollBar = ui.R_RegisterShaderNoMip( ASSET_SCROLLBAR );
uiInfo.uiDC.Assets.scrollBarArrowDown = ui.R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
uiInfo.uiDC.Assets.scrollBarArrowUp = ui.R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
uiInfo.uiDC.Assets.scrollBarArrowLeft = ui.R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
uiInfo.uiDC.Assets.scrollBarArrowRight = ui.R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
uiInfo.uiDC.Assets.scrollBarThumb = ui.R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
uiInfo.uiDC.Assets.sliderBar = ui.R_RegisterShaderNoMip( "menu/new/slider" );
uiInfo.uiDC.Assets.sliderThumb = ui.R_RegisterShaderNoMip( "menu/new/sliderthumb");
/*
for( n = 0; n < NUM_CROSSHAIRS; n++ )
{
uiInfo.uiDC.Assets.crosshairShader[n] = ui.R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) );
}
*/
}
/*
================
_UI_DrawSides
=================
*/
void _UI_DrawSides(float x, float y, float w, float h, float size)
{
size *= uiInfo.uiDC.xscale;
trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
}
/*
================
_UI_DrawTopBottom
=================
*/
void _UI_DrawTopBottom(float x, float y, float w, float h, float size)
{
size *= uiInfo.uiDC.yscale;
trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
}
/*
================
UI_DrawRect
Coordinates are 640*480 virtual values
=================
*/
void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color )
{
trap_R_SetColor( color );
_UI_DrawTopBottom(x, y, width, height, size);
_UI_DrawSides(x, y, width, height, size);
trap_R_SetColor( NULL );
}
/*
=================
UI_UpdateCvars
=================
*/
void UI_UpdateCvars( void )
{
int i;
cvarTable_t *cv;
for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ )
{
Cvar_Update( cv->vmCvar );
}
}
/*
=================
UI_DrawEffects
=================
*/
static void UI_DrawEffects(rectDef_t *rect, float scale, vec4_t color)
{
UI_DrawHandlePic( rect->x, rect->y - 14, 128, 8, uiInfo.uiDC.Assets.fxBasePic );
UI_DrawHandlePic( rect->x + uiInfo.effectsColor * 16 + 8, rect->y - 16, 16, 12, uiInfo.uiDC.Assets.fxPic[uiInfo.effectsColor] );
}
/*
=================
UI_Version
=================
*/
static void UI_Version(rectDef_t *rect, float scale, vec4_t color, int iFontIndex)
{
int width;
width = DC->textWidth(Q3_VERSION, scale, 0);
DC->drawText(rect->x - width, rect->y, scale, color, Q3_VERSION, 0, ITEM_TEXTSTYLE_SHADOWED, iFontIndex);
}
/*
=================
UI_DrawKeyBindStatus
=================
*/
static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iFontIndex)
{
if (Display_KeyBindPending())
{
Text_Paint(rect->x, rect->y, scale, color, ui.SP_GetStringTextString("MENUS_WAITINGFORKEY"), 0, textStyle, iFontIndex);
}
else
{
// Text_Paint(rect->x, rect->y, scale, color, ui.SP_GetStringTextString("MENUS_ENTERTOCHANGE"), 0, textStyle, iFontIndex);
}
}
/*
=================
UI_DrawKeyBindStatus
=================
*/
static void UI_DrawGLInfo(rectDef_t *rect, float scale, vec4_t color, int textStyle, int iFontIndex)
{
#define MAX_LINES 64
char buff[4096];
char * eptr = buff;
const char *lines[MAX_LINES];
int y, numLines=0, i=0;
y = rect->y;
Text_Paint(rect->x, y, scale, color, va("GL_VENDOR: %s",uiInfo.uiDC.glconfig.vendor_string), rect->w, textStyle, iFontIndex);
y += 15;
Text_Paint(rect->x, y, scale, color, va("GL_VERSION: %s: %s", uiInfo.uiDC.glconfig.version_string,uiInfo.uiDC.glconfig.renderer_string), rect->w, textStyle, iFontIndex);
y += 15;
Text_Paint(rect->x, y, scale, color, "GL_PIXELFORMAT:", rect->w, textStyle, iFontIndex);
y += 15;
Text_Paint(rect->x, y, scale, color, va ("Color(%d-bits) Z(%d-bits) stencil(%d-bits)",uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), rect->w, textStyle, iFontIndex);
y += 15;
// build null terminated extension strings
Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, sizeof(buff));
int testy=y-16;
while ( testy <= rect->y + rect->h && *eptr && (numLines < MAX_LINES) )
{
while ( *eptr && *eptr == ' ' )
*eptr++ = '\0';
// track start of valid string
if (*eptr && *eptr != ' ')
{
lines[numLines++] = eptr;
testy+=16;
}
while ( *eptr && *eptr != ' ' )
eptr++;
}
numLines--;
while (i < numLines)
{
Text_Paint(rect->x, y, scale, color, lines[i++], rect->w, textStyle, iFontIndex);
y += 16;
}
}
/*
===================
UI_DataPad_DrawIconBackground
===================
*/
void UI_DataPad_DrawIconBackground(void)
{
// ui.R_SetColor( colorTable[CT_WHITE] );
// CG_DrawPic( prongLeftX+xAdd, y2-10, 40, 80, cgs.media.weaponProngsOff);
// CG_DrawPic( prongRightX-xAdd, y2-10, -40, 80, cgs.media.weaponProngsOff);
}
/*
=================
UI_DataPad_Inventory
=================
*/
/*
static void UI_DataPad_Inventory(rectDef_t *rect, float scale, vec4_t color, int iFontIndex)
{
Text_Paint(rect->x, rect->y, scale, color, "INVENTORY", 0, 1, iFontIndex);
}
*/
/*
=================
UI_DataPad_ForcePowers
=================
*/
/*
static void UI_DataPad_ForcePowers(rectDef_t *rect, float scale, vec4_t color, int iFontIndex)
{
Text_Paint(rect->x, rect->y, scale, color, "FORCE POWERS", 0, 1, iFontIndex);
}
*/
static void UI_DrawCrosshair(rectDef_t *rect, float scale, vec4_t color) {
trap_R_SetColor( color );
if (uiInfo.currentCrosshair < 0 || uiInfo.currentCrosshair >= NUM_CROSSHAIRS) {
uiInfo.currentCrosshair = 0;
}
UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.uiDC.Assets.crosshairShader[uiInfo.currentCrosshair]);
trap_R_SetColor( NULL );
}
/*
=================
UI_OwnerDraw
=================
*/
static void UI_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle, int iFontIndex)
{
rectDef_t rect;
rect.x = x + text_x;
rect.y = y + text_y;
rect.w = w;
rect.h = h;
switch (ownerDraw)
{
case UI_EFFECTS:
UI_DrawEffects(&rect, scale, color);
break;
case UI_VERSION:
UI_Version(&rect, scale, color, iFontIndex);
break;
case UI_DATAPAD_MISSION:
ui.Draw_DataPad(DP_HUD);
ui.Draw_DataPad(DP_OBJECTIVES);
break;
case UI_DATAPAD_WEAPONS:
ui.Draw_DataPad(DP_HUD);
ui.Draw_DataPad(DP_WEAPONS);
break;
case UI_DATAPAD_INVENTORY:
ui.Draw_DataPad(DP_HUD);
ui.Draw_DataPad(DP_INVENTORY);
break;
case UI_DATAPAD_FORCEPOWERS:
ui.Draw_DataPad(DP_HUD);
ui.Draw_DataPad(DP_FORCEPOWERS);
break;
case UI_ALLMAPS_SELECTION://saved game thumbnail
ui.DrawStretchRaw( x, y+h, w, -h, SG_SCR_WIDTH, SG_SCR_HEIGHT, screenShotBuf, 0, qtrue );
ui.R_Font_DrawString( x, // int ox
y+h, // int oy
s_savedata[s_savegame.currentLine].currentSaveFileMap, // const char *text
color, // paletteRGBA_c c
iFontIndex, // const int iFontHandle
w,//-1, // iMaxPixelWidth (-1 = none)
scale // const float scale = 1.0f
);
break;
case UI_PREVIEWCINEMATIC:
// FIXME BOB - make this work?
// UI_DrawPreviewCinematic(&rect, scale, color);
break;
case UI_CROSSHAIR:
UI_DrawCrosshair(&rect, scale, color);
break;
case UI_GLINFO:
UI_DrawGLInfo(&rect,scale, color, textStyle, iFontIndex);
break;
case UI_KEYBINDSTATUS:
UI_DrawKeyBindStatus(&rect,scale, color, textStyle, iFontIndex);
break;
default:
break;
}
}
/*
=================
UI_UpdateCvars
=================
*/
static qboolean UI_OwnerDrawVisible(int flags)
{
qboolean vis = qtrue;
while (flags)
{
// FIXME BOB
/* if (flags & UI_SHOW_FFA)
{
if (trap_Cvar_VariableValue("g_gametype") != GT_FFA)
{
vis = qfalse;
}
flags &= ~UI_SHOW_FFA;
}
*/
// FIXME BOB
/* if (flags & UI_SHOW_NOTFFA)
{
if (trap_Cvar_VariableValue("g_gametype") == GT_FFA)
{
vis = qfalse;
}
flags &= ~UI_SHOW_NOTFFA;
}
if (flags & UI_SHOW_LEADER)
{
// these need to show when this client can give orders to a player or a group
if (!uiInfo.teamLeader)
{
vis = qfalse;
}
else
{
// if showing yourself
if (ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)
{
vis = qfalse;
}
}
flags &= ~UI_SHOW_LEADER;
}
if (flags & UI_SHOW_NOTLEADER)
{
// these need to show when this client is assigning their own status or they are NOT the leader
if (uiInfo.teamLeader) {
// if not showing yourself
if (!(ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)) {
vis = qfalse;
}
}
flags &= ~UI_SHOW_NOTLEADER;
}
if (flags & UI_SHOW_FAVORITESERVERS)
{
// this assumes you only put this type of display flag on something showing in the proper context
if (ui_netSource.integer != AS_FAVORITES)
{
vis = qfalse;
}
flags &= ~UI_SHOW_FAVORITESERVERS;
}
if (flags & UI_SHOW_NOTFAVORITESERVERS)
{
// this assumes you only put this type of display flag on something showing in the proper context
if (ui_netSource.integer == AS_FAVORITES)
{
vis = qfalse;
}
flags &= ~UI_SHOW_NOTFAVORITESERVERS;
}
if (flags & UI_SHOW_ANYTEAMGAME)
{
if (uiInfo.gameTypes[ui_gameType.integer].gtEnum <= GT_TEAM )
{
vis = qfalse;
}
flags &= ~UI_SHOW_ANYTEAMGAME;
}
if (flags & UI_SHOW_ANYNONTEAMGAME)
{
if (uiInfo.gameTypes[ui_gameType.integer].gtEnum > GT_TEAM )
{
vis = qfalse;
}
flags &= ~UI_SHOW_ANYNONTEAMGAME;
}
if (flags & UI_SHOW_NETANYTEAMGAME)
{
if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum <= GT_TEAM )
{
vis = qfalse;
}
flags &= ~UI_SHOW_NETANYTEAMGAME;
}
if (flags & UI_SHOW_NETANYNONTEAMGAME)
{
if (uiInfo.gameTypes[ui_netGameType.integer].gtEnum > GT_TEAM )
{
vis = qfalse;
}
flags &= ~UI_SHOW_NETANYNONTEAMGAME;
}
if (flags & UI_SHOW_NEWHIGHSCORE)
{
if (uiInfo.newHighScoreTime < uiInfo.uiDC.realTime)
{
vis = qfalse;
} else {
if (uiInfo.soundHighScore)
{
if (trap_Cvar_VariableValue("sv_killserver") == 0)
{
// wait on server to go down before playing sound
trap_S_StartLocalSound(uiInfo.newHighScoreSound, CHAN_ANNOUNCER);
uiInfo.soundHighScore = qfalse;
}
}
}
flags &= ~UI_SHOW_NEWHIGHSCORE;
}
if (flags & UI_SHOW_NEWBESTTIME)
{
if (uiInfo.newBestTime < uiInfo.uiDC.realTime)
{
vis = qfalse;
}
flags &= ~UI_SHOW_NEWBESTTIME;
}
*/
if (flags & UI_SHOW_DEMOAVAILABLE)
{
if (!uiInfo.demoAvailable)
{
vis = qfalse;
}
flags &= ~UI_SHOW_DEMOAVAILABLE;
}
else
{
flags = 0;
}
}
return vis;
}
/*
=================
Text_Width
=================
*/
int Text_Width(const char *text, float scale, int iFontIndex)
{
// temp code until Bob retro-fits all menus to have font specifiers...
//
if ( iFontIndex == 0 )
{
iFontIndex = uiInfo.uiDC.Assets.qhMediumFont;
}
return ui.R_Font_StrLenPixels(text, iFontIndex, scale);
}
/*
=================
UI_OwnerDrawWidth
=================
*/
int UI_OwnerDrawWidth(int ownerDraw, float scale)
{
// int i, h, value;
// const char *text;
const char *s = NULL;
switch (ownerDraw)
{
case UI_KEYBINDSTATUS:
if (Display_KeyBindPending())
{
s = ui.SP_GetStringTextString("MENUS_WAITINGFORKEY");
}
else
{
// s = ui.SP_GetStringTextString("MENUS_ENTERTOCHANGE");
}
break;
// FIXME BOB
// case UI_SERVERREFRESHDATE:
// s = UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer));
// break;
default:
break;
}
if (s)
{
return Text_Width(s, scale, 0);
}
return 0;
}
/*
=================
Text_Height
=================
*/
int Text_Height(const char *text, float scale, int iFontIndex)
{
// temp until Bob retro-fits all menu files with font specifiers...
//
if ( iFontIndex == 0 )
{
iFontIndex = uiInfo.uiDC.Assets.qhMediumFont;
}
return ui.R_Font_HeightPixels(iFontIndex, scale);
}
/*
=================
UI_MouseEvent
=================
*/
void _UI_MouseEvent( int dx, int dy )
{
// update mouse screen position
uiInfo.uiDC.cursorx += dx;
if (uiInfo.uiDC.cursorx < 0)
{
uiInfo.uiDC.cursorx = 0;
}
else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH)
{
uiInfo.uiDC.cursorx = SCREEN_WIDTH;
}
uiInfo.uiDC.cursory += dy;
if (uiInfo.uiDC.cursory < 0)
{
uiInfo.uiDC.cursory = 0;
}
else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT)
{
uiInfo.uiDC.cursory = SCREEN_HEIGHT;
}
if (Menu_Count() > 0)
{
//menuDef_t *menu = Menu_GetFocused();
//Menu_HandleMouseMove(menu, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
}
}
/*
=================
UI_KeyEvent
=================
*/
void _UI_KeyEvent( int key, qboolean down )
{
/* extern qboolean SwallowBadNumLockedKPKey( int iKey );
if (SwallowBadNumLockedKPKey(key)){
return;
}
*/
if (Menu_Count() > 0)
{
menuDef_t *menu = Menu_GetFocused();
if (menu)
{
if (key == K_ESCAPE && down && !Menus_AnyFullScreenVisible())
{
Menus_CloseAll();
}
else
{
Menu_HandleKey(menu, key, down );
}
}
else
{
trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
trap_Key_ClearStates();
Cvar_Set( "cl_paused", "0" );
}
}
}
/*
=================
UI_Report
=================
*/
void UI_Report(void)
{
String_Report();
}
int s_textlanguage_Names[] =
{
// MNT_ENGLISH,
// MNT_GERMAN,
// MNT_FRENCH,
NULL
};
int s_voicelanguage_Names[] =
{
// MNT_ENGLISH,
// MNT_GERMAN,
NULL
};
int s_subtitle_Names[] =
{
// MNT_OFF,
// MNT_ON,
// MNT_CINEMATIC,
NULL
};
void Menus_CloseByName(const char *p);
/*
=================
UI_DataPadMenu
=================
*/
void UI_DataPadMenu(void)
{
int newForcePower,newObjective;
Menus_CloseByName("mainhud");
newForcePower = (int)trap_Cvar_VariableValue("cg_updatedDataPadForcePower1");
newObjective = (int)trap_Cvar_VariableValue("cg_updatedDataPadObjective");
if (newForcePower)
{
Menus_ActivateByName("datapadForcePowersMenu");
}
else if (newObjective)
{
Menus_ActivateByName("datapadMissionMenu");
}
else
{
Menus_ActivateByName("datapadMissionMenu");
}
ui.Key_SetCatcher( KEYCATCH_UI );
}
/*
=================
UI_InGameMenu
=================
*/
void UI_InGameMenu(const char*menuID)
{
ui.PrecacheScreenshot();
Menus_CloseByName("mainhud");
if (menuID)
{
Menus_ActivateByName(menuID);
}
else
{
Menus_ActivateByName("ingameMainMenu");
}
ui.Key_SetCatcher( KEYCATCH_UI );
}
qboolean _UI_IsFullscreen( void )
{
return Menus_AnyFullScreenVisible();
}
/*
=======================================================================
MAIN MENU
=======================================================================
*/
static const char *s_keyboardlanguage_Names[] =
{
"AMERICAN",
"DEUTSCH",
"FRANCAIS",
"ESPANOL",
"ITALIANO",
0
};
/*
===============
UI_MainMenu
The main menu only comes up when not in a game,
so make sure that the attract loop server is down
and that local cinematics are killed
===============
*/
void UI_MainMenu(void)
{
char buf[256];
ui.Cvar_Set("sv_killserver", "1"); // let the demo server know it should shut down
ui.Key_SetCatcher( KEYCATCH_UI );
Menus_OpenByName("mainMenu");
ui.Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf));
if (strlen(buf)) {
Menus_ActivateByName("error_popmenu");
}
}
/*
=================
Menu_Cache
=================
*/
void Menu_Cache( void )
{
uis.cursor = ui.R_RegisterShaderNoMip( "menu/new/crosshairb");
// Common menu graphics
uis.whiteShader = ui.R_RegisterShader( "white" );
uis.menuBackShader = ui.R_RegisterShader( "menu/art/unknownmap" );
}
/*
=================
UI_UpdateVideoSetup
Copies the temporary user interface version of the video cvars into
their real counterparts. This is to create a interface which allows
you to discard your changes if you did something you didnt want
=================
*/
void UI_UpdateVideoSetup ( void )
{
Cvar_Set ( "r_mode", Cvar_VariableString ( "ui_r_mode" ) );
Cvar_Set ( "r_fullscreen", Cvar_VariableString ( "ui_r_fullscreen" ) );
Cvar_Set ( "r_colorbits", Cvar_VariableString ( "ui_r_colorbits" ) );
Cvar_Set ( "r_lodbias", Cvar_VariableString ( "ui_r_lodbias" ) );
Cvar_Set ( "r_picmip", Cvar_VariableString ( "ui_r_picmip" ) );
Cvar_Set ( "r_texturebits", Cvar_VariableString ( "ui_r_texturebits" ) );
Cvar_Set ( "r_texturemode", Cvar_VariableString ( "ui_r_texturemode" ) );
Cvar_Set ( "r_detailtextures", Cvar_VariableString ( "ui_r_detailtextures" ) );
Cvar_Set ( "r_ext_compress_textures", Cvar_VariableString ( "ui_r_ext_compress_textures" ) );
Cvar_Set ( "r_depthbits", Cvar_VariableString ( "ui_r_depthbits" ) );
Cvar_Set ( "r_subdivisions", Cvar_VariableString ( "ui_r_subdivisions" ) );
Cvar_Set ( "r_fastSky", Cvar_VariableString ( "ui_r_fastSky" ) );
Cvar_Set ( "r_inGameVideo", Cvar_VariableString ( "ui_r_inGameVideo" ) );
Cvar_Set ( "r_allowExtensions", Cvar_VariableString ( "ui_r_allowExtensions" ) );
Cvar_Set ( "cg_shadows", Cvar_VariableString ( "ui_cg_shadows" ) );
Cvar_Set ( "ui_r_modified", "0" );
Cbuf_ExecuteText( EXEC_APPEND, "vid_restart;" );
}
/*
=================
UI_GetVideoSetup
Retrieves the current actual video settings into the temporary user
interface versions of the cvars.
=================
*/
void UI_GetVideoSetup ( void )
{
// Make sure the cvars are registered as read only.
Cvar_Register ( NULL, "ui_r_glCustom", "4", CVAR_ROM|CVAR_ARCHIVE );
Cvar_Register ( NULL, "ui_r_mode", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_fullscreen", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_colorbits", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_lodbias", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_picmip", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_texturebits", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_texturemode", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_detailtextures", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_ext_compress_textures", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_depthbits", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_subdivisions", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_fastSky", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_inGameVideo", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_allowExtensions", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_cg_shadows", "0", CVAR_ROM );
Cvar_Register ( NULL, "ui_r_modified", "0", CVAR_ROM );
// Copy over the real video cvars into their temporary counterparts
Cvar_Set ( "ui_r_mode", Cvar_VariableString ( "r_mode" ) );
Cvar_Set ( "ui_r_colorbits", Cvar_VariableString ( "r_colorbits" ) );
Cvar_Set ( "ui_r_fullscreen", Cvar_VariableString ( "r_fullscreen" ) );
Cvar_Set ( "ui_r_lodbias", Cvar_VariableString ( "r_lodbias" ) );
Cvar_Set ( "ui_r_picmip", Cvar_VariableString ( "r_picmip" ) );
Cvar_Set ( "ui_r_texturebits", Cvar_VariableString ( "r_texturebits" ) );
Cvar_Set ( "ui_r_texturemode", Cvar_VariableString ( "r_texturemode" ) );
Cvar_Set ( "ui_r_detailtextures", Cvar_VariableString ( "r_detailtextures" ) );
Cvar_Set ( "ui_r_ext_compress_textures", Cvar_VariableString ( "r_ext_compress_textures" ) );
Cvar_Set ( "ui_r_depthbits", Cvar_VariableString ( "r_depthbits" ) );
Cvar_Set ( "ui_r_subdivisions", Cvar_VariableString ( "r_subdivisions" ) );
Cvar_Set ( "ui_r_fastSky", Cvar_VariableString ( "r_fastSky" ) );
Cvar_Set ( "ui_r_inGameVideo", Cvar_VariableString ( "r_inGameVideo" ) );
Cvar_Set ( "ui_r_allowExtensions", Cvar_VariableString ( "r_allowExtensions" ) );
Cvar_Set ( "ui_cg_shadows", Cvar_VariableString ( "cg_shadows" ) );
Cvar_Set ( "ui_r_modified", "0" );
}
char GoToMenu[1024];
/*
=================
Menus_SaveGoToMenu
=================
*/
void Menus_SaveGoToMenu(const char *menuTo)
{
memcpy(GoToMenu, menuTo, sizeof(GoToMenu));
}
/*
=================
UI_CheckVid1Data
=================
*/
void UI_CheckVid1Data(const char *menuTo,const char *warningMenuName)
{
menuDef_t *menu;
itemDef_t *applyChanges;
menu = Menu_GetFocused(); // Get current menu (either video or ingame video, I would assume)
if (!menu)
{
Com_Printf(S_COLOR_YELLOW"WARNING: No videoMenu was found. Video data could not be checked\n");
return;
}
applyChanges = (itemDef_s *) Menu_FindItemByName(menu, "applyChanges");
if (!applyChanges)
{
// Menus_CloseAll();
Menus_OpenByName(menuTo);
return;
}
if ((applyChanges->window.flags & WINDOW_VISIBLE)) // Is the APPLY CHANGES button active?
{
// Menus_SaveGoToMenu(menuTo); // Save menu you're going to
// Menus_HideItems(menu->window.name); // HIDE videMenu in case you have to come back
Menus_OpenByName(warningMenuName); // Give warning
}
else
{
// Menus_CloseAll();
// Menus_OpenByName(menuTo);
}
}
/*
=================
UI_ResetDefaults
=================
*/
void UI_ResetDefaults( void )
{
ui.Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n");
ui.Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n");
ui.Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
Cvar_Set("com_introPlayed", "1" );
}
/*
=======================
UI_SortSaveGames
=======================
*/
static int UI_SortSaveGames( const void *A, const void *B )
{
const int &a = ((savedata_t*)A)->currentSaveFileDateTime;
const int &b = ((savedata_t*)B)->currentSaveFileDateTime;
if (a > b)
{
return -1;
}
else
{
return (a < b);
}
}
/*
=================
ReadSaveDirectory
=================
*/
void ReadSaveDirectory (void)
{
int i;
char *holdChar;
int len;
int fileCnt;
// Clear out save data
memset(s_savedata,0,sizeof(s_savedata));
s_savegame.saveFileCnt = 0;
Cvar_Set("ui_gameDesc", "" ); // Blank out comment
Cvar_Set("ui_SelectionOK", "0" );
memset( screenShotBuf,0,(SG_SCR_WIDTH * SG_SCR_HEIGHT * 4)); //blank out sshot
// Get everything in saves directory
fileCnt = ui.FS_GetFileList("saves", ".sav", s_savegame.listBuf, LISTBUFSIZE );
Cvar_Set("ui_ResumeOK", "0" );
holdChar = s_savegame.listBuf;
for ( i = 0; i < fileCnt; i++ )
{
// strip extension
len = strlen( holdChar );
holdChar[len-4] = '\0';
if ( Q_stricmp("current",holdChar)!=0 )
{
time_t result;
if (Q_stricmp("auto",holdChar)==0)
{
Cvar_Set("ui_ResumeOK", "1" );
}
else
{ // Is this a valid file??? & Get comment of file
result = ui.SG_GetSaveGameComment(holdChar, s_savedata[s_savegame.saveFileCnt].currentSaveFileComments, s_savedata[s_savegame.saveFileCnt].currentSaveFileMap);
if (result != 0) // ignore Bad save game
{
s_savedata[s_savegame.saveFileCnt].currentSaveFileName = holdChar;
s_savedata[s_savegame.saveFileCnt].currentSaveFileDateTime = result;
struct tm *localTime;
localTime = localtime( &result );
strcpy(s_savedata[s_savegame.saveFileCnt].currentSaveFileDateTimeString,asctime( localTime ) );
s_savegame.saveFileCnt++;
if (s_savegame.saveFileCnt == MAX_SAVELOADFILES)
{
break;
}
}
}
}
holdChar += len + 1; //move to next item
}
qsort( s_savedata, s_savegame.saveFileCnt, sizeof(savedata_t), UI_SortSaveGames );
}