| 1644 | |
| 1645 | |
| 1646 | void PollJoysticks() |
| 1647 | // It's best to call this function only directly from MsgSleep() or when there is an instance of |
| 1648 | // MsgSleep() closer on the call stack than the nearest dialog's message pump (e.g. MsgBox). |
| 1649 | // This is because events posted to the thread indirectly by us here would be discarded or mishandled |
| 1650 | // by a non-standard (dialog) message pump. |
| 1651 | // |
| 1652 | // Polling the joysticks this way rather than using joySetCapture() is preferable for several reasons: |
| 1653 | // 1) I believe joySetCapture() internally polls the joystick anyway, via a system timer, so it probably |
| 1654 | // doesn't perform much better (if at all) than polling "manually". |
| 1655 | // 2) joySetCapture() only supports 4 buttons; |
| 1656 | // 3) joySetCapture() will fail if another app is already capturing the joystick; |
| 1657 | // 4) Even if the joySetCapture() succeeds, other programs (e.g. older games), would be prevented from |
| 1658 | // capturing the joystick while the script in question is running. |
| 1659 | { |
| 1660 | // Even if joystick hotkeys aren't currently allowed to fire, poll it anyway so that hotkey |
| 1661 | // messages can be buffered for later. |
| 1662 | static DWORD sButtonsPrev[MAX_JOYSTICKS] = {0}; // Set initial state to "all buttons up for all joysticks". |
| 1663 | JOYINFOEX jie; |
| 1664 | DWORD buttons_newly_down; |
| 1665 | |
| 1666 | for (int i = 0; i < MAX_JOYSTICKS; ++i) |
| 1667 | { |
| 1668 | if (!Hotkey::sJoystickHasHotkeys[i]) |
| 1669 | continue; |
| 1670 | // Reset these every time in case joyGetPosEx() ever changes them. Also, most systems have only one joystick, |
| 1671 | // so this code will hardly ever be executed more than once (and sometimes zero times): |
| 1672 | jie.dwSize = sizeof(JOYINFOEX); |
| 1673 | jie.dwFlags = JOY_RETURNBUTTONS; // vs. JOY_RETURNALL |
| 1674 | if (joyGetPosEx(i, &jie) != JOYERR_NOERROR) // Skip this joystick and try the others. |
| 1675 | continue; |
| 1676 | // The exclusive-or operator determines which buttons have changed state. After that, |
| 1677 | // the bitwise-and operator determines which of those have gone from up to down (the |
| 1678 | // down-to-up events are currently not significant). |
| 1679 | buttons_newly_down = (jie.dwButtons ^ sButtonsPrev[i]) & jie.dwButtons; |
| 1680 | sButtonsPrev[i] = jie.dwButtons; |
| 1681 | if (!buttons_newly_down) |
| 1682 | continue; |
| 1683 | // See if any of the joystick hotkeys match this joystick ID and one of the buttons that |
| 1684 | // has just been pressed on it. If so, queue up (buffer) the hotkey events so that they will |
| 1685 | // be processed when messages are next checked: |
| 1686 | Hotkey::TriggerJoyHotkeys(i, buttons_newly_down); |
| 1687 | } |
| 1688 | } |
| 1689 | |
| 1690 | |
| 1691 |
nothing calls this directly
no outgoing calls
no test coverage detected