summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cgame/cg_draw.c72
-rw-r--r--src/cgame/cg_local.h14
-rw-r--r--src/cgame/cg_main.c34
-rw-r--r--src/cgame/cg_view.c4
-rw-r--r--src/ui/ui_shared.c212
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';
}
}