Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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.  
  38. static  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.  
  55. int rndindex = 0;
  56.  
  57. static 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. ///////////////////////////////////////////////////////////////////////////
  87. void 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. ///////////////////////////////////////////////////////////////////////////
  103. void
  104. US_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. ///////////////////////////////////////////////////////////////////////////
  121. void
  122. US_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. ///////////////////////////////////////////////////////////////////////////
  135. void
  136. US_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. ///////////////////////////////////////////////////////////////////////////
  176. void
  177. US_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. ///////////////////////////////////////////////////////////////////////////
  190. void
  191. US_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. ///////////////////////////////////////////////////////////////////////////
  203. void
  204. USL_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. ///////////////////////////////////////////////////////////////////////////
  223. void
  224. US_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. ///////////////////////////////////////////////////////////////////////////
  242. void
  243. US_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. ///////////////////////////////////////////////////////////////////////////
  263. void
  264. US_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.  
  297. void 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.  
  316. void 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. ///////////////////////////////////////////////////////////////////////////
  334. void
  335. US_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. ///////////////////////////////////////////////////////////////////////////
  347. void
  348. US_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. ///////////////////////////////////////////////////////////////////////////
  383. void
  384. US_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. ///////////////////////////////////////////////////////////////////////////
  395. void
  396. US_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. ///////////////////////////////////////////////////////////////////////////
  413. void
  414. US_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. ///////////////////////////////////////////////////////////////////////////
  432. static void
  433. USL_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.  
  457. char 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. ///////////////////////////////////////////////////////////////////////////
  485. boolean
  486. US_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. ///////////////////////////////////////////////////////////////////////////
  772. void 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. ///////////////////////////////////////////////////////////////////////////
  785. int US_RndT()
  786. {
  787.     rndindex = (rndindex+1)&0xff;
  788.     return rndtable[rndindex];
  789. }
  790.