summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_us_1.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/id_us_1.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
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}