1 /* Emacs style mode select   -*- C++ -*-
2  *-----------------------------------------------------------------------------
3  *
4  *
5  *  PrBoom: a Doom port merged with LxDoom and LSDLDoom
6  *  based on BOOM, a modified and improved DOOM engine
7  *  Copyright (C) 1999 by
8  *  id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9  *  Copyright (C) 1999-2000 by
10  *  Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
11  *  Copyright 2005, 2006 by
12  *  Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13  *
14  *  This program is free software; you can redistribute it and/or
15  *  modify it under the terms of the GNU General Public License
16  *  as published by the Free Software Foundation; either version 2
17  *  of the License, or (at your option) any later version.
18  *
19  *  This program is distributed in the hope that it will be useful,
20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *  GNU General Public License for more details.
23  *
24  *  You should have received a copy of the GNU General Public License
25  *  along with this program; if not, write to the Free Software
26  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27  *  02111-1307, USA.
28  *
29  * DESCRIPTION:
30  *      The status bar widget code.
31  *
32  *-----------------------------------------------------------------------------*/
33 
34 #include "doomdef.h"
35 #include "doomstat.h"
36 #include "v_video.h"
37 #include "w_wad.h"
38 #include "st_stuff.h"
39 #include "st_lib.h"
40 #include "r_main.h"
41 #include "lprintf.h"
42 
43 int sts_always_red;      //jff 2/18/98 control to disable status color changes
44 int sts_pct_always_gray; // killough 2/21/98: always gray %'s? bug or feature?
45 
46 //
47 // STlib_init()
48 //
STlib_init(void)49 void STlib_init(void)
50 {
51   // cph - no longer hold STMINUS pointer
52 }
53 
54 //
55 // STlib_initNum()
56 //
57 // Initializes an st_number_t widget
58 //
59 // Passed the widget, its position, the patches for the digits, a pointer
60 // to the value displayed, a pointer to the on/off control, and the width
61 // Returns nothing
62 //
STlib_initNum(st_number_t * n,int x,int y,const patchnum_t * pl,int * num,boolean * on,int width)63 void STlib_initNum
64 ( st_number_t* n,
65   int x,
66   int y,
67   const patchnum_t* pl,
68   int* num,
69   boolean* on,
70   int     width )
71 {
72   n->x  = x;
73   n->y  = y;
74   n->oldnum = 0;
75   n->width  = width;
76   n->num  = num;
77   n->on = on;
78   n->p  = pl;
79 }
80 
81 /*
82  * STlib_drawNum()
83  *
84  * A fairly efficient way to draw a number based on differences from the
85  * old number.
86  *
87  * Passed a st_number_t widget, a color range for output, and a flag
88  * indicating whether refresh is needed.
89  * Returns nothing
90  *
91  * jff 2/16/98 add color translation to digit output
92  * cphipps 10/99 - const pointer to colour trans table, made function static
93  */
STlib_drawNum(st_number_t * n,int cm,boolean refresh)94 static void STlib_drawNum
95 ( st_number_t*  n,
96   int cm,
97   boolean refresh )
98 {
99 
100   int   numdigits = n->width;
101   int   num = *n->num;
102 
103   int   w = n->p[0].width;
104   int   h = n->p[0].height;
105   int   x = n->x;
106 
107   int   neg;
108 
109   // leban 1/20/99:
110   // strange that somebody went through all the work to draw only the
111   // differences, and then went and constantly redrew all the numbers.
112   // return without drawing if the number didn't change and the bar
113   // isn't refreshing.
114   if(n->oldnum == num && !refresh)
115     return;
116 
117   // CPhipps - compact some code, use num instead of *n->num
118   if ((neg = (n->oldnum = num) < 0))
119   {
120     if (numdigits == 2 && num < -9)
121       num = -9;
122     else if (numdigits == 3 && num < -99)
123       num = -99;
124 
125     num = -num;
126   }
127 
128   // clear the area
129   x = n->x - numdigits*w;
130 
131 #ifdef RANGECHECK
132   if (n->y - ST_Y < 0)
133     I_Error("STlib_drawNum: n->y - ST_Y < 0");
134 #endif
135 
136   V_CopyRect(x, n->y - ST_Y, BG, w*numdigits, h, x, n->y, FG, VPT_STRETCH);
137 
138   // if non-number, do not draw it
139   if (num == 1994)
140     return;
141 
142   x = n->x;
143 
144   //jff 2/16/98 add color translation to digit output
145   // in the special case of 0, you draw 0
146   if (!num)
147     // CPhipps - patch drawing updated, reformatted
148     V_DrawNumPatch(x - w, n->y, FG, n->p[0].lumpnum, cm,
149        (((cm!=CR_DEFAULT) && !sts_always_red) ? VPT_TRANS : VPT_NONE) | VPT_STRETCH);
150 
151   // draw the new number
152   //jff 2/16/98 add color translation to digit output
153   while (num && numdigits--) {
154     // CPhipps - patch drawing updated, reformatted
155     x -= w;
156     V_DrawNumPatch(x, n->y, FG, n->p[num % 10].lumpnum, cm,
157        (((cm!=CR_DEFAULT) && !sts_always_red) ? VPT_TRANS : VPT_NONE) | VPT_STRETCH);
158     num /= 10;
159   }
160 
161   // draw a minus sign if necessary
162   //jff 2/16/98 add color translation to digit output
163   // cph - patch drawing updated, load by name instead of acquiring pointer earlier
164   if (neg)
165     V_DrawNamePatch(x - w, n->y, FG, "STTMINUS", cm,
166        (((cm!=CR_DEFAULT) && !sts_always_red) ? VPT_TRANS : VPT_NONE) | VPT_STRETCH);
167 }
168 
169 /*
170  * STlib_updateNum()
171  *
172  * Draws a number conditionally based on the widget's enable
173  *
174  * Passed a number widget, the output color range, and a refresh flag
175  * Returns nothing
176  *
177  * jff 2/16/98 add color translation to digit output
178  * cphipps 10/99 - make that pointer const
179  */
STlib_updateNum(st_number_t * n,int cm,boolean refresh)180 void STlib_updateNum
181 ( st_number_t*    n,
182   int cm,
183   boolean   refresh )
184 {
185   if (*n->on) STlib_drawNum(n, cm, refresh);
186 }
187 
188 //
189 // STlib_initPercent()
190 //
191 // Initialize a st_percent_t number with percent sign widget
192 //
193 // Passed a st_percent_t widget, the position, the digit patches, a pointer
194 // to the number to display, a pointer to the enable flag, and patch
195 // for the percent sign.
196 // Returns nothing.
197 //
STlib_initPercent(st_percent_t * p,int x,int y,const patchnum_t * pl,int * num,boolean * on,const patchnum_t * percent)198 void STlib_initPercent
199 ( st_percent_t* p,
200   int x,
201   int y,
202   const patchnum_t* pl,
203   int* num,
204   boolean* on,
205   const patchnum_t* percent )
206 {
207   STlib_initNum(&p->n, x, y, pl, num, on, 3);
208   p->p = percent;
209 }
210 
211 /*
212  * STlib_updatePercent()
213  *
214  * Draws a number/percent conditionally based on the widget's enable
215  *
216  * Passed a precent widget, the output color range, and a refresh flag
217  * Returns nothing
218  *
219  * jff 2/16/98 add color translation to digit output
220  * cphipps - const for pointer to the colour translation table
221  */
222 
STlib_updatePercent(st_percent_t * per,int cm,int refresh)223 void STlib_updatePercent
224 ( st_percent_t*   per,
225   int cm,
226   int refresh )
227 {
228   if (*per->n.on && (refresh || (per->n.oldnum != *per->n.num))) {
229     // killough 2/21/98: fix percents not updated;
230     /* CPhipps - make %'s only be updated if number changed */
231     // CPhipps - patch drawing updated
232     V_DrawNumPatch(per->n.x, per->n.y, FG, per->p->lumpnum,
233        sts_pct_always_gray ? CR_GRAY : cm,
234        (sts_always_red ? VPT_NONE : VPT_TRANS) | VPT_STRETCH);
235   }
236 
237   STlib_updateNum(&per->n, cm, refresh);
238 }
239 
240 //
241 // STlib_initMultIcon()
242 //
243 // Initialize a st_multicon_t widget, used for a multigraphic display
244 // like the status bar's keys.
245 //
246 // Passed a st_multicon_t widget, the position, the graphic patches, a pointer
247 // to the numbers representing what to display, and pointer to the enable flag
248 // Returns nothing.
249 //
STlib_initMultIcon(st_multicon_t * i,int x,int y,const patchnum_t * il,int * inum,boolean * on)250 void STlib_initMultIcon
251 ( st_multicon_t* i,
252   int x,
253   int y,
254   const patchnum_t* il,
255   int* inum,
256   boolean* on )
257 {
258   i->x  = x;
259   i->y  = y;
260   i->oldinum  = -1;
261   i->inum = inum;
262   i->on = on;
263   i->p  = il;
264 }
265 
266 //
267 // STlib_updateMultIcon()
268 //
269 // Draw a st_multicon_t widget, used for a multigraphic display
270 // like the status bar's keys. Displays each when the control
271 // numbers change or refresh is true
272 //
273 // Passed a st_multicon_t widget, and a refresh flag
274 // Returns nothing.
275 //
STlib_updateMultIcon(st_multicon_t * mi,boolean refresh)276 void STlib_updateMultIcon
277 ( st_multicon_t*  mi,
278   boolean   refresh )
279 {
280   int w;
281   int h;
282   int x;
283   int y;
284 
285   if (*mi->on && (mi->oldinum != *mi->inum || refresh))
286   {
287     if (mi->oldinum != -1)
288     {
289       x = mi->x - mi->p[mi->oldinum].leftoffset;
290       y = mi->y - mi->p[mi->oldinum].topoffset;
291       w = mi->p[mi->oldinum].width;
292       h = mi->p[mi->oldinum].height;
293 
294 #ifdef RANGECHECK
295       if (y - ST_Y < 0)
296         I_Error("STlib_updateMultIcon: y - ST_Y < 0");
297 #endif
298 
299       V_CopyRect(x, y-ST_Y, BG, w, h, x, y, FG, VPT_STRETCH);
300     }
301     if (*mi->inum != -1)  // killough 2/16/98: redraw only if != -1
302       V_DrawNumPatch(mi->x, mi->y, FG, mi->p[*mi->inum].lumpnum, CR_DEFAULT, VPT_STRETCH);
303     mi->oldinum = *mi->inum;
304   }
305 }
306 
307 //
308 // STlib_initBinIcon()
309 //
310 // Initialize a st_binicon_t widget, used for a multinumber display
311 // like the status bar's weapons, that are present or not.
312 //
313 // Passed a st_binicon_t widget, the position, the digit patches, a pointer
314 // to the flags representing what is displayed, and pointer to the enable flag
315 // Returns nothing.
316 //
STlib_initBinIcon(st_binicon_t * b,int x,int y,const patchnum_t * i,boolean * val,boolean * on)317 void STlib_initBinIcon
318 ( st_binicon_t* b,
319   int x,
320   int y,
321   const patchnum_t* i,
322   boolean* val,
323   boolean* on )
324 {
325   b->x  = x;
326   b->y  = y;
327   b->oldval = 0;
328   b->val  = val;
329   b->on = on;
330   b->p  = i;
331 }
332 
333 //
334 // STlib_updateBinIcon()
335 //
336 // DInitialize a st_binicon_t widget, used for a multinumber display
337 // like the status bar's weapons, that are present or not.
338 //
339 // Draw a st_binicon_t widget, used for a multinumber display
340 // like the status bar's weapons that are present or not. Displays each
341 // when the control flag changes or refresh is true
342 //
343 // Passed a st_binicon_t widget, and a refresh flag
344 // Returns nothing.
345 //
STlib_updateBinIcon(st_binicon_t * bi,boolean refresh)346 void STlib_updateBinIcon
347 ( st_binicon_t*   bi,
348   boolean   refresh )
349 {
350   int     x;
351   int     y;
352   int     w;
353   int     h;
354 
355   if (*bi->on && (bi->oldval != *bi->val || refresh))
356   {
357     x = bi->x - bi->p->leftoffset;
358     y = bi->y - bi->p->topoffset;
359     w = bi->p->width;
360     h = bi->p->height;
361 
362 #ifdef RANGECHECK
363     if (y - ST_Y < 0)
364       I_Error("STlib_updateBinIcon: y - ST_Y < 0");
365 #endif
366 
367     if (*bi->val)
368       V_DrawNumPatch(bi->x, bi->y, FG, bi->p->lumpnum, CR_DEFAULT, VPT_STRETCH);
369     else
370       V_CopyRect(x, y-ST_Y, BG, w, h, x, y, FG, VPT_STRETCH);
371 
372     bi->oldval = *bi->val;
373   }
374 }
375