1 /** @file h_special.cpp Special color effects for the game view.
2 *
3 * @authors Copyright (c) 2018 Jaakko Keränen <jaakko.keranen@iki.fi>
4 *
5 * @par License
6 * GPL: http://www.gnu.org/licenses/gpl.html
7 *
8 * <small>This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. This program is distributed in the hope that it
12 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details. You should have received a copy of the GNU
15 * General Public License along with this program; if not, see:
16 * http://www.gnu.org/licenses</small>
17 */
18
19 #include "r_special.h"
20 #include "common.h"
21
22 static float appliedFilter[MAXPLAYERS];
23
24 #if defined(__JHERETIC__)
25 static byte ringShader = 0;
26 #endif
27
R_SpecialFilterRegister()28 void R_SpecialFilterRegister()
29 {
30 #if defined(__JHERETIC__)
31 C_VAR_BYTE("rend-ring-effect", &ringShader, 0, 0, 1);
32 #endif
33 R_InitSpecialFilter();
34 }
35
R_InitSpecialFilter()36 void R_InitSpecialFilter()
37 {
38 for(int i = 0; i < MAXPLAYERS; ++i)
39 {
40 appliedFilter[i] = -1;
41 }
42 }
43
R_ClearSpecialFilter(int player,float fadeDuration)44 void R_ClearSpecialFilter(int player, float fadeDuration)
45 {
46 if (appliedFilter[player] > 0)
47 {
48 DD_Executef(true, "postfx %i opacity 1; postfx %i none %f", player, player, fadeDuration);
49 appliedFilter[player] = -1;
50 }
51 }
52
R_UpdateSpecialFilterWithTimeDelta(int player,float delta)53 void R_UpdateSpecialFilterWithTimeDelta(int player, float delta)
54 {
55 const player_t *plr = players + player;
56 const char * fxName = "none";
57 float intensity = 1.f;
58
59 #if defined(__JDOOM__)
60 {
61 // In HacX a simple blue shift is used instead.
62 if (gameMode == doom2_hacx) return;
63
64 fxName = "monochrome.inverted";
65
66 int filter = plr->powers[PT_INVULNERABILITY];
67 if (!filter)
68 {
69 // Clear the filter.
70 R_ClearSpecialFilter(player, delta);
71 return;
72 }
73 if (filter < 4 * 32 && !(filter & 8))
74 {
75 intensity = 0;
76 }
77 }
78 #endif
79
80 #if defined(__JHERETIC__)
81 {
82 delta = 0; // not animated
83 fxName = (ringShader == 0 ? "colorize.gold" : "colorize.inverted.gold");
84
85 const int filter = plr->powers[PT_INVULNERABILITY];
86 if (!filter)
87 {
88 // Clear the filter.
89 R_ClearSpecialFilter(player, delta);
90 return;
91 }
92 if (filter <= BLINKTHRESHOLD && !(filter & 8))
93 {
94 intensity = 0;
95 }
96 }
97 #endif
98
99 if (gfw_CurrentGame() == GFW_HEXEN || gfw_CurrentGame() == GFW_DOOM64)
100 {
101 R_ClearSpecialFilter(player, delta);
102 return;
103 }
104
105 // Activate the filter; load the shader if the effect was previously not in use.
106 if (appliedFilter[player] < 0)
107 {
108 DD_Executef(true, "postfx %i %s %f", player, fxName, delta);
109 }
110
111 // Update filter opacity.
112 if (!FEQUAL(appliedFilter[player], intensity))
113 {
114 DD_Executef(true, "postfx %i opacity %f", player, intensity);
115 appliedFilter[player] = intensity;
116 }
117 }
118
R_UpdateSpecialFilter(int player)119 void R_UpdateSpecialFilter(int player)
120 {
121 R_UpdateSpecialFilterWithTimeDelta(player, .3f);
122 }
123