diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_draw.c | 72 | ||||
-rw-r--r-- | src/cgame/cg_local.h | 14 | ||||
-rw-r--r-- | src/cgame/cg_main.c | 34 | ||||
-rw-r--r-- | src/cgame/cg_view.c | 4 | ||||
-rw-r--r-- | src/ui/ui_shared.c | 212 |
5 files changed, 294 insertions, 42 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c index 74b5dc61..6befbcd0 100644 --- a/src/cgame/cg_draw.c +++ b/src/cgame/cg_draw.c @@ -412,12 +412,8 @@ static void CG_DrawPlayerStamina( rectDef_t *rect ) playerState_t *ps = &cg.snap->ps; int stamina = ps->stats[ STAT_STAMINA ]; int height = (int)( (float)stamina / ( MAX_STAMINA / ( rect->h / 2 ) ) ); - vec4_t bcolor = { 0.5f, 0.5f, 0.5f, 0.5f }; - vec4_t pos = { 0.0f, 0.5f, 0.0f, 0.5f }; - vec4_t neg = { 0.5f, 0.0f, 0.0f, 0.5f }; - - trap_R_SetColor( bcolor ); // white - CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.whiteShader ); + vec4_t pos = { 0.0f, 1.0f, 0.0f, 0.5f }; + vec4_t neg = { 1.0f, 0.0f, 0.0f, 0.5f }; if( stamina > 0 ) { @@ -1446,6 +1442,66 @@ static void CG_DrawLagometer( rectDef_t *rect, qhandle_t shader ) CG_DrawDisconnect(); } +/* +============== +CG_DrawConsole +============== +*/ +static void CG_DrawConsole( rectDef_t *rect, float text_x, float text_y, vec4_t color, + float scale, int align, int textStyle ) +{ + float x, y, w, h; + menuDef_t dummyParent; + itemDef_t textItem; + + //offset the text + x = rect->x; + y = rect->y; + w = rect->w - ( 16 + ( 2 * text_x ) ); //16 to ensure text within frame + h = rect->h; + + textItem.text = cg.consoleText; + + textItem.parent = &dummyParent; + memcpy( textItem.window.foreColor, color, sizeof( vec4_t ) ); + textItem.window.flags = 0; + + switch( align ) + { + case ITEM_ALIGN_LEFT: + textItem.window.rect.x = x; + break; + + case ITEM_ALIGN_RIGHT: + textItem.window.rect.x = x + w; + break; + + case ITEM_ALIGN_CENTER: + textItem.window.rect.x = x + ( w / 2 ); + break; + + default: + textItem.window.rect.x = x; + break; + } + + textItem.window.rect.y = y; + textItem.window.rect.w = w; + textItem.window.rect.h = h; + textItem.window.borderSize = 0; + textItem.textRect.x = 0; + textItem.textRect.y = 0; + textItem.textRect.w = 0; + textItem.textRect.h = 0; + textItem.textalignment = align; + textItem.textalignx = text_x; + textItem.textaligny = text_y; + textItem.textscale = scale; + textItem.textStyle = textStyle; + + //hack to utilise existing autowrap code + Item_Text_AutoWrapped_Paint( &textItem ); +} void CG_OwnerDraw( float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, @@ -1552,6 +1608,10 @@ void CG_OwnerDraw( float x, float y, float w, float h, float text_x, CG_DrawLagometer( &rect, shader ); break; + case CG_CONSOLE: + CG_DrawConsole( &rect, text_x, text_y, color, scale, align, textStyle ); + break; + default: break; } diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 6324de79..2bd676a2 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -506,6 +506,15 @@ typedef struct int numHumanClients; } entityPos_t; +typedef struct +{ + int time; + int length; +} consoleLine_t; + +#define MAX_CONSOLE_TEXT 8192 +#define MAX_CONSOLE_LINES 32 + // all cg.stepTime, cg.duckTime, cg.landTime, etc are set to cg.time when the action // occurs, and they will have visible effects for #define STEP_TIME or whatever msec after @@ -726,6 +735,10 @@ typedef struct { entityPos_t ep; int lastBuildAttempt; + + char consoleText[ MAX_CONSOLE_TEXT ]; + consoleLine_t consoleLines[ MAX_CONSOLE_LINES ]; + int numConsoleLines; } cg_t; @@ -1270,6 +1283,7 @@ extern vmCvar_t cg_debugAlloc; extern vmCvar_t cg_wwSmoothTime; extern vmCvar_t cg_wwFollow; extern vmCvar_t cg_zsortLEs; +extern vmCvar_t cg_consoleLatency; //TA: hack to get class an carriage through to UI module extern vmCvar_t ui_currentClass; diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c index 57fb621e..a5ffec50 100644 --- a/src/cgame/cg_main.c +++ b/src/cgame/cg_main.c @@ -183,6 +183,7 @@ vmCvar_t cg_debugAlloc; vmCvar_t cg_wwSmoothTime; vmCvar_t cg_wwFollow; vmCvar_t cg_zsortLEs; +vmCvar_t cg_consoleLatency; //TA: hack to get class and carriage through to UI module vmCvar_t ui_currentClass; @@ -274,6 +275,7 @@ static cvarTable_t cvarTable[] = { { &cg_wwSmoothTime, "cg_wwSmoothTime", "300", CVAR_ARCHIVE }, { &cg_wwFollow, "cg_wwFollow", "1", CVAR_ARCHIVE|CVAR_USERINFO }, { &cg_zsortLEs, "cg_zsortLEs", "1", CVAR_ARCHIVE }, + { &cg_consoleLatency, "cg_consoleLatency", "3000", CVAR_ARCHIVE }, { &ui_currentClass, "ui_currentClass", "0", 0 }, { &ui_carriage, "ui_carriage", "", 0 }, @@ -410,6 +412,26 @@ int CG_LastAttacker( void ) { return cg.snap->ps.persistant[PERS_ATTACKER]; } +void CG_RemoveConsoleLine( void ) +{ + int i, offset, totalLength; + + if( cg.numConsoleLines == 0 ) + return; + + offset = cg.consoleLines[ 0 ].length; + totalLength = strlen( cg.consoleText ) - offset; + + //slide up consoleText + for( i = 0; i <= totalLength; i++ ) + cg.consoleText[ i ] = cg.consoleText[ i + offset ]; + + //pop up the first consoleLine + for( i = 0; i < cg.numConsoleLines; i++ ) + cg.consoleLines[ i ] = cg.consoleLines[ i + 1 ]; + + cg.numConsoleLines--; +} void QDECL CG_Printf( const char *msg, ... ) { va_list argptr; @@ -419,6 +441,15 @@ void QDECL CG_Printf( const char *msg, ... ) { vsprintf (text, msg, argptr); va_end (argptr); + //TA: team arena UI based console + if( cg.numConsoleLines == MAX_CONSOLE_LINES ) + CG_RemoveConsoleLine( ); + + strcat( cg.consoleText, text ); + cg.consoleLines[ cg.numConsoleLines ].time = cg.time; + cg.consoleLines[ cg.numConsoleLines ].length = strlen( text ); + cg.numConsoleLines++; + trap_Print( text ); } @@ -1638,6 +1669,9 @@ void CG_Init( int serverMessageNum, int serverCommandSequence, int clientNum ) { CG_RegisterCvars(); CG_InitConsoleCommands(); + + //repress standard Q3 console + trap_Cvar_Set( "con_notifytime", "-2" ); //TA: moved up for LoadHudMenu String_Init(); diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index eb9cfacd..ce49d68a 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -1236,6 +1236,10 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo // warning sounds when powerup is wearing off /*CG_PowerupTimerSounds();*/ + //remove expired console lines + if( cg.consoleLines[ 0 ].time + cg_consoleLatency.integer < cg.time ) + CG_RemoveConsoleLine( ); + // update audio positions trap_S_Respatialize( cg.snap->ps.clientNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater ); diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c index 8c4ae3e8..4db016a7 100644 --- a/src/ui/ui_shared.c +++ b/src/ui/ui_shared.c @@ -2813,76 +2813,216 @@ void Item_TextColor(itemDef_t *item, vec4_t *newColor) { } } -void Item_Text_AutoWrapped_Paint(itemDef_t *item) { - char text[1024]; - const char *p, *textPtr, *newLinePtr; - char buff[1024]; - int width, height, len, textWidth, newLine, newLineWidth; - float y; - vec4_t color; +int Item_Text_AutoWrapped_Lines( itemDef_t *item ) +{ + char text[ 1024 ]; + const char *p, *textPtr, *newLinePtr; + char buff[ 1024 ]; + int len, textWidth, newLine, newLineWidth; + vec4_t color; + int lines = 0; textWidth = 0; newLinePtr = NULL; - if (item->text == NULL) { - if (item->cvar == NULL) { - return; - } - else { - DC->getCVarString(item->cvar, text, sizeof(text)); + if( item->text == NULL ) + { + if( item->cvar == NULL ) + return 0; + else + { + DC->getCVarString( item->cvar, text, sizeof( text ) ); textPtr = text; } } - else { + else textPtr = item->text; + + if( *textPtr == '\0' ) + return 0; + + len = 0; + buff[ 0 ] = '\0'; + newLine = 0; + newLineWidth = 0; + p = textPtr; + + while( p ) + { + textWidth = DC->textWidth( buff, item->textscale, 0 ); + + if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) + { + newLine = len; + newLinePtr = p + 1; + newLineWidth = textWidth; + } + + //TA: forceably split lines that are too long (where normal splitage has failed) + if( textWidth > item->window.rect.w && newLine == 0 ) + { + newLine = len; + newLinePtr = p; + newLineWidth = textWidth; + } + + if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' ) + { + if( len ) + buff[ newLine ] = '\0'; + + if( !( *p == '\n' && !*( p + 1 ) ) ) + lines++; + + if( *p == '\0' ) + break; + + // + p = newLinePtr; + len = 0; + newLine = 0; + newLineWidth = 0; + + continue; + } + + buff[ len++ ] = *p++; + buff[ len ] = '\0'; } - if (*textPtr == '\0') { - return; + + return lines; +} + +void Item_Text_AutoWrapped_Paint( itemDef_t *item ) +{ + char text[ 1024 ]; + const char *p, *textPtr, *newLinePtr; + char buff[ 1024 ]; + char lastCMod[ 2 ] = { 0, 0 }; + qboolean forwardColor; + int width, height, len, textWidth, newLine, newLineWidth, skipLines, totalLines; + float y, totalY; + vec4_t color; + + textWidth = 0; + newLinePtr = NULL; + + if( item->text == NULL ) + { + if( item->cvar == NULL ) + return; + else + { + DC->getCVarString( item->cvar, text, sizeof( text ) ); + textPtr = text; + } } - Item_TextColor(item, &color); - Item_SetTextExtents(item, &width, &height, textPtr); + else + textPtr = item->text; + + if( *textPtr == '\0' ) + return; + + Item_TextColor( item, &color ); + Item_SetTextExtents( item, &width, &height, textPtr ); y = item->textaligny; len = 0; - buff[0] = '\0'; + buff[ 0 ] = '\0'; newLine = 0; newLineWidth = 0; p = textPtr; - while (p) { - if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\0') { + + skipLines = -1; + totalLines = Item_Text_AutoWrapped_Lines( item ); + + do + { + skipLines++; + totalY = ( totalLines - skipLines ) * ( height + 5 ); + } while( totalY > item->window.rect.h ); + + while( p ) + { + textWidth = DC->textWidth( buff, item->textscale, 0 ); + + if( *p == '^' ) + { + lastCMod[ 0 ] = p[ 0 ]; + lastCMod[ 1 ] = p[ 1 ]; + } + + if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) + { newLine = len; newLinePtr = p+1; newLineWidth = textWidth; + + if( *p == '\n' ) //don't forward colours past deilberate \n's + lastCMod[ 0 ] = lastCMod[ 1 ] = 0; + else + forwardColor = qtrue; } - textWidth = DC->textWidth(buff, item->textscale, 0); - if ( (newLine && textWidth > item->window.rect.w) || *p == '\n' || *p == '\0') { - if (len) { - if (item->textalignment == ITEM_ALIGN_LEFT) { + + //TA: forceably split lines that are too long (where normal splitage has failed) + if( textWidth > item->window.rect.w && newLine == 0 ) + { + newLine = len; + newLinePtr = p; + newLineWidth = textWidth; + + forwardColor = qtrue; + } + + if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' ) + { + if( len ) + { + if( item->textalignment == ITEM_ALIGN_LEFT ) item->textRect.x = item->textalignx; - } else if (item->textalignment == ITEM_ALIGN_RIGHT) { + else if( item->textalignment == ITEM_ALIGN_RIGHT ) item->textRect.x = item->textalignx - newLineWidth; - } else if (item->textalignment == ITEM_ALIGN_CENTER) { + else if( item->textalignment == ITEM_ALIGN_CENTER ) item->textRect.x = item->textalignx - newLineWidth / 2; - } + item->textRect.y = y; - ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window); + ToWindowCoords( &item->textRect.x, &item->textRect.y, &item->window ); // - buff[newLine] = '\0'; - DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle); + buff[ newLine ] = '\0'; + + if( !skipLines ) + DC->drawText( item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle ); } - if (*p == '\0') { + + if( *p == '\0' ) break; - } + // - y += height + 5; + if( !skipLines ) + y += height + 5; + + if( skipLines ) + skipLines--; + p = newLinePtr; len = 0; newLine = 0; newLineWidth = 0; + + if( forwardColor && lastCMod[ 0 ] != 0 ) + { + buff[ len++ ] = lastCMod[ 0 ]; + buff[ len++ ] = lastCMod[ 1 ]; + buff[ len ] = '\0'; + + forwardColor = qfalse; + } + continue; } - buff[len++] = *p++; - buff[len] = '\0'; + + buff[ len++ ] = *p++; + buff[ len ] = '\0'; } } |