1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
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
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.
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.
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
27 * DESCRIPTION: heads-up text and input code
29 *-----------------------------------------------------------------------------
41 #include "rockmacros.h"
43 // boolean : whether the screen is always erased
44 #define noterased viewwindowx
46 extern int key_backspace
; // phares
47 extern int key_enter
; // phares
51 // code to initialize HUlib would go here if needed
57 ////////////////////////////////////////////////////////
59 // Basic text line widget
61 ////////////////////////////////////////////////////////
64 // HUlib_clearTextLine()
66 // Blank the internal text line in a hu_textline_t widget
68 // Passed a hu_textline_t, returns nothing
70 void HUlib_clearTextLine(hu_textline_t
* t
)
72 t
->linelen
= // killough 1/23 98: support multiple lines
75 t
->needsupdate
= true;
79 // HUlib_initTextLine()
81 // Initialize a hu_textline_t widget. Set the position, font, start char
82 // of the font, and color range to be used.
84 // Passed a hu_textline_t, and the values used to initialize
87 void 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
96 HUlib_clearTextLine(t
);
100 // HUlib_addCharToTextLine()
102 // Adds a character at the end of the text line in a hu_textline_t widget
104 // Passed the hu_textline_t and the char to add
105 // Returns false if already at length limit, true if the character added
107 boolean HUlib_addCharToTextLine
111 // killough 1/23/98 -- support multiple lines
112 if (t
->linelen
== HU_MAXLINELENGTH
)
129 // HUlib_delCharFromTextLine()
131 // Deletes a character at the end of the text line in a hu_textline_t widget
133 // Passed the hu_textline_t
134 // Returns false if already empty, true if the character deleted
136 boolean
HUlib_delCharFromTextLine(hu_textline_t
* t
)
138 if (!t
->len
) return false;
148 // HUlib_drawTextLine()
150 // Draws a hu_textline_t widget
152 // Passed the hu_textline_t and flag whether to draw a cursor
155 void HUlib_drawTextLine
164 int oc
= l
->cm
; //jff 2/17/98 remember default color
165 int y
= l
->y
; // killough 1/18/98 -- support multiple lines
167 // draw the new stuff
169 for (i
=0;i
<l
->len
;i
++)
171 c
= toupper(l
->l
[i
]); //jff insure were not getting a cheap toupper conv.
173 if (c
=='\n') // killough 1/18/98 -- support multiple lines
175 else if (c
=='\t') // killough 1/23/98 -- support tab stops
177 else if (c
=='\x1b') //jff 2/17/98 escape code for color change
178 { //jff 3/26/98 changed to actual escape char
180 if (l
->l
[i
]>='0' && l
->l
[i
]<='9')
183 else if (c
!= ' ' && c
>= l
->sc
&& c
<= 127)
185 w
= SHORT(l
->f
[c
- l
->sc
].width
);
186 if (x
+w
> BASE_WIDTH
)
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
);
200 l
->cm
= oc
; //jff 2/17/98 restore original color
202 // draw the cursor if requested
203 if (drawcursor
&& x
+ SHORT(l
->f
['_' - l
->sc
].width
) <= BASE_WIDTH
)
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
);
212 // HUlib_eraseTextLine()
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
217 // Passed the hu_textline_t
220 void HUlib_eraseTextLine(hu_textline_t
* l
)
222 // KK - If someone finds a use for this code, please fix it, I havn't seen the need
223 // And it's not written to take into account scaling. Causing some nasty effects
224 // on smaller screens.
231 // Only erases when NOT in automap and the screen is reduced,
232 // and the text must either need updating or refreshing
233 // (because of a recent change back from the automap)
235 if (!(automapmode
& am_active
) && viewwindowx
&& l
->needsupdate
)
237 lh
= SHORT(l
->f
[0].height
) + 1;
238 for (y
=l
->y
,yoffset
=y
*SCREENWIDTH
; y
<l
->y
+lh
; y
++,yoffset
+=SCREENWIDTH
)
240 if (y
< viewwindowy
|| y
>= viewwindowy
+ viewheight
)
241 R_VideoErase(yoffset
, SCREENWIDTH
); // erase entire line
245 R_VideoErase(yoffset
, viewwindowx
);
246 // erase right border
247 R_VideoErase(yoffset
+ viewwindowx
+ viewwidth
, viewwindowx
);
251 if (l
->needsupdate
) l
->needsupdate
--;
255 ////////////////////////////////////////////////////////
257 // Player message widget (up to 4 lines of text)
259 ////////////////////////////////////////////////////////
264 // Initialize a hu_stext_t widget. Set the position, number of lines, font,
265 // start char of the font, and color range to be used, and whether enabled.
267 // Passed a hu_stext_t, and the values used to initialize
275 const patchnum_t
* font
,
277 int cm
, //jff 2/16/98 add color range parameter
292 y
- i
*(SHORT(font
[0].height
)+1),
300 // HUlib_addLineToSText()
302 // Adds a blank line to a hu_stext_t widget
304 // Passed a hu_stext_t
307 void HUlib_addLineToSText(hu_stext_t
* s
)
315 HUlib_clearTextLine(&s
->l
[s
->cl
]);
317 // everything needs updating
318 for (i
=0 ; i
<s
->h
; i
++)
319 s
->l
[i
].needsupdate
= 4;
324 // HUlib_addMessageToSText()
326 // Adds a message line with prefix to a hu_stext_t widget
328 // Passed a hu_stext_t, the prefix string, and a message string
331 void HUlib_addMessageToSText(hu_stext_t
* s
, const char* prefix
, const char* msg
)
333 HUlib_addLineToSText(s
);
336 HUlib_addCharToTextLine(&s
->l
[s
->cl
], *(prefix
++));
339 HUlib_addCharToTextLine(&s
->l
[s
->cl
], *(msg
++));
345 // Displays a hu_stext_t widget
347 // Passed a hu_stext_t
350 void HUlib_drawSText(hu_stext_t
* s
)
356 return; // if not on, don't draw
359 for (i
=0 ; i
<s
->h
; i
++)
363 idx
+= s
->h
; // handle queue of lines
367 // need a decision made here on whether to skip the draw
368 HUlib_drawTextLine(l
, false); // no cursor, please
373 // HUlib_eraseSText()
375 // Erases a hu_stext_t widget, when the screen is not fullsize
377 // Passed a hu_stext_t
380 void HUlib_eraseSText(hu_stext_t
* s
)
384 for (i
=0 ; i
<s
->h
; i
++)
386 if (s
->laston
&& !*s
->on
)
387 s
->l
[i
].needsupdate
= 4;
388 HUlib_eraseTextLine(&s
->l
[i
]);
393 ////////////////////////////////////////////////////////
395 // Scrolling message review widget
399 ////////////////////////////////////////////////////////
404 // Initialize a hu_mtext_t widget. Set the position, width, number of lines,
405 // font, start char of the font, color range, background font, and whether
408 // Passed a hu_mtext_t, and the values used to initialize
411 void HUlib_initMText(hu_mtext_t
*m
, int x
, int y
, int w
, int h
,
412 const patchnum_t
* font
, int startchar
, int cm
,
413 const patchnum_t
* bgfont
, boolean
*on
)
419 m
->cl
= -1; //jff 4/28/98 prepare for pre-increment
426 for (i
=0;i
<HU_MAXMESSAGES
;i
++)
432 y
+ (hud_list_bgon
? i
+1 : i
)*HU_REFRESHSPACING
,
441 // HUlib_addLineToMText()
443 // Adds a blank line to a hu_mtext_t widget
445 // Passed a hu_mtext_t
448 void HUlib_addLineToMText(hu_mtext_t
* m
)
451 if (++m
->cl
== hud_msg_lines
)
453 HUlib_clearTextLine(&m
->l
[m
->cl
]);
455 if (m
->nl
<hud_msg_lines
)
459 m
->l
[m
->cl
].needsupdate
= 4;
463 // HUlib_addMessageToMText()
465 // Adds a message line with prefix to a hu_mtext_t widget
467 // Passed a hu_mtext_t, the prefix string, and a message string
470 void HUlib_addMessageToMText(hu_mtext_t
* m
, const char* prefix
, const char* msg
)
472 HUlib_addLineToMText(m
);
475 HUlib_addCharToTextLine(&m
->l
[m
->cl
], *(prefix
++));
478 HUlib_addCharToTextLine(&m
->l
[m
->cl
], *(msg
++));
484 // Draws a background box which the message display review widget can
487 // Passed position, width, height, and the background patches
495 const patchnum_t
* bgp
498 int xs
= bgp
[0].width
;
499 int ys
= bgp
[0].height
;
502 // CPhipps - patch drawing updated
504 V_DrawNumPatch(x
, y
, FG
, bgp
[0].lumpnum
, CR_DEFAULT
, VPT_STRETCH
); // ul
505 for (j
=x
+xs
;j
<x
+w
-xs
;j
+=xs
) // uc
506 V_DrawNumPatch(j
, y
, FG
, bgp
[1].lumpnum
, CR_DEFAULT
, VPT_STRETCH
);
507 V_DrawNumPatch(j
, y
, FG
, bgp
[2].lumpnum
, CR_DEFAULT
, VPT_STRETCH
); // ur
510 for (i
=y
+ys
;i
<y
+h
-ys
;i
+=ys
)
512 V_DrawNumPatch(x
, i
, FG
, bgp
[3].lumpnum
, CR_DEFAULT
, VPT_STRETCH
); // cl
513 for (j
=x
+xs
;j
<x
+w
-xs
;j
+=xs
) // cc
514 V_DrawNumPatch(j
, i
, FG
, bgp
[4].lumpnum
, CR_DEFAULT
, VPT_STRETCH
);
515 V_DrawNumPatch(j
, i
, FG
, bgp
[5].lumpnum
, CR_DEFAULT
, VPT_STRETCH
); // cr
519 V_DrawNumPatch(x
, i
, FG
, bgp
[6].lumpnum
, CR_DEFAULT
, VPT_STRETCH
); // ll
520 for (j
=x
+xs
;j
<x
+w
-xs
;j
+=xs
) // lc
521 V_DrawNumPatch(j
, i
, FG
, bgp
[7].lumpnum
, CR_DEFAULT
, VPT_STRETCH
);
522 V_DrawNumPatch(j
, i
, FG
, bgp
[8].lumpnum
, CR_DEFAULT
, VPT_STRETCH
); // lr
528 // Displays a hu_mtext_t widget
530 // Passed a hu_mtext_t
533 void HUlib_drawMText(hu_mtext_t
* m
)
539 return; // if not on, don't draw
543 HUlib_drawMBg(m
->x
,m
->y
,m
->w
,m
->h
,m
->bg
);
544 y
= m
->y
+ HU_REFRESHSPACING
;
545 for (i
=0 ; i
<m
->nl
; i
++)
549 idx
+= m
->nl
; // handle queue of lines
555 l
->y
= m
->y
+ (i
+1)*HU_REFRESHSPACING
;
560 l
->y
= m
->y
+ i
*HU_REFRESHSPACING
;
563 // need a decision made here on whether to skip the draw
564 HUlib_drawTextLine(l
, false); // no cursor, please
571 // Erases background behind hu_mtext_t widget, when the screen is not fullsize
573 // Passed a hu_mtext_t
576 static void HUlib_eraseMBg(hu_mtext_t
* m
)
582 // Only erases when NOT in automap and the screen is reduced,
583 // and the text must either need updating or refreshing
584 // (because of a recent change back from the automap)
586 if (!(automapmode
& am_active
) && viewwindowx
)
588 lh
= SHORT(m
->l
[0].f
[0].height
) + 1;
589 for (y
=m
->y
,yoffset
=y
*SCREENWIDTH
; y
<m
->y
+lh
*(hud_msg_lines
+2) ; y
++,yoffset
+=SCREENWIDTH
)
591 if (y
< viewwindowy
|| y
>= viewwindowy
+ viewheight
)
592 R_VideoErase(yoffset
, SCREENWIDTH
); // erase entire line
596 R_VideoErase(yoffset
, viewwindowx
);
597 // erase right border
598 R_VideoErase(yoffset
+ viewwindowx
+ viewwidth
, viewwindowx
);
606 // HUlib_eraseMText()
608 // Erases a hu_mtext_t widget, when the screen is not fullsize
610 // Passed a hu_mtext_t
613 void HUlib_eraseMText(hu_mtext_t
* m
)
620 for (i
=0 ; i
< m
->nl
; i
++)
622 m
->l
[i
].needsupdate
= 4;
623 HUlib_eraseTextLine(&m
->l
[i
]);
627 ////////////////////////////////////////////////////////
629 // Interactive text entry widget
631 ////////////////////////////////////////////////////////
636 // Initialize a hu_itext_t widget. Set the position, font,
637 // start char of the font, color range, and whether enabled.
639 // Passed a hu_itext_t, and the values used to initialize
646 const patchnum_t
* font
,
648 int cm
, //jff 2/16/98 add color range parameter
651 it
->lm
= 0; // default left margin is start of text
654 HUlib_initTextLine(&it
->l
, x
, y
, font
, startchar
, cm
);
657 // The following deletion routines adhere to the left margin restriction
660 // HUlib_delCharFromIText()
662 // Deletes a character at the end of the text line in a hu_itext_t widget
664 // Passed the hu_itext_t
667 void HUlib_delCharFromIText(hu_itext_t
* it
)
669 if (it
->l
.len
!= it
->lm
)
670 HUlib_delCharFromTextLine(&it
->l
);
674 // HUlib_eraseLineFromIText()
676 // Deletes all characters from a hu_itext_t widget
678 // Passed the hu_itext_t
681 void HUlib_eraseLineFromIText(hu_itext_t
* it
)
683 while (it
->lm
!= it
->l
.len
)
684 HUlib_delCharFromTextLine(&it
->l
);
688 // HUlib_resetIText()
690 // Deletes all characters from a hu_itext_t widget
691 // Resets left margin as well
693 // Passed the hu_itext_t
696 void HUlib_resetIText(hu_itext_t
* it
)
699 HUlib_clearTextLine(&it
->l
);
703 // HUlib_addPrefixToIText()
705 // Adds a prefix string passed to a hu_itext_t widget
706 // Sets left margin to length of string added
708 // Passed the hu_itext_t and the prefix string
711 void HUlib_addPrefixToIText
716 HUlib_addCharToTextLine(&it
->l
, *(str
++));
721 // HUlib_keyInIText()
723 // Wrapper function for handling general keyed input.
725 // Passed the hu_itext_t and the char input
726 // Returns true if it ate the key
728 boolean HUlib_keyInIText
733 if (ch
>= ' ' && ch
<= '_')
734 HUlib_addCharToTextLine(&it
->l
, (char) ch
);
735 else if (ch
== key_backspace
) // phares
736 HUlib_delCharFromIText(it
);
737 else if (ch
!= key_enter
) // phares
738 return false; // did not eat key
740 return true; // ate the key
746 // Displays a hu_itext_t widget
748 // Passed the hu_itext_t
751 void HUlib_drawIText(hu_itext_t
* it
)
753 hu_textline_t
*l
= &it
->l
;
757 HUlib_drawTextLine(l
, true); // draw the line w/ cursor
761 // HUlib_eraseIText()
763 // Erases a hu_itext_t widget when the screen is not fullsize
765 // Passed the hu_itext_t
768 void HUlib_eraseIText(hu_itext_t
* it
)
770 if (it
->laston
&& !*it
->on
)
771 it
->l
.needsupdate
= 4;
772 HUlib_eraseTextLine(&it
->l
);
773 it
->laston
= *it
->on
;