Update the discussion of themeing in the manual, and put a note in the wps tags appen...
[kugel-rb.git] / apps / plugins / doom / hu_lib.c
blobdf2fa883ecb6baee8e8a34cde627a13bc4e21cec
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
25 * 02111-1307, USA.
27 * DESCRIPTION: heads-up text and input code
29 *-----------------------------------------------------------------------------
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"
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
50 // not used currently
51 // code to initialize HUlib would go here if needed
53 void HUlib_init(void)
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
73 t->len = 0;
74 t->l[0] = 0;
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
85 // Returns nothing
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
91 t->x = x;
92 t->y = y;
93 t->f = f;
94 t->sc = sc;
95 t->cm = cm;
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
108 ( hu_textline_t* t,
109 char ch )
111 // killough 1/23/98 -- support multiple lines
112 if (t->linelen == HU_MAXLINELENGTH)
113 return false;
114 else
116 t->linelen++;
117 if (ch == '\n')
118 t->linelen=0;
120 t->l[t->len++] = ch;
121 t->l[t->len] = 0;
122 t->needsupdate = 4;
123 return true;
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;
139 else
141 t->l[--t->len] = 0;
142 t->needsupdate = 4;
143 return true;
148 // HUlib_drawTextLine()
150 // Draws a hu_textline_t widget
152 // Passed the hu_textline_t and flag whether to draw a cursor
153 // Returns nothing
155 void HUlib_drawTextLine
156 ( hu_textline_t* l,
157 boolean drawcursor )
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
167 // draw the new stuff
168 x = l->x;
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
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';
183 else if (c != ' ' && c >= l->sc && c <= 127)
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;
193 else
195 x += 4;
196 if (x >= BASE_WIDTH)
197 break;
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
218 // Returns nothing
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.
225 (void)l;
226 #if 0
227 int lh;
228 int y;
229 int yoffset;
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
242 else
244 // erase left border
245 R_VideoErase(yoffset, viewwindowx);
246 // erase right border
247 R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
251 if (l->needsupdate) l->needsupdate--;
252 #endif
255 ////////////////////////////////////////////////////////
257 // Player message widget (up to 4 lines of text)
259 ////////////////////////////////////////////////////////
262 // HUlib_initSText()
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
268 // Returns nothing
270 void HUlib_initSText
271 ( hu_stext_t* s,
272 int x,
273 int y,
274 int h,
275 const patchnum_t* font,
276 int startchar,
277 int cm, //jff 2/16/98 add color range parameter
278 boolean* on )
281 int i;
283 s->h = h;
284 s->on = on;
285 s->laston = true;
286 s->cl = 0;
287 for (i=0;i<h;i++)
288 HUlib_initTextLine
290 &s->l[i],
292 y - i*(SHORT(font[0].height)+1),
293 font,
294 startchar,
300 // HUlib_addLineToSText()
302 // Adds a blank line to a hu_stext_t widget
304 // Passed a hu_stext_t
305 // Returns nothing
307 void HUlib_addLineToSText(hu_stext_t* s)
310 int i;
312 // add a clear line
313 if (++s->cl == s->h)
314 s->cl = 0;
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
329 // Returns nothing
331 void HUlib_addMessageToSText(hu_stext_t* s, const char* prefix, const char* msg)
333 HUlib_addLineToSText(s);
334 if (prefix)
335 while (*prefix)
336 HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
338 while (*msg)
339 HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
343 // HUlib_drawSText()
345 // Displays a hu_stext_t widget
347 // Passed a hu_stext_t
348 // Returns nothing
350 void HUlib_drawSText(hu_stext_t* s)
352 int i, idx;
353 hu_textline_t *l;
355 if (!*s->on)
356 return; // if not on, don't draw
358 // draw everything
359 for (i=0 ; i<s->h ; i++)
361 idx = s->cl - i;
362 if (idx < 0)
363 idx += s->h; // handle queue of lines
365 l = &s->l[idx];
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
378 // Returns nothing
380 void HUlib_eraseSText(hu_stext_t* s)
382 int i;
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]);
390 s->laston = *s->on;
393 ////////////////////////////////////////////////////////
395 // Scrolling message review widget
397 // jff added 2/26/98
399 ////////////////////////////////////////////////////////
402 // HUlib_initMText()
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
406 // enabled.
408 // Passed a hu_mtext_t, and the values used to initialize
409 // Returns nothing
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)
415 int i;
417 m->nl = 0;
418 m->nr = 0;
419 m->cl = -1; //jff 4/28/98 prepare for pre-increment
420 m->x = x;
421 m->y = y;
422 m->w = w;
423 m->h = h;
424 m->bg = bgfont;
425 m->on = on;
426 for (i=0;i<HU_MAXMESSAGES;i++)
428 HUlib_initTextLine
430 &m->l[i],
432 y + (hud_list_bgon? i+1 : i)*HU_REFRESHSPACING,
433 font,
434 startchar,
441 // HUlib_addLineToMText()
443 // Adds a blank line to a hu_mtext_t widget
445 // Passed a hu_mtext_t
446 // Returns nothing
448 void HUlib_addLineToMText(hu_mtext_t* m)
450 // add a clear line
451 if (++m->cl == hud_msg_lines)
452 m->cl = 0;
453 HUlib_clearTextLine(&m->l[m->cl]);
455 if (m->nl<hud_msg_lines)
456 m->nl++;
458 // needs updating
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
468 // Returns nothing
470 void HUlib_addMessageToMText(hu_mtext_t* m, const char* prefix, const char* msg)
472 HUlib_addLineToMText(m);
473 if (prefix)
474 while (*prefix)
475 HUlib_addCharToTextLine(&m->l[m->cl], *(prefix++));
477 while (*msg)
478 HUlib_addCharToTextLine(&m->l[m->cl], *(msg++));
482 // HUlib_drawMBg()
484 // Draws a background box which the message display review widget can
485 // display over
487 // Passed position, width, height, and the background patches
488 // Returns nothing
490 void HUlib_drawMBg
491 ( int x,
492 int y,
493 int w,
494 int h,
495 const patchnum_t* bgp
498 int xs = bgp[0].width;
499 int ys = bgp[0].height;
500 int i,j;
502 // CPhipps - patch drawing updated
503 // top rows
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
509 // middle rows
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
518 // bottom row
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
526 // HUlib_drawMText()
528 // Displays a hu_mtext_t widget
530 // Passed a hu_mtext_t
531 // Returns nothing
533 void HUlib_drawMText(hu_mtext_t* m)
535 int i, idx, y;
536 hu_textline_t *l;
538 if (!*m->on)
539 return; // if not on, don't draw
541 // draw everything
542 if (hud_list_bgon)
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++)
547 idx = m->cl - i;
548 if (idx < 0)
549 idx += m->nl; // handle queue of lines
551 l = &m->l[idx];
552 if (hud_list_bgon)
554 l->x = m->x + 4;
555 l->y = m->y + (i+1)*HU_REFRESHSPACING;
557 else
559 l->x = m->x;
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
569 // HUlib_eraseMBg()
571 // Erases background behind hu_mtext_t widget, when the screen is not fullsize
573 // Passed a hu_mtext_t
574 // Returns nothing
576 static void HUlib_eraseMBg(hu_mtext_t* m)
578 int lh;
579 int y;
580 int yoffset;
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
593 else
595 // erase left border
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
611 // Returns nothing
613 void HUlib_eraseMText(hu_mtext_t* m)
615 int i;
617 if (hud_list_bgon)
618 HUlib_eraseMBg(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 ////////////////////////////////////////////////////////
634 // HUlib_initIText()
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
640 // Returns nothing
642 void HUlib_initIText
643 ( hu_itext_t* it,
644 int x,
645 int y,
646 const patchnum_t* font,
647 int startchar,
648 int cm, //jff 2/16/98 add color range parameter
649 boolean* on )
651 it->lm = 0; // default left margin is start of text
652 it->on = on;
653 it->laston = true;
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
665 // Returns nothing
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
679 // Returns nothing
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
694 // Returns nothing
696 void HUlib_resetIText(hu_itext_t* it)
698 it->lm = 0;
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
709 // Returns nothing
711 void HUlib_addPrefixToIText
712 ( hu_itext_t* it,
713 char* str )
715 while (*str)
716 HUlib_addCharToTextLine(&it->l, *(str++));
717 it->lm = it->l.len;
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
729 ( hu_itext_t* it,
730 unsigned char ch )
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
744 // HUlib_drawIText()
746 // Displays a hu_itext_t widget
748 // Passed the hu_itext_t
749 // Returns nothing
751 void HUlib_drawIText(hu_itext_t* it)
753 hu_textline_t *l = &it->l;
755 if (!*it->on)
756 return;
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
766 // Returns nothing
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;