home *** CD-ROM | disk | FTP | other *** search
/ 100 af Verdens Bedste Spil / 100Spil.iso / dos / wolf3d / source / wolfsrc.1 / ID_US_1.C < prev    next >
C/C++ Source or Header  |  1993-02-04  |  16KB  |  756 lines

  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. //      abortgame - Flag set if the current game should be aborted (if a load
  18. //            game fails)
  19. //        loadedgame - Flag set if a game was loaded
  20. //        abortprogram - Normally nil, this points to a terminal error message
  21. //            if the program needs to abort
  22. //        restartgame - Normally set to gd_Continue, this is set to one of the
  23. //            difficulty levels if a new game should be started
  24. //        PrintX, PrintY - Where the User Mgr will print (global coords)
  25. //        WindowX,WindowY,WindowW,WindowH - The dimensions of the current
  26. //            window
  27. //
  28.  
  29. #include "ID_HEADS.H"
  30.  
  31. #pragma    hdrstop
  32.  
  33. #pragma    warn    -pia
  34.  
  35.  
  36. //    Global variables
  37.         char        *abortprogram;
  38.         boolean        NoWait;
  39.         word        PrintX,PrintY;
  40.         word        WindowX,WindowY,WindowW,WindowH;
  41.  
  42. //    Internal variables
  43. #define    ConfigVersion    1
  44.  
  45. static    char        *ParmStrings[] = {"TEDLEVEL","NOWAIT"},
  46.                     *ParmStrings2[] = {"COMP","NOCOMP"};
  47. static    boolean        US_Started;
  48.  
  49.         boolean        Button0,Button1,
  50.                     CursorBad;
  51.         int            CursorX,CursorY;
  52.  
  53.         void        (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
  54.                     (*USL_DrawString)(char far *) = VWB_DrawPropString;
  55.  
  56.         SaveGame    Games[MaxSaveGames];
  57.         HighScore    Scores[MaxScores] =
  58.                     {
  59.                         {"id software-'92",10000,1},
  60.                         {"Adrian Carmack",10000,1},
  61.                         {"John Carmack",10000,1},
  62.                         {"Kevin Cloud",10000,1},
  63.                         {"Tom Hall",10000,1},
  64.                         {"John Romero",10000,1},
  65.                         {"Jay Wilbur",10000,1},
  66.                     };
  67.  
  68. //    Internal routines
  69.  
  70. //    Public routines
  71.  
  72. ///////////////////////////////////////////////////////////////////////////
  73. //
  74. //    USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
  75. //            from DOS.
  76. //
  77. ///////////////////////////////////////////////////////////////////////////
  78. #pragma    warn    -par
  79. #pragma    warn    -rch
  80. int
  81. USL_HardError(word errval,int ax,int bp,int si)
  82. {
  83. #define IGNORE  0
  84. #define RETRY   1
  85. #define    ABORT   2
  86. extern    void    ShutdownId(void);
  87.  
  88. static    char        buf[32];
  89. static    WindowRec    wr;
  90.         int            di;
  91.         char        c,*s,*t;
  92.  
  93.  
  94.     di = _DI;
  95.  
  96.     if (ax < 0)
  97.         s = "Device Error";
  98.     else
  99.     {
  100.         if ((di & 0x00ff) == 0)
  101.             s = "Drive ~ is Write Protected";
  102.         else
  103.             s = "Error on Drive ~";
  104.         for (t = buf;*s;s++,t++)    // Can't use sprintf()
  105.             if ((*t = *s) == '~')
  106.                 *t = (ax & 0x00ff) + 'A';
  107.         *t = '\0';
  108.         s = buf;
  109.     }
  110.  
  111.     c = peekb(0x40,0x49);    // Get the current screen mode
  112.     if ((c < 4) || (c == 7))
  113.         goto oh_kill_me;
  114.  
  115.     // DEBUG - handle screen cleanup
  116.  
  117.     US_SaveWindow(&wr);
  118.     US_CenterWindow(30,3);
  119.     US_CPrint(s);
  120.     US_CPrint("(R)etry or (A)bort?");
  121.     VW_UpdateScreen();
  122.     IN_ClearKeysDown();
  123.  
  124. asm    sti    // Let the keyboard interrupts come through
  125.  
  126.     while (true)
  127.     {
  128.         switch (IN_WaitForASCII())
  129.         {
  130.         case key_Escape:
  131.         case 'a':
  132.         case 'A':
  133.             goto oh_kill_me;
  134.             break;
  135.         case key_Return:
  136.         case key_Space:
  137.         case 'r':
  138.         case 'R':
  139.             US_ClearWindow();
  140.             VW_UpdateScreen();
  141.             US_RestoreWindow(&wr);
  142.             return(RETRY);
  143.             break;
  144.         }
  145.     }
  146.  
  147. oh_kill_me:
  148.     abortprogram = s;
  149.     ShutdownId();
  150.     fprintf(stderr,"Terminal Error: %s\n",s);
  151.     if (tedlevel)
  152.         fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
  153.  
  154.     return(ABORT);
  155. #undef    IGNORE
  156. #undef    RETRY
  157. #undef    ABORT
  158. }
  159. #pragma    warn    +par
  160. #pragma    warn    +rch
  161.  
  162.  
  163. ///////////////////////////////////////////////////////////////////////////
  164. //
  165. //    US_Startup() - Starts the User Mgr
  166. //
  167. ///////////////////////////////////////////////////////////////////////////
  168. void
  169. US_Startup(void)
  170. {
  171.     int    i,n;
  172.  
  173.     if (US_Started)
  174.         return;
  175.  
  176.     harderr(USL_HardError);    // Install the fatal error handler
  177.  
  178.     US_InitRndT(true);        // Initialize the random number generator
  179.  
  180.     for (i = 1;i < _argc;i++)
  181.     {
  182.         switch (US_CheckParm(_argv[i],ParmStrings2))
  183.         {
  184.         case 0:
  185.             compatability = true;
  186.             break;
  187.         case 1:
  188.             compatability = false;
  189.             break;
  190.         }
  191.     }
  192.  
  193.     // Check for TED launching here
  194.     for (i = 1;i < _argc;i++)
  195.     {
  196.         n = US_CheckParm(_argv[i],ParmStrings);
  197.         switch(n)
  198.         {
  199.          case 0:
  200.            tedlevelnum = atoi(_argv[i + 1]);
  201.            if (tedlevelnum >= 0)
  202.              tedlevel = true;
  203.            break;
  204.  
  205.          case 1:
  206.            NoWait = true;
  207.            break;
  208.         }
  209.     }
  210.  
  211.     US_Started = true;
  212. }
  213.  
  214.  
  215. ///////////////////////////////////////////////////////////////////////////
  216. //
  217. //    US_Shutdown() - Shuts down the User Mgr
  218. //
  219. ///////////////////////////////////////////////////////////////////////////
  220. void
  221. US_Shutdown(void)
  222. {
  223.     if (!US_Started)
  224.         return;
  225.  
  226.     US_Started = false;
  227. }
  228.  
  229. ///////////////////////////////////////////////////////////////////////////
  230. //
  231. //    US_CheckParm() - checks to see if a string matches one of a set of
  232. //        strings. The check is case insensitive. The routine returns the
  233. //        index of the string that matched, or -1 if no matches were found
  234. //
  235. ///////////////////////////////////////////////////////////////////////////
  236. int
  237. US_CheckParm(char *parm,char **strings)
  238. {
  239.     char    cp,cs,
  240.             *p,*s;
  241.     int        i;
  242.  
  243.     while (!isalpha(*parm))    // Skip non-alphas
  244.         parm++;
  245.  
  246.     for (i = 0;*strings && **strings;i++)
  247.     {
  248.         for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
  249.         {
  250.             cs = *s++;
  251.             if (!cs)
  252.                 return(i);
  253.             cp = *p++;
  254.  
  255.             if (isupper(cs))
  256.                 cs = tolower(cs);
  257.             if (isupper(cp))
  258.                 cp = tolower(cp);
  259.         }
  260.     }
  261.     return(-1);
  262. }
  263.  
  264.  
  265. //    Window/Printing routines
  266.  
  267. ///////////////////////////////////////////////////////////////////////////
  268. //
  269. //    US_SetPrintRoutines() - Sets the routines used to measure and print
  270. //        from within the User Mgr. Primarily provided to allow switching
  271. //        between masked and non-masked fonts
  272. //
  273. ///////////////////////////////////////////////////////////////////////////
  274. void
  275. US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
  276. {
  277.     USL_MeasureString = measure;
  278.     USL_DrawString = print;
  279. }
  280.  
  281. ///////////////////////////////////////////////////////////////////////////
  282. //
  283. //    US_Print() - Prints a string in the current window. Newlines are
  284. //        supported.
  285. //
  286. ///////////////////////////////////////////////////////////////////////////
  287. void
  288. US_Print(char far *s)
  289. {
  290.     char    c,far *se;
  291.     word    w,h;
  292.  
  293.     while (*s)
  294.     {
  295.         se = s;
  296.         while ((c = *se) && (c != '\n'))
  297.             se++;
  298.         *se = '\0';
  299.  
  300.         USL_MeasureString(s,&w,&h);
  301.         px = PrintX;
  302.         py = PrintY;
  303.         USL_DrawString(s);
  304.  
  305.         s = se;
  306.         if (c)
  307.         {
  308.             *se = c;
  309.             s++;
  310.  
  311.             PrintX = WindowX;
  312.             PrintY += h;
  313.         }
  314.         else
  315.             PrintX += w;
  316.     }
  317. }
  318.  
  319. ///////////////////////////////////////////////////////////////////////////
  320. //
  321. //    US_PrintUnsigned() - Prints an unsigned long
  322. //
  323. ///////////////////////////////////////////////////////////////////////////
  324. void
  325. US_PrintUnsigned(longword n)
  326. {
  327.     char    buffer[32];
  328.  
  329.     US_Print(ultoa(n,buffer,10));
  330. }
  331.  
  332. ///////////////////////////////////////////////////////////////////////////
  333. //
  334. //    US_PrintSigned() - Prints a signed long
  335. //
  336. ///////////////////////////////////////////////////////////////////////////
  337. void
  338. US_PrintSigned(long n)
  339. {
  340.     char    buffer[32];
  341.  
  342.     US_Print(ltoa(n,buffer,10));
  343. }
  344.  
  345. ///////////////////////////////////////////////////////////////////////////
  346. //
  347. //    USL_PrintInCenter() - Prints a string in the center of the given rect
  348. //
  349. ///////////////////////////////////////////////////////////////////////////
  350. void
  351. USL_PrintInCenter(char far *s,Rect r)
  352. {
  353.     word    w,h,
  354.             rw,rh;
  355.  
  356.     USL_MeasureString(s,&w,&h);
  357.     rw = r.lr.x - r.ul.x;
  358.     rh = r.lr.y - r.ul.y;
  359.  
  360.     px = r.ul.x + ((rw - w) / 2);
  361.     py = r.ul.y + ((rh - h) / 2);
  362.     USL_DrawString(s);
  363. }
  364.  
  365. ///////////////////////////////////////////////////////////////////////////
  366. //
  367. //    US_PrintCentered() - Prints a string centered in the current window.
  368. //
  369. ///////////////////////////////////////////////////////////////////////////
  370. void
  371. US_PrintCentered(char far *s)
  372. {
  373.     Rect    r;
  374.  
  375.     r.ul.x = WindowX;
  376.     r.ul.y = WindowY;
  377.     r.lr.x = r.ul.x + WindowW;
  378.     r.lr.y = r.ul.y + WindowH;
  379.  
  380.     USL_PrintInCenter(s,r);
  381. }
  382.  
  383. ///////////////////////////////////////////////////////////////////////////
  384. //
  385. //    US_CPrintLine() - Prints a string centered on the current line and
  386. //        advances to the next line. Newlines are not supported.
  387. //
  388. ///////////////////////////////////////////////////////////////////////////
  389. void
  390. US_CPrintLine(char far *s)
  391. {
  392.     word    w,h;
  393.  
  394.     USL_MeasureString(s,&w,&h);
  395.  
  396.     if (w > WindowW)
  397.         Quit("US_CPrintLine() - String exceeds width");
  398.     px = WindowX + ((WindowW - w) / 2);
  399.     py = PrintY;
  400.     USL_DrawString(s);
  401.     PrintY += h;
  402. }
  403.  
  404. ///////////////////////////////////////////////////////////////////////////
  405. //
  406. //    US_CPrint() - Prints a string in the current window. Newlines are
  407. //        supported.
  408. //
  409. ///////////////////////////////////////////////////////////////////////////
  410. void
  411. US_CPrint(char far *s)
  412. {
  413.     char    c,far *se;
  414.  
  415.     while (*s)
  416.     {
  417.         se = s;
  418.         while ((c = *se) && (c != '\n'))
  419.             se++;
  420.         *se = '\0';
  421.  
  422.         US_CPrintLine(s);
  423.  
  424.         s = se;
  425.         if (c)
  426.         {
  427.             *se = c;
  428.             s++;
  429.         }
  430.     }
  431. }
  432.  
  433. ///////////////////////////////////////////////////////////////////////////
  434. //
  435. //    US_ClearWindow() - Clears the current window to white and homes the
  436. //        cursor
  437. //
  438. ///////////////////////////////////////////////////////////////////////////
  439. void
  440. US_ClearWindow(void)
  441. {
  442.     VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
  443.     PrintX = WindowX;
  444.     PrintY = WindowY;
  445. }
  446.  
  447. ///////////////////////////////////////////////////////////////////////////
  448. //
  449. //    US_DrawWindow() - Draws a frame and sets the current window parms
  450. //
  451. ///////////////////////////////////////////////////////////////////////////
  452. void
  453. US_DrawWindow(word x,word y,word w,word h)
  454. {
  455.     word    i,
  456.             sx,sy,sw,sh;
  457.  
  458.     WindowX = x * 8;
  459.     WindowY = y * 8;
  460.     WindowW = w * 8;
  461.     WindowH = h * 8;
  462.  
  463.     PrintX = WindowX;
  464.     PrintY = WindowY;
  465.  
  466.     sx = (x - 1) * 8;
  467.     sy = (y - 1) * 8;
  468.     sw = (w + 1) * 8;
  469.     sh = (h + 1) * 8;
  470.  
  471.     US_ClearWindow();
  472.  
  473.     VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);
  474.     for (i = sx + 8;i <= sx + sw - 8;i += 8)
  475.         VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);
  476.     VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);
  477.  
  478.     for (i = sy + 8;i <= sy + sh - 8;i += 8)
  479.         VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);
  480. }
  481.  
  482. ///////////////////////////////////////////////////////////////////////////
  483. //
  484. //    US_CenterWindow() - Generates a window of a given width & height in the
  485. //        middle of the screen
  486. //
  487. ///////////////////////////////////////////////////////////////////////////
  488. void
  489. US_CenterWindow(word w,word h)
  490. {
  491.     US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
  492. }
  493.  
  494. ///////////////////////////////////////////////////////////////////////////
  495. //
  496. //    US_SaveWindow() - Saves the current window parms into a record for
  497. //        later restoration
  498. //
  499. ///////////////////////////////////////////////////////////////////////////
  500. void
  501. US_SaveWindow(WindowRec *win)
  502. {
  503.     win->x = WindowX;
  504.     win->y = WindowY;
  505.     win->w = WindowW;
  506.     win->h = WindowH;
  507.  
  508.     win->px = PrintX;
  509.     win->py = PrintY;
  510. }
  511.  
  512. ///////////////////////////////////////////////////////////////////////////
  513. //
  514. //    US_RestoreWindow() - Sets the current window parms to those held in the
  515. //        record
  516. //
  517. ///////////////////////////////////////////////////////////////////////////
  518. void
  519. US_RestoreWindow(WindowRec *win)
  520. {
  521.     WindowX = win->x;
  522.     WindowY = win->y;
  523.     WindowW = win->w;
  524.     WindowH = win->h;
  525.  
  526.     PrintX = win->px;
  527.     PrintY = win->py;
  528. }
  529.  
  530. //    Input routines
  531.  
  532. ///////////////////////////////////////////////////////////////////////////
  533. //
  534. //    USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
  535. //
  536. ///////////////////////////////////////////////////////////////////////////
  537. static void
  538. USL_XORICursor(int x,int y,char *s,word cursor)
  539. {
  540.     static    boolean    status;        // VGA doesn't XOR...
  541.     char    buf[MaxString];
  542.     int        temp;
  543.     word    w,h;
  544.  
  545.     strcpy(buf,s);
  546.     buf[cursor] = '\0';
  547.     USL_MeasureString(buf,&w,&h);
  548.  
  549.     px = x + w - 1;
  550.     py = y;
  551.     if (status^=1)
  552.         USL_DrawString("\x80");
  553.     else
  554.     {
  555.         temp = fontcolor;
  556.         fontcolor = backcolor;
  557.         USL_DrawString("\x80");
  558.         fontcolor = temp;
  559.     }
  560.  
  561. }
  562.  
  563. ///////////////////////////////////////////////////////////////////////////
  564. //
  565. //    US_LineInput() - Gets a line of user input at (x,y), the string defaults
  566. //        to whatever is pointed at by def. Input is restricted to maxchars
  567. //        chars or maxwidth pixels wide. If the user hits escape (and escok is
  568. //        true), nothing is copied into buf, and false is returned. If the
  569. //        user hits return, the current string is copied into buf, and true is
  570. //        returned
  571. //
  572. ///////////////////////////////////////////////////////////////////////////
  573. boolean
  574. US_LineInput(int x,int y,char *buf,char *def,boolean escok,
  575.                 int maxchars,int maxwidth)
  576. {
  577.     boolean        redraw,
  578.                 cursorvis,cursormoved,
  579.                 done,result;
  580.     ScanCode    sc;
  581.     char        c,
  582.                 s[MaxString],olds[MaxString];
  583.     word        i,
  584.                 cursor,
  585.                 w,h,
  586.                 len,temp;
  587.     longword    lasttime;
  588.  
  589.     if (def)
  590.         strcpy(s,def);
  591.     else
  592.         *s = '\0';
  593.     *olds = '\0';
  594.     cursor = strlen(s);
  595.     cursormoved = redraw = true;
  596.  
  597.     cursorvis = done = false;
  598.     lasttime = TimeCount;
  599.     LastASCII = key_None;
  600.     LastScan = sc_None;
  601.  
  602.     while (!done)
  603.     {
  604.         if (cursorvis)
  605.             USL_XORICursor(x,y,s,cursor);
  606.  
  607.     asm    pushf
  608.     asm    cli
  609.  
  610.         sc = LastScan;
  611.         LastScan = sc_None;
  612.         c = LastASCII;
  613.         LastASCII = key_None;
  614.  
  615.     asm    popf
  616.  
  617.         switch (sc)
  618.         {
  619.         case sc_LeftArrow:
  620.             if (cursor)
  621.                 cursor--;
  622.             c = key_None;
  623.             cursormoved = true;
  624.             break;
  625.         case sc_RightArrow:
  626.             if (s[cursor])
  627.                 cursor++;
  628.             c = key_None;
  629.             cursormoved = true;
  630.             break;
  631.         case sc_Home:
  632.             cursor = 0;
  633.             c = key_None;
  634.             cursormoved = true;
  635.             break;
  636.         case sc_End:
  637.             cursor = strlen(s);
  638.             c = key_None;
  639.             cursormoved = true;
  640.             break;
  641.  
  642.         case sc_Return:
  643.             strcpy(buf,s);
  644.             done = true;
  645.             result = true;
  646.             c = key_None;
  647.             break;
  648.         case sc_Escape:
  649.             if (escok)
  650.             {
  651.                 done = true;
  652.                 result = false;
  653.             }
  654.             c = key_None;
  655.             break;
  656.  
  657.         case sc_BackSpace:
  658.             if (cursor)
  659.             {
  660.                 strcpy(s + cursor - 1,s + cursor);
  661.                 cursor--;
  662.                 redraw = true;
  663.             }
  664.             c = key_None;
  665.             cursormoved = true;
  666.             break;
  667.         case sc_Delete:
  668.             if (s[cursor])
  669.             {
  670.                 strcpy(s + cursor,s + cursor + 1);
  671.                 redraw = true;
  672.             }
  673.             c = key_None;
  674.             cursormoved = true;
  675.             break;
  676.  
  677.         case 0x4c:    // Keypad 5
  678.         case sc_UpArrow:
  679.         case sc_DownArrow:
  680.         case sc_PgUp:
  681.         case sc_PgDn:
  682.         case sc_Insert:
  683.             c = key_None;
  684.             break;
  685.         }
  686.  
  687.         if (c)
  688.         {
  689.             len = strlen(s);
  690.             USL_MeasureString(s,&w,&h);
  691.  
  692.             if
  693.             (
  694.                 isprint(c)
  695.             &&    (len < MaxString - 1)
  696.             &&    ((!maxchars) || (len < maxchars))
  697.             &&    ((!maxwidth) || (w < maxwidth))
  698.             )
  699.             {
  700.                 for (i = len + 1;i > cursor;i--)
  701.                     s[i] = s[i - 1];
  702.                 s[cursor++] = c;
  703.                 redraw = true;
  704.             }
  705.         }
  706.  
  707.         if (redraw)
  708.         {
  709.             px = x;
  710.             py = y;
  711.             temp = fontcolor;
  712.             fontcolor = backcolor;
  713.             USL_DrawString(olds);
  714.             fontcolor = temp;
  715.             strcpy(olds,s);
  716.  
  717.             px = x;
  718.             py = y;
  719.             USL_DrawString(s);
  720.  
  721.             redraw = false;
  722.         }
  723.  
  724.         if (cursormoved)
  725.         {
  726.             cursorvis = false;
  727.             lasttime = TimeCount - TickBase;
  728.  
  729.             cursormoved = false;
  730.         }
  731.         if (TimeCount - lasttime > TickBase / 2)
  732.         {
  733.             lasttime = TimeCount;
  734.  
  735.             cursorvis ^= true;
  736.         }
  737.         if (cursorvis)
  738.             USL_XORICursor(x,y,s,cursor);
  739.  
  740.         VW_UpdateScreen();
  741.     }
  742.  
  743.     if (cursorvis)
  744.         USL_XORICursor(x,y,s,cursor);
  745.     if (!result)
  746.     {
  747.         px = x;
  748.         py = y;
  749.         USL_DrawString(olds);
  750.     }
  751.     VW_UpdateScreen();
  752.  
  753.     IN_ClearKeysDown();
  754.     return(result);
  755. }
  756.