3 // ID_US_1.c - User Manager - General routines
\r
5 // By Jason Blochowiak
\r
6 // Hacked up for Catacomb 3D
\r
7 // Open Watcom port by sparky4
\r
11 // This module handles dealing with user input & feedback
\r
13 // Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
\r
14 // and Refresh Mgrs, Memory Mgr for background save/restore
\r
17 // ingame - Flag set by game indicating if a game is in progress
\r
18 // abortgame - Flag set if the current game should be aborted (if a load
\r
20 // loadedgame - Flag set if a game was loaded
\r
21 // abortprogram - Normally nil, this points to a terminal error message
\r
22 // if the program needs to abort
\r
23 // restartgame - Normally set to gd_Continue, this is set to one of the
\r
24 // difficulty levels if a new game should be started
\r
25 // PrintX, PrintY - Where the User Mgr will print (global coords)
\r
26 // WindowX,WindowY,WindowW,WindowH - The dimensions of the current
\r
30 #include "src/lib/16_us.h"
\r
36 static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */
\r
39 boolean compatability; word px,py;
\r
45 word WindowX,WindowY,WindowW,WindowH;
\r
47 // Internal variables
\r
48 #define ConfigVersion 1
\r
50 static char *ParmStrings[] = {"TEDLEVEL","NOWAIT"},
\r
51 *ParmStrings2[] = {"COMP","NOCOMP"};
\r
52 static boolean US_Started;
\r
54 boolean Button0,Button1,
\r
56 int CursorX,CursorY;
\r
58 void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
\r
59 (*USL_DrawString)(char far *) = VWB_DrawPropString;
\r
61 SaveGame Games[MaxSaveGames];
\r
62 HighScore Scores[MaxScores] =
\r
64 {"id software-'92",10000,1},
\r
65 {"Adrian Carmack",10000,1},
\r
66 {"John Carmack",10000,1},
\r
67 {"Kevin Cloud",10000,1},
\r
68 {"Tom Hall",10000,1},
\r
69 {"John Romero",10000,1},
\r
70 {"Jay Wilbur",10000,1},
\r
73 // Internal routines
\r
77 ///////////////////////////////////////////////////////////////////////////
\r
79 // USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
\r
82 ///////////////////////////////////////////////////////////////////////////
\r
86 USL_HardError(word errval,int ax,int bp,int si)
\r
91 extern void ShutdownId(void);
\r
93 static char buf[32];
\r
94 static WindowRec wr;
\r
104 s = "Device Error";
\r
107 if ((dival & 0x00ff) == 0)
\r
108 s = "Drive ~ is Write Protected";
\r
110 s = "Error on Drive ~";
\r
111 for (t = buf;*s;s++,t++) // Can't use sprintf()
\r
112 if ((*t = *s) == '~')
\r
113 *t = (ax & 0x00ff) + 'A';
\r
118 c = peekb(0x40,0x49); // Get the current screen mode
\r
119 if ((c < 4) || (c == 7))
\r
122 // DEBUG - handle screen cleanup
\r
124 US_SaveWindow(&wr);
\r
125 US_CenterWindow(30,3);
\r
127 US_CPrint("(R)etry or (A)bort?");
\r
128 //++++VW_UpdateScreen();
\r
129 IN_ClearKeysDown();
\r
131 __asm sti // Let the keyboard interrupts come through
\r
135 switch (IN_WaitForASCII())
\r
147 //++++VW_UpdateScreen();
\r
148 US_RestoreWindow(&wr);
\r
157 fprintf(stderr,"Terminal Error: %s\n",s);
\r
159 fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
\r
170 ///////////////////////////////////////////////////////////////////////////
\r
172 // US_Startup() - Starts the User Mgr
\r
174 ///////////////////////////////////////////////////////////////////////////
\r
183 //++++_harderr(USL_HardError); // Install the fatal error handler
\r
185 US_InitRndT(true); // Initialize the random number generator
\r
187 for (i = 1;i < _argc;i++)
\r
189 switch (US_CheckParm(_argv[i],ParmStrings2))
\r
192 compatability = true;
\r
195 compatability = false;
\r
200 // Check for TED launching here
\r
201 for (i = 1;i < _argc;i++)
\r
203 n = US_CheckParm(_argv[i],ParmStrings);
\r
207 tedlevelnum = atoi(_argv[i + 1]);
\r
208 if (tedlevelnum >= 0)
\r
222 ///////////////////////////////////////////////////////////////////////////
\r
224 // US_Shutdown() - Shuts down the User Mgr
\r
226 ///////////////////////////////////////////////////////////////////////////
\r
233 US_Started = false;
\r
236 ///////////////////////////////////////////////////////////////////////////
\r
238 // US_CheckParm() - checks to see if a string matches one of a set of
\r
239 // strings. The check is case insensitive. The routine returns the
\r
240 // index of the string that matched, or -1 if no matches were found
\r
242 ///////////////////////////////////////////////////////////////////////////
\r
244 US_CheckParm(char *parm,char **strings)
\r
250 while (!isalpha(*parm)) // Skip non-alphas
\r
253 for (i = 0;*strings && **strings;i++)
\r
255 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
\r
272 // Window/Printing routines
\r
274 ///////////////////////////////////////////////////////////////////////////
\r
276 // US_SetPrintRoutines() - Sets the routines used to measure and print
\r
277 // from within the User Mgr. Primarily provided to allow switching
\r
278 // between masked and non-masked fonts
\r
280 ///////////////////////////////////////////////////////////////////////////
\r
282 US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
\r
284 USL_MeasureString = measure;
\r
285 USL_DrawString = print;
\r
288 ///////////////////////////////////////////////////////////////////////////
\r
290 // US_Print() - Prints a string in the current window. Newlines are
\r
293 ///////////////////////////////////////////////////////////////////////////
\r
295 US_Print(char far *s)
\r
303 while ((c = *se) && (c != '\n'))
\r
307 USL_MeasureString(s,&w,&h);
\r
326 ///////////////////////////////////////////////////////////////////////////
\r
328 // US_PrintUnsigned() - Prints an unsigned long
\r
330 ///////////////////////////////////////////////////////////////////////////
\r
332 US_PrintUnsigned(word n)
\r
336 US_Print(ultoa(n,buffer,10));
\r
339 ///////////////////////////////////////////////////////////////////////////
\r
341 // US_PrintSigned() - Prints a signed long
\r
343 ///////////////////////////////////////////////////////////////////////////
\r
345 US_PrintSigned(long n)
\r
349 US_Print(ltoa(n,buffer,10));
\r
352 ///////////////////////////////////////////////////////////////////////////
\r
354 // USL_PrintInCenter() - Prints a string in the center of the given rect
\r
356 ///////////////////////////////////////////////////////////////////////////
\r
358 USL_PrintInCenter(char far *s,Rect r)
\r
363 USL_MeasureString(s,&w,&h);
\r
364 rw = r.lr.x - r.ul.x;
\r
365 rh = r.lr.y - r.ul.y;
\r
367 px = r.ul.x + ((rw - w) / 2);
\r
368 py = r.ul.y + ((rh - h) / 2);
\r
372 ///////////////////////////////////////////////////////////////////////////
\r
374 // US_PrintCentered() - Prints a string centered in the current window.
\r
376 ///////////////////////////////////////////////////////////////////////////
\r
378 US_PrintCentered(char far *s)
\r
384 r.lr.x = r.ul.x + WindowW;
\r
385 r.lr.y = r.ul.y + WindowH;
\r
387 USL_PrintInCenter(s,r);
\r
390 ///////////////////////////////////////////////////////////////////////////
\r
392 // US_CPrintLine() - Prints a string centered on the current line and
\r
393 // advances to the next line. Newlines are not supported.
\r
395 ///////////////////////////////////////////////////////////////////////////
\r
397 US_CPrintLine(char far *s)
\r
401 USL_MeasureString(s,&w,&h);
\r
404 Quit("US_CPrintLine() - String exceeds width");
\r
405 px = WindowX + ((WindowW - w) / 2);
\r
411 ///////////////////////////////////////////////////////////////////////////
\r
413 // US_CPrint() - Prints a string in the current window. Newlines are
\r
416 ///////////////////////////////////////////////////////////////////////////
\r
418 US_CPrint(char far *s)
\r
425 while ((c = *se) && (c != '\n'))
\r
440 ///////////////////////////////////////////////////////////////////////////
\r
442 // US_ClearWindow() - Clears the current window to white and homes the
\r
445 ///////////////////////////////////////////////////////////////////////////
\r
447 US_ClearWindow(void)
\r
449 VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
\r
454 ///////////////////////////////////////////////////////////////////////////
\r
456 // US_DrawWindow() - Draws a frame and sets the current window parms
\r
458 ///////////////////////////////////////////////////////////////////////////
\r
460 US_DrawWindow(word x,word y,word w,word h)
\r
480 VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
\r
481 for (i = sx + 8;i <= sx + sw - 8;i += 8)
\r
482 VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
\r
483 VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
\r
485 for (i = sy + 8;i <= sy + sh - 8;i += 8)
\r
486 VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
\r
489 ///////////////////////////////////////////////////////////////////////////
\r
491 // US_CenterWindow() - Generates a window of a given width & height in the
\r
492 // middle of the screen
\r
494 ///////////////////////////////////////////////////////////////////////////
\r
496 US_CenterWindow(word w,word h)
\r
498 US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
\r
501 ///////////////////////////////////////////////////////////////////////////
\r
503 // US_SaveWindow() - Saves the current window parms into a record for
\r
504 // later restoration
\r
506 ///////////////////////////////////////////////////////////////////////////
\r
508 US_SaveWindow(WindowRec *win)
\r
519 ///////////////////////////////////////////////////////////////////////////
\r
521 // US_RestoreWindow() - Sets the current window parms to those held in the
\r
524 ///////////////////////////////////////////////////////////////////////////
\r
526 US_RestoreWindow(WindowRec *win)
\r
539 ///////////////////////////////////////////////////////////////////////////
\r
541 // USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
\r
543 ///////////////////////////////////////////////////////////////////////////
\r
545 USL_XORICursor(int x,int y,char *s,word cursor)
\r
547 static boolean status; // VGA doesn't XOR...
\r
548 char buf[MaxString];
\r
553 buf[cursor] = '\0';
\r
554 USL_MeasureString(buf,&w,&h);
\r
559 USL_DrawString("\x80");
\r
563 fontcolor = backcolor;
\r
564 USL_DrawString("\x80");
\r
570 ///////////////////////////////////////////////////////////////////////////
\r
572 // US_LineInput() - Gets a line of user input at (x,y), the string defaults
\r
573 // to whatever is pointed at by def. Input is restricted to maxchars
\r
574 // chars or maxwidth pixels wide. If the user hits escape (and escok is
\r
575 // true), nothing is copied into buf, and false is returned. If the
\r
576 // user hits return, the current string is copied into buf, and true is
\r
579 ///////////////////////////////////////////////////////////////////////////
\r
581 US_LineInput(int x,int y,char *buf,char *def,boolean escok,
\r
582 int maxchars,int maxwidth)
\r
585 cursorvis,cursormoved,
\r
589 s[MaxString],olds[MaxString];
\r
595 word TimeCount = *clockw;
\r
602 cursor = strlen(s);
\r
603 cursormoved = redraw = true;
\r
605 cursorvis = done = false;
\r
606 lasttime = TimeCount;
\r
607 LastASCII = key_None;
\r
608 LastScan = sc_None;
\r
613 USL_XORICursor(x,y,s,cursor);
\r
619 LastScan = sc_None;
\r
621 LastASCII = key_None;
\r
631 cursormoved = true;
\r
633 case sc_RightArrow:
\r
637 cursormoved = true;
\r
642 cursormoved = true;
\r
645 cursor = strlen(s);
\r
647 cursormoved = true;
\r
668 strcpy(s + cursor - 1,s + cursor);
\r
673 cursormoved = true;
\r
678 strcpy(s + cursor,s + cursor + 1);
\r
682 cursormoved = true;
\r
685 case 0x4c: // Keypad 5
\r
698 USL_MeasureString(s,&w,&h);
\r
703 && (len < MaxString - 1)
\r
704 && ((!maxchars) || (len < maxchars))
\r
705 && ((!maxwidth) || (w < maxwidth))
\r
708 for (i = len + 1;i > cursor;i--)
\r
720 fontcolor = backcolor;
\r
721 USL_DrawString(olds);
\r
735 lasttime = TimeCount - TickBase;
\r
737 cursormoved = false;
\r
739 if (TimeCount - lasttime > TickBase / 2)
\r
741 lasttime = TimeCount;
\r
746 USL_XORICursor(x,y,s,cursor);
\r
748 //++++VW_UpdateScreen();
\r
752 USL_XORICursor(x,y,s,cursor);
\r
757 USL_DrawString(olds);
\r
759 //++++VW_UpdateScreen();
\r
761 IN_ClearKeysDown();
\r
767 #define PaddleMinX (CtlPanelSX + 3)
\r
768 #define PaddleMaxX (CtlPanelEX - 15)
\r
769 #define BallMinX (CtlPanelSX + 2)
\r
770 #define BallMinY (CtlPanelSY + 12 + 2)
\r
771 #define BallMaxX (CtlPanelEX - 6)
\r
772 #define BallMaxY (CtlPanelEY - 13)
\r
773 #define CPaddleY (BallMinY + 4)
\r
774 #define KPaddleY (BallMaxY - 2)
\r
776 USL_DrawPongScore(word k,word c)
\r
778 fontcolor = HiliteColor;
\r
779 PrintY = py = CtlPanelSY + 4;
\r
780 px = CtlPanelSX + 6;
\r
781 VWB_Bar(px,py,42,6,BackColor);
\r
782 USL_DrawString("YOU:");
\r
784 US_PrintUnsigned(k);
\r
785 px = CtlPanelSX + 108;
\r
786 VWB_Bar(px,py,50,6,BackColor);
\r
787 USL_DrawString("COMP:");
\r
789 US_PrintUnsigned(c);
\r
795 boolean ball,killball,revdir,done,lastscore;
\r
804 word balltime,waittime;
\r
805 CursorInfo cursorinfo;
\r
807 kx = cx = PaddleMinX + ((PaddleMaxX - PaddleMinX) / 2);
\r
808 bx = by = bdx = bdy = 0;
\r
809 kscore = cscore = 0;
\r
810 USL_DrawPongScore(0,0);
\r
818 waittime = TimeCount;
\r
820 IN_ReadCursor(&cursorinfo);
\r
821 if (((cursorinfo.x < 0) || IN_KeyDown(sc_LeftArrow)) && (kx > PaddleMinX))
\r
823 else if (((cursorinfo.x > 0) || IN_KeyDown(sc_RightArrow)) && (kx < PaddleMaxX))
\r
829 balltime = TimeCount + TickBase;
\r
834 if (ball && (cycle++ % 3))
\r
838 x += (US_RndT() & 1);
\r
840 if ((cx + 6 < x) && (cx < PaddleMaxX))
\r
842 else if ((cx + 6 > x) && (cx > PaddleMinX))
\r
846 VWB_Bar(BallMinX,BallMinY - 1,
\r
847 BallMaxX - BallMinX + 5,BallMaxY - BallMinY + 7,
\r
849 VWB_DrawSprite(cx,CPaddleY,PADDLESPR);
\r
850 VWB_DrawSprite(kx,KPaddleY,PADDLESPR);
\r
855 (((bx + bdx) >> 2) > BallMaxX)
\r
856 || (((bx + bdx) >> 2) < BallMinX)
\r
859 SD_PlaySound(BALLBOUNCESND);
\r
864 if (((by + bdy) >> 2) > BallMaxY)
\r
869 SD_PlaySound(COMPSCOREDSND);
\r
870 USL_DrawPongScore(kscore,cscore);
\r
873 USL_CtlDialog("You lost!","Press any key",nil);
\r
878 else if (((by + bdy) >> 2) < BallMinY)
\r
883 SD_PlaySound(KEENSCOREDSND);
\r
884 USL_DrawPongScore(kscore,cscore);
\r
887 USL_CtlDialog("You won!","Press any key",nil);
\r
901 && ((y >= CPaddleY) && (y < CPaddleY + 3))
\r
902 && ((x >= (cx - 5)) && (x < (cx + 11)))
\r
907 SD_PlaySound(COMPPADDLESND);
\r
912 && ((y >= (KPaddleY - 3)) && (y < KPaddleY))
\r
913 && ((x >= (kx - 5)) && (x < (kx + 11)))
\r
916 if (((bdy >> 2) < 3) && !(--speedup))
\r
923 SD_PlaySound(KEENPADDLESND);
\r
928 bdx = ((x + 5 - rx) >> 1) - (1 << 2);
\r
934 VWB_DrawSprite(x,y,(x & 1)? BALL1PIXELTOTHERIGHTSPR : BALLSPR);
\r
936 else if (TimeCount >= balltime)
\r
939 bdx = 1 - (US_RndT() % 3);
\r
943 bx = (BallMinX + ((BallMaxX - BallMinX) / 2)) << 2;
\r
944 by = (BallMinY + ((BallMaxY - BallMinY) / 2)) << 2;
\r
946 //++++VW_UpdateScreen();
\r
947 while (waittime == TimeCount)
\r
948 ; // DEBUG - do adaptiveness
\r
949 } while ((LastScan != sc_Escape) && !done);
\r
950 IN_ClearKeysDown();
\r
955 USL_PongCustom(UserCall call,struct UserItem far *item)
\r
957 if (call != uic_SetupCard)
\r
960 VWB_DrawPic(0,0,CP_MENUSCREENPIC);
\r
961 VWB_DrawPic(CtlPanelSX + 56,CtlPanelSY,CP_PADDLEWARPIC);
\r
962 VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelSY + 12,HiliteColor ^ BackColor);
\r
963 VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelEY - 7,HiliteColor ^ BackColor);
\r