rpgxef/code/ui/ui_atoms.c.orig
Walter Julius Hennecke a39565b783 Integrated RPG-X2 rpgxEF edition into the rpgxEF repo
... not quite content with where the project files lie but it is ok for
now.
... compiling works fine so far (only tested mingw32 right now)
2012-08-04 12:54:37 +02:00

2133 lines
48 KiB
C

// Copyright (C) 1999-2000 Id Software, Inc.
//
/**********************************************************************
UI_ATOMS.C
User interface building blocks and support functions.
**********************************************************************/
#include "ui_local.h"
#include "../qcommon/stv_version.h"
uiStatic_t uis;
qboolean m_entersound; // after a frame, so caching won't disrupt the sound
static void UI_LanguageFilename(char *baseName,char *baseExtension,char *finalName);
void BG_LoadItemNames(void);
// these are here so the functions in q_shared.c can link
#ifndef UI_HARD_LINKED
void QDECL Com_Error( int level, const char *error, ... ) {
va_list argptr;
char text[1024];
va_start (argptr, error);
vsprintf (text, error, argptr);
va_end (argptr);
trap_Error( va("%s", text) );
}
void QDECL Com_Printf( const char *msg, ... ) {
va_list argptr;
char text[1024];
va_start (argptr, msg);
vsprintf (text, msg, argptr);
va_end (argptr);
trap_Print( va("%s", text) );
}
#endif
typedef struct
{
int initialized; // Has this structure been initialized
qhandle_t cornerUpper;
qhandle_t cornerUpper2;
qhandle_t cornerLower;
} menuframe_t;
static menuframe_t s_menuframe;
const char menuEmptyLine[] = " ";
/*
=================
UI_ClampCvar
=================
*/
float UI_ClampCvar( float min, float max, float value )
{
if ( value < min ) return min;
if ( value > max ) return max;
return value;
}
/*
=================
UI_PushMenu
=================
*/
void UI_PushMenu( menuframework_s *menu )
{
int i;
menucommon_s* item;
// avoid stacking menus invoked by hotkeys
for (i=0 ; i<uis.menusp ; i++)
{
if (uis.stack[i] == menu)
{
uis.menusp = i;
break;
}
}
if (i == uis.menusp)
{
if (uis.menusp >= MAX_MENUDEPTH)
trap_Error("UI_PushMenu: menu stack overflow");
uis.stack[uis.menusp++] = menu;
}
uis.activemenu = menu;
// default cursor position
menu->cursor = 0;
menu->cursor_prev = 0;
m_entersound = qtrue;
trap_Key_SetCatcher( KEYCATCH_UI );
// force first available item to have focus
for (i=0; i<menu->nitems; i++)
{
item = (menucommon_s *)menu->items[i];
if (!(item->flags & (QMF_GRAYED|QMF_MOUSEONLY|QMF_INACTIVE)))
{
menu->cursor_prev = -1;
Menu_SetCursor( menu, i );
break;
}
}
uis.firstdraw = qtrue;
}
/*
=================
UI_PopMenu
=================
*/
void UI_PopMenu (void)
{
trap_S_StartLocalSound( menu_out_sound, CHAN_LOCAL_SOUND );
uis.menusp--;
if (uis.menusp < 0)
trap_Error ("UI_PopMenu: menu stack underflow");
if (uis.menusp) {
uis.activemenu = uis.stack[uis.menusp-1];
uis.firstdraw = qtrue;
}
else {
UI_ForceMenuOff ();
}
}
void UI_ForceMenuOff (void)
{
uis.menusp = 0;
uis.activemenu = NULL;
trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
trap_Key_ClearStates();
trap_Cvar_Set( "cl_paused", "0" );
}
/*
=================
UI_LerpColor
=================
*/
static void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t)
{
int i;
// lerp and clamp each component
for (i=0; i<4; i++)
{
c[i] = a[i] + t*(b[i]-a[i]);
if (c[i] < 0)
c[i] = 0;
else if (c[i] > 1.0)
c[i] = 1.0;
}
}
/*
=================
UI_DrawProportionalString2
=================
*/
#define CHARMAX 256
#define PROPB_GAP_WIDTH 4
#define PROPB_SPACE_WIDTH 12
#define PROPB_HEIGHT 36
static int propMapBig[CHARMAX][3];
static int propMap[CHARMAX][3];
static int propMapTiny[CHARMAX][3];
static int const propMapB[26][3] = {
{11, 12, 33},
{49, 12, 31},
{85, 12, 31},
{120, 12, 30},
{156, 12, 21},
{183, 12, 21},
{207, 12, 32},
{13, 55, 30},
{49, 55, 13},
{66, 55, 29},
{101, 55, 31},
{135, 55, 21},
{158, 55, 40},
{204, 55, 32},
{12, 97, 31},
{48, 97, 31},
{82, 97, 30},
{118, 97, 30},
{153, 97, 30},
{185, 97, 25},
{213, 97, 30},
{11, 139, 32},
{42, 139, 51},
{93, 139, 32},
{126, 139, 31},
{158, 139, 25},
};
/*
=================
UI_DrawBannerString
=================
*/
static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color )
{
const char* s;
char ch;
float ax;
float ay;
float aw;
float ah;
float frow;
float fcol;
float fwidth;
float fheight;
// draw the colored text
trap_R_SetColor( color );
// ax = x * uis.scale + uis.bias;
ax = x * uis.scalex;
ay = y * uis.scaley;
s = str;
while ( *s )
{
ch = *s & 255;
if ( ch == ' ' ) {
ax += ((float)PROPB_SPACE_WIDTH + (float)PROPB_GAP_WIDTH)* uis.scalex;
}
else if ( ch >= 'A' && ch <= 'Z' ) {
ch -= 'A';
fcol = (float)propMapB[ch][0] / 256.0f; //256.0f
frow = (float)propMapB[ch][1] / 256.0f;
fwidth = (float)propMapB[ch][2] / 256.0f;
fheight = (float)PROPB_HEIGHT / 256.0f;
aw = (float)propMapB[ch][2] * uis.scalex;
ah = (float)PROPB_HEIGHT * uis.scaley;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, uis.charsetPropB );
ax += (aw + (float)PROPB_GAP_WIDTH * uis.scalex);
}
s++;
}
trap_R_SetColor( NULL );
}
/*
=================
UI_DrawBannerString
=================
*/
void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ) {
const char * s;
int ch;
int width;
vec4_t drawcolor;
// find the width of the drawn text
s = str;
width = 0;
while ( *s ) {
ch = *s;
if ( ch == ' ' ) {
width += PROPB_SPACE_WIDTH;
}
else if ( ch >= 'A' && ch <= 'Z' ) {
width += propMapB[ch - 'A'][2] + PROPB_GAP_WIDTH;
}
s++;
}
width -= PROPB_GAP_WIDTH;
switch( style & UI_FORMATMASK ) {
case UI_CENTER:
x -= width / 2;
break;
case UI_RIGHT:
x -= width;
break;
case UI_LEFT:
default:
break;
}
if ( style & UI_DROPSHADOW ) {
drawcolor[0] = drawcolor[1] = drawcolor[2] = 0;
drawcolor[3] = color[3];
UI_DrawBannerString2( x+2, y+2, str, drawcolor );
}
UI_DrawBannerString2( x, y, str, color );
}
/*
=================
UI_ProportionalStringWidth
=================
*/
int UI_ProportionalStringWidth( const char* str,int style ) {
const char * s;
int ch;
int charWidth;
int width;
if (style == UI_TINYFONT)
{
s = str;
width = 0;
while ( *s ) {
ch = *s & 255;
charWidth = propMapTiny[ch][2];
if ( charWidth != -1 ) {
width += charWidth;
width += PROP_GAP_TINY_WIDTH;
}
s++;
}
width -= PROP_GAP_TINY_WIDTH;
}
else if (style == UI_BIGFONT)
{
s = str;
width = 0;
while ( *s ) {
ch = *s & 255;
charWidth = propMapBig[ch][2];
if ( charWidth != -1 ) {
width += charWidth;
width += PROP_GAP_BIG_WIDTH;
}
s++;
}
width -= PROP_GAP_BIG_WIDTH;
}
else
{
s = str;
width = 0;
while ( *s ) {
ch = *s & 255;
charWidth = propMap[ch][2];
if ( charWidth != -1 ) {
width += charWidth;
width += PROP_GAP_WIDTH;
}
s++;
}
width -= PROP_GAP_WIDTH;
}
return width;
}
static int specialTinyPropChars[CHARMAX][2] = {
{0, 0},
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 10
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 20
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 30
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 40
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 50
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 60
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 70
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 80
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 90
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 100
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 110
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 120
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 130
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 140
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 150
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{2,-3},{0, 0}, // 160
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 170
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 180
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 190
{0,-1},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{0, 0},{2, 0},{2,-3}, // 200
{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{0,-1},{2,-3},{2,-3}, // 210
{2,-3},{3,-3},{2,-3},{2,-3},{0, 0},{0,-1},{2,-3},{2,-3},{2,-3},{2,-3}, // 220
{2,-3},{0,-1},{0,-1},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{0, 0}, // 230
{2, 0},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{0, 0}, // 240
{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{2,-3},{0, 0},{0,-1},{2,-3},{2,-3}, // 250
{2,-3},{2,-3},{2,-3},{0,-1},{2,-3} // 255
};
static int specialPropChars[CHARMAX][2] = {
{0, 0},
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 10
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 20
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 30
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 40
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 50
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 60
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 70
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 80
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 90
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 100
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 110
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 120
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 130
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 140
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 150
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 160
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 170
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 180
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 190
{2,-2},{2,-2},{2,-2},{2,-2},{2,-2},{2,-2},{2,-2},{0, 0},{1, 1},{2,-2}, // 200
{2,-2},{2,-2},{2,-2},{2,-2},{2,-2},{2,-2},{2,-2},{0, 0},{2,-2},{2,-2}, // 210
{2,-2},{2,-2},{2,-2},{2,-2},{0, 0},{0, 0},{2,-2},{2,-2},{2,-2},{2,-2}, // 220
{2,-2},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 230
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 240
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 250
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0} // 255
};
static int specialBigPropChars[CHARMAX][2] = {
{0, 0},
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 10
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 20
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 30
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 40
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 50
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 60
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 70
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 80
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 90
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 100
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 110
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 120
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 130
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 140
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 150
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 160
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 170
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 180
{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0},{0, 0}, // 190
{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{0, 0},{3, 1},{3,-3}, // 200
{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{0, 0},{3,-3},{3,-3}, // 210
{3,-3},{3,-3},{3,-3},{3,-3},{0, 0},{0, 0},{3,-3},{3,-3},{3,-3},{3,-3}, // 220
{3,-3},{0, 0},{0, 0},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{0, 0}, // 230
{3, 1},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{0, 0}, // 240
{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{3,-3},{0, 0},{0, 0},{3,-3},{3,-3}, // 250
{3,-3},{3,-3},{3,-3},{0, 0},{3,-3} // 255
};
/*
=================
UI_DrawProportionalString2
=================
*/
static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t color, int style, qhandle_t charset )
{
const char* s;
unsigned char ch;
float ax;
float ay,holdY;
float aw;
float ah;
float frow;
float fcol;
float fwidth;
float fheight;
float sizeScale;
int colorI;
int special;
// draw the colored text
trap_R_SetColor( color );
// ax = x * uis.scale + uis.bias;
ax = x * uis.scalex;
ay = y * uis.scaley;
holdY = ay;
sizeScale = UI_ProportionalSizeScale( style );
if (style & UI_TINYFONT)
{
s = str;
while ( *s )
{
// Is this a color????
if ( Q_IsColorString( s ) )
{
colorI = ColorIndex( *(s+1) );
trap_R_SetColor( g_color_table[colorI] );
s += 2;
continue;
}
ch = *s & 255;
if ( ch == ' ' ) {
aw = (float)PROP_SPACE_TINY_WIDTH;
}
else if ( propMap[ch][2] != -1 ) {
// Because some foreign characters were a little different
special = specialTinyPropChars[ch][0];
ay = holdY + (specialTinyPropChars[ch][1] * uis.scaley);
fcol = (float ) propMapTiny[ch][0] / 256.0f; //256.0f
frow = (float)propMapTiny[ch][1] / 256.0f;
fwidth = (float)propMapTiny[ch][2] / 256.0f;
fheight = (float)(PROP_TINY_HEIGHT + special) / 256.0f;
aw = (float)propMapTiny[ch][2] * uis.scalex * sizeScale;
ah = (float)(PROP_TINY_HEIGHT+ special) * uis.scaley * sizeScale;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + fwidth, frow + fheight, charset );
}
else
{
aw = 0;
}
ax += (aw + (float)PROP_GAP_TINY_WIDTH * uis.scalex * sizeScale);
s++;
}
}
else if (style & UI_BIGFONT)
{
s = str;
while ( *s )
{
// Is this a color????
if ( Q_IsColorString( s ) )
{
colorI = ColorIndex( *(s+1) );
trap_R_SetColor( g_color_table[colorI] );
s += 2;
continue;
}
ch = *s & 255;
if ( ch == ' ' ) {
aw = (float)PROP_SPACE_BIG_WIDTH * uis.scalex;
}
else if ( propMap[ch][2] != -1 ) {
// Because some foreign characters were a little different
special = specialBigPropChars[ch][0];
ay = holdY + (specialBigPropChars[ch][1] * uis.scaley);
fcol = (float ) propMapBig[ch][0] / 256.0f; //256.0f
frow = (float)propMapBig[ch][1] / 256.0f;
fwidth = (float)propMapBig[ch][2] / 256.0f;
fheight = (float)(PROP_BIG_HEIGHT+ special) / 256.0f;
aw = (float)propMapBig[ch][2] * uis.scalex * sizeScale;
ah = (float)(PROP_BIG_HEIGHT+ special) * uis.scaley * sizeScale;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + fwidth, frow + fheight, charset );
}
else
{
aw = 0;
}
ax += (aw + (float)PROP_GAP_BIG_WIDTH * uis.scalex * sizeScale);
s++;
}
}
else
{
s = str;
while ( *s )
{
// Is this a color????
if ( Q_IsColorString( s ) )
{
colorI = ColorIndex( *(s+1) );
trap_R_SetColor( g_color_table[colorI] );
s += 2;
continue;
}
ch = *s & 255;
if ( ch == ' ' ) {
aw = (float)PROP_SPACE_WIDTH * uis.scalex * sizeScale;
}
else if ( propMap[ch][2] != -1 ) {
// Because some foreign characters were a little different
special = specialPropChars[ch][0];
ay = holdY + (specialPropChars[ch][1] * uis.scaley);
fcol = (float)propMap[ch][0] / 256.0f;
frow = (float)propMap[ch][1] / 256.0f;
fwidth = (float)propMap[ch][2] / 256.0f;
fheight = (float)(PROP_HEIGHT+ special) / 256.0f;
aw = (float)propMap[ch][2] * uis.scalex * sizeScale;
ah = (float)(PROP_HEIGHT+ special) * uis.scaley * sizeScale;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, charset );
}
else
{
aw = 0;
}
ax += (aw + (float)PROP_GAP_WIDTH * uis.scalex * sizeScale);
s++;
}
}
trap_R_SetColor( NULL );
}
/*
=================
UI_ProportionalSizeScale
=================
*/
float UI_ProportionalSizeScale( int style ) {
if( style & UI_SMALLFONT ) {
return PROP_SMALL_SIZE_SCALE;
}
return 1.00;
}
/*
=================
UI_DrawProportionalString
=================
*/
void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ) {
vec4_t drawcolor;
int width;
float sizeScale;
int charstyle=0;
if ((style & UI_BLINK) && ((uis.realtime/BLINK_DIVISOR) & 1))
return;
// Get char style
if (style & UI_TINYFONT)
{
charstyle = UI_TINYFONT;
}
else if (style & UI_SMALLFONT)
{
charstyle = UI_SMALLFONT;
}
else if (style & UI_BIGFONT)
{
charstyle = UI_BIGFONT;
}
else if (style & UI_GIANTFONT)
{
charstyle = UI_GIANTFONT;
}
else // Just in case
{
charstyle = UI_SMALLFONT;
}
sizeScale = UI_ProportionalSizeScale( style );
switch( style & UI_FORMATMASK ) {
case UI_CENTER:
width = UI_ProportionalStringWidth( str,charstyle) * sizeScale;
x -= width / 2;
break;
case UI_RIGHT:
width = UI_ProportionalStringWidth( str,charstyle) * sizeScale;
x -= width;
break;
case UI_LEFT:
default:
break;
}
if ( style & UI_DROPSHADOW ) {
drawcolor[0] = drawcolor[1] = drawcolor[2] = 0;
drawcolor[3] = color[3];
UI_DrawProportionalString2( x+2, y+2, str, drawcolor, sizeScale, uis.charsetProp );
}
if ( style & UI_INVERSE ) {
drawcolor[0] = color[0] * 0.7;
drawcolor[1] = color[1] * 0.7;
drawcolor[2] = color[2] * 0.7;
drawcolor[3] = color[3];
UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, uis.charsetProp );
return;
}
if ( style & UI_PULSE ) {
drawcolor[0] = color[0] * 0.7;
drawcolor[1] = color[1] * 0.7;
drawcolor[2] = color[2] * 0.7;
drawcolor[3] = color[3];
UI_DrawProportionalString2( x, y, str, color, sizeScale, uis.charsetProp );
drawcolor[0] = color[0];
drawcolor[1] = color[1];
drawcolor[2] = color[2];
drawcolor[3] = 0.5 + 0.5 * sin( uis.realtime / PULSE_DIVISOR );
UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, uis.charsetProp );
return;
}
if (style & UI_TINYFONT)
{
UI_DrawProportionalString2( x, y, str, color, charstyle, uis.charsetPropTiny );
}
else if (style & UI_BIGFONT)
{
UI_DrawProportionalString2( x, y, str, color, charstyle, uis.charsetPropBig );
}
else
{
UI_DrawProportionalString2( x, y, str, color, charstyle, uis.charsetProp );
}
}
static int showColorChars;
/*
=================
UI_DrawString2
=================
*/
static void UI_DrawString2( int x, int y, const char* str, vec4_t color, int charw, int charh )
{
const char* s;
char ch;
int forceColor = qfalse; //APSFIXME;
vec4_t tempcolor;
float ax;
float ay;
float aw;
float ah;
float frow;
float fcol;
if (y < -charh)
// offscreen
return;
// draw the colored text
trap_R_SetColor( color );
// ax = x * uis.scale + uis.bias;
ax = x * uis.scalex;
ay = y * uis.scaley;
aw = charw * uis.scalex;
ah = charh * uis.scaley;
s = str;
while ( *s )
{
if (!showColorChars)
{
if ( Q_IsColorString( s ) )
{
if ( !forceColor )
{
memcpy( tempcolor, g_color_table[ColorIndex(s[1])], sizeof( tempcolor ) );
tempcolor[3] = color[3];
trap_R_SetColor( tempcolor );
}
s += 2;
continue;
}
}
ch = *s & 255;
if (ch != ' ')
{
// frow = (ch>>4)*0.0625;
// fcol = (ch&15)*0.0625;
// trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + 0.0625, frow + 0.0625, uis.charset );
frow = (ch>>4)*0.0625;
fcol = (ch&15)*0.0625;
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + 0.03125, frow + 0.0625, uis.charset );
}
ax += aw;
s++;
}
trap_R_SetColor( NULL );
}
/*
=================
UI_DrawString
=================
*/
void UI_DrawString( int x, int y, const char* str, int style, vec4_t color )
{
int len;
int charw;
int charh;
vec4_t newcolor;
vec4_t lowlight;
float *drawcolor;
vec4_t dropcolor;
if( !str ) {
return;
}
if ((style & UI_BLINK) && ((uis.realtime/BLINK_DIVISOR) & 1))
return;
if (style & UI_TINYFONT)
{
charw = TINYCHAR_WIDTH;
charh = TINYCHAR_HEIGHT;
}
else if (style & UI_BIGFONT)
{
charw = BIGCHAR_WIDTH;
charh = BIGCHAR_HEIGHT;
}
else if (style & UI_GIANTFONT)
{
charw = GIANTCHAR_WIDTH;
charh = GIANTCHAR_HEIGHT;
}
else
{
charw = SMALLCHAR_WIDTH;
charh = SMALLCHAR_HEIGHT;
}
if (style & UI_PULSE)
{
lowlight[0] = 0.8*color[0];
lowlight[1] = 0.8*color[1];
lowlight[2] = 0.8*color[2];
lowlight[3] = 0.8*color[3];
UI_LerpColor(color,lowlight,newcolor,0.5+0.5*sin(uis.realtime/PULSE_DIVISOR));
drawcolor = newcolor;
}
else
drawcolor = color;
switch (style & UI_FORMATMASK)
{
case UI_CENTER:
// center justify at x
len = strlen(str);
x = x - len*charw/2;
break;
case UI_RIGHT:
// right justify at x
len = strlen(str);
x = x - len*charw;
break;
default:
// left justify at x
break;
}
if (style & UI_SHOWCOLOR)
{
showColorChars = qtrue;
}
else
{
showColorChars = qfalse;
}
if ( style & UI_DROPSHADOW )
{
dropcolor[0] = dropcolor[1] = dropcolor[2] = 0;
dropcolor[3] = drawcolor[3];
UI_DrawString2(x+2,y+2,str,dropcolor,charw,charh);
}
UI_DrawString2(x,y,str,drawcolor,charw,charh);
}
/*
=================
UI_DrawChar
=================
*/
void UI_DrawChar( int x, int y, int ch, int style, vec4_t color )
{
char buff[2];
buff[0] = ch;
buff[1] = '\0';
UI_DrawString( x, y, buff, style, color );
}
qboolean UI_IsFullscreen( void ) {
if ( uis.activemenu && ( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
return uis.activemenu->fullscreen;
}
return qfalse;
}
static void NeedCDAction( qboolean result ) {
if ( !result ) {
trap_Cvar_Set ("rpg_playIntro", "1");
trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" );
}
}
void UI_SetActiveMenu( uiMenuCommand_t menu ) {
// this should be the ONLY way the menu system is brought up, except for UI_ConsoleCommand below
// enusure minumum menu data is cached
Menu_Cache();
switch ( menu ) {
case UIMENU_NONE:
UI_ForceMenuOff();
return;
case UIMENU_MAIN:
UI_MainMenu();
return;
case UIMENU_NEED_CD:
UI_ConfirmMenu( menu_normal_text[MNT_INSERTCD], 0, NeedCDAction );
return;
case UIMENU_INGAME:
trap_Cvar_Set( "cl_paused", "1" );
UI_InGameMenu();
return;
}
}
/*
=================
UI_KeyEvent
=================
*/
void UI_KeyEvent( int key ) {
sfxHandle_t s;
if (!uis.activemenu) {
return;
}
if (uis.activemenu->key)
s = uis.activemenu->key( key );
else
s = Menu_DefaultKey( uis.activemenu, key );
if ((s > 0) && (s != menu_null_sound))
trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND );
}
/*
=================
UI_MouseEvent
=================
*/
void UI_MouseEvent( int dx, int dy )
{
int i;
menucommon_s* m;
if (!uis.activemenu)
return;
// update mouse screen position
uis.cursorx += dx;
if (uis.cursorx < 0)
uis.cursorx = 0;
else if (uis.cursorx > SCREEN_WIDTH)
uis.cursorx = SCREEN_WIDTH;
uis.cursory += dy;
if (uis.cursory < 0)
uis.cursory = 0;
else if (uis.cursory > SCREEN_HEIGHT)
uis.cursory = SCREEN_HEIGHT;
// region test the active menu items
for (i=0; i<uis.activemenu->nitems; i++)
{
m = (menucommon_s*)uis.activemenu->items[i];
if (m->flags & (QMF_GRAYED|QMF_INACTIVE))
continue;
if ((uis.cursorx < m->left) ||
(uis.cursorx > m->right) ||
(uis.cursory < m->top) ||
(uis.cursory > m->bottom))
{
// cursor out of item bounds
continue;
}
// set focus to item at cursor
if (uis.activemenu->cursor != i)
{
Menu_SetCursor( uis.activemenu, i );
((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor_prev]))->flags &= ~QMF_HASMOUSEFOCUS;
if ( !(((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags & QMF_SILENT ) ) {
trap_S_StartLocalSound( menu_move_sound, CHAN_LOCAL_SOUND );
}
}
((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags |= QMF_HASMOUSEFOCUS;
return;
}
if (uis.activemenu->nitems > 0) {
// out of any region
((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags &= ~QMF_HASMOUSEFOCUS;
}
}
char *UI_Argv( int arg ) {
static char buffer[MAX_STRING_CHARS];
trap_Argv( arg, buffer, sizeof( buffer ) );
return buffer;
}
char *UI_Cvar_VariableString( const char *var_name ) {
static char buffer[MAX_STRING_CHARS];
trap_Cvar_VariableStringBuffer( var_name, buffer, sizeof( buffer ) );
return buffer;
}
/*
=================
UI_Cache
=================
*/
static void UI_Cache_f( void ) {
MainMenu_Cache();
InGame_Cache();
ConfirmMenu_Cache();
PlayerModel_Cache();
PlayerSettings_Cache();
// Preferences_Cache();
ServerInfo_Cache();
SpecifyServer_Cache();
ArenaServers_Cache();
StartServer_Cache();
ServerOptions_Cache();
DriverInfo_Cache();
// GraphicsOptions_Cache();
// UI_DisplayOptionsMenu_Cache();
// UI_SoundOptionsMenu_Cache();
UI_NetworkOptionsMenu_Cache();
UI_SPLevelMenu_Cache();
UI_SPSkillMenu_Cache();
UI_SPPostgameMenu_Cache();
TeamMain_Cache();
UI_AddBots_Cache();
UI_RemoveBots_Cache();
// UI_LoadConfig_Cache();
// UI_SaveConfigMenu_Cache();
UI_BotSelectMenu_Cache();
UI_CDKeyMenu_Cache();
UI_ModsMenu_Cache();
UI_SoundMenu_Cache();
UI_QuitMenu_Cache();
UI_DemosMenu_Cache();
UI_VideoDataMenu_Cache();
UI_GameOptionsMenu_Cache();
UI_ControlsMouseJoyStickMenu_Cache();
UI_ResetGameMenu_Cache();
UI_VideoData2Menu_Cache();
UI_VideoDriverMenu_Cache();
UI_HolomatchInMenu_Cache();
UI_ChooseServerTypeMenu_Cache();
}
/*
=================
UI_ConsoleCommand
=================
*/
qboolean UI_ConsoleCommand( void ) {
char *cmd;
cmd = UI_Argv( 0 );
// ensure minimum menu data is available
Menu_Cache();
if ( Q_stricmp (cmd, "levelselect") == 0 ) {
UI_SPLevelMenu_f();
return qtrue;
}
if ( Q_stricmp (cmd, "postgame") == 0 ) {
UI_SPPostgameMenu_f();
return qtrue;
}
if ( Q_stricmp (cmd, "ui_cache") == 0 ) {
UI_Cache_f();
return qtrue;
}
if ( Q_stricmp (cmd, "ui_teamOrders") == 0 ) {
UI_TeamOrdersMenu_f();
return qtrue;
}
if ( Q_stricmp (cmd, "ui_cdkey") == 0 ) {
UI_CDKeyMenu_f();
return qtrue;
}
if ( Q_stricmp (cmd, "err_dialog") == 0 ) {
UI_ConfirmMenu( UI_Argv( 1 ), 0, 0);
return qtrue;
}
return qfalse;
}
/*
=================
UI_Shutdown
=================
*/
void UI_Shutdown( void ) {
//trap_Cvar_Set ("rpg_playIntro", "1");
}
//--------------------------------------------
static char *UI_ParseFontParms(char *buffer,int propArray[CHARMAX][3])
{
char *token;
int i,i2;
while ( buffer )
{
token = COM_ParseExt( &buffer, qtrue );
// Start with open braket
if ( !Q_stricmp( token, "{" ) )
{
for (i=0;i<CHARMAX;++i)
{
// Brackets for the numbers
token = COM_ParseExt( &buffer, qtrue );
if ( !Q_stricmp( token, "{" ) )
{
;
}
else
{
trap_Print( va( S_COLOR_RED "UI_ParseFontParms : Invalid FONTS.DAT data, near character %d!\n",i));
return(NULL);
}
for (i2=0;i2<3;++i2)
{
token = COM_ParseExt( &buffer, qtrue );
propArray[i][i2] = atoi(token);
}
token = COM_ParseExt( &buffer, qtrue );
if ( !Q_stricmp( token, "}" ) )
{
;
}
else
{
trap_Print( va( S_COLOR_RED "UI_ParseFontParms : Invalid FONTS.DAT data, near character %d!\n",i));
return(NULL);
}
}
}
token = COM_ParseExt( &buffer, qtrue ); // Grab closing bracket
if ( !Q_stricmp( token, "}" ) )
{
break;
}
}
return(buffer);
}
#define FONT_BUFF_LENGTH 20000
/*
=================
UI_LoadFonts
=================
*/
void UI_LoadFonts( void )
{
char buffer[FONT_BUFF_LENGTH];
int len;
fileHandle_t f;
char *holdBuf;
len = trap_FS_FOpenFile( "ext_data/fonts.dat", &f, FS_READ );
if ( !f )
{
trap_Print( va( S_COLOR_RED "UI_LoadFonts : FONTS.DAT file not found!\n"));
return;
}
if (len > FONT_BUFF_LENGTH)
{
trap_Print( va( S_COLOR_RED "UI_LoadFonts : FONTS.DAT file bigger than %d!\n",FONT_BUFF_LENGTH));
return;
}
// initialise the data area
memset(buffer, 0, sizeof(buffer));
trap_FS_Read( buffer, len, f );
trap_FS_FCloseFile( f );
COM_BeginParseSession();
holdBuf = (char *) buffer;
holdBuf = UI_ParseFontParms( holdBuf,propMapTiny);
holdBuf = UI_ParseFontParms( holdBuf,propMap);
holdBuf = UI_ParseFontParms( holdBuf,propMapBig);
}
/*
=================
UI_Init
=================
*/
void UI_Init( void ) {
UI_RegisterCvars();
UI_LoadMenuText();
UI_LoadButtonText();
UI_LoadFonts();
BG_LoadItemNames();
UI_InitGameinfo();
// cache redundant calulations
trap_GetGlconfig( &uis.glconfig );
// for 640x480 virtualized screen
uis.scaley = uis.glconfig.vidHeight * (1.0/480.0);
uis.scalex = uis.glconfig.vidWidth * (1.0/640.0);
/* uis.scale = uis.glconfig.vidHeight * (1.0/480.0);
if ( uis.glconfig.vidWidth * 480 > uis.glconfig.vidHeight * 640 ) {
// wide screen
uis.bias = 0.5 * ( uis.glconfig.vidWidth - ( uis.glconfig.vidHeight * (640.0/480.0) ) );
}
else {
// no wide screen
uis.bias = 0;
}
*/
// initialize the menu system
Menu_Cache();
uis.activemenu = NULL;
uis.menusp = 0;
trap_Cvar_Create ("ui_initialsetup", "0", CVAR_ARCHIVE );
trap_Cvar_Create ("rpg_playIntro", "1", CVAR_ARCHIVE ); //RPG-X | Phenix | 25/02/2005
}
/*
================
UI_AdjustFrom640
Adjusted for resolution and screen aspect ratio
================
*/
void UI_AdjustFrom640( float *x, float *y, float *w, float *h ) {
// expect valid pointers
// *x = *x * uis.scale + uis.bias;
*x *= uis.scalex;
*y *= uis.scaley;
*w *= uis.scalex;
*h *= uis.scaley;
}
void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ) {
qhandle_t hShader;
hShader = trap_R_RegisterShaderNoMip( picname );
UI_AdjustFrom640( &x, &y, &width, &height );
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
}
void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ) {
float s0;
float s1;
float t0;
float t1;
if( w < 0 ) { // flip about vertical
w = -w;
s0 = 1;
s1 = 0;
}
else {
s0 = 0;
s1 = 1;
}
if( h < 0 ) { // flip about horizontal
h = -h;
t0 = 1;
t1 = 0;
}
else {
t0 = 0;
t1 = 1;
}
UI_AdjustFrom640( &x, &y, &w, &h );
trap_R_DrawStretchPic( x, y, w, h, s0, t0, s1, t1, hShader );
}
/*
================
UI_FillRect
Coordinates are 640*480 virtual values
=================
*/
void UI_FillRect( float x, float y, float width, float height, const float *color ) {
trap_R_SetColor( color );
UI_AdjustFrom640( &x, &y, &width, &height );
trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, uis.whiteShader );
trap_R_SetColor( NULL );
}
/*
================
UI_DrawRect
Coordinates are 640*480 virtual values
=================
*/
void UI_DrawRect( float x, float y, float width, float height, const float *color ) {
trap_R_SetColor( color );
UI_AdjustFrom640( &x, &y, &width, &height );
trap_R_DrawStretchPic( x, y, width, 1, 0, 0, 0, 0, uis.whiteShader );
trap_R_DrawStretchPic( x, y, 1, height, 0, 0, 0, 0, uis.whiteShader );
trap_R_DrawStretchPic( x, y + height - 1, width, 1, 0, 0, 0, 0, uis.whiteShader );
trap_R_DrawStretchPic( x + width - 1, y, 1, height, 0, 0, 0, 0, uis.whiteShader );
trap_R_SetColor( NULL );
}
/*
=================
UI_Refresh
=================
*/
void UI_Refresh( int realtime )
{
vec4_t color;
uis.frametime = realtime - uis.realtime;
uis.realtime = realtime;
//trap_Cvar_Set( "sys_lastactive", uis.realtime );
if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
return;
}
UI_UpdateCvars();
if ( uis.activemenu )
{
if (uis.activemenu->fullscreen)
{
// draw the background
trap_R_SetColor( colorTable[CT_BLACK]);
UI_DrawHandlePic(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.whiteShader );
}
else if (!uis.activemenu->nobackground)
{
// draw the background
color[0] = colorTable[CT_BLACK][0];
color[1] = colorTable[CT_BLACK][1];
color[2] = colorTable[CT_BLACK][1];
color[3] = .75;
trap_R_SetColor( color);
UI_DrawHandlePic(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.whiteShader );
}
if (uis.activemenu->draw)
uis.activemenu->draw();
else
Menu_Draw( uis.activemenu );
if( uis.firstdraw ) {
UI_MouseEvent( 0, 0 );
uis.firstdraw = qfalse;
}
}
// draw cursor
trap_R_SetColor( NULL );
if (uis.cursorDraw)
{
UI_DrawHandlePic( uis.cursorx, uis.cursory, 16, 16, uis.cursor);
}
#ifndef NDEBUG
if (uis.debug)
{
// cursor coordinates
UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed );
}
#endif
// delay playing the enter sound until after the
// menu has been drawn, to avoid delay while
// caching images
if (m_entersound)
{
trap_S_StartLocalSound( menu_in_sound, CHAN_LOCAL_SOUND );
m_entersound = qfalse;
}
}
qboolean UI_CursorInRect (int x, int y, int width, int height)
{
if (uis.cursorx < x ||
uis.cursory < y ||
uis.cursorx > x+width ||
uis.cursory > y+height)
return qfalse;
return qtrue;
}
/*
==============
UI_DrawNumField
Take x,y positions as if 640 x 480 and scales them to the proper resolution
==============
*/
static void UI_DrawNumField (int x, int y, int width, int value,int charWidth,int charHeight)
{
char num[16], *ptr;
int l;
int frame;
int xWidth;
if (width < 1)
return;
// draw number string
if (width > 15)
width = 15;
switch ( width ) {
case 1:
value = value > 9 ? 9 : value;
value = value < 0 ? 0 : value;
break;
case 2:
value = value > 99 ? 99 : value;
value = value < -9 ? -9 : value;
break;
case 3:
value = value > 999 ? 999 : value;
value = value < -99 ? -99 : value;
break;
case 4:
value = value > 9999 ? 9999 : value;
value = value < -999 ? -999 : value;
break;
}
Com_sprintf (num, sizeof(num), "%i", value);
l = strlen(num);
if (l > width)
l = width;
xWidth = (charWidth/3);
x += (xWidth)*(width - l);
ptr = num;
while (*ptr && l)
{
//if (*ptr == '-')
// frame = STAT_MINUS;
//else
frame = *ptr -'0';
UI_DrawHandlePic( x,y, 16, 16, uis.smallNumbers[frame] );
x += (xWidth);
ptr++;
l--;
}
}
/*
==============
UI_PrintMenuGraphics
==============
*/
void UI_PrintMenuGraphics(menugraphics_s *menuGraphics,int maxI)
{
int i;
const char *text;
// Now that all the changes are made, print up the graphics
for (i=0;i<maxI;++i)
{
if (menuGraphics[i].type == MG_GRAPHIC)
{
trap_R_SetColor( colorTable[menuGraphics[i].color]);
UI_DrawHandlePic( menuGraphics[i].x,
menuGraphics[i].y,
menuGraphics[i].width,
menuGraphics[i].height,
menuGraphics[i].graphic);
trap_R_SetColor( colorTable[CT_NONE]);
}
else if (menuGraphics[i].type == MG_STRING)
{
if (menuGraphics[i].file)
{
text = menuGraphics[i].file;
}
else if (menuGraphics[i].normaltextEnum)
{
text= menu_normal_text[menuGraphics[i].normaltextEnum];
}
else
{
return;
}
UI_DrawProportionalString( menuGraphics[i].x,
menuGraphics[i].y,
text,
menuGraphics[i].style,
colorTable[menuGraphics[i].color]);
}
else if (menuGraphics[i].type == MG_NUMBER)
{
trap_R_SetColor( colorTable[menuGraphics[i].color]);
UI_DrawNumField (menuGraphics[i].x,
menuGraphics[i].y,
menuGraphics[i].max,
menuGraphics[i].target,
menuGraphics[i].width,
menuGraphics[i].height);
trap_R_SetColor( colorTable[CT_NONE]);
}
else if (menuGraphics[i].type == MG_NONE)
{
; // Don't print anything
}
}
}
/*
==============
UI_PrecacheMenuGraphics
==============
*/
void UI_PrecacheMenuGraphics(menugraphics_s *menuGraphics,int maxI)
{
int i;
for (i=0;i<maxI;++i)
{
if (menuGraphics[i].type == MG_GRAPHIC)
{
menuGraphics[i].graphic = trap_R_RegisterShaderNoMip(menuGraphics[i].file);
}
}
}
/*
===============
MenuFrame_Cache
===============
*/
static void MenuFrame_Cache(void)
{
s_menuframe.cornerUpper = trap_R_RegisterShaderNoMip("menu/common/corner_ll_47_7.tga");
s_menuframe.cornerUpper2= trap_R_RegisterShaderNoMip("menu/common/corner_ul_47_7.tga");
s_menuframe.cornerLower = trap_R_RegisterShaderNoMip("menu/common/corner_ll_47_18.tga");
}
/*
===============
UI_FrameTop_Graphics
===============
*/
static void UI_FrameTop_Graphics(menuframework_s *menu)
{
trap_R_SetColor( colorTable[CT_DKPURPLE2] );
UI_DrawHandlePic( 30, 24, 47, 54, uis.whiteShader); // Top left hand column
trap_R_SetColor( colorTable[CT_DKPURPLE3]);
UI_DrawHandlePic( 30, 81, 47, 34, uis.whiteShader); // Middle left hand column
UI_DrawHandlePic( 30, 115, 128, 64, s_menuframe.cornerUpper); // Corner
UI_DrawHandlePic( 100, 136, 49, 6.5, uis.whiteShader); // Start of line across bottom of top third section
//ABOVE HAS LINE BUG 111 - 38 - 7
trap_R_SetColor( colorTable[CT_LTBROWN1]); ///
UI_DrawHandlePic( 152, 136, 135, 7, uis.whiteShader); // 2nd line across bottom of top third section
trap_R_SetColor( colorTable[CT_LTPURPLE2]);
UI_DrawHandlePic( 290, 136, 12, 7, uis.whiteShader); // 3rd line across bottom of top third section
trap_R_SetColor( colorTable[CT_LTBROWN1]); //RPG-X ADDITION
UI_DrawHandlePic( 305, 139, 60, 4, uis.whiteShader); // 4th line across bottom of top third section
//RPG-X REMOVE trap_R_SetColor( colorTable[CT_LTBROWN1]);
UI_DrawHandlePic( 368, 136, 111, 7, uis.whiteShader); // 5th line across bottom of top third section
if (menu->titleI)
{
UI_DrawProportionalString( menu->titleX, menu->titleY ,menu_normal_text[menu->titleI],
UI_RIGHT|UI_BIGFONT, colorTable[CT_LTORANGE]);
}
}
/*
===============
UI_FrameBottom_Graphics
===============
*/
static void UI_FrameBottom_Graphics(void)
{
trap_R_SetColor( colorTable[CT_DKBROWN1]);
UI_DrawHandlePic( 30, 147, 128, 64, s_menuframe.cornerUpper2); // Top corner
UI_DrawHandlePic( 50, 147, 99, 7, uis.whiteShader);
trap_R_SetColor( colorTable[CT_LTBROWN1]); //DKBROWN1
UI_DrawHandlePic( 152, 147, 135, 7, uis.whiteShader);
trap_R_SetColor( colorTable[CT_DKRED1]); //DKBROWN1
UI_DrawHandlePic( 290, 147, 12, 7, uis.whiteShader);
trap_R_SetColor( colorTable[CT_LTBROWN1]);
UI_DrawHandlePic( 305, 147, 60, 4, uis.whiteShader);
trap_R_SetColor( colorTable[CT_LTGOLD1]); //DKBROWN1
UI_DrawHandlePic( 368, 147, 111, 7, uis.whiteShader);
trap_R_SetColor( colorTable[CT_DKBROWN1]);
UI_DrawHandlePic( 30, 173, 47, 27, uis.whiteShader); // Top left column (81453)
//Start of piece (431108)
UI_DrawHandlePic( 30, 392, 47, 33, uis.whiteShader); // Bottom left column
UI_DrawHandlePic( 30, 425, 128, 64, s_menuframe.cornerLower);// Bottom Left Corner
trap_R_SetColor( colorTable[CT_LTBLUE1]); //LTBROWN1]);
UI_DrawHandlePic( 96, 438, 268, 18, uis.whiteShader); // Bottom front Line
trap_R_SetColor(NULL);
}
/*
=================
UI_MenuBottomLineEnd_Graphics
=================
*/
void UI_MenuBottomLineEnd_Graphics (const char *string,int color)
{
int holdX,holdLength;
trap_R_SetColor( colorTable[color]);
holdX = MENU_TITLE_X - (UI_ProportionalStringWidth( string,UI_SMALLFONT));
holdLength = (367 + 6) - holdX;
UI_DrawHandlePic( 367, 438, holdLength, 18, uis.whiteShader); // Bottom end line
}
/*
=================
UI_MenuFrame
=================
*/
void UI_MenuFrame(menuframework_s *menu)
{
if (!s_menuframe.initialized)
{
MenuFrame_Cache();
}
if (!ingameFlag)
{
menu->fullscreen = qtrue;
}
else // In game menu
{
menu->fullscreen = qfalse;
}
// Graphic frame
UI_FrameTop_Graphics(menu); // Top third
UI_FrameBottom_Graphics(); // Bottom two thirds
// Add foot note
if (menu->footNoteEnum)
{
UI_DrawProportionalString( MENU_TITLE_X, 440, menu_normal_text[menu->footNoteEnum],UI_RIGHT | UI_SMALLFONT, colorTable[CT_LTORANGE]);
UI_MenuBottomLineEnd_Graphics (menu_normal_text[menu->footNoteEnum],CT_LTBROWN1);
}
// Print version
UI_DrawProportionalString( 371, 445, Q3_VERSION,UI_TINYFONT, colorTable[CT_BLACK]);
}
/*
=================
UI_MenuFrame2
=================
*/
void UI_MenuFrame2(menuframework_s *menu)
{
if (!s_menuframe.initialized)
{
MenuFrame_Cache();
}
if (!ingameFlag)
{
menu->fullscreen = qtrue;
}
else // In game menu
{
menu->fullscreen = qfalse;
}
if (menu->titleI)
{
UI_DrawProportionalString( menu->titleX, menu->titleY ,menu_normal_text[menu->titleI],
UI_RIGHT|UI_BIGFONT, colorTable[CT_LTORANGE]);
}
trap_R_SetColor( colorTable[CT_DKBROWN1]);
UI_DrawHandlePic( 30, 25, 47, 119, uis.whiteShader); // Top left column
UI_DrawHandlePic( 30, 147, 47, 53, uis.whiteShader); // left column
UI_DrawHandlePic( 30, 175, 47, 25, uis.whiteShader); // Mid left column
UI_DrawHandlePic( 30, 392, 47, 33, uis.whiteShader); // Bottom left column
UI_DrawHandlePic( 30, 425, 128, 64, s_menuframe.cornerLower);// Bottom Left Corner
trap_R_SetColor( colorTable[CT_LTBROWN1]);
UI_DrawHandlePic( 96, 438, 268, 18, uis.whiteShader); // Bottom front Line
// Add foot note
if (menu->footNoteEnum)
{
UI_DrawProportionalString( MENU_TITLE_X, 440, menu_normal_text[menu->footNoteEnum],UI_RIGHT | UI_SMALLFONT, colorTable[CT_LTORANGE]);
UI_MenuBottomLineEnd_Graphics (menu_normal_text[menu->footNoteEnum],CT_LTBROWN1);
}
trap_R_SetColor(NULL);
// Print version
UI_DrawProportionalString( 371, 445, Q3_VERSION,UI_TINYFONT, colorTable[CT_BLACK]);
}
/*
=================
UI_AntiPlagiarise
RPG-X: TiM- After I noticed how Scott and his buddies
were having a grand time renaming RPG-X to D4, I thought of this
little function to make that a little harder from them.
The function works in 2 phases:
firstly, it scans each string that is parsed into the game
and if either D4 or RPG-Y is seen, it quits the game right away,
giving them absolutely no reason why. Hopefully if they're not too smart,
they'll think it's some other kind of error :D
Secondly, (if the arg is 1) if the string 'RPG-X' is NOT present (Like in the main menu title),
it quits as well. :)
=================
*/
const char* illegalStrings[] = { "D4", "d4", "RPG-Y", "rpg-y", "AORP", "aorp" };
static void UI_AntiPlagiarise ( const char *textLine, int arg )
{
int i;
char language[32];
trap_Cvar_VariableStringBuffer( "g_language", language, 32 );
// If it's English then no extension
if (language[0]=='\0' || Q_stricmp ("ENGLISH",language)==0)
{
if (arg == 0 ) {
for (i = 0; i < 6; i++ ) {
if ( strstr( textLine, illegalStrings[i] ) != 0 )
trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" );
}
}
else if (arg == 1 ) {
if ( !strstr( textLine, "RPG-X" ) ) {
trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" );
}
}
}
}
#define MAXMENUTEXT 15000
char MenuText[MAXMENUTEXT];
/*
=================
UI_ParseMenuText
=================
*/
static void UI_ParseMenuText()
{
char *token;
char *buffer;
int i;
int len;
int j;
COM_BeginParseSession();
buffer = MenuText;
//RPG-X: TiM - Stop any D3 menu hacks in their tracks :P
UI_AntiPlagiarise( buffer, 0 );
i = 1; // Zero is null string
while ( buffer )
{
token = COM_ParseExt( &buffer, qtrue );
len = strlen(token);
if (len)
{
menu_normal_text[i] = (buffer - (len + 1));
*(buffer - 1) = '\0'; // Place an string end where is belongs.
i++;
}
if (i> MNT_MAX)
{
Com_Printf( S_COLOR_RED "UI_ParseMenuText : too many values! Needed %d but got %d.\n",MNT_MAX,i);
return;
}
}
if (i != MNT_MAX)
{
Com_Printf( S_COLOR_RED "UI_ParseMenuText : not enough lines. Read %d of %d!\n",i,MNT_MAX);
for(;i<MNT_MAX;i++) {
menu_normal_text[i] = "?";
}
}
//RPG-X: TiM- If 'RPG-X' is missing from any of the main menu titles, kick it ;)
for(j=1; j < 12; j++) {
UI_AntiPlagiarise( menu_normal_text[j], 1 );
}
}
/*
=================
UI_LoadMenuText
=================
*/
void UI_LoadMenuText()
{
int len;//,i;
fileHandle_t f;
char filename[MAX_QPATH];
UI_LanguageFilename("ext_data/mp_normaltext","dat",filename);
len = trap_FS_FOpenFile( filename, &f, FS_READ );
if ( !f )
{
Com_Error( ERR_FATAL, "UI_LoadMenuText : MP_NORMALTEXT.DAT file not found!\n");
return;
}
if ( len > MAXMENUTEXT )
{
Com_Error( ERR_FATAL, "UI_LoadMenuText : MP_NORMALTEXT.DAT size (%d) > max (%d)!\n", len, MAXMENUTEXT );
return;
}
// initialise the data area
memset(MenuText, 0, sizeof(MenuText));
trap_FS_Read( MenuText, len, f );
trap_FS_FCloseFile( f );
UI_ParseMenuText();
}
#define MAXBUTTONTEXT 15000
char ButtonText[MAXBUTTONTEXT];
/*
=================
UI_ParseButtonText
=================
*/
static void UI_ParseButtonText()
{
char *token;
char *buffer;
int i;
int len;
COM_BeginParseSession();
buffer = ButtonText;
//RPG-X: TiM - Stop any D3 menu hacks in their tracks :P
UI_AntiPlagiarise( buffer, 0 );
i = 1; // Zero is null string
while ( buffer )
{
// G_ParseString( &buffer, &token);
token = COM_ParseExt( &buffer, qtrue );
len = strlen(token);
if (len)
{
if ((len == 1) && (token[0] == '/')) // A NULL?
{
menu_button_text[i][0] = menuEmptyLine;
menu_button_text[i][1] = menuEmptyLine;
}
else
{
menu_button_text[i][0] = (buffer - (len + 1)); // The +1 is to get rid of the " at the beginning of the sting.
}
*(buffer - 1) = '\0'; // Place an string end where is belongs.
token = COM_ParseExt( &buffer, qtrue );
len = strlen(token);
if (len)
{
menu_button_text[i][1] = (buffer - (len+1)); // The +1 is to get rid of the " at the beginning of the sting.
*(buffer-1) = '\0'; // Place an string end where is belongs.
}
++i;
}
if (i> MBT_MAX)
{
Com_Printf( S_COLOR_RED "UI_ParseButtonText : too many values!\n");
return;
}
}
if (i != MBT_MAX)
{
Com_Printf( S_COLOR_RED "UI_ParseButtonText : not enough lines. Read %d of %d!\n",i,MBT_MAX);
for(;i<MBT_MAX;i++) {
menu_button_text[i][0] = "?";
menu_button_text[i][1] = "?";
}
}
}
/*
=================
UI_LoadButtonText
=================
*/
void UI_LoadButtonText()
{
char filename[MAX_QPATH];
int len,i;
fileHandle_t f;
UI_LanguageFilename("ext_data/mp_buttontext","dat",filename);
len = trap_FS_FOpenFile( filename, &f, FS_READ );
if ( !f )
{
Com_Printf( S_COLOR_RED "UI_LoadButtonText : MP_BUTTONTEXT.DAT file not found!\n");
return;
}
if ( len > MAXBUTTONTEXT )
{
Com_Printf( S_COLOR_RED "UI_LoadButtonText : MP_BUTTONTEXT.DAT too big!\n");
return;
}
for (i=0;i<MBT_MAX;++i)
{
menu_button_text[i][0] = menuEmptyLine;
menu_button_text[i][1] = menuEmptyLine;
}
// initialise the data area
memset(ButtonText, 0, sizeof(ButtonText));
trap_FS_Read( ButtonText, len, f );
trap_FS_FCloseFile( f );
UI_ParseButtonText();
}
/*
=================
UI_InitSpinControl
=================
*/
void UI_InitSpinControl(menulist_s *spincontrol)
{
spincontrol->generic.type = MTYPE_SPINCONTROL;
spincontrol->generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
spincontrol->textcolor = CT_BLACK;
spincontrol->textcolor2 = CT_WHITE;
spincontrol->color = CT_DKPURPLE1;
spincontrol->color2 = CT_LTPURPLE1;
spincontrol->textX = MENU_BUTTON_TEXT_X;
spincontrol->textY = MENU_BUTTON_TEXT_Y;
}
/*
UI_LanguageFilename - create a filename with an extension based on the value in g_language
*/
static void UI_LanguageFilename(char *baseName,char *baseExtension,char *finalName)
{
char language[32];
fileHandle_t file;
trap_Cvar_VariableStringBuffer( "g_language", language, 32 );
// If it's English then no extension
if (language[0]=='\0' || Q_stricmp ("ENGLISH",language)==0)
{
Com_sprintf(finalName,MAX_QPATH,"%s.%s",baseName,baseExtension);
}
else
{
Com_sprintf(finalName,MAX_QPATH,"%s_%s.%s",baseName,language,baseExtension);
//Attempt to load the file
trap_FS_FOpenFile( finalName, &file, FS_READ );
if ( file == 0 ) // This extension doesn't exist, go English.
{
Com_sprintf(finalName,MAX_QPATH,"%s.%s",baseName,baseExtension); //the caller will give the error if this isn't there
}
else
{
trap_FS_FCloseFile( file );
}
}
}