summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_us_1.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_us_1.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/id_us_1.c789
1 files changed, 789 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/id_us_1.c b/apps/plugins/sdl/progs/wolf3d/id_us_1.c
new file mode 100644
index 0000000000..76b53f30f0
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/id_us_1.c
@@ -0,0 +1,789 @@
1//
2// ID Engine
3// ID_US_1.c - User Manager - General routines
4// v1.1d1
5// By Jason Blochowiak
6// Hacked up for Catacomb 3D
7//
8
9//
10// This module handles dealing with user input & feedback
11//
12// Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
13// and Refresh Mgrs, Memory Mgr for background save/restore
14//
15// Globals:
16// ingame - Flag set by game indicating if a game is in progress
17// loadedgame - Flag set if a game was loaded
18// PrintX, PrintY - Where the User Mgr will print (global coords)
19// WindowX,WindowY,WindowW,WindowH - The dimensions of the current
20// window
21//
22
23#include "wl_def.h"
24
25#pragma hdrstop
26
27#if _MSC_VER == 1200 // Visual C++ 6
28 #define vsnprintf _vsnprintf
29#endif
30
31// Global variables
32 word PrintX,PrintY;
33 word WindowX,WindowY,WindowW,WindowH;
34
35// Internal variables
36#define ConfigVersion 1
37
38static boolean US_Started;
39
40 void (*USL_MeasureString)(const char *,word *,word *) = VW_MeasurePropString;
41 void (*USL_DrawString)(const char *) = VWB_DrawPropString;
42
43 SaveGame Games[MaxSaveGames];
44 HighScore Scores[MaxScores] =
45 {
46 {"id software-'92",10000,1},
47 {"Adrian Carmack",10000,1},
48 {"John Carmack",10000,1},
49 {"Kevin Cloud",10000,1},
50 {"Tom Hall",10000,1},
51 {"John Romero",10000,1},
52 {"Jay Wilbur",10000,1},
53 };
54
55int rndindex = 0;
56
57static byte rndtable[] = {
58 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66,
59 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36,
60 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188,
61 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224,
62 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242,
63 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0,
64 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235,
65 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113,
66 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75,
67 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196,
68 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113,
69 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241,
70 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224,
71 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95,
72 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226,
73 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36,
74 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106,
75 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136,
76 120, 163, 236, 249 };
77
78// Internal routines
79
80// Public routines
81
82///////////////////////////////////////////////////////////////////////////
83//
84// US_Startup() - Starts the User Mgr
85//
86///////////////////////////////////////////////////////////////////////////
87void US_Startup()
88{
89 if (US_Started)
90 return;
91
92 US_InitRndT(true); // Initialize the random number generator
93
94 US_Started = true;
95}
96
97
98///////////////////////////////////////////////////////////////////////////
99//
100// US_Shutdown() - Shuts down the User Mgr
101//
102///////////////////////////////////////////////////////////////////////////
103void
104US_Shutdown(void)
105{
106 if (!US_Started)
107 return;
108
109 US_Started = false;
110}
111
112// Window/Printing routines
113
114///////////////////////////////////////////////////////////////////////////
115//
116// US_SetPrintRoutines() - Sets the routines used to measure and print
117// from within the User Mgr. Primarily provided to allow switching
118// between masked and non-masked fonts
119//
120///////////////////////////////////////////////////////////////////////////
121void
122US_SetPrintRoutines(void (*measure)(const char *,word *,word *),
123 void (*print)(const char *))
124{
125 USL_MeasureString = measure;
126 USL_DrawString = print;
127}
128
129///////////////////////////////////////////////////////////////////////////
130//
131// US_Print() - Prints a string in the current window. Newlines are
132// supported.
133//
134///////////////////////////////////////////////////////////////////////////
135void
136US_Print(const char *sorg)
137{
138 char c;
139 char *sstart = strdup(sorg);
140 char *s = sstart;
141 char *se;
142 word w,h;
143
144 while (*s)
145 {
146 se = s;
147 while ((c = *se)!=0 && (c != '\n'))
148 se++;
149 *se = '\0';
150
151 USL_MeasureString(s,&w,&h);
152 px = PrintX;
153 py = PrintY;
154 USL_DrawString(s);
155
156 s = se;
157 if (c)
158 {
159 *se = c;
160 s++;
161
162 PrintX = WindowX;
163 PrintY += h;
164 }
165 else
166 PrintX += w;
167 }
168 free(sstart);
169}
170
171///////////////////////////////////////////////////////////////////////////
172//
173// US_PrintUnsigned() - Prints an unsigned long
174//
175///////////////////////////////////////////////////////////////////////////
176void
177US_PrintUnsigned(longword n)
178{
179 char buffer[32];
180 sprintf(buffer, "%lu", n);
181
182 US_Print(buffer);
183}
184
185///////////////////////////////////////////////////////////////////////////
186//
187// US_PrintSigned() - Prints a signed long
188//
189///////////////////////////////////////////////////////////////////////////
190void
191US_PrintSigned(int32_t n)
192{
193 char buffer[32];
194
195 US_Print(ltoa(n,buffer,10));
196}
197
198///////////////////////////////////////////////////////////////////////////
199//
200// USL_PrintInCenter() - Prints a string in the center of the given rect
201//
202///////////////////////////////////////////////////////////////////////////
203void
204USL_PrintInCenter(const char *s,Rect r)
205{
206 word w,h,
207 rw,rh;
208
209 USL_MeasureString(s,&w,&h);
210 rw = r.lr.x - r.ul.x;
211 rh = r.lr.y - r.ul.y;
212
213 px = r.ul.x + ((rw - w) / 2);
214 py = r.ul.y + ((rh - h) / 2);
215 USL_DrawString(s);
216}
217
218///////////////////////////////////////////////////////////////////////////
219//
220// US_PrintCentered() - Prints a string centered in the current window.
221//
222///////////////////////////////////////////////////////////////////////////
223void
224US_PrintCentered(const char *s)
225{
226 Rect r;
227
228 r.ul.x = WindowX;
229 r.ul.y = WindowY;
230 r.lr.x = r.ul.x + WindowW;
231 r.lr.y = r.ul.y + WindowH;
232
233 USL_PrintInCenter(s,r);
234}
235
236///////////////////////////////////////////////////////////////////////////
237//
238// US_CPrintLine() - Prints a string centered on the current line and
239// advances to the next line. Newlines are not supported.
240//
241///////////////////////////////////////////////////////////////////////////
242void
243US_CPrintLine(const char *s)
244{
245 word w,h;
246
247 USL_MeasureString(s,&w,&h);
248
249 if (w > WindowW)
250 Quit("US_CPrintLine() - String exceeds width");
251 px = WindowX + ((WindowW - w) / 2);
252 py = PrintY;
253 USL_DrawString(s);
254 PrintY += h;
255}
256
257///////////////////////////////////////////////////////////////////////////
258//
259// US_CPrint() - Prints a string centered in the current window.
260// Newlines are supported.
261//
262///////////////////////////////////////////////////////////////////////////
263void
264US_CPrint(const char *sorg)
265{
266 char c;
267 char *sstart = strdup(sorg);
268 char *s = sstart;
269 char *se;
270
271 while (*s)
272 {
273 se = s;
274 while ((c = *se)!=0 && (c != '\n'))
275 se++;
276 *se = '\0';
277
278 US_CPrintLine(s);
279
280 s = se;
281 if (c)
282 {
283 *se = c;
284 s++;
285 }
286 }
287 free(sstart);
288}
289
290///////////////////////////////////////////////////////////////////////////
291//
292// US_Printf() - Prints a formatted string in the current window.
293// Newlines are supported.
294//
295///////////////////////////////////////////////////////////////////////////
296
297void US_Printf(const char *formatStr, ...)
298{
299 char strbuf[256];
300 va_list vlist;
301 va_start(vlist, formatStr);
302 int len = vsnprintf(strbuf, sizeof(strbuf), formatStr, vlist);
303 va_end(vlist);
304 if(len <= -1 || len >= sizeof(strbuf))
305 strbuf[sizeof(strbuf) - 1] = 0;
306 US_Print(strbuf);
307}
308
309///////////////////////////////////////////////////////////////////////////
310//
311// US_CPrintf() - Prints a formatted string centered in the current window.
312// Newlines are supported.
313//
314///////////////////////////////////////////////////////////////////////////
315
316void US_CPrintf(const char *formatStr, ...)
317{
318 char strbuf[256];
319 va_list vlist;
320 va_start(vlist, formatStr);
321 int len = vsnprintf(strbuf, sizeof(strbuf), formatStr, vlist);
322 va_end(vlist);
323 if(len <= -1 || len >= sizeof(strbuf))
324 strbuf[sizeof(strbuf) - 1] = 0;
325 US_CPrint(strbuf);
326}
327
328///////////////////////////////////////////////////////////////////////////
329//
330// US_ClearWindow() - Clears the current window to white and homes the
331// cursor
332//
333///////////////////////////////////////////////////////////////////////////
334void
335US_ClearWindow(void)
336{
337 VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
338 PrintX = WindowX;
339 PrintY = WindowY;
340}
341
342///////////////////////////////////////////////////////////////////////////
343//
344// US_DrawWindow() - Draws a frame and sets the current window parms
345//
346///////////////////////////////////////////////////////////////////////////
347void
348US_DrawWindow(word x,word y,word w,word h)
349{
350 word i,
351 sx,sy,sw,sh;
352
353 WindowX = x * 8;
354 WindowY = y * 8;
355 WindowW = w * 8;
356 WindowH = h * 8;
357
358 PrintX = WindowX;
359 PrintY = WindowY;
360
361 sx = (x - 1) * 8;
362 sy = (y - 1) * 8;
363 sw = (w + 1) * 8;
364 sh = (h + 1) * 8;
365
366 US_ClearWindow();
367
368 VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
369 for (i = sx + 8;i <= sx + sw - 8;i += 8)
370 VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
371 VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
372
373 for (i = sy + 8;i <= sy + sh - 8;i += 8)
374 VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
375}
376
377///////////////////////////////////////////////////////////////////////////
378//
379// US_CenterWindow() - Generates a window of a given width & height in the
380// middle of the screen
381//
382///////////////////////////////////////////////////////////////////////////
383void
384US_CenterWindow(word w,word h)
385{
386 US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
387}
388
389///////////////////////////////////////////////////////////////////////////
390//
391// US_SaveWindow() - Saves the current window parms into a record for
392// later restoration
393//
394///////////////////////////////////////////////////////////////////////////
395void
396US_SaveWindow(WindowRec *win)
397{
398 win->x = WindowX;
399 win->y = WindowY;
400 win->w = WindowW;
401 win->h = WindowH;
402
403 win->px = PrintX;
404 win->py = PrintY;
405}
406
407///////////////////////////////////////////////////////////////////////////
408//
409// US_RestoreWindow() - Sets the current window parms to those held in the
410// record
411//
412///////////////////////////////////////////////////////////////////////////
413void
414US_RestoreWindow(WindowRec *win)
415{
416 WindowX = win->x;
417 WindowY = win->y;
418 WindowW = win->w;
419 WindowH = win->h;
420
421 PrintX = win->px;
422 PrintY = win->py;
423}
424
425// Input routines
426
427///////////////////////////////////////////////////////////////////////////
428//
429// USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
430//
431///////////////////////////////////////////////////////////////////////////
432static void
433USL_XORICursor(int x,int y,const char *s,word cursor)
434{
435 static boolean status; // VGA doesn't XOR...
436 char buf[MaxString];
437 int temp;
438 word w,h;
439
440 strcpy(buf,s);
441 buf[cursor] = '\0';
442 USL_MeasureString(buf,&w,&h);
443
444 px = x + w - 1;
445 py = y;
446 if (status^=1)
447 USL_DrawString("\x80");
448 else
449 {
450 temp = fontcolor;
451 fontcolor = backcolor;
452 USL_DrawString("\x80");
453 fontcolor = temp;
454 }
455}
456
457char USL_RotateChar(char ch, int dir)
458{
459 static const char charSet[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ.,-!?0123456789";
460 const int numChars = sizeof(charSet) / sizeof(char) - 1;
461 int i;
462 for(i = 0; i < numChars; i++)
463 {
464 if(ch == charSet[i]) break;
465 }
466
467 if(i == numChars) i = 0;
468
469 i += dir;
470 if(i < 0) i = numChars - 1;
471 else if(i >= numChars) i = 0;
472 return charSet[i];
473}
474
475///////////////////////////////////////////////////////////////////////////
476//
477// US_LineInput() - Gets a line of user input at (x,y), the string defaults
478// to whatever is pointed at by def. Input is restricted to maxchars
479// chars or maxwidth pixels wide. If the user hits escape (and escok is
480// true), nothing is copied into buf, and false is returned. If the
481// user hits return, the current string is copied into buf, and true is
482// returned
483//
484///////////////////////////////////////////////////////////////////////////
485boolean
486US_LineInput(int x,int y,char *buf,const char *def,boolean escok,
487 int maxchars,int maxwidth)
488{
489 boolean redraw,
490 cursorvis,cursormoved,
491 done,result, checkkey;
492 ScanCode sc;
493 char c;
494 char s[MaxString],olds[MaxString];
495 int cursor,len;
496 word i,
497 w,h,
498 temp;
499 longword curtime, lasttime, lastdirtime, lastbuttontime, lastdirmovetime;
500 ControlInfo ci;
501 Direction lastdir = dir_None;
502
503 if (def)
504 strcpy(s,def);
505 else
506 *s = '\0';
507 *olds = '\0';
508 cursor = (int) strlen(s);
509 cursormoved = redraw = true;
510
511 cursorvis = done = false;
512 lasttime = lastdirtime = lastdirmovetime = GetTimeCount();
513 lastbuttontime = lasttime + TickBase / 4; // 250 ms => first button press accepted after 500 ms
514 LastASCII = key_None;
515 LastScan = sc_None;
516
517 while (!done)
518 {
519 ReadAnyControl(&ci);
520
521 if (cursorvis)
522 USL_XORICursor(x,y,s,cursor);
523
524 sc = LastScan;
525 LastScan = sc_None;
526 c = LastASCII;
527 LastASCII = key_None;
528
529 checkkey = true;
530 curtime = GetTimeCount();
531
532 // After each direction change accept the next change after 250 ms and then everz 125 ms
533 if(ci.dir != lastdir || curtime - lastdirtime > TickBase / 4 && curtime - lastdirmovetime > TickBase / 8)
534 {
535 if(ci.dir != lastdir)
536 {
537 lastdir = ci.dir;
538 lastdirtime = curtime;
539 }
540 lastdirmovetime = curtime;
541
542 switch(ci.dir)
543 {
544 case dir_West:
545 if(cursor)
546 {
547 // Remove trailing whitespace if cursor is at end of string
548 if(s[cursor] == ' ' && s[cursor + 1] == 0)
549 s[cursor] = 0;
550 cursor--;
551 }
552 cursormoved = true;
553 checkkey = false;
554 break;
555 case dir_East:
556 if(cursor >= MaxString - 1) break;
557
558 if(!s[cursor])
559 {
560 USL_MeasureString(s,&w,&h);
561 if(len >= maxchars || maxwidth && w >= maxwidth) break;
562
563 s[cursor] = ' ';
564 s[cursor + 1] = 0;
565 }
566 cursor++;
567 cursormoved = true;
568 checkkey = false;
569 break;
570
571 case dir_North:
572 if(!s[cursor])
573 {
574 USL_MeasureString(s,&w,&h);
575 if(len >= maxchars || maxwidth && w >= maxwidth) break;
576 s[cursor + 1] = 0;
577 }
578 s[cursor] = USL_RotateChar(s[cursor], 1);
579 redraw = true;
580 checkkey = false;
581 break;
582
583 case dir_South:
584 if(!s[cursor])
585 {
586 USL_MeasureString(s,&w,&h);
587 if(len >= maxchars || maxwidth && w >= maxwidth) break;
588 s[cursor + 1] = 0;
589 }
590 s[cursor] = USL_RotateChar(s[cursor], -1);
591 redraw = true;
592 checkkey = false;
593 break;
594 }
595 }
596
597 if((int)(curtime - lastbuttontime) > TickBase / 4) // 250 ms
598 {
599 if(ci.button0) // acts as return
600 {
601 strcpy(buf,s);
602 done = true;
603 result = true;
604 checkkey = false;
605 }
606 if(ci.button1 && escok) // acts as escape
607 {
608 done = true;
609 result = false;
610 checkkey = false;
611 }
612 if(ci.button2) // acts as backspace
613 {
614 lastbuttontime = curtime;
615 if(cursor)
616 {
617 strcpy(s + cursor - 1,s + cursor);
618 cursor--;
619 redraw = true;
620 }
621 cursormoved = true;
622 checkkey = false;
623 }
624 }
625
626 if(checkkey)
627 {
628 switch (sc)
629 {
630 case sc_LeftArrow:
631 if (cursor)
632 cursor--;
633 c = key_None;
634 cursormoved = true;
635 break;
636 case sc_RightArrow:
637 if (s[cursor])
638 cursor++;
639 c = key_None;
640 cursormoved = true;
641 break;
642 case sc_Home:
643 cursor = 0;
644 c = key_None;
645 cursormoved = true;
646 break;
647 case sc_End:
648 cursor = (int) strlen(s);
649 c = key_None;
650 cursormoved = true;
651 break;
652
653 case sc_Return:
654 strcpy(buf,s);
655 done = true;
656 result = true;
657 c = key_None;
658 break;
659 case sc_Escape:
660 if (escok)
661 {
662 done = true;
663 result = false;
664 }
665 c = key_None;
666 break;
667
668 case sc_BackSpace:
669 if (cursor)
670 {
671 strcpy(s + cursor - 1,s + cursor);
672 cursor--;
673 redraw = true;
674 }
675 c = key_None;
676 cursormoved = true;
677 break;
678 case sc_Delete:
679 if (s[cursor])
680 {
681 strcpy(s + cursor,s + cursor + 1);
682 redraw = true;
683 }
684 c = key_None;
685 cursormoved = true;
686 break;
687
688 case SDLK_KP5: //0x4c: // Keypad 5 // TODO: hmmm...
689 case sc_UpArrow:
690 case sc_DownArrow:
691 case sc_PgUp:
692 case sc_PgDn:
693 case sc_Insert:
694 c = key_None;
695 break;
696 }
697
698 if (c)
699 {
700 len = (int) strlen(s);
701 USL_MeasureString(s,&w,&h);
702
703 if(isprint(c) && (len < MaxString - 1) && ((!maxchars) || (len < maxchars))
704 && ((!maxwidth) || (w < maxwidth)))
705 {
706 for (i = len + 1;i > cursor;i--)
707 s[i] = s[i - 1];
708 s[cursor++] = c;
709 redraw = true;
710 }
711 }
712 }
713
714 if (redraw)
715 {
716 px = x;
717 py = y;
718 temp = fontcolor;
719 fontcolor = backcolor;
720 USL_DrawString(olds);
721 fontcolor = (byte) temp;
722 strcpy(olds,s);
723
724 px = x;
725 py = y;
726 USL_DrawString(s);
727
728 redraw = false;
729 }
730
731 if (cursormoved)
732 {
733 cursorvis = false;
734 lasttime = curtime - TickBase;
735
736 cursormoved = false;
737 }
738 if (curtime - lasttime > TickBase / 2) // 500 ms
739 {
740 lasttime = curtime;
741
742 cursorvis ^= true;
743 }
744 else SDL_Delay(5);
745 if (cursorvis)
746 USL_XORICursor(x,y,s,cursor);
747
748 VW_UpdateScreen();
749 }
750
751 if (cursorvis)
752 USL_XORICursor(x,y,s,cursor);
753 if (!result)
754 {
755 px = x;
756 py = y;
757 USL_DrawString(olds);
758 }
759 VW_UpdateScreen();
760
761 IN_ClearKeysDown();
762 return(result);
763}
764
765///////////////////////////////////////////////////////////////////////////
766//
767// US_InitRndT - Initializes the pseudo random number generator.
768// If randomize is true, the seed will be initialized depending on the
769// current time
770//
771///////////////////////////////////////////////////////////////////////////
772void US_InitRndT(int randomize)
773{
774 if(randomize)
775 rndindex = (SDL_GetTicks() >> 4) & 0xff;
776 else
777 rndindex = 0;
778}
779
780///////////////////////////////////////////////////////////////////////////
781//
782// US_RndT - Returns the next 8-bit pseudo random number
783//
784///////////////////////////////////////////////////////////////////////////
785int US_RndT()
786{
787 rndindex = (rndindex+1)&0xff;
788 return rndtable[rndindex];
789}