summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cgame/cg_draw.c113
-rw-r--r--src/cgame/cg_event.c3
-rw-r--r--src/cgame/cg_local.h10
-rw-r--r--src/cgame/cg_main.c10
-rw-r--r--src/cgame/cg_playerstate.c4
-rw-r--r--src/cgame/cg_view.c48
6 files changed, 140 insertions, 48 deletions
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 104968a6..40a49358 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -3222,6 +3222,115 @@ static void CG_Draw2D( void )
CG_DrawCenterString( );
}
+#define PAINBLEND_BORDER_W 128.0f
+#define PAINBLEND_BORDER_H 96.0f
+/*
+===============
+CG_PainBlend
+===============
+*/
+static void CG_PainBlend( void )
+{
+ vec4_t color;
+ int damage;
+ float damageAsFracOfMax;
+ qhandle_t shader = cgs.media.whiteShader;
+ float x, y, w, h;
+
+ damage = cg.lastHealth - cg.snap->ps.stats[ STAT_HEALTH ];
+
+ if( damage < 0 )
+ damage = 0;
+
+ damageAsFracOfMax = (float)damage / cg.snap->ps.stats[ STAT_MAX_HEALTH ];
+ cg.lastHealth = cg.snap->ps.stats[ STAT_HEALTH ];
+
+ cg.painBlendValue += damageAsFracOfMax * cg_painBlendScale.value;
+
+ if( cg.painBlendValue > 0.0f )
+ {
+ cg.painBlendValue -= ( cg.frametime / 1000.0f ) *
+ cg_painBlendDownRate.value;
+ }
+
+ if( cg.painBlendValue > 1.0f )
+ cg.painBlendValue = 1.0f;
+ else if( cg.painBlendValue <= 0.0f )
+ {
+ cg.painBlendValue = 0.0f;
+ return;
+ }
+
+ if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
+ VectorSet( color, 0.43f, 0.8f, 0.37f );
+ else if( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
+ VectorSet( color, 0.8f, 0.0f, 0.0f );
+
+ if( cg.painBlendValue > cg.painBlendTarget )
+ {
+ cg.painBlendTarget += ( cg.frametime / 1000.0f ) *
+ cg_painBlendUpRate.value;
+ }
+ else if( cg.painBlendValue < cg.painBlendTarget )
+ cg.painBlendTarget = cg.painBlendValue;
+
+ if( cg.painBlendTarget > cg_painBlendMax.value )
+ cg.painBlendTarget = cg_painBlendMax.value;
+
+ color[ 3 ] = cg.painBlendTarget;
+
+ trap_R_SetColor( color );
+
+ //left
+ x = 0.0f; y = 0.0f;
+ w = PAINBLEND_BORDER_W; h = 480.0f;
+ CG_AdjustFrom640( &x, &y, &w, &h );
+ trap_R_DrawStretchPic( x, y, w, h,
+ 0.0f, 0.0f,
+ PAINBLEND_BORDER_W / 640.0f, 1.0f,
+ shader );
+
+ //right
+ x = 640.0f - PAINBLEND_BORDER_W; y = 0.0f;
+ w = PAINBLEND_BORDER_W; h = 480.0f;
+ CG_AdjustFrom640( &x, &y, &w, &h );
+ trap_R_DrawStretchPic( x, y, w, h,
+ ( 640.0f - PAINBLEND_BORDER_W ) / 640.0f, 0.0f,
+ 1.0f, 1.0f,
+ shader );
+
+ //top
+ x = PAINBLEND_BORDER_W; y = 0.0f;
+ w = 640.0f - 2 * PAINBLEND_BORDER_W; h = PAINBLEND_BORDER_H;
+ CG_AdjustFrom640( &x, &y, &w, &h );
+ trap_R_DrawStretchPic( x, y, w, h,
+ PAINBLEND_BORDER_W / 640.0f, 0.0f,
+ ( 640.0f - PAINBLEND_BORDER_W ) / 640.0f, PAINBLEND_BORDER_H / 480.0f,
+ shader );
+
+ //bottom
+ x = PAINBLEND_BORDER_W; y = 480.0f - PAINBLEND_BORDER_H;
+ w = 640.0f - 2 * PAINBLEND_BORDER_W; h = PAINBLEND_BORDER_H;
+ CG_AdjustFrom640( &x, &y, &w, &h );
+ trap_R_DrawStretchPic( x, y, w, h,
+ PAINBLEND_BORDER_W / 640.0f, ( 480.0f - PAINBLEND_BORDER_H ) / 480.0f,
+ ( 640.0f - PAINBLEND_BORDER_W ) / 640.0f, 1.0f,
+ shader );
+
+ trap_R_SetColor( NULL );
+}
+
+/*
+=====================
+CG_ResetPainBlend
+=====================
+*/
+void CG_ResetPainBlend( void )
+{
+ cg.painBlendValue = 0.0f;
+ cg.painBlendTarget = 0.0f;
+ cg.lastHealth = cg.snap->ps.stats[ STAT_MAX_HEALTH ];
+}
/*
=====================
@@ -3272,6 +3381,10 @@ void CG_DrawActive( stereoFrame_t stereoView )
if( separation != 0 )
VectorCopy( baseOrg, cg.refdef.vieworg );
+ // first person blend blobs, done after AnglesToAxis
+ if( !cg.renderingThirdPerson )
+ CG_PainBlend( );
+
// draw status bar and other floating elements
CG_Draw2D( );
}
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index f2d64601..b89c8e7c 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -905,7 +905,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
}
if( es->number == cg.clientNum )
+ {
+ CG_ResetPainBlend( );
cg.spawnTime = cg.time;
+ }
break;
case EV_ALIEN_EVOLVE_FAILED:
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index f1bc15d6..c42e1efa 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -1116,6 +1116,10 @@ typedef struct
qboolean consoleValid;
particleSystem_t *poisonCloudPS;
+
+ float painBlendValue;
+ float painBlendTarget;
+ int lastHealth;
} cg_t;
@@ -1467,6 +1471,11 @@ extern vmCvar_t cg_debugPVS;
extern vmCvar_t cg_disableWarningDialogs;
extern vmCvar_t cg_disableScannerPlane;
+extern vmCvar_t cg_painBlendUpRate;
+extern vmCvar_t cg_painBlendDownRate;
+extern vmCvar_t cg_painBlendMax;
+extern vmCvar_t cg_painBlendScale;
+
//TA: hack to get class an carriage through to UI module
extern vmCvar_t ui_currentClass;
extern vmCvar_t ui_carriage;
@@ -1573,6 +1582,7 @@ void CG_Text_PaintChar( float x, float y, float width, float height, floa
float s, float t, float s2, float t2, qhandle_t hShader );
void CG_DrawLoadingScreen( void );
void CG_UpdateMediaFraction( float newFract );
+void CG_ResetPainBlend( void );
//
// cg_players.c
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 98d2788d..ebc5c1e8 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -204,6 +204,11 @@ vmCvar_t cg_debugPVS;
vmCvar_t cg_disableWarningDialogs;
vmCvar_t cg_disableScannerPlane;
+vmCvar_t cg_painBlendUpRate;
+vmCvar_t cg_painBlendDownRate;
+vmCvar_t cg_painBlendMax;
+vmCvar_t cg_painBlendScale;
+
//TA: hack to get class and carriage through to UI module
vmCvar_t ui_currentClass;
vmCvar_t ui_carriage;
@@ -311,6 +316,11 @@ static cvarTable_t cvarTable[ ] =
{ &cg_disableScannerPlane, "cg_disableScannerPlane", "0", CVAR_ARCHIVE },
{ &cg_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE},
+ { &cg_painBlendUpRate, "cg_painBlendUpRate", "10.0", 0 },
+ { &cg_painBlendDownRate, "cg_painBlendDownRate", "1.0", 0 },
+ { &cg_painBlendMax, "cg_painBlendMax", "0.5", 0 },
+ { &cg_painBlendScale, "cg_painBlendScale", "7.0", 0 },
+
{ &ui_currentClass, "ui_currentClass", "0", 0 },
{ &ui_carriage, "ui_carriage", "", 0 },
{ &ui_stages, "ui_stages", "0 0", 0 },
diff --git a/src/cgame/cg_playerstate.c b/src/cgame/cg_playerstate.c
index 4837df9b..489b024d 100644
--- a/src/cgame/cg_playerstate.c
+++ b/src/cgame/cg_playerstate.c
@@ -141,6 +141,8 @@ void CG_Respawn( void )
// select the weapon the server says we are using
cg.weaponSelect = cg.snap->ps.weapon;
+
+ CG_ResetPainBlend( );
}
/*
@@ -271,6 +273,8 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops )
cg.thisFrameTeleport = qtrue;
// make sure we don't get any unwanted transition effects
*ops = *ps;
+
+ CG_ResetPainBlend( );
}
// damage events (player is getting wounded)
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index 5dc58e30..ec296c04 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -834,50 +834,6 @@ static int CG_CalcFov( void )
-/*
-===============
-CG_DamageBlendBlob
-
-===============
-*/
-static void CG_DamageBlendBlob( void )
-{
- int t;
- int maxTime;
- refEntity_t ent;
-
- if( !cg.damageValue )
- return;
-
- // ragePro systems can't fade blends, so don't obscure the screen
- if( cgs.glconfig.hardwareType == GLHW_RAGEPRO )
- return;
-
- maxTime = DAMAGE_TIME;
- t = cg.time - cg.damageTime;
-
- if( t <= 0 || t >= maxTime )
- return;
-
-
- memset( &ent, 0, sizeof( ent ) );
- ent.reType = RT_SPRITE;
- ent.renderfx = RF_FIRST_PERSON;
-
- VectorMA( cg.refdef.vieworg, 8, cg.refdef.viewaxis[ 0 ], ent.origin );
- VectorMA( ent.origin, cg.damageX * -8, cg.refdef.viewaxis[ 1 ], ent.origin );
- VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[ 2 ], ent.origin );
-
- ent.radius = cg.damageValue * 3;
- ent.customShader = cgs.media.viewBloodShader;
- ent.shaderRGBA[ 0 ] = 255;
- ent.shaderRGBA[ 1 ] = 255;
- ent.shaderRGBA[ 2 ] = 255;
- ent.shaderRGBA[ 3 ] = 200 * ( 1.0 - ( (float)t / maxTime) );
- trap_R_AddRefEntityToScene( &ent );
-}
-
-
#define NORMAL_HEIGHT 64.0f
#define NORMAL_WIDTH 6.0f
@@ -1301,10 +1257,6 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// build cg.refdef
inwater = CG_CalcViewValues( );
- // first person blend blobs, done after AnglesToAxis
- if( !cg.renderingThirdPerson )
- CG_DamageBlendBlob( );
-
// build the render lists
if( !cg.hyperspace )
{