3 // ID_US_1.c - User Manager - General routines
\r
5 // By Jason Blochowiak
\r
6 // Hacked up for Catacomb 3D
\r
10 // This module handles dealing with user input & feedback
\r
12 // Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
\r
13 // and Refresh Mgrs, Memory Mgr for background save/restore
\r
16 // ingame - Flag set by game indicating if a game is in progress
\r
17 // abortgame - Flag set if the current game should be aborted (if a load
\r
19 // loadedgame - Flag set if a game was loaded
\r
20 // abortprogram - Normally nil, this points to a terminal error message
\r
21 // if the program needs to abort
\r
22 // restartgame - Normally set to gd_Continue, this is set to one of the
\r
23 // difficulty levels if a new game should be started
\r
24 // PrintX, PrintY - Where the User Mgr will print (global coords)
\r
25 // WindowX,WindowY,WindowW,WindowH - The dimensions of the current
\r
29 #include "ID_HEADS.H"
\r
40 word WindowX,WindowY,WindowW,WindowH;
\r
42 // Internal variables
\r
43 #define ConfigVersion 1
\r
45 static char *ParmStrings[] = {"TEDLEVEL","NOWAIT"},
\r
46 *ParmStrings2[] = {"COMP","NOCOMP"};
\r
47 static boolean US_Started;
\r
49 boolean Button0,Button1,
\r
51 int CursorX,CursorY;
\r
53 void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
\r
54 (*USL_DrawString)(char far *) = VWB_DrawPropString;
\r
56 SaveGame Games[MaxSaveGames];
\r
57 HighScore Scores[MaxScores] =
\r
59 {"id software-'92",10000,1},
\r
60 {"Adrian Carmack",10000,1},
\r
61 {"John Carmack",10000,1},
\r
62 {"Kevin Cloud",10000,1},
\r
63 {"Tom Hall",10000,1},
\r
64 {"John Romero",10000,1},
\r
65 {"Jay Wilbur",10000,1},
\r
68 // Internal routines
\r
72 ///////////////////////////////////////////////////////////////////////////
\r
74 // USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
\r
77 ///////////////////////////////////////////////////////////////////////////
\r
81 USL_HardError(word errval,int ax,int bp,int si)
\r
86 extern void ShutdownId(void);
\r
88 static char buf[32];
\r
89 static WindowRec wr;
\r
100 if ((di & 0x00ff) == 0)
\r
101 s = "Drive ~ is Write Protected";
\r
103 s = "Error on Drive ~";
\r
104 for (t = buf;*s;s++,t++) // Can't use sprintf()
\r
105 if ((*t = *s) == '~')
\r
106 *t = (ax & 0x00ff) + 'A';
\r
111 c = peekb(0x40,0x49); // Get the current screen mode
\r
112 if ((c < 4) || (c == 7))
\r
115 // DEBUG - handle screen cleanup
\r
117 US_SaveWindow(&wr);
\r
118 US_CenterWindow(30,3);
\r
120 US_CPrint("(R)etry or (A)bort?");
\r
122 IN_ClearKeysDown();
\r
124 asm sti // Let the keyboard interrupts come through
\r
128 switch (IN_WaitForASCII())
\r
141 US_RestoreWindow(&wr);
\r
150 fprintf(stderr,"Terminal Error: %s\n",s);
\r
152 fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
\r
163 ///////////////////////////////////////////////////////////////////////////
\r
165 // US_Startup() - Starts the User Mgr
\r
167 ///////////////////////////////////////////////////////////////////////////
\r
176 harderr(USL_HardError); // Install the fatal error handler
\r
178 US_InitRndT(true); // Initialize the random number generator
\r
180 for (i = 1;i < _argc;i++)
\r
182 switch (US_CheckParm(_argv[i],ParmStrings2))
\r
185 compatability = true;
\r
188 compatability = false;
\r
193 // Check for TED launching here
\r
194 for (i = 1;i < _argc;i++)
\r
196 n = US_CheckParm(_argv[i],ParmStrings);
\r
200 tedlevelnum = atoi(_argv[i + 1]);
\r
201 if (tedlevelnum >= 0)
\r
215 ///////////////////////////////////////////////////////////////////////////
\r
217 // US_Shutdown() - Shuts down the User Mgr
\r
219 ///////////////////////////////////////////////////////////////////////////
\r
226 US_Started = false;
\r
229 ///////////////////////////////////////////////////////////////////////////
\r
231 // US_CheckParm() - checks to see if a string matches one of a set of
\r
232 // strings. The check is case insensitive. The routine returns the
\r
233 // index of the string that matched, or -1 if no matches were found
\r
235 ///////////////////////////////////////////////////////////////////////////
\r
237 US_CheckParm(char *parm,char **strings)
\r
243 while (!isalpha(*parm)) // Skip non-alphas
\r
246 for (i = 0;*strings && **strings;i++)
\r
248 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
\r
265 // Window/Printing routines
\r
267 ///////////////////////////////////////////////////////////////////////////
\r
269 // US_SetPrintRoutines() - Sets the routines used to measure and print
\r
270 // from within the User Mgr. Primarily provided to allow switching
\r
271 // between masked and non-masked fonts
\r
273 ///////////////////////////////////////////////////////////////////////////
\r
275 US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
\r
277 USL_MeasureString = measure;
\r
278 USL_DrawString = print;
\r
281 ///////////////////////////////////////////////////////////////////////////
\r
283 // US_Print() - Prints a string in the current window. Newlines are
\r
286 ///////////////////////////////////////////////////////////////////////////
\r
288 US_Print(char far *s)
\r
296 while ((c = *se) && (c != '\n'))
\r
300 USL_MeasureString(s,&w,&h);
\r
319 ///////////////////////////////////////////////////////////////////////////
\r
321 // US_PrintUnsigned() - Prints an unsigned long
\r
323 ///////////////////////////////////////////////////////////////////////////
\r
325 US_PrintUnsigned(longword n)
\r
329 US_Print(ultoa(n,buffer,10));
\r
332 ///////////////////////////////////////////////////////////////////////////
\r
334 // US_PrintSigned() - Prints a signed long
\r
336 ///////////////////////////////////////////////////////////////////////////
\r
338 US_PrintSigned(long n)
\r
342 US_Print(ltoa(n,buffer,10));
\r
345 ///////////////////////////////////////////////////////////////////////////
\r
347 // USL_PrintInCenter() - Prints a string in the center of the given rect
\r
349 ///////////////////////////////////////////////////////////////////////////
\r
351 USL_PrintInCenter(char far *s,Rect r)
\r
356 USL_MeasureString(s,&w,&h);
\r
357 rw = r.lr.x - r.ul.x;
\r
358 rh = r.lr.y - r.ul.y;
\r
360 px = r.ul.x + ((rw - w) / 2);
\r
361 py = r.ul.y + ((rh - h) / 2);
\r
365 ///////////////////////////////////////////////////////////////////////////
\r
367 // US_PrintCentered() - Prints a string centered in the current window.
\r
369 ///////////////////////////////////////////////////////////////////////////
\r
371 US_PrintCentered(char far *s)
\r
377 r.lr.x = r.ul.x + WindowW;
\r
378 r.lr.y = r.ul.y + WindowH;
\r
380 USL_PrintInCenter(s,r);
\r
383 ///////////////////////////////////////////////////////////////////////////
\r
385 // US_CPrintLine() - Prints a string centered on the current line and
\r
386 // advances to the next line. Newlines are not supported.
\r
388 ///////////////////////////////////////////////////////////////////////////
\r
390 US_CPrintLine(char far *s)
\r
394 USL_MeasureString(s,&w,&h);
\r
397 Quit("US_CPrintLine() - String exceeds width");
\r
398 px = WindowX + ((WindowW - w) / 2);
\r
404 ///////////////////////////////////////////////////////////////////////////
\r
406 // US_CPrint() - Prints a string in the current window. Newlines are
\r
409 ///////////////////////////////////////////////////////////////////////////
\r
411 US_CPrint(char far *s)
\r
418 while ((c = *se) && (c != '\n'))
\r
433 ///////////////////////////////////////////////////////////////////////////
\r
435 // US_ClearWindow() - Clears the current window to white and homes the
\r
438 ///////////////////////////////////////////////////////////////////////////
\r
440 US_ClearWindow(void)
\r
442 VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
\r
447 ///////////////////////////////////////////////////////////////////////////
\r
449 // US_DrawWindow() - Draws a frame and sets the current window parms
\r
451 ///////////////////////////////////////////////////////////////////////////
\r
453 US_DrawWindow(word x,word y,word w,word h)
\r
473 VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
\r
474 for (i = sx + 8;i <= sx + sw - 8;i += 8)
\r
475 VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
\r
476 VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
\r
478 for (i = sy + 8;i <= sy + sh - 8;i += 8)
\r
479 VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
\r
482 ///////////////////////////////////////////////////////////////////////////
\r
484 // US_CenterWindow() - Generates a window of a given width & height in the
\r
485 // middle of the screen
\r
487 ///////////////////////////////////////////////////////////////////////////
\r
489 US_CenterWindow(word w,word h)
\r
491 US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
\r
494 ///////////////////////////////////////////////////////////////////////////
\r
496 // US_SaveWindow() - Saves the current window parms into a record for
\r
497 // later restoration
\r
499 ///////////////////////////////////////////////////////////////////////////
\r
501 US_SaveWindow(WindowRec *win)
\r
512 ///////////////////////////////////////////////////////////////////////////
\r
514 // US_RestoreWindow() - Sets the current window parms to those held in the
\r
517 ///////////////////////////////////////////////////////////////////////////
\r
519 US_RestoreWindow(WindowRec *win)
\r
532 ///////////////////////////////////////////////////////////////////////////
\r
534 // USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
\r
536 ///////////////////////////////////////////////////////////////////////////
\r
538 USL_XORICursor(int x,int y,char *s,word cursor)
\r
540 static boolean status; // VGA doesn't XOR...
\r
541 char buf[MaxString];
\r
546 buf[cursor] = '\0';
\r
547 USL_MeasureString(buf,&w,&h);
\r
552 USL_DrawString("\x80");
\r
556 fontcolor = backcolor;
\r
557 USL_DrawString("\x80");
\r
563 ///////////////////////////////////////////////////////////////////////////
\r
565 // US_LineInput() - Gets a line of user input at (x,y), the string defaults
\r
566 // to whatever is pointed at by def. Input is restricted to maxchars
\r
567 // chars or maxwidth pixels wide. If the user hits escape (and escok is
\r
568 // true), nothing is copied into buf, and false is returned. If the
\r
569 // user hits return, the current string is copied into buf, and true is
\r
572 ///////////////////////////////////////////////////////////////////////////
\r
574 US_LineInput(int x,int y,char *buf,char *def,boolean escok,
\r
575 int maxchars,int maxwidth)
\r
578 cursorvis,cursormoved,
\r
582 s[MaxString],olds[MaxString];
\r
594 cursor = strlen(s);
\r
595 cursormoved = redraw = true;
\r
597 cursorvis = done = false;
\r
598 lasttime = TimeCount;
\r
599 LastASCII = key_None;
\r
600 LastScan = sc_None;
\r
605 USL_XORICursor(x,y,s,cursor);
\r
611 LastScan = sc_None;
\r
613 LastASCII = key_None;
\r
623 cursormoved = true;
\r
625 case sc_RightArrow:
\r
629 cursormoved = true;
\r
634 cursormoved = true;
\r
637 cursor = strlen(s);
\r
639 cursormoved = true;
\r
660 strcpy(s + cursor - 1,s + cursor);
\r
665 cursormoved = true;
\r
670 strcpy(s + cursor,s + cursor + 1);
\r
674 cursormoved = true;
\r
677 case 0x4c: // Keypad 5
\r
690 USL_MeasureString(s,&w,&h);
\r
695 && (len < MaxString - 1)
\r
696 && ((!maxchars) || (len < maxchars))
\r
697 && ((!maxwidth) || (w < maxwidth))
\r
700 for (i = len + 1;i > cursor;i--)
\r
712 fontcolor = backcolor;
\r
713 USL_DrawString(olds);
\r
727 lasttime = TimeCount - TickBase;
\r
729 cursormoved = false;
\r
731 if (TimeCount - lasttime > TickBase / 2)
\r
733 lasttime = TimeCount;
\r
738 USL_XORICursor(x,y,s,cursor);
\r
744 USL_XORICursor(x,y,s,cursor);
\r
749 USL_DrawString(olds);
\r
753 IN_ClearKeysDown();
\r