]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/hu_lib.c
games/doom: implement filelength() (thanks quux)
[plan9front.git] / sys / src / games / doom / hu_lib.c
1 // Emacs style mode select   -*- C++ -*- 
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // $Log:$
18 //
19 // DESCRIPTION:  heads-up text and input code
20 //
21 //-----------------------------------------------------------------------------
22
23 static const char
24 rcsid[] = "$Id: hu_lib.c,v 1.3 1997/01/26 07:44:58 b1 Exp $";
25
26 #include <ctype.h>
27
28 #include "doomdef.h"
29
30 #include "v_video.h"
31 #include "m_swap.h"
32
33 #include "hu_lib.h"
34 #include "r_local.h"
35 #include "r_draw.h"
36
37 // boolean : whether the screen is always erased
38 #define noterased viewwindowx
39
40 extern boolean  automapactive;  // in AM_map.c
41
42 void HUlib_init(void)
43 {
44 }
45
46 void HUlib_clearTextLine(hu_textline_t* t)
47 {
48     t->len = 0;
49     t->l[0] = 0;
50     t->needsupdate = true;
51 }
52
53 void
54 HUlib_initTextLine
55 ( hu_textline_t*        t,
56   int                   x,
57   int                   y,
58   patch_t**             f,
59   int                   sc )
60 {
61     t->x = x;
62     t->y = y;
63     t->f = f;
64     t->sc = sc;
65     HUlib_clearTextLine(t);
66 }
67
68 boolean
69 HUlib_addCharToTextLine
70 ( hu_textline_t*        t,
71   char                  ch )
72 {
73
74     if (t->len == HU_MAXLINELENGTH)
75         return false;
76     else
77     {
78         t->l[t->len++] = ch;
79         t->l[t->len] = 0;
80         t->needsupdate = 4;
81         return true;
82     }
83
84 }
85
86 boolean HUlib_delCharFromTextLine(hu_textline_t* t)
87 {
88
89     if (!t->len) return false;
90     else
91     {
92         t->l[--t->len] = 0;
93         t->needsupdate = 4;
94         return true;
95     }
96
97 }
98
99 void
100 HUlib_drawTextLine
101 ( hu_textline_t*        l,
102   boolean               drawcursor )
103 {
104
105     int                 i;
106     int                 w;
107     int                 x;
108     unsigned char       c;
109
110     // draw the new stuff
111     x = l->x;
112     for (i=0;i<l->len;i++)
113     {
114         c = toupper(l->l[i]);
115         if (c != ' '
116             && c >= l->sc
117             && c <= '_')
118         {
119             w = SHORT(l->f[c - l->sc]->width);
120             if (x+w > SCREENWIDTH)
121                 break;
122             V_DrawPatchDirect(x, l->y, FG, l->f[c - l->sc]);
123             x += w;
124         }
125         else
126         {
127             x += 4;
128             if (x >= SCREENWIDTH)
129                 break;
130         }
131     }
132
133     // draw the cursor if requested
134     if (drawcursor
135         && x + SHORT(l->f['_' - l->sc]->width) <= SCREENWIDTH)
136     {
137         V_DrawPatchDirect(x, l->y, FG, l->f['_' - l->sc]);
138     }
139 }
140
141
142 // sorta called by HU_Erase and just better darn get things straight
143 void HUlib_eraseTextLine(hu_textline_t* l)
144 {
145     int                 lh;
146     int                 y;
147     int                 yoffset;
148     static boolean      lastautomapactive = true;
149
150     // Only erases when NOT in automap and the screen is reduced,
151     // and the text must either need updating or refreshing
152     // (because of a recent change back from the automap)
153
154     if (!automapactive &&
155         viewwindowx && l->needsupdate)
156     {
157         lh = SHORT(l->f[0]->height) + 1;
158         for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH)
159         {
160             if (y < viewwindowy || y >= viewwindowy + viewheight)
161                 R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
162             else
163             {
164                 R_VideoErase(yoffset, viewwindowx); // erase left border
165                 R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
166                 // erase right border
167             }
168         }
169     }
170
171     lastautomapactive = automapactive;
172     if (l->needsupdate) l->needsupdate--;
173
174 }
175
176 void
177 HUlib_initSText
178 ( hu_stext_t*   s,
179   int           x,
180   int           y,
181   int           h,
182   patch_t**     font,
183   int           startchar,
184   boolean*      on )
185 {
186
187     int i;
188
189     s->h = h;
190     s->on = on;
191     s->laston = true;
192     s->cl = 0;
193     for (i=0;i<h;i++)
194         HUlib_initTextLine(&s->l[i],
195                            x, y - i*(SHORT(font[0]->height)+1),
196                            font, startchar);
197
198 }
199
200 void HUlib_addLineToSText(hu_stext_t* s)
201 {
202
203     int i;
204
205     // add a clear line
206     if (++s->cl == s->h)
207         s->cl = 0;
208     HUlib_clearTextLine(&s->l[s->cl]);
209
210     // everything needs updating
211     for (i=0 ; i<s->h ; i++)
212         s->l[i].needsupdate = 4;
213
214 }
215
216 void
217 HUlib_addMessageToSText
218 ( hu_stext_t*   s,
219   char*         prefix,
220   char*         msg )
221 {
222     HUlib_addLineToSText(s);
223     if (prefix)
224         while (*prefix)
225             HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
226
227     while (*msg)
228         HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
229 }
230
231 void HUlib_drawSText(hu_stext_t* s)
232 {
233     int i, idx;
234     hu_textline_t *l;
235
236     if (!*s->on)
237         return; // if not on, don't draw
238
239     // draw everything
240     for (i=0 ; i<s->h ; i++)
241     {
242         idx = s->cl - i;
243         if (idx < 0)
244             idx += s->h; // handle queue of lines
245         
246         l = &s->l[idx];
247
248         // need a decision made here on whether to skip the draw
249         HUlib_drawTextLine(l, false); // no cursor, please
250     }
251
252 }
253
254 void HUlib_eraseSText(hu_stext_t* s)
255 {
256
257     int i;
258
259     for (i=0 ; i<s->h ; i++)
260     {
261         if (s->laston && !*s->on)
262             s->l[i].needsupdate = 4;
263         HUlib_eraseTextLine(&s->l[i]);
264     }
265     s->laston = *s->on;
266
267 }
268
269 void
270 HUlib_initIText
271 ( hu_itext_t*   it,
272   int           x,
273   int           y,
274   patch_t**     font,
275   int           startchar,
276   boolean*      on )
277 {
278     it->lm = 0; // default left margin is start of text
279     it->on = on;
280     it->laston = true;
281     HUlib_initTextLine(&it->l, x, y, font, startchar);
282 }
283
284
285 // The following deletion routines adhere to the left margin restriction
286 void HUlib_delCharFromIText(hu_itext_t* it)
287 {
288     if (it->l.len != it->lm)
289         HUlib_delCharFromTextLine(&it->l);
290 }
291
292 void HUlib_eraseLineFromIText(hu_itext_t* it)
293 {
294     while (it->lm != it->l.len)
295         HUlib_delCharFromTextLine(&it->l);
296 }
297
298 // Resets left margin as well
299 void HUlib_resetIText(hu_itext_t* it)
300 {
301     it->lm = 0;
302     HUlib_clearTextLine(&it->l);
303 }
304
305 void
306 HUlib_addPrefixToIText
307 ( hu_itext_t*   it,
308   char*         str )
309 {
310     while (*str)
311         HUlib_addCharToTextLine(&it->l, *(str++));
312     it->lm = it->l.len;
313 }
314
315 // wrapper function for handling general keyed input.
316 // returns true if it ate the key
317 boolean
318 HUlib_keyInIText
319 ( hu_itext_t*   it,
320   unsigned char ch )
321 {
322
323     if (ch >= ' ' && ch <= '_') 
324         HUlib_addCharToTextLine(&it->l, (char) ch);
325     else 
326         if (ch == KEY_BACKSPACE) 
327             HUlib_delCharFromIText(it);
328         else 
329             if (ch != KEY_ENTER) 
330                 return false; // did not eat key
331
332     return true; // ate the key
333
334 }
335
336 void HUlib_drawIText(hu_itext_t* it)
337 {
338
339     hu_textline_t *l = &it->l;
340
341     if (!*it->on)
342         return;
343     HUlib_drawTextLine(l, true); // draw the line w/ cursor
344
345 }
346
347 void HUlib_eraseIText(hu_itext_t* it)
348 {
349     if (it->laston && !*it->on)
350         it->l.needsupdate = 4;
351     HUlib_eraseTextLine(&it->l);
352     it->laston = *it->on;
353 }
354