- changed damage screen blending code so that the same version can be used by any renderer.

- added GZDoom's version of blending for Strife's hazard sectors as an option to the paletteflash CVAR.


SVN r3613 (trunk)
This commit is contained in:
Christoph Oelckers 2012-05-01 11:27:54 +00:00
parent 81b4f782f7
commit 75dc6cb0b2
10 changed files with 234 additions and 125 deletions

View file

@ -741,6 +741,7 @@ add_executable( zdoom WIN32
tables.cpp
teaminfo.cpp
tempfiles.cpp
v_blend.cpp
v_collection.cpp
v_draw.cpp
v_font.cpp

View file

@ -3,13 +3,6 @@
#include "d_player.h"
EXTERN_CVAR (Int, paletteflash)
enum PaletteFlashFlags
{
PF_HEXENWEAPONS = 1,
PF_SPECIALDAMAGE = 2,
};
class AHolySpirit : public AActor
{
DECLARE_CLASS (AHolySpirit, AActor)

View file

@ -18,6 +18,7 @@
#include "m_bbox.h"
#include "ravenshared.h"
#include "farchive.h"
#include "v_palette.h"
// Include all the Hexen stuff here to reduce compile time
#include "a_bats.cpp"

View file

@ -366,8 +366,6 @@ private:
void DrawMessages (int bottom);
void DrawConsistancy () const;
static BYTE DamageToAlpha[114];
TObjPtr<DHUDMessage> Messages;
bool ShowLog;
};

View file

@ -88,6 +88,9 @@ int BaseBlendR, BaseBlendG, BaseBlendB;
float BaseBlendA;
CVAR (Int, paletteflash, 0, CVAR_ARCHIVE)
CVAR (Flag, pf_hexenweaps, paletteflash, PF_HEXENWEAPONS)
CVAR (Flag, pf_specialdamage, paletteflash, PF_SPECIALDAMAGE)
CVAR (Flag, pf_hazard, paletteflash, PF_HAZARD)
// Stretch status bar to full screen width?
CUSTOM_CVAR (Bool, st_scale, true, CVAR_ARCHIVE)
@ -112,20 +115,6 @@ CUSTOM_CVAR(Int, am_showmaplabel, 2, CVAR_ARCHIVE)
CVAR (Bool, idmypos, false, 0);
// [RH] Amount of red flash for up to 114 damage points. Calculated by hand
// using a logarithmic scale and my trusty HP48G.
BYTE DBaseStatusBar::DamageToAlpha[114] =
{
0, 8, 16, 23, 30, 36, 42, 47, 53, 58, 62, 67, 71, 75, 79,
83, 87, 90, 94, 97, 100, 103, 107, 109, 112, 115, 118, 120, 123, 125,
128, 130, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157,
159, 160, 162, 164, 165, 167, 169, 170, 172, 173, 175, 176, 178, 179, 181,
182, 183, 185, 186, 187, 189, 190, 191, 192, 194, 195, 196, 197, 198, 200,
201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 216,
217, 218, 219, 220, 221, 221, 222, 223, 224, 225, 226, 227, 228, 229, 229,
230, 231, 232, 233, 234, 235, 235, 236, 237
};
//---------------------------------------------------------------------------
//
// Format the map name, include the map label if wanted
@ -1500,27 +1489,6 @@ void DBaseStatusBar::DrawPowerups ()
}
}
/*
=============
SV_AddBlend
[RH] This is from Q2.
=============
*/
void DBaseStatusBar::AddBlend (float r, float g, float b, float a, float v_blend[4])
{
float a2, a3;
if (a <= 0)
return;
a2 = v_blend[3] + (1-v_blend[3])*a; // new total alpha
a3 = v_blend[3]/a2; // fraction of color from old
v_blend[0] = v_blend[0]*a3 + r*(1-a3);
v_blend[1] = v_blend[1]*a3 + g*(1-a3);
v_blend[2] = v_blend[2]*a3 + b*(1-a3);
v_blend[3] = a2;
}
//---------------------------------------------------------------------------
//
// BlendView
@ -1529,90 +1497,13 @@ void DBaseStatusBar::AddBlend (float r, float g, float b, float a, float v_blend
void DBaseStatusBar::BlendView (float blend[4])
{
int cnt;
AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, BaseBlendA, blend);
// [RH] All powerups can affect the screen blending now
for (AInventory *item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
{
PalEntry color = item->GetBlend ();
if (color.a != 0)
{
AddBlend (color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f, blend);
}
}
if (CPlayer->bonuscount)
{
cnt = CPlayer->bonuscount << 3;
AddBlend (RPART(gameinfo.pickupcolor)/255.f, GPART(gameinfo.pickupcolor)/255.f,
BPART(gameinfo.pickupcolor)/255.f, cnt > 128 ? 0.5f : cnt / 255.f, blend);
}
PainFlashList * pfl = CPlayer->mo->GetClass()->ActorInfo->PainFlashes;
PalEntry painFlash = CPlayer->mo->DamageFade;
if (pfl)
{
PalEntry * color = pfl->CheckKey(CPlayer->mo->DamageTypeReceived);
if (color) painFlash = *color;
}
if (painFlash.a != 0)
{
cnt = DamageToAlpha[MIN (113, CPlayer->damagecount * painFlash.a / 255)];
if (cnt)
{
if (cnt > 228)
cnt = 228;
AddBlend (painFlash.r / 255.f, painFlash.g / 255.f, painFlash.b / 255.f, cnt / 255.f, blend);
}
}
// Unlike Doom, I did not have any utility source to look at to find the
// exact numbers to use here, so I've had to guess by looking at how they
// affect the white color in Hexen's palette and picking an alpha value
// that seems reasonable.
// [Gez] The exact values could be obtained by looking how they affect
// each color channel in Hexen's palette.
if (CPlayer->poisoncount)
{
cnt = MIN (CPlayer->poisoncount, 64);
if (paletteflash & PF_SPECIALDAMAGE)
{
AddBlend(44/255.f, 92/255.f, 36/255.f, ((cnt + 7) >> 3) * 0.1f, blend);
}
else
{
AddBlend (0.04f, 0.2571f, 0.f, cnt/93.2571428571f, blend);
}
}
if (CPlayer->hazardcount > 16*TICRATE || (CPlayer->hazardcount & 8))
{
AddBlend (0.f, 1.f, 0.f, 0.125f, blend);
}
if (CPlayer->mo->DamageType == NAME_Ice)
{
if (paletteflash & PF_SPECIALDAMAGE)
{
AddBlend(0.f, 0.f, 224/255.f, 0.5f, blend);
}
else
{
AddBlend (0.25f, 0.25f, 0.853f, 0.4f, blend);
}
}
V_AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, BaseBlendA, blend);
V_AddPlayerBlend(CPlayer, blend, 1.0f, 228);
if (screen->Accel2D || (CPlayer->camera != NULL && menuactive == MENU_Off && ConsoleState == c_up))
{
player_t *player = (CPlayer->camera != NULL && CPlayer->camera->player != NULL) ? CPlayer->camera->player : CPlayer;
AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
}
V_SetBlend ((int)(blend[0] * 255.0f), (int)(blend[1] * 255.0f),

View file

@ -2247,14 +2247,23 @@ void P_PlayerThink (player_t *player)
}
else if (!player->centering)
{
fixed_t oldpitch = player->mo->pitch;
player->mo->pitch -= look;
if (look > 0)
{ // look up
player->mo->pitch = MAX(player->mo->pitch, player->MinPitch);
if (player->mo->pitch > oldpitch)
{
player->mo->pitch = player->MinPitch;
}
}
else
{ // look down
player->mo->pitch = MIN(player->mo->pitch, player->MaxPitch);
if (player->mo->pitch < oldpitch)
{
player->mo->pitch = player->MaxPitch;
}
}
}
}

197
src/v_blend.cpp Normal file
View file

@ -0,0 +1,197 @@
/*
** v_blend.cpp
** Screen blending stuff
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include <assert.h>
#include "templates.h"
#include "sbar.h"
#include "c_cvars.h"
#include "c_dispatch.h"
#include "c_console.h"
#include "v_video.h"
#include "m_swap.h"
#include "w_wad.h"
#include "v_text.h"
#include "s_sound.h"
#include "gi.h"
#include "doomstat.h"
#include "g_level.h"
#include "d_net.h"
#include "colormatcher.h"
#include "v_palette.h"
#include "d_player.h"
#include "farchive.h"
#include "a_hexenglobal.h"
// [RH] Amount of red flash for up to 114 damage points. Calculated by hand
// using a logarithmic scale and my trusty HP48G.
static BYTE DamageToAlpha[114] =
{
0, 8, 16, 23, 30, 36, 42, 47, 53, 58, 62, 67, 71, 75, 79,
83, 87, 90, 94, 97, 100, 103, 107, 109, 112, 115, 118, 120, 123, 125,
128, 130, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157,
159, 160, 162, 164, 165, 167, 169, 170, 172, 173, 175, 176, 178, 179, 181,
182, 183, 185, 186, 187, 189, 190, 191, 192, 194, 195, 196, 197, 198, 200,
201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 216,
217, 218, 219, 220, 221, 221, 222, 223, 224, 225, 226, 227, 228, 229, 229,
230, 231, 232, 233, 234, 235, 235, 236, 237
};
/*
=============
SV_AddBlend
[RH] This is from Q2.
=============
*/
void V_AddBlend (float r, float g, float b, float a, float v_blend[4])
{
float a2, a3;
if (a <= 0)
return;
a2 = v_blend[3] + (1-v_blend[3])*a; // new total alpha
a3 = v_blend[3]/a2; // fraction of color from old
v_blend[0] = v_blend[0]*a3 + r*(1-a3);
v_blend[1] = v_blend[1]*a3 + g*(1-a3);
v_blend[2] = v_blend[2]*a3 + b*(1-a3);
v_blend[3] = a2;
}
//---------------------------------------------------------------------------
//
// BlendView
//
//---------------------------------------------------------------------------
void V_AddPlayerBlend (player_t *CPlayer, float blend[4], float maxinvalpha, int maxpainblend)
{
int cnt;
// [RH] All powerups can affect the screen blending now
for (AInventory *item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
{
PalEntry color = item->GetBlend ();
if (color.a != 0)
{
V_AddBlend (color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f, blend);
if (color.a/255.f > maxinvalpha) maxinvalpha = color.a/255.f;
}
}
if (CPlayer->bonuscount)
{
cnt = CPlayer->bonuscount << 3;
V_AddBlend (RPART(gameinfo.pickupcolor)/255.f, GPART(gameinfo.pickupcolor)/255.f,
BPART(gameinfo.pickupcolor)/255.f, cnt > 128 ? 0.5f : cnt / 255.f, blend);
}
PainFlashList * pfl = CPlayer->mo->GetClass()->ActorInfo->PainFlashes;
PalEntry painFlash = CPlayer->mo->DamageFade;
if (pfl)
{
PalEntry * color = pfl->CheckKey(CPlayer->mo->DamageTypeReceived);
if (color) painFlash = *color;
}
if (painFlash.a != 0)
{
cnt = DamageToAlpha[MIN (113, CPlayer->damagecount * painFlash.a / 255)];
if (cnt)
{
if (cnt > maxpainblend)
cnt = maxpainblend;
V_AddBlend (painFlash.r / 255.f, painFlash.g / 255.f, painFlash.b / 255.f, cnt / 255.f, blend);
}
}
// Unlike Doom, I did not have any utility source to look at to find the
// exact numbers to use here, so I've had to guess by looking at how they
// affect the white color in Hexen's palette and picking an alpha value
// that seems reasonable.
// [Gez] The exact values could be obtained by looking how they affect
// each color channel in Hexen's palette.
if (CPlayer->poisoncount)
{
cnt = MIN (CPlayer->poisoncount, 64);
if (paletteflash & PF_SPECIALDAMAGE)
{
V_AddBlend(44/255.f, 92/255.f, 36/255.f, ((cnt + 7) >> 3) * 0.1f, blend);
}
else
{
V_AddBlend (0.04f, 0.2571f, 0.f, cnt/93.2571428571f, blend);
}
}
if (CPlayer->hazardcount)
{
if (paletteflash & PF_HAZARD)
{
if (CPlayer->hazardcount > 16*TICRATE || (CPlayer->hazardcount & 8))
{
V_AddBlend (0.f, 1.f, 0.f, 0.125f, blend);
}
}
else
{
cnt= MIN(CPlayer->hazardcount/8, 64);
V_AddBlend (0.f, 0.2571f, 0.f, cnt/93.2571428571f, blend);
}
}
if (CPlayer->mo->DamageType == NAME_Ice)
{
if (paletteflash & PF_SPECIALDAMAGE)
{
V_AddBlend(0.f, 0.f, 224/255.f, 0.5f, blend);
}
else
{
V_AddBlend (0.25f, 0.25f, 0.853f, 0.4f, blend);
}
}
// cap opacity if desired
if (blend[3] > maxinvalpha) blend[3] = maxinvalpha;
}

View file

@ -35,6 +35,7 @@
#define __V_PALETTE_H__
#include "doomtype.h"
#include "c_cvars.h"
#define MAKERGB(r,g,b) DWORD(((r)<<16)|((g)<<8)|(b))
#define MAKEARGB(a,r,g,b) DWORD(((a)<<24)|((r)<<16)|((g)<<8)|(b))
@ -91,6 +92,20 @@ void V_SetBlend (int blendr, int blendg, int blendb, int blenda);
void V_ForceBlend (int blendr, int blendg, int blendb, int blenda);
EXTERN_CVAR (Int, paletteflash)
enum PaletteFlashFlags
{
PF_HEXENWEAPONS = 1,
PF_SPECIALDAMAGE = 2,
PF_HAZARD = 4,
};
class player_t;
void V_AddBlend (float r, float g, float b, float a, float v_blend[4]);
void V_AddPlayerBlend (player_t *CPlayer, float blend[4], float maxinvalpha, int maxpainblend);
// Colorspace conversion RGB <-> HSV
void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v);
void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v);

View file

@ -322,7 +322,7 @@ void DCanvas::Dim (PalEntry color)
if (color.a != 0)
{
float dim[4] = { color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f };
DBaseStatusBar::AddBlend (dimmer.r/255.f, dimmer.g/255.f, dimmer.b/255.f, amount, dim);
V_AddBlend (dimmer.r/255.f, dimmer.g/255.f, dimmer.b/255.f, amount, dim);
dimmer = PalEntry (BYTE(dim[0]*255), BYTE(dim[1]*255), BYTE(dim[2]*255));
amount = dim[3];
}

View file

@ -1032,6 +1032,10 @@
RelativePath=".\src\tempfiles.cpp"
>
</File>
<File
RelativePath=".\src\v_blend.cpp"
>
</File>
<File
RelativePath=".\src\v_collection.cpp"
>