1 /** @file healthwidget.cpp  GUI widget for -.
2  *
3  * @authors Copyright © 2005-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  * @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net>
5  *
6  * @par License
7  * GPL: http://www.gnu.org/licenses/gpl.html
8  *
9  * <small>This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by the
11  * Free Software Foundation; either version 2 of the License, or (at your
12  * option) any later version. This program is distributed in the hope that it
13  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details. You should have received a copy of the GNU
16  * General Public License along with this program; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA</small>
19  */
20 
21 #include "hud/widgets/healthwidget.h"
22 
23 #include "g_common.h"
24 #if __JHERETIC__ || __JHEXEN__
25 #  include "hu_inventory.h"
26 #endif
27 #include "player.h"
28 #include "p_actor.h"
29 
30 using namespace de;
31 
guidata_health_t(void (* updateGeometry)(HudWidget * wi),void (* drawer)(HudWidget * wi,Point2Raw const * offset),dint player)32 guidata_health_t::guidata_health_t(void (*updateGeometry) (HudWidget *wi),
33                                    void (*drawer) (HudWidget *wi, Point2Raw const *offset),
34                                    dint player)
35     : HudWidget(updateGeometry,
36                 drawer,
37                 player)
38 {}
39 
~guidata_health_t()40 guidata_health_t::~guidata_health_t()
41 {}
42 
reset()43 void guidata_health_t::reset()
44 {
45     _value = 1994;
46 }
47 
tick(timespan_t)48 void guidata_health_t::tick(timespan_t /*elapsed*/)
49 {
50     if(Pause_IsPaused() || !DD_IsSharpTick()) return;
51 
52     player_t const *plr = &::players[player()];
53     _value = plr->health;
54 }
55 
HealthWidget_Draw(guidata_health_t * hlth,Point2Raw const * offset)56 void HealthWidget_Draw(guidata_health_t *hlth, Point2Raw const *offset)
57 {
58 #if __JDOOM__
59 #  define X_OFFSET              ( 0 )
60 #  define Y_OFFSET              ( 0 )
61 #  define TRACKING              ( 0 )
62 #  define SUFFIX                ( "%" )
63 #else
64 #  define X_OFFSET              (-1 )
65 #  define Y_OFFSET              (-1 )
66 #  define TRACKING              ( 1 )
67 #  define SUFFIX                ( "" )
68 #endif
69 
70     DENG2_ASSERT(hlth);
71     dfloat const textOpacity = ::uiRendState->pageAlpha * ::cfg.common.hudColor[3];
72 
73     if(hlth->_value == 1994) return;
74 
75     if(!::cfg.hudShown[HUD_HEALTH]) return;
76     if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
77     if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
78 
79     auto const valueAsText = String::number(hlth->_value) + SUFFIX;
80 
81     DGL_MatrixMode(DGL_MODELVIEW);
82     DGL_PushMatrix();
83     if(offset) DGL_Translatef(offset->x, offset->y, 0);
84     DGL_Scalef(::cfg.common.hudScale, ::cfg.common.hudScale, 1);
85 
86     DGL_Enable(DGL_TEXTURE_2D);
87 
88     FR_SetFont(hlth->font());
89     FR_SetTracking(TRACKING);
90 
91 #if __JHERETIC__
92     // Draw a shadow.
93     FR_SetColorAndAlpha(0, 0, 0, textOpacity * .4f);
94     FR_DrawTextXY(valueAsText.toUtf8().constData(), X_OFFSET + 2, Y_OFFSET + 2);
95 #endif
96 
97     FR_SetColorAndAlpha(::cfg.common.hudColor[0], ::cfg.common.hudColor[1], ::cfg.common.hudColor[2], textOpacity);
98     FR_DrawTextXY(valueAsText.toUtf8().constData(), X_OFFSET, Y_OFFSET);
99 
100     DGL_Disable(DGL_TEXTURE_2D);
101     DGL_MatrixMode(DGL_MODELVIEW);
102     DGL_PopMatrix();
103 
104 #undef SUFFIX
105 #undef TRACKING
106 #undef Y_OFFSET
107 #undef X_OFFSET
108 }
109 
SBarHealthWidget_Draw(guidata_health_t * hlth,Point2Raw const * offset)110 void SBarHealthWidget_Draw(guidata_health_t *hlth, Point2Raw const *offset)
111 {
112 #if __JDOOM__
113 #  define X_OFFSET              ( 90 )
114 #  define Y_OFFSET              (  3 )
115 #elif __JHERETIC__
116 #  define X_OFFSET              ( 85 )
117 #  define Y_OFFSET              ( 12 )
118 #elif __JHEXEN__
119 #  define X_OFFSET              ( 64 )
120 #  define Y_OFFSET              ( 14 )
121 #else
122 #  define X_OFFSET              (  0 )
123 #  define Y_OFFSET              (  0 )
124 #endif
125 #if __JHERETIC__
126 #  define TRACKING              ( 1 )
127 #else
128 #  define TRACKING              ( 0 )
129 #endif
130     DENG2_ASSERT(hlth);
131 
132     Vector2i const origin((-ST_WIDTH / 2 ) + X_OFFSET, (-ST_HEIGHT ) + Y_OFFSET );
133 
134     if(hlth->_value == 1994) return;
135 
136     dint const activeHud     = ST_ActiveHud(hlth->player());
137     dint const yOffset       = ST_HEIGHT * (1 - ST_StatusBarShown(hlth->player()));
138     dfloat const textOpacity = (activeHud == 0? 1 : ::uiRendState->pageAlpha * ::cfg.common.statusbarCounterAlpha);
139     //dfloat const iconOpacity = (activeHud == 0? 1 : ::uiRendState->pageAlpha * ::cfg.common.statusbarCounterAlpha);
140 
141 #if __JHERETIC__ || __JHEXEN__
142     if(gfw_Rule(deathmatch)) return;
143     if(Hu_InventoryIsOpen(hlth->player())) return;
144 #endif
145 
146 #if __JHEXEN__
147     if(ST_AutomapIsOpen(hlth->player())) return;
148 #else
149     if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
150 #endif
151     if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
152 
153     auto const valueAsText = String::number(hlth->_value);
154 
155     DGL_MatrixMode(DGL_MODELVIEW);
156     DGL_PushMatrix();
157     if(offset) DGL_Translatef(offset->x, offset->y, 0);
158     DGL_Scalef(::cfg.common.statusbarScale, ::cfg.common.statusbarScale, 1);
159     DGL_Translatef(0, yOffset, 0);
160 
161     DGL_Enable(DGL_TEXTURE_2D);
162 
163     FR_SetFont(hlth->font());
164     FR_SetTracking(TRACKING);
165 #if __JDOOM__
166     if(::gameMode == doom_chex)
167     {
168         FR_SetColorAndAlpha(::defFontRGB3[0], ::defFontRGB3[1], ::defFontRGB3[2], textOpacity);
169     }
170     else
171 #endif
172     {
173         FR_SetColorAndAlpha(::defFontRGB2[0], ::defFontRGB2[1], ::defFontRGB2[2], textOpacity);
174     }
175     FR_DrawTextXY3(valueAsText.toUtf8().constData(), origin.x, origin.y, ALIGN_TOPRIGHT, DTF_NO_EFFECTS);
176 #if __JDOOM__
177     FR_DrawCharXY('%', origin.x, origin.y);
178 #endif
179 
180     DGL_Disable(DGL_TEXTURE_2D);
181     DGL_MatrixMode(DGL_MODELVIEW);
182     DGL_PopMatrix();
183 
184 #undef TRACKING
185 #undef Y_OFFSET
186 #undef X_OFFSET
187 }
188 
HealthWidget_UpdateGeometry(guidata_health_t * hlth)189 void HealthWidget_UpdateGeometry(guidata_health_t *hlth)
190 {
191 #if __JDOOM__
192 #  define TRACKING              ( 0 )
193 #  define SUFFIX                ( "%" )
194 #else
195 #  define TRACKING              ( 1 )
196 #  define SUFFIX                ( "" )
197 #endif
198 
199     DENG2_ASSERT(hlth);
200     Rect_SetWidthHeight(&hlth->geometry(), 0, 0);
201 
202     if(hlth->_value == 1994) return;
203 
204     if(!::cfg.hudShown[HUD_HEALTH]) return;
205     if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
206     if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
207 
208     auto const valueAsText = String::number(hlth->_value) + SUFFIX;
209 
210     FR_SetFont(hlth->font());
211     FR_SetTracking(TRACKING);
212     Size2Raw textSize; FR_TextSize(&textSize, valueAsText.toUtf8().constData());
213     textSize.width  *= ::cfg.common.hudScale;
214     textSize.height *= ::cfg.common.hudScale;
215     Rect_SetWidthHeight(&hlth->geometry(), textSize.width, textSize.height);
216 
217 #undef SUFFIX
218 #undef TRACKING
219 }
220 
SBarHealthWidget_UpdateGeometry(guidata_health_t * hlth)221 void SBarHealthWidget_UpdateGeometry(guidata_health_t *hlth)
222 {
223 #if __JHERETIC__
224 #  define TRACKING              ( 1 )
225 #else
226 #  define TRACKING              ( 0 )
227 #endif
228 
229     DENG2_ASSERT(hlth);
230     Rect_SetWidthHeight(&hlth->geometry(), 0, 0);
231 
232     if(hlth->_value == 1994) return;
233 
234 #if __JHERETIC__ || __JHEXEN__
235     if(gfw_Rule(deathmatch)) return;
236     if(Hu_InventoryIsOpen(hlth->player())) return;
237 #endif
238 
239 #if __JHEXEN__
240     if(ST_AutomapIsOpen(hlth->player())) return;
241 #else
242     if(ST_AutomapIsOpen(hlth->player()) && ::cfg.common.automapHudDisplay == 0) return;
243 #endif
244     if(P_MobjIsCamera(::players[hlth->player()].plr->mo) && Get(DD_PLAYBACK)) return;
245 
246     auto const valueAsText = String::number(hlth->_value);
247 
248     FR_SetFont(hlth->font());
249     FR_SetTracking(TRACKING);
250     Size2Raw textSize; FR_TextSize(&textSize, valueAsText.toUtf8().constData());
251 #if __JDOOM__
252     textSize.width += FR_CharWidth('%');
253     textSize.height = de::max(textSize.height, FR_CharHeight('%'));
254 #endif
255     Rect_SetWidthHeight(&hlth->geometry(), textSize.width  * ::cfg.common.statusbarScale,
256                                            textSize.height * ::cfg.common.statusbarScale);
257 
258 #undef TRACKING
259 }
260