📄 ui_main.c
字号:
float yadj;
float useScale;
fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
if (scale <= ui_smallFont.value) {
font = &uiInfo.uiDC.Assets.smallFont;
} else if (scale >= ui_bigFont.value) {
font = &uiInfo.uiDC.Assets.bigFont;
}
useScale = scale * font->glyphScale;
if (text) {
const char *s = text; // bk001206 - unsigned
trap_R_SetColor( color );
memcpy(&newColor[0], &color[0], sizeof(vec4_t));
len = strlen(text);
if (limit > 0 && len > limit) {
len = limit;
}
count = 0;
glyph2 = &font->glyphs[ (int) cursor]; // bk001206 - possible signed char
while (s && *s && count < len) {
glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build
//int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top;
//float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height);
if ( Q_IsColorString( s ) ) {
memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) );
newColor[3] = color[3];
trap_R_SetColor( newColor );
s += 2;
continue;
} else {
yadj = useScale * glyph->top;
if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) {
int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2;
colorBlack[3] = newColor[3];
trap_R_SetColor( colorBlack );
Text_PaintChar(x + ofs, y - yadj + ofs,
glyph->imageWidth,
glyph->imageHeight,
useScale,
glyph->s,
glyph->t,
glyph->s2,
glyph->t2,
glyph->glyph);
colorBlack[3] = 1.0;
trap_R_SetColor( newColor );
}
Text_PaintChar(x, y - yadj,
glyph->imageWidth,
glyph->imageHeight,
useScale,
glyph->s,
glyph->t,
glyph->s2,
glyph->t2,
glyph->glyph);
yadj = useScale * glyph2->top;
if (count == cursorPos && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) {
Text_PaintChar(x, y - yadj,
glyph2->imageWidth,
glyph2->imageHeight,
useScale,
glyph2->s,
glyph2->t,
glyph2->s2,
glyph2->t2,
glyph2->glyph);
}
x += (glyph->xSkip * useScale);
s++;
count++;
}
}
// need to paint cursor at end of text
if (cursorPos == len && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) {
yadj = useScale * glyph2->top;
Text_PaintChar(x, y - yadj,
glyph2->imageWidth,
glyph2->imageHeight,
useScale,
glyph2->s,
glyph2->t,
glyph2->s2,
glyph2->t2,
glyph2->glyph);
}
trap_R_SetColor( NULL );
}
}
static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit) {
int len, count;
vec4_t newColor;
glyphInfo_t *glyph;
if (text) {
const char *s = text; // bk001206 - unsigned
float max = *maxX;
float useScale;
fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
if (scale <= ui_smallFont.value) {
font = &uiInfo.uiDC.Assets.smallFont;
} else if (scale > ui_bigFont.value) {
font = &uiInfo.uiDC.Assets.bigFont;
}
useScale = scale * font->glyphScale;
trap_R_SetColor( color );
len = strlen(text);
if (limit > 0 && len > limit) {
len = limit;
}
count = 0;
while (s && *s && count < len) {
glyph = &font->glyphs[(int)*s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build
if ( Q_IsColorString( s ) ) {
memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) );
newColor[3] = color[3];
trap_R_SetColor( newColor );
s += 2;
continue;
} else {
float yadj = useScale * glyph->top;
if (Text_Width(s, useScale, 1) + x > max) {
*maxX = 0;
break;
}
Text_PaintChar(x, y - yadj,
glyph->imageWidth,
glyph->imageHeight,
useScale,
glyph->s,
glyph->t,
glyph->s2,
glyph->t2,
glyph->glyph);
x += (glyph->xSkip * useScale) + adjust;
*maxX = x;
count++;
s++;
}
}
trap_R_SetColor( NULL );
}
}
void UI_ShowPostGame(qboolean newHigh) {
trap_Cvar_Set ("cg_cameraOrbit", "0");
trap_Cvar_Set("cg_thirdPerson", "0");
trap_Cvar_Set( "sv_killserver", "1" );
uiInfo.soundHighScore = newHigh;
_UI_SetActiveMenu(UIMENU_POSTGAME);
}
/*
=================
_UI_Refresh
=================
*/
void UI_DrawCenteredPic(qhandle_t image, int w, int h) {
int x, y;
x = (SCREEN_WIDTH - w) / 2;
y = (SCREEN_HEIGHT - h) / 2;
UI_DrawHandlePic(x, y, w, h, image);
}
int frameCount = 0;
int startTime;
#define UI_FPS_FRAMES 4
void _UI_Refresh( int realtime )
{
static int index;
static int previousTimes[UI_FPS_FRAMES];
//if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
// return;
//}
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) {
UI_DrawHandlePic( uiInfo.uiDC.cursorx-16, uiInfo.uiDC.cursory-16, 32, 32, uiInfo.uiDC.Assets.cursor);
}
#ifndef NDEBUG
if (uiInfo.uiDC.debug)
{
// cursor coordinates
//FIXME
//UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed );
}
#endif
}
/*
=================
_UI_Shutdown
=================
*/
void _UI_Shutdown( void ) {
trap_LAN_SaveCachedServers();
}
char *defaultMenu = NULL;
char *GetMenuBuffer(const char *filename) {
int len;
fileHandle_t f;
static char buf[MAX_MENUFILE];
len = trap_FS_FOpenFile( filename, &f, FS_READ );
if ( !f ) {
trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
return defaultMenu;
}
if ( len >= MAX_MENUFILE ) {
trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
trap_FS_FCloseFile( f );
return defaultMenu;
}
trap_FS_Read( buf, len, f );
buf[len] = 0;
trap_FS_FCloseFile( f );
//COM_Compress(buf);
return buf;
}
qboolean Asset_Parse(int handle) {
pc_token_t token;
const char *tempStr;
if (!trap_PC_ReadToken(handle, &token))
return qfalse;
if (Q_stricmp(token.string, "{") != 0) {
return qfalse;
}
while ( 1 ) {
memset(&token, 0, sizeof(pc_token_t));
if (!trap_PC_ReadToken(handle, &token))
return qfalse;
if (Q_stricmp(token.string, "}") == 0) {
return qtrue;
}
// font
if (Q_stricmp(token.string, "font") == 0) {
int pointSize;
if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) {
return qfalse;
}
trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont);
uiInfo.uiDC.Assets.fontRegistered = qtrue;
continue;
}
if (Q_stricmp(token.string, "smallFont") == 0) {
int pointSize;
if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) {
return qfalse;
}
trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.smallFont);
continue;
}
if (Q_stricmp(token.string, "bigFont") == 0) {
int pointSize;
if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) {
return qfalse;
}
trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.bigFont);
continue;
}
// gradientbar
if (Q_stricmp(token.string, "gradientbar") == 0) {
if (!PC_String_Parse(handle, &tempStr)) {
return qfalse;
}
uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr);
continue;
}
// enterMenuSound
if (Q_stricmp(token.string, "menuEnterSound") == 0) {
if (!PC_String_Parse(handle, &tempStr)) {
return qfalse;
}
uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
// exitMenuSound
if (Q_stricmp(token.string, "menuExitSound") == 0) {
if (!PC_String_Parse(handle, &tempStr)) {
return qfalse;
}
uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
// itemFocusSound
if (Q_stricmp(token.string, "itemFocusSound") == 0) {
if (!PC_String_Parse(handle, &tempStr)) {
return qfalse;
}
uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
// menuBuzzSound
if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
if (!PC_String_Parse(handle, &tempStr)) {
return qfalse;
}
uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse );
continue;
}
if (Q_stricmp(token.string, "cursor") == 0) {
if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr)) {
return qfalse;
}
uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr);
continue;
}
if (Q_stricmp(token.string, "fadeClamp") == 0) {
if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) {
return qfalse;
}
continue;
}
if (Q_stricmp(token.string, "fadeCycle") == 0) {
if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) {
return qfalse;
}
continue;
}
if (Q_stricmp(token.string, "fadeAmount") == 0) {
if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) {
return qfalse;
}
continue;
}
if (Q_stricmp(token.string, "shadowX") == 0) {
if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) {
return qfalse;
}
continue;
}
if (Q_stricmp(token.string, "shadowY") == 0) {
if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) {
return qfalse;
}
continue;
}
if (Q_stricmp(token.string, "shadowColor") == 0) {
if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) {
return qfalse;
}
uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
continue;
}
}
return qfalse;
}
void Font_Report() {
int i;
Com_Printf("Font Info\n");
Com_Printf("=========\n");
for ( i = 32; i < 96; i++) {
Com_Printf("Glyph handle %i: %i\n", i, uiInfo.uiDC.Assets.textFont.glyphs[i].glyph);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -