summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/hu_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/doom/hu_lib.c')
-rw-r--r--apps/plugins/doom/hu_lib.c770
1 files changed, 770 insertions, 0 deletions
diff --git a/apps/plugins/doom/hu_lib.c b/apps/plugins/doom/hu_lib.c
new file mode 100644
index 0000000000..2ac3d35dde
--- /dev/null
+++ b/apps/plugins/doom/hu_lib.c
@@ -0,0 +1,770 @@
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 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
26 *
27 * DESCRIPTION: heads-up text and input code
28 *
29 *-----------------------------------------------------------------------------
30 */
31
32#include "doomdef.h"
33#include "doomstat.h"
34#include "v_video.h"
35#include "m_swap.h"
36#include "hu_lib.h"
37#include "hu_stuff.h"
38#include "r_main.h"
39#include "r_draw.h"
40
41#include "rockmacros.h"
42
43// boolean : whether the screen is always erased
44#define noterased viewwindowx
45
46extern int key_backspace; // phares
47extern int key_enter; // phares
48
49//
50// not used currently
51// code to initialize HUlib would go here if needed
52//
53void HUlib_init(void)
54{
55}
56
57////////////////////////////////////////////////////////
58//
59// Basic text line widget
60//
61////////////////////////////////////////////////////////
62
63//
64// HUlib_clearTextLine()
65//
66// Blank the internal text line in a hu_textline_t widget
67//
68// Passed a hu_textline_t, returns nothing
69//
70void HUlib_clearTextLine(hu_textline_t* t)
71{
72 t->linelen = // killough 1/23 98: support multiple lines
73 t->len = 0;
74 t->l[0] = 0;
75 t->needsupdate = true;
76}
77
78//
79// HUlib_initTextLine()
80//
81// Initialize a hu_textline_t widget. Set the position, font, start char
82// of the font, and color range to be used.
83//
84// Passed a hu_textline_t, and the values used to initialize
85// Returns nothing
86//
87void HUlib_initTextLine(hu_textline_t* t, int x, int y,
88 const patchnum_t* f, int sc, int cm )
89//jff 2/16/98 add color range parameter
90{
91 t->x = x;
92 t->y = y;
93 t->f = f;
94 t->sc = sc;
95 t->cm = cm;
96 HUlib_clearTextLine(t);
97}
98
99//
100// HUlib_addCharToTextLine()
101//
102// Adds a character at the end of the text line in a hu_textline_t widget
103//
104// Passed the hu_textline_t and the char to add
105// Returns false if already at length limit, true if the character added
106//
107boolean HUlib_addCharToTextLine
108( hu_textline_t* t,
109 char ch )
110{
111 // killough 1/23/98 -- support multiple lines
112 if (t->linelen == HU_MAXLINELENGTH)
113 return false;
114 else
115 {
116 t->linelen++;
117 if (ch == '\n')
118 t->linelen=0;
119
120 t->l[t->len++] = ch;
121 t->l[t->len] = 0;
122 t->needsupdate = 4;
123 return true;
124 }
125
126}
127
128//
129// HUlib_delCharFromTextLine()
130//
131// Deletes a character at the end of the text line in a hu_textline_t widget
132//
133// Passed the hu_textline_t
134// Returns false if already empty, true if the character deleted
135//
136boolean HUlib_delCharFromTextLine(hu_textline_t* t)
137{
138 if (!t->len) return false;
139 else
140 {
141 t->l[--t->len] = 0;
142 t->needsupdate = 4;
143 return true;
144 }
145}
146
147//
148// HUlib_drawTextLine()
149//
150// Draws a hu_textline_t widget
151//
152// Passed the hu_textline_t and flag whether to draw a cursor
153// Returns nothing
154//
155void HUlib_drawTextLine
156( hu_textline_t* l,
157 boolean drawcursor )
158{
159
160 int i;
161 int w;
162 int x;
163 unsigned char c;
164 int oc = l->cm; //jff 2/17/98 remember default color
165 int y = l->y; // killough 1/18/98 -- support multiple lines
166
167 // draw the new stuff
168 x = l->x;
169 for (i=0;i<l->len;i++)
170 {
171 c = toupper(l->l[i]); //jff insure were not getting a cheap toupper conv.
172
173 if (c=='\n') // killough 1/18/98 -- support multiple lines
174 x=0,y+=8;
175 else if (c=='\t') // killough 1/23/98 -- support tab stops
176 x=x-x%80+80;
177 else if (c=='\x1b') //jff 2/17/98 escape code for color change
178 { //jff 3/26/98 changed to actual escape char
179 if (++i<l->len)
180 if (l->l[i]>='0' && l->l[i]<='9')
181 l->cm = l->l[i]-'0';
182 }
183 else if (c != ' ' && c >= l->sc && c <= 127)
184 {
185 w = SHORT(l->f[c - l->sc].width);
186 if (x+w > BASE_WIDTH)
187 break;
188 // killough 1/18/98 -- support multiple lines:
189 // CPhipps - patch drawing updated
190 V_DrawNumPatch(x, y, FG, l->f[c - l->sc].lumpnum, l->cm, VPT_TRANS | VPT_STRETCH);
191 x += w;
192 }
193 else
194 {
195 x += 4;
196 if (x >= BASE_WIDTH)
197 break;
198 }
199 }
200 l->cm = oc; //jff 2/17/98 restore original color
201
202 // draw the cursor if requested
203 if (drawcursor && x + SHORT(l->f['_' - l->sc].width) <= BASE_WIDTH)
204 {
205 // killough 1/18/98 -- support multiple lines
206 // CPhipps - patch drawing updated
207 V_DrawNumPatch(x, y, FG, l->f['_' - l->sc].lumpnum, CR_DEFAULT, VPT_NONE | VPT_STRETCH);
208 }
209}
210
211//
212// HUlib_eraseTextLine()
213//
214// Erases a hu_textline_t widget when screen border is behind text
215// Sorta called by HU_Erase and just better darn get things straight
216//
217// Passed the hu_textline_t
218// Returns nothing
219//
220void HUlib_eraseTextLine(hu_textline_t* l)
221{
222 int lh;
223 int y;
224 int yoffset;
225
226 // Only erases when NOT in automap and the screen is reduced,
227 // and the text must either need updating or refreshing
228 // (because of a recent change back from the automap)
229
230 if (!(automapmode & am_active) && viewwindowx && l->needsupdate)
231 {
232 lh = SHORT(l->f[0].height) + 1;
233 for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH)
234 {
235 if (y < viewwindowy || y >= viewwindowy + viewheight)
236 R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
237 else
238 {
239 // erase left border
240 R_VideoErase(yoffset, viewwindowx);
241 // erase right border
242 R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
243 }
244 }
245 }
246
247 if (l->needsupdate) l->needsupdate--;
248}
249
250////////////////////////////////////////////////////////
251//
252// Player message widget (up to 4 lines of text)
253//
254////////////////////////////////////////////////////////
255
256//
257// HUlib_initSText()
258//
259// Initialize a hu_stext_t widget. Set the position, number of lines, font,
260// start char of the font, and color range to be used, and whether enabled.
261//
262// Passed a hu_stext_t, and the values used to initialize
263// Returns nothing
264//
265void HUlib_initSText
266( hu_stext_t* s,
267 int x,
268 int y,
269 int h,
270 const patchnum_t* font,
271 int startchar,
272 int cm, //jff 2/16/98 add color range parameter
273 boolean* on )
274{
275
276 int i;
277
278 s->h = h;
279 s->on = on;
280 s->laston = true;
281 s->cl = 0;
282 for (i=0;i<h;i++)
283 HUlib_initTextLine
284 (
285 &s->l[i],
286 x,
287 y - i*(SHORT(font[0].height)+1),
288 font,
289 startchar,
290 cm
291 );
292}
293
294//
295// HUlib_addLineToSText()
296//
297// Adds a blank line to a hu_stext_t widget
298//
299// Passed a hu_stext_t
300// Returns nothing
301//
302void HUlib_addLineToSText(hu_stext_t* s)
303{
304
305 int i;
306
307 // add a clear line
308 if (++s->cl == s->h)
309 s->cl = 0;
310 HUlib_clearTextLine(&s->l[s->cl]);
311
312 // everything needs updating
313 for (i=0 ; i<s->h ; i++)
314 s->l[i].needsupdate = 4;
315
316}
317
318//
319// HUlib_addMessageToSText()
320//
321// Adds a message line with prefix to a hu_stext_t widget
322//
323// Passed a hu_stext_t, the prefix string, and a message string
324// Returns nothing
325//
326void HUlib_addMessageToSText(hu_stext_t* s, const char* prefix, const char* msg)
327{
328 HUlib_addLineToSText(s);
329 if (prefix)
330 while (*prefix)
331 HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
332
333 while (*msg)
334 HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
335}
336
337//
338// HUlib_drawSText()
339//
340// Displays a hu_stext_t widget
341//
342// Passed a hu_stext_t
343// Returns nothing
344//
345void HUlib_drawSText(hu_stext_t* s)
346{
347 int i, idx;
348 hu_textline_t *l;
349
350 if (!*s->on)
351 return; // if not on, don't draw
352
353 // draw everything
354 for (i=0 ; i<s->h ; i++)
355 {
356 idx = s->cl - i;
357 if (idx < 0)
358 idx += s->h; // handle queue of lines
359
360 l = &s->l[idx];
361
362 // need a decision made here on whether to skip the draw
363 HUlib_drawTextLine(l, false); // no cursor, please
364 }
365}
366
367//
368// HUlib_eraseSText()
369//
370// Erases a hu_stext_t widget, when the screen is not fullsize
371//
372// Passed a hu_stext_t
373// Returns nothing
374//
375void HUlib_eraseSText(hu_stext_t* s)
376{
377 int i;
378
379 for (i=0 ; i<s->h ; i++)
380 {
381 if (s->laston && !*s->on)
382 s->l[i].needsupdate = 4;
383 HUlib_eraseTextLine(&s->l[i]);
384 }
385 s->laston = *s->on;
386}
387
388////////////////////////////////////////////////////////
389//
390// Scrolling message review widget
391//
392// jff added 2/26/98
393//
394////////////////////////////////////////////////////////
395
396//
397// HUlib_initMText()
398//
399// Initialize a hu_mtext_t widget. Set the position, width, number of lines,
400// font, start char of the font, color range, background font, and whether
401// enabled.
402//
403// Passed a hu_mtext_t, and the values used to initialize
404// Returns nothing
405//
406void HUlib_initMText(hu_mtext_t *m, int x, int y, int w, int h,
407 const patchnum_t* font, int startchar, int cm,
408 const patchnum_t* bgfont, boolean *on)
409{
410 int i;
411
412 m->nl = 0;
413 m->nr = 0;
414 m->cl = -1; //jff 4/28/98 prepare for pre-increment
415 m->x = x;
416 m->y = y;
417 m->w = w;
418 m->h = h;
419 m->bg = bgfont;
420 m->on = on;
421 for (i=0;i<HU_MAXMESSAGES;i++)
422 {
423 HUlib_initTextLine
424 (
425 &m->l[i],
426 x,
427 y + (hud_list_bgon? i+1 : i)*HU_REFRESHSPACING,
428 font,
429 startchar,
430 cm
431 );
432 }
433}
434
435//
436// HUlib_addLineToMText()
437//
438// Adds a blank line to a hu_mtext_t widget
439//
440// Passed a hu_mtext_t
441// Returns nothing
442//
443void HUlib_addLineToMText(hu_mtext_t* m)
444{
445 // add a clear line
446 if (++m->cl == hud_msg_lines)
447 m->cl = 0;
448 HUlib_clearTextLine(&m->l[m->cl]);
449
450 if (m->nl<hud_msg_lines)
451 m->nl++;
452
453 // needs updating
454 m->l[m->cl].needsupdate = 4;
455}
456
457//
458// HUlib_addMessageToMText()
459//
460// Adds a message line with prefix to a hu_mtext_t widget
461//
462// Passed a hu_mtext_t, the prefix string, and a message string
463// Returns nothing
464//
465void HUlib_addMessageToMText(hu_mtext_t* m, const char* prefix, const char* msg)
466{
467 HUlib_addLineToMText(m);
468 if (prefix)
469 while (*prefix)
470 HUlib_addCharToTextLine(&m->l[m->cl], *(prefix++));
471
472 while (*msg)
473 HUlib_addCharToTextLine(&m->l[m->cl], *(msg++));
474}
475
476//
477// HUlib_drawMBg()
478//
479// Draws a background box which the message display review widget can
480// display over
481//
482// Passed position, width, height, and the background patches
483// Returns nothing
484//
485void HUlib_drawMBg
486( int x,
487 int y,
488 int w,
489 int h,
490 const patchnum_t* bgp
491)
492{
493 int xs = bgp[0].width;
494 int ys = bgp[0].height;
495 int i,j;
496
497 // CPhipps - patch drawing updated
498 // top rows
499 V_DrawNumPatch(x, y, FG, bgp[0].lumpnum, CR_DEFAULT, VPT_STRETCH); // ul
500 for (j=x+xs;j<x+w-xs;j+=xs) // uc
501 V_DrawNumPatch(j, y, FG, bgp[1].lumpnum, CR_DEFAULT, VPT_STRETCH);
502 V_DrawNumPatch(j, y, FG, bgp[2].lumpnum, CR_DEFAULT, VPT_STRETCH); // ur
503
504 // middle rows
505 for (i=y+ys;i<y+h-ys;i+=ys)
506 {
507 V_DrawNumPatch(x, i, FG, bgp[3].lumpnum, CR_DEFAULT, VPT_STRETCH); // cl
508 for (j=x+xs;j<x+w-xs;j+=xs) // cc
509 V_DrawNumPatch(j, i, FG, bgp[4].lumpnum, CR_DEFAULT, VPT_STRETCH);
510 V_DrawNumPatch(j, i, FG, bgp[5].lumpnum, CR_DEFAULT, VPT_STRETCH); // cr
511 }
512
513 // bottom row
514 V_DrawNumPatch(x, i, FG, bgp[6].lumpnum, CR_DEFAULT, VPT_STRETCH); // ll
515 for (j=x+xs;j<x+w-xs;j+=xs) // lc
516 V_DrawNumPatch(j, i, FG, bgp[7].lumpnum, CR_DEFAULT, VPT_STRETCH);
517 V_DrawNumPatch(j, i, FG, bgp[8].lumpnum, CR_DEFAULT, VPT_STRETCH); // lr
518}
519
520//
521// HUlib_drawMText()
522//
523// Displays a hu_mtext_t widget
524//
525// Passed a hu_mtext_t
526// Returns nothing
527//
528void HUlib_drawMText(hu_mtext_t* m)
529{
530 int i, idx, y;
531 hu_textline_t *l;
532
533 if (!*m->on)
534 return; // if not on, don't draw
535
536 // draw everything
537 if (hud_list_bgon)
538 HUlib_drawMBg(m->x,m->y,m->w,m->h,m->bg);
539 y = m->y + HU_REFRESHSPACING;
540 for (i=0 ; i<m->nl ; i++)
541 {
542 idx = m->cl - i;
543 if (idx < 0)
544 idx += m->nl; // handle queue of lines
545
546 l = &m->l[idx];
547 if (hud_list_bgon)
548 {
549 l->x = m->x + 4;
550 l->y = m->y + (i+1)*HU_REFRESHSPACING;
551 }
552 else
553 {
554 l->x = m->x;
555 l->y = m->y + i*HU_REFRESHSPACING;
556 }
557
558 // need a decision made here on whether to skip the draw
559 HUlib_drawTextLine(l, false); // no cursor, please
560 }
561}
562
563//
564// HUlib_eraseMBg()
565//
566// Erases background behind hu_mtext_t widget, when the screen is not fullsize
567//
568// Passed a hu_mtext_t
569// Returns nothing
570//
571static void HUlib_eraseMBg(hu_mtext_t* m)
572{
573 int lh;
574 int y;
575 int yoffset;
576
577 // Only erases when NOT in automap and the screen is reduced,
578 // and the text must either need updating or refreshing
579 // (because of a recent change back from the automap)
580
581 if (!(automapmode & am_active) && viewwindowx)
582 {
583 lh = SHORT(m->l[0].f[0].height) + 1;
584 for (y=m->y,yoffset=y*SCREENWIDTH ; y<m->y+lh*(hud_msg_lines+2) ; y++,yoffset+=SCREENWIDTH)
585 {
586 if (y < viewwindowy || y >= viewwindowy + viewheight)
587 R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
588 else
589 {
590 // erase left border
591 R_VideoErase(yoffset, viewwindowx);
592 // erase right border
593 R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
594
595 }
596 }
597 }
598}
599
600//
601// HUlib_eraseMText()
602//
603// Erases a hu_mtext_t widget, when the screen is not fullsize
604//
605// Passed a hu_mtext_t
606// Returns nothing
607//
608void HUlib_eraseMText(hu_mtext_t* m)
609{
610 int i;
611
612 if (hud_list_bgon)
613 HUlib_eraseMBg(m);
614
615 for (i=0 ; i< m->nl ; i++)
616 {
617 m->l[i].needsupdate = 4;
618 HUlib_eraseTextLine(&m->l[i]);
619 }
620}
621
622////////////////////////////////////////////////////////
623//
624// Interactive text entry widget
625//
626////////////////////////////////////////////////////////
627
628//
629// HUlib_initIText()
630//
631// Initialize a hu_itext_t widget. Set the position, font,
632// start char of the font, color range, and whether enabled.
633//
634// Passed a hu_itext_t, and the values used to initialize
635// Returns nothing
636//
637void HUlib_initIText
638( hu_itext_t* it,
639 int x,
640 int y,
641 const patchnum_t* font,
642 int startchar,
643 int cm, //jff 2/16/98 add color range parameter
644 boolean* on )
645{
646 it->lm = 0; // default left margin is start of text
647 it->on = on;
648 it->laston = true;
649 HUlib_initTextLine(&it->l, x, y, font, startchar, cm);
650}
651
652// The following deletion routines adhere to the left margin restriction
653
654//
655// HUlib_delCharFromIText()
656//
657// Deletes a character at the end of the text line in a hu_itext_t widget
658//
659// Passed the hu_itext_t
660// Returns nothing
661//
662void HUlib_delCharFromIText(hu_itext_t* it)
663{
664 if (it->l.len != it->lm)
665 HUlib_delCharFromTextLine(&it->l);
666}
667
668//
669// HUlib_eraseLineFromIText()
670//
671// Deletes all characters from a hu_itext_t widget
672//
673// Passed the hu_itext_t
674// Returns nothing
675//
676void HUlib_eraseLineFromIText(hu_itext_t* it)
677{
678 while (it->lm != it->l.len)
679 HUlib_delCharFromTextLine(&it->l);
680}
681
682//
683// HUlib_resetIText()
684//
685// Deletes all characters from a hu_itext_t widget
686// Resets left margin as well
687//
688// Passed the hu_itext_t
689// Returns nothing
690//
691void HUlib_resetIText(hu_itext_t* it)
692{
693 it->lm = 0;
694 HUlib_clearTextLine(&it->l);
695}
696
697//
698// HUlib_addPrefixToIText()
699//
700// Adds a prefix string passed to a hu_itext_t widget
701// Sets left margin to length of string added
702//
703// Passed the hu_itext_t and the prefix string
704// Returns nothing
705//
706void HUlib_addPrefixToIText
707( hu_itext_t* it,
708 char* str )
709{
710 while (*str)
711 HUlib_addCharToTextLine(&it->l, *(str++));
712 it->lm = it->l.len;
713}
714
715//
716// HUlib_keyInIText()
717//
718// Wrapper function for handling general keyed input.
719//
720// Passed the hu_itext_t and the char input
721// Returns true if it ate the key
722//
723boolean HUlib_keyInIText
724( hu_itext_t* it,
725 unsigned char ch )
726{
727
728 if (ch >= ' ' && ch <= '_')
729 HUlib_addCharToTextLine(&it->l, (char) ch);
730 else if (ch == key_backspace) // phares
731 HUlib_delCharFromIText(it);
732 else if (ch != key_enter) // phares
733 return false; // did not eat key
734
735 return true; // ate the key
736}
737
738//
739// HUlib_drawIText()
740//
741// Displays a hu_itext_t widget
742//
743// Passed the hu_itext_t
744// Returns nothing
745//
746void HUlib_drawIText(hu_itext_t* it)
747{
748 hu_textline_t *l = &it->l;
749
750 if (!*it->on)
751 return;
752 HUlib_drawTextLine(l, true); // draw the line w/ cursor
753}
754
755//
756// HUlib_eraseIText()
757//
758// Erases a hu_itext_t widget when the screen is not fullsize
759//
760// Passed the hu_itext_t
761// Returns nothing
762//
763void HUlib_eraseIText(hu_itext_t* it)
764{
765 if (it->laston && !*it->on)
766 it->l.needsupdate = 4;
767 HUlib_eraseTextLine(&it->l);
768 it->laston = *it->on;
769}
770