Subversion Repositories Kolibri OS

Rev

Rev 9097 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. //
  2. //      ID Engine
  3. //      ID_IN.c - Input Manager
  4. //      v1.0d1
  5. //      By Jason Blochowiak
  6. //
  7.  
  8. //
  9. //      This module handles dealing with the various input devices
  10. //
  11. //      Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),
  12. //                              User Mgr (for command line parms)
  13. //
  14. //      Globals:
  15. //              LastScan - The keyboard scan code of the last key pressed
  16. //              LastASCII - The ASCII value of the last key pressed
  17. //      DEBUG - there are more globals
  18. //
  19.  
  20. #include "wl_def.h"
  21.  
  22.  
  23. /*
  24. =============================================================================
  25.  
  26.                                         GLOBAL VARIABLES
  27.  
  28. =============================================================================
  29. */
  30.  
  31.  
  32. //
  33. // configuration variables
  34. //
  35. boolean MousePresent;
  36. boolean forcegrabmouse;
  37.  
  38.  
  39. //      Global variables
  40. volatile boolean    Keyboard[SDLK_LAST];
  41. volatile boolean        Paused;
  42. volatile char           LastASCII;
  43. volatile ScanCode       LastScan;
  44.  
  45. //KeyboardDef   KbdDefs = {0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51};
  46. static KeyboardDef KbdDefs = {
  47.     sc_Control,             // button0
  48.     sc_Alt,                 // button1
  49.     sc_Home,                // upleft
  50.     sc_UpArrow,             // up
  51.     sc_PgUp,                // upright
  52.     sc_LeftArrow,           // left
  53.     sc_RightArrow,          // right
  54.     sc_End,                 // downleft
  55.     sc_DownArrow,           // down
  56.     sc_PgDn                 // downright
  57. };
  58.  
  59. static SDL_Joystick *Joystick;
  60. int JoyNumButtons;
  61. static int JoyNumHats;
  62.  
  63. static bool GrabInput = false;
  64. static bool NeedRestore = false;
  65.  
  66. /*
  67. =============================================================================
  68.  
  69.                                         LOCAL VARIABLES
  70.  
  71. =============================================================================
  72. */
  73. byte        ASCIINames[] =              // Unshifted ASCII for scan codes       // TODO: keypad
  74. {
  75. //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  76.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,8  ,9  ,0  ,0  ,0  ,13 ,0  ,0  ,        // 0
  77.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,27 ,0  ,0  ,0  ,    // 1
  78.         ' ',0  ,0  ,0  ,0  ,0  ,0  ,39 ,0  ,0  ,'*','+',',','-','.','/',        // 2
  79.         '0','1','2','3','4','5','6','7','8','9',0  ,';',0  ,'=',0  ,0  ,        // 3
  80.         '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',        // 4
  81.         'p','q','r','s','t','u','v','w','x','y','z','[',92 ,']',0  ,0  ,        // 5
  82.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6
  83.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7
  84. };
  85. byte ShiftNames[] =             // Shifted ASCII for scan codes
  86. {
  87. //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  88.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,8  ,9  ,0  ,0  ,0  ,13 ,0  ,0  ,        // 0
  89.     0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,27 ,0  ,0  ,0  ,    // 1
  90.         ' ',0  ,0  ,0  ,0  ,0  ,0  ,34 ,0  ,0  ,'*','+','<','_','>','?',        // 2
  91.         ')','!','@','#','$','%','^','&','*','(',0  ,':',0  ,'+',0  ,0  ,        // 3
  92.         '~','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',        // 4
  93.         'P','Q','R','S','T','U','V','W','X','Y','Z','{','|','}',0  ,0  ,        // 5
  94.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6
  95.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7
  96. };
  97. byte SpecialNames[] =   // ASCII for 0xe0 prefixed codes
  98. {
  99. //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
  100.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 0
  101.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,13 ,0  ,0  ,0  ,        // 1
  102.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 2
  103.         0  ,0  ,0  ,0  ,0  ,'/',0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 3
  104.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 4
  105.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 5
  106.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6
  107.         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7
  108. };
  109.  
  110.  
  111. static  boolean         IN_Started;
  112.  
  113. static  Direction       DirTable[] =            // Quick lookup for total direction
  114. {
  115.     dir_NorthWest,      dir_North,      dir_NorthEast,
  116.     dir_West,           dir_None,       dir_East,
  117.     dir_SouthWest,      dir_South,      dir_SouthEast
  118. };
  119.  
  120.  
  121. ///////////////////////////////////////////////////////////////////////////
  122. //
  123. //      INL_GetMouseButtons() - Gets the status of the mouse buttons from the
  124. //              mouse driver
  125. //
  126. ///////////////////////////////////////////////////////////////////////////
  127. static int
  128. INL_GetMouseButtons(void)
  129. {
  130.     int buttons = SDL_GetMouseState(NULL, NULL);
  131.     int middlePressed = buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE);
  132.     int rightPressed = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
  133.     buttons &= ~(SDL_BUTTON(SDL_BUTTON_MIDDLE) | SDL_BUTTON(SDL_BUTTON_RIGHT));
  134.     if(middlePressed) buttons |= 1 << 2;
  135.     if(rightPressed) buttons |= 1 << 1;
  136.  
  137.     return buttons;
  138. }
  139.  
  140. ///////////////////////////////////////////////////////////////////////////
  141. //
  142. //      IN_GetJoyDelta() - Returns the relative movement of the specified
  143. //              joystick (from +/-127)
  144. //
  145. ///////////////////////////////////////////////////////////////////////////
  146. void IN_GetJoyDelta(int *dx,int *dy)
  147. {
  148.     if(!Joystick)
  149.     {
  150.         *dx = *dy = 0;
  151.         return;
  152.     }
  153.  
  154.     SDL_JoystickUpdate();
  155. #ifdef _arch_dreamcast
  156.     int x = 0;
  157.     int y = 0;
  158. #else
  159.     int x = SDL_JoystickGetAxis(Joystick, 0) >> 8;
  160.     int y = SDL_JoystickGetAxis(Joystick, 1) >> 8;
  161. #endif
  162.  
  163.     if(param_joystickhat != -1)
  164.     {
  165.         uint8_t hatState = SDL_JoystickGetHat(Joystick, param_joystickhat);
  166.         if(hatState & SDL_HAT_RIGHT)
  167.             x += 127;
  168.         else if(hatState & SDL_HAT_LEFT)
  169.             x -= 127;
  170.         if(hatState & SDL_HAT_DOWN)
  171.             y += 127;
  172.         else if(hatState & SDL_HAT_UP)
  173.             y -= 127;
  174.  
  175.         if(x < -128) x = -128;
  176.         else if(x > 127) x = 127;
  177.  
  178.         if(y < -128) y = -128;
  179.         else if(y > 127) y = 127;
  180.     }
  181.  
  182.     *dx = x;
  183.     *dy = y;
  184. }
  185.  
  186. ///////////////////////////////////////////////////////////////////////////
  187. //
  188. //      IN_GetJoyFineDelta() - Returns the relative movement of the specified
  189. //              joystick without dividing the results by 256 (from +/-127)
  190. //
  191. ///////////////////////////////////////////////////////////////////////////
  192. void IN_GetJoyFineDelta(int *dx, int *dy)
  193. {
  194.     if(!Joystick)
  195.     {
  196.         *dx = 0;
  197.         *dy = 0;
  198.         return;
  199.     }
  200.  
  201.     SDL_JoystickUpdate();
  202.     int x = SDL_JoystickGetAxis(Joystick, 0);
  203.     int y = SDL_JoystickGetAxis(Joystick, 1);
  204.  
  205.     if(x < -128) x = -128;
  206.     else if(x > 127) x = 127;
  207.  
  208.     if(y < -128) y = -128;
  209.     else if(y > 127) y = 127;
  210.  
  211.     *dx = x;
  212.     *dy = y;
  213. }
  214.  
  215. /*
  216. ===================
  217. =
  218. = IN_JoyButtons
  219. =
  220. ===================
  221. */
  222.  
  223. int IN_JoyButtons()
  224. {
  225.     if(!Joystick) return 0;
  226.  
  227.     SDL_JoystickUpdate();
  228.  
  229.     int res = 0;
  230.     for(int i = 0; i < JoyNumButtons && i < 32; i++)
  231.         res |= SDL_JoystickGetButton(Joystick, i) << i;
  232.     return res;
  233. }
  234.  
  235. boolean IN_JoyPresent()
  236. {
  237.     return Joystick != NULL;
  238. }
  239.  
  240. static void processEvent(SDL_Event *event)
  241. {
  242.     switch (event->type)
  243.     {
  244.         // exit if the window is closed
  245.         case SDL_QUIT:
  246.             Quit(NULL);
  247.  
  248.         // check for keypresses
  249.         case SDL_KEYDOWN:
  250.         {
  251.             if(event->key.keysym.sym==SDLK_SCROLLOCK || event->key.keysym.sym==SDLK_F12)
  252.             {
  253.                 GrabInput = !GrabInput;
  254.                 SDL_WM_GrabInput(GrabInput ? SDL_GRAB_ON : SDL_GRAB_OFF);
  255.                 return;
  256.             }
  257.  
  258.             LastScan = event->key.keysym.sym;
  259.             SDLMod mod = SDL_GetModState();
  260.             if(Keyboard[sc_Alt])
  261.             {
  262.                 if(LastScan==SDLK_F4)
  263.                     Quit(NULL);
  264.             }
  265.  
  266.             if(LastScan == SDLK_KP_ENTER) LastScan = SDLK_RETURN;
  267.             else if(LastScan == SDLK_RSHIFT) LastScan = SDLK_LSHIFT;
  268.             else if(LastScan == SDLK_RALT) LastScan = SDLK_LALT;
  269.             else if(LastScan == SDLK_RCTRL) LastScan = SDLK_LCTRL;
  270.             else
  271.             {
  272.                 if((mod & KMOD_NUM) == 0)
  273.                 {
  274.                     switch(LastScan)
  275.                     {
  276.                         case SDLK_KP2: LastScan = SDLK_DOWN; break;
  277.                         case SDLK_KP4: LastScan = SDLK_LEFT; break;
  278.                         case SDLK_KP6: LastScan = SDLK_RIGHT; break;
  279.                         case SDLK_KP8: LastScan = SDLK_UP; break;
  280.                     }
  281.                 }
  282.             }
  283.  
  284.             int sym = LastScan;
  285.             if(sym >= 'a' && sym <= 'z')
  286.                 sym -= 32;  // convert to uppercase
  287.  
  288.             if(mod & (KMOD_SHIFT | KMOD_CAPS))
  289.             {
  290.                 if(sym < lengthof(ShiftNames) && ShiftNames[sym])
  291.                     LastASCII = ShiftNames[sym];
  292.             }
  293.             else
  294.             {
  295.                 if(sym < lengthof(ASCIINames) && ASCIINames[sym])
  296.                     LastASCII = ASCIINames[sym];
  297.             }
  298.             if(LastScan<SDLK_LAST)
  299.                 Keyboard[LastScan] = 1;
  300.             if(LastScan == SDLK_PAUSE)
  301.                 Paused = true;
  302.             break;
  303.                 }
  304.  
  305.         case SDL_KEYUP:
  306.         {
  307.             int key = event->key.keysym.sym;
  308.             if(key == SDLK_KP_ENTER) key = SDLK_RETURN;
  309.             else if(key == SDLK_RSHIFT) key = SDLK_LSHIFT;
  310.             else if(key == SDLK_RALT) key = SDLK_LALT;
  311.             else if(key == SDLK_RCTRL) key = SDLK_LCTRL;
  312.             else
  313.             {
  314.                 if((SDL_GetModState() & KMOD_NUM) == 0)
  315.                 {
  316.                     switch(key)
  317.                     {
  318.                         case SDLK_KP2: key = SDLK_DOWN; break;
  319.                         case SDLK_KP4: key = SDLK_LEFT; break;
  320.                         case SDLK_KP6: key = SDLK_RIGHT; break;
  321.                         case SDLK_KP8: key = SDLK_UP; break;
  322.                     }
  323.                 }
  324.             }
  325.  
  326.             if(key<SDLK_LAST)
  327.                 Keyboard[key] = 0;
  328.             break;
  329.         }
  330.  
  331.         case SDL_ACTIVEEVENT:
  332.         {
  333.             if(fullscreen && (event->active.state & SDL_APPACTIVE) != 0)
  334.             {
  335.                 if(event->active.gain)
  336.                 {
  337.                     if(NeedRestore)
  338.                     {
  339.                         FreeLatchMem();
  340.                         LoadLatchMem();
  341.                     }
  342.  
  343.                     NeedRestore = false;
  344.                 }
  345.                 else NeedRestore = true;
  346.             }
  347.         }
  348.  
  349. #if defined(GP2X)
  350.         case SDL_JOYBUTTONDOWN:
  351.             GP2X_ButtonDown(event->jbutton.button);
  352.             break;
  353.  
  354.         case SDL_JOYBUTTONUP:
  355.             GP2X_ButtonUp(event->jbutton.button);
  356.             break;
  357. #endif
  358.     }
  359. }
  360.  
  361. void IN_WaitAndProcessEvents()
  362. {
  363.     SDL_Event event;
  364.     if(!SDL_WaitEvent(&event)) return;
  365.     do
  366.     {
  367.         processEvent(&event);
  368.     }
  369.     while(SDL_PollEvent(&event));
  370. }
  371.  
  372. void IN_ProcessEvents()
  373. {
  374.     SDL_Event event;
  375.  
  376.     while (SDL_PollEvent(&event))
  377.     {
  378.         processEvent(&event);
  379.     }
  380. }
  381.  
  382.  
  383. ///////////////////////////////////////////////////////////////////////////
  384. //
  385. //      IN_Startup() - Starts up the Input Mgr
  386. //
  387. ///////////////////////////////////////////////////////////////////////////
  388. void
  389. IN_Startup(void)
  390. {
  391.         if (IN_Started)
  392.                 return;
  393.  
  394.     IN_ClearKeysDown();
  395.  
  396.     if(param_joystickindex >= 0 && param_joystickindex < SDL_NumJoysticks())
  397.     {
  398.         Joystick = SDL_JoystickOpen(param_joystickindex);
  399.         if(Joystick)
  400.         {
  401.             JoyNumButtons = SDL_JoystickNumButtons(Joystick);
  402.             if(JoyNumButtons > 32) JoyNumButtons = 32;      // only up to 32 buttons are supported
  403.             JoyNumHats = SDL_JoystickNumHats(Joystick);
  404.             if(param_joystickhat < -1 || param_joystickhat >= JoyNumHats)
  405.                 Quit("The joystickhat param must be between 0 and %i!", JoyNumHats - 1);
  406.         }
  407.     }
  408.  
  409.     SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
  410.  
  411.     if(fullscreen || forcegrabmouse)
  412.     {
  413.         GrabInput = true;
  414.         SDL_WM_GrabInput(SDL_GRAB_ON);
  415.     }
  416.  
  417.     // I didn't find a way to ask libSDL whether a mouse is present, yet...
  418. #if defined(GP2X)
  419.     MousePresent = false;
  420. #elif defined(_arch_dreamcast)
  421.     MousePresent = DC_MousePresent();
  422. #else
  423.     MousePresent = true;
  424. #endif
  425.  
  426.     IN_Started = true;
  427. }
  428.  
  429. ///////////////////////////////////////////////////////////////////////////
  430. //
  431. //      IN_Shutdown() - Shuts down the Input Mgr
  432. //
  433. ///////////////////////////////////////////////////////////////////////////
  434. void
  435. IN_Shutdown(void)
  436. {
  437.         if (!IN_Started)
  438.                 return;
  439.  
  440.     if(Joystick)
  441.         SDL_JoystickClose(Joystick);
  442.  
  443.         IN_Started = false;
  444. }
  445.  
  446. ///////////////////////////////////////////////////////////////////////////
  447. //
  448. //      IN_ClearKeysDown() - Clears the keyboard array
  449. //
  450. ///////////////////////////////////////////////////////////////////////////
  451. void
  452. IN_ClearKeysDown(void)
  453. {
  454.         LastScan = sc_None;
  455.         LastASCII = key_None;
  456.         memset ((void *) Keyboard,0,sizeof(Keyboard));
  457. }
  458.  
  459.  
  460. ///////////////////////////////////////////////////////////////////////////
  461. //
  462. //      IN_ReadControl() - Reads the device associated with the specified
  463. //              player and fills in the control info struct
  464. //
  465. ///////////////////////////////////////////////////////////////////////////
  466. void
  467. IN_ReadControl(int player,ControlInfo *info)
  468. {
  469.         word            buttons;
  470.         int                     dx,dy;
  471.         Motion          mx,my;
  472.  
  473.         dx = dy = 0;
  474.         mx = my = motion_None;
  475.         buttons = 0;
  476.  
  477.         IN_ProcessEvents();
  478.  
  479.     if (Keyboard[KbdDefs.upleft])
  480.         mx = motion_Left,my = motion_Up;
  481.     else if (Keyboard[KbdDefs.upright])
  482.         mx = motion_Right,my = motion_Up;
  483.     else if (Keyboard[KbdDefs.downleft])
  484.         mx = motion_Left,my = motion_Down;
  485.     else if (Keyboard[KbdDefs.downright])
  486.         mx = motion_Right,my = motion_Down;
  487.  
  488.     if (Keyboard[KbdDefs.up])
  489.         my = motion_Up;
  490.     else if (Keyboard[KbdDefs.down])
  491.         my = motion_Down;
  492.  
  493.     if (Keyboard[KbdDefs.left])
  494.         mx = motion_Left;
  495.     else if (Keyboard[KbdDefs.right])
  496.         mx = motion_Right;
  497.  
  498.     if (Keyboard[KbdDefs.button0])
  499.         buttons += 1 << 0;
  500.     if (Keyboard[KbdDefs.button1])
  501.         buttons += 1 << 1;
  502.  
  503.         dx = mx * 127;
  504.         dy = my * 127;
  505.  
  506.         info->x = dx;
  507.         info->xaxis = mx;
  508.         info->y = dy;
  509.         info->yaxis = my;
  510.         info->button0 = (buttons & (1 << 0)) != 0;
  511.         info->button1 = (buttons & (1 << 1)) != 0;
  512.         info->button2 = (buttons & (1 << 2)) != 0;
  513.         info->button3 = (buttons & (1 << 3)) != 0;
  514.         info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
  515. }
  516.  
  517. ///////////////////////////////////////////////////////////////////////////
  518. //
  519. //      IN_WaitForKey() - Waits for a scan code, then clears LastScan and
  520. //              returns the scan code
  521. //
  522. ///////////////////////////////////////////////////////////////////////////
  523. ScanCode
  524. IN_WaitForKey(void)
  525. {
  526.         ScanCode        result;
  527.  
  528.         while ((result = LastScan)==0)
  529.                 IN_WaitAndProcessEvents();
  530.         LastScan = 0;
  531.         return(result);
  532. }
  533.  
  534. ///////////////////////////////////////////////////////////////////////////
  535. //
  536. //      IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
  537. //              returns the ASCII value
  538. //
  539. ///////////////////////////////////////////////////////////////////////////
  540. char
  541. IN_WaitForASCII(void)
  542. {
  543.         char            result;
  544.  
  545.         while ((result = LastASCII)==0)
  546.                 IN_WaitAndProcessEvents();
  547.         LastASCII = '\0';
  548.         return(result);
  549. }
  550.  
  551. ///////////////////////////////////////////////////////////////////////////
  552. //
  553. //      IN_Ack() - waits for a button or key press.  If a button is down, upon
  554. // calling, it must be released for it to be recognized
  555. //
  556. ///////////////////////////////////////////////////////////////////////////
  557.  
  558. boolean btnstate[NUMBUTTONS];
  559.  
  560. void IN_StartAck(void)
  561. {
  562.     IN_ProcessEvents();
  563. //
  564. // get initial state of everything
  565. //
  566.         IN_ClearKeysDown();
  567.         memset(btnstate, 0, sizeof(btnstate));
  568.  
  569.         int buttons = IN_JoyButtons() << 4;
  570.  
  571.         if(MousePresent)
  572.                 buttons |= IN_MouseButtons();
  573.  
  574.         for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
  575.                 if(buttons & 1)
  576.                         btnstate[i] = true;
  577. }
  578.  
  579.  
  580. boolean IN_CheckAck (void)
  581. {
  582.     IN_ProcessEvents();
  583. //
  584. // see if something has been pressed
  585. //
  586.         if(LastScan)
  587.                 return true;
  588.  
  589.         int buttons = IN_JoyButtons() << 4;
  590.  
  591.         if(MousePresent)
  592.                 buttons |= IN_MouseButtons();
  593.  
  594.         for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
  595.         {
  596.                 if(buttons & 1)
  597.                 {
  598.                         if(!btnstate[i])
  599.             {
  600.                 // Wait until button has been released
  601.                 do
  602.                 {
  603.                     IN_WaitAndProcessEvents();
  604.                     buttons = IN_JoyButtons() << 4;
  605.  
  606.                     if(MousePresent)
  607.                         buttons |= IN_MouseButtons();
  608.                 }
  609.                 while(buttons & (1 << i));
  610.  
  611.                                 return true;
  612.             }
  613.                 }
  614.                 else
  615.                         btnstate[i] = false;
  616.         }
  617.  
  618.         return false;
  619. }
  620.  
  621.  
  622. void IN_Ack (void)
  623. {
  624.         IN_StartAck ();
  625.  
  626.     do
  627.     {
  628.         IN_WaitAndProcessEvents();
  629.     }
  630.         while(!IN_CheckAck ());
  631. }
  632.  
  633.  
  634. ///////////////////////////////////////////////////////////////////////////
  635. //
  636. //      IN_UserInput() - Waits for the specified delay time (in ticks) or the
  637. //              user pressing a key or a mouse button. If the clear flag is set, it
  638. //              then either clears the key or waits for the user to let the mouse
  639. //              button up.
  640. //
  641. ///////////////////////////////////////////////////////////////////////////
  642. boolean IN_UserInput(longword delay)
  643. {
  644.         longword        lasttime;
  645.  
  646.         lasttime = GetTimeCount();
  647.         IN_StartAck ();
  648.         do
  649.         {
  650.         IN_ProcessEvents();
  651.                 if (IN_CheckAck())
  652.                         return true;
  653.         SDL_Delay(5);
  654.         } while (GetTimeCount() - lasttime < delay);
  655.         return(false);
  656. }
  657.  
  658. //===========================================================================
  659.  
  660. /*
  661. ===================
  662. =
  663. = IN_MouseButtons
  664. =
  665. ===================
  666. */
  667. int IN_MouseButtons (void)
  668. {
  669.         if (MousePresent)
  670.                 return INL_GetMouseButtons();
  671.         else
  672.                 return 0;
  673. }
  674.  
  675. bool IN_IsInputGrabbed()
  676. {
  677.     return GrabInput;
  678. }
  679.  
  680. void IN_CenterMouse()
  681. {
  682.     SDL_WarpMouse(screenWidth / 2, screenHeight / 2);
  683. }
  684.