1 /* dashboard.c - graphic tstatw - 6/2/93
2  *
3  * Copyright (C) 1993, Lars Bernhardsson (lab@mtek.chalmers.se)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * Color by Nick Trown.
28  *
29  */
30 
31 #include "config.h"
32 #include "copyright.h"
33 
34 #include <stdio.h>
35 #include "Wlib.h"
36 #include "defs.h"
37 #include "struct.h"
38 #include "data.h"
39 
40 #include "string_util.h"
41 
42 #define DB_NOFILL 0
43 #define DB_LINE 1
44 #define DB_FILL 2
45 
46 #define DB_3DIGITS 0
47 #define DB_5DIGITS 1
48 
49 #define BAR_LENGTH 56
50 
51 extern void db_redraw_lab2(int fr);
52 
53 void
db_box(int x,int y,int w,int h,int f,int color)54         db_box(int x, int y, int w, int h, int f, int color)
55 {
56   int     border = W_White;
57 
58   if (color == W_Red)
59     border = color;
60 
61   if (w == 0 || h == 0)
62     return;
63 
64   switch (f)
65     {
66     case DB_FILL:
67       W_FillArea(tstatw, x, y, w + 1, h + 1, color);
68       break;
69     case DB_LINE:
70       W_MakeLine(tstatw, x + w, y, x + w, y + h, border);
71       W_MakeLine(tstatw, x + w, y + 4, x + BAR_LENGTH, y + 4, border);
72       break;
73     case DB_NOFILL:
74       W_MakeLine(tstatw, x, y, x + w, y, border);
75       W_MakeLine(tstatw, x + w, y, x + w, y + h, border);
76       W_MakeLine(tstatw, x + w, y + h, x, y + h, border);
77       W_MakeLine(tstatw, x, y + h, x, y, border);
78       break;
79     }
80 }
81 
82 void
db_bar(char * lab,int x,int y,int value,int tmpmax,int max,int digits,int color)83         db_bar(char *lab, int x, int y, int value, int tmpmax, int max, int digits, int color)
84 {
85   register int wt, wv, tw, tc;
86   char    valstr[32];
87 
88   switch (digits)
89     {
90     case DB_3DIGITS:
91       tc = 11;
92       tw = W_Textwidth * tc;
93       valstr[0] = lab[0];
94       valstr[1] = lab[1];
95       valstr[2] = '[';
96       itoapad(value, &(valstr[3]), 0, 3);
97       valstr[6] = '/';
98       itoapad(tmpmax, &(valstr[7]), 0, 3);
99       valstr[10] = ']';
100       W_ClearArea(tstatw, x, y, tw + BAR_LENGTH, 10);
101       break;
102     case DB_5DIGITS:
103       tc = 15;
104       tw = W_Textwidth * tc;
105       valstr[0] = lab[0];
106       valstr[1] = lab[1];
107       valstr[2] = '[';
108       itoapad(value, &(valstr[3]), 0, 5);
109       valstr[8] = '/';
110       itoapad(tmpmax, &(valstr[9]), 0, 5);
111       valstr[14] = ']';
112       W_ClearArea(tstatw, x, y, tw + BAR_LENGTH, 10);
113       break;
114     }
115 
116   wt = (int) ((float) BAR_LENGTH * ((float) tmpmax / (float) max));
117   wv = (int) ((float) BAR_LENGTH * ((float) value / (float) max));
118   if (wt > BAR_LENGTH)
119     wt = BAR_LENGTH;
120   if (wv > BAR_LENGTH)
121     wv = BAR_LENGTH;
122 
123   W_WriteText(tstatw, x, y, textColor, valstr, 3, W_RegularFont);
124   W_WriteText(tstatw, x + 3 * W_Textwidth, y, textColor, (&valstr[3]), tc / 2 + 1, W_BoldFont);
125   W_WriteText(tstatw, x + (tc / 2 + 1) * W_Textwidth, y, textColor, (&valstr[tc / 2 + 1]), tc / 2, W_RegularFont);
126 
127   db_box(x + tw, y, BAR_LENGTH, 9, DB_NOFILL, color);
128   if (wt >= wv && wt > 0)
129     db_box(x + tw, y, wt, 9, DB_LINE, color);
130 
131   if (wv > 0)
132     db_box(x + tw, y, wv, 9, DB_FILL, color);
133 }
134 
135 void
db_flags(int fr)136         db_flags(int fr)
137 {
138   static float old_kills = -1.0;
139   static int old_torp = -1;
140   static unsigned int old_flags = -1;
141   static int old_tourn = -1;
142   char    buf[16];
143   struct player *plr;
144 
145   if ((me->p_flags & (PFPLOCK | PFOBSERV)) == (PFPLOCK | PFOBSERV))
146     plr = players + me->p_playerl;
147   else
148     plr = me;
149 
150   if (fr || me->p_flags != old_flags)
151     {
152       buf[0] = (me->p_flags & PFSHIELD ? 'S' : ' ');
153       if (me->p_flags & PFGREEN)
154 	buf[1] = 'G';
155       else if (me->p_flags & PFYELLOW)
156 	buf[1] = 'Y';
157       else
158 	buf[1] = 'R';
159       buf[2] = (me->p_flags & (PFPLLOCK | PFPLOCK) ? 'L' : ' ');
160       buf[3] = (me->p_flags & PFREPAIR ? 'R' : ' ');
161       buf[4] = (me->p_flags & PFBOMB ? 'B' : ' ');
162       buf[5] = (me->p_flags & PFORBIT ? 'O' : ' ');
163       if (me->p_ship.s_type == STARBASE)
164 	buf[6] = (me->p_flags & PFDOCKOK ? 'D' : ' ');
165       else
166 	buf[6] = (me->p_flags & PFDOCK ? 'D' : ' ');
167       buf[7] = (me->p_flags & PFCLOAK ? 'C' : ' ');
168       buf[8] = (me->p_flags & PFWEP ? 'W' : ' ');
169       buf[9] = (me->p_flags & PFENG ? 'E' : ' ');
170       if (me->p_flags & PFPRESS)
171 	buf[10] = 'P';
172       else if (me->p_flags & PFTRACT)
173 	buf[10] = 'T';
174       else
175 	buf[10] = ' ';
176       if (me->p_flags & PFBEAMUP)
177 	buf[11] = 'u';
178       else if (me->p_flags & PFBEAMDOWN)
179 	buf[11] = 'd';
180       else
181 	buf[11] = ' ';
182 
183       W_WriteText(tstatw, 2, 3, textColor, "Flags", 5, W_RegularFont);
184       W_WriteText(tstatw, 2, 17, textColor, buf, 12, W_RegularFont);
185       old_flags = me->p_flags;
186     }
187 
188   if (fr || status->tourn != old_tourn)
189     {
190       if (status->tourn)
191 	W_WriteText(tstatw, 74, 17, textColor, "T", 1, W_BoldFont);
192       else
193 	W_WriteText(tstatw, 74, 17, textColor, " ", 1, W_BoldFont);
194 
195       old_tourn = status->tourn;
196     }
197 
198   if (fr || plr->p_kills != old_kills)
199     {
200       if (plr->p_kills > 0.0)
201 	{
202 	  W_WriteText(tstatw, 346, 17, textColor, "Kills:", 6, W_RegularFont);
203 	  ftoa(plr->p_kills, buf, 0, 3, 2);
204 	  W_WriteText(tstatw, 386, 17, textColor, buf, strlen(buf), W_RegularFont);
205 	}
206       else
207 	{
208 	  W_ClearArea(tstatw, 346, 17, 96, 10);
209 	}
210       old_kills = plr->p_kills;
211     }
212 
213   if (fr || plr->p_ntorp != old_torp)
214     {
215       if (plr->p_ntorp > 0)
216 	{
217 	  W_WriteText(tstatw, 346, 30, textColor, "Torps:", 6, W_RegularFont);
218 	  buf[0] = plr->p_ntorp % 10 + '0';
219 	  W_WriteText(tstatw, 386, 30, textColor, buf, 1, W_RegularFont);
220 	}
221       else
222 	{
223 	  W_ClearArea(tstatw, 346, 30, 96, 10);
224 	}
225       old_torp = plr->p_ntorp;
226     }
227 }
228 
229 
230 void
db_redraw_krp(int fr)231         db_redraw_krp(int fr)
232 {
233   static int old_spd = -1, old_cur_spd = -1;
234   static int old_shl = -1, old_dam = -1;
235   static int old_arm = -1, old_cur_arm = -1;
236   static int old_wpn = -1, old_egn = -1;
237   static int old_ful = -1;
238   register int cur_max;
239   register int value;
240   int     color;
241   float   kills;
242 
243   if ((me->p_flags & (PFPLOCK | PFOBSERV)) == (PFPLOCK | PFOBSERV))
244     kills = players[me->p_playerl].p_kills;
245   else
246     kills = me->p_kills;
247 
248   if (fr)
249     W_ClearWindow(tstatw);
250 
251   db_flags(fr);
252 
253   cur_max = (me->p_ship.s_maxspeed + 2) - (me->p_ship.s_maxspeed + 1) *
254       ((float) me->p_damage / (float) (me->p_ship.s_maxdamage));
255   if (cur_max > me->p_ship.s_maxspeed)
256     cur_max = me->p_ship.s_maxspeed;
257   if (cur_max < 0)
258     cur_max = 0;
259 
260   if (fr || me->p_speed != old_spd || cur_max != old_cur_spd)
261     {
262       if (me->p_speed >= me->p_ship.s_maxspeed - 2)
263 	color = W_Red;
264       else
265 	color = W_Green;
266       db_bar("Sp", 90, 3,
267 	     me->p_speed, cur_max, me->p_ship.s_maxspeed, DB_3DIGITS, color);
268       old_spd = me->p_speed;
269       old_cur_spd = cur_max;
270     }
271 
272   if (fr || me->p_shield != old_shl)
273     {
274       value = (100 * me->p_shield) / me->p_ship.s_maxshield;
275       if (value <= 16)
276 	color = W_Red;
277       else if (value <= 66)
278 	color = W_Yellow;
279       else
280 	color = W_Green;
281       db_bar("Sh", 90, 17,
282 	     me->p_shield, me->p_ship.s_maxshield, me->p_ship.s_maxshield,
283 	     DB_3DIGITS, color);
284       old_shl = me->p_shield;
285     }
286 
287   if (fr || me->p_damage != old_dam)
288     {
289       value = (100 * (me->p_ship.s_maxdamage - me->p_damage)) / me->p_ship.s_maxdamage;
290       if (value <= 16)
291 	color = W_Red;
292       else if (value <= 66)
293 	color = W_Yellow;
294       else
295 	color = W_Green;
296       db_bar("Hu", 90, 31,
297 	     (me->p_ship.s_maxdamage - me->p_damage),
298 	     me->p_ship.s_maxdamage, me->p_ship.s_maxdamage,
299 	     DB_3DIGITS, color);
300       old_dam = me->p_damage;
301     }
302 
303   if (me->p_ship.s_type == ASSAULT)
304     cur_max = (((kills * 3) > me->p_ship.s_maxarmies) ?
305 	       me->p_ship.s_maxarmies : (int) (kills * 3));
306   else if (me->p_ship.s_type == STARBASE)
307     cur_max = me->p_ship.s_maxarmies;
308   else
309     cur_max = (((kills * 2) > me->p_ship.s_maxarmies) ?
310 	       me->p_ship.s_maxarmies : (int) (kills * 2));
311 
312   if (fr || me->p_armies != old_arm || cur_max != old_cur_arm)
313     {
314       value = me->p_armies;
315 
316       if (value <= 0)
317 	color = W_Green;
318       else
319 	color = W_Red;
320 
321       db_bar("Ar", 218, 3,
322 	  me->p_armies, cur_max, me->p_ship.s_maxarmies, DB_3DIGITS, color);
323       old_arm = me->p_armies;
324       old_cur_arm = cur_max;
325     }
326 
327   if (fr || me->p_wtemp != old_wpn)
328     {
329       value = (100 * me->p_wtemp) / me->p_ship.s_maxwpntemp;
330 
331       if (value <= 16)
332 	color = W_Green;
333       else if (value <= 66)
334 	color = W_Yellow;
335       else
336 	color = W_Red;
337       db_bar("Wt", 218, 17,
338 	     me->p_wtemp / 10, me->p_ship.s_maxwpntemp / 10, me->p_ship.s_maxwpntemp / 10, DB_3DIGITS
339 	     ,color);
340       old_wpn = me->p_wtemp;
341     }
342 
343   if (fr || me->p_etemp != old_egn)
344     {
345       value = (100 * me->p_etemp) / me->p_ship.s_maxegntemp;
346       if (value <= 16)
347 	color = W_Green;
348       else if (value <= 66)
349 	color = W_Yellow;
350       else
351 	color = W_Red;
352       db_bar("Et", 218, 31,
353 	     me->p_etemp / 10, me->p_ship.s_maxegntemp / 10, me->p_ship.s_maxegntemp / 10, DB_3DIGITS
354 	     ,color);
355       old_egn = me->p_etemp;
356     }
357 
358   if (fr || me->p_fuel != old_ful)
359     {
360       value = ((100 * me->p_fuel) / me->p_ship.s_maxfuel);
361       if (value <= 16)
362 	color = W_Red;
363       else if (value <= 66)
364 	color = W_Yellow;
365       else
366 	color = W_Green;
367       db_bar("Fu", 346, 3,
368 	     me->p_fuel, me->p_ship.s_maxfuel, me->p_ship.s_maxfuel, DB_5DIGITS, color);
369       old_ful = me->p_fuel;
370     }
371 }
372 
373 
db_redraw_COW(int fr)374 void    db_redraw_COW(int fr)
375 {
376   static int old_spd = -1, old_cur_spd = -1;
377   static int old_shl = -1, old_dam = -1;
378   static int old_arm = -1, old_cur_arm = -1;
379   static int old_wpn = -1, old_egn = -1;
380   static int old_ful = -1;
381   register int cur_max;
382   register int value;
383   int     color;
384   float   kills;
385 
386   if ((me->p_flags & (PFPLOCK | PFOBSERV)) == (PFPLOCK | PFOBSERV))
387     kills = players[me->p_playerl].p_kills;
388   else
389     kills = me->p_kills;
390 
391 
392   if (fr)
393     W_ClearWindow(tstatw);
394 
395   db_flags(fr);
396 
397   cur_max = (me->p_ship.s_maxspeed + 2) - (me->p_ship.s_maxspeed + 1) *
398       ((float) me->p_damage / (float) (me->p_ship.s_maxdamage));
399   if (cur_max > me->p_ship.s_maxspeed)
400     cur_max = me->p_ship.s_maxspeed;
401   if (cur_max < 0)
402     cur_max = 0;
403 
404   if (fr || me->p_speed != old_spd || cur_max != old_cur_spd)
405     {
406       if (me->p_speed >= me->p_ship.s_maxspeed - 2)
407 	color = W_Yellow;
408       else
409 	color = W_White;
410       db_bar("Sp", 90, 3,
411 	     me->p_speed, cur_max, me->p_ship.s_maxspeed, DB_3DIGITS, color);
412       old_spd = me->p_speed;
413       old_cur_spd = cur_max;
414     }
415 
416   if (fr || me->p_shield != old_shl)
417     {
418       value = (100 * me->p_shield) / me->p_ship.s_maxshield;
419       if (value <= 50)
420 	color = W_Red;
421       else if (value < 90)
422 	color = W_Yellow;
423       else
424 	color = W_White;
425       db_bar("Sh", 90, 17,
426 	     me->p_ship.s_maxshield - me->p_shield, me->p_ship.s_maxshield, me->p_ship.s_maxshield, DB_3DIGITS, color);
427       old_shl = me->p_shield;
428     }
429 
430   if (fr || me->p_damage != old_dam)
431     {
432       value = (100 * me->p_damage) / me->p_ship.s_maxdamage;
433       if (value <= 10)
434 	color = W_White;
435       else if (value > 50)
436 	color = W_Red;
437       else
438 	color = W_Yellow;
439       db_bar("Da", 90, 31,
440 	     me->p_damage, me->p_ship.s_maxdamage, me->p_ship.s_maxdamage, DB_3DIGITS, color);
441       old_dam = me->p_damage;
442     }
443 
444   if (me->p_ship.s_type == ASSAULT)
445     cur_max = (((kills * 3) > me->p_ship.s_maxarmies) ?
446 	       me->p_ship.s_maxarmies : (int) (kills * 3));
447   else if (me->p_ship.s_type == STARBASE)
448     cur_max = me->p_ship.s_maxarmies;
449   else
450     cur_max = (((kills * 2) > me->p_ship.s_maxarmies) ?
451 	       me->p_ship.s_maxarmies : (int) (kills * 2));
452 
453   if (fr || me->p_armies != old_arm || cur_max != old_cur_arm)
454     {
455       value = me->p_armies;
456 
457       if (value <= 3)
458 	color = W_White;
459       else if (value > 5)
460 	color = W_Red;
461       else
462 	color = W_Yellow;
463       db_bar("Ar", 218, 3,
464 	  me->p_armies, cur_max, me->p_ship.s_maxarmies, DB_3DIGITS, color);
465       old_arm = me->p_armies;
466       old_cur_arm = cur_max;
467     }
468 
469   if (fr || me->p_wtemp != old_wpn)
470     {
471       value = (100 * me->p_wtemp) / me->p_ship.s_maxwpntemp;
472 
473       if (value > 50)
474 	color = W_Red;
475       else if (value <= 20)
476 	color = W_White;
477       else
478 	color = W_Yellow;
479       db_bar("Wt", 218, 17,
480 	     me->p_wtemp / 10, me->p_ship.s_maxwpntemp / 10, me->p_ship.s_maxwpntemp / 10, DB_3DIGITS
481 	     ,color);
482       old_wpn = me->p_wtemp;
483     }
484 
485   if (fr || me->p_etemp != old_egn)
486     {
487       value = (100 * me->p_etemp) / me->p_ship.s_maxegntemp;
488 
489       if (value <= 25)
490 	color = W_White;
491       else if (value < 75)
492 	color = W_Yellow;
493       else
494 	color = W_Red;
495       db_bar("Et", 218, 31,
496 	     me->p_etemp / 10, me->p_ship.s_maxegntemp / 10, me->p_ship.s_maxegntemp / 10, DB_3DIGITS
497 	     ,color);
498       old_egn = me->p_etemp;
499     }
500 
501   if (fr || me->p_fuel != old_ful)
502     {
503       value = ((100 * me->p_fuel) / me->p_ship.s_maxfuel);
504 
505       if (value <= 50)
506 	color = W_Red;
507       else if (value > 90)
508 	color = W_White;
509       else
510 	color = W_Yellow;
511       db_bar("Fu", 346, 3,
512 	     me->p_fuel, me->p_ship.s_maxfuel, me->p_ship.s_maxfuel, DB_5DIGITS, color);
513       old_ful = me->p_fuel;
514     }
515 }
516 
517 void
db_redraw(int fr)518         db_redraw(int fr)
519 {
520   switch (newDashboard)
521     {
522     case 2:
523       db_redraw_krp(fr);
524       break;
525     case 3:
526       db_redraw_lab2(fr);
527       break;
528     default:
529       db_redraw_COW(fr);
530     }
531 }
532