]> 4ch.mooo.com Git - 16.git/blobdiff - 16/wf3d8086/id_us_1.c
wolf3d 8088 port by king crimsom is added to 16/
[16.git] / 16 / wf3d8086 / id_us_1.c
diff --git a/16/wf3d8086/id_us_1.c b/16/wf3d8086/id_us_1.c
new file mode 100755 (executable)
index 0000000..c06e4ed
--- /dev/null
@@ -0,0 +1,755 @@
+//\r
+//     ID Engine\r
+//     ID_US_1.c - User Manager - General routines\r
+//     v1.1d1\r
+//     By Jason Blochowiak\r
+//     Hacked up for Catacomb 3D\r
+//\r
+\r
+//\r
+//     This module handles dealing with user input & feedback\r
+//\r
+//     Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,\r
+//             and Refresh Mgrs, Memory Mgr for background save/restore\r
+//\r
+//     Globals:\r
+//             ingame - Flag set by game indicating if a game is in progress\r
+//      abortgame - Flag set if the current game should be aborted (if a load\r
+//                     game fails)\r
+//             loadedgame - Flag set if a game was loaded\r
+//             abortprogram - Normally nil, this points to a terminal error message\r
+//                     if the program needs to abort\r
+//             restartgame - Normally set to gd_Continue, this is set to one of the\r
+//                     difficulty levels if a new game should be started\r
+//             PrintX, PrintY - Where the User Mgr will print (global coords)\r
+//             WindowX,WindowY,WindowW,WindowH - The dimensions of the current\r
+//                     window\r
+//\r
+\r
+#include "ID_HEADS.H"\r
+\r
+#pragma        hdrstop\r
+\r
+#pragma        warn    -pia\r
+\r
+\r
+//     Global variables\r
+               char            *abortprogram;\r
+               boolean         NoWait;\r
+               word            PrintX,PrintY;\r
+               word            WindowX,WindowY,WindowW,WindowH;\r
+\r
+//     Internal variables\r
+#define        ConfigVersion   1\r
+\r
+static char            *ParmStrings[] = {"TEDLEVEL","NOWAIT"},\r
+                                       *ParmStrings2[] = {"COMP","NOCOMP"};\r
+static boolean         US_Started;\r
+\r
+               boolean         Button0,Button1,\r
+                                       CursorBad;\r
+               int                     CursorX,CursorY;\r
+\r
+               void            (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,\r
+                                       (*USL_DrawString)(char far *) = VWB_DrawPropString;\r
+\r
+               SaveGame        Games[MaxSaveGames];\r
+               HighScore       Scores[MaxScores] =\r
+                                       {\r
+                                               {"id software-'92",10000,1},\r
+                                               {"Adrian Carmack",10000,1},\r
+                                               {"John Carmack",10000,1},\r
+                                               {"Kevin Cloud",10000,1},\r
+                                               {"Tom Hall",10000,1},\r
+                                               {"John Romero",10000,1},\r
+                                               {"Jay Wilbur",10000,1},\r
+                                       };\r
+\r
+//     Internal routines\r
+\r
+//     Public routines\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed\r
+//                     from DOS.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#pragma        warn    -par\r
+#pragma        warn    -rch\r
+int\r
+USL_HardError(word errval,int ax,int bp,int si)\r
+{\r
+#define IGNORE  0\r
+#define RETRY   1\r
+#define        ABORT   2\r
+extern void    ShutdownId(void);\r
+\r
+static char            buf[32];\r
+static WindowRec       wr;\r
+               int                     di;\r
+               char            c,*s,*t;\r
+\r
+\r
+       di = _DI;\r
+\r
+       if (ax < 0)\r
+               s = "Device Error";\r
+       else\r
+       {\r
+               if ((di & 0x00ff) == 0)\r
+                       s = "Drive ~ is Write Protected";\r
+               else\r
+                       s = "Error on Drive ~";\r
+               for (t = buf;*s;s++,t++)        // Can't use sprintf()\r
+                       if ((*t = *s) == '~')\r
+                               *t = (ax & 0x00ff) + 'A';\r
+               *t = '\0';\r
+               s = buf;\r
+       }\r
+\r
+       c = peekb(0x40,0x49);   // Get the current screen mode\r
+       if ((c < 4) || (c == 7))\r
+               goto oh_kill_me;\r
+\r
+       // DEBUG - handle screen cleanup\r
+\r
+       US_SaveWindow(&wr);\r
+       US_CenterWindow(30,3);\r
+       US_CPrint(s);\r
+       US_CPrint("(R)etry or (A)bort?");\r
+       VW_UpdateScreen();\r
+       IN_ClearKeysDown();\r
+\r
+asm    sti     // Let the keyboard interrupts come through\r
+\r
+       while (true)\r
+       {\r
+               switch (IN_WaitForASCII())\r
+               {\r
+               case key_Escape:\r
+               case 'a':\r
+               case 'A':\r
+                       goto oh_kill_me;\r
+                       break;\r
+               case key_Return:\r
+               case key_Space:\r
+               case 'r':\r
+               case 'R':\r
+                       US_ClearWindow();\r
+                       VW_UpdateScreen();\r
+                       US_RestoreWindow(&wr);\r
+                       return(RETRY);\r
+                       break;\r
+               }\r
+       }\r
+\r
+oh_kill_me:\r
+       abortprogram = s;\r
+       ShutdownId();\r
+       fprintf(stderr,"Terminal Error: %s\n",s);\r
+       if (tedlevel)\r
+               fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");\r
+\r
+       return(ABORT);\r
+#undef IGNORE\r
+#undef RETRY\r
+#undef ABORT\r
+}\r
+#pragma        warn    +par\r
+#pragma        warn    +rch\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_Startup() - Starts the User Mgr\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_Startup(void)\r
+{\r
+       int     i,n;\r
+\r
+       if (US_Started)\r
+               return;\r
+\r
+       harderr(USL_HardError); // Install the fatal error handler\r
+\r
+       US_InitRndT(true);              // Initialize the random number generator\r
+\r
+       for (i = 1;i < _argc;i++)\r
+       {\r
+               switch (US_CheckParm(_argv[i],ParmStrings2))\r
+               {\r
+               case 0:\r
+                       compatability = true;\r
+                       break;\r
+               case 1:\r
+                       compatability = false;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       // Check for TED launching here\r
+       for (i = 1;i < _argc;i++)\r
+       {\r
+               n = US_CheckParm(_argv[i],ParmStrings);\r
+               switch(n)\r
+               {\r
+                case 0:\r
+                  tedlevelnum = atoi(_argv[i + 1]);\r
+                  if (tedlevelnum >= 0)\r
+                    tedlevel = true;\r
+                  break;\r
+\r
+                case 1:\r
+                  NoWait = true;\r
+                  break;\r
+               }\r
+       }\r
+\r
+       US_Started = true;\r
+}\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_Shutdown() - Shuts down the User Mgr\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_Shutdown(void)\r
+{\r
+       if (!US_Started)\r
+               return;\r
+\r
+       US_Started = false;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_CheckParm() - checks to see if a string matches one of a set of\r
+//             strings. The check is case insensitive. The routine returns the\r
+//             index of the string that matched, or -1 if no matches were found\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+int\r
+US_CheckParm(char *parm,char **strings)\r
+{\r
+       char    cp,cs,\r
+                       *p,*s;\r
+       int             i;\r
+\r
+       while (!isalpha(*parm)) // Skip non-alphas\r
+               parm++;\r
+\r
+       for (i = 0;*strings && **strings;i++)\r
+       {\r
+               for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)\r
+               {\r
+                       cs = *s++;\r
+                       if (!cs)\r
+                               return(i);\r
+                       cp = *p++;\r
+\r
+                       if (isupper(cs))\r
+                               cs = tolower(cs);\r
+                       if (isupper(cp))\r
+                               cp = tolower(cp);\r
+               }\r
+       }\r
+       return(-1);\r
+}\r
+\r
+\r
+//     Window/Printing routines\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_SetPrintRoutines() - Sets the routines used to measure and print\r
+//             from within the User Mgr. Primarily provided to allow switching\r
+//             between masked and non-masked fonts\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))\r
+{\r
+       USL_MeasureString = measure;\r
+       USL_DrawString = print;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_Print() - Prints a string in the current window. Newlines are\r
+//             supported.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_Print(char far *s)\r
+{\r
+       char    c,far *se;\r
+       word    w,h;\r
+\r
+       while (*s)\r
+       {\r
+               se = s;\r
+               while ((c = *se) && (c != '\n'))\r
+                       se++;\r
+               *se = '\0';\r
+\r
+               USL_MeasureString(s,&w,&h);\r
+               px = PrintX;\r
+               py = PrintY;\r
+               USL_DrawString(s);\r
+\r
+               s = se;\r
+               if (c)\r
+               {\r
+                       *se = c;\r
+                       s++;\r
+\r
+                       PrintX = WindowX;\r
+                       PrintY += h;\r
+               }\r
+               else\r
+                       PrintX += w;\r
+       }\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_PrintUnsigned() - Prints an unsigned long\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_PrintUnsigned(longword n)\r
+{\r
+       char    buffer[32];\r
+\r
+       US_Print(ultoa(n,buffer,10));\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_PrintSigned() - Prints a signed long\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_PrintSigned(long n)\r
+{\r
+       char    buffer[32];\r
+\r
+       US_Print(ltoa(n,buffer,10));\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     USL_PrintInCenter() - Prints a string in the center of the given rect\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+USL_PrintInCenter(char far *s,Rect r)\r
+{\r
+       word    w,h,\r
+                       rw,rh;\r
+\r
+       USL_MeasureString(s,&w,&h);\r
+       rw = r.lr.x - r.ul.x;\r
+       rh = r.lr.y - r.ul.y;\r
+\r
+       px = r.ul.x + ((rw - w) / 2);\r
+       py = r.ul.y + ((rh - h) / 2);\r
+       USL_DrawString(s);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_PrintCentered() - Prints a string centered in the current window.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_PrintCentered(char far *s)\r
+{\r
+       Rect    r;\r
+\r
+       r.ul.x = WindowX;\r
+       r.ul.y = WindowY;\r
+       r.lr.x = r.ul.x + WindowW;\r
+       r.lr.y = r.ul.y + WindowH;\r
+\r
+       USL_PrintInCenter(s,r);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_CPrintLine() - Prints a string centered on the current line and\r
+//             advances to the next line. Newlines are not supported.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_CPrintLine(char far *s)\r
+{\r
+       word    w,h;\r
+\r
+       USL_MeasureString(s,&w,&h);\r
+\r
+       if (w > WindowW)\r
+               Quit("US_CPrintLine() - String exceeds width");\r
+       px = WindowX + ((WindowW - w) / 2);\r
+       py = PrintY;\r
+       USL_DrawString(s);\r
+       PrintY += h;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_CPrint() - Prints a string in the current window. Newlines are\r
+//             supported.\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_CPrint(char far *s)\r
+{\r
+       char    c,far *se;\r
+\r
+       while (*s)\r
+       {\r
+               se = s;\r
+               while ((c = *se) && (c != '\n'))\r
+                       se++;\r
+               *se = '\0';\r
+\r
+               US_CPrintLine(s);\r
+\r
+               s = se;\r
+               if (c)\r
+               {\r
+                       *se = c;\r
+                       s++;\r
+               }\r
+       }\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_ClearWindow() - Clears the current window to white and homes the\r
+//             cursor\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_ClearWindow(void)\r
+{\r
+       VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);\r
+       PrintX = WindowX;\r
+       PrintY = WindowY;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_DrawWindow() - Draws a frame and sets the current window parms\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_DrawWindow(word x,word y,word w,word h)\r
+{\r
+       word    i,\r
+                       sx,sy,sw,sh;\r
+\r
+       WindowX = x * 8;\r
+       WindowY = y * 8;\r
+       WindowW = w * 8;\r
+       WindowH = h * 8;\r
+\r
+       PrintX = WindowX;\r
+       PrintY = WindowY;\r
+\r
+       sx = (x - 1) * 8;\r
+       sy = (y - 1) * 8;\r
+       sw = (w + 1) * 8;\r
+       sh = (h + 1) * 8;\r
+\r
+       US_ClearWindow();\r
+\r
+       VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);\r
+       for (i = sx + 8;i <= sx + sw - 8;i += 8)\r
+               VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);\r
+       VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);\r
+\r
+       for (i = sy + 8;i <= sy + sh - 8;i += 8)\r
+               VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_CenterWindow() - Generates a window of a given width & height in the\r
+//             middle of the screen\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_CenterWindow(word w,word h)\r
+{\r
+       US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_SaveWindow() - Saves the current window parms into a record for\r
+//             later restoration\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_SaveWindow(WindowRec *win)\r
+{\r
+       win->x = WindowX;\r
+       win->y = WindowY;\r
+       win->w = WindowW;\r
+       win->h = WindowH;\r
+\r
+       win->px = PrintX;\r
+       win->py = PrintY;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_RestoreWindow() - Sets the current window parms to those held in the\r
+//             record\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+void\r
+US_RestoreWindow(WindowRec *win)\r
+{\r
+       WindowX = win->x;\r
+       WindowY = win->y;\r
+       WindowW = win->w;\r
+       WindowH = win->h;\r
+\r
+       PrintX = win->px;\r
+       PrintY = win->py;\r
+}\r
+\r
+//     Input routines\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+static void\r
+USL_XORICursor(int x,int y,char *s,word cursor)\r
+{\r
+       static  boolean status;         // VGA doesn't XOR...\r
+       char    buf[MaxString];\r
+       int             temp;\r
+       word    w,h;\r
+\r
+       strcpy(buf,s);\r
+       buf[cursor] = '\0';\r
+       USL_MeasureString(buf,&w,&h);\r
+\r
+       px = x + w - 1;\r
+       py = y;\r
+       if (status^=1)\r
+               USL_DrawString("\x80");\r
+       else\r
+       {\r
+               temp = fontcolor;\r
+               fontcolor = backcolor;\r
+               USL_DrawString("\x80");\r
+               fontcolor = temp;\r
+       }\r
+\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+//     US_LineInput() - Gets a line of user input at (x,y), the string defaults\r
+//             to whatever is pointed at by def. Input is restricted to maxchars\r
+//             chars or maxwidth pixels wide. If the user hits escape (and escok is\r
+//             true), nothing is copied into buf, and false is returned. If the\r
+//             user hits return, the current string is copied into buf, and true is\r
+//             returned\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+boolean\r
+US_LineInput(int x,int y,char *buf,char *def,boolean escok,\r
+                               int maxchars,int maxwidth)\r
+{\r
+       boolean         redraw,\r
+                               cursorvis,cursormoved,\r
+                               done,result;\r
+       ScanCode        sc;\r
+       char            c,\r
+                               s[MaxString],olds[MaxString];\r
+       word            i,\r
+                               cursor,\r
+                               w,h,\r
+                               len,temp;\r
+       longword        lasttime;\r
+\r
+       if (def)\r
+               strcpy(s,def);\r
+       else\r
+               *s = '\0';\r
+       *olds = '\0';\r
+       cursor = strlen(s);\r
+       cursormoved = redraw = true;\r
+\r
+       cursorvis = done = false;\r
+       lasttime = TimeCount;\r
+       LastASCII = key_None;\r
+       LastScan = sc_None;\r
+\r
+       while (!done)\r
+       {\r
+               if (cursorvis)\r
+                       USL_XORICursor(x,y,s,cursor);\r
+\r
+       asm     pushf\r
+       asm     cli\r
+\r
+               sc = LastScan;\r
+               LastScan = sc_None;\r
+               c = LastASCII;\r
+               LastASCII = key_None;\r
+\r
+       asm     popf\r
+\r
+               switch (sc)\r
+               {\r
+               case sc_LeftArrow:\r
+                       if (cursor)\r
+                               cursor--;\r
+                       c = key_None;\r
+                       cursormoved = true;\r
+                       break;\r
+               case sc_RightArrow:\r
+                       if (s[cursor])\r
+                               cursor++;\r
+                       c = key_None;\r
+                       cursormoved = true;\r
+                       break;\r
+               case sc_Home:\r
+                       cursor = 0;\r
+                       c = key_None;\r
+                       cursormoved = true;\r
+                       break;\r
+               case sc_End:\r
+                       cursor = strlen(s);\r
+                       c = key_None;\r
+                       cursormoved = true;\r
+                       break;\r
+\r
+               case sc_Return:\r
+                       strcpy(buf,s);\r
+                       done = true;\r
+                       result = true;\r
+                       c = key_None;\r
+                       break;\r
+               case sc_Escape:\r
+                       if (escok)\r
+                       {\r
+                               done = true;\r
+                               result = false;\r
+                       }\r
+                       c = key_None;\r
+                       break;\r
+\r
+               case sc_BackSpace:\r
+                       if (cursor)\r
+                       {\r
+                               strcpy(s + cursor - 1,s + cursor);\r
+                               cursor--;\r
+                               redraw = true;\r
+                       }\r
+                       c = key_None;\r
+                       cursormoved = true;\r
+                       break;\r
+               case sc_Delete:\r
+                       if (s[cursor])\r
+                       {\r
+                               strcpy(s + cursor,s + cursor + 1);\r
+                               redraw = true;\r
+                       }\r
+                       c = key_None;\r
+                       cursormoved = true;\r
+                       break;\r
+\r
+               case 0x4c:      // Keypad 5\r
+               case sc_UpArrow:\r
+               case sc_DownArrow:\r
+               case sc_PgUp:\r
+               case sc_PgDn:\r
+               case sc_Insert:\r
+                       c = key_None;\r
+                       break;\r
+               }\r
+\r
+               if (c)\r
+               {\r
+                       len = strlen(s);\r
+                       USL_MeasureString(s,&w,&h);\r
+\r
+                       if\r
+                       (\r
+                               isprint(c)\r
+                       &&      (len < MaxString - 1)\r
+                       &&      ((!maxchars) || (len < maxchars))\r
+                       &&      ((!maxwidth) || (w < maxwidth))\r
+                       )\r
+                       {\r
+                               for (i = len + 1;i > cursor;i--)\r
+                                       s[i] = s[i - 1];\r
+                               s[cursor++] = c;\r
+                               redraw = true;\r
+                       }\r
+               }\r
+\r
+               if (redraw)\r
+               {\r
+                       px = x;\r
+                       py = y;\r
+                       temp = fontcolor;\r
+                       fontcolor = backcolor;\r
+                       USL_DrawString(olds);\r
+                       fontcolor = temp;\r
+                       strcpy(olds,s);\r
+\r
+                       px = x;\r
+                       py = y;\r
+                       USL_DrawString(s);\r
+\r
+                       redraw = false;\r
+               }\r
+\r
+               if (cursormoved)\r
+               {\r
+                       cursorvis = false;\r
+                       lasttime = TimeCount - TickBase;\r
+\r
+                       cursormoved = false;\r
+               }\r
+               if (TimeCount - lasttime > TickBase / 2)\r
+               {\r
+                       lasttime = TimeCount;\r
+\r
+                       cursorvis ^= true;\r
+               }\r
+               if (cursorvis)\r
+                       USL_XORICursor(x,y,s,cursor);\r
+\r
+               VW_UpdateScreen();\r
+       }\r
+\r
+       if (cursorvis)\r
+               USL_XORICursor(x,y,s,cursor);\r
+       if (!result)\r
+       {\r
+               px = x;\r
+               py = y;\r
+               USL_DrawString(olds);\r
+       }\r
+       VW_UpdateScreen();\r
+\r
+       IN_ClearKeysDown();\r
+       return(result);\r
+}\r