From d6ae5bfafad28dc0dcf97e72472e8827827a75ef Mon Sep 17 00:00:00 2001 From: Clang Format Date: Sun, 4 Sep 2016 14:16:34 +0200 Subject: [PATCH] reformat lilypad Note: I'm worried on the EXPORT/CALLBACK behavior on multiple OS --- plugins/LilyPad/Config.cpp | 3802 ++++++++++++----------- plugins/LilyPad/Config.h | 81 +- plugins/LilyPad/DeviceEnumerator.cpp | 29 +- plugins/LilyPad/DeviceEnumerator.h | 1 - plugins/LilyPad/Diagnostics.cpp | 228 +- plugins/LilyPad/DirectInput.cpp | 1013 +++--- plugins/LilyPad/DualShock3.cpp | 747 ++--- plugins/LilyPad/Global.h | 153 +- plugins/LilyPad/HidDevice.cpp | 102 +- plugins/LilyPad/HidDevice.h | 11 +- plugins/LilyPad/InputManager.cpp | 1077 +++---- plugins/LilyPad/InputManager.h | 461 +-- plugins/LilyPad/KeyboardQueue.cpp | 84 +- plugins/LilyPad/KeyboardQueue.h | 2 +- plugins/LilyPad/LilyPad.cpp | 2423 ++++++++------- plugins/LilyPad/Linux/Config.cpp | 777 ++--- plugins/LilyPad/Linux/ConfigHelper.cpp | 82 +- plugins/LilyPad/Linux/ConfigHelper.h | 38 +- plugins/LilyPad/Linux/JoyEvdev.cpp | 304 +- plugins/LilyPad/Linux/JoyEvdev.h | 93 +- plugins/LilyPad/Linux/KeyboardMouse.cpp | 73 +- plugins/LilyPad/Linux/KeyboardMouse.h | 11 +- plugins/LilyPad/Linux/KeyboardQueue.cpp | 53 +- plugins/LilyPad/Linux/bitmaskros.h | 12 +- plugins/LilyPad/RawInput.cpp | 480 +-- plugins/LilyPad/VKey.cpp | 139 +- plugins/LilyPad/WindowsKeyboard.cpp | 76 +- plugins/LilyPad/WindowsKeyboard.h | 15 +- plugins/LilyPad/WindowsMessaging.cpp | 262 +- plugins/LilyPad/WindowsMouse.cpp | 113 +- plugins/LilyPad/WindowsMouse.h | 39 +- plugins/LilyPad/WndProcEater.cpp | 180 +- plugins/LilyPad/WndProcEater.h | 43 +- plugins/LilyPad/XInputEnum.cpp | 453 +-- plugins/LilyPad/usb.h | 473 +-- 35 files changed, 7158 insertions(+), 6772 deletions(-) diff --git a/plugins/LilyPad/Config.cpp b/plugins/LilyPad/Config.cpp index 98588a4756..9d24416234 100644 --- a/plugins/LilyPad/Config.cpp +++ b/plugins/LilyPad/Config.cpp @@ -32,32 +32,32 @@ //max len 24 wchar_t const wchar_t *padTypes[] = { - L"Unplugged", - L"Dualshock 2", - L"Guitar" , - L"Pop'n Music controller" -}; + L"Unplugged", + L"Dualshock 2", + L"Guitar", + L"Pop'n Music controller"}; // Hacks or configurations which PCSX2 needs with a specific value -void PCSX2_overrideConfig(GeneralConfig& config_in_out) { - config_in_out.disableScreenSaver = 0; // Not required - handled internally by PCSX2 - config_in_out.escapeFullscreenHack = 0; // Not required - handled internally by PCSX2 - config_in_out.saveStateTitle = 0; // Not required - handled internally by PCSX2 - config_in_out.closeHacks = 0; // Cannot function when used by PCSX2 +void PCSX2_overrideConfig(GeneralConfig &config_in_out) +{ + config_in_out.disableScreenSaver = 0; // Not required - handled internally by PCSX2 + config_in_out.escapeFullscreenHack = 0; // Not required - handled internally by PCSX2 + config_in_out.saveStateTitle = 0; // Not required - handled internally by PCSX2 + config_in_out.closeHacks = 0; // Cannot function when used by PCSX2 } // Dialog widgets which should be disabled - mostly matching PCSX2_overrideConfig -const UINT* PCSX2_disabledWidgets() { - static const UINT disabledWidgets[] = { - IDC_DISABLE_SCREENSAVER, - IDC_ESCAPE_FULLSCREEN_HACK, - IDC_SAVE_STATE_TITLE, - IDC_ANALOG_START1, // start in analog mode - only useful for PS1 - IDC_CLOSE_HACK1, - IDC_CLOSE_HACK2, - 0 - }; - return disabledWidgets; +const UINT *PCSX2_disabledWidgets() +{ + static const UINT disabledWidgets[] = { + IDC_DISABLE_SCREENSAVER, + IDC_ESCAPE_FULLSCREEN_HACK, + IDC_SAVE_STATE_TITLE, + IDC_ANALOG_START1, // start in analog mode - only useful for PS1 + IDC_CLOSE_HACK1, + IDC_CLOSE_HACK2, + 0}; + return disabledWidgets; } GeneralConfig config; @@ -80,139 +80,143 @@ bool createIniDir = true; HWND hWnds[2][4]; HWND hWndGeneral = 0; -struct GeneralSettingsBool { - wchar_t *name; - unsigned int ControlId; - u8 defaultValue; +struct GeneralSettingsBool +{ + wchar_t *name; + unsigned int ControlId; + u8 defaultValue; }; // Ties together config data structure, config files, and general config // dialog. const GeneralSettingsBool BoolOptionsInfo[] = { - {L"Force Cursor Hide", IDC_FORCE_HIDE, 0}, - {L"Mouse Unfocus", IDC_MOUSE_UNFOCUS, 1}, - {L"Background", IDC_BACKGROUND, 1}, - {L"Multiple Bindings", IDC_MULTIPLE_BINDING, 0}, + {L"Force Cursor Hide", IDC_FORCE_HIDE, 0}, + {L"Mouse Unfocus", IDC_MOUSE_UNFOCUS, 1}, + {L"Background", IDC_BACKGROUND, 1}, + {L"Multiple Bindings", IDC_MULTIPLE_BINDING, 0}, - {L"DirectInput Game Devices", IDC_G_DI, 1}, - {L"XInput", IDC_G_XI, 1}, - {L"DualShock 3", IDC_G_DS3, 0}, + {L"DirectInput Game Devices", IDC_G_DI, 1}, + {L"XInput", IDC_G_XI, 1}, + {L"DualShock 3", IDC_G_DS3, 0}, - {L"Multitap 1", IDC_MULTITAP1, 0}, - {L"Multitap 2", IDC_MULTITAP2, 0}, + {L"Multitap 1", IDC_MULTITAP1, 0}, + {L"Multitap 2", IDC_MULTITAP2, 0}, - {L"Escape Fullscreen Hack", IDC_ESCAPE_FULLSCREEN_HACK, 1}, // Not required for PCSX2 - {L"Disable Screen Saver", IDC_DISABLE_SCREENSAVER, 1}, // Not required for PCSX2 - {L"Logging", IDC_DEBUG_FILE, 0}, + {L"Escape Fullscreen Hack", IDC_ESCAPE_FULLSCREEN_HACK, 1}, // Not required for PCSX2 + {L"Disable Screen Saver", IDC_DISABLE_SCREENSAVER, 1}, // Not required for PCSX2 + {L"Logging", IDC_DEBUG_FILE, 0}, - {L"Save State in Title", IDC_SAVE_STATE_TITLE, 0}, // Not required for PCSX2 - {L"GH2", IDC_GH2_HACK, 0}, - {L"Turbo Key Hack", IDC_TURBO_KEY_HACK, 0}, + {L"Save State in Title", IDC_SAVE_STATE_TITLE, 0}, // Not required for PCSX2 + {L"GH2", IDC_GH2_HACK, 0}, + {L"Turbo Key Hack", IDC_TURBO_KEY_HACK, 0}, }; void Populate(int port, int slot); -void SetupLogSlider(HWND hWndSlider) { - SendMessage(hWndSlider, TBM_SETRANGEMIN, 0, 1); - SendMessage(hWndSlider, TBM_SETPAGESIZE, 0, 1<<13); - SendMessage(hWndSlider, TBM_SETRANGEMAX, 1, 1<<22); - SendMessage(hWndSlider, TBM_SETTIC, 0, 1<<21); - SendMessage(hWndSlider, TBM_SETTIC, 0, 1<<20); - SendMessage(hWndSlider, TBM_SETTIC, 0, 3<<20); +void SetupLogSlider(HWND hWndSlider) +{ + SendMessage(hWndSlider, TBM_SETRANGEMIN, 0, 1); + SendMessage(hWndSlider, TBM_SETPAGESIZE, 0, 1 << 13); + SendMessage(hWndSlider, TBM_SETRANGEMAX, 1, 1 << 22); + SendMessage(hWndSlider, TBM_SETTIC, 0, 1 << 21); + SendMessage(hWndSlider, TBM_SETTIC, 0, 1 << 20); + SendMessage(hWndSlider, TBM_SETTIC, 0, 3 << 20); } -int GetLogSliderVal(HWND hWnd, int id) { - HWND hWndSlider = GetDlgItem(hWnd, id); - int val = SendMessage(hWndSlider, TBM_GETPOS, 0, 0); - if (val <= (1<<21)) { - val = (val+16) >> 5; - } - else { - double v = (val - (1<<21))/(double)((1<<22)- (1<<21)); - double max = log((double)(1<<23)); - double min = log((double)BASE_SENSITIVITY); - v = v*(max-min)+min; - // exp is not implemented in ntdll, so use pow instead. - // More than accurate enough for my needs. - // v = exp(v); - v = pow(2.7182818284590451, v); - if (v > (1<<23)) v = (1<<23); - val = (int)floor(v+0.5); - } - if (!val) val = 1; - if (IsDlgButtonChecked(hWnd, id+1) == BST_CHECKED) { - val = -val; - } - return val; +int GetLogSliderVal(HWND hWnd, int id) +{ + HWND hWndSlider = GetDlgItem(hWnd, id); + int val = SendMessage(hWndSlider, TBM_GETPOS, 0, 0); + if (val <= (1 << 21)) { + val = (val + 16) >> 5; + } else { + double v = (val - (1 << 21)) / (double)((1 << 22) - (1 << 21)); + double max = log((double)(1 << 23)); + double min = log((double)BASE_SENSITIVITY); + v = v * (max - min) + min; + // exp is not implemented in ntdll, so use pow instead. + // More than accurate enough for my needs. + // v = exp(v); + v = pow(2.7182818284590451, v); + if (v > (1 << 23)) + v = (1 << 23); + val = (int)floor(v + 0.5); + } + if (!val) + val = 1; + if (IsDlgButtonChecked(hWnd, id + 1) == BST_CHECKED) { + val = -val; + } + return val; } -void SetLogSliderVal(HWND hWnd, int id, HWND hWndText, int val) { - HWND hWndSlider = GetDlgItem(hWnd, id); - int sliderPos = 0; - wchar_t temp[30]; - EnableWindow(hWndSlider, val != 0); - EnableWindow(hWndText, val != 0); - EnableWindow(GetDlgItem(hWnd, id+1), val != 0); - if (!val) val = BASE_SENSITIVITY; - CheckDlgButton(hWnd, id+1, BST_CHECKED * (val<0)); - if (val < 0) { - val = -val; - } - if (val <= BASE_SENSITIVITY) { - sliderPos = val<<5; - } - else { - double max = log((double)(1<<23)); - double min = log((double)BASE_SENSITIVITY); - double v = log((double)(val)); - v = (v-min)/(max-min); - v = ((1<<22)- (1<<21)) *v + (1<<21); - // _ftol - sliderPos = (int)(floor(v+0.5)); - } - SendMessage(hWndSlider, TBM_SETPOS, 1, sliderPos); - int val2 = (int)(1000*(__int64)val/BASE_SENSITIVITY); - wsprintfW(temp, L"%i.%03i", val2/1000, val2%1000); - SetWindowTextW(hWndText, temp); +void SetLogSliderVal(HWND hWnd, int id, HWND hWndText, int val) +{ + HWND hWndSlider = GetDlgItem(hWnd, id); + int sliderPos = 0; + wchar_t temp[30]; + EnableWindow(hWndSlider, val != 0); + EnableWindow(hWndText, val != 0); + EnableWindow(GetDlgItem(hWnd, id + 1), val != 0); + if (!val) + val = BASE_SENSITIVITY; + CheckDlgButton(hWnd, id + 1, BST_CHECKED * (val < 0)); + if (val < 0) { + val = -val; + } + if (val <= BASE_SENSITIVITY) { + sliderPos = val << 5; + } else { + double max = log((double)(1 << 23)); + double min = log((double)BASE_SENSITIVITY); + double v = log((double)(val)); + v = (v - min) / (max - min); + v = ((1 << 22) - (1 << 21)) * v + (1 << 21); + // _ftol + sliderPos = (int)(floor(v + 0.5)); + } + SendMessage(hWndSlider, TBM_SETPOS, 1, sliderPos); + int val2 = (int)(1000 * (__int64)val / BASE_SENSITIVITY); + wsprintfW(temp, L"%i.%03i", val2 / 1000, val2 % 1000); + SetWindowTextW(hWndText, temp); } -void RefreshEnabledDevices(int updateDeviceList) { - // Clears all device state. - static int lastXInputState = -1; - if (updateDeviceList || lastXInputState != config.gameApis.xInput) { - EnumDevices(config.gameApis.xInput); - lastXInputState = config.gameApis.xInput; - } +void RefreshEnabledDevices(int updateDeviceList) +{ + // Clears all device state. + static int lastXInputState = -1; + if (updateDeviceList || lastXInputState != config.gameApis.xInput) { + EnumDevices(config.gameApis.xInput); + lastXInputState = config.gameApis.xInput; + } - for (int i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; + for (int i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; - if (!dev->attached && dev->displayName[0] != '[') { - wchar_t *newName = (wchar_t*) malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12)); - wsprintfW(newName, L"[Detached] %s", dev->displayName); - free(dev->displayName); - dev->displayName = newName; - } + if (!dev->attached && dev->displayName[0] != '[') { + wchar_t *newName = (wchar_t *)malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12)); + wsprintfW(newName, L"[Detached] %s", dev->displayName); + free(dev->displayName); + dev->displayName = newName; + } - if ((dev->type == KEYBOARD && dev->api == IGNORE_KEYBOARD) || - (dev->type == KEYBOARD && dev->api == config.keyboardApi) || - (dev->type == MOUSE && dev->api == config.mouseApi) || - (dev->type == OTHER && - ((dev->api == DI && config.gameApis.directInput) || - (dev->api == DS3 && config.gameApis.dualShock3) || - (dev->api == XINPUT && config.gameApis.xInput)))) { - if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName && - !wcsicmp(dev->displayName, L"DX PLAYSTATION(R)3 Controller")) { - dm->DisableDevice(i); - } - else { - dm->EnableDevice(i); - } - } - else { - dm->DisableDevice(i); - } - } + if ((dev->type == KEYBOARD && dev->api == IGNORE_KEYBOARD) || + (dev->type == KEYBOARD && dev->api == config.keyboardApi) || + (dev->type == MOUSE && dev->api == config.mouseApi) || + (dev->type == OTHER && + ((dev->api == DI && config.gameApis.directInput) || + (dev->api == DS3 && config.gameApis.dualShock3) || + (dev->api == XINPUT && config.gameApis.xInput)))) { + if (config.gameApis.dualShock3 && dev->api == DI && dev->displayName && + !wcsicmp(dev->displayName, L"DX PLAYSTATION(R)3 Controller")) { + dm->DisableDevice(i); + } else { + dm->EnableDevice(i); + } + } else { + dm->DisableDevice(i); + } + } } // Disables/enables devices as necessary. Also updates diagnostic list @@ -221,134 +225,137 @@ void RefreshEnabledDevices(int updateDeviceList) { // Must be called at some point when entering config mode, as I disable // (non-keyboard/mice) devices with no active bindings when the emulator's running. -void RefreshEnabledDevicesAndDisplay(int updateDeviceList = 0, HWND hWnd = 0, int populate=0) { - RefreshEnabledDevices(updateDeviceList); - if (hWnd) { - HWND hWndList = GetDlgItem(hWnd, IDC_LIST); - ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER); - int count = ListView_GetItemCount(hWndList); - LVITEM item; - item.iItem = 0; - item.iSubItem = 0; - item.mask = LVIF_TEXT | LVIF_PARAM; - for (int j=0; jnumDevices; j++) { - if (dm->devices[j]->enabled && dm->devices[j]->api != IGNORE_KEYBOARD) { - item.lParam = j; - item.pszText = dm->devices[j]->displayName; - if (count > 0) { - ListView_SetItem(hWndList, &item); - count --; - } - else { - ListView_InsertItem(hWndList, &item); - } - item.iItem++; - } - } - // This way, won't scroll list to start. - while(count > 0) { - ListView_DeleteItem(hWndList, item.iItem); - count --; - } - } - if (populate) { - for (int i=0; i<8; i++) { - Populate(i&1, i>>1); - } - } -} - -wchar_t *GetCommandStringW(u8 command, int port, int slot) { - static wchar_t temp[34]; - if (command >= 0x20 && command <= 0x27) { - if (config.padConfigs[port][slot].type == GuitarPad && (command == 0x20 || command == 0x22)) { - HWND hWnd = GetDlgItem(hWnds[port][slot], 0x10F0+command); - int res = GetWindowTextW(hWnd, temp, 20); - if ((unsigned int)res-1 <= 18) return temp; - } - static wchar_t stick[2] = {'L', 'R'}; - static wchar_t *dir[] = { - L"Up", L"Right", - L"Down", L"Left"}; - wsprintfW(temp, L"%c-Stick %s", stick[(command-0x20)/4], dir[command & 3]); - return temp; - } - /* Get text from the buttons. */ - if (command >= 0x0C && command <=0x28) { - HWND hWnd = GetDlgItem(hWnds[port][slot], 0x10F0+command); - if (!hWnd) { - wchar_t *strings[] = { - L"Lock Buttons", - L"Lock Input", - L"Lock Direction", - L"Mouse", - L"Select", - L"L3", - L"R3", - L"Start", - L"Up", - L"Right", - L"Down", - L"Left", - L"L2", - L"R2", - L"L1", - L"R1", - L"Triangle", - L"Circle", - L"Square", - L"Cross", - L"L-Stick Up", - L"L-Stick Right", - L"L-Stick Down", - L"L-Stick Left", - L"R-Stick Up", - L"R-Stick Right", - L"R-Stick Down", - L"R-Stick Left", - L"Analog", - }; - return strings[command - 0xC]; - } - int res = GetWindowTextW(hWnd, temp, 20); - if ((unsigned int)res-1 <= 18) return temp; - } - else if (command == 0x7F) { - return L"Ignore Key"; - } - return L""; -} - -static wchar_t iniFile[MAX_PATH*2] = L"inis/LilyPad.ini"; - -void CALLBACK PADsetSettingsDir( const char *dir ) +void RefreshEnabledDevicesAndDisplay(int updateDeviceList = 0, HWND hWnd = 0, int populate = 0) { - //swprintf_s( iniFile, L"%S", (dir==NULL) ? "inis" : dir ); - - //uint targlen = MultiByteToWideChar(CP_ACP, 0, dir, -1, NULL, 0); - MultiByteToWideChar(CP_ACP, 0, dir, -1, iniFile, MAX_PATH*2); - wcscat_s(iniFile, L"/LilyPad.ini"); + RefreshEnabledDevices(updateDeviceList); + if (hWnd) { + HWND hWndList = GetDlgItem(hWnd, IDC_LIST); + ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER); + int count = ListView_GetItemCount(hWndList); + LVITEM item; + item.iItem = 0; + item.iSubItem = 0; + item.mask = LVIF_TEXT | LVIF_PARAM; + for (int j = 0; j < dm->numDevices; j++) { + if (dm->devices[j]->enabled && dm->devices[j]->api != IGNORE_KEYBOARD) { + item.lParam = j; + item.pszText = dm->devices[j]->displayName; + if (count > 0) { + ListView_SetItem(hWndList, &item); + count--; + } else { + ListView_InsertItem(hWndList, &item); + } + item.iItem++; + } + } + // This way, won't scroll list to start. + while (count > 0) { + ListView_DeleteItem(hWndList, item.iItem); + count--; + } + } + if (populate) { + for (int i = 0; i < 8; i++) { + Populate(i & 1, i >> 1); + } + } +} - createIniDir = false; +wchar_t *GetCommandStringW(u8 command, int port, int slot) +{ + static wchar_t temp[34]; + if (command >= 0x20 && command <= 0x27) { + if (config.padConfigs[port][slot].type == GuitarPad && (command == 0x20 || command == 0x22)) { + HWND hWnd = GetDlgItem(hWnds[port][slot], 0x10F0 + command); + int res = GetWindowTextW(hWnd, temp, 20); + if ((unsigned int)res - 1 <= 18) + return temp; + } + static wchar_t stick[2] = {'L', 'R'}; + static wchar_t *dir[] = { + L"Up", L"Right", + L"Down", L"Left"}; + wsprintfW(temp, L"%c-Stick %s", stick[(command - 0x20) / 4], dir[command & 3]); + return temp; + } + /* Get text from the buttons. */ + if (command >= 0x0C && command <= 0x28) { + HWND hWnd = GetDlgItem(hWnds[port][slot], 0x10F0 + command); + if (!hWnd) { + wchar_t *strings[] = { + L"Lock Buttons", + L"Lock Input", + L"Lock Direction", + L"Mouse", + L"Select", + L"L3", + L"R3", + L"Start", + L"Up", + L"Right", + L"Down", + L"Left", + L"L2", + L"R2", + L"L1", + L"R1", + L"Triangle", + L"Circle", + L"Square", + L"Cross", + L"L-Stick Up", + L"L-Stick Right", + L"L-Stick Down", + L"L-Stick Left", + L"R-Stick Up", + L"R-Stick Right", + L"R-Stick Down", + L"R-Stick Left", + L"Analog", + }; + return strings[command - 0xC]; + } + int res = GetWindowTextW(hWnd, temp, 20); + if ((unsigned int)res - 1 <= 18) + return temp; + } else if (command == 0x7F) { + return L"Ignore Key"; + } + return L""; +} - FILE *temp = nullptr; - _wfopen_s(&temp, iniFile, L"r"); - if (!temp) { // File not found, possibly. - HRSRC res = FindResource(hInst, MAKEINTRESOURCE(IDR_INI1), RT_RCDATA); - if (!res) return; - HGLOBAL data = LoadResource(hInst, res); - if (!data) return; - size_t size = SizeofResource(hInst, res); - u8 *fdata = (u8*)LockResource(data); - _wfopen_s(&temp, iniFile, L"w"); - if (!temp) return; - fwrite(fdata, 1, size, temp); - fclose(temp); - } - else { - fclose(temp); - } - +static wchar_t iniFile[MAX_PATH * 2] = L"inis/LilyPad.ini"; + +void CALLBACK PADsetSettingsDir(const char *dir) +{ + //swprintf_s( iniFile, L"%S", (dir==NULL) ? "inis" : dir ); + + //uint targlen = MultiByteToWideChar(CP_ACP, 0, dir, -1, NULL, 0); + MultiByteToWideChar(CP_ACP, 0, dir, -1, iniFile, MAX_PATH * 2); + wcscat_s(iniFile, L"/LilyPad.ini"); + + createIniDir = false; + + FILE *temp = nullptr; + _wfopen_s(&temp, iniFile, L"r"); + if (!temp) { // File not found, possibly. + HRSRC res = FindResource(hInst, MAKEINTRESOURCE(IDR_INI1), RT_RCDATA); + if (!res) + return; + HGLOBAL data = LoadResource(hInst, res); + if (!data) + return; + size_t size = SizeofResource(hInst, res); + u8 *fdata = (u8 *)LockResource(data); + _wfopen_s(&temp, iniFile, L"w"); + if (!temp) + return; + fwrite(fdata, 1, size, temp); + fclose(temp); + } else { + fclose(temp); + } } int GetBinding(int port, int slot, int index, Device *&dev, Binding *&b, ForceFeedbackBinding *&ffb); @@ -356,1761 +363,1806 @@ int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int s int CreateEffectBinding(Device *dev, wchar_t *effectName, unsigned int port, unsigned int slot, unsigned int motor, ForceFeedbackBinding **binding); -void SelChanged(int port, int slot) { - HWND hWnd = hWnds[port][slot]; - if (!hWnd) return; - HWND hWndTemp, hWndList = GetDlgItem(hWnd, IDC_LIST); - int j, i = ListView_GetSelectedCount(hWndList); - wchar_t *devName = L"N/A"; - wchar_t *key = L"N/A"; - wchar_t *command = L"N/A"; - // Second value is now turbo. - int turbo = -1; - int sensitivity = 0; - int deadZone = 0; - int nonButtons = 0; - // Set if sensitivity != 0, but need to disable flip anyways. - // Only used to relative axes. - int disableFlip = 0; - wchar_t temp[4][1000]; - Device *dev; - int bFound = 0; - int ffbFound = 0; - ForceFeedbackBinding *ffb = 0; - Binding *b = 0; - if (i >= 1) { - int index = -1; - int flipped = 0; - while (1) { - index = ListView_GetNextItem(hWndList, index, LVNI_SELECTED); - if (index < 0) break; - LVITEMW item; - item.iItem = index; - item.mask = LVIF_TEXT; - item.pszText = temp[3]; - for (j=0; j<3; j++) { - item.iSubItem = j; - item.cchTextMax = sizeof(temp[0])/sizeof(temp[3][0]); - if (!ListView_GetItem(hWndList, &item)) break; - if (!bFound && !ffbFound) - wcscpy(temp[j], temp[3]); - else if (wcsicmp(temp[j], temp[3])) { - int q = 0; - while (temp[j][q] == temp[3][q]) q++; - if (q && temp[j][q-1] == ' ' && temp[j][q] && temp[j][q+1] == 0) q--; - if (j == 1) { - // Really ugly, but merges labels for multiple directions for same axis. - if ((temp[j][q] == 0 || (temp[j][q] == ' ' && temp[j][q+2] == 0)) && - (temp[3][q] == 0 || (temp[3][q] == ' ' && temp[3][q+2] == 0))) { - temp[j][q] = 0; - continue; - } - } - // Merge different directions for same stick. - else if (j == 2 && q > 4) { - temp[j][q] = 0; - continue; - } - wcscpy(temp[j], L"*"); - } - } - if (j == 3) { - devName = temp[0]; - key = temp[1]; - command = temp[2]; - if (GetBinding(port, slot, index, dev, b, ffb)) { - if (b) { - bFound ++; - VirtualControl *control = &dev->virtualControls[b->controlIndex]; - // Ignore - if (b->command != 0x7F) { - // Only relative axes can't have negative sensitivity. - if (((control->uid >> 16) & 0xFF) == RELAXIS) { - disableFlip = 1; - } - turbo += b->turbo; - if (b->sensitivity < 0) { - flipped ++; - sensitivity -= b->sensitivity; - } - else { - sensitivity += b->sensitivity; - } - if (((control->uid >> 16)&0xFF) != PSHBTN && ((control->uid >> 16)&0xFF) != TGLBTN) { - deadZone += b->deadZone; - nonButtons++; - } - } - else disableFlip = 1; - } - else ffbFound++; - } - } - } - if ((bFound && ffbFound) || ffbFound > 1) { - ffb = 0; - turbo = -1; - deadZone = 0; - sensitivity = 0; - disableFlip = 1; - bFound = ffbFound = 0; - } - else if (bFound) { - turbo++; - sensitivity /= bFound; - if (nonButtons) { - deadZone /= nonButtons; - } - if (bFound > 1) disableFlip = 1; - else if (flipped) { - sensitivity = -sensitivity; - } - } - } +void SelChanged(int port, int slot) +{ + HWND hWnd = hWnds[port][slot]; + if (!hWnd) + return; + HWND hWndTemp, hWndList = GetDlgItem(hWnd, IDC_LIST); + int j, i = ListView_GetSelectedCount(hWndList); + wchar_t *devName = L"N/A"; + wchar_t *key = L"N/A"; + wchar_t *command = L"N/A"; + // Second value is now turbo. + int turbo = -1; + int sensitivity = 0; + int deadZone = 0; + int nonButtons = 0; + // Set if sensitivity != 0, but need to disable flip anyways. + // Only used to relative axes. + int disableFlip = 0; + wchar_t temp[4][1000]; + Device *dev; + int bFound = 0; + int ffbFound = 0; + ForceFeedbackBinding *ffb = 0; + Binding *b = 0; + if (i >= 1) { + int index = -1; + int flipped = 0; + while (1) { + index = ListView_GetNextItem(hWndList, index, LVNI_SELECTED); + if (index < 0) + break; + LVITEMW item; + item.iItem = index; + item.mask = LVIF_TEXT; + item.pszText = temp[3]; + for (j = 0; j < 3; j++) { + item.iSubItem = j; + item.cchTextMax = sizeof(temp[0]) / sizeof(temp[3][0]); + if (!ListView_GetItem(hWndList, &item)) + break; + if (!bFound && !ffbFound) + wcscpy(temp[j], temp[3]); + else if (wcsicmp(temp[j], temp[3])) { + int q = 0; + while (temp[j][q] == temp[3][q]) + q++; + if (q && temp[j][q - 1] == ' ' && temp[j][q] && temp[j][q + 1] == 0) + q--; + if (j == 1) { + // Really ugly, but merges labels for multiple directions for same axis. + if ((temp[j][q] == 0 || (temp[j][q] == ' ' && temp[j][q + 2] == 0)) && + (temp[3][q] == 0 || (temp[3][q] == ' ' && temp[3][q + 2] == 0))) { + temp[j][q] = 0; + continue; + } + } + // Merge different directions for same stick. + else if (j == 2 && q > 4) { + temp[j][q] = 0; + continue; + } + wcscpy(temp[j], L"*"); + } + } + if (j == 3) { + devName = temp[0]; + key = temp[1]; + command = temp[2]; + if (GetBinding(port, slot, index, dev, b, ffb)) { + if (b) { + bFound++; + VirtualControl *control = &dev->virtualControls[b->controlIndex]; + // Ignore + if (b->command != 0x7F) { + // Only relative axes can't have negative sensitivity. + if (((control->uid >> 16) & 0xFF) == RELAXIS) { + disableFlip = 1; + } + turbo += b->turbo; + if (b->sensitivity < 0) { + flipped++; + sensitivity -= b->sensitivity; + } else { + sensitivity += b->sensitivity; + } + if (((control->uid >> 16) & 0xFF) != PSHBTN && ((control->uid >> 16) & 0xFF) != TGLBTN) { + deadZone += b->deadZone; + nonButtons++; + } + } else + disableFlip = 1; + } else + ffbFound++; + } + } + } + if ((bFound && ffbFound) || ffbFound > 1) { + ffb = 0; + turbo = -1; + deadZone = 0; + sensitivity = 0; + disableFlip = 1; + bFound = ffbFound = 0; + } else if (bFound) { + turbo++; + sensitivity /= bFound; + if (nonButtons) { + deadZone /= nonButtons; + } + if (bFound > 1) + disableFlip = 1; + else if (flipped) { + sensitivity = -sensitivity; + } + } + } - for (i=IDC_SLIDER1; i= IDC_FF_AXIS1_ENABLED) { - int index = (i - IDC_FF_AXIS1_ENABLED) / 16; - if (index >= dev->numFFAxes) { - enable = 0; - } - else { - int type = i - index*16; - AxisEffectInfo *info = 0; - if (dev->numFFAxes > index) { - info = ffb->axes+index; - } - if (type == IDC_FF_AXIS1) { - // takes care of IDC_FF_AXIS1_FLIP as well. - SetupLogSlider(hWndTemp); - int force = 0; - if (info) { - force = info->force; - } - SetLogSliderVal(hWnd, i, GetDlgItem(hWnd, i-IDC_FF_AXIS1+IDC_FF_AXIS1_SCALE), force); - } - else if (type == IDC_FF_AXIS1_ENABLED) { - CheckDlgButton(hWnd, i, BST_CHECKED * (info->force!=0)); - wsprintfW(temp[0], L"Axis %i", index+1); - if (dev->ffAxes[index].displayName && wcslen(dev->ffAxes[index].displayName) < 50) { - wchar_t *end = wcschr(temp[0], 0); - wsprintfW(end, L": %s", dev->ffAxes[index].displayName); - } - SetWindowText(hWndTemp, temp[0]); - } - } - } - ShowWindow(hWndTemp, enable); - } - } - if (!ffb) { - SetLogSliderVal(hWnd, IDC_SLIDER1, GetDlgItem(hWnd, IDC_AXIS_SENSITIVITY1), sensitivity); - SetLogSliderVal(hWnd, IDC_SLIDER_DEADZONE, GetDlgItem(hWnd, IDC_AXIS_DEADZONE), deadZone); + for (i = IDC_SLIDER1; i < ID_DELETE; i++) { + hWndTemp = GetDlgItem(hWnd, i); + if (hWndTemp) + ShowWindow(hWndTemp, ffb == 0); + } + for (i = 0x1300; i < 0x1400; i++) { + hWndTemp = GetDlgItem(hWnd, i); + if (hWndTemp) { + int enable = ffb != 0; + if (ffb && i >= IDC_FF_AXIS1_ENABLED) { + int index = (i - IDC_FF_AXIS1_ENABLED) / 16; + if (index >= dev->numFFAxes) { + enable = 0; + } else { + int type = i - index * 16; + AxisEffectInfo *info = 0; + if (dev->numFFAxes > index) { + info = ffb->axes + index; + } + if (type == IDC_FF_AXIS1) { + // takes care of IDC_FF_AXIS1_FLIP as well. + SetupLogSlider(hWndTemp); + int force = 0; + if (info) { + force = info->force; + } + SetLogSliderVal(hWnd, i, GetDlgItem(hWnd, i - IDC_FF_AXIS1 + IDC_FF_AXIS1_SCALE), force); + } else if (type == IDC_FF_AXIS1_ENABLED) { + CheckDlgButton(hWnd, i, BST_CHECKED * (info->force != 0)); + wsprintfW(temp[0], L"Axis %i", index + 1); + if (dev->ffAxes[index].displayName && wcslen(dev->ffAxes[index].displayName) < 50) { + wchar_t *end = wcschr(temp[0], 0); + wsprintfW(end, L": %s", dev->ffAxes[index].displayName); + } + SetWindowText(hWndTemp, temp[0]); + } + } + } + ShowWindow(hWndTemp, enable); + } + } + if (!ffb) { + SetLogSliderVal(hWnd, IDC_SLIDER1, GetDlgItem(hWnd, IDC_AXIS_SENSITIVITY1), sensitivity); + SetLogSliderVal(hWnd, IDC_SLIDER_DEADZONE, GetDlgItem(hWnd, IDC_AXIS_DEADZONE), deadZone); - if (disableFlip) EnableWindow(GetDlgItem(hWnd, IDC_FLIP1), 0); + if (disableFlip) + EnableWindow(GetDlgItem(hWnd, IDC_FLIP1), 0); - EnableWindow(GetDlgItem(hWnd, IDC_TURBO), turbo >= 0); - if (turbo > 0 && turbo < bFound) { - SendMessage(GetDlgItem(hWnd, IDC_TURBO), BM_SETSTYLE, BS_AUTO3STATE, 0); - CheckDlgButton(hWnd, IDC_TURBO, BST_INDETERMINATE); - } - else { - SendMessage(GetDlgItem(hWnd, IDC_TURBO), BM_SETSTYLE, BS_AUTOCHECKBOX, 0); - CheckDlgButton(hWnd, IDC_TURBO, BST_CHECKED * (bFound && turbo == bFound)); - } - HWND hWndCombo = GetDlgItem(hWnd, IDC_AXIS_DIRECTION); - int enableCombo = 0; - SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0); - if (b && bFound == 1) { - VirtualControl *control = &dev->virtualControls[b->controlIndex]; - unsigned int uid = control->uid; - if (((uid>>16) & 0xFF) == ABSAXIS) { - enableCombo = 1; - wchar_t *endings[3] = {L" -", L" +", L""}; - wchar_t *string = temp[3]; - wcscpy(string, key); - wchar_t *end = wcschr(string, 0); - int sel = 2; - if (!(uid & UID_AXIS)) { - end[-2] = 0; - sel = (end[-1] == '+'); - end -= 2; - } - for (int i=0; i<3; i++) { - wcscpy(end, endings[i]); - SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) string); - if (i == sel) - SendMessage(hWndCombo, CB_SETCURSEL, i, 0); - } - } - } - EnableWindow(hWndCombo, enableCombo); - if (!enableCombo) { - SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) key); - SendMessage(hWndCombo, CB_SELECTSTRING, i, (LPARAM) key); - } + EnableWindow(GetDlgItem(hWnd, IDC_TURBO), turbo >= 0); + if (turbo > 0 && turbo < bFound) { + SendMessage(GetDlgItem(hWnd, IDC_TURBO), BM_SETSTYLE, BS_AUTO3STATE, 0); + CheckDlgButton(hWnd, IDC_TURBO, BST_INDETERMINATE); + } else { + SendMessage(GetDlgItem(hWnd, IDC_TURBO), BM_SETSTYLE, BS_AUTOCHECKBOX, 0); + CheckDlgButton(hWnd, IDC_TURBO, BST_CHECKED * (bFound && turbo == bFound)); + } + HWND hWndCombo = GetDlgItem(hWnd, IDC_AXIS_DIRECTION); + int enableCombo = 0; + SendMessage(hWndCombo, CB_RESETCONTENT, 0, 0); + if (b && bFound == 1) { + VirtualControl *control = &dev->virtualControls[b->controlIndex]; + unsigned int uid = control->uid; + if (((uid >> 16) & 0xFF) == ABSAXIS) { + enableCombo = 1; + wchar_t *endings[3] = {L" -", L" +", L""}; + wchar_t *string = temp[3]; + wcscpy(string, key); + wchar_t *end = wcschr(string, 0); + int sel = 2; + if (!(uid & UID_AXIS)) { + end[-2] = 0; + sel = (end[-1] == '+'); + end -= 2; + } + for (int i = 0; i < 3; i++) { + wcscpy(end, endings[i]); + SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM)string); + if (i == sel) + SendMessage(hWndCombo, CB_SETCURSEL, i, 0); + } + } + } + EnableWindow(hWndCombo, enableCombo); + if (!enableCombo) { + SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM)key); + SendMessage(hWndCombo, CB_SELECTSTRING, i, (LPARAM)key); + } - SetDlgItemText(hWnd, IDC_AXIS_DEVICE1, devName); - SetDlgItemText(hWnd, IDC_AXIS_CONTROL1, command); - } - else { - wchar_t temp2[2000]; - wsprintfW(temp2, L"%s / %s", devName, command); - SetDlgItemText(hWnd, ID_FF, temp2); + SetDlgItemText(hWnd, IDC_AXIS_DEVICE1, devName); + SetDlgItemText(hWnd, IDC_AXIS_CONTROL1, command); + } else { + wchar_t temp2[2000]; + wsprintfW(temp2, L"%s / %s", devName, command); + SetDlgItemText(hWnd, ID_FF, temp2); - hWndTemp = GetDlgItem(hWnd, IDC_FF_EFFECT); - SendMessage(hWndTemp, CB_RESETCONTENT, 0, 0); - for (i=0; inumFFEffectTypes; i++) { - SendMessage(hWndTemp, CB_INSERTSTRING, i, (LPARAM)dev->ffEffectTypes[i].displayName); - } - SendMessage(hWndTemp, CB_SETCURSEL, ffb->effectIndex, 0); - EnableWindow(hWndTemp, dev->numFFEffectTypes>1); - } + hWndTemp = GetDlgItem(hWnd, IDC_FF_EFFECT); + SendMessage(hWndTemp, CB_RESETCONTENT, 0, 0); + for (i = 0; i < dev->numFFEffectTypes; i++) { + SendMessage(hWndTemp, CB_INSERTSTRING, i, (LPARAM)dev->ffEffectTypes[i].displayName); + } + SendMessage(hWndTemp, CB_SETCURSEL, ffb->effectIndex, 0); + EnableWindow(hWndTemp, dev->numFFEffectTypes > 1); + } } -void UnselectAll(HWND hWnd) { - int i = ListView_GetSelectedCount(hWnd); - while (i-- > 0) { - int index = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED); - ListView_SetItemState(hWnd, index, 0, LVIS_SELECTED); - } +void UnselectAll(HWND hWnd) +{ + int i = ListView_GetSelectedCount(hWnd); + while (i-- > 0) { + int index = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED); + ListView_SetItemState(hWnd, index, 0, LVIS_SELECTED); + } } -int GetItemIndex(int port, int slot, Device *dev, ForceFeedbackBinding *binding) { - int count = 0; - for (int i = 0; inumDevices; i++) { - Device *dev2 = dm->devices[i]; - if (!dev2->enabled) continue; - if (dev2 != dev) { - count += dev2->pads[port][slot].numBindings + dev2->pads[port][slot].numFFBindings; - continue; - } - return count += dev2->pads[port][slot].numBindings + (binding - dev2->pads[port][slot].ffBindings); - } - return -1; +int GetItemIndex(int port, int slot, Device *dev, ForceFeedbackBinding *binding) +{ + int count = 0; + for (int i = 0; i < dm->numDevices; i++) { + Device *dev2 = dm->devices[i]; + if (!dev2->enabled) + continue; + if (dev2 != dev) { + count += dev2->pads[port][slot].numBindings + dev2->pads[port][slot].numFFBindings; + continue; + } + return count += dev2->pads[port][slot].numBindings + (binding - dev2->pads[port][slot].ffBindings); + } + return -1; } -int GetItemIndex(int port, int slot, Device *dev, Binding *binding) { - int count = 0; - for (int i = 0; inumDevices; i++) { - Device *dev2 = dm->devices[i]; - if (!dev2->enabled) continue; - if (dev2 != dev) { - count += dev2->pads[port][slot].numBindings + dev2->pads[port][slot].numFFBindings; - continue; - } - return count += binding - dev->pads[port][slot].bindings; - } - return -1; +int GetItemIndex(int port, int slot, Device *dev, Binding *binding) +{ + int count = 0; + for (int i = 0; i < dm->numDevices; i++) { + Device *dev2 = dm->devices[i]; + if (!dev2->enabled) + continue; + if (dev2 != dev) { + count += dev2->pads[port][slot].numBindings + dev2->pads[port][slot].numFFBindings; + continue; + } + return count += binding - dev->pads[port][slot].bindings; + } + return -1; } // Doesn't check if already displayed. -int ListBoundCommand(int port, int slot, Device *dev, Binding *b) { - if (!hWnds[port][slot]) return -1; - HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); - int index = -1; - if (hWndList) { - index = GetItemIndex(port, slot, dev, b); - if (index >= 0) { - LVITEM item; - item.mask = LVIF_TEXT; - item.pszText = dev->displayName; - item.iItem = index; - item.iSubItem = 0; - SendMessage(hWndList, LVM_INSERTITEM, 0, (LPARAM)&item); - item.mask = LVIF_TEXT; - item.iSubItem = 1; - item.pszText = dev->GetVirtualControlName(&dev->virtualControls[b->controlIndex]); - SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); - item.iSubItem = 2; - item.pszText = GetCommandStringW(b->command, port, slot); - SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); - } - } - return index; +int ListBoundCommand(int port, int slot, Device *dev, Binding *b) +{ + if (!hWnds[port][slot]) + return -1; + HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); + int index = -1; + if (hWndList) { + index = GetItemIndex(port, slot, dev, b); + if (index >= 0) { + LVITEM item; + item.mask = LVIF_TEXT; + item.pszText = dev->displayName; + item.iItem = index; + item.iSubItem = 0; + SendMessage(hWndList, LVM_INSERTITEM, 0, (LPARAM)&item); + item.mask = LVIF_TEXT; + item.iSubItem = 1; + item.pszText = dev->GetVirtualControlName(&dev->virtualControls[b->controlIndex]); + SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); + item.iSubItem = 2; + item.pszText = GetCommandStringW(b->command, port, slot); + SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); + } + } + return index; } -int ListBoundEffect(int port, int slot, Device *dev, ForceFeedbackBinding *b) { - if (!hWnds[port][slot]) return -1; - HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); - int index = -1; - if (hWndList) { - index = GetItemIndex(port, slot, dev, b); - if (index >= 0) { - LVITEM item; - item.mask = LVIF_TEXT; - item.pszText = dev->displayName; - item.iItem = index; - item.iSubItem = 0; - SendMessage(hWndList, LVM_INSERTITEM, 0, (LPARAM)&item); - item.mask = LVIF_TEXT; - item.iSubItem = 1; - item.pszText = dev->ffEffectTypes[b->effectIndex].displayName; - SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); - item.iSubItem = 2; - wchar_t *ps2Motors[2] = {L"Big Motor", L"Small Motor"}; - item.pszText = ps2Motors[b->motor]; - SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); - } - } - return index; +int ListBoundEffect(int port, int slot, Device *dev, ForceFeedbackBinding *b) +{ + if (!hWnds[port][slot]) + return -1; + HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); + int index = -1; + if (hWndList) { + index = GetItemIndex(port, slot, dev, b); + if (index >= 0) { + LVITEM item; + item.mask = LVIF_TEXT; + item.pszText = dev->displayName; + item.iItem = index; + item.iSubItem = 0; + SendMessage(hWndList, LVM_INSERTITEM, 0, (LPARAM)&item); + item.mask = LVIF_TEXT; + item.iSubItem = 1; + item.pszText = dev->ffEffectTypes[b->effectIndex].displayName; + SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); + item.iSubItem = 2; + wchar_t *ps2Motors[2] = {L"Big Motor", L"Small Motor"}; + item.pszText = ps2Motors[b->motor]; + SendMessage(hWndList, LVM_SETITEM, 0, (LPARAM)&item); + } + } + return index; } // Only for use with control bindings. Affects all highlighted bindings. -void ChangeValue(int port, int slot, int *newSensitivity, int *newTurbo, int *newDeadZone) { - if (!hWnds[port][slot]) return; - HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); - int count = ListView_GetSelectedCount(hWndList); - if (count < 1) return; - int index = -1; - while (1) { - index = ListView_GetNextItem(hWndList, index, LVNI_SELECTED); - if (index < 0) break; - Device *dev; - Binding *b; - ForceFeedbackBinding *ffb; - if (!GetBinding(port, slot, index, dev, b, ffb) || ffb) return; - if (newSensitivity) { - // Don't change flip state when modifying multiple controls. - if (count > 1 && b->sensitivity < 0) - b->sensitivity = -*newSensitivity; - else - b->sensitivity = *newSensitivity; - } - if (newDeadZone) { - if (b->deadZone) { - b->deadZone = *newDeadZone; - } - } - if (newTurbo) { - b->turbo = *newTurbo; - } - } - PropSheet_Changed(hWndProp, hWnds[port][slot]); - SelChanged(port, slot); +void ChangeValue(int port, int slot, int *newSensitivity, int *newTurbo, int *newDeadZone) +{ + if (!hWnds[port][slot]) + return; + HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); + int count = ListView_GetSelectedCount(hWndList); + if (count < 1) + return; + int index = -1; + while (1) { + index = ListView_GetNextItem(hWndList, index, LVNI_SELECTED); + if (index < 0) + break; + Device *dev; + Binding *b; + ForceFeedbackBinding *ffb; + if (!GetBinding(port, slot, index, dev, b, ffb) || ffb) + return; + if (newSensitivity) { + // Don't change flip state when modifying multiple controls. + if (count > 1 && b->sensitivity < 0) + b->sensitivity = -*newSensitivity; + else + b->sensitivity = *newSensitivity; + } + if (newDeadZone) { + if (b->deadZone) { + b->deadZone = *newDeadZone; + } + } + if (newTurbo) { + b->turbo = *newTurbo; + } + } + PropSheet_Changed(hWndProp, hWnds[port][slot]); + SelChanged(port, slot); } // Only for use with effect bindings. -void ChangeEffect(int port, int slot, int id, int *newForce, unsigned int *newEffectType) { - if (!hWnds[port][slot]) return; - HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); - int i = ListView_GetSelectedCount(hWndList); - if (i != 1) return; - int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - Device *dev; - Binding *b; - ForceFeedbackBinding *ffb; - if (!GetBinding(port, slot, index, dev, b, ffb) || b) return; - if (newForce) { - unsigned int axisIndex = (id - IDC_FF_AXIS1_ENABLED)/16; - if (axisIndex < (unsigned int)dev->numFFAxes) { - ffb->axes[axisIndex].force = *newForce; - } - } - if (newEffectType && *newEffectType < (unsigned int)dev->numFFEffectTypes) { - ffb->effectIndex = *newEffectType; - ListView_DeleteItem(hWndList, index); - index = ListBoundEffect(port, slot, dev, ffb); - ListView_SetItemState(hWndList, index, LVIS_SELECTED, LVIS_SELECTED); - } - PropSheet_Changed(hWndProp, hWnds[port][slot]); - SelChanged(port, slot); +void ChangeEffect(int port, int slot, int id, int *newForce, unsigned int *newEffectType) +{ + if (!hWnds[port][slot]) + return; + HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); + int i = ListView_GetSelectedCount(hWndList); + if (i != 1) + return; + int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + Device *dev; + Binding *b; + ForceFeedbackBinding *ffb; + if (!GetBinding(port, slot, index, dev, b, ffb) || b) + return; + if (newForce) { + unsigned int axisIndex = (id - IDC_FF_AXIS1_ENABLED) / 16; + if (axisIndex < (unsigned int)dev->numFFAxes) { + ffb->axes[axisIndex].force = *newForce; + } + } + if (newEffectType && *newEffectType < (unsigned int)dev->numFFEffectTypes) { + ffb->effectIndex = *newEffectType; + ListView_DeleteItem(hWndList, index); + index = ListBoundEffect(port, slot, dev, ffb); + ListView_SetItemState(hWndList, index, LVIS_SELECTED, LVIS_SELECTED); + } + PropSheet_Changed(hWndProp, hWnds[port][slot]); + SelChanged(port, slot); } -void Populate(int port, int slot) { - if (!hWnds[port][slot]) return; - HWND hWnd = GetDlgItem(hWnds[port][slot], IDC_LIST); - ListView_DeleteAllItems(hWnd); - int i, j; +void Populate(int port, int slot) +{ + if (!hWnds[port][slot]) + return; + HWND hWnd = GetDlgItem(hWnds[port][slot], IDC_LIST); + ListView_DeleteAllItems(hWnd); + int i, j; - int multipleBinding = config.multipleBinding; - config.multipleBinding = 1; - for (j=0; jnumDevices; j++) { - Device *dev = dm->devices[j]; - if (!dev->enabled) continue; - for (i=0; ipads[port][slot].numBindings; i++) { - ListBoundCommand(port, slot, dev, dev->pads[port][slot].bindings+i); - } - for (i=0; ipads[port][slot].numFFBindings; i++) { - ListBoundEffect(port, slot, dev, dev->pads[port][slot].ffBindings+i); - } - } - config.multipleBinding = multipleBinding; + int multipleBinding = config.multipleBinding; + config.multipleBinding = 1; + for (j = 0; j < dm->numDevices; j++) { + Device *dev = dm->devices[j]; + if (!dev->enabled) + continue; + for (i = 0; i < dev->pads[port][slot].numBindings; i++) { + ListBoundCommand(port, slot, dev, dev->pads[port][slot].bindings + i); + } + for (i = 0; i < dev->pads[port][slot].numFFBindings; i++) { + ListBoundEffect(port, slot, dev, dev->pads[port][slot].ffBindings + i); + } + } + config.multipleBinding = multipleBinding; - hWnd = GetDlgItem(hWnds[port][slot], IDC_FORCEFEEDBACK); - SendMessage(hWnd, CB_RESETCONTENT, 0, 0); - int added = 0; - for (i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; - if (dev->enabled && dev->numFFAxes && dev->numFFEffectTypes) { - SendMessage(hWnd, CB_INSERTSTRING, added, (LPARAM)dev->displayName); - SendMessage(hWnd, CB_SETITEMDATA, added, i); - added++; - } - } - SendMessage(hWnd, CB_SETCURSEL, 0, 0); - EnableWindow(hWnd, added!=0); - EnableWindow(GetDlgItem(hWnds[port][slot], ID_BIG_MOTOR), added!=0); - EnableWindow(GetDlgItem(hWnds[port][slot], ID_SMALL_MOTOR), added!=0); + hWnd = GetDlgItem(hWnds[port][slot], IDC_FORCEFEEDBACK); + SendMessage(hWnd, CB_RESETCONTENT, 0, 0); + int added = 0; + for (i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; + if (dev->enabled && dev->numFFAxes && dev->numFFEffectTypes) { + SendMessage(hWnd, CB_INSERTSTRING, added, (LPARAM)dev->displayName); + SendMessage(hWnd, CB_SETITEMDATA, added, i); + added++; + } + } + SendMessage(hWnd, CB_SETCURSEL, 0, 0); + EnableWindow(hWnd, added != 0); + EnableWindow(GetDlgItem(hWnds[port][slot], ID_BIG_MOTOR), added != 0); + EnableWindow(GetDlgItem(hWnds[port][slot], ID_SMALL_MOTOR), added != 0); - SelChanged(port, slot); + SelChanged(port, slot); } -int WritePrivateProfileInt(wchar_t *s1, wchar_t *s2, int v, wchar_t *ini) { - wchar_t temp[100]; - _itow(v, temp, 10); - return WritePrivateProfileStringW(s1, s2, temp, ini); +int WritePrivateProfileInt(wchar_t *s1, wchar_t *s2, int v, wchar_t *ini) +{ + wchar_t temp[100]; + _itow(v, temp, 10); + return WritePrivateProfileStringW(s1, s2, temp, ini); } -int SaveSettings(wchar_t *file=0) { +int SaveSettings(wchar_t *file = 0) +{ - // Need this either way for saving path. - if (!file) { - file = iniFile; - } - else { - wchar_t *c = wcsrchr(file, '\\'); - if (*c) { - *c = 0; - wcscpy(config.lastSaveConfigPath, file); - wcscpy(config.lastSaveConfigFileName, c+1); - *c = '\\'; - } - } - DeleteFileW(file); + // Need this either way for saving path. + if (!file) { + file = iniFile; + } else { + wchar_t *c = wcsrchr(file, '\\'); + if (*c) { + *c = 0; + wcscpy(config.lastSaveConfigPath, file); + wcscpy(config.lastSaveConfigFileName, c + 1); + *c = '\\'; + } + } + DeleteFileW(file); - WritePrivateProfileStringW(L"General Settings", L"Last Config Path", config.lastSaveConfigPath, iniFile); - WritePrivateProfileStringW(L"General Settings", L"Last Config Name", config.lastSaveConfigFileName, iniFile); + WritePrivateProfileStringW(L"General Settings", L"Last Config Path", config.lastSaveConfigPath, iniFile); + WritePrivateProfileStringW(L"General Settings", L"Last Config Name", config.lastSaveConfigFileName, iniFile); - // Just check first, last, and all pad bindings. Should be more than enough. No real need to check - // config path. - int noError = 1; + // Just check first, last, and all pad bindings. Should be more than enough. No real need to check + // config path. + int noError = 1; - for (int i=0; inumDevices; i++) { - wchar_t id[50]; - wchar_t temp[50], temp2[1000]; - wsprintfW(id, L"Device %i", i); - Device *dev = dm->devices[i]; - wchar_t *name = dev->displayName; - while (name[0] == '[') { - wchar_t *name2 = wcschr(name, ']'); - if (!name2) break; - name = name2+1; - while (iswspace(name[0])) name++; - } - WritePrivateProfileStringW(id, L"Display Name", name, file); - WritePrivateProfileStringW(id, L"Instance ID", dev->instanceID, file); - if (dev->productID) { - WritePrivateProfileStringW(id, L"Product ID", dev->productID, file); - } - WritePrivateProfileInt(id, L"API", dev->api, file); - WritePrivateProfileInt(id, L"Type", dev->type, file); - int ffBindingCount = 0; - int bindingCount = 0; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - for (int j=0; jpads[port][slot].numBindings; j++) { - Binding *b = dev->pads[port][slot].bindings+j; - VirtualControl *c = &dev->virtualControls[b->controlIndex]; - wsprintfW(temp, L"Binding %i", bindingCount++); - wsprintfW(temp2, L"0x%08X, %i, %i, %i, %i, %i, %i", c->uid, port, b->command, b->sensitivity, b->turbo, slot, b->deadZone); - noError &= WritePrivateProfileStringW(id, temp, temp2, file); - } - for (int j=0; jpads[port][slot].numFFBindings; j++) { - ForceFeedbackBinding *b = dev->pads[port][slot].ffBindings+j; - ForceFeedbackEffectType *eff = &dev->ffEffectTypes[b->effectIndex]; - wsprintfW(temp, L"FF Binding %i", ffBindingCount++); - wsprintfW(temp2, L"%s %i, %i, %i", eff->effectID, port, b->motor, slot); - for (int k=0; knumFFAxes; k++) { - ForceFeedbackAxis *axis = dev->ffAxes + k; - AxisEffectInfo *info = b->axes + k; - wsprintfW(wcschr(temp2,0), L", %i, %i", axis->id, info->force); - } - noError &= WritePrivateProfileStringW(id, temp, temp2, file); - } - } - } - } - if (!noError) { - MessageBoxA(hWndProp, "Unable to save settings. Make sure the disk is not full or write protected, the file isn't write protected, and that the app has permissions to write to the directory. On Vista, try running in administrator mode.", "Error Writing Configuration File", MB_OK | MB_ICONERROR); - } - return !noError; + for (int i = 0; i < dm->numDevices; i++) { + wchar_t id[50]; + wchar_t temp[50], temp2[1000]; + wsprintfW(id, L"Device %i", i); + Device *dev = dm->devices[i]; + wchar_t *name = dev->displayName; + while (name[0] == '[') { + wchar_t *name2 = wcschr(name, ']'); + if (!name2) + break; + name = name2 + 1; + while (iswspace(name[0])) + name++; + } + WritePrivateProfileStringW(id, L"Display Name", name, file); + WritePrivateProfileStringW(id, L"Instance ID", dev->instanceID, file); + if (dev->productID) { + WritePrivateProfileStringW(id, L"Product ID", dev->productID, file); + } + WritePrivateProfileInt(id, L"API", dev->api, file); + WritePrivateProfileInt(id, L"Type", dev->type, file); + int ffBindingCount = 0; + int bindingCount = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + for (int j = 0; j < dev->pads[port][slot].numBindings; j++) { + Binding *b = dev->pads[port][slot].bindings + j; + VirtualControl *c = &dev->virtualControls[b->controlIndex]; + wsprintfW(temp, L"Binding %i", bindingCount++); + wsprintfW(temp2, L"0x%08X, %i, %i, %i, %i, %i, %i", c->uid, port, b->command, b->sensitivity, b->turbo, slot, b->deadZone); + noError &= WritePrivateProfileStringW(id, temp, temp2, file); + } + for (int j = 0; j < dev->pads[port][slot].numFFBindings; j++) { + ForceFeedbackBinding *b = dev->pads[port][slot].ffBindings + j; + ForceFeedbackEffectType *eff = &dev->ffEffectTypes[b->effectIndex]; + wsprintfW(temp, L"FF Binding %i", ffBindingCount++); + wsprintfW(temp2, L"%s %i, %i, %i", eff->effectID, port, b->motor, slot); + for (int k = 0; k < dev->numFFAxes; k++) { + ForceFeedbackAxis *axis = dev->ffAxes + k; + AxisEffectInfo *info = b->axes + k; + wsprintfW(wcschr(temp2, 0), L", %i, %i", axis->id, info->force); + } + noError &= WritePrivateProfileStringW(id, temp, temp2, file); + } + } + } + } + if (!noError) { + MessageBoxA(hWndProp, "Unable to save settings. Make sure the disk is not full or write protected, the file isn't write protected, and that the app has permissions to write to the directory. On Vista, try running in administrator mode.", "Error Writing Configuration File", MB_OK | MB_ICONERROR); + } + return !noError; } -u8 GetPrivateProfileBool(wchar_t *s1, wchar_t *s2, int def, wchar_t *ini) { - return (0!=GetPrivateProfileIntW(s1, s2, def, ini)); +u8 GetPrivateProfileBool(wchar_t *s1, wchar_t *s2, int def, wchar_t *ini) +{ + return (0 != GetPrivateProfileIntW(s1, s2, def, ini)); } -int LoadSettings(int force, wchar_t *file) { - if (dm && !force) return 0; +int LoadSettings(int force, wchar_t *file) +{ + if (dm && !force) + return 0; - if( createIniDir ) - { - CreateDirectory(L"inis", 0); - createIniDir = false; - } + if (createIniDir) { + CreateDirectory(L"inis", 0); + createIniDir = false; + } - // Could just do ClearDevices() instead, but if I ever add any extra stuff, - // this will still work. - UnloadConfigs(); - dm = new InputDeviceManager(); + // Could just do ClearDevices() instead, but if I ever add any extra stuff, + // this will still work. + UnloadConfigs(); + dm = new InputDeviceManager(); - if (!file) { - file = iniFile; - GetPrivateProfileStringW(L"General Settings", L"Last Config Path", L"inis", config.lastSaveConfigPath, sizeof(config.lastSaveConfigPath), file); - GetPrivateProfileStringW(L"General Settings", L"Last Config Name", L"LilyPad.lily", config.lastSaveConfigFileName, sizeof(config.lastSaveConfigFileName), file); - } - else { - wchar_t *c = wcsrchr(file, '\\'); - if (c) { - *c = 0; - wcscpy(config.lastSaveConfigPath, file); - wcscpy(config.lastSaveConfigFileName, c+1); - *c = '\\'; - WritePrivateProfileStringW(L"General Settings", L"Last Config Path", config.lastSaveConfigPath, iniFile); - WritePrivateProfileStringW(L"General Settings", L"Last Config Name", config.lastSaveConfigFileName, iniFile); - } - } + if (!file) { + file = iniFile; + GetPrivateProfileStringW(L"General Settings", L"Last Config Path", L"inis", config.lastSaveConfigPath, sizeof(config.lastSaveConfigPath), file); + GetPrivateProfileStringW(L"General Settings", L"Last Config Name", L"LilyPad.lily", config.lastSaveConfigFileName, sizeof(config.lastSaveConfigFileName), file); + } else { + wchar_t *c = wcsrchr(file, '\\'); + if (c) { + *c = 0; + wcscpy(config.lastSaveConfigPath, file); + wcscpy(config.lastSaveConfigFileName, c + 1); + *c = '\\'; + WritePrivateProfileStringW(L"General Settings", L"Last Config Path", config.lastSaveConfigPath, iniFile); + WritePrivateProfileStringW(L"General Settings", L"Last Config Name", config.lastSaveConfigFileName, iniFile); + } + } - for (int i=0; i= 100) break; - continue; - } - wchar_t *id2 = 0; - if (GetPrivateProfileStringW(id, L"Product ID", 0, temp4, 1000, file) && temp4[0]) - id2 = temp4; + int i = 0; + int multipleBinding = config.multipleBinding; + // Disabling multiple binding only prevents new multiple bindings. + config.multipleBinding = 1; + while (1) { + wchar_t id[50]; + wchar_t temp[50], temp2[1000], temp3[1000], temp4[1000]; + wsprintfW(id, L"Device %i", i++); + if (!GetPrivateProfileStringW(id, L"Display Name", 0, temp2, 1000, file) || !temp2[0] || + !GetPrivateProfileStringW(id, L"Instance ID", 0, temp3, 1000, file) || !temp3[0]) { + if (i >= 100) + break; + continue; + } + wchar_t *id2 = 0; + if (GetPrivateProfileStringW(id, L"Product ID", 0, temp4, 1000, file) && temp4[0]) + id2 = temp4; - int api = GetPrivateProfileIntW(id, L"API", 0, file); - int type = GetPrivateProfileIntW(id, L"Type", 0, file); - if (!api || !type) continue; + int api = GetPrivateProfileIntW(id, L"API", 0, file); + int type = GetPrivateProfileIntW(id, L"Type", 0, file); + if (!api || !type) + continue; - Device *dev = new Device((DeviceAPI)api, (DeviceType)type, temp2, temp3, id2); - dev->attached = 0; - dm->AddDevice(dev); - int j = 0; - int last = 0; - while (1) { - wsprintfW(temp, L"Binding %i", j++); - if (!GetPrivateProfileStringW(id, temp, 0, temp2, 1000, file)) { - if (j >= 100) { - if (!last) break; - last = 0; - } - continue; - } - last = 1; - unsigned int uid; - int port, command, sensitivity, turbo, slot = 0, deadZone = 0; - int w = 0; - char string[1000]; - while (temp2[w]) { - string[w] = (char)temp2[w]; - w++; - } - string[w] = 0; - int len = sscanf(string, " %i , %i , %i , %i , %i , %i , %i", &uid, &port, &command, &sensitivity, &turbo, &slot, &deadZone); - if (len >= 5 && type) { - VirtualControl *c = dev->GetVirtualControl(uid); - if (!c) c = dev->AddVirtualControl(uid, -1); - if (c) { - BindCommand(dev, uid, port, slot, command, sensitivity, turbo, deadZone); - } - } - } - j = 0; - while (1) { - wsprintfW(temp, L"FF Binding %i", j++); - if (!GetPrivateProfileStringW(id, temp, 0, temp2, 1000, file)) { - if (j >= 10) { - if (!last) break; - last = 0; - } - continue; - } - last = 1; - int port, slot, motor; - int w = 0; - char string[1000]; - char effect[1000]; - while (temp2[w]) { - string[w] = (char)temp2[w]; - w++; - } - string[w] = 0; - // wcstok not in ntdll. More effore than its worth to shave off - // whitespace without it. - if (sscanf(string, " %s %i , %i , %i", effect, &port, &motor, &slot) == 4) { - char *s = strchr(strchr(strchr(string, ',')+1, ',')+1, ','); - if (!s) continue; - s++; - w = 0; - while (effect[w]) { - temp2[w] = effect[w]; - w++; - } - temp2[w] = 0; - ForceFeedbackEffectType *eff = dev->GetForcefeedbackEffect(temp2); - if (!eff) { - // At the moment, don't record effect types. - // Only used internally, anyways, so not an issue. - dev->AddFFEffectType(temp2, temp2, EFFECT_CONSTANT); - // eff = &dev->ffEffectTypes[dev->numFFEffectTypes-1]; - } - ForceFeedbackBinding *b; - CreateEffectBinding(dev, temp2, port, slot, motor, &b); - if (b) { - while (1) { - int axisID = atoi(s); - if (!(s = strchr(s, ','))) break; - s++; - int force = atoi(s); - int i; - for (i=0; inumFFAxes; i++) { - if (axisID == dev->ffAxes[i].id) break; - } - if (i == dev->numFFAxes) { - dev->AddFFAxis(L"?", axisID); - } - b->axes[i].force = force; - if (!(s = strchr(s, ','))) break; - s++; - } - } - } - } - } - config.multipleBinding = multipleBinding; + Device *dev = new Device((DeviceAPI)api, (DeviceType)type, temp2, temp3, id2); + dev->attached = 0; + dm->AddDevice(dev); + int j = 0; + int last = 0; + while (1) { + wsprintfW(temp, L"Binding %i", j++); + if (!GetPrivateProfileStringW(id, temp, 0, temp2, 1000, file)) { + if (j >= 100) { + if (!last) + break; + last = 0; + } + continue; + } + last = 1; + unsigned int uid; + int port, command, sensitivity, turbo, slot = 0, deadZone = 0; + int w = 0; + char string[1000]; + while (temp2[w]) { + string[w] = (char)temp2[w]; + w++; + } + string[w] = 0; + int len = sscanf(string, " %i , %i , %i , %i , %i , %i , %i", &uid, &port, &command, &sensitivity, &turbo, &slot, &deadZone); + if (len >= 5 && type) { + VirtualControl *c = dev->GetVirtualControl(uid); + if (!c) + c = dev->AddVirtualControl(uid, -1); + if (c) { + BindCommand(dev, uid, port, slot, command, sensitivity, turbo, deadZone); + } + } + } + j = 0; + while (1) { + wsprintfW(temp, L"FF Binding %i", j++); + if (!GetPrivateProfileStringW(id, temp, 0, temp2, 1000, file)) { + if (j >= 10) { + if (!last) + break; + last = 0; + } + continue; + } + last = 1; + int port, slot, motor; + int w = 0; + char string[1000]; + char effect[1000]; + while (temp2[w]) { + string[w] = (char)temp2[w]; + w++; + } + string[w] = 0; + // wcstok not in ntdll. More effore than its worth to shave off + // whitespace without it. + if (sscanf(string, " %s %i , %i , %i", effect, &port, &motor, &slot) == 4) { + char *s = strchr(strchr(strchr(string, ',') + 1, ',') + 1, ','); + if (!s) + continue; + s++; + w = 0; + while (effect[w]) { + temp2[w] = effect[w]; + w++; + } + temp2[w] = 0; + ForceFeedbackEffectType *eff = dev->GetForcefeedbackEffect(temp2); + if (!eff) { + // At the moment, don't record effect types. + // Only used internally, anyways, so not an issue. + dev->AddFFEffectType(temp2, temp2, EFFECT_CONSTANT); + // eff = &dev->ffEffectTypes[dev->numFFEffectTypes-1]; + } + ForceFeedbackBinding *b; + CreateEffectBinding(dev, temp2, port, slot, motor, &b); + if (b) { + while (1) { + int axisID = atoi(s); + if (!(s = strchr(s, ','))) + break; + s++; + int force = atoi(s); + int i; + for (i = 0; i < dev->numFFAxes; i++) { + if (axisID == dev->ffAxes[i].id) + break; + } + if (i == dev->numFFAxes) { + dev->AddFFAxis(L"?", axisID); + } + b->axes[i].force = force; + if (!(s = strchr(s, ','))) + break; + s++; + } + } + } + } + } + config.multipleBinding = multipleBinding; - RefreshEnabledDevicesAndDisplay(1); + RefreshEnabledDevicesAndDisplay(1); - if (ps2e) - PCSX2_overrideConfig(config); + if (ps2e) + PCSX2_overrideConfig(config); - return 0; + return 0; } -inline int GetPort(HWND hWnd, int *slot) { - for (int i=0; i>1] == hWnd) { - *slot = i>>1; - return i&1; - } - } - *slot = 0; - return 0; +inline int GetPort(HWND hWnd, int *slot) +{ + for (int i = 0; i < sizeof(hWnds) / sizeof(hWnds[0][0]); i++) { + if (hWnds[i & 1][i >> 1] == hWnd) { + *slot = i >> 1; + return i & 1; + } + } + *slot = 0; + return 0; } -void Diagnostics(HWND hWnd) { - HWND hWndList = GetDlgItem(hWnd, IDC_LIST); - if (!hWndList) return; - int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - if (index < 0) return; - LVITEM item; - memset(&item, 0, sizeof(item)); - item.mask = LVIF_PARAM; - item.iSubItem = 0; - item.iItem = index; - if (!ListView_GetItem(hWndList, &item)) return; - Diagnose(item.lParam, hWnd); - RefreshEnabledDevicesAndDisplay(0, hWnd, 1); +void Diagnostics(HWND hWnd) +{ + HWND hWndList = GetDlgItem(hWnd, IDC_LIST); + if (!hWndList) + return; + int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + if (index < 0) + return; + LVITEM item; + memset(&item, 0, sizeof(item)); + item.mask = LVIF_PARAM; + item.iSubItem = 0; + item.iItem = index; + if (!ListView_GetItem(hWndList, &item)) + return; + Diagnose(item.lParam, hWnd); + RefreshEnabledDevicesAndDisplay(0, hWnd, 1); } -int GetBinding(int port, int slot, int index, Device *&dev, Binding *&b, ForceFeedbackBinding *&ffb) { - ffb = 0; - b = 0; - for (int i = 0; inumDevices; i++) { - dev = dm->devices[i]; - if (!dev->enabled) continue; - if (index < dev->pads[port][slot].numBindings) { - b = dev->pads[port][slot].bindings + index; - return 1; - } - index -= dev->pads[port][slot].numBindings; +int GetBinding(int port, int slot, int index, Device *&dev, Binding *&b, ForceFeedbackBinding *&ffb) +{ + ffb = 0; + b = 0; + for (int i = 0; i < dm->numDevices; i++) { + dev = dm->devices[i]; + if (!dev->enabled) + continue; + if (index < dev->pads[port][slot].numBindings) { + b = dev->pads[port][slot].bindings + index; + return 1; + } + index -= dev->pads[port][slot].numBindings; - if (index < dev->pads[port][slot].numFFBindings) { - ffb = dev->pads[port][slot].ffBindings + index; - return 1; - } - index -= dev->pads[port][slot].numFFBindings; - } - return 0; + if (index < dev->pads[port][slot].numFFBindings) { + ffb = dev->pads[port][slot].ffBindings + index; + return 1; + } + index -= dev->pads[port][slot].numFFBindings; + } + return 0; } // Only used when deleting things from ListView. Will remove from listview if needed. -void DeleteBinding(int port, int slot, Device *dev, Binding *b) { - if (dev->enabled && hWnds[port][slot]) { - int count = GetItemIndex(port, slot, dev, b); - if (count >= 0) { - HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); - if (hWndList) { - ListView_DeleteItem(hWndList, count); - } - } - } - Binding *bindings = dev->pads[port][slot].bindings; - int i = b - bindings; - memmove(bindings+i, bindings+i+1, sizeof(Binding) * (dev->pads[port][slot].numBindings - i - 1)); - dev->pads[port][slot].numBindings--; +void DeleteBinding(int port, int slot, Device *dev, Binding *b) +{ + if (dev->enabled && hWnds[port][slot]) { + int count = GetItemIndex(port, slot, dev, b); + if (count >= 0) { + HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); + if (hWndList) { + ListView_DeleteItem(hWndList, count); + } + } + } + Binding *bindings = dev->pads[port][slot].bindings; + int i = b - bindings; + memmove(bindings + i, bindings + i + 1, sizeof(Binding) * (dev->pads[port][slot].numBindings - i - 1)); + dev->pads[port][slot].numBindings--; } -void DeleteBinding(int port, int slot, Device *dev, ForceFeedbackBinding *b) { - if (dev->enabled && hWnds[port][slot]) { - int count = GetItemIndex(port, slot, dev, b); - if (count >= 0) { - HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); - if (hWndList) { - ListView_DeleteItem(hWndList, count); - } - } - } - ForceFeedbackBinding *bindings = dev->pads[port][slot].ffBindings; - int i = b - bindings; - memmove(bindings+i, bindings+i+1, sizeof(Binding) * (dev->pads[port][slot].numFFBindings - i - 1)); - dev->pads[port][slot].numFFBindings--; +void DeleteBinding(int port, int slot, Device *dev, ForceFeedbackBinding *b) +{ + if (dev->enabled && hWnds[port][slot]) { + int count = GetItemIndex(port, slot, dev, b); + if (count >= 0) { + HWND hWndList = GetDlgItem(hWnds[port][slot], IDC_LIST); + if (hWndList) { + ListView_DeleteItem(hWndList, count); + } + } + } + ForceFeedbackBinding *bindings = dev->pads[port][slot].ffBindings; + int i = b - bindings; + memmove(bindings + i, bindings + i + 1, sizeof(Binding) * (dev->pads[port][slot].numFFBindings - i - 1)); + dev->pads[port][slot].numFFBindings--; } -int DeleteByIndex(int port, int slot, int index) { - ForceFeedbackBinding *ffb; - Binding *b; - Device *dev; - if (GetBinding(port, slot, index, dev, b, ffb)) { - if (b) { - DeleteBinding(port, slot, dev, b); - } - else { - DeleteBinding(port, slot, dev, ffb); - } - return 1; - } - return 0; +int DeleteByIndex(int port, int slot, int index) +{ + ForceFeedbackBinding *ffb; + Binding *b; + Device *dev; + if (GetBinding(port, slot, index, dev, b, ffb)) { + if (b) { + DeleteBinding(port, slot, dev, b); + } else { + DeleteBinding(port, slot, dev, ffb); + } + return 1; + } + return 0; } -int DeleteSelected(int port, int slot) { - if (!hWnds[port][slot]) return 0; - HWND hWnd = GetDlgItem(hWnds[port][slot], IDC_LIST); - int changes = 0; - while (1) { - int index = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED); - if (index < 0) break; - changes += DeleteByIndex(port, slot, index); - } - //ShowScrollBar(hWnd, SB_VERT, 1); - return changes; +int DeleteSelected(int port, int slot) +{ + if (!hWnds[port][slot]) + return 0; + HWND hWnd = GetDlgItem(hWnds[port][slot], IDC_LIST); + int changes = 0; + while (1) { + int index = ListView_GetNextItem(hWnd, -1, LVNI_SELECTED); + if (index < 0) + break; + changes += DeleteByIndex(port, slot, index); + } + //ShowScrollBar(hWnd, SB_VERT, 1); + return changes; } -int CreateEffectBinding(Device *dev, wchar_t *effectID, unsigned int port, unsigned int slot, unsigned int motor, ForceFeedbackBinding **binding) { - // Checks needed because I use this directly when loading bindings. - // Note: dev->numFFAxes *can* be 0, for loading from file. - *binding = 0; - if (port > 1 || slot>3 || motor > 1 || !dev->numFFEffectTypes) { - return -1; - } - ForceFeedbackEffectType *eff = 0; - if (effectID) { - eff = dev->GetForcefeedbackEffect(effectID); - } - if (!eff) { - eff = dev->ffEffectTypes; - } - if (!eff) { - return -1; - } - int effectIndex = eff - dev->ffEffectTypes; - dev->pads[port][slot].ffBindings = (ForceFeedbackBinding*) realloc(dev->pads[port][slot].ffBindings, (dev->pads[port][slot].numFFBindings+1) * sizeof(ForceFeedbackBinding)); - int newIndex = dev->pads[port][slot].numFFBindings; - while (newIndex && dev->pads[port][slot].ffBindings[newIndex-1].motor >= motor) { - dev->pads[port][slot].ffBindings[newIndex] = dev->pads[port][slot].ffBindings[newIndex-1]; - newIndex--; - } - ForceFeedbackBinding *b = dev->pads[port][slot].ffBindings + newIndex; - b->axes = (AxisEffectInfo*) calloc(dev->numFFAxes, sizeof(AxisEffectInfo)); - b->motor = motor; - b->effectIndex = effectIndex; - dev->pads[port][slot].numFFBindings++; - if (binding) *binding = b; - return ListBoundEffect(port, slot, dev, b); +int CreateEffectBinding(Device *dev, wchar_t *effectID, unsigned int port, unsigned int slot, unsigned int motor, ForceFeedbackBinding **binding) +{ + // Checks needed because I use this directly when loading bindings. + // Note: dev->numFFAxes *can* be 0, for loading from file. + *binding = 0; + if (port > 1 || slot > 3 || motor > 1 || !dev->numFFEffectTypes) { + return -1; + } + ForceFeedbackEffectType *eff = 0; + if (effectID) { + eff = dev->GetForcefeedbackEffect(effectID); + } + if (!eff) { + eff = dev->ffEffectTypes; + } + if (!eff) { + return -1; + } + int effectIndex = eff - dev->ffEffectTypes; + dev->pads[port][slot].ffBindings = (ForceFeedbackBinding *)realloc(dev->pads[port][slot].ffBindings, (dev->pads[port][slot].numFFBindings + 1) * sizeof(ForceFeedbackBinding)); + int newIndex = dev->pads[port][slot].numFFBindings; + while (newIndex && dev->pads[port][slot].ffBindings[newIndex - 1].motor >= motor) { + dev->pads[port][slot].ffBindings[newIndex] = dev->pads[port][slot].ffBindings[newIndex - 1]; + newIndex--; + } + ForceFeedbackBinding *b = dev->pads[port][slot].ffBindings + newIndex; + b->axes = (AxisEffectInfo *)calloc(dev->numFFAxes, sizeof(AxisEffectInfo)); + b->motor = motor; + b->effectIndex = effectIndex; + dev->pads[port][slot].numFFBindings++; + if (binding) + *binding = b; + return ListBoundEffect(port, slot, dev, b); } -int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int slot, int command, int sensitivity, int turbo, int deadZone) { - // Checks needed because I use this directly when loading bindings. - if (port > 1 || slot>3) { - return -1; - } - if (!sensitivity) sensitivity = BASE_SENSITIVITY; - if ((uid>>16) & (PSHBTN|TGLBTN)) { - deadZone = 0; - } - else if (!deadZone) { - if ((uid>>16) & PRESSURE_BTN) { - deadZone = 1; - } - else { - deadZone = DEFAULT_DEADZONE; - } - } - // Relative axes can have negative sensitivity. - else if (((uid>>16) & 0xFF) == RELAXIS) { - sensitivity = abs(sensitivity); - } - VirtualControl *c = dev->GetVirtualControl(uid); - if (!c) return -1; - // Add before deleting. Means I won't scroll up one line when scrolled down to bottom. - int controlIndex = c - dev->virtualControls; - int index = 0; - PadBindings *p = dev->pads[port]+slot; - p->bindings = (Binding*) realloc(p->bindings, (p->numBindings+1) * sizeof(Binding)); - for (index = p->numBindings; index > 0; index--) { - if (p->bindings[index-1].controlIndex < controlIndex) break; - p->bindings[index] = p->bindings[index-1]; - } - Binding *b = p->bindings+index; - p->numBindings++; - b->command = command; - b->controlIndex = controlIndex; - b->turbo = turbo; - b->sensitivity = sensitivity; - b->deadZone = deadZone; - // Where it appears in listview. - int count = ListBoundCommand(port, slot, dev, b); +int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int slot, int command, int sensitivity, int turbo, int deadZone) +{ + // Checks needed because I use this directly when loading bindings. + if (port > 1 || slot > 3) { + return -1; + } + if (!sensitivity) + sensitivity = BASE_SENSITIVITY; + if ((uid >> 16) & (PSHBTN | TGLBTN)) { + deadZone = 0; + } else if (!deadZone) { + if ((uid >> 16) & PRESSURE_BTN) { + deadZone = 1; + } else { + deadZone = DEFAULT_DEADZONE; + } + } + // Relative axes can have negative sensitivity. + else if (((uid >> 16) & 0xFF) == RELAXIS) { + sensitivity = abs(sensitivity); + } + VirtualControl *c = dev->GetVirtualControl(uid); + if (!c) + return -1; + // Add before deleting. Means I won't scroll up one line when scrolled down to bottom. + int controlIndex = c - dev->virtualControls; + int index = 0; + PadBindings *p = dev->pads[port] + slot; + p->bindings = (Binding *)realloc(p->bindings, (p->numBindings + 1) * sizeof(Binding)); + for (index = p->numBindings; index > 0; index--) { + if (p->bindings[index - 1].controlIndex < controlIndex) + break; + p->bindings[index] = p->bindings[index - 1]; + } + Binding *b = p->bindings + index; + p->numBindings++; + b->command = command; + b->controlIndex = controlIndex; + b->turbo = turbo; + b->sensitivity = sensitivity; + b->deadZone = deadZone; + // Where it appears in listview. + int count = ListBoundCommand(port, slot, dev, b); - int newBindingIndex = index; - index = 0; - while (index < p->numBindings) { - if (index == newBindingIndex) { - index ++; - continue; - } - b = p->bindings + index; - int nuke = 0; - if (config.multipleBinding) { - if (b->controlIndex == controlIndex && b->command == command) - nuke = 1; - } - else { - int uid2 = dev->virtualControls[b->controlIndex].uid; - if (b->controlIndex == controlIndex || (!((uid2^uid) & 0xFFFFFF) && ((uid|uid2) & (UID_POV | UID_AXIS)))) - nuke = 1; - } - if (!nuke) { - index++; - continue; - } - if (index < newBindingIndex) { - newBindingIndex--; - count --; - } - DeleteBinding(port, slot, dev, b); - } - if (!config.multipleBinding) { - for (int port2=0; port2<2; port2++) { - for (int slot2=0; slot2<4; slot2++) { - if (port2==port && slot2 == slot) continue; - PadBindings *p = dev->pads[port2]+slot2; - for (int i=0; i < p->numBindings; i++) { - Binding *b = p->bindings+i; - int uid2 = dev->virtualControls[b->controlIndex].uid; - if (b->controlIndex == controlIndex || (!((uid2^uid) & 0xFFFFFF) && ((uid|uid2) & (UID_POV | UID_AXIS)))) { - DeleteBinding(port2, slot2, dev, b); - i--; - } - } - } - } - } + int newBindingIndex = index; + index = 0; + while (index < p->numBindings) { + if (index == newBindingIndex) { + index++; + continue; + } + b = p->bindings + index; + int nuke = 0; + if (config.multipleBinding) { + if (b->controlIndex == controlIndex && b->command == command) + nuke = 1; + } else { + int uid2 = dev->virtualControls[b->controlIndex].uid; + if (b->controlIndex == controlIndex || (!((uid2 ^ uid) & 0xFFFFFF) && ((uid | uid2) & (UID_POV | UID_AXIS)))) + nuke = 1; + } + if (!nuke) { + index++; + continue; + } + if (index < newBindingIndex) { + newBindingIndex--; + count--; + } + DeleteBinding(port, slot, dev, b); + } + if (!config.multipleBinding) { + for (int port2 = 0; port2 < 2; port2++) { + for (int slot2 = 0; slot2 < 4; slot2++) { + if (port2 == port && slot2 == slot) + continue; + PadBindings *p = dev->pads[port2] + slot2; + for (int i = 0; i < p->numBindings; i++) { + Binding *b = p->bindings + i; + int uid2 = dev->virtualControls[b->controlIndex].uid; + if (b->controlIndex == controlIndex || (!((uid2 ^ uid) & 0xFFFFFF) && ((uid | uid2) & (UID_POV | UID_AXIS)))) { + DeleteBinding(port2, slot2, dev, b); + i--; + } + } + } + } + } - return count; + return count; } // Does nothing, but makes sure I'm overriding the dialog's window proc, to block // default key handling. -ExtraWndProcResult DoNothingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - return CONTINUE_BLISSFULLY; +ExtraWndProcResult DoNothingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) +{ + return CONTINUE_BLISSFULLY; } -void EndBinding(HWND hWnd) { - if (selected) { - KillTimer(hWnd, 1); +void EndBinding(HWND hWnd) +{ + if (selected) { + KillTimer(hWnd, 1); - int needRefreshDevices = 0; - // If binding ignore keyboard, this will disable it and enable other devices. - // 0xFF is used for testing force feedback. I disable all other devices first - // just so I don't needlessly steal the mouse. - if (selected == 0x7F || selected == 0xFF) { - needRefreshDevices = 1; - } - selected = 0; + int needRefreshDevices = 0; + // If binding ignore keyboard, this will disable it and enable other devices. + // 0xFF is used for testing force feedback. I disable all other devices first + // just so I don't needlessly steal the mouse. + if (selected == 0x7F || selected == 0xFF) { + needRefreshDevices = 1; + } + selected = 0; - dm->ReleaseInput(); - ClearKeyQueue(); - hWndButtonProc.Release(); + dm->ReleaseInput(); + ClearKeyQueue(); + hWndButtonProc.Release(); - // Safest to do this last. - if (needRefreshDevices) { - RefreshEnabledDevices(); - } - } + // Safest to do this last. + if (needRefreshDevices) { + RefreshEnabledDevices(); + } + } } -INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam) { - int index = (hWnd == PropSheet_IndexToHwnd(hWndProp, 1)); - int slot; - int port = GetPort(hWnd, &slot); - HWND hWndList = GetDlgItem(hWnd, IDC_LIST); - switch (msg) { - case WM_INITDIALOG: - { - ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER); - LVCOLUMN c; - c.mask = LVCF_TEXT | LVCF_WIDTH; - c.cx = 100; - c.pszText = L"Device"; - ListView_InsertColumn(hWndList, 0, &c); - c.cx = 70; - c.pszText = L"PC Control"; - ListView_InsertColumn(hWndList, 1, &c); - c.cx = 84; - c.pszText = L"PS2 Control"; - ListView_InsertColumn(hWndList, 2, &c); - selected = 0; - port = (int)((PROPSHEETPAGE *)lParam)->lParam & 1; - slot = (int)((PROPSHEETPAGE *)lParam)->lParam >> 1; - hWnds[port][slot] = hWnd; - SendMessage(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); - SetupLogSlider(GetDlgItem(hWnd, IDC_SLIDER1)); - SetupLogSlider(GetDlgItem(hWnd, IDC_SLIDER_DEADZONE)); - if (port || slot) - EnableWindow(GetDlgItem(hWnd, ID_IGNORE), 0); +INT_PTR CALLBACK DialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam) +{ + int index = (hWnd == PropSheet_IndexToHwnd(hWndProp, 1)); + int slot; + int port = GetPort(hWnd, &slot); + HWND hWndList = GetDlgItem(hWnd, IDC_LIST); + switch (msg) { + case WM_INITDIALOG: { + ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER); + LVCOLUMN c; + c.mask = LVCF_TEXT | LVCF_WIDTH; + c.cx = 100; + c.pszText = L"Device"; + ListView_InsertColumn(hWndList, 0, &c); + c.cx = 70; + c.pszText = L"PC Control"; + ListView_InsertColumn(hWndList, 1, &c); + c.cx = 84; + c.pszText = L"PS2 Control"; + ListView_InsertColumn(hWndList, 2, &c); + selected = 0; + port = (int)((PROPSHEETPAGE *)lParam)->lParam & 1; + slot = (int)((PROPSHEETPAGE *)lParam)->lParam >> 1; + hWnds[port][slot] = hWnd; + SendMessage(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); + SetupLogSlider(GetDlgItem(hWnd, IDC_SLIDER1)); + SetupLogSlider(GetDlgItem(hWnd, IDC_SLIDER_DEADZONE)); + if (port || slot) + EnableWindow(GetDlgItem(hWnd, ID_IGNORE), 0); - Populate(port, slot); - } - break; - case WM_DEVICECHANGE: - if (wParam == DBT_DEVNODES_CHANGED) { - EndBinding(hWnd); - RefreshEnabledDevicesAndDisplay(1, hWndGeneral, 1); - } - break; - case WM_TIMER: - // ignore generic timer callback and handle the hwnd-specific one which comes later - if(hWnd == 0) return 0; + Populate(port, slot); + } break; + case WM_DEVICECHANGE: + if (wParam == DBT_DEVNODES_CHANGED) { + EndBinding(hWnd); + RefreshEnabledDevicesAndDisplay(1, hWndGeneral, 1); + } + break; + case WM_TIMER: + // ignore generic timer callback and handle the hwnd-specific one which comes later + if (hWnd == 0) + return 0; - if (!selected || selected == 0xFF) { - // !selected is mostly for device added/removed when binding. - selected = 0xFF; - EndBinding(hWnd); - } - else { - unsigned int uid; - int value; + if (!selected || selected == 0xFF) { + // !selected is mostly for device added/removed when binding. + selected = 0xFF; + EndBinding(hWnd); + } else { + unsigned int uid; + int value; - // The old code re-bound our button hWndProcEater to GetDlgItem(hWnd, selected). But at best hWnd - // was null (WM_TIMER is passed twice, once with a null parameter, and a second time that is hWnd - // specific), and at worst 'selected' is a post-processed code "based" on cmd, so GetDlgItem - // *always* returned NULL anyway. This resulted in hWndButton being null, which meant Device code - // used hWnd instead. This may have caused odd behavior since the callbacks were still all eaten - // by the initial GetDlgItem(hWnd, cmd) selection made when the timer was initialized. + // The old code re-bound our button hWndProcEater to GetDlgItem(hWnd, selected). But at best hWnd + // was null (WM_TIMER is passed twice, once with a null parameter, and a second time that is hWnd + // specific), and at worst 'selected' is a post-processed code "based" on cmd, so GetDlgItem + // *always* returned NULL anyway. This resulted in hWndButton being null, which meant Device code + // used hWnd instead. This may have caused odd behavior since the callbacks were still all eaten + // by the initial GetDlgItem(hWnd, cmd) selection made when the timer was initialized. - InitInfo info = {selected==0x7F, 1, hWndProp, &hWndButtonProc}; - Device *dev = dm->GetActiveDevice(&info, &uid, &index, &value); - if (dev) { - int command = selected; - // Good idea to do this first, as BindCommand modifies the ListView, which will - // call it anyways, which is a bit funky. - EndBinding(hWnd); - UnselectAll(hWndList); - int index = -1; - if (command == 0x7F && dev->api == IGNORE_KEYBOARD) { - index = BindCommand(dev, uid, 0, 0, command, BASE_SENSITIVITY, 0, 0); - } - else if (command < 0x30) { - index = BindCommand(dev, uid, port, slot, command, BASE_SENSITIVITY, 0, 0); - } - if (index >= 0) { - PropSheet_Changed(hWndProp, hWnds[port][slot]); - ListView_SetItemState(hWndList, index, LVIS_SELECTED, LVIS_SELECTED); - ListView_EnsureVisible(hWndList, index, 0); - } - } - } - break; - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - EndBinding(hWnd); - break; - case PSM_CANCELTOCLOSE: - // Load(); - break; - case WM_ACTIVATE: - EndBinding(hWnd); - break; - case WM_NOTIFY: - { - PSHNOTIFY* n = (PSHNOTIFY*) lParam; - if (n->hdr.hwndFrom == hWndProp) { - switch(n->hdr.code) { - case PSN_QUERYCANCEL: - case PSN_KILLACTIVE: - EndBinding(hWnd); - return 0; - case PSN_SETACTIVE: - return 0; - case PSN_APPLY: - SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_NOERROR); - return 1; - } - break; - } - else if (n->hdr.idFrom == IDC_LIST) { - static int NeedUpdate = 0; - if (n->hdr.code == LVN_KEYDOWN) { - NMLVKEYDOWN *key = (NMLVKEYDOWN *) n; - if (key->wVKey == VK_DELETE || - key->wVKey == VK_BACK) { + InitInfo info = {selected == 0x7F, 1, hWndProp, &hWndButtonProc}; + Device *dev = dm->GetActiveDevice(&info, &uid, &index, &value); + if (dev) { + int command = selected; + // Good idea to do this first, as BindCommand modifies the ListView, which will + // call it anyways, which is a bit funky. + EndBinding(hWnd); + UnselectAll(hWndList); + int index = -1; + if (command == 0x7F && dev->api == IGNORE_KEYBOARD) { + index = BindCommand(dev, uid, 0, 0, command, BASE_SENSITIVITY, 0, 0); + } else if (command < 0x30) { + index = BindCommand(dev, uid, port, slot, command, BASE_SENSITIVITY, 0, 0); + } + if (index >= 0) { + PropSheet_Changed(hWndProp, hWnds[port][slot]); + ListView_SetItemState(hWndList, index, LVIS_SELECTED, LVIS_SELECTED); + ListView_EnsureVisible(hWndList, index, 0); + } + } + } + break; + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + EndBinding(hWnd); + break; + case PSM_CANCELTOCLOSE: + // Load(); + break; + case WM_ACTIVATE: + EndBinding(hWnd); + break; + case WM_NOTIFY: { + PSHNOTIFY *n = (PSHNOTIFY *)lParam; + if (n->hdr.hwndFrom == hWndProp) { + switch (n->hdr.code) { + case PSN_QUERYCANCEL: + case PSN_KILLACTIVE: + EndBinding(hWnd); + return 0; + case PSN_SETACTIVE: + return 0; + case PSN_APPLY: + SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_NOERROR); + return 1; + } + break; + } else if (n->hdr.idFrom == IDC_LIST) { + static int NeedUpdate = 0; + if (n->hdr.code == LVN_KEYDOWN) { + NMLVKEYDOWN *key = (NMLVKEYDOWN *)n; + if (key->wVKey == VK_DELETE || + key->wVKey == VK_BACK) { - if (DeleteSelected(port, slot)) - PropSheet_Changed(hWndProp, hWnds[0]); - } - } - // Update sensitivity and motor/binding display on redraw - // rather than on itemchanged. This reduces blinking, as - // I get 3 LVN_ITEMCHANGED messages, and first is sent before - // the new item is set as being selected. - else if (n->hdr.code == LVN_ITEMCHANGED) { - NeedUpdate = 1; - } - else if (n->hdr.code == NM_CUSTOMDRAW && NeedUpdate) { - NeedUpdate = 0; - SelChanged(port, slot); - } - } - } - break; - case WM_HSCROLL: - { - int id = GetDlgCtrlID((HWND)lParam); - int val = GetLogSliderVal(hWnd, id); - if (id == IDC_SLIDER1) { - ChangeValue(port, slot, &val, 0, 0); - } - else if (id == IDC_SLIDER_DEADZONE) { - ChangeValue(port, slot, 0, 0, &val); - } - else { - ChangeEffect(port, slot, id, &val, 0); - } - } - break; - case WM_COMMAND: - if (HIWORD(wParam)==CBN_SELCHANGE && LOWORD(wParam) == IDC_AXIS_DIRECTION) { - int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - if (index >= 0) { - int cbsel = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); - if (cbsel >= 0) { - ForceFeedbackBinding *ffb; - Binding *b; - Device *dev; - if (GetBinding(port, slot, index, dev, b, ffb)) { - const static unsigned int axisUIDs[3] = {UID_AXIS_NEG, UID_AXIS_POS, UID_AXIS}; - int uid = dev->virtualControls[b->controlIndex].uid; - uid = (uid&0x00FFFFFF) | axisUIDs[cbsel]; - Binding backup = *b; - DeleteSelected(port, slot); - int index = BindCommand(dev, uid, port, slot, backup.command, backup.sensitivity, backup.turbo, backup.deadZone); - ListView_SetItemState(hWndList, index, LVIS_SELECTED, LVIS_SELECTED); - PropSheet_Changed(hWndProp, hWnd); - } - } - } - } - else if (HIWORD(wParam)==CBN_SELCHANGE && LOWORD(wParam) == IDC_FF_EFFECT) { - int typeIndex = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); - if (typeIndex >= 0) - ChangeEffect(port, slot, 0, 0, (unsigned int*)&typeIndex); - } - else if (HIWORD(wParam)==BN_CLICKED) { - EndBinding(hWnd); - int cmd = LOWORD(wParam); - if (cmd == ID_DELETE) { - if (DeleteSelected(port, slot)) - PropSheet_Changed(hWndProp, hWnd); - } - else if (cmd == ID_CLEAR) { - while (DeleteByIndex(port, slot, 0)) PropSheet_Changed(hWndProp, hWnd); - } - else if (cmd == ID_BIG_MOTOR || cmd == ID_SMALL_MOTOR) { - int i = (int)SendMessage(GetDlgItem(hWnd, IDC_FORCEFEEDBACK), CB_GETCURSEL, 0, 0); - if (i >= 0) { - unsigned int index = (unsigned int)SendMessage(GetDlgItem(hWnd, IDC_FORCEFEEDBACK), CB_GETITEMDATA, i, 0); - if (index < (unsigned int) dm->numDevices) { - Device *dev = dm->devices[index]; - ForceFeedbackBinding *b; - wchar_t *effectID = 0; - if (dev->api == DI) { - // Constant effect. - if (cmd == ID_BIG_MOTOR) effectID = L"13541C20-8E33-11D0-9AD0-00A0C9A06E35"; - // Square. - else effectID = L"13541C22-8E33-11D0-9AD0-00A0C9A06E35"; - } - int count = CreateEffectBinding(dev, effectID, port, slot, cmd-ID_BIG_MOTOR, &b); - if (b) { - int needSet = 1; - if (dev->api == XINPUT && dev->numFFAxes == 2) { - needSet = 0; - if (cmd == ID_BIG_MOTOR) { - b->axes[0].force = BASE_SENSITIVITY; - } - else { - b->axes[1].force = BASE_SENSITIVITY; - } - } - else if (dev->api == DS3 && dev->numFFAxes == 2) { - needSet = 0; - if (cmd == ID_BIG_MOTOR) { - b->axes[0].force = BASE_SENSITIVITY; - } - else { - b->axes[1].force = BASE_SENSITIVITY; - } - } - else if (dev->api == DI) { - int bigIndex=0, littleIndex=0; - int j; - for (j=0; jnumFFAxes; j++) { - // DI object instance. 0 is x-axis, 1 is y-axis. - int instance = (dev->ffAxes[j].id>>8)&0xFFFF; - if (instance == 0) { - bigIndex = j; - } - else if (instance == 1) { - littleIndex = j; - } - } - needSet = 0; - if (cmd == ID_BIG_MOTOR) { - b->axes[bigIndex].force = BASE_SENSITIVITY; - b->axes[littleIndex].force = 1; - } - else { - b->axes[bigIndex].force = 1; - b->axes[littleIndex].force = BASE_SENSITIVITY; - } - } - if (needSet) { - for (int j=0; j<2 && j numFFAxes; j++) { - b->axes[j].force = BASE_SENSITIVITY; - } - } - UnselectAll(hWndList); - ListView_SetItemState(hWndList, count, LVIS_SELECTED, LVIS_SELECTED); - ListView_EnsureVisible(hWndList, count, 0); - } - PropSheet_Changed(hWndProp, hWnd); - } - } - } - else if (cmd == ID_CONTROLS) { - UnselectAll(hWndList); - } - else if (cmd == ID_TEST) { - // Just in case... - if (selected) break; - Device *dev; - Binding *b; - ForceFeedbackBinding *ffb = 0; - int selIndex = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - if (selIndex >= 0) { - if (GetBinding(port, slot, selIndex, dev, b, ffb)) { - selected = 0xFF; - hWndButtonProc.SetWndHandle(GetDlgItem(hWnd, cmd)); - InitInfo info = {0, 1, hWndProp, &hWndButtonProc}; - for (int i=0; inumDevices; i++) { - if (dm->devices[i] != dev) { - dm->DisableDevice(i); - } - } - dm->Update(&info); - dm->PostRead(); - dev->SetEffect(ffb, 255); - Sleep(200); - dm->Update(&info); - SetTimer(hWnd, 1, 3000, 0); - } - } - } - else if ((cmd >= ID_LOCK_BUTTONS && cmd <= ID_ANALOG) || cmd == ID_IGNORE) {// || cmd == ID_FORCE_FEEDBACK) { - // Messes up things, unfortunately. - // End binding on a bunch of notification messages, and - // this will send a bunch. - // UnselectAll(hWndList); - EndBinding(hWnd); - if (cmd != ID_IGNORE) { - selected = cmd-(ID_SELECT-0x10); - } - else { - selected = 0x7F; - for (int i=0; inumDevices; i++) { - if (dm->devices[i]->api != IGNORE_KEYBOARD) { - dm->DisableDevice(i); - } - else { - dm->EnableDevice(i); - } - } - } + if (DeleteSelected(port, slot)) + PropSheet_Changed(hWndProp, hWnds[0]); + } + } + // Update sensitivity and motor/binding display on redraw + // rather than on itemchanged. This reduces blinking, as + // I get 3 LVN_ITEMCHANGED messages, and first is sent before + // the new item is set as being selected. + else if (n->hdr.code == LVN_ITEMCHANGED) { + NeedUpdate = 1; + } else if (n->hdr.code == NM_CUSTOMDRAW && NeedUpdate) { + NeedUpdate = 0; + SelChanged(port, slot); + } + } + } break; + case WM_HSCROLL: { + int id = GetDlgCtrlID((HWND)lParam); + int val = GetLogSliderVal(hWnd, id); + if (id == IDC_SLIDER1) { + ChangeValue(port, slot, &val, 0, 0); + } else if (id == IDC_SLIDER_DEADZONE) { + ChangeValue(port, slot, 0, 0, &val); + } else { + ChangeEffect(port, slot, id, &val, 0); + } + } break; + case WM_COMMAND: + if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_AXIS_DIRECTION) { + int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + if (index >= 0) { + int cbsel = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); + if (cbsel >= 0) { + ForceFeedbackBinding *ffb; + Binding *b; + Device *dev; + if (GetBinding(port, slot, index, dev, b, ffb)) { + const static unsigned int axisUIDs[3] = {UID_AXIS_NEG, UID_AXIS_POS, UID_AXIS}; + int uid = dev->virtualControls[b->controlIndex].uid; + uid = (uid & 0x00FFFFFF) | axisUIDs[cbsel]; + Binding backup = *b; + DeleteSelected(port, slot); + int index = BindCommand(dev, uid, port, slot, backup.command, backup.sensitivity, backup.turbo, backup.deadZone); + ListView_SetItemState(hWndList, index, LVIS_SELECTED, LVIS_SELECTED); + PropSheet_Changed(hWndProp, hWnd); + } + } + } + } else if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_FF_EFFECT) { + int typeIndex = SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); + if (typeIndex >= 0) + ChangeEffect(port, slot, 0, 0, (unsigned int *)&typeIndex); + } else if (HIWORD(wParam) == BN_CLICKED) { + EndBinding(hWnd); + int cmd = LOWORD(wParam); + if (cmd == ID_DELETE) { + if (DeleteSelected(port, slot)) + PropSheet_Changed(hWndProp, hWnd); + } else if (cmd == ID_CLEAR) { + while (DeleteByIndex(port, slot, 0)) + PropSheet_Changed(hWndProp, hWnd); + } else if (cmd == ID_BIG_MOTOR || cmd == ID_SMALL_MOTOR) { + int i = (int)SendMessage(GetDlgItem(hWnd, IDC_FORCEFEEDBACK), CB_GETCURSEL, 0, 0); + if (i >= 0) { + unsigned int index = (unsigned int)SendMessage(GetDlgItem(hWnd, IDC_FORCEFEEDBACK), CB_GETITEMDATA, i, 0); + if (index < (unsigned int)dm->numDevices) { + Device *dev = dm->devices[index]; + ForceFeedbackBinding *b; + wchar_t *effectID = 0; + if (dev->api == DI) { + // Constant effect. + if (cmd == ID_BIG_MOTOR) + effectID = L"13541C20-8E33-11D0-9AD0-00A0C9A06E35"; + // Square. + else + effectID = L"13541C22-8E33-11D0-9AD0-00A0C9A06E35"; + } + int count = CreateEffectBinding(dev, effectID, port, slot, cmd - ID_BIG_MOTOR, &b); + if (b) { + int needSet = 1; + if (dev->api == XINPUT && dev->numFFAxes == 2) { + needSet = 0; + if (cmd == ID_BIG_MOTOR) { + b->axes[0].force = BASE_SENSITIVITY; + } else { + b->axes[1].force = BASE_SENSITIVITY; + } + } else if (dev->api == DS3 && dev->numFFAxes == 2) { + needSet = 0; + if (cmd == ID_BIG_MOTOR) { + b->axes[0].force = BASE_SENSITIVITY; + } else { + b->axes[1].force = BASE_SENSITIVITY; + } + } else if (dev->api == DI) { + int bigIndex = 0, littleIndex = 0; + int j; + for (j = 0; j < dev->numFFAxes; j++) { + // DI object instance. 0 is x-axis, 1 is y-axis. + int instance = (dev->ffAxes[j].id >> 8) & 0xFFFF; + if (instance == 0) { + bigIndex = j; + } else if (instance == 1) { + littleIndex = j; + } + } + needSet = 0; + if (cmd == ID_BIG_MOTOR) { + b->axes[bigIndex].force = BASE_SENSITIVITY; + b->axes[littleIndex].force = 1; + } else { + b->axes[bigIndex].force = 1; + b->axes[littleIndex].force = BASE_SENSITIVITY; + } + } + if (needSet) { + for (int j = 0; j < 2 && j < dev->numFFAxes; j++) { + b->axes[j].force = BASE_SENSITIVITY; + } + } + UnselectAll(hWndList); + ListView_SetItemState(hWndList, count, LVIS_SELECTED, LVIS_SELECTED); + ListView_EnsureVisible(hWndList, count, 0); + } + PropSheet_Changed(hWndProp, hWnd); + } + } + } else if (cmd == ID_CONTROLS) { + UnselectAll(hWndList); + } else if (cmd == ID_TEST) { + // Just in case... + if (selected) + break; + Device *dev; + Binding *b; + ForceFeedbackBinding *ffb = 0; + int selIndex = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + if (selIndex >= 0) { + if (GetBinding(port, slot, selIndex, dev, b, ffb)) { + selected = 0xFF; + hWndButtonProc.SetWndHandle(GetDlgItem(hWnd, cmd)); + InitInfo info = {0, 1, hWndProp, &hWndButtonProc}; + for (int i = 0; i < dm->numDevices; i++) { + if (dm->devices[i] != dev) { + dm->DisableDevice(i); + } + } + dm->Update(&info); + dm->PostRead(); + dev->SetEffect(ffb, 255); + Sleep(200); + dm->Update(&info); + SetTimer(hWnd, 1, 3000, 0); + } + } + } else if ((cmd >= ID_LOCK_BUTTONS && cmd <= ID_ANALOG) || cmd == ID_IGNORE) { // || cmd == ID_FORCE_FEEDBACK) { + // Messes up things, unfortunately. + // End binding on a bunch of notification messages, and + // this will send a bunch. + // UnselectAll(hWndList); + EndBinding(hWnd); + if (cmd != ID_IGNORE) { + selected = cmd - (ID_SELECT - 0x10); + } else { + selected = 0x7F; + for (int i = 0; i < dm->numDevices; i++) { + if (dm->devices[i]->api != IGNORE_KEYBOARD) { + dm->DisableDevice(i); + } else { + dm->EnableDevice(i); + } + } + } - hWndButtonProc.SetWndHandle(GetDlgItem(hWnd, cmd)); - hWndButtonProc.Eat(DoNothingWndProc, 0); - InitInfo info = {selected==0x7F, 1, hWndProp, &hWndButtonProc}; - int w = timeGetTime(); - dm->Update(&info); - dm->PostRead(); - // Workaround for things that return 0 on first poll and something else ever after. - Sleep(80); - dm->Update(&info); - dm->PostRead(); - SetTimer(hWnd, 1, 30, 0); - } - if (cmd == IDC_TURBO) { - // Don't allow setting it back to indeterminate. - SendMessage(GetDlgItem(hWnd, IDC_TURBO), BM_SETSTYLE, BS_AUTOCHECKBOX, 0); - int turbo = (IsDlgButtonChecked(hWnd, IDC_TURBO) == BST_CHECKED); - ChangeValue(port, slot, 0, &turbo, 0); - } - else if (cmd == IDC_FLIP1) { - int val = GetLogSliderVal(hWnd, IDC_SLIDER1); - ChangeValue(port, slot, &val, 0, 0); - } - else if (cmd >= IDC_FF_AXIS1_ENABLED && cmd < IDC_FF_AXIS8_ENABLED + 16) { - int index = (cmd - IDC_FF_AXIS1_ENABLED)/16; - int val = GetLogSliderVal(hWnd, 16*index + IDC_FF_AXIS1); - if (IsDlgButtonChecked(hWnd, 16*index + IDC_FF_AXIS1_ENABLED) != BST_CHECKED) { - val = 0; - } - ChangeEffect(port, slot, cmd, &val, 0); - } - } - break; - default: - break; - } - return 0; + hWndButtonProc.SetWndHandle(GetDlgItem(hWnd, cmd)); + hWndButtonProc.Eat(DoNothingWndProc, 0); + InitInfo info = {selected == 0x7F, 1, hWndProp, &hWndButtonProc}; + int w = timeGetTime(); + dm->Update(&info); + dm->PostRead(); + // Workaround for things that return 0 on first poll and something else ever after. + Sleep(80); + dm->Update(&info); + dm->PostRead(); + SetTimer(hWnd, 1, 30, 0); + } + if (cmd == IDC_TURBO) { + // Don't allow setting it back to indeterminate. + SendMessage(GetDlgItem(hWnd, IDC_TURBO), BM_SETSTYLE, BS_AUTOCHECKBOX, 0); + int turbo = (IsDlgButtonChecked(hWnd, IDC_TURBO) == BST_CHECKED); + ChangeValue(port, slot, 0, &turbo, 0); + } else if (cmd == IDC_FLIP1) { + int val = GetLogSliderVal(hWnd, IDC_SLIDER1); + ChangeValue(port, slot, &val, 0, 0); + } else if (cmd >= IDC_FF_AXIS1_ENABLED && cmd < IDC_FF_AXIS8_ENABLED + 16) { + int index = (cmd - IDC_FF_AXIS1_ENABLED) / 16; + int val = GetLogSliderVal(hWnd, 16 * index + IDC_FF_AXIS1); + if (IsDlgButtonChecked(hWnd, 16 * index + IDC_FF_AXIS1_ENABLED) != BST_CHECKED) { + val = 0; + } + ChangeEffect(port, slot, cmd, &val, 0); + } + } + break; + default: + break; + } + return 0; } // Returns 0 if pad doesn't exist due to mtap settings, as a convenience. -int GetPadString(wchar_t *string, unsigned int port, unsigned int slot) { - if (!slot && !config.multitap[port]) { - wsprintfW(string, L"Pad %i", port+1); - } - else { - wsprintfW(string, L"Pad %i%c", port+1, 'A'+slot); - if (!config.multitap[port]) return 0; - } - return 1; +int GetPadString(wchar_t *string, unsigned int port, unsigned int slot) +{ + if (!slot && !config.multitap[port]) { + wsprintfW(string, L"Pad %i", port + 1); + } else { + wsprintfW(string, L"Pad %i%c", port + 1, 'A' + slot); + if (!config.multitap[port]) + return 0; + } + return 1; } -void UpdatePadPages() { - HPROPSHEETPAGE pages[10]; - int count = 0; - memset(hWnds, 0, sizeof(hWnds)); - int slot = 0; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - if (config.padConfigs[port][slot].type == DisabledPad) continue; - wchar_t title[20]; - if (!GetPadString(title, port, slot)) continue; +void UpdatePadPages() +{ + HPROPSHEETPAGE pages[10]; + int count = 0; + memset(hWnds, 0, sizeof(hWnds)); + int slot = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + if (config.padConfigs[port][slot].type == DisabledPad) + continue; + wchar_t title[20]; + if (!GetPadString(title, port, slot)) + continue; - PROPSHEETPAGE psp; - ZeroMemory(&psp, sizeof(psp)); - psp.dwSize = sizeof(psp); - psp.dwFlags = PSP_USETITLE | PSP_PREMATURE; - psp.hInstance = hInst; - psp.pfnDlgProc = DialogProc; - psp.lParam = port | (slot<<1); - psp.pszTitle = title; - if (config.padConfigs[port][slot].type == GuitarPad) - psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_GUITAR); - else if (config.padConfigs[port][slot].type == PopnPad) - psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_POPN); - else - psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG); + PROPSHEETPAGE psp; + ZeroMemory(&psp, sizeof(psp)); + psp.dwSize = sizeof(psp); + psp.dwFlags = PSP_USETITLE | PSP_PREMATURE; + psp.hInstance = hInst; + psp.pfnDlgProc = DialogProc; + psp.lParam = port | (slot << 1); + psp.pszTitle = title; + if (config.padConfigs[port][slot].type == GuitarPad) + psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_GUITAR); + else if (config.padConfigs[port][slot].type == PopnPad) + psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG_POPN); + else + psp.pszTemplate = MAKEINTRESOURCE(IDD_CONFIG); - pages[count] = CreatePropertySheetPage(&psp); - if (pages[count]) count++; - } - } - while (SendMessage(hWndProp, PSM_INDEXTOPAGE, 1, 0)) { - PropSheet_RemovePage(hWndProp, 1, 0); - } - for (int i=0; i= 2 + 3*(config.multitap[0]+config.multitap[1])) { - *port = 0; - *slot = 0; - return 0; - } - if (index < 1 + 3*config.multitap[0]) { - *port = 0; - *slot = index; - } - else { - *port = 1; - *slot = index-1-3*config.multitap[0]; - } - return 1; +int ListIndexToPortAndSlot(int index, int *port, int *slot) +{ + if (index < 0 || index >= 2 + 3 * (config.multitap[0] + config.multitap[1])) { + *port = 0; + *slot = 0; + return 0; + } + if (index < 1 + 3 * config.multitap[0]) { + *port = 0; + *slot = index; + } else { + *port = 1; + *slot = index - 1 - 3 * config.multitap[0]; + } + return 1; } -void UpdatePadList(HWND hWnd) { - static u8 recurse = 0; - if (recurse) return; - recurse = 1; - HWND hWndList = GetDlgItem(hWnd, IDC_PAD_LIST); - HWND hWndCombo = GetDlgItem(hWnd, IDC_PAD_TYPE); - HWND hWndAnalog = GetDlgItem(hWnd, IDC_ANALOG_START1); - int slot; - int port; - int index = 0; +void UpdatePadList(HWND hWnd) +{ + static u8 recurse = 0; + if (recurse) + return; + recurse = 1; + HWND hWndList = GetDlgItem(hWnd, IDC_PAD_LIST); + HWND hWndCombo = GetDlgItem(hWnd, IDC_PAD_TYPE); + HWND hWndAnalog = GetDlgItem(hWnd, IDC_ANALOG_START1); + int slot; + int port; + int index = 0; - for (port=0; port<2; port++) { - for (slot = 0; slot<4; slot++) { - wchar_t text[25]; - if (!GetPadString(text, port, slot)) continue; - LVITEM item; - item.iItem = index; - item.iSubItem = 0; - item.mask = LVIF_TEXT; - item.pszText = text; - if (SendMessage(hWndList, LVM_GETITEMCOUNT, 0, 0) <= index) { - ListView_InsertItem(hWndList, &item); - } - else { - ListView_SetItem(hWndList, &item); - } + for (port = 0; port < 2; port++) { + for (slot = 0; slot < 4; slot++) { + wchar_t text[25]; + if (!GetPadString(text, port, slot)) + continue; + LVITEM item; + item.iItem = index; + item.iSubItem = 0; + item.mask = LVIF_TEXT; + item.pszText = text; + if (SendMessage(hWndList, LVM_GETITEMCOUNT, 0, 0) <= index) { + ListView_InsertItem(hWndList, &item); + } else { + ListView_SetItem(hWndList, &item); + } - item.iSubItem = 1; - if (numPadTypes - 1 < (unsigned int)config.padConfigs[port][slot].type) config.padConfigs[port][slot].type = Dualshock2Pad; - wcsncpy(item.pszText, padTypes[config.padConfigs[port][slot].type], 25); - //if (!slot && !config.padConfigs[port][slot].type) - // item.pszText = L"Unplugged (Kinda)"; + item.iSubItem = 1; + if (numPadTypes - 1 < (unsigned int)config.padConfigs[port][slot].type) + config.padConfigs[port][slot].type = Dualshock2Pad; + wcsncpy(item.pszText, padTypes[config.padConfigs[port][slot].type], 25); + //if (!slot && !config.padConfigs[port][slot].type) + // item.pszText = L"Unplugged (Kinda)"; - ListView_SetItem(hWndList, &item); + ListView_SetItem(hWndList, &item); - item.iSubItem = 2; - int count = 0; - for (int i = 0; inumDevices; i++) { - Device *dev = dm->devices[i]; - if (!dev->enabled) continue; - count += dev->pads[port][slot].numBindings + dev->pads[port][slot].numFFBindings; - } - wsprintf(text, L"%i", count); - item.pszText = text; - ListView_SetItem(hWndList, &item); - index++; - } - } - while (ListView_DeleteItem(hWndList, index)); - int sel = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + item.iSubItem = 2; + int count = 0; + for (int i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; + if (!dev->enabled) + continue; + count += dev->pads[port][slot].numBindings + dev->pads[port][slot].numFFBindings; + } + wsprintf(text, L"%i", count); + item.pszText = text; + ListView_SetItem(hWndList, &item); + index++; + } + } + while (ListView_DeleteItem(hWndList, index)) + ; + int sel = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - int enable; - if (!ListIndexToPortAndSlot(sel, &port, &slot)) { - enable = 0; - SendMessage(hWndCombo, CB_SETCURSEL, -1, 0); - CheckDlgButton(hWnd, IDC_ANALOG_START1, BST_UNCHECKED); - } - else { - enable = 1; - SendMessage(hWndCombo, CB_SETCURSEL, config.padConfigs[port][slot].type, 0); - CheckDlgButton(hWnd, IDC_ANALOG_START1, BST_CHECKED*config.padConfigs[port][slot].autoAnalog); - } - EnableWindow(hWndCombo, enable); - EnableWindow(hWndAnalog, enable); - //ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_DOUBLEBUFFER|LVS_EX_ONECLICKACTIVATE, LVS_EX_DOUBLEBUFFER|LVS_EX_ONECLICKACTIVATE); - recurse = 0; + int enable; + if (!ListIndexToPortAndSlot(sel, &port, &slot)) { + enable = 0; + SendMessage(hWndCombo, CB_SETCURSEL, -1, 0); + CheckDlgButton(hWnd, IDC_ANALOG_START1, BST_UNCHECKED); + } else { + enable = 1; + SendMessage(hWndCombo, CB_SETCURSEL, config.padConfigs[port][slot].type, 0); + CheckDlgButton(hWnd, IDC_ANALOG_START1, BST_CHECKED * config.padConfigs[port][slot].autoAnalog); + } + EnableWindow(hWndCombo, enable); + EnableWindow(hWndAnalog, enable); + //ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_DOUBLEBUFFER|LVS_EX_ONECLICKACTIVATE, LVS_EX_DOUBLEBUFFER|LVS_EX_ONECLICKACTIVATE); + recurse = 0; } -INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam) { - int i; - HWND hWndList = GetDlgItem(hWnd, IDC_PAD_LIST); - switch (msg) { - case WM_INITDIALOG: - { - HWND hWndCombo = GetDlgItem(hWnd, IDC_PAD_TYPE); - if (SendMessage(hWndCombo, CB_GETCOUNT, 0, 0) == 0) { - LVCOLUMN c; - c.mask = LVCF_TEXT | LVCF_WIDTH; - c.cx = 50; - c.pszText = L"Pad"; - ListView_InsertColumn(hWndList, 0, &c); - c.cx = 120; - c.pszText = L"Type"; - ListView_InsertColumn(hWndList, 1, &c); - c.cx = 70; - c.pszText = L"Bindings"; - ListView_InsertColumn(hWndList, 2, &c); - selected = 0; - ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER, LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER); - SendMessage(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); - for (int i = 0; i < numPadTypes; i++) - SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM) padTypes[i]); +INT_PTR CALLBACK GeneralDialogProc(HWND hWnd, unsigned int msg, WPARAM wParam, LPARAM lParam) +{ + int i; + HWND hWndList = GetDlgItem(hWnd, IDC_PAD_LIST); + switch (msg) { + case WM_INITDIALOG: { + HWND hWndCombo = GetDlgItem(hWnd, IDC_PAD_TYPE); + if (SendMessage(hWndCombo, CB_GETCOUNT, 0, 0) == 0) { + LVCOLUMN c; + c.mask = LVCF_TEXT | LVCF_WIDTH; + c.cx = 50; + c.pszText = L"Pad"; + ListView_InsertColumn(hWndList, 0, &c); + c.cx = 120; + c.pszText = L"Type"; + ListView_InsertColumn(hWndList, 1, &c); + c.cx = 70; + c.pszText = L"Bindings"; + ListView_InsertColumn(hWndList, 2, &c); + selected = 0; + ListView_SetExtendedListViewStyleEx(hWndList, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER); + SendMessage(hWndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); + for (int i = 0; i < numPadTypes; i++) + SendMessage(hWndCombo, CB_ADDSTRING, 0, (LPARAM)padTypes[i]); - if (ps2e) { - // This disabled some widgets which are not required for PCSX2. - // Currently the trigger is that it's in PS2 emulation mode - const UINT* toDisable = PCSX2_disabledWidgets(); - while (toDisable && *toDisable) { - EnableWindow(GetDlgItem(hWnd, *toDisable), 0); - toDisable++; - } - } - } - } - UpdatePadPages(); - hWndGeneral = hWnd; - RefreshEnabledDevicesAndDisplay(0, hWnd, 0); - UpdatePadList(hWnd); + if (ps2e) { + // This disabled some widgets which are not required for PCSX2. + // Currently the trigger is that it's in PS2 emulation mode + const UINT *toDisable = PCSX2_disabledWidgets(); + while (toDisable && *toDisable) { + EnableWindow(GetDlgItem(hWnd, *toDisable), 0); + toDisable++; + } + } + } + } + UpdatePadPages(); + hWndGeneral = hWnd; + RefreshEnabledDevicesAndDisplay(0, hWnd, 0); + UpdatePadList(hWnd); - if (!DualShock3Possible()) { - config.gameApis.dualShock3 = 0; - EnableWindow(GetDlgItem(hWnd, IDC_G_DS3), 0); - } + if (!DualShock3Possible()) { + config.gameApis.dualShock3 = 0; + EnableWindow(GetDlgItem(hWnd, IDC_G_DS3), 0); + } - for (int j=0; j>1)); + CheckDlgButton(hWnd, IDC_CLOSE_HACK1, BST_CHECKED * (config.closeHacks & 1)); + CheckDlgButton(hWnd, IDC_CLOSE_HACK2, BST_CHECKED * ((config.closeHacks & 2) >> 1)); - if (config.keyboardApi < 0 || config.keyboardApi > 3) config.keyboardApi = NO_API; - CheckRadioButton(hWnd, IDC_KB_DISABLE, IDC_KB_RAW, IDC_KB_DISABLE + config.keyboardApi); - if (config.mouseApi < 0 || config.mouseApi > 3) config.mouseApi = NO_API; - CheckRadioButton(hWnd, IDC_M_DISABLE, IDC_M_RAW, IDC_M_DISABLE + config.mouseApi); + if (config.keyboardApi < 0 || config.keyboardApi > 3) + config.keyboardApi = NO_API; + CheckRadioButton(hWnd, IDC_KB_DISABLE, IDC_KB_RAW, IDC_KB_DISABLE + config.keyboardApi); + if (config.mouseApi < 0 || config.mouseApi > 3) + config.mouseApi = NO_API; + CheckRadioButton(hWnd, IDC_M_DISABLE, IDC_M_RAW, IDC_M_DISABLE + config.mouseApi); - break; - case WM_DEVICECHANGE: - if (wParam == DBT_DEVNODES_CHANGED) { - RefreshEnabledDevicesAndDisplay(1, hWndGeneral, 1); - UpdatePadList(hWnd); - } - break; - case WM_COMMAND: - if (LOWORD(wParam) == IDC_PAD_TYPE) { - if (HIWORD(wParam) == CBN_SELCHANGE) { - HWND hWndCombo = GetDlgItem(hWnd, IDC_PAD_TYPE); - int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - int sel = SendMessage(hWndCombo, CB_GETCURSEL, 0, 0); - int port, slot; - if (sel < 0 || !ListIndexToPortAndSlot(index, &port, &slot)) break; - if (sel != config.padConfigs[port][slot].type) { - config.padConfigs[port][slot].type = (PadType)sel; - UpdatePadList(hWnd); - UpdatePadPages(); - RefreshEnabledDevicesAndDisplay(0, hWnd, 1); - PropSheet_Changed(hWndProp, hWnd); - } - } - } - else if (HIWORD(wParam)==BN_CLICKED && (LOWORD(wParam) == ID_LOAD || LOWORD(wParam) == ID_SAVE)) { - OPENFILENAMEW ofn; - memset (&ofn, 0, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hWnd; - ofn.lpstrFilter = L"LilyPad Config Files\0*.lily\0All Files\0*.*\0\0"; - wchar_t file[MAX_PATH+1]; - ofn.lpstrFile = file; - ofn.nMaxFile = MAX_PATH; - wcscpy(file, config.lastSaveConfigFileName); - ofn.lpstrInitialDir = config.lastSaveConfigPath; - ofn.Flags = OFN_DONTADDTORECENT | OFN_LONGNAMES | OFN_NOCHANGEDIR; - ofn.lpstrDefExt = L"lily"; - if (LOWORD(wParam) == ID_LOAD) { - ofn.lpstrTitle = L"Load LilyPad Configuration"; - ofn.Flags |= OFN_FILEMUSTEXIST; - if (GetOpenFileNameW(&ofn)) { - LoadSettings(1, ofn.lpstrFile); - GeneralDialogProc(hWnd, WM_INITDIALOG, 0, 0); - PropSheet_Changed(hWndProp, hWnd); - } - } - else { - ofn.lpstrTitle = L"Save LilyPad Configuration"; - ofn.Flags |= OFN_OVERWRITEPROMPT; - if (GetSaveFileNameW(&ofn)) { - if (SaveSettings(ofn.lpstrFile) == -1) { - MessageBox(hWnd, L"Save fail", L"Couldn't save file.", MB_OK); - } - } - } - break; - } + break; + case WM_DEVICECHANGE: + if (wParam == DBT_DEVNODES_CHANGED) { + RefreshEnabledDevicesAndDisplay(1, hWndGeneral, 1); + UpdatePadList(hWnd); + } + break; + case WM_COMMAND: + if (LOWORD(wParam) == IDC_PAD_TYPE) { + if (HIWORD(wParam) == CBN_SELCHANGE) { + HWND hWndCombo = GetDlgItem(hWnd, IDC_PAD_TYPE); + int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + int sel = SendMessage(hWndCombo, CB_GETCURSEL, 0, 0); + int port, slot; + if (sel < 0 || !ListIndexToPortAndSlot(index, &port, &slot)) + break; + if (sel != config.padConfigs[port][slot].type) { + config.padConfigs[port][slot].type = (PadType)sel; + UpdatePadList(hWnd); + UpdatePadPages(); + RefreshEnabledDevicesAndDisplay(0, hWnd, 1); + PropSheet_Changed(hWndProp, hWnd); + } + } + } else if (HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == ID_LOAD || LOWORD(wParam) == ID_SAVE)) { + OPENFILENAMEW ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = L"LilyPad Config Files\0*.lily\0All Files\0*.*\0\0"; + wchar_t file[MAX_PATH + 1]; + ofn.lpstrFile = file; + ofn.nMaxFile = MAX_PATH; + wcscpy(file, config.lastSaveConfigFileName); + ofn.lpstrInitialDir = config.lastSaveConfigPath; + ofn.Flags = OFN_DONTADDTORECENT | OFN_LONGNAMES | OFN_NOCHANGEDIR; + ofn.lpstrDefExt = L"lily"; + if (LOWORD(wParam) == ID_LOAD) { + ofn.lpstrTitle = L"Load LilyPad Configuration"; + ofn.Flags |= OFN_FILEMUSTEXIST; + if (GetOpenFileNameW(&ofn)) { + LoadSettings(1, ofn.lpstrFile); + GeneralDialogProc(hWnd, WM_INITDIALOG, 0, 0); + PropSheet_Changed(hWndProp, hWnd); + } + } else { + ofn.lpstrTitle = L"Save LilyPad Configuration"; + ofn.Flags |= OFN_OVERWRITEPROMPT; + if (GetSaveFileNameW(&ofn)) { + if (SaveSettings(ofn.lpstrFile) == -1) { + MessageBox(hWnd, L"Save fail", L"Couldn't save file.", MB_OK); + } + } + } + break; + } - else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam) == ID_TEST) { - Diagnostics(hWnd); - RefreshEnabledDevices(); - } - else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam) == ID_REFRESH) { - RefreshEnabledDevicesAndDisplay(1, hWnd, 1); - UpdatePadList(hWnd); - } - else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam) == IDC_ANALOG_START1) { - int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - int port, slot; - if (!ListIndexToPortAndSlot(index, &port, &slot)) break; - config.padConfigs[port][slot].autoAnalog = (IsDlgButtonChecked(hWnd, IDC_ANALOG_START1) == BST_CHECKED); - PropSheet_Changed(hWndProp, hWnd); - } - else { - int t = IDC_CLOSE_HACK1; - int test = LOWORD(wParam); - if (test == IDC_CLOSE_HACK1) { - CheckDlgButton(hWnd, IDC_CLOSE_HACK2, BST_UNCHECKED); - } - else if (test == IDC_CLOSE_HACK2) { - CheckDlgButton(hWnd, IDC_CLOSE_HACK1, BST_UNCHECKED); - } + else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == ID_TEST) { + Diagnostics(hWnd); + RefreshEnabledDevices(); + } else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == ID_REFRESH) { + RefreshEnabledDevicesAndDisplay(1, hWnd, 1); + UpdatePadList(hWnd); + } else if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_ANALOG_START1) { + int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + int port, slot; + if (!ListIndexToPortAndSlot(index, &port, &slot)) + break; + config.padConfigs[port][slot].autoAnalog = (IsDlgButtonChecked(hWnd, IDC_ANALOG_START1) == BST_CHECKED); + PropSheet_Changed(hWndProp, hWnd); + } else { + int t = IDC_CLOSE_HACK1; + int test = LOWORD(wParam); + if (test == IDC_CLOSE_HACK1) { + CheckDlgButton(hWnd, IDC_CLOSE_HACK2, BST_UNCHECKED); + } else if (test == IDC_CLOSE_HACK2) { + CheckDlgButton(hWnd, IDC_CLOSE_HACK1, BST_UNCHECKED); + } - int mtap = config.multitap[0] + 2*config.multitap[1]; + int mtap = config.multitap[0] + 2 * config.multitap[1]; - for (int j=0; jhdr.hwndFrom == hWndProp) { - switch(n->hdr.code) { - case PSN_QUERYCANCEL: - case PSN_KILLACTIVE: - EndBinding(hWnd); - return 0; - case PSN_SETACTIVE: - //selected = 0; - UpdatePadList(hWnd); - return 0; - case PSN_APPLY: - selected = 0; - if (SaveSettings()) { - SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - return 0; - } - SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_NOERROR); - return 1; - } - } - else if (n->hdr.idFrom == IDC_LIST && n->hdr.code == NM_DBLCLK) { - Diagnostics(hWnd); - } - else if (n->hdr.idFrom == IDC_PAD_LIST) { - if (n->hdr.code == LVN_ITEMCHANGED) { - UpdatePadList(hWnd); - } - if (n->hdr.code == NM_RCLICK) { - UpdatePadList(hWnd); - int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); - int port1, slot1, port2, slot2; - if (!ListIndexToPortAndSlot(index, &port1, &slot1)) break; - HMENU hMenu = CreatePopupMenu(); - if (!hMenu) break; - MENUITEMINFOW info; - for (port2=1; port2>=0; port2--) { - for (slot2 = 3; slot2>=0; slot2--) { - wchar_t text[40]; - wchar_t pad[20]; - if (!GetPadString(pad, port2, slot2)) continue; - info.cbSize = sizeof(info); - info.fMask = MIIM_STRING | MIIM_ID; - info.dwTypeData = text; - if (port2 == port1 && slot2 == slot1) { - int index = GetMenuItemCount(hMenu); - wsprintfW(text, L"Clear %s Bindings", pad); - info.wID = -1; - InsertMenuItemW(hMenu, index, 1, &info); - info.fMask = MIIM_TYPE; - info.fType = MFT_SEPARATOR; - InsertMenuItemW(hMenu, index, 1, &info); - } - else { - info.wID = port2+2*slot2+1; - wsprintfW(text, L"Swap with %s", pad); - InsertMenuItemW(hMenu, 0, 1, &info); - } - } - } - POINT pos; - GetCursorPos(&pos); - short res = TrackPopupMenuEx(hMenu, TPM_NONOTIFY|TPM_RETURNCMD, pos.x, pos.y, hWndProp, 0); - DestroyMenu(hMenu); - if (!res) break; - if (res > 0) { - res--; - slot2 = res / 2; - port2 = res&1; - PadConfig padCfgTemp = config.padConfigs[port1][slot1]; - config.padConfigs[port1][slot1] = config.padConfigs[port2][slot2]; - config.padConfigs[port2][slot2] = padCfgTemp; - for (int i=0; inumDevices; i++) { - if (dm->devices[i]->type == IGNORE) continue; - PadBindings bindings = dm->devices[i]->pads[port1][slot1]; - dm->devices[i]->pads[port1][slot1] = dm->devices[i]->pads[port2][slot2]; - dm->devices[i]->pads[port2][slot2] = bindings; - } - } - else { - for (int i=0; inumDevices; i++) { - if (dm->devices[i]->type == IGNORE) continue; - free(dm->devices[i]->pads[port1][slot1].bindings); - for (int j=0; jdevices[i]->pads[port1][slot1].numFFBindings; j++) { - free(dm->devices[i]->pads[port1][slot1].ffBindings[j].axes); - } - free(dm->devices[i]->pads[port1][slot1].ffBindings); - memset(&dm->devices[i]->pads[port1][slot1], 0, sizeof(dm->devices[i]->pads[port1][slot1])); - } - } - UpdatePadPages(); - UpdatePadList(hWnd); - PropSheet_Changed(hWndProp, hWnd); - } - } - } - break; - default: - break; - } - return 0; + PropSheet_Changed(hWndProp, hWnd); + } + break; + case WM_NOTIFY: { + PSHNOTIFY *n = (PSHNOTIFY *)lParam; + if (n->hdr.hwndFrom == hWndProp) { + switch (n->hdr.code) { + case PSN_QUERYCANCEL: + case PSN_KILLACTIVE: + EndBinding(hWnd); + return 0; + case PSN_SETACTIVE: + //selected = 0; + UpdatePadList(hWnd); + return 0; + case PSN_APPLY: + selected = 0; + if (SaveSettings()) { + SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); + return 0; + } + SetWindowLongPtr(hWnd, DWLP_MSGRESULT, PSNRET_NOERROR); + return 1; + } + } else if (n->hdr.idFrom == IDC_LIST && n->hdr.code == NM_DBLCLK) { + Diagnostics(hWnd); + } else if (n->hdr.idFrom == IDC_PAD_LIST) { + if (n->hdr.code == LVN_ITEMCHANGED) { + UpdatePadList(hWnd); + } + if (n->hdr.code == NM_RCLICK) { + UpdatePadList(hWnd); + int index = ListView_GetNextItem(hWndList, -1, LVNI_SELECTED); + int port1, slot1, port2, slot2; + if (!ListIndexToPortAndSlot(index, &port1, &slot1)) + break; + HMENU hMenu = CreatePopupMenu(); + if (!hMenu) + break; + MENUITEMINFOW info; + for (port2 = 1; port2 >= 0; port2--) { + for (slot2 = 3; slot2 >= 0; slot2--) { + wchar_t text[40]; + wchar_t pad[20]; + if (!GetPadString(pad, port2, slot2)) + continue; + info.cbSize = sizeof(info); + info.fMask = MIIM_STRING | MIIM_ID; + info.dwTypeData = text; + if (port2 == port1 && slot2 == slot1) { + int index = GetMenuItemCount(hMenu); + wsprintfW(text, L"Clear %s Bindings", pad); + info.wID = -1; + InsertMenuItemW(hMenu, index, 1, &info); + info.fMask = MIIM_TYPE; + info.fType = MFT_SEPARATOR; + InsertMenuItemW(hMenu, index, 1, &info); + } else { + info.wID = port2 + 2 * slot2 + 1; + wsprintfW(text, L"Swap with %s", pad); + InsertMenuItemW(hMenu, 0, 1, &info); + } + } + } + POINT pos; + GetCursorPos(&pos); + short res = TrackPopupMenuEx(hMenu, TPM_NONOTIFY | TPM_RETURNCMD, pos.x, pos.y, hWndProp, 0); + DestroyMenu(hMenu); + if (!res) + break; + if (res > 0) { + res--; + slot2 = res / 2; + port2 = res & 1; + PadConfig padCfgTemp = config.padConfigs[port1][slot1]; + config.padConfigs[port1][slot1] = config.padConfigs[port2][slot2]; + config.padConfigs[port2][slot2] = padCfgTemp; + for (int i = 0; i < dm->numDevices; i++) { + if (dm->devices[i]->type == IGNORE) + continue; + PadBindings bindings = dm->devices[i]->pads[port1][slot1]; + dm->devices[i]->pads[port1][slot1] = dm->devices[i]->pads[port2][slot2]; + dm->devices[i]->pads[port2][slot2] = bindings; + } + } else { + for (int i = 0; i < dm->numDevices; i++) { + if (dm->devices[i]->type == IGNORE) + continue; + free(dm->devices[i]->pads[port1][slot1].bindings); + for (int j = 0; j < dm->devices[i]->pads[port1][slot1].numFFBindings; j++) { + free(dm->devices[i]->pads[port1][slot1].ffBindings[j].axes); + } + free(dm->devices[i]->pads[port1][slot1].ffBindings); + memset(&dm->devices[i]->pads[port1][slot1], 0, sizeof(dm->devices[i]->pads[port1][slot1])); + } + } + UpdatePadPages(); + UpdatePadList(hWnd); + PropSheet_Changed(hWndProp, hWnd); + } + } + } break; + default: + break; + } + return 0; } -int CALLBACK PropSheetProc(HWND hWnd, UINT msg, LPARAM lParam) { - if (hWnd) hWndProp = hWnd; - return 0; +int CALLBACK PropSheetProc(HWND hWnd, UINT msg, LPARAM lParam) +{ + if (hWnd) + hWndProp = hWnd; + return 0; } -void Configure() { - // Can end up here without PADinit() being called first. - LoadSettings(); - // Can also end up here after running emulator a bit, and possibly - // disabling some devices due to focus changes, or releasing mouse. - RefreshEnabledDevices(0); +void Configure() +{ + // Can end up here without PADinit() being called first. + LoadSettings(); + // Can also end up here after running emulator a bit, and possibly + // disabling some devices due to focus changes, or releasing mouse. + RefreshEnabledDevices(0); - memset(hWnds, 0, sizeof(hWnds)); + memset(hWnds, 0, sizeof(hWnds)); - PROPSHEETPAGE psp; - ZeroMemory(&psp, sizeof(psp)); - psp.dwSize = sizeof(psp); - psp.dwFlags = PSP_USETITLE | PSP_PREMATURE; - psp.hInstance = hInst; - psp.pfnDlgProc = GeneralDialogProc; - psp.pszTitle = L"General"; - psp.pszTemplate = MAKEINTRESOURCE(IDD_GENERAL); - HPROPSHEETPAGE page = CreatePropertySheetPage(&psp); - if (!page) return; + PROPSHEETPAGE psp; + ZeroMemory(&psp, sizeof(psp)); + psp.dwSize = sizeof(psp); + psp.dwFlags = PSP_USETITLE | PSP_PREMATURE; + psp.hInstance = hInst; + psp.pfnDlgProc = GeneralDialogProc; + psp.pszTitle = L"General"; + psp.pszTemplate = MAKEINTRESOURCE(IDD_GENERAL); + HPROPSHEETPAGE page = CreatePropertySheetPage(&psp); + if (!page) + return; - PROPSHEETHEADER psh; - ZeroMemory(&psh, sizeof(psh)); - psh.dwFlags = PSH_DEFAULT | PSH_USECALLBACK | PSH_NOCONTEXTHELP; - psh.dwSize = sizeof(PROPSHEETHEADER); - psh.pfnCallback = PropSheetProc; - psh.hwndParent = GetActiveWindow(); - psh.nPages = 1; - psh.phpage = &page; - wchar_t title[200]; - GetNameAndVersionString(title); - wcscat(title, L" Settings"); - psh.pszCaption = title; - PropertySheet(&psh); - LoadSettings(1); - memset(hWnds, 0, sizeof(hWnds)); + PROPSHEETHEADER psh; + ZeroMemory(&psh, sizeof(psh)); + psh.dwFlags = PSH_DEFAULT | PSH_USECALLBACK | PSH_NOCONTEXTHELP; + psh.dwSize = sizeof(PROPSHEETHEADER); + psh.pfnCallback = PropSheetProc; + psh.hwndParent = GetActiveWindow(); + psh.nPages = 1; + psh.phpage = &page; + wchar_t title[200]; + GetNameAndVersionString(title); + wcscat(title, L" Settings"); + psh.pszCaption = title; + PropertySheet(&psh); + LoadSettings(1); + memset(hWnds, 0, sizeof(hWnds)); } -void UnloadConfigs() { - if (dm) { - delete dm; - dm = 0; - } +void UnloadConfigs() +{ + if (dm) { + delete dm; + dm = 0; + } } diff --git a/plugins/LilyPad/Config.h b/plugins/LilyPad/Config.h index 9e7e8c0a7d..f35a8332d4 100644 --- a/plugins/LilyPad/Config.h +++ b/plugins/LilyPad/Config.h @@ -21,60 +21,65 @@ extern u8 ps2e; enum PadType { - DisabledPad, - Dualshock2Pad, - GuitarPad, - PopnPad + DisabledPad, + Dualshock2Pad, + GuitarPad, + PopnPad }; -const int numPadTypes= 4; +const int numPadTypes = 4; extern const wchar_t *padTypes[numPadTypes]; -struct PadConfig { - PadType type; - u8 autoAnalog; +struct PadConfig +{ + PadType type; + u8 autoAnalog; }; -struct GeneralConfig { +struct GeneralConfig +{ public: - PadConfig padConfigs[2][4]; + PadConfig padConfigs[2][4]; - u8 closeHacks; + u8 closeHacks; - DeviceAPI keyboardApi; - DeviceAPI mouseApi; + DeviceAPI keyboardApi; + DeviceAPI mouseApi; - // Derived value, calculated by GetInput(). - u8 ignoreKeys; + // Derived value, calculated by GetInput(). + u8 ignoreKeys; - union { - struct { - u8 forceHide; - u8 mouseUnfocus; - u8 background; - u8 multipleBinding; + union + { + struct + { + u8 forceHide; + u8 mouseUnfocus; + u8 background; + u8 multipleBinding; - struct { - u8 directInput; - u8 xInput; - u8 dualShock3; - } gameApis; + struct + { + u8 directInput; + u8 xInput; + u8 dualShock3; + } gameApis; - u8 multitap[2]; + u8 multitap[2]; - u8 escapeFullscreenHack; - u8 disableScreenSaver; - u8 debug; + u8 escapeFullscreenHack; + u8 disableScreenSaver; + u8 debug; - u8 saveStateTitle; - u8 GH2; - u8 turboKeyHack; - }; - u8 bools[15]; - }; + u8 saveStateTitle; + u8 GH2; + u8 turboKeyHack; + }; + u8 bools[15]; + }; - wchar_t lastSaveConfigPath[MAX_PATH+1]; - wchar_t lastSaveConfigFileName[MAX_PATH+1]; + wchar_t lastSaveConfigPath[MAX_PATH + 1]; + wchar_t lastSaveConfigFileName[MAX_PATH + 1]; }; extern GeneralConfig config; diff --git a/plugins/LilyPad/DeviceEnumerator.cpp b/plugins/LilyPad/DeviceEnumerator.cpp index 8760c62cbf..bf39407f4f 100644 --- a/plugins/LilyPad/DeviceEnumerator.cpp +++ b/plugins/LilyPad/DeviceEnumerator.cpp @@ -33,24 +33,25 @@ #include "Linux/JoyEvdev.h" #endif -void EnumDevices(int hideDXXinput) { - // Needed for enumeration of some device types. - dm->ReleaseInput(); - InputDeviceManager *oldDm = dm; - dm = new InputDeviceManager(); +void EnumDevices(int hideDXXinput) +{ + // Needed for enumeration of some device types. + dm->ReleaseInput(); + InputDeviceManager *oldDm = dm; + dm = new InputDeviceManager(); #ifdef _MSC_VER - EnumWindowsMessagingDevices(); - EnumRawInputDevices(); - EnumDualShock3s(); - EnumXInputDevices(); - EnumDirectInputDevices(hideDXXinput); + EnumWindowsMessagingDevices(); + EnumRawInputDevices(); + EnumDualShock3s(); + EnumXInputDevices(); + EnumDirectInputDevices(hideDXXinput); #else - EnumLnx(); - EnumJoystickEvdev(); + EnumLnx(); + EnumJoystickEvdev(); #endif - dm->CopyBindings(oldDm->numDevices, oldDm->devices); + dm->CopyBindings(oldDm->numDevices, oldDm->devices); - delete oldDm; + delete oldDm; } diff --git a/plugins/LilyPad/DeviceEnumerator.h b/plugins/LilyPad/DeviceEnumerator.h index 255fd459b4..7a6f84442b 100644 --- a/plugins/LilyPad/DeviceEnumerator.h +++ b/plugins/LilyPad/DeviceEnumerator.h @@ -16,4 +16,3 @@ */ void EnumDevices(int hideDXXinput); - diff --git a/plugins/LilyPad/Diagnostics.cpp b/plugins/LilyPad/Diagnostics.cpp index d5c169f821..a227de3e4d 100644 --- a/plugins/LilyPad/Diagnostics.cpp +++ b/plugins/LilyPad/Diagnostics.cpp @@ -25,121 +25,121 @@ Device *dev; -INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam) { - int i; - HWND hWndList = GetDlgItem(hWnd, IDC_LIST); - static int fullRefresh; - if (dev) { - switch (uMsg) { - case WM_INITDIALOG: - { - fullRefresh = 1; - SetWindowText(hWnd, dev->displayName); - LVCOLUMNW c; - c.mask = LVCF_TEXT | LVCF_WIDTH; - c.cx = 151; - c.pszText = L"Control"; - ListView_InsertColumn(hWndList, 0, &c); - c.cx = 90; - c.pszText = L"Value"; - ListView_InsertColumn(hWndList, 1, &c); - ListView_DeleteAllItems(hWndList); - LVITEM item; - item.mask = LVIF_TEXT; - item.iSubItem = 0; - for (i=0; inumVirtualControls; i++) { - item.pszText = dev->GetVirtualControlName(dev->virtualControls+i); - item.iItem = i; - ListView_InsertItem(hWndList, &item); - } - SetTimer(hWnd, 1, 200, 0); - } - //break; - case WM_TIMER: - { - hWndButtonProc.SetWndHandle(hWndList); - InitInfo info = {0, 1, hWnd, &hWndButtonProc}; - dm->Update(&info); - LVITEMW item; - item.mask = LVIF_TEXT; - item.iSubItem = 1; - //ShowWindow(hWndList, 0); - //LockWindowUpdate(hWndList); - if (!dev->active) { - item.pszText = L"?"; - for (i=0; inumVirtualControls; i++) { - item.iItem = i; - ListView_SetItem(hWndList, &item); - } - fullRefresh = 1; - } - else { - for (i=0; inumVirtualControls; i++) { - if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) { +INT_PTR CALLBACK DiagDialog(HWND hWnd, unsigned int uMsg, WPARAM wParam, LPARAM lParam) +{ + int i; + HWND hWndList = GetDlgItem(hWnd, IDC_LIST); + static int fullRefresh; + if (dev) { + switch (uMsg) { + case WM_INITDIALOG: { + fullRefresh = 1; + SetWindowText(hWnd, dev->displayName); + LVCOLUMNW c; + c.mask = LVCF_TEXT | LVCF_WIDTH; + c.cx = 151; + c.pszText = L"Control"; + ListView_InsertColumn(hWndList, 0, &c); + c.cx = 90; + c.pszText = L"Value"; + ListView_InsertColumn(hWndList, 1, &c); + ListView_DeleteAllItems(hWndList); + LVITEM item; + item.mask = LVIF_TEXT; + item.iSubItem = 0; + for (i = 0; i < dev->numVirtualControls; i++) { + item.pszText = dev->GetVirtualControlName(dev->virtualControls + i); + item.iItem = i; + ListView_InsertItem(hWndList, &item); + } + SetTimer(hWnd, 1, 200, 0); + } + //break; + case WM_TIMER: { + hWndButtonProc.SetWndHandle(hWndList); + InitInfo info = {0, 1, hWnd, &hWndButtonProc}; + dm->Update(&info); + LVITEMW item; + item.mask = LVIF_TEXT; + item.iSubItem = 1; + //ShowWindow(hWndList, 0); + //LockWindowUpdate(hWndList); + if (!dev->active) { + item.pszText = L"?"; + for (i = 0; i < dev->numVirtualControls; i++) { + item.iItem = i; + ListView_SetItem(hWndList, &item); + } + fullRefresh = 1; + } else { + for (i = 0; i < dev->numVirtualControls; i++) { + if (fullRefresh || dev->virtualControlState[i] != dev->oldVirtualControlState[i]) { - VirtualControl *c = dev->virtualControls + i; - wchar_t temp[50]; - int val = dev->virtualControlState[i]; - if (c->uid & (UID_POV)) { - wsprintfW(temp, L"%i", val); - } - else { - wchar_t *sign = L""; - if (val < 0) { - sign = L"-"; - val = -val; - } - if ((c->uid& UID_AXIS) && val) { - val = val; - } - val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN); - wsprintfW(temp, L"%s%i.%03i", sign, val/1000, val%1000); - } - item.pszText = temp; - item.iItem = i; - ListView_SetItem(hWndList, &item); - } - } - dm->PostRead(); - fullRefresh = 0; - } - //LockWindowUpdate(0); - //ShowWindow(hWndList, 1); - //UpdateWindow(hWnd); - } - break; - case WM_NOTIFY: - { - NMLVKEYDOWN *n = (NMLVKEYDOWN *) lParam; - // Don't always get the notification when testing DirectInput non-keyboard devices. - // Don't get it (Or want it) when testing keyboards. - if (n->hdr.idFrom != IDC_LIST || n->hdr.code != LVN_KEYDOWN || n->wVKey != VK_ESCAPE) break; - } - case WM_ACTIVATE: - if (uMsg == WM_ACTIVATE && wParam != WA_INACTIVE) break; - break; - case WM_CLOSE: - KillTimer(hWnd, 1); - dm->ReleaseInput(); - // Prevents reaching this branch again. - dev = 0; - EndDialog(hWnd, 1); - break; - default: - break; - } - } - return 0; + VirtualControl *c = dev->virtualControls + i; + wchar_t temp[50]; + int val = dev->virtualControlState[i]; + if (c->uid & (UID_POV)) { + wsprintfW(temp, L"%i", val); + } else { + wchar_t *sign = L""; + if (val < 0) { + sign = L"-"; + val = -val; + } + if ((c->uid & UID_AXIS) && val) { + val = val; + } + val = (int)floor(0.5 + val * 1000.0 / (double)FULLY_DOWN); + wsprintfW(temp, L"%s%i.%03i", sign, val / 1000, val % 1000); + } + item.pszText = temp; + item.iItem = i; + ListView_SetItem(hWndList, &item); + } + } + dm->PostRead(); + fullRefresh = 0; + } + //LockWindowUpdate(0); + //ShowWindow(hWndList, 1); + //UpdateWindow(hWnd); + } break; + case WM_NOTIFY: { + NMLVKEYDOWN *n = (NMLVKEYDOWN *)lParam; + // Don't always get the notification when testing DirectInput non-keyboard devices. + // Don't get it (Or want it) when testing keyboards. + if (n->hdr.idFrom != IDC_LIST || n->hdr.code != LVN_KEYDOWN || n->wVKey != VK_ESCAPE) + break; + } + case WM_ACTIVATE: + if (uMsg == WM_ACTIVATE && wParam != WA_INACTIVE) + break; + break; + case WM_CLOSE: + KillTimer(hWnd, 1); + dm->ReleaseInput(); + // Prevents reaching this branch again. + dev = 0; + EndDialog(hWnd, 1); + break; + default: + break; + } + } + return 0; } -void Diagnose(int id, HWND hWnd) { - // init = 0; - dev = dm->devices[id]; - for (int i=0; inumDevices; i++) { - if (i != id) dm->DisableDevice(i); - // Shouldn't be needed. - else dm->EnableDevice(i); - } - DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog); - ClearKeyQueue(); +void Diagnose(int id, HWND hWnd) +{ + // init = 0; + dev = dm->devices[id]; + for (int i = 0; i < dm->numDevices; i++) { + if (i != id) + dm->DisableDevice(i); + // Shouldn't be needed. + else + dm->EnableDevice(i); + } + DialogBox(hInst, MAKEINTRESOURCE(IDD_DIAG), hWnd, DiagDialog); + ClearKeyQueue(); } diff --git a/plugins/LilyPad/DirectInput.cpp b/plugins/LilyPad/DirectInput.cpp index 0fa4e7e2a0..ee038fa71a 100644 --- a/plugins/LilyPad/DirectInput.cpp +++ b/plugins/LilyPad/DirectInput.cpp @@ -32,186 +32,208 @@ // media SDK also be installed for a simple macro. This is // simpler and less silly. #ifndef SAFE_RELEASE -#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } +#define SAFE_RELEASE(p) \ + { \ + if (p) { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } #endif // Aka htons, without the winsock dependency. -inline static u16 flipShort(u16 s) { - return (s>>8) | (s<<8); +inline static u16 flipShort(u16 s) +{ + return (s >> 8) | (s << 8); } // Aka htonl, without the winsock dependency. -inline static u32 flipLong(u32 l) { - return (((u32)flipShort((u16)l))<<16) | flipShort((u16)(l>>16)); +inline static u32 flipLong(u32 l) +{ + return (((u32)flipShort((u16)l)) << 16) | flipShort((u16)(l >> 16)); } -static void GUIDtoString(wchar_t *data, const GUID *pg) { - wsprintfW(data, L"%08X-%04X-%04X-%04X-%04X%08X", - pg->Data1, (u32)pg->Data2, (u32)pg->Data3, - flipShort(((u16*)pg->Data4)[0]), - flipShort(((u16*)pg->Data4)[1]), - flipLong(((u32*)pg->Data4)[1])); +static void GUIDtoString(wchar_t *data, const GUID *pg) +{ + wsprintfW(data, L"%08X-%04X-%04X-%04X-%04X%08X", + pg->Data1, (u32)pg->Data2, (u32)pg->Data3, + flipShort(((u16 *)pg->Data4)[0]), + flipShort(((u16 *)pg->Data4)[1]), + flipLong(((u32 *)pg->Data4)[1])); } -struct DirectInput8Data { - IDirectInput8* lpDI8; - int refCount; - int deviceCount; +struct DirectInput8Data +{ + IDirectInput8 *lpDI8; + int refCount; + int deviceCount; }; -DirectInput8Data di8d = {0,0,0}; +DirectInput8Data di8d = {0, 0, 0}; -IDirectInput8* GetDirectInput() { - if (!di8d.lpDI8) { - if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void**) &di8d.lpDI8, 0))) return 0; - } - di8d.refCount++; - return di8d.lpDI8; +IDirectInput8 *GetDirectInput() +{ + if (!di8d.lpDI8) { + if (FAILED(DirectInput8Create(hInst, 0x800, IID_IDirectInput8, (void **)&di8d.lpDI8, 0))) + return 0; + } + di8d.refCount++; + return di8d.lpDI8; } -void ReleaseDirectInput() { - if (di8d.refCount) { - di8d.refCount--; - if (!di8d.refCount) { - di8d.lpDI8->Release(); - di8d.lpDI8 = 0; - } - } +void ReleaseDirectInput() +{ + if (di8d.refCount) { + di8d.refCount--; + if (!di8d.refCount) { + di8d.lpDI8->Release(); + di8d.lpDI8 = 0; + } + } } -static int StringToGUID(GUID *pg, wchar_t *dataw) { - char data[100]; - if (wcslen(dataw) > 50) return 0; - int w = 0; - while (dataw[w]) { - data[w] = (char) dataw[w]; - w++; - } - data[w] = 0; - u32 temp[5]; - sscanf(data, "%08X-%04X-%04X-%04X-%04X%08X", - &pg->Data1, temp, temp+1, - temp+2, temp+3, temp+4); - pg->Data2 = (u16) temp[0]; - pg->Data3 = (u16) temp[1]; - ((u16*)pg->Data4)[0] = flipShort((u16)temp[2]); - ((u16*)pg->Data4)[1] = flipShort((u16)temp[3]); - ((u32*)pg->Data4)[1] = flipLong(temp[4]); - return 1; +static int StringToGUID(GUID *pg, wchar_t *dataw) +{ + char data[100]; + if (wcslen(dataw) > 50) + return 0; + int w = 0; + while (dataw[w]) { + data[w] = (char)dataw[w]; + w++; + } + data[w] = 0; + u32 temp[5]; + sscanf(data, "%08X-%04X-%04X-%04X-%04X%08X", + &pg->Data1, temp, temp + 1, + temp + 2, temp + 3, temp + 4); + pg->Data2 = (u16)temp[0]; + pg->Data3 = (u16)temp[1]; + ((u16 *)pg->Data4)[0] = flipShort((u16)temp[2]); + ((u16 *)pg->Data4)[1] = flipShort((u16)temp[3]); + ((u32 *)pg->Data4)[1] = flipLong(temp[4]); + return 1; } -struct DI8Effect { - IDirectInputEffect *die; - int scale; +struct DI8Effect +{ + IDirectInputEffect *die; + int scale; }; -BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); +BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef); BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef); -class DirectInputDevice : public Device { +class DirectInputDevice : public Device +{ public: - DI8Effect *diEffects; + DI8Effect *diEffects; - IDirectInputDevice8 *did; - GUID guidInstance; - DirectInputDevice(DeviceType type, IDirectInputDevice8* did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID, GUID guid) : Device(DI, type, displayName, instanceID, productID) { - diEffects = 0; - guidInstance = guid; - this->did = 0; - did->EnumEffects(EnumEffectsCallback, this, DIEFT_ALL); - did->EnumObjects(EnumDeviceObjectsCallback, this, DIDFT_ALL); - did->Release(); - } + IDirectInputDevice8 *did; + GUID guidInstance; + DirectInputDevice(DeviceType type, IDirectInputDevice8 *did, wchar_t *displayName, wchar_t *instanceID, wchar_t *productID, GUID guid) + : Device(DI, type, displayName, instanceID, productID) + { + diEffects = 0; + guidInstance = guid; + this->did = 0; + did->EnumEffects(EnumEffectsCallback, this, DIEFT_ALL); + did->EnumObjects(EnumDeviceObjectsCallback, this, DIDFT_ALL); + did->Release(); + } - void SetEffect(ForceFeedbackBinding *binding, unsigned char force) { - int index = 0; - if (!diEffects) { - return; - } - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - unsigned int diff = binding - pads[port][slot].ffBindings; - if (diff < (unsigned int)pads[port][slot].numFFBindings) { - index += diff; - port = 2; - break; - } - index += pads[port][slot].numFFBindings; - } - } - IDirectInputEffect *die = diEffects[index].die; - if (die) { - DIEFFECT dieffect; - memset(&dieffect, 0, sizeof(dieffect)); - union { - DIPERIODIC periodic; - DIRAMPFORCE ramp; - DICONSTANTFORCE constant; - }; + void SetEffect(ForceFeedbackBinding *binding, unsigned char force) + { + int index = 0; + if (!diEffects) { + return; + } + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + unsigned int diff = binding - pads[port][slot].ffBindings; + if (diff < (unsigned int)pads[port][slot].numFFBindings) { + index += diff; + port = 2; + break; + } + index += pads[port][slot].numFFBindings; + } + } + IDirectInputEffect *die = diEffects[index].die; + if (die) { + DIEFFECT dieffect; + memset(&dieffect, 0, sizeof(dieffect)); + union + { + DIPERIODIC periodic; + DIRAMPFORCE ramp; + DICONSTANTFORCE constant; + }; - dieffect.dwSize = sizeof(dieffect); - dieffect.lpvTypeSpecificParams = &periodic; - int magnitude = abs((int)((force*10000*(__int64)diEffects[index].scale)/BASE_SENSITIVITY/255)); - if (magnitude > 10000) magnitude = 10000; - int type = ffEffectTypes[binding->effectIndex].type; - if (type == EFFECT_CONSTANT) { - dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - constant.lMagnitude = magnitude; - } - else if (type == EFFECT_PERIODIC) { - dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC); - periodic.dwMagnitude = 0; - periodic.lOffset = magnitude; - periodic.dwPhase = 0; - periodic.dwPeriod = 2000000; - } - else if (type == EFFECT_RAMP) { - dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); - ramp.lEnd = ramp.lStart = magnitude; - } - dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS; - dieffect.dwDuration = 2000000; - die->SetParameters(&dieffect, DIEP_TYPESPECIFICPARAMS | DIEP_START); - } - } + dieffect.dwSize = sizeof(dieffect); + dieffect.lpvTypeSpecificParams = &periodic; + int magnitude = abs((int)((force * 10000 * (__int64)diEffects[index].scale) / BASE_SENSITIVITY / 255)); + if (magnitude > 10000) + magnitude = 10000; + int type = ffEffectTypes[binding->effectIndex].type; + if (type == EFFECT_CONSTANT) { + dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + constant.lMagnitude = magnitude; + } else if (type == EFFECT_PERIODIC) { + dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC); + periodic.dwMagnitude = 0; + periodic.lOffset = magnitude; + periodic.dwPhase = 0; + periodic.dwPeriod = 2000000; + } else if (type == EFFECT_RAMP) { + dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); + ramp.lEnd = ramp.lStart = magnitude; + } + dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS; + dieffect.dwDuration = 2000000; + die->SetParameters(&dieffect, DIEP_TYPESPECIFICPARAMS | DIEP_START); + } + } - int Activate(InitInfo *initInfo) { - int i; - IDirectInput8 *di8 = GetDirectInput(); - Deactivate(); - if (!di8) return 0; - if (DI_OK != di8->CreateDevice(guidInstance, &did, 0)) { - ReleaseDirectInput(); - did = 0; - return 0; - } + int Activate(InitInfo *initInfo) + { + int i; + IDirectInput8 *di8 = GetDirectInput(); + Deactivate(); + if (!di8) + return 0; + if (DI_OK != di8->CreateDevice(guidInstance, &did, 0)) { + ReleaseDirectInput(); + did = 0; + return 0; + } - { - DIOBJECTDATAFORMAT *formats = (DIOBJECTDATAFORMAT*)calloc(numPhysicalControls, sizeof(DIOBJECTDATAFORMAT)); - for (i=0; iSetDataFormat(&format); - for (i=0; iSetProperty(DIPROP_RANGE, &prop.diph); + { + DIOBJECTDATAFORMAT *formats = (DIOBJECTDATAFORMAT *)calloc(numPhysicalControls, sizeof(DIOBJECTDATAFORMAT)); + for (i = 0; i < numPhysicalControls; i++) { + formats[i].dwType = physicalControls[i].type | DIDFT_MAKEINSTANCE(physicalControls[i].id); + formats[i].dwOfs = 4 * i; + } + DIDATAFORMAT format; + format.dwSize = sizeof(format); + format.dwDataSize = 4 * numPhysicalControls; + format.dwObjSize = sizeof(DIOBJECTDATAFORMAT); + format.dwFlags = 0; + format.dwNumObjs = numPhysicalControls; + format.rgodf = formats; + int res = did->SetDataFormat(&format); + for (i = 0; i < numPhysicalControls; i++) { + if (physicalControls[i].type == ABSAXIS) { + DIPROPRANGE prop; + prop.diph.dwHeaderSize = sizeof(DIPROPHEADER); + prop.diph.dwSize = sizeof(DIPROPRANGE); + prop.diph.dwObj = formats[i].dwType; + prop.diph.dwHow = DIPH_BYID; + prop.lMin = -FULLY_DOWN; + prop.lMax = FULLY_DOWN; + did->SetProperty(DIPROP_RANGE, &prop.diph); - // May do something like this again, if there's any need. - /* + // May do something like this again, if there's any need. + /* if (FAILED(DI->did->SetProperty(DIPROP_RANGE, &prop.diph))) { if (FAILED(DI->did->GetProperty(DIPROP_RANGE, &prop.diph))) { // ???? @@ -223,418 +245,423 @@ public: DI->objects[i].min = prop.lMin; DI->objects[i].max = prop.lMax; //*/ - } - } - free(formats); - } - // Note: Have to use hWndTop to properly hide cursor for mouse device. - if (type == OTHER) { - did->SetCooperativeLevel(initInfo->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE); - } - else if (type == KEYBOARD) { - did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND); - } - else { - did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE); - } - if (did->Acquire() != DI_OK) { - did->Release(); - did = 0; - ReleaseDirectInput(); - return 0; - } - AllocState(); - int count = GetFFBindingCount(); - diEffects = (DI8Effect*) calloc(count, sizeof(DI8Effect)); - i = 0; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - int subIndex = i; - for (int j=0; jeffectIndex; - GUID guid; - if (!StringToGUID(&guid, eff->effectID)) continue; + } + } + free(formats); + } + // Note: Have to use hWndTop to properly hide cursor for mouse device. + if (type == OTHER) { + did->SetCooperativeLevel(initInfo->hWndTop, DISCL_BACKGROUND | DISCL_EXCLUSIVE); + } else if (type == KEYBOARD) { + did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND); + } else { + did->SetCooperativeLevel(initInfo->hWndTop, DISCL_FOREGROUND | DISCL_EXCLUSIVE); + } + if (did->Acquire() != DI_OK) { + did->Release(); + did = 0; + ReleaseDirectInput(); + return 0; + } + AllocState(); + int count = GetFFBindingCount(); + diEffects = (DI8Effect *)calloc(count, sizeof(DI8Effect)); + i = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + int subIndex = i; + for (int j = 0; j < pads[port][slot].numFFBindings; j++) { + ForceFeedbackBinding *b = 0; + b = &pads[port][slot].ffBindings[i - subIndex]; + ForceFeedbackEffectType *eff = ffEffectTypes + b->effectIndex; + GUID guid; + if (!StringToGUID(&guid, eff->effectID)) + continue; - DIEFFECT dieffect; - memset(&dieffect, 0, sizeof(dieffect)); - dieffect.dwSize = sizeof(dieffect); - dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS; - dieffect.dwDuration = 1000000; - dieffect.dwGain = 10000; - dieffect.dwTriggerButton = DIEB_NOTRIGGER; - union { - DIPERIODIC pediodic; - DIRAMPFORCE ramp; - DICONSTANTFORCE constant; - } stuff = {0,0,0,0}; + DIEFFECT dieffect; + memset(&dieffect, 0, sizeof(dieffect)); + dieffect.dwSize = sizeof(dieffect); + dieffect.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTIDS; + dieffect.dwDuration = 1000000; + dieffect.dwGain = 10000; + dieffect.dwTriggerButton = DIEB_NOTRIGGER; + union + { + DIPERIODIC pediodic; + DIRAMPFORCE ramp; + DICONSTANTFORCE constant; + } stuff = {0, 0, 0, 0}; - if (eff->type == EFFECT_CONSTANT) { - dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); - } - else if (eff->type == EFFECT_PERIODIC) { - dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC); - } - else if (eff->type == EFFECT_RAMP) { - dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); - } - dieffect.lpvTypeSpecificParams = &stuff; + if (eff->type == EFFECT_CONSTANT) { + dieffect.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + } else if (eff->type == EFFECT_PERIODIC) { + dieffect.cbTypeSpecificParams = sizeof(DIPERIODIC); + } else if (eff->type == EFFECT_RAMP) { + dieffect.cbTypeSpecificParams = sizeof(DIRAMPFORCE); + } + dieffect.lpvTypeSpecificParams = &stuff; - int maxForce = 0; - int numAxes = 0; - int *axes = (int*) malloc(sizeof(int) * 3 * numFFAxes); - DWORD *axisIDs = (DWORD*)(axes + numFFAxes); - LONG *dirList = (LONG*)(axisIDs + numFFAxes); - dieffect.rgdwAxes = axisIDs; - dieffect.rglDirection = dirList; - for (int k=0; kaxes[k].force) { - int force = abs(b->axes[k].force); - if (force > maxForce) { - maxForce = force; - } - axes[numAxes] = k; - axisIDs[numAxes] = ffAxes[k].id; - dirList[numAxes] = b->axes[k].force; - numAxes++; - } - } - if (!numAxes) { - free(axes); - continue; - } - dieffect.cAxes = numAxes; - diEffects[i].scale = maxForce; - if (!SUCCEEDED(did->CreateEffect(guid, &dieffect, &diEffects[i].die, 0))) { - diEffects[i].die = 0; - diEffects[i].scale = 0; - } + int maxForce = 0; + int numAxes = 0; + int *axes = (int *)malloc(sizeof(int) * 3 * numFFAxes); + DWORD *axisIDs = (DWORD *)(axes + numFFAxes); + LONG *dirList = (LONG *)(axisIDs + numFFAxes); + dieffect.rgdwAxes = axisIDs; + dieffect.rglDirection = dirList; + for (int k = 0; k < numFFAxes; k++) { + if (b->axes[k].force) { + int force = abs(b->axes[k].force); + if (force > maxForce) { + maxForce = force; + } + axes[numAxes] = k; + axisIDs[numAxes] = ffAxes[k].id; + dirList[numAxes] = b->axes[k].force; + numAxes++; + } + } + if (!numAxes) { + free(axes); + continue; + } + dieffect.cAxes = numAxes; + diEffects[i].scale = maxForce; + if (!SUCCEEDED(did->CreateEffect(guid, &dieffect, &diEffects[i].die, 0))) { + diEffects[i].die = 0; + diEffects[i].scale = 0; + } - free(axes); - axes = 0; - i++; - } - } - } - active = 1; - return 1; - } + free(axes); + axes = 0; + i++; + } + } + } + active = 1; + return 1; + } - int Update() { - if (!active) return 0; - if (numPhysicalControls) { - HRESULT res = did->Poll(); - // ?? - if ((res != DI_OK && res != DI_NOEFFECT) || - DI_OK != did->GetDeviceState(4*numPhysicalControls, physicalControlState)) { - Deactivate(); - return 0; - } - for (int i=0; iPoll(); + // ?? + if ((res != DI_OK && res != DI_NOEFFECT) || + DI_OK != did->GetDeviceState(4 * numPhysicalControls, physicalControlState)) { + Deactivate(); + return 0; + } + for (int i = 0; i < numPhysicalControls; i++) { + if (physicalControls[i].type & RELAXIS) { + physicalControlState[i] *= (FULLY_DOWN / 3); + } else if (physicalControls[i].type & BUTTON) { + physicalControlState[i] = (physicalControlState[i] & 0x80) * FULLY_DOWN / 128; + } + } + } + return 1; + } - int GetFFBindingCount() { - int count = 0; - for (int port = 0; port<2; port++) { - for (int slot = 0; slot<4; slot++) { - count += pads[port][slot].numFFBindings; - } - } - return count; - } + int GetFFBindingCount() + { + int count = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + count += pads[port][slot].numFFBindings; + } + } + return count; + } - void Deactivate() { - FreeState(); - if (diEffects) { - int count = GetFFBindingCount(); - for (int i=0; iStop(); - diEffects[i].die->Release(); - } - } - free(diEffects); - diEffects = 0; - } - if (active) { - did->Unacquire(); - did->Release(); - ReleaseDirectInput(); - did = 0; - active = 0; - } - } + void Deactivate() + { + FreeState(); + if (diEffects) { + int count = GetFFBindingCount(); + for (int i = 0; i < count; i++) { + if (diEffects[i].die) { + diEffects[i].die->Stop(); + diEffects[i].die->Release(); + } + } + free(diEffects); + diEffects = 0; + } + if (active) { + did->Unacquire(); + did->Release(); + ReleaseDirectInput(); + did = 0; + active = 0; + } + } - ~DirectInputDevice() { - } + ~DirectInputDevice() + { + } }; -BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef) { - DirectInputDevice * did = (DirectInputDevice*) pvRef; - EffectType type; - int diType = DIEFT_GETTYPE(pdei->dwEffType); - if (diType == DIEFT_CONSTANTFORCE) { - type = EFFECT_CONSTANT; - } - else if (diType == DIEFT_RAMPFORCE) { - type = EFFECT_RAMP; - } - else if (diType == DIEFT_PERIODIC) { - type = EFFECT_PERIODIC; - } - else { - return DIENUM_CONTINUE; - } - wchar_t guidString[50]; - GUIDtoString(guidString, &pdei->guid); - did->AddFFEffectType(pdei->tszName, guidString, type); +BOOL CALLBACK EnumEffectsCallback(LPCDIEFFECTINFOW pdei, LPVOID pvRef) +{ + DirectInputDevice *did = (DirectInputDevice *)pvRef; + EffectType type; + int diType = DIEFT_GETTYPE(pdei->dwEffType); + if (diType == DIEFT_CONSTANTFORCE) { + type = EFFECT_CONSTANT; + } else if (diType == DIEFT_RAMPFORCE) { + type = EFFECT_RAMP; + } else if (diType == DIEFT_PERIODIC) { + type = EFFECT_PERIODIC; + } else { + return DIENUM_CONTINUE; + } + wchar_t guidString[50]; + GUIDtoString(guidString, &pdei->guid); + did->AddFFEffectType(pdei->tszName, guidString, type); - return DIENUM_CONTINUE; + return DIENUM_CONTINUE; } -BOOL CALLBACK EnumDeviceObjectsCallback (LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) { - DirectInputDevice * did = (DirectInputDevice*) pvRef; - if (lpddoi->dwType & DIDFT_FFACTUATOR) { - did->AddFFAxis(lpddoi->tszName, lpddoi->dwType); - } +BOOL CALLBACK EnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef) +{ + DirectInputDevice *did = (DirectInputDevice *)pvRef; + if (lpddoi->dwType & DIDFT_FFACTUATOR) { + did->AddFFAxis(lpddoi->tszName, lpddoi->dwType); + } - ControlType type; + ControlType type; - if (lpddoi->dwType & DIDFT_POV) - type = POV; - else if (lpddoi->dwType & DIDFT_ABSAXIS) - type = ABSAXIS; - else if (lpddoi->dwType & DIDFT_RELAXIS) - type = RELAXIS; - else if (lpddoi->dwType & DIDFT_PSHBUTTON) - type = PSHBTN; - else if (lpddoi->dwType & DIDFT_TGLBUTTON) - type = TGLBTN; - else - return DIENUM_CONTINUE; - // If too many objects, ignore extra buttons. - if ((did->numPhysicalControls > 255 && DIDFT_GETINSTANCE(lpddoi->dwType) > 255) && (type & (DIDFT_PSHBUTTON | DIDFT_TGLBUTTON))) { - int i; - for (i = did->numPhysicalControls-1; i>did->numPhysicalControls-4; i--) { - if (!lpddoi->tszName[0]) break; - const wchar_t *s1 = lpddoi->tszName; - const wchar_t *s2 = did->physicalControls[i].name; - while (*s1 && *s1 == *s2) { - s1++; - s2++; - } - // If perfect match with one of last 4 names, break. - if (!*s1 && !*s2) break; + if (lpddoi->dwType & DIDFT_POV) + type = POV; + else if (lpddoi->dwType & DIDFT_ABSAXIS) + type = ABSAXIS; + else if (lpddoi->dwType & DIDFT_RELAXIS) + type = RELAXIS; + else if (lpddoi->dwType & DIDFT_PSHBUTTON) + type = PSHBTN; + else if (lpddoi->dwType & DIDFT_TGLBUTTON) + type = TGLBTN; + else + return DIENUM_CONTINUE; + // If too many objects, ignore extra buttons. + if ((did->numPhysicalControls > 255 && DIDFT_GETINSTANCE(lpddoi->dwType) > 255) && (type & (DIDFT_PSHBUTTON | DIDFT_TGLBUTTON))) { + int i; + for (i = did->numPhysicalControls - 1; i > did->numPhysicalControls - 4; i--) { + if (!lpddoi->tszName[0]) + break; + const wchar_t *s1 = lpddoi->tszName; + const wchar_t *s2 = did->physicalControls[i].name; + while (*s1 && *s1 == *s2) { + s1++; + s2++; + } + // If perfect match with one of last 4 names, break. + if (!*s1 && !*s2) + break; - while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9')) s1--; - int check = 0; - while (*s1 >= '0' && *s1 <= '9') { - check = check*10 + *s1 - '0'; - s1++; - } - while (*s2 >= '0' && *s2 <= '9') { - s2++; - } - // If perfect match other than final number > 30, then break. - // takes care of "button xx" case without causing issues with F keys. - if (!*s1 && !*s2 && check > 30) break; - } - if (i != did->numPhysicalControls-4) { - return DIENUM_CONTINUE; - } - } + while (s1 != lpddoi->tszName && (s1[-1] >= '0' && s1[-1] <= '9')) + s1--; + int check = 0; + while (*s1 >= '0' && *s1 <= '9') { + check = check * 10 + *s1 - '0'; + s1++; + } + while (*s2 >= '0' && *s2 <= '9') { + s2++; + } + // If perfect match other than final number > 30, then break. + // takes care of "button xx" case without causing issues with F keys. + if (!*s1 && !*s2 && check > 30) + break; + } + if (i != did->numPhysicalControls - 4) { + return DIENUM_CONTINUE; + } + } - int vkey = 0; - if (lpddoi->tszName[0] && did->type == KEYBOARD) { - for (u32 i = 0; i<256; i++) { - wchar_t *t = GetVKStringW((u8)i); - if (!wcsicmp(lpddoi->tszName, t)) { - vkey = i; - break; - } - } - } - did->AddPhysicalControl(type, DIDFT_GETINSTANCE(lpddoi->dwType), vkey, lpddoi->tszName); - return DIENUM_CONTINUE; + int vkey = 0; + if (lpddoi->tszName[0] && did->type == KEYBOARD) { + for (u32 i = 0; i < 256; i++) { + wchar_t *t = GetVKStringW((u8)i); + if (!wcsicmp(lpddoi->tszName, t)) { + vkey = i; + break; + } + } + } + did->AddPhysicalControl(type, DIDFT_GETINSTANCE(lpddoi->dwType), vkey, lpddoi->tszName); + return DIENUM_CONTINUE; } // Evil code from MS's site. If only they'd just made a way to get // an XInput device's GUID directly in the first place... -BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput ) +BOOL IsXInputDevice(const GUID *pGuidProductFromDirectInput) { - IWbemLocator* pIWbemLocator = NULL; - IEnumWbemClassObject* pEnumDevices = NULL; - IWbemClassObject* pDevices[20] = {0}; - IWbemServices* pIWbemServices = NULL; - BSTR bstrNamespace = NULL; - BSTR bstrDeviceID = NULL; - BSTR bstrClassName = NULL; - DWORD uReturned = 0; - bool bIsXinputDevice= false; - UINT iDevice = 0; - VARIANT var; - HRESULT hr; + IWbemLocator *pIWbemLocator = NULL; + IEnumWbemClassObject *pEnumDevices = NULL; + IWbemClassObject *pDevices[20] = {0}; + IWbemServices *pIWbemServices = NULL; + BSTR bstrNamespace = NULL; + BSTR bstrDeviceID = NULL; + BSTR bstrClassName = NULL; + DWORD uReturned = 0; + bool bIsXinputDevice = false; + UINT iDevice = 0; + VARIANT var; + HRESULT hr; // CoInit if needed hr = CoInitialize(NULL); bool bCleanupCOM = SUCCEEDED(hr); // Create WMI - hr = CoCreateInstance( __uuidof(WbemLocator), - NULL, - CLSCTX_INPROC_SERVER, - __uuidof(IWbemLocator), - (LPVOID*) &pIWbemLocator); - if( FAILED(hr) || pIWbemLocator == NULL ) + hr = CoCreateInstance(__uuidof(WbemLocator), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IWbemLocator), + (LPVOID *)&pIWbemLocator); + if (FAILED(hr) || pIWbemLocator == NULL) goto LCleanup; - bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup; - bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; - bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; + bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); + if (bstrNamespace == NULL) + goto LCleanup; + bstrClassName = SysAllocString(L"Win32_PNPEntity"); + if (bstrClassName == NULL) + goto LCleanup; + bstrDeviceID = SysAllocString(L"DeviceID"); + if (bstrDeviceID == NULL) + goto LCleanup; // Connect to WMI - hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L, - 0L, NULL, NULL, &pIWbemServices ); - if( FAILED(hr) || pIWbemServices == NULL ) + hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, + 0L, NULL, NULL, &pIWbemServices); + if (FAILED(hr) || pIWbemServices == NULL) goto LCleanup; // Switch security level to IMPERSONATE. - CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); + CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); - hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices ); - if( FAILED(hr) || pEnumDevices == NULL ) + hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices); + if (FAILED(hr) || pEnumDevices == NULL) goto LCleanup; // Loop over all devices - for( ;; ) - { + for (;;) { // Get 20 at a time - hr = pEnumDevices->Next( 10000, 20, pDevices, &uReturned ); - if( FAILED(hr) ) + hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned); + if (FAILED(hr)) goto LCleanup; - if( uReturned == 0 ) + if (uReturned == 0) break; - for( iDevice=0; iDeviceGet( bstrDeviceID, 0L, &var, NULL, NULL ); - if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL ) - { + hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL); + if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) { // Check if the device ID contains "IG_". If it does, then it's an XInput device - // This information can not be found from DirectInput - if( wcsstr( var.bstrVal, L"IG_" ) ) - { + // This information can not be found from DirectInput + if (wcsstr(var.bstrVal, L"IG_")) { // If it does, then get the VID/PID from var.bstrVal DWORD dwPid = 0, dwVid = 0; - WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" ); - if (strVid) { - dwVid = wcstoul(strVid+4, 0, 16); - } - WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" ); - if (strPid) { - dwPid = wcstoul(strPid+4, 0, 16); - } + WCHAR *strVid = wcsstr(var.bstrVal, L"VID_"); + if (strVid) { + dwVid = wcstoul(strVid + 4, 0, 16); + } + WCHAR *strPid = wcsstr(var.bstrVal, L"PID_"); + if (strPid) { + dwPid = wcstoul(strPid + 4, 0, 16); + } // Compare the VID/PID to the DInput device - DWORD dwVidPid = MAKELONG( dwVid, dwPid ); - if( dwVidPid == pGuidProductFromDirectInput->Data1 ) - { + DWORD dwVidPid = MAKELONG(dwVid, dwPid); + if (dwVidPid == pGuidProductFromDirectInput->Data1) { bIsXinputDevice = true; goto LCleanup; } } } - SAFE_RELEASE( pDevices[iDevice] ); + SAFE_RELEASE(pDevices[iDevice]); } } LCleanup: - if(bstrNamespace) + if (bstrNamespace) SysFreeString(bstrNamespace); - if(bstrDeviceID) + if (bstrDeviceID) SysFreeString(bstrDeviceID); - if(bstrClassName) + if (bstrClassName) SysFreeString(bstrClassName); - for( iDevice=0; iDevice<20; iDevice++ ) - SAFE_RELEASE( pDevices[iDevice] ); - SAFE_RELEASE( pEnumDevices ); - SAFE_RELEASE( pIWbemLocator ); - SAFE_RELEASE( pIWbemServices ); + for (iDevice = 0; iDevice < 20; iDevice++) + SAFE_RELEASE(pDevices[iDevice]); + SAFE_RELEASE(pEnumDevices); + SAFE_RELEASE(pIWbemLocator); + SAFE_RELEASE(pIWbemServices); - if( bCleanupCOM ) + if (bCleanupCOM) CoUninitialize(); return bIsXinputDevice; } -struct DeviceEnumInfo { - IDirectInput8 *di8; - int ignoreXInput; +struct DeviceEnumInfo +{ + IDirectInput8 *di8; + int ignoreXInput; }; -BOOL CALLBACK EnumCallback (LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) { - IDirectInput8* di8 = ((DeviceEnumInfo*)pvRef)->di8; - const wchar_t *name; - wchar_t temp[40]; - //if (((DeviceEnumInfo*)pvRef)->ignoreXInput && lpddi-> - if (lpddi->tszInstanceName[0]) { - name = lpddi->tszInstanceName; - } - else if (lpddi->tszProductName[0]) { - name = lpddi->tszProductName; - } - else { - wsprintfW (temp, L"Device %i", di8d.deviceCount); - name = temp; - } - di8d.deviceCount++; - wchar_t *fullName = (wchar_t *) malloc((wcslen(name) + 4) * sizeof(wchar_t)); - wsprintf(fullName, L"DX %s", name); - wchar_t instanceID[100]; - wchar_t productID[100]; - GUIDtoString(instanceID, &lpddi->guidInstance); - GUIDtoString(productID, &lpddi->guidProduct); - DeviceType type = OTHER; - if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD) { - type = KEYBOARD; - } - else if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE) { - type = MOUSE; - } - IDirectInputDevice8 *did; - if (DI_OK == di8->CreateDevice(lpddi->guidInstance, &did, 0)) { - DirectInputDevice *dev = new DirectInputDevice(type, did, fullName, instanceID, productID, lpddi->guidInstance); - if (dev->numPhysicalControls || dev->numFFAxes) { - dm->AddDevice(dev); - } - else { - delete dev; - } - } - free(fullName); - return DIENUM_CONTINUE; +BOOL CALLBACK EnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) +{ + IDirectInput8 *di8 = ((DeviceEnumInfo *)pvRef)->di8; + const wchar_t *name; + wchar_t temp[40]; + //if (((DeviceEnumInfo*)pvRef)->ignoreXInput && lpddi-> + if (lpddi->tszInstanceName[0]) { + name = lpddi->tszInstanceName; + } else if (lpddi->tszProductName[0]) { + name = lpddi->tszProductName; + } else { + wsprintfW(temp, L"Device %i", di8d.deviceCount); + name = temp; + } + di8d.deviceCount++; + wchar_t *fullName = (wchar_t *)malloc((wcslen(name) + 4) * sizeof(wchar_t)); + wsprintf(fullName, L"DX %s", name); + wchar_t instanceID[100]; + wchar_t productID[100]; + GUIDtoString(instanceID, &lpddi->guidInstance); + GUIDtoString(productID, &lpddi->guidProduct); + DeviceType type = OTHER; + if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_KEYBOARD) { + type = KEYBOARD; + } else if ((lpddi->dwDevType & 0xFF) == DI8DEVTYPE_MOUSE) { + type = MOUSE; + } + IDirectInputDevice8 *did; + if (DI_OK == di8->CreateDevice(lpddi->guidInstance, &did, 0)) { + DirectInputDevice *dev = new DirectInputDevice(type, did, fullName, instanceID, productID, lpddi->guidInstance); + if (dev->numPhysicalControls || dev->numFFAxes) { + dm->AddDevice(dev); + } else { + delete dev; + } + } + free(fullName); + return DIENUM_CONTINUE; } -void EnumDirectInputDevices(int ignoreXInput) { - DeviceEnumInfo enumInfo; - enumInfo.di8 = GetDirectInput(); - if (!enumInfo.di8) return; - enumInfo.ignoreXInput = ignoreXInput; - di8d.deviceCount = 0; - enumInfo.di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &enumInfo, DIEDFL_ATTACHEDONLY); - ReleaseDirectInput(); +void EnumDirectInputDevices(int ignoreXInput) +{ + DeviceEnumInfo enumInfo; + enumInfo.di8 = GetDirectInput(); + if (!enumInfo.di8) + return; + enumInfo.ignoreXInput = ignoreXInput; + di8d.deviceCount = 0; + enumInfo.di8->EnumDevices(DI8DEVCLASS_ALL, EnumCallback, &enumInfo, DIEDFL_ATTACHEDONLY); + ReleaseDirectInput(); } - diff --git a/plugins/LilyPad/DualShock3.cpp b/plugins/LilyPad/DualShock3.cpp index 5dfcaad6ff..54c080abfe 100644 --- a/plugins/LilyPad/DualShock3.cpp +++ b/plugins/LilyPad/DualShock3.cpp @@ -41,15 +41,15 @@ unsigned int lastDS3Check = 0; unsigned int lastDS3Enum = 0; -typedef void (__cdecl *_usb_init)(void); -typedef int (__cdecl *_usb_close)(usb_dev_handle *dev); -typedef int (__cdecl *_usb_get_string_simple)(usb_dev_handle *dev, int index, char *buf, size_t buflen); +typedef void(__cdecl *_usb_init)(void); +typedef int(__cdecl *_usb_close)(usb_dev_handle *dev); +typedef int(__cdecl *_usb_get_string_simple)(usb_dev_handle *dev, int index, char *buf, size_t buflen); typedef usb_dev_handle *(__cdecl *_usb_open)(struct usb_device *dev); -typedef int (__cdecl *_usb_find_busses)(void); -typedef int (__cdecl *_usb_find_devices)(void); +typedef int(__cdecl *_usb_find_busses)(void); +typedef int(__cdecl *_usb_find_devices)(void); typedef struct usb_bus *(__cdecl *_usb_get_busses)(void); typedef usb_dev_handle *(__cdecl *_usb_open)(struct usb_device *dev); -typedef int (__cdecl *_usb_control_msg)(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); +typedef int(__cdecl *_usb_control_msg)(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); _usb_init pusb_init; _usb_close pusb_close; @@ -62,408 +62,435 @@ _usb_control_msg pusb_control_msg; HMODULE hModLibusb = 0; -void UninitLibUsb() { - if (hModLibusb) { - FreeLibrary(hModLibusb); - hModLibusb = 0; - } +void UninitLibUsb() +{ + if (hModLibusb) { + FreeLibrary(hModLibusb); + hModLibusb = 0; + } } -void TryInitDS3(usb_device *dev) { - while (dev) { - if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) { - usb_dev_handle *handle = pusb_open(dev); - if (handle) { - char junk[20]; - // This looks like HidD_GetFeature with a feature report id of 0xF2 to me and a length of 17. - // That doesn't work, however, and 17 is shorter than the report length. - pusb_control_msg(handle, 0xa1, 1, 0x03f2, dev->config->interface->altsetting->bInterfaceNumber, junk, 17, 1000); - pusb_close(handle); - } - } - if (dev->num_children) { - for (int i=0; inum_children; i++) { - TryInitDS3(dev->children[i]); - } - } - dev = dev->next; - } +void TryInitDS3(usb_device *dev) +{ + while (dev) { + if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) { + usb_dev_handle *handle = pusb_open(dev); + if (handle) { + char junk[20]; + // This looks like HidD_GetFeature with a feature report id of 0xF2 to me and a length of 17. + // That doesn't work, however, and 17 is shorter than the report length. + pusb_control_msg(handle, 0xa1, 1, 0x03f2, dev->config->interface->altsetting->bInterfaceNumber, junk, 17, 1000); + pusb_close(handle); + } + } + if (dev->num_children) { + for (int i = 0; i < dev->num_children; i++) { + TryInitDS3(dev->children[i]); + } + } + dev = dev->next; + } } -void DS3Enum(unsigned int time) { - if (time - lastDS3Enum < DOUBLE_ENUM_DELAY) { - return; - } - lastDS3Enum = time; - pusb_find_busses(); - pusb_find_devices(); +void DS3Enum(unsigned int time) +{ + if (time - lastDS3Enum < DOUBLE_ENUM_DELAY) { + return; + } + lastDS3Enum = time; + pusb_find_busses(); + pusb_find_devices(); } -void DS3Check(unsigned int time) { - if (time - lastDS3Check < DOUBLE_CHECK_DELAY) { - return; - } - if (!lastDS3Check) { - DS3Enum(time); - } - lastDS3Check = time; +void DS3Check(unsigned int time) +{ + if (time - lastDS3Check < DOUBLE_CHECK_DELAY) { + return; + } + if (!lastDS3Check) { + DS3Enum(time); + } + lastDS3Check = time; - usb_bus *bus = pusb_get_busses(); - while (bus) { - TryInitDS3(bus->devices); - bus = bus->next; - } + usb_bus *bus = pusb_get_busses(); + while (bus) { + TryInitDS3(bus->devices); + bus = bus->next; + } } -int InitLibUsb() { - if (hModLibusb) { - return 1; - } - hModLibusb = LoadLibraryA("C:\\windows\\system32\\libusb0.dll"); - if (hModLibusb) { - if ((pusb_init = (_usb_init) GetProcAddress(hModLibusb, "usb_init")) && - (pusb_close = (_usb_close) GetProcAddress(hModLibusb, "usb_close")) && - (pusb_get_string_simple = (_usb_get_string_simple) GetProcAddress(hModLibusb, "usb_get_string_simple")) && - (pusb_open = (_usb_open) GetProcAddress(hModLibusb, "usb_open")) && - (pusb_find_busses = (_usb_find_busses) GetProcAddress(hModLibusb, "usb_find_busses")) && - (pusb_find_devices = (_usb_find_devices) GetProcAddress(hModLibusb, "usb_find_devices")) && - (pusb_get_busses = (_usb_get_busses) GetProcAddress(hModLibusb, "usb_get_busses")) && - (pusb_control_msg = (_usb_control_msg) GetProcAddress(hModLibusb, "usb_control_msg"))) { - pusb_init(); - return 1; - } - UninitLibUsb(); - } - return 0; +int InitLibUsb() +{ + if (hModLibusb) { + return 1; + } + hModLibusb = LoadLibraryA("C:\\windows\\system32\\libusb0.dll"); + if (hModLibusb) { + if ((pusb_init = (_usb_init)GetProcAddress(hModLibusb, "usb_init")) && + (pusb_close = (_usb_close)GetProcAddress(hModLibusb, "usb_close")) && + (pusb_get_string_simple = (_usb_get_string_simple)GetProcAddress(hModLibusb, "usb_get_string_simple")) && + (pusb_open = (_usb_open)GetProcAddress(hModLibusb, "usb_open")) && + (pusb_find_busses = (_usb_find_busses)GetProcAddress(hModLibusb, "usb_find_busses")) && + (pusb_find_devices = (_usb_find_devices)GetProcAddress(hModLibusb, "usb_find_devices")) && + (pusb_get_busses = (_usb_get_busses)GetProcAddress(hModLibusb, "usb_get_busses")) && + (pusb_control_msg = (_usb_control_msg)GetProcAddress(hModLibusb, "usb_control_msg"))) { + pusb_init(); + return 1; + } + UninitLibUsb(); + } + return 0; } -int DualShock3Possible() { - return InitLibUsb(); +int DualShock3Possible() +{ + return InitLibUsb(); } #include -struct MotorState { - unsigned char duration; - unsigned char force; +struct MotorState +{ + unsigned char duration; + unsigned char force; }; -struct LightState { - // 0xFF makes it stay on. - unsigned char duration; - // Have to make one or the other non-zero to turn on light. - unsigned char dunno[2]; - // 0 is fully lit. - unsigned char dimness; - // Have to make non-zero to turn on light. - unsigned char on; +struct LightState +{ + // 0xFF makes it stay on. + unsigned char duration; + // Have to make one or the other non-zero to turn on light. + unsigned char dunno[2]; + // 0 is fully lit. + unsigned char dimness; + // Have to make non-zero to turn on light. + unsigned char on; }; // Data sent to DS3 to set state. -struct DS3Command { - unsigned char id; - unsigned char unsure; - // Small is first, then big. - MotorState motors[2]; - unsigned char noClue[4]; - // 2 is pad 1 light, 4 is pad 2, 8 is pad 3, 16 is pad 4. No clue about the others. - unsigned char lightFlags; - // Lights are in reverse order. pad 1 is last. - LightState lights[4]; - unsigned char dunno[18]; +struct DS3Command +{ + unsigned char id; + unsigned char unsure; + // Small is first, then big. + MotorState motors[2]; + unsigned char noClue[4]; + // 2 is pad 1 light, 4 is pad 2, 8 is pad 3, 16 is pad 4. No clue about the others. + unsigned char lightFlags; + // Lights are in reverse order. pad 1 is last. + LightState lights[4]; + unsigned char dunno[18]; }; #include -int CharToAxis(unsigned char c) { - int v = (int)c + ((unsigned int)c >> 7); - return ((c-128) * FULLY_DOWN)>>7; +int CharToAxis(unsigned char c) +{ + int v = (int)c + ((unsigned int)c >> 7); + return ((c - 128) * FULLY_DOWN) >> 7; } -int CharToButton(unsigned char c) { - int v = (int)c + ((unsigned int)c >> 7); - return (v * FULLY_DOWN)>>8; +int CharToButton(unsigned char c) +{ + int v = (int)c + ((unsigned int)c >> 7); + return (v * FULLY_DOWN) >> 8; } -class DualShock3Device : public Device { - // Cached last vibration values by pad and motor. - // Need this, as only one value is changed at a time. - int ps2Vibration[2][4][2]; - int vibration[2]; +class DualShock3Device : public Device +{ + // Cached last vibration values by pad and motor. + // Need this, as only one value is changed at a time. + int ps2Vibration[2][4][2]; + int vibration[2]; + public: - int index; - HANDLE hFile; - DS3Command sendState; - unsigned char getState[49]; - OVERLAPPED readop; - OVERLAPPED writeop; - int writeCount; - int lastWrite; + int index; + HANDLE hFile; + DS3Command sendState; + unsigned char getState[49]; + OVERLAPPED readop; + OVERLAPPED writeop; + int writeCount; + int lastWrite; - unsigned int dataLastReceived; + unsigned int dataLastReceived; - int writeQueued; - int writing; + int writeQueued; + int writing; - int StartRead() { - int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop); - return (res || GetLastError() == ERROR_IO_PENDING); - } + int StartRead() + { + int res = ReadFile(hFile, &getState, sizeof(getState), 0, &readop); + return (res || GetLastError() == ERROR_IO_PENDING); + } - void QueueWrite() { - // max of 2 queued writes allowed, one for either motor. - if (writeQueued < 2) { - writeQueued++; - StartWrite(); - } - } + void QueueWrite() + { + // max of 2 queued writes allowed, one for either motor. + if (writeQueued < 2) { + writeQueued++; + StartWrite(); + } + } - int StartWrite() { - if (!writing && writeQueued) { - lastWrite = GetTickCount(); - writing++; - writeQueued--; - sendState.motors[0].duration = 0x50; - sendState.motors[1].duration = 0x50; + int StartWrite() + { + if (!writing && writeQueued) { + lastWrite = GetTickCount(); + writing++; + writeQueued--; + sendState.motors[0].duration = 0x50; + sendState.motors[1].duration = 0x50; - int bigForce = vibration[0] * 256/FULLY_DOWN; - if (bigForce > 255) bigForce = 255; - sendState.motors[1].force = (unsigned char) bigForce; - sendState.motors[0].force = (unsigned char) (vibration[1] >= FULLY_DOWN/2); - // Can't seem to have them both non-zero at once. - if (sendState.motors[writeCount&1].force) { - sendState.motors[(writeCount&1)^1].force = 0; - sendState.motors[(writeCount&1)^1].duration = 0; - } + int bigForce = vibration[0] * 256 / FULLY_DOWN; + if (bigForce > 255) + bigForce = 255; + sendState.motors[1].force = (unsigned char)bigForce; + sendState.motors[0].force = (unsigned char)(vibration[1] >= FULLY_DOWN / 2); + // Can't seem to have them both non-zero at once. + if (sendState.motors[writeCount & 1].force) { + sendState.motors[(writeCount & 1) ^ 1].force = 0; + sendState.motors[(writeCount & 1) ^ 1].duration = 0; + } - writeCount++; - int res = WriteFile(hFile, &sendState, sizeof(sendState), 0, &writeop); - return (res || GetLastError() == ERROR_IO_PENDING); - } - return 1; - } + writeCount++; + int res = WriteFile(hFile, &sendState, sizeof(sendState), 0, &writeop); + return (res || GetLastError() == ERROR_IO_PENDING); + } + return 1; + } - DualShock3Device(int index, wchar_t *name, wchar_t *path) : Device(DS3, OTHER, name, path, L"DualShock 3") { - writeCount = 0; - writing = 0; - writeQueued = 0; - memset(&readop, 0, sizeof(readop)); - memset(&writeop, 0, sizeof(writeop)); - memset(&sendState, 0, sizeof(sendState)); - sendState.id = 1; - int temp = (index&4); - sendState.lightFlags = (1 << (temp+1)); - sendState.lights[3-temp].duration = 0xFF; - sendState.lights[3-temp].dunno[0] = 1; - sendState.lights[3-temp].on = 1; - memset(ps2Vibration, 0, sizeof(ps2Vibration)); - vibration[0] = vibration[1] = 0; - this->index = index; - int i; - for (i=0; i<16; i++) { - if (i != 14 && i != 15 && i != 8 && i != 9) { - AddPhysicalControl(PRESSURE_BTN, i, 0); - } - else { - AddPhysicalControl(PSHBTN, i, 0); - } - } - for (; i<23; i++) { - AddPhysicalControl(ABSAXIS, i, 0); - } - AddFFAxis(L"Big Motor", 0); - AddFFAxis(L"Small Motor", 1); - AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT); - hFile = INVALID_HANDLE_VALUE; - } + DualShock3Device(int index, wchar_t *name, wchar_t *path) + : Device(DS3, OTHER, name, path, L"DualShock 3") + { + writeCount = 0; + writing = 0; + writeQueued = 0; + memset(&readop, 0, sizeof(readop)); + memset(&writeop, 0, sizeof(writeop)); + memset(&sendState, 0, sizeof(sendState)); + sendState.id = 1; + int temp = (index & 4); + sendState.lightFlags = (1 << (temp + 1)); + sendState.lights[3 - temp].duration = 0xFF; + sendState.lights[3 - temp].dunno[0] = 1; + sendState.lights[3 - temp].on = 1; + memset(ps2Vibration, 0, sizeof(ps2Vibration)); + vibration[0] = vibration[1] = 0; + this->index = index; + int i; + for (i = 0; i < 16; i++) { + if (i != 14 && i != 15 && i != 8 && i != 9) { + AddPhysicalControl(PRESSURE_BTN, i, 0); + } else { + AddPhysicalControl(PSHBTN, i, 0); + } + } + for (; i < 23; i++) { + AddPhysicalControl(ABSAXIS, i, 0); + } + AddFFAxis(L"Big Motor", 0); + AddFFAxis(L"Small Motor", 1); + AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT); + hFile = INVALID_HANDLE_VALUE; + } - wchar_t *GetPhysicalControlName(PhysicalControl *c) { - const static wchar_t *names[] = { - L"Square", - L"Cross", - L"Circle", - L"Triangle", - L"R1", - L"L1", - L"R2", - L"L2", - L"R3", - L"L3", - L"Left", - L"Down", - L"Right", - L"Up", - L"Start", - L"Select", - L"L-Stick X", - L"L-Stick Y", - L"R-Stick X", - L"R-Stick Y", - L"Left/Right Tilt", - L"Forward/Back Tilt", - L"???", - }; - unsigned int i = (unsigned int) (c - physicalControls); - if (i < sizeof(names)/sizeof(names[0])) { - return (wchar_t*)names[i]; - } - return Device::GetPhysicalControlName(c); - } + wchar_t *GetPhysicalControlName(PhysicalControl *c) + { + const static wchar_t *names[] = { + L"Square", + L"Cross", + L"Circle", + L"Triangle", + L"R1", + L"L1", + L"R2", + L"L2", + L"R3", + L"L3", + L"Left", + L"Down", + L"Right", + L"Up", + L"Start", + L"Select", + L"L-Stick X", + L"L-Stick Y", + L"R-Stick X", + L"R-Stick Y", + L"Left/Right Tilt", + L"Forward/Back Tilt", + L"???", + }; + unsigned int i = (unsigned int)(c - physicalControls); + if (i < sizeof(names) / sizeof(names[0])) { + return (wchar_t *)names[i]; + } + return Device::GetPhysicalControlName(c); + } - int Activate(InitInfo *initInfo) { - if (active) Deactivate(); - // Give grace period before get mad. - lastWrite = dataLastReceived = GetTickCount(); - readop.hEvent = CreateEvent(0, 0, 0, 0); - writeop.hEvent = CreateEvent(0, 0, 0, 0); - hFile = CreateFileW(instanceID, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - if (!readop.hEvent || !writeop.hEvent || hFile == INVALID_HANDLE_VALUE || - !StartRead()) { - Deactivate(); - return 0; - } - active = 1; - AllocState(); - return 1; - } + int Activate(InitInfo *initInfo) + { + if (active) + Deactivate(); + // Give grace period before get mad. + lastWrite = dataLastReceived = GetTickCount(); + readop.hEvent = CreateEvent(0, 0, 0, 0); + writeop.hEvent = CreateEvent(0, 0, 0, 0); + hFile = CreateFileW(instanceID, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + if (!readop.hEvent || !writeop.hEvent || hFile == INVALID_HANDLE_VALUE || + !StartRead()) { + Deactivate(); + return 0; + } + active = 1; + AllocState(); + return 1; + } - int Update() { - if (!active) return 0; - HANDLE h[2] = { - readop.hEvent, - writeop.hEvent - }; - unsigned int time = GetTickCount(); - if (time - lastWrite > UPDATE_INTERVAL) { - QueueWrite(); - } - while (1) { - DWORD res = WaitForMultipleObjects(2, h, 0, 0); - if (res == WAIT_OBJECT_0) { - dataLastReceived = time; - if (!StartRead()) { - Deactivate(); - return 0; - } + int Update() + { + if (!active) + return 0; + HANDLE h[2] = { + readop.hEvent, + writeop.hEvent}; + unsigned int time = GetTickCount(); + if (time - lastWrite > UPDATE_INTERVAL) { + QueueWrite(); + } + while (1) { + DWORD res = WaitForMultipleObjects(2, h, 0, 0); + if (res == WAIT_OBJECT_0) { + dataLastReceived = time; + if (!StartRead()) { + Deactivate(); + return 0; + } - physicalControlState[0] = CharToButton(getState[25]); - physicalControlState[1] = CharToButton(getState[24]); - physicalControlState[2] = CharToButton(getState[23]); - physicalControlState[3] = CharToButton(getState[22]); - physicalControlState[4] = CharToButton(getState[21]); - physicalControlState[5] = CharToButton(getState[20]); - physicalControlState[6] = CharToButton(getState[19]); - physicalControlState[7] = CharToButton(getState[18]); - physicalControlState[10] = CharToButton(getState[17]); - physicalControlState[11] = CharToButton(getState[16]); - physicalControlState[12] = CharToButton(getState[15]); - physicalControlState[13] = CharToButton(getState[14]); - physicalControlState[8] = ((getState[2]&4)/4) * FULLY_DOWN; - physicalControlState[9] = ((getState[2]&2)/2) * FULLY_DOWN; - physicalControlState[15] = ((getState[2]&1)/1) * FULLY_DOWN; - physicalControlState[14] = ((getState[2]&8)/8) * FULLY_DOWN; - physicalControlState[16] = CharToAxis(getState[6]); - physicalControlState[17] = CharToAxis(getState[7]); - physicalControlState[18] = CharToAxis(getState[8]); - physicalControlState[19] = CharToAxis(getState[9]); - physicalControlState[20] = CharToAxis(getState[42]+128); - physicalControlState[21] = CharToAxis(getState[44]+128); - physicalControlState[22] = CharToAxis(getState[46]+128); - continue; - } - else if (res == WAIT_OBJECT_0+1) { - writing = 0; - if (!writeQueued && (vibration[0] | vibration[1])) { - QueueWrite(); - } - if (!StartWrite()) { - Deactivate(); - return 0; - } - } - else { - if (time-dataLastReceived >= DEVICE_CHECK_DELAY) { - if (time-dataLastReceived >= DEVICE_ENUM_DELAY) { - DS3Enum(time); - } - DS3Check(time); - QueueWrite(); - } - } - break; - } - return 1; - } + physicalControlState[0] = CharToButton(getState[25]); + physicalControlState[1] = CharToButton(getState[24]); + physicalControlState[2] = CharToButton(getState[23]); + physicalControlState[3] = CharToButton(getState[22]); + physicalControlState[4] = CharToButton(getState[21]); + physicalControlState[5] = CharToButton(getState[20]); + physicalControlState[6] = CharToButton(getState[19]); + physicalControlState[7] = CharToButton(getState[18]); + physicalControlState[10] = CharToButton(getState[17]); + physicalControlState[11] = CharToButton(getState[16]); + physicalControlState[12] = CharToButton(getState[15]); + physicalControlState[13] = CharToButton(getState[14]); + physicalControlState[8] = ((getState[2] & 4) / 4) * FULLY_DOWN; + physicalControlState[9] = ((getState[2] & 2) / 2) * FULLY_DOWN; + physicalControlState[15] = ((getState[2] & 1) / 1) * FULLY_DOWN; + physicalControlState[14] = ((getState[2] & 8) / 8) * FULLY_DOWN; + physicalControlState[16] = CharToAxis(getState[6]); + physicalControlState[17] = CharToAxis(getState[7]); + physicalControlState[18] = CharToAxis(getState[8]); + physicalControlState[19] = CharToAxis(getState[9]); + physicalControlState[20] = CharToAxis(getState[42] + 128); + physicalControlState[21] = CharToAxis(getState[44] + 128); + physicalControlState[22] = CharToAxis(getState[46] + 128); + continue; + } else if (res == WAIT_OBJECT_0 + 1) { + writing = 0; + if (!writeQueued && (vibration[0] | vibration[1])) { + QueueWrite(); + } + if (!StartWrite()) { + Deactivate(); + return 0; + } + } else { + if (time - dataLastReceived >= DEVICE_CHECK_DELAY) { + if (time - dataLastReceived >= DEVICE_ENUM_DELAY) { + DS3Enum(time); + } + DS3Check(time); + QueueWrite(); + } + } + break; + } + return 1; + } - void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) { - ps2Vibration[port][slot][motor] = force; - vibration[0] = vibration[1] = 0; - for (int p=0; p<2; p++) { - for (int s=0; s<4; s++) { - for (int i=0; iaxes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); - vibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); - } - } - } - // Make sure at least 2 writes are queued, to update both motors. - QueueWrite(); - QueueWrite(); - } + void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) + { + ps2Vibration[port][slot][motor] = force; + vibration[0] = vibration[1] = 0; + for (int p = 0; p < 2; p++) { + for (int s = 0; s < 4; s++) { + for (int i = 0; i < pads[p][s].numFFBindings; i++) { + // Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me. + ForceFeedbackBinding *ffb = &pads[p][s].ffBindings[i]; + vibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); + vibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); + } + } + } + // Make sure at least 2 writes are queued, to update both motors. + QueueWrite(); + QueueWrite(); + } - void SetEffect(ForceFeedbackBinding *binding, unsigned char force) { - PadBindings pBackup = pads[0][0]; - pads[0][0].ffBindings = binding; - pads[0][0].numFFBindings = 1; - SetEffects(0, 0, binding->motor, 255); - pads[0][0] = pBackup; - } + void SetEffect(ForceFeedbackBinding *binding, unsigned char force) + { + PadBindings pBackup = pads[0][0]; + pads[0][0].ffBindings = binding; + pads[0][0].numFFBindings = 1; + SetEffects(0, 0, binding->motor, 255); + pads[0][0] = pBackup; + } - void Deactivate() { - if (hFile != INVALID_HANDLE_VALUE) { - CancelIo(hFile); - CloseHandle(hFile); - hFile = INVALID_HANDLE_VALUE; - } - if (readop.hEvent) { - CloseHandle(readop.hEvent); - } - if (writeop.hEvent) { - CloseHandle(writeop.hEvent); - } - writing = 0; - writeQueued = 0; - memset(ps2Vibration, 0, sizeof(ps2Vibration)); - vibration[0] = vibration[1] = 0; + void Deactivate() + { + if (hFile != INVALID_HANDLE_VALUE) { + CancelIo(hFile); + CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; + } + if (readop.hEvent) { + CloseHandle(readop.hEvent); + } + if (writeop.hEvent) { + CloseHandle(writeop.hEvent); + } + writing = 0; + writeQueued = 0; + memset(ps2Vibration, 0, sizeof(ps2Vibration)); + vibration[0] = vibration[1] = 0; - FreeState(); - active = 0; - } + FreeState(); + active = 0; + } - ~DualShock3Device() { - } + ~DualShock3Device() + { + } }; -void EnumDualShock3s() { - if (!InitLibUsb()) return; +void EnumDualShock3s() +{ + if (!InitLibUsb()) + return; - HidDeviceInfo *foundDevs = 0; + HidDeviceInfo *foundDevs = 0; - int numDevs = FindHids(&foundDevs, VID, PID); - if (!numDevs) return; - int index = 0; - for (int i=0; iAddDevice(new DualShock3Device(index, temp, foundDevs[i].path)); - index++; - } - free(foundDevs[i].path); - } - free(foundDevs); + int numDevs = FindHids(&foundDevs, VID, PID); + if (!numDevs) + return; + int index = 0; + for (int i = 0; i < numDevs; i++) { + if (foundDevs[i].caps.FeatureReportByteLength == 49 && + foundDevs[i].caps.InputReportByteLength == 49 && + foundDevs[i].caps.OutputReportByteLength == 49) { + wchar_t temp[100]; + wsprintfW(temp, L"DualShock 3 #%i", index + 1); + dm->AddDevice(new DualShock3Device(index, temp, foundDevs[i].path)); + index++; + } + free(foundDevs[i].path); + } + free(foundDevs); } diff --git a/plugins/LilyPad/Global.h b/plugins/LilyPad/Global.h index d4718a2029..e0f2f84102 100644 --- a/plugins/LilyPad/Global.h +++ b/plugins/LilyPad/Global.h @@ -23,58 +23,62 @@ typedef uint32_t DWORD; typedef uint16_t USHORT; #ifndef __INTEL_COMPILER -typedef int64_t __int64; +typedef int64_t __int64; #endif -#define MAX_PATH (256) // random value +#define MAX_PATH (256) // random value #include -#define VK_SHIFT XK_Shift_L -#define VK_LSHIFT XK_Shift_L -#define VK_RSHIFT XK_Shift_R -#define VK_LMENU XK_Menu -#define VK_RMENU XK_Menu -#define VK_MENU XK_Menu -#define VK_CONTROL XK_Control_L -#define VK_TAB XK_Tab -#define VK_ESCAPE XK_Escape -#define VK_F4 XK_F4 +#define VK_SHIFT XK_Shift_L +#define VK_LSHIFT XK_Shift_L +#define VK_RSHIFT XK_Shift_R +#define VK_LMENU XK_Menu +#define VK_RMENU XK_Menu +#define VK_MENU XK_Menu +#define VK_CONTROL XK_Control_L +#define VK_TAB XK_Tab +#define VK_ESCAPE XK_Escape +#define VK_F4 XK_F4 #include #include template -void wsprintfW(Array& buf, const wchar_t *format, ...) { - va_list a; - va_start(a, format); +void wsprintfW(Array &buf, const wchar_t *format, ...) +{ + va_list a; + va_start(a, format); - vswprintf(buf, sizeof(buf)/sizeof(buf[0]), format, a); + vswprintf(buf, sizeof(buf) / sizeof(buf[0]), format, a); - va_end(a); + va_end(a); } template -void wsprintf(Array& buf, const wchar_t *format, ...) { - va_list a; - va_start(a, format); +void wsprintf(Array &buf, const wchar_t *format, ...) +{ + va_list a; + va_start(a, format); - vswprintf(buf, sizeof(buf)/sizeof(buf[0]), format, a); + vswprintf(buf, sizeof(buf) / sizeof(buf[0]), format, a); - va_end(a); + va_end(a); } -static inline int wcsicmp(const wchar_t* w1, const wchar_t* w2) { - // I didn't find a way to put ignore case ... - return wcscmp(w1, w2); +static inline int wcsicmp(const wchar_t *w1, const wchar_t *w2) +{ + // I didn't find a way to put ignore case ... + return wcscmp(w1, w2); } #include -static inline unsigned int timeGetTime() { - struct timeval now; - gettimeofday(&now, NULL); - uint64_t ms = (now.tv_usec/1000) + ((uint64_t)now.tv_sec * 1000); - return (ms & 0xFFFFFFFF); // MS code is u32 ... +static inline unsigned int timeGetTime() +{ + struct timeval now; + gettimeofday(&now, NULL); + uint64_t ms = (now.tv_usec / 1000) + ((uint64_t)now.tv_sec * 1000); + return (ms & 0xFFFFFFFF); // MS code is u32 ... } #include "Utilities/Dependencies.h" @@ -84,7 +88,7 @@ static inline unsigned int timeGetTime() { #include extern Display *GSdsp; -extern Window GSwin; +extern Window GSwin; #endif @@ -95,7 +99,7 @@ extern Window GSwin; #ifdef _MSC_VER #define EXPORT_C_(type) extern "C" type CALLBACK #else -#define EXPORT_C_(type) extern "C" __attribute__((stdcall,externally_visible,visibility("default"))) type CALLBACK +#define EXPORT_C_(type) extern "C" __attribute__((stdcall, externally_visible, visibility("default"))) type CALLBACK #endif #ifdef _MSC_VER @@ -136,35 +140,60 @@ extern HINSTANCE hInst; // Needed for config screen void GetNameAndVersionString(wchar_t *out); -typedef struct { - unsigned char controllerType; - unsigned short buttonStatus; - unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY; - unsigned char moveX, moveY; - unsigned char reserved[91]; +typedef struct +{ + unsigned char controllerType; + unsigned short buttonStatus; + unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY; + unsigned char moveX, moveY; + unsigned char reserved[91]; } PadDataS; -EXPORT_C_(void) PADupdate(int pad); -EXPORT_C_(u32) PS2EgetLibType(void); -EXPORT_C_(u32) PS2EgetLibVersion2(u32 type); -EXPORT_C_(char*) PSEgetLibName(); -EXPORT_C_(char*) PS2EgetLibName(void); -EXPORT_C_(void) PADshutdown(); -EXPORT_C_(s32) PADinit(u32 flags); -EXPORT_C_(s32) PADopen(void *pDsp); -EXPORT_C_(void) PADclose(); -EXPORT_C_(u8) PADstartPoll(int pad); -EXPORT_C_(u8) PADpoll(u8 value); -EXPORT_C_(u32) PADquery(); -EXPORT_C_(void) PADabout(); -EXPORT_C_(s32) PADtest(); -EXPORT_C_(keyEvent*) PADkeyEvent(); -EXPORT_C_(u32) PADreadPort1 (PadDataS* pads); -EXPORT_C_(u32) PADreadPort2 (PadDataS* pads); -EXPORT_C_(u32) PSEgetLibType(); -EXPORT_C_(u32) PSEgetLibVersion(); -EXPORT_C_(void) PADconfigure(); -EXPORT_C_(s32) PADfreeze(int mode, freezeData *data); -EXPORT_C_(s32) PADsetSlot(u8 port, u8 slot); -EXPORT_C_(s32) PADqueryMtap(u8 port); -EXPORT_C_(void) PADsetSettingsDir(const char *dir); +EXPORT_C_(void) +PADupdate(int pad); +EXPORT_C_(u32) +PS2EgetLibType(void); +EXPORT_C_(u32) +PS2EgetLibVersion2(u32 type); +EXPORT_C_(char *) +PSEgetLibName(); +EXPORT_C_(char *) +PS2EgetLibName(void); +EXPORT_C_(void) +PADshutdown(); +EXPORT_C_(s32) +PADinit(u32 flags); +EXPORT_C_(s32) +PADopen(void *pDsp); +EXPORT_C_(void) +PADclose(); +EXPORT_C_(u8) +PADstartPoll(int pad); +EXPORT_C_(u8) +PADpoll(u8 value); +EXPORT_C_(u32) +PADquery(); +EXPORT_C_(void) +PADabout(); +EXPORT_C_(s32) +PADtest(); +EXPORT_C_(keyEvent *) +PADkeyEvent(); +EXPORT_C_(u32) +PADreadPort1(PadDataS *pads); +EXPORT_C_(u32) +PADreadPort2(PadDataS *pads); +EXPORT_C_(u32) +PSEgetLibType(); +EXPORT_C_(u32) +PSEgetLibVersion(); +EXPORT_C_(void) +PADconfigure(); +EXPORT_C_(s32) +PADfreeze(int mode, freezeData *data); +EXPORT_C_(s32) +PADsetSlot(u8 port, u8 slot); +EXPORT_C_(s32) +PADqueryMtap(u8 port); +EXPORT_C_(void) +PADsetSettingsDir(const char *dir); diff --git a/plugins/LilyPad/HidDevice.cpp b/plugins/LilyPad/HidDevice.cpp index 38e9fcfe43..29917cbf27 100644 --- a/plugins/LilyPad/HidDevice.cpp +++ b/plugins/LilyPad/HidDevice.cpp @@ -20,57 +20,61 @@ #include #include -int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) { - GUID GUID_DEVINTERFACE_HID; - int numFoundDevs = 0; - *foundDevs = 0; - HidD_GetHidGuid(&GUID_DEVINTERFACE_HID); - HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (hdev != INVALID_HANDLE_VALUE) { - SP_DEVICE_INTERFACE_DATA devInterfaceData; - devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - for (int i=0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++) { +int FindHids(HidDeviceInfo **foundDevs, int vid, int pid) +{ + GUID GUID_DEVINTERFACE_HID; + int numFoundDevs = 0; + *foundDevs = 0; + HidD_GetHidGuid(&GUID_DEVINTERFACE_HID); + HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (hdev != INVALID_HANDLE_VALUE) { + SP_DEVICE_INTERFACE_DATA devInterfaceData; + devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + for (int i = 0; SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVINTERFACE_HID, i, &devInterfaceData); i++) { - DWORD size = 0; - SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0); - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size) continue; - SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *) malloc(size); - if (!devInterfaceDetails) continue; + DWORD size = 0; + SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, 0, 0, &size, 0); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !size) + continue; + SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(size); + if (!devInterfaceDetails) + continue; - devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails); - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + devInterfaceDetails->cbSize = sizeof(*devInterfaceDetails); + SP_DEVINFO_DATA devInfoData; + devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData)) continue; + if (!SetupDiGetDeviceInterfaceDetail(hdev, &devInterfaceData, devInterfaceDetails, size, &size, &devInfoData)) + continue; - HANDLE hfile = CreateFile(devInterfaceDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); - if (hfile != INVALID_HANDLE_VALUE) { - HIDD_ATTRIBUTES attributes; - attributes.Size = sizeof(attributes); - if (HidD_GetAttributes(hfile, &attributes)) { - if (attributes.VendorID == vid && attributes.ProductID == pid) { - PHIDP_PREPARSED_DATA pData; - HIDP_CAPS caps; - if (HidD_GetPreparsedData(hfile, &pData)) { - if (HidP_GetCaps(pData, &caps) == HIDP_STATUS_SUCCESS) { - if (numFoundDevs % 32 == 0) { - *foundDevs = (HidDeviceInfo*) realloc(*foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs)); - } - HidDeviceInfo *dev = &foundDevs[0][numFoundDevs++]; - dev->caps = caps; - dev->vid = attributes.VendorID; - dev->pid = attributes.ProductID; - dev->path = wcsdup(devInterfaceDetails->DevicePath); - } - HidD_FreePreparsedData(pData); - } - } - } - CloseHandle(hfile); - } - free(devInterfaceDetails); - } - SetupDiDestroyDeviceInfoList(hdev); - } - return numFoundDevs; + HANDLE hfile = CreateFile(devInterfaceDetails->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); + if (hfile != INVALID_HANDLE_VALUE) { + HIDD_ATTRIBUTES attributes; + attributes.Size = sizeof(attributes); + if (HidD_GetAttributes(hfile, &attributes)) { + if (attributes.VendorID == vid && attributes.ProductID == pid) { + PHIDP_PREPARSED_DATA pData; + HIDP_CAPS caps; + if (HidD_GetPreparsedData(hfile, &pData)) { + if (HidP_GetCaps(pData, &caps) == HIDP_STATUS_SUCCESS) { + if (numFoundDevs % 32 == 0) { + *foundDevs = (HidDeviceInfo *)realloc(*foundDevs, sizeof(HidDeviceInfo) * (32 + numFoundDevs)); + } + HidDeviceInfo *dev = &foundDevs[0][numFoundDevs++]; + dev->caps = caps; + dev->vid = attributes.VendorID; + dev->pid = attributes.ProductID; + dev->path = wcsdup(devInterfaceDetails->DevicePath); + } + HidD_FreePreparsedData(pData); + } + } + } + CloseHandle(hfile); + } + free(devInterfaceDetails); + } + SetupDiDestroyDeviceInfoList(hdev); + } + return numFoundDevs; } diff --git a/plugins/LilyPad/HidDevice.h b/plugins/LilyPad/HidDevice.h index ad64d2afc3..107203d69e 100644 --- a/plugins/LilyPad/HidDevice.h +++ b/plugins/LilyPad/HidDevice.h @@ -20,11 +20,12 @@ #include -struct HidDeviceInfo { - HIDP_CAPS caps; - wchar_t *path; - unsigned short vid; - unsigned short pid; +struct HidDeviceInfo +{ + HIDP_CAPS caps; + wchar_t *path; + unsigned short vid; + unsigned short pid; }; int FindHids(HidDeviceInfo **foundDevs, int vid, int pid); diff --git a/plugins/LilyPad/InputManager.cpp b/plugins/LilyPad/InputManager.cpp index 2891f32c63..512336375f 100644 --- a/plugins/LilyPad/InputManager.cpp +++ b/plugins/LilyPad/InputManager.cpp @@ -21,604 +21,635 @@ InputDeviceManager *dm = 0; -InputDeviceManager::InputDeviceManager() { - memset(this, 0, sizeof(*this)); +InputDeviceManager::InputDeviceManager() +{ + memset(this, 0, sizeof(*this)); } -void InputDeviceManager::ClearDevices() { - for (int i=0; iapi = api; - type = d; - this->displayName = wcsdup(displayName); - if (instanceID) - this->instanceID = wcsdup(instanceID); - else - this->instanceID = wcsdup(displayName); - this->productID = 0; - if (productID) - this->productID = wcsdup(productID); - active = 0; - attached = 1; - enabled = 0; +Device::Device(DeviceAPI api, DeviceType d, const wchar_t *displayName, const wchar_t *instanceID, const wchar_t *productID) +{ + memset(pads, 0, sizeof(pads)); + this->api = api; + type = d; + this->displayName = wcsdup(displayName); + if (instanceID) + this->instanceID = wcsdup(instanceID); + else + this->instanceID = wcsdup(displayName); + this->productID = 0; + if (productID) + this->productID = wcsdup(productID); + active = 0; + attached = 1; + enabled = 0; #ifdef _MSC_VER - hWndProc = 0; + hWndProc = 0; #endif - virtualControls = 0; - numVirtualControls = 0; - virtualControlState = 0; - oldVirtualControlState = 0; + virtualControls = 0; + numVirtualControls = 0; + virtualControlState = 0; + oldVirtualControlState = 0; - physicalControls = 0; - numPhysicalControls = 0; - physicalControlState = 0; + physicalControls = 0; + numPhysicalControls = 0; + physicalControlState = 0; - ffEffectTypes = 0; - numFFEffectTypes = 0; - ffAxes = 0; - numFFAxes = 0; + ffEffectTypes = 0; + numFFEffectTypes = 0; + ffAxes = 0; + numFFAxes = 0; } -void Device::FreeState() { - if (virtualControlState) free(virtualControlState); - virtualControlState = 0; - oldVirtualControlState = 0; - physicalControlState = 0; +void Device::FreeState() +{ + if (virtualControlState) + free(virtualControlState); + virtualControlState = 0; + oldVirtualControlState = 0; + physicalControlState = 0; } -Device::~Device() { - Deactivate(); - // Generally called by deactivate, but just in case... - FreeState(); - int i; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - free(pads[port][slot].bindings); - for (i=0; i=0; i--) { - if (physicalControls[i].name) free(physicalControls[i].name); - } - free(physicalControls); + for (i = numPhysicalControls - 1; i >= 0; i--) { + if (physicalControls[i].name) + free(physicalControls[i].name); + } + free(physicalControls); - free(displayName); - free(instanceID); - free(productID); - if (ffAxes) { - for (i=0; iaxes = (AxisEffectInfo*) realloc(b->axes, sizeof(AxisEffectInfo) * (numFFAxes)); - memset(b->axes + (numFFAxes-1), 0, sizeof(AxisEffectInfo)); - bindingsExist = 1; - } - } - } - // Generally the case when not loading a binding file. - if (!bindingsExist) { - int i = numFFAxes-1; - ForceFeedbackAxis temp = ffAxes[i]; - while (i && temp.id < ffAxes[i-1].id) { - ffAxes[i] = ffAxes[i-1]; - i--; - } - ffAxes[i] = temp; - } +void Device::AddFFAxis(const wchar_t *displayName, int id) +{ + ffAxes = (ForceFeedbackAxis *)realloc(ffAxes, sizeof(ForceFeedbackAxis) * (numFFAxes + 1)); + ffAxes[numFFAxes].id = id; + ffAxes[numFFAxes].displayName = wcsdup(displayName); + numFFAxes++; + int bindingsExist = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + for (int i = 0; i < pads[port][slot].numFFBindings; i++) { + ForceFeedbackBinding *b = pads[port][slot].ffBindings + i; + b->axes = (AxisEffectInfo *)realloc(b->axes, sizeof(AxisEffectInfo) * (numFFAxes)); + memset(b->axes + (numFFAxes - 1), 0, sizeof(AxisEffectInfo)); + bindingsExist = 1; + } + } + } + // Generally the case when not loading a binding file. + if (!bindingsExist) { + int i = numFFAxes - 1; + ForceFeedbackAxis temp = ffAxes[i]; + while (i && temp.id < ffAxes[i - 1].id) { + ffAxes[i] = ffAxes[i - 1]; + i--; + } + ffAxes[i] = temp; + } } -void Device::AllocState() { - FreeState(); - virtualControlState = (int*) calloc(numVirtualControls + numVirtualControls + numPhysicalControls, sizeof(int)); - oldVirtualControlState = virtualControlState + numVirtualControls; - physicalControlState = oldVirtualControlState + numVirtualControls; +void Device::AllocState() +{ + FreeState(); + virtualControlState = (int *)calloc(numVirtualControls + numVirtualControls + numPhysicalControls, sizeof(int)); + oldVirtualControlState = virtualControlState + numVirtualControls; + physicalControlState = oldVirtualControlState + numVirtualControls; } -void Device::FlipState() { - memcpy(oldVirtualControlState, virtualControlState, sizeof(int)*numVirtualControls); +void Device::FlipState() +{ + memcpy(oldVirtualControlState, virtualControlState, sizeof(int) * numVirtualControls); } -void Device::PostRead() { - FlipState(); +void Device::PostRead() +{ + FlipState(); } -void Device::CalcVirtualState() { - for (int i=0; ibaseVirtualControlIndex; - int val = physicalControlState[i]; - if (c->type & BUTTON) { - virtualControlState[index] = val; - // DirectInput keyboard events only. - if (this->api == DI && this->type == KEYBOARD) { - if (!(virtualControlState[index]>>15) != !(oldVirtualControlState[index]>>15) && c->vkey) { - // Check for alt-F4 to avoid toggling skip mode incorrectly. - if (c->vkey == VK_F4) { - int i; - for (i=0; i>15)) event = KEYRELEASE; - QueueKeyEvent(c->vkey, event); - } - } - } - else if (c->type & ABSAXIS) { - virtualControlState[index] = (val + FULLY_DOWN)/2; - // Positive. Overkill. - virtualControlState[index+1] = (val & ~(val>>31)); - // Negative - virtualControlState[index+2] = (-val & (val>>31)); - } - else if (c->type & RELAXIS) { - int delta = val - oldVirtualControlState[index]; - virtualControlState[index] = val; - // Positive - virtualControlState[index+1] = (delta & ~(delta>>31)); - // Negative - virtualControlState[index+2] = (-delta & (delta>>31)); - } - else if (c->type & POV) { - virtualControlState[index] = val; - int iSouth = 0; - int iEast = 0; - if ((unsigned int)val <= 37000) { - double angle = val * (3.141592653589793/18000.0); - double East = sin(angle); - double South = -cos(angle); - // Normalize so greatest direction is 1. +void Device::CalcVirtualState() +{ + for (int i = 0; i < numPhysicalControls; i++) { + PhysicalControl *c = physicalControls + i; + int index = c->baseVirtualControlIndex; + int val = physicalControlState[i]; + if (c->type & BUTTON) { + virtualControlState[index] = val; + // DirectInput keyboard events only. + if (this->api == DI && this->type == KEYBOARD) { + if (!(virtualControlState[index] >> 15) != !(oldVirtualControlState[index] >> 15) && c->vkey) { + // Check for alt-F4 to avoid toggling skip mode incorrectly. + if (c->vkey == VK_F4) { + int i; + for (i = 0; i < numPhysicalControls; i++) { + if (virtualControlState[physicalControls[i].baseVirtualControlIndex] && + (physicalControls[i].vkey == VK_MENU || + physicalControls[i].vkey == VK_RMENU || + physicalControls[i].vkey == VK_LMENU)) { + break; + } + } + if (i < numPhysicalControls) + continue; + } + int event = KEYPRESS; + if (!(virtualControlState[index] >> 15)) + event = KEYRELEASE; + QueueKeyEvent(c->vkey, event); + } + } + } else if (c->type & ABSAXIS) { + virtualControlState[index] = (val + FULLY_DOWN) / 2; + // Positive. Overkill. + virtualControlState[index + 1] = (val & ~(val >> 31)); + // Negative + virtualControlState[index + 2] = (-val & (val >> 31)); + } else if (c->type & RELAXIS) { + int delta = val - oldVirtualControlState[index]; + virtualControlState[index] = val; + // Positive + virtualControlState[index + 1] = (delta & ~(delta >> 31)); + // Negative + virtualControlState[index + 2] = (-delta & (delta >> 31)); + } else if (c->type & POV) { + virtualControlState[index] = val; + int iSouth = 0; + int iEast = 0; + if ((unsigned int)val <= 37000) { + double angle = val * (3.141592653589793 / 18000.0); + double East = sin(angle); + double South = -cos(angle); +// Normalize so greatest direction is 1. #ifdef __linux__ - double mul = FULLY_DOWN / std::max(fabs(South), fabs(East)); + double mul = FULLY_DOWN / std::max(fabs(South), fabs(East)); #else - double mul = FULLY_DOWN / max(fabs(South), fabs(East)); + double mul = FULLY_DOWN / max(fabs(South), fabs(East)); #endif - iEast = (int) floor(East * mul + 0.5); - iSouth = (int) floor(South * mul + 0.5); - } - // N - virtualControlState[index+1] = (-iSouth & (iSouth>>31)); - // S - virtualControlState[index+3] = (iSouth & ~(iSouth>>31)); - // E - virtualControlState[index+2] = (iEast & ~(iEast>>31)); - // W - virtualControlState[index+4] = (-iEast & (iEast>>31)); - } - } + iEast = (int)floor(East * mul + 0.5); + iSouth = (int)floor(South * mul + 0.5); + } + // N + virtualControlState[index + 1] = (-iSouth & (iSouth >> 31)); + // S + virtualControlState[index + 3] = (iSouth & ~(iSouth >> 31)); + // E + virtualControlState[index + 2] = (iEast & ~(iEast >> 31)); + // W + virtualControlState[index + 4] = (-iEast & (iEast >> 31)); + } + } } -VirtualControl *Device::GetVirtualControl(unsigned int uid) { - for (int i=0; iuid = uid; - c->physicalControlIndex = physicalControlIndex; + c->uid = uid; + c->physicalControlIndex = physicalControlIndex; - numVirtualControls++; - return c; + numVirtualControls++; + return c; } -PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name) { - // Not really necessary, as always call AllocState when activated, but doesn't hurt. - FreeState(); +PhysicalControl *Device::AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name) +{ + // Not really necessary, as always call AllocState when activated, but doesn't hurt. + FreeState(); - if (numPhysicalControls % 16 == 0) { - physicalControls = (PhysicalControl*) realloc(physicalControls, sizeof(PhysicalControl)*(numPhysicalControls+16)); - } - PhysicalControl *control = physicalControls + numPhysicalControls; + if (numPhysicalControls % 16 == 0) { + physicalControls = (PhysicalControl *)realloc(physicalControls, sizeof(PhysicalControl) * (numPhysicalControls + 16)); + } + PhysicalControl *control = physicalControls + numPhysicalControls; - memset(control, 0, sizeof(PhysicalControl)); - control->type = type; - control->id = id; - if (name) control->name = wcsdup(name); - control->baseVirtualControlIndex = numVirtualControls; - unsigned int uid = id | (type<<16); - if (type & BUTTON) { - AddVirtualControl(uid, numPhysicalControls); - control->vkey = vkey; - } - else if (type & AXIS) { - AddVirtualControl(uid | UID_AXIS, numPhysicalControls); - AddVirtualControl(uid | UID_AXIS_POS, numPhysicalControls); - AddVirtualControl(uid | UID_AXIS_NEG, numPhysicalControls); - } - else if (type & POV) { - AddVirtualControl(uid | UID_POV, numPhysicalControls); - AddVirtualControl(uid | UID_POV_N, numPhysicalControls); - AddVirtualControl(uid | UID_POV_E, numPhysicalControls); - AddVirtualControl(uid | UID_POV_S, numPhysicalControls); - AddVirtualControl(uid | UID_POV_W, numPhysicalControls); - } - numPhysicalControls++; - return control; + memset(control, 0, sizeof(PhysicalControl)); + control->type = type; + control->id = id; + if (name) + control->name = wcsdup(name); + control->baseVirtualControlIndex = numVirtualControls; + unsigned int uid = id | (type << 16); + if (type & BUTTON) { + AddVirtualControl(uid, numPhysicalControls); + control->vkey = vkey; + } else if (type & AXIS) { + AddVirtualControl(uid | UID_AXIS, numPhysicalControls); + AddVirtualControl(uid | UID_AXIS_POS, numPhysicalControls); + AddVirtualControl(uid | UID_AXIS_NEG, numPhysicalControls); + } else if (type & POV) { + AddVirtualControl(uid | UID_POV, numPhysicalControls); + AddVirtualControl(uid | UID_POV_N, numPhysicalControls); + AddVirtualControl(uid | UID_POV_E, numPhysicalControls); + AddVirtualControl(uid | UID_POV_S, numPhysicalControls); + AddVirtualControl(uid | UID_POV_W, numPhysicalControls); + } + numPhysicalControls++; + return control; } -void Device::SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) { - for (int i=0; imotor == motor) { - SetEffect(binding, force); - } - } +void Device::SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) +{ + for (int i = 0; i < pads[port][slot].numFFBindings; i++) { + ForceFeedbackBinding *binding = pads[port][slot].ffBindings + i; + if (binding->motor == motor) { + SetEffect(binding, force); + } + } } -wchar_t *GetDefaultControlName(unsigned short id, int type) { - static wchar_t name[20]; - if (type & BUTTON) { - wsprintfW(name, L"Button %i", id); - } - else if (type & AXIS) { - wsprintfW(name, L"Axis %i", id); - } - else if (type & POV) { - wsprintfW(name, L"POV %i", id); - } - else { - wcscpy(name, L"Unknown"); - } - return name; +wchar_t *GetDefaultControlName(unsigned short id, int type) +{ + static wchar_t name[20]; + if (type & BUTTON) { + wsprintfW(name, L"Button %i", id); + } else if (type & AXIS) { + wsprintfW(name, L"Axis %i", id); + } else if (type & POV) { + wsprintfW(name, L"POV %i", id); + } else { + wcscpy(name, L"Unknown"); + } + return name; } -wchar_t *Device::GetVirtualControlName(VirtualControl *control) { - static wchar_t temp[100]; - wchar_t *baseName = 0; - if (control->physicalControlIndex >= 0) { - baseName = physicalControls[control->physicalControlIndex].name; - if (!baseName) baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]); - } - unsigned int uid = control->uid; - if (!baseName) { - baseName = GetDefaultControlName(uid & 0xFFFF, (uid >> 16)& 0x1F); - } - uid &= 0xFF000000; - int len = (int)wcslen(baseName); - if (len > 99) len = 99; - memcpy(temp, baseName, len*sizeof(wchar_t)); - temp[len] = 0; - if (uid) { - if (len > 95) len = 95; - wchar_t *out = temp+len; - if (uid == UID_AXIS_POS) { - wcscpy(out, L" +"); - } - else if (uid == UID_AXIS_NEG) { - wcscpy(out, L" -"); - } - else if (uid == UID_POV_N) { - wcscpy(out, L" N"); - } - else if (uid == UID_POV_E) { - wcscpy(out, L" E"); - } - else if (uid == UID_POV_S) { - wcscpy(out, L" S"); - } - else if (uid == UID_POV_W) { - wcscpy(out, L" W"); - } - } - return temp; +wchar_t *Device::GetVirtualControlName(VirtualControl *control) +{ + static wchar_t temp[100]; + wchar_t *baseName = 0; + if (control->physicalControlIndex >= 0) { + baseName = physicalControls[control->physicalControlIndex].name; + if (!baseName) + baseName = GetPhysicalControlName(&physicalControls[control->physicalControlIndex]); + } + unsigned int uid = control->uid; + if (!baseName) { + baseName = GetDefaultControlName(uid & 0xFFFF, (uid >> 16) & 0x1F); + } + uid &= 0xFF000000; + int len = (int)wcslen(baseName); + if (len > 99) + len = 99; + memcpy(temp, baseName, len * sizeof(wchar_t)); + temp[len] = 0; + if (uid) { + if (len > 95) + len = 95; + wchar_t *out = temp + len; + if (uid == UID_AXIS_POS) { + wcscpy(out, L" +"); + } else if (uid == UID_AXIS_NEG) { + wcscpy(out, L" -"); + } else if (uid == UID_POV_N) { + wcscpy(out, L" N"); + } else if (uid == UID_POV_E) { + wcscpy(out, L" E"); + } else if (uid == UID_POV_S) { + wcscpy(out, L" S"); + } else if (uid == UID_POV_W) { + wcscpy(out, L" W"); + } + } + return temp; } -wchar_t *Device::GetPhysicalControlName(PhysicalControl *control) { - if (control->name) return control->name; - return GetDefaultControlName(control->id, control->type); +wchar_t *Device::GetPhysicalControlName(PhysicalControl *control) +{ + if (control->name) + return control->name; + return GetDefaultControlName(control->id, control->type); } -void InputDeviceManager::AddDevice(Device *d) { - devices = (Device**) realloc(devices, sizeof(Device*) * (numDevices+1)); - devices[numDevices++] = d; +void InputDeviceManager::AddDevice(Device *d) +{ + devices = (Device **)realloc(devices, sizeof(Device *) * (numDevices + 1)); + devices[numDevices++] = d; } -void InputDeviceManager::Update(InitInfo *info) { - for (int i=0; ienabled) { - if (!devices[i]->active) { - if (!devices[i]->Activate(info) || !devices[i]->Update()) continue; - devices[i]->CalcVirtualState(); - devices[i]->PostRead(); - } - if (devices[i]->Update()) - devices[i]->CalcVirtualState(); - } - } +void InputDeviceManager::Update(InitInfo *info) +{ + for (int i = 0; i < numDevices; i++) { + if (devices[i]->enabled) { + if (!devices[i]->active) { + if (!devices[i]->Activate(info) || !devices[i]->Update()) + continue; + devices[i]->CalcVirtualState(); + devices[i]->PostRead(); + } + if (devices[i]->Update()) + devices[i]->CalcVirtualState(); + } + } } -void InputDeviceManager::PostRead() { - for (int i=0; iactive) - devices[i]->PostRead(); - } +void InputDeviceManager::PostRead() +{ + for (int i = 0; i < numDevices; i++) { + if (devices[i]->active) + devices[i]->PostRead(); + } } -Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value) { - int i, j; - Update(info); - int bestDiff = FULLY_DOWN/2; - Device *bestDevice = 0; - for (i=0; iactive) { - for (j=0; jnumVirtualControls; j++) { - if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j]) continue; - if (devices[i]->virtualControls[j].uid & UID_POV) continue; - // Fix for releasing button used to click on bind button - if (!((devices[i]->virtualControls[j].uid>>16) & (POV|RELAXIS|ABSAXIS))) { - if (abs(devices[i]->oldVirtualControlState[j]) > abs(devices[i]->virtualControlState[j])) { - devices[i]->oldVirtualControlState[j] = 0; - } - } - int diff = abs(devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]); - // Make it require a bit more work to bind relative axes. - if (((devices[i]->virtualControls[j].uid>>16) & 0xFF) == RELAXIS) { - diff = diff/4+1; - } - // Less pressure needed to bind DS3/SCP buttons. - if ((devices[i]->api == DS3 || devices[i]->api == XINPUT) && (((devices[i]->virtualControls[j].uid>>16) & 0xFF) & BUTTON)) { - diff *= 4; - } - if (diff > bestDiff) { - if (devices[i]->virtualControls[j].uid & UID_AXIS) { - if ((((devices[i]->virtualControls[j].uid>>16)&0xFF) != ABSAXIS)) continue; - // Very picky when binding entire axes. Prefer binding half-axes. - if (!((devices[i]->oldVirtualControlState[j] < FULLY_DOWN/32 && devices[i]->virtualControlState[j] > FULLY_DOWN/8) || - (devices[i]->oldVirtualControlState[j] > 31*FULLY_DOWN/32 && devices[i]->virtualControlState[j] < 7*FULLY_DOWN/8))) { - continue; - } - } - else if ((((devices[i]->virtualControls[j].uid>>16)&0xFF) == ABSAXIS)) { - if (devices[i]->oldVirtualControlState[j] > 15*FULLY_DOWN/16) - continue; - } - bestDiff = diff; - *uid = devices[i]->virtualControls[j].uid; - *index = j; - bestDevice = devices[i]; - if (value) { - if ((devices[i]->virtualControls[j].uid>>16)& RELAXIS) { - *value = devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]; - } - else { - *value = devices[i]->virtualControlState[j]; - } - } - } - } - } - } - // Don't call when binding. - // PostRead(); - return bestDevice; +Device *InputDeviceManager::GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value) +{ + int i, j; + Update(info); + int bestDiff = FULLY_DOWN / 2; + Device *bestDevice = 0; + for (i = 0; i < numDevices; i++) { + if (devices[i]->active) { + for (j = 0; j < devices[i]->numVirtualControls; j++) { + if (devices[i]->virtualControlState[j] == devices[i]->oldVirtualControlState[j]) + continue; + if (devices[i]->virtualControls[j].uid & UID_POV) + continue; + // Fix for releasing button used to click on bind button + if (!((devices[i]->virtualControls[j].uid >> 16) & (POV | RELAXIS | ABSAXIS))) { + if (abs(devices[i]->oldVirtualControlState[j]) > abs(devices[i]->virtualControlState[j])) { + devices[i]->oldVirtualControlState[j] = 0; + } + } + int diff = abs(devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]); + // Make it require a bit more work to bind relative axes. + if (((devices[i]->virtualControls[j].uid >> 16) & 0xFF) == RELAXIS) { + diff = diff / 4 + 1; + } + // Less pressure needed to bind DS3/SCP buttons. + if ((devices[i]->api == DS3 || devices[i]->api == XINPUT) && (((devices[i]->virtualControls[j].uid >> 16) & 0xFF) & BUTTON)) { + diff *= 4; + } + if (diff > bestDiff) { + if (devices[i]->virtualControls[j].uid & UID_AXIS) { + if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) != ABSAXIS)) + continue; + // Very picky when binding entire axes. Prefer binding half-axes. + if (!((devices[i]->oldVirtualControlState[j] < FULLY_DOWN / 32 && devices[i]->virtualControlState[j] > FULLY_DOWN / 8) || + (devices[i]->oldVirtualControlState[j] > 31 * FULLY_DOWN / 32 && devices[i]->virtualControlState[j] < 7 * FULLY_DOWN / 8))) { + continue; + } + } else if ((((devices[i]->virtualControls[j].uid >> 16) & 0xFF) == ABSAXIS)) { + if (devices[i]->oldVirtualControlState[j] > 15 * FULLY_DOWN / 16) + continue; + } + bestDiff = diff; + *uid = devices[i]->virtualControls[j].uid; + *index = j; + bestDevice = devices[i]; + if (value) { + if ((devices[i]->virtualControls[j].uid >> 16) & RELAXIS) { + *value = devices[i]->virtualControlState[j] - devices[i]->oldVirtualControlState[j]; + } else { + *value = devices[i]->virtualControlState[j]; + } + } + } + } + } + } + // Don't call when binding. + // PostRead(); + return bestDevice; } -void InputDeviceManager::ReleaseInput() { - for (int i=0; iactive) devices[i]->Deactivate(); - } +void InputDeviceManager::ReleaseInput() +{ + for (int i = 0; i < numDevices; i++) { + if (devices[i]->active) + devices[i]->Deactivate(); + } } -void InputDeviceManager::EnableDevices(DeviceType type, DeviceAPI api) { - for (int i=0; iapi == api && devices[i]->type == type) { - EnableDevice(i); - } - } +void InputDeviceManager::EnableDevices(DeviceType type, DeviceAPI api) +{ + for (int i = 0; i < numDevices; i++) { + if (devices[i]->api == api && devices[i]->type == type) { + EnableDevice(i); + } + } } -void InputDeviceManager::DisableAllDevices() { - for (int i=0; ienabled = 0; - if (devices[index]->active) { - devices[index]->Deactivate(); - } +void InputDeviceManager::DisableDevice(int index) +{ + devices[index]->enabled = 0; + if (devices[index]->active) { + devices[index]->Deactivate(); + } } -ForceFeedbackEffectType *Device::GetForcefeedbackEffect(wchar_t *id) { - for (int i=0; ipads[port][slot].numBindings + old->pads[port][slot].numFFBindings) { - // Means that there are bindings. - oldMatches[i] = -1; - } - } - } - } - // Loops through ids looking for match, from most specific to most general. - for (int id=0; id<3; id++) { - for (i=0; i= 0) continue; - for (j=0; j= 0) { - continue; - } - wchar_t *id1 = devices[j]->IDs[id]; - wchar_t *id2 = oldDevices[i]->IDs[id]; - if (!id1 || !id2) { - continue; - } - if (!wcsicmp(id1, id2)) { - matches[j] = i; - oldMatches[i] = j; - break; - } - } - } - } +void InputDeviceManager::CopyBindings(int numOldDevices, Device **oldDevices) +{ + int *oldMatches = (int *)malloc(sizeof(int) * numOldDevices); + int *matches = (int *)malloc(sizeof(int) * numDevices); + int i, j, port, slot; + Device *old, *dev; + for (i = 0; i < numDevices; i++) { + matches[i] = -1; + } + for (i = 0; i < numOldDevices; i++) { + oldMatches[i] = -2; + old = oldDevices[i]; + for (port = 0; port < 2; port++) { + for (slot = 0; slot < 4; slot++) { + if (old->pads[port][slot].numBindings + old->pads[port][slot].numFFBindings) { + // Means that there are bindings. + oldMatches[i] = -1; + } + } + } + } + // Loops through ids looking for match, from most specific to most general. + for (int id = 0; id < 3; id++) { + for (i = 0; i < numOldDevices; i++) { + if (oldMatches[i] >= 0) + continue; + for (j = 0; j < numDevices; j++) { + if (matches[j] >= 0) { + continue; + } + wchar_t *id1 = devices[j]->IDs[id]; + wchar_t *id2 = oldDevices[i]->IDs[id]; + if (!id1 || !id2) { + continue; + } + if (!wcsicmp(id1, id2)) { + matches[j] = i; + oldMatches[i] = j; + break; + } + } + } + } - for (i=0; iapi, old->type, old->displayName, old->instanceID, old->productID); - dev->attached = 0; - AddDevice(dev); - for (j=0; jnumVirtualControls; j++) { - VirtualControl *c = old->virtualControls+j; - dev->AddVirtualControl(c->uid, -1); - } - for (j=0; jnumFFEffectTypes; j++) { - ForceFeedbackEffectType * effect = old->ffEffectTypes + j; - dev->AddFFEffectType(effect->displayName, effect->effectID, effect->type); - } - for (j=0; jnumFFAxes; j++) { - ForceFeedbackAxis * axis = old->ffAxes + j; - dev->AddFFAxis(axis->displayName, axis->id); - } - // Just steal the old bindings directly when there's no matching device. - // Indices will be the same. - memcpy(dev->pads, old->pads, sizeof(old->pads)); - memset(old->pads, 0, sizeof(old->pads)); - } - else { - dev = devices[oldMatches[i]]; - for (port=0; port<2; port++) { - for (slot=0; slot<4; slot++) { - if (old->pads[port][slot].numBindings) { - dev->pads[port][slot].bindings = (Binding*) malloc(old->pads[port][slot].numBindings * sizeof(Binding)); - for (int j=0; jpads[port][slot].numBindings; j++) { - Binding *bo = old->pads[port][slot].bindings + j; - Binding *bn = dev->pads[port][slot].bindings + dev->pads[port][slot].numBindings; - VirtualControl *cn = dev->GetVirtualControl(old->virtualControls[bo->controlIndex].uid); - if (cn) { - *bn = *bo; - bn->controlIndex = cn - dev->virtualControls; - dev->pads[port][slot].numBindings++; - } - } - } - if (old->pads[port][slot].numFFBindings) { - dev->pads[port][slot].ffBindings = (ForceFeedbackBinding*) malloc(old->pads[port][slot].numFFBindings * sizeof(ForceFeedbackBinding)); - for (int j=0; jpads[port][slot].numFFBindings; j++) { - ForceFeedbackBinding *bo = old->pads[port][slot].ffBindings + j; - ForceFeedbackBinding *bn = dev->pads[port][slot].ffBindings + dev->pads[port][slot].numFFBindings; - ForceFeedbackEffectType *en = dev->GetForcefeedbackEffect(old->ffEffectTypes[bo->effectIndex].effectID); - if (en) { - *bn = *bo; - bn->effectIndex = en - dev->ffEffectTypes; - bn->axes = (AxisEffectInfo*)calloc(dev->numFFAxes, sizeof(AxisEffectInfo)); - for (int k=0; knumFFAxes; k++) { - ForceFeedbackAxis *newAxis = dev->GetForceFeedbackAxis(old->ffAxes[k].id); - if (newAxis) { - bn->axes[newAxis - dev->ffAxes] = bo->axes[k]; - } - } - dev->pads[port][slot].numFFBindings++; - } - } - } - } - } - } - } - free(oldMatches); - free(matches); + for (i = 0; i < numOldDevices; i++) { + if (oldMatches[i] == -2) + continue; + old = oldDevices[i]; + if (oldMatches[i] < 0) { + dev = new Device(old->api, old->type, old->displayName, old->instanceID, old->productID); + dev->attached = 0; + AddDevice(dev); + for (j = 0; j < old->numVirtualControls; j++) { + VirtualControl *c = old->virtualControls + j; + dev->AddVirtualControl(c->uid, -1); + } + for (j = 0; j < old->numFFEffectTypes; j++) { + ForceFeedbackEffectType *effect = old->ffEffectTypes + j; + dev->AddFFEffectType(effect->displayName, effect->effectID, effect->type); + } + for (j = 0; j < old->numFFAxes; j++) { + ForceFeedbackAxis *axis = old->ffAxes + j; + dev->AddFFAxis(axis->displayName, axis->id); + } + // Just steal the old bindings directly when there's no matching device. + // Indices will be the same. + memcpy(dev->pads, old->pads, sizeof(old->pads)); + memset(old->pads, 0, sizeof(old->pads)); + } else { + dev = devices[oldMatches[i]]; + for (port = 0; port < 2; port++) { + for (slot = 0; slot < 4; slot++) { + if (old->pads[port][slot].numBindings) { + dev->pads[port][slot].bindings = (Binding *)malloc(old->pads[port][slot].numBindings * sizeof(Binding)); + for (int j = 0; j < old->pads[port][slot].numBindings; j++) { + Binding *bo = old->pads[port][slot].bindings + j; + Binding *bn = dev->pads[port][slot].bindings + dev->pads[port][slot].numBindings; + VirtualControl *cn = dev->GetVirtualControl(old->virtualControls[bo->controlIndex].uid); + if (cn) { + *bn = *bo; + bn->controlIndex = cn - dev->virtualControls; + dev->pads[port][slot].numBindings++; + } + } + } + if (old->pads[port][slot].numFFBindings) { + dev->pads[port][slot].ffBindings = (ForceFeedbackBinding *)malloc(old->pads[port][slot].numFFBindings * sizeof(ForceFeedbackBinding)); + for (int j = 0; j < old->pads[port][slot].numFFBindings; j++) { + ForceFeedbackBinding *bo = old->pads[port][slot].ffBindings + j; + ForceFeedbackBinding *bn = dev->pads[port][slot].ffBindings + dev->pads[port][slot].numFFBindings; + ForceFeedbackEffectType *en = dev->GetForcefeedbackEffect(old->ffEffectTypes[bo->effectIndex].effectID); + if (en) { + *bn = *bo; + bn->effectIndex = en - dev->ffEffectTypes; + bn->axes = (AxisEffectInfo *)calloc(dev->numFFAxes, sizeof(AxisEffectInfo)); + for (int k = 0; k < old->numFFAxes; k++) { + ForceFeedbackAxis *newAxis = dev->GetForceFeedbackAxis(old->ffAxes[k].id); + if (newAxis) { + bn->axes[newAxis - dev->ffAxes] = bo->axes[k]; + } + } + dev->pads[port][slot].numFFBindings++; + } + } + } + } + } + } + } + free(oldMatches); + free(matches); } -void InputDeviceManager::SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) { - for (int i=0; ienabled && dev->numFFEffectTypes) { - dev->SetEffects(port, slot, motor, force); - } - } +void InputDeviceManager::SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) +{ + for (int i = 0; i < numDevices; i++) { + Device *dev = devices[i]; + if (dev->enabled && dev->numFFEffectTypes) { + dev->SetEffects(port, slot, motor, force); + } + } } - diff --git a/plugins/LilyPad/InputManager.h b/plugins/LilyPad/InputManager.h index 673c8203e8..18db5c90e6 100644 --- a/plugins/LilyPad/InputManager.h +++ b/plugins/LilyPad/InputManager.h @@ -23,10 +23,10 @@ // Fully down means that value corresponds to a button being fully down (255). // a value of 128 or more corresponds to that button being pressed, for binary // values. -#define BASE_SENSITIVITY (1<<16) -#define FULLY_DOWN (1<<16) +#define BASE_SENSITIVITY (1 << 16) +#define FULLY_DOWN (1 << 16) -#define DEFAULT_DEADZONE (BASE_SENSITIVITY * 201/1000) +#define DEFAULT_DEADZONE (BASE_SENSITIVITY * 201 / 1000) /* Idea is for this file and the associated cpp file to be Windows independent. * Still more effort than it's worth to port to Linux, however. @@ -36,28 +36,28 @@ // One physical axis maps to 3 virtual ones, and one physical POV control maps to // 4 virtual ones. enum ControlType { - NO_CONTROL = 0, - // Axes are ints. Relative axes are for mice, mice wheels, etc, - // and are always reported relative to their last value. - // Absolute axes range from -65536 to 65536 and are absolute positions, - // like for joysticks and pressure sensitive buttons. - RELAXIS = 1, - ABSAXIS = 2, + NO_CONTROL = 0, + // Axes are ints. Relative axes are for mice, mice wheels, etc, + // and are always reported relative to their last value. + // Absolute axes range from -65536 to 65536 and are absolute positions, + // like for joysticks and pressure sensitive buttons. + RELAXIS = 1, + ABSAXIS = 2, - // Buttons range from 0 to 65536. - PSHBTN = 4, - TGLBTN = 8, + // Buttons range from 0 to 65536. + PSHBTN = 4, + TGLBTN = 8, - // POV controls are ints, values range from -1 to 36000. - // -1 means not pressed, otherwise it's an angle. - // For easy DirectInput compatibility, anything outside. - // that range is treated as -1 (Though 36000-37000 is treated - // like 0 to 1000, just in case). - POV = 16, + // POV controls are ints, values range from -1 to 36000. + // -1 means not pressed, otherwise it's an angle. + // For easy DirectInput compatibility, anything outside. + // that range is treated as -1 (Though 36000-37000 is treated + // like 0 to 1000, just in case). + POV = 16, - // Pressure sensitive buttons. Only a different type because - // they have configurable dead zones, unlike push or toggle buttons. - PRESSURE_BTN = 32, + // Pressure sensitive buttons. Only a different type because + // they have configurable dead zones, unlike push or toggle buttons. + PRESSURE_BTN = 32, }; // Masks to determine button type. Don't need one for POV. @@ -65,37 +65,39 @@ enum ControlType { #define BINARY_BUTTON (PSHBTN | TGLBTN) #define AXIS 3 -struct Binding { - int controlIndex; - int command; - int sensitivity; - int deadZone; - unsigned char turbo; +struct Binding +{ + int controlIndex; + int command; + int sensitivity; + int deadZone; + unsigned char turbo; }; -#define UID_AXIS (1U<<31) -#define UID_POV (1<<30) +#define UID_AXIS (1U << 31) +#define UID_POV (1 << 30) -#define UID_AXIS_POS (1U<<24) -#define UID_AXIS_NEG (2U<<24) -#define UID_POV_N (3<<24) -#define UID_POV_E (4<<24) -#define UID_POV_S (5<<24) -#define UID_POV_W (6<<24) +#define UID_AXIS_POS (1U << 24) +#define UID_AXIS_NEG (2U << 24) +#define UID_POV_N (3 << 24) +#define UID_POV_E (4 << 24) +#define UID_POV_S (5 << 24) +#define UID_POV_W (6 << 24) // One of these exists for each bindable object. // Bindable objects consist of buttons, axis, pov controls, // and individual axis/pov directions. Not that pov controls // cannot actually be bound, but when trying to bind as an axis, // all directions are assigned individually. -struct VirtualControl { - // Unique id for control, given device. Based on source control's id, - // source control type, axis/pov flags if it's a pov/axis (Rather than - // a button or a pov/axis control's individual button), and an index, - // if the control is split. - unsigned int uid; - // virtual key code. 0 if none. - int physicalControlIndex; +struct VirtualControl +{ + // Unique id for control, given device. Based on source control's id, + // source control type, axis/pov flags if it's a pov/axis (Rather than + // a button or a pov/axis control's individual button), and an index, + // if the control is split. + unsigned int uid; + // virtual key code. 0 if none. + int physicalControlIndex; }; // Need one for each button, axis, and pov control. @@ -103,79 +105,84 @@ struct VirtualControl { // updates their state, standard function then populates // the VirtualControls and queues the keyboard messages, if // needed. -struct PhysicalControl { - // index of the first virtual control corresponding to this. - // Buttons have 1 virtual control, axes 3, and povs 5, all - // in a row. - int baseVirtualControlIndex; - ControlType type; - // id. Must be unique for control type. - // short so can be combined with other values to get - // uid for virtual controls. - unsigned short id; - unsigned short vkey; - wchar_t *name; +struct PhysicalControl +{ + // index of the first virtual control corresponding to this. + // Buttons have 1 virtual control, axes 3, and povs 5, all + // in a row. + int baseVirtualControlIndex; + ControlType type; + // id. Must be unique for control type. + // short so can be combined with other values to get + // uid for virtual controls. + unsigned short id; + unsigned short vkey; + wchar_t *name; }; enum DeviceAPI { - NO_API = 0, - DI = 1, - WM = 2, - RAW = 3, - XINPUT = 4, - DS3 = 5, - // Not currently used. - LLHOOK = 6, - // Not a real API, obviously. Only used with keyboards, - // to ignore individual buttons. Wrapper itself takes care - // of ignoring bound keys. Otherwise, works normally. - IGNORE_KEYBOARD = 7, - // XXX - LNX_KEYBOARD = 16, - LNX_JOY = 17, + NO_API = 0, + DI = 1, + WM = 2, + RAW = 3, + XINPUT = 4, + DS3 = 5, + // Not currently used. + LLHOOK = 6, + // Not a real API, obviously. Only used with keyboards, + // to ignore individual buttons. Wrapper itself takes care + // of ignoring bound keys. Otherwise, works normally. + IGNORE_KEYBOARD = 7, + // XXX + LNX_KEYBOARD = 16, + LNX_JOY = 17, }; enum DeviceType { - NO_DEVICE = 0, - KEYBOARD = 1, - MOUSE = 2, - OTHER = 3 + NO_DEVICE = 0, + KEYBOARD = 1, + MOUSE = 2, + OTHER = 3 }; enum EffectType { - EFFECT_CONSTANT, - EFFECT_PERIODIC, - EFFECT_RAMP + EFFECT_CONSTANT, + EFFECT_PERIODIC, + EFFECT_RAMP }; // force range sfrom -BASE_SENSITIVITY to BASE_SENSITIVITY. // Order matches ForceFeedbackAxis order. force of 0 means to // ignore that axis completely. Force of 1 or -1 means to initialize // the axis with minimum force (Possibly 0 force), if applicable. -struct AxisEffectInfo { - int force; +struct AxisEffectInfo +{ + int force; }; -struct ForceFeedbackBinding { - AxisEffectInfo *axes; - int effectIndex; - unsigned char motor; +struct ForceFeedbackBinding +{ + AxisEffectInfo *axes; + int effectIndex; + unsigned char motor; }; // Bindings listed by effect, so I don't have to bother with // indexing effects. -struct ForceFeedbackEffectType { - wchar_t *displayName; - // Because I'm lazy, can only have ASCII characters and no spaces. - wchar_t *effectID; - // constant, ramp, or periodic - EffectType type; +struct ForceFeedbackEffectType +{ + wchar_t *displayName; + // Because I'm lazy, can only have ASCII characters and no spaces. + wchar_t *effectID; + // constant, ramp, or periodic + EffectType type; }; -struct ForceFeedbackAxis { - wchar_t *displayName; - int id; +struct ForceFeedbackAxis +{ + wchar_t *displayName; + int id; }; // Used both for active devices and for sets of settings for devices. @@ -184,190 +191,200 @@ struct ForceFeedbackAxis { // one set of generic devices. Then I enumerate all devices. Then I merge // them, moving settings from the generic devices to the enumerated ones. -struct PadBindings { - Binding *bindings; - int numBindings; - ForceFeedbackBinding *ffBindings; - int numFFBindings; +struct PadBindings +{ + Binding *bindings; + int numBindings; + ForceFeedbackBinding *ffBindings; + int numFFBindings; }; class WndProcEater; -struct InitInfo { - // 1 when binding key to ignore. - int bindingIgnore; - // 1 when binding. - int binding; +struct InitInfo +{ + // 1 when binding key to ignore. + int bindingIgnore; + // 1 when binding. + int binding; #ifdef _MSC_VER - HWND hWndTop; + HWND hWndTop; - // For config screen, need to eat button's message handling. - //HWND hWndButton; + // For config screen, need to eat button's message handling. + //HWND hWndButton; - WndProcEater* hWndProc; + WndProcEater *hWndProc; #else - // Linux equivalent to HWND - Display *GSdsp; - Window GSwin; + // Linux equivalent to HWND + Display *GSdsp; + Window GSwin; #endif }; // Mostly self-contained, but bindings are modified by config.cpp, to make // updating the ListView simpler. -class Device { +class Device +{ public: - DeviceAPI api; - DeviceType type; - char active; - char attached; - // Based on input modes. - char enabled; + DeviceAPI api; + DeviceType type; + char active; + char attached; + // Based on input modes. + char enabled; #ifdef _MSC_VER - // Not all devices need to subclass the windproc, but most do so might as well - // put it here... --air - WndProcEater* hWndProc; + // Not all devices need to subclass the windproc, but most do so might as well + // put it here... --air + WndProcEater *hWndProc; #endif - union { - // Allows for one loop to compare all 3 in order. - wchar_t *IDs[3]; - struct { - // Same as DisplayName, when not given. Absolutely must be unique. - // Used for loading/saving controls. If matches, all other strings - // are ignored, so must be unique. - wchar_t *instanceID; - // Not required. Used when a device's instance id changes, doesn't have to - // be unique. For devices that can only have one instance, not needed. - wchar_t *productID; + union + { + // Allows for one loop to compare all 3 in order. + wchar_t *IDs[3]; + struct + { + // Same as DisplayName, when not given. Absolutely must be unique. + // Used for loading/saving controls. If matches, all other strings + // are ignored, so must be unique. + wchar_t *instanceID; + // Not required. Used when a device's instance id changes, doesn't have to + // be unique. For devices that can only have one instance, not needed. + wchar_t *productID; - wchar_t *displayName; - }; - }; + wchar_t *displayName; + }; + }; - PadBindings pads[2][4]; + PadBindings pads[2][4]; - // Virtual controls. All basically act like pressure sensitivity buttons, with - // values between 0 and 2^16. 2^16 is fully down, 0 is up. Larger values - // are allowed, but *only* for absolute axes (Which don't support the flip checkbox). - // Each control on a device must have a unique id, used for binding. - VirtualControl *virtualControls; - int numVirtualControls; + // Virtual controls. All basically act like pressure sensitivity buttons, with + // values between 0 and 2^16. 2^16 is fully down, 0 is up. Larger values + // are allowed, but *only* for absolute axes (Which don't support the flip checkbox). + // Each control on a device must have a unique id, used for binding. + VirtualControl *virtualControls; + int numVirtualControls; - int *virtualControlState; - int *oldVirtualControlState; + int *virtualControlState; + int *oldVirtualControlState; - PhysicalControl *physicalControls; - int numPhysicalControls; - int *physicalControlState; + PhysicalControl *physicalControls; + int numPhysicalControls; + int *physicalControlState; - ForceFeedbackEffectType *ffEffectTypes; - int numFFEffectTypes; - ForceFeedbackAxis *ffAxes; - int numFFAxes; - void AddFFAxis(const wchar_t *displayName, int id); - void AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type); + ForceFeedbackEffectType *ffEffectTypes; + int numFFEffectTypes; + ForceFeedbackAxis *ffAxes; + int numFFAxes; + void AddFFAxis(const wchar_t *displayName, int id); + void AddFFEffectType(const wchar_t *displayName, const wchar_t *effectID, EffectType type); - Device(DeviceAPI, DeviceType, const wchar_t *displayName, const wchar_t *instanceID = 0, const wchar_t *deviceID = 0); - virtual ~Device(); + Device(DeviceAPI, DeviceType, const wchar_t *displayName, const wchar_t *instanceID = 0, const wchar_t *deviceID = 0); + virtual ~Device(); - // Allocates memory for old and new state, sets everything to 0. - // all old states are in one array, buttons, axes, and then POVs. - // start of each section is int aligned. This makes it DirectInput - // compatible. - void AllocState(); + // Allocates memory for old and new state, sets everything to 0. + // all old states are in one array, buttons, axes, and then POVs. + // start of each section is int aligned. This makes it DirectInput + // compatible. + void AllocState(); - // Doesn't actually flip. Copies current state to old state. - void FlipState(); + // Doesn't actually flip. Copies current state to old state. + void FlipState(); - // Frees state variables. - void FreeState(); + // Frees state variables. + void FreeState(); - ForceFeedbackEffectType *GetForcefeedbackEffect(wchar_t *id); - ForceFeedbackAxis *GetForceFeedbackAxis(int id); + ForceFeedbackEffectType *GetForcefeedbackEffect(wchar_t *id); + ForceFeedbackAxis *GetForceFeedbackAxis(int id); - VirtualControl *GetVirtualControl(unsigned int uid); + VirtualControl *GetVirtualControl(unsigned int uid); - PhysicalControl *AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name = 0); - VirtualControl *AddVirtualControl(unsigned int uid, int physicalControlIndex); + PhysicalControl *AddPhysicalControl(ControlType type, unsigned short id, unsigned short vkey, const wchar_t *name = 0); + VirtualControl *AddVirtualControl(unsigned int uid, int physicalControlIndex); - virtual wchar_t *GetVirtualControlName(VirtualControl *c); - virtual wchar_t *GetPhysicalControlName(PhysicalControl *c); + virtual wchar_t *GetVirtualControlName(VirtualControl *c); + virtual wchar_t *GetPhysicalControlName(PhysicalControl *c); - void CalcVirtualState(); + void CalcVirtualState(); - virtual int Activate(InitInfo *args) { - return 0; - } + virtual int Activate(InitInfo *args) + { + return 0; + } - inline virtual void Deactivate() { - FreeState(); - active = 0; - } + inline virtual void Deactivate() + { + FreeState(); + active = 0; + } - // Default update proc. All that's needed for post-based APIs. - inline virtual int Update() { - return active; - } + // Default update proc. All that's needed for post-based APIs. + inline virtual int Update() + { + return active; + } - // force is from -FULLY_DOWN to FULLY_DOWN. - // Either function can be overridden. Second one by default calls the first - // for every bound effect that's affected. + // force is from -FULLY_DOWN to FULLY_DOWN. + // Either function can be overridden. Second one by default calls the first + // for every bound effect that's affected. - // Note: Only used externally for binding, so if override the other one, can assume - // all other forces are currently 0. - inline virtual void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {} - virtual void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force); + // Note: Only used externally for binding, so if override the other one, can assume + // all other forces are currently 0. + inline virtual void SetEffect(ForceFeedbackBinding *binding, unsigned char force) {} + virtual void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force); - // Called after reading. Basically calls FlipState(). - // Some device types (Those that don't incrementally update) - // could call FlipState elsewhere, but this makes it simpler to ignore - // while binding. - virtual void PostRead(); + // Called after reading. Basically calls FlipState(). + // Some device types (Those that don't incrementally update) + // could call FlipState elsewhere, but this makes it simpler to ignore + // while binding. + virtual void PostRead(); }; -class InputDeviceManager { +class InputDeviceManager +{ public: - Device **devices; - int numDevices; + Device **devices; + int numDevices; - void ClearDevices(); + void ClearDevices(); - // When refreshing devices, back up old devices, then - // populate this with new devices, then call copy bindings. - // All old bindings are copied to matching devices. + // When refreshing devices, back up old devices, then + // populate this with new devices, then call copy bindings. + // All old bindings are copied to matching devices. - // When old devices are missing, I do a slightly more careful search - // using productIDs and then (in desperation) displayName. - // Finally create new dummy devices if no matches found. - void CopyBindings(int numDevices, Device **devices); + // When old devices are missing, I do a slightly more careful search + // using productIDs and then (in desperation) displayName. + // Finally create new dummy devices if no matches found. + void CopyBindings(int numDevices, Device **devices); - InputDeviceManager(); - ~InputDeviceManager(); + InputDeviceManager(); + ~InputDeviceManager(); - void AddDevice(Device *d); - Device *GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value); - void Update(InitInfo *initInfo); + void AddDevice(Device *d); + Device *GetActiveDevice(InitInfo *info, unsigned int *uid, int *index, int *value); + void Update(InitInfo *initInfo); - // Called after reading state, after Update(). - void PostRead(); + // Called after reading state, after Update(). + void PostRead(); - void SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force); + void SetEffect(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force); - // Update does this as needed. - // void GetInput(void *v); - void ReleaseInput(); + // Update does this as needed. + // void GetInput(void *v); + void ReleaseInput(); - void DisableDevice(int index); - inline void EnableDevice(int i) { - devices[i]->enabled = 1; - } + void DisableDevice(int index); + inline void EnableDevice(int i) + { + devices[i]->enabled = 1; + } - void EnableDevices(DeviceType type, DeviceAPI api); - void DisableAllDevices(); + void EnableDevices(DeviceType type, DeviceAPI api); + void DisableAllDevices(); }; extern InputDeviceManager *dm; diff --git a/plugins/LilyPad/KeyboardQueue.cpp b/plugins/LilyPad/KeyboardQueue.cpp index 846b649d68..7b170d445a 100644 --- a/plugins/LilyPad/KeyboardQueue.cpp +++ b/plugins/LilyPad/KeyboardQueue.cpp @@ -34,64 +34,68 @@ static u8 lastQueuedEvent = 0; static u8 nextQueuedEvent = 0; static keyEvent queuedEvents[EVENT_QUEUE_LEN]; -void QueueKeyEvent(int key, int event) { +void QueueKeyEvent(int key, int event) +{ #ifdef _MSC_VER - if (!csInitialized) { - csInitialized = 1; - InitializeCriticalSection(&cSection); - } - EnterCriticalSection(&cSection); + if (!csInitialized) { + csInitialized = 1; + InitializeCriticalSection(&cSection); + } + EnterCriticalSection(&cSection); #else - std::lock_guard lock(cSection); + std::lock_guard lock(cSection); #endif - // Don't queue events if escape is on top of queue. This is just for safety - // purposes when a game is killing the emulator for whatever reason. - if (nextQueuedEvent == lastQueuedEvent || - queuedEvents[nextQueuedEvent].key != VK_ESCAPE || - queuedEvents[nextQueuedEvent].evt != KEYPRESS) { - // Clear queue on escape down, bringing escape to front. May do something - // with shift/ctrl/alt and F-keys, later. - if (event == KEYPRESS && key == VK_ESCAPE) { - nextQueuedEvent = lastQueuedEvent; - } + // Don't queue events if escape is on top of queue. This is just for safety + // purposes when a game is killing the emulator for whatever reason. + if (nextQueuedEvent == lastQueuedEvent || + queuedEvents[nextQueuedEvent].key != VK_ESCAPE || + queuedEvents[nextQueuedEvent].evt != KEYPRESS) { + // Clear queue on escape down, bringing escape to front. May do something + // with shift/ctrl/alt and F-keys, later. + if (event == KEYPRESS && key == VK_ESCAPE) { + nextQueuedEvent = lastQueuedEvent; + } - queuedEvents[lastQueuedEvent].key = key; - queuedEvents[lastQueuedEvent].evt = event; + queuedEvents[lastQueuedEvent].key = key; + queuedEvents[lastQueuedEvent].evt = event; - lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN; - // If queue wrapped around, remove last element. - if (nextQueuedEvent == lastQueuedEvent) { - nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN; - } - } + lastQueuedEvent = (lastQueuedEvent + 1) % EVENT_QUEUE_LEN; + // If queue wrapped around, remove last element. + if (nextQueuedEvent == lastQueuedEvent) { + nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN; + } + } #ifdef _MSC_VER - LeaveCriticalSection(&cSection); + LeaveCriticalSection(&cSection); #endif } -int GetQueuedKeyEvent(keyEvent *event) { - if (lastQueuedEvent == nextQueuedEvent) return 0; +int GetQueuedKeyEvent(keyEvent *event) +{ + if (lastQueuedEvent == nextQueuedEvent) + return 0; #ifdef _MSC_VER - EnterCriticalSection(&cSection); + EnterCriticalSection(&cSection); #else - std::lock_guard lock(cSection); + std::lock_guard lock(cSection); #endif - *event = queuedEvents[nextQueuedEvent]; - nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN; + *event = queuedEvents[nextQueuedEvent]; + nextQueuedEvent = (nextQueuedEvent + 1) % EVENT_QUEUE_LEN; #ifdef _MSC_VER - LeaveCriticalSection(&cSection); + LeaveCriticalSection(&cSection); #endif - return 1; + return 1; } -void ClearKeyQueue() { - lastQueuedEvent = nextQueuedEvent; +void ClearKeyQueue() +{ + lastQueuedEvent = nextQueuedEvent; #ifdef _MSC_VER - if (csInitialized) { - DeleteCriticalSection(&cSection); - csInitialized = 0; - } + if (csInitialized) { + DeleteCriticalSection(&cSection); + csInitialized = 0; + } #endif } diff --git a/plugins/LilyPad/KeyboardQueue.h b/plugins/LilyPad/KeyboardQueue.h index f79ef32658..f6f4cf6283 100644 --- a/plugins/LilyPad/KeyboardQueue.h +++ b/plugins/LilyPad/KeyboardQueue.h @@ -26,7 +26,7 @@ int GetQueuedKeyEvent(keyEvent *event); void ClearKeyQueue(); #ifdef __linux__ -void R_QueueKeyEvent(const keyEvent& event); +void R_QueueKeyEvent(const keyEvent &event); int R_GetQueuedKeyEvent(keyEvent *event); void R_ClearKeyQueue(); #endif diff --git a/plugins/LilyPad/LilyPad.cpp b/plugins/LilyPad/LilyPad.cpp index 5f62b4e66d..62d5ca153f 100644 --- a/plugins/LilyPad/LilyPad.cpp +++ b/plugins/LilyPad/LilyPad.cpp @@ -42,11 +42,11 @@ #define FORCE_UPDATE_LPARAM ((LPARAM)0x89437437) // LilyPad version. -#define VERSION ((0<<8) | 11 | (0<<24)) +#define VERSION ((0 << 8) | 11 | (0 << 24)) #ifdef __linux__ Display *GSdsp; -Window GSwin; +Window GSwin; #else HINSTANCE hInst; HWND hWnd; @@ -91,135 +91,146 @@ unsigned char inBuf[50]; #define MODE_DS2_NATIVE 0x79 #ifdef _MSC_VER -int IsWindowMaximized (HWND hWnd) { - RECT rect; - if (GetWindowRect(hWnd, &rect)) { - POINT p; - p.x = rect.left; - p.y = rect.top; - MONITORINFO info; - memset(&info, 0, sizeof(info)); - info.cbSize = sizeof(info); - HMONITOR hMonitor; - if ((hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY)) && - GetMonitorInfo(hMonitor, &info) && - memcmp(&info.rcMonitor, &rect, sizeof(rect)) == 0) { - return 1; - } - } - return 0; +int IsWindowMaximized(HWND hWnd) +{ + RECT rect; + if (GetWindowRect(hWnd, &rect)) { + POINT p; + p.x = rect.left; + p.y = rect.top; + MONITORINFO info; + memset(&info, 0, sizeof(info)); + info.cbSize = sizeof(info); + HMONITOR hMonitor; + if ((hMonitor = MonitorFromPoint(p, MONITOR_DEFAULTTOPRIMARY)) && + GetMonitorInfo(hMonitor, &info) && + memcmp(&info.rcMonitor, &rect, sizeof(rect)) == 0) { + return 1; + } + } + return 0; } #endif -void DEBUG_TEXT_OUT(const char *text) { - if (!config.debug) - return; +void DEBUG_TEXT_OUT(const char *text) +{ + if (!config.debug) + return; - std::ofstream file("logs/padLog.txt", std::ios::app); - if (!file.good()) - return; - file << text; + std::ofstream file("logs/padLog.txt", std::ios::app); + if (!file.good()) + return; + file << text; } -void DEBUG_NEW_SET() { - if (config.debug && bufSize > 1) { - std::ofstream file("logs/padLog.txt", std::ios::app); - if (file.good()) { - std::stringstream stream; - stream.setf(std::ios::hex, std::ios::basefield); - stream.setf(std::ios::uppercase); - stream.fill('0'); +void DEBUG_NEW_SET() +{ + if (config.debug && bufSize > 1) { + std::ofstream file("logs/padLog.txt", std::ios::app); + if (file.good()) { + std::stringstream stream; + stream.setf(std::ios::hex, std::ios::basefield); + stream.setf(std::ios::uppercase); + stream.fill('0'); - unsigned char *buffer[2] = {inBuf, outBuf}; - for (const auto &buf : buffer) { - // Port/FF - stream << std::setw(2) << int(buf[0]); - // Active slots/Enabled (only relevant for multitap) - stream << " (" << std::setw(2) << int(buf[1]) << ')'; + unsigned char *buffer[2] = {inBuf, outBuf}; + for (const auto &buf : buffer) { + // Port/FF + stream << std::setw(2) << int(buf[0]); + // Active slots/Enabled (only relevant for multitap) + stream << " (" << std::setw(2) << int(buf[1]) << ')'; - // Command/Response - for (u32 n = 2; n < bufSize; ++n) - stream << ' ' << std::setw(2) << int(buf[n]); - stream << '\n'; - } - stream << '\n'; - file << stream.rdbuf(); - } - } - bufSize = 0; + // Command/Response + for (u32 n = 2; n < bufSize; ++n) + stream << ' ' << std::setw(2) << int(buf[n]); + stream << '\n'; + } + stream << '\n'; + file << stream.rdbuf(); + } + } + bufSize = 0; } -inline void DEBUG_IN(unsigned char c) { - if (bufSize < sizeof(inBuf)) inBuf[bufSize] = c; +inline void DEBUG_IN(unsigned char c) +{ + if (bufSize < sizeof(inBuf)) + inBuf[bufSize] = c; } -inline void DEBUG_OUT(unsigned char c) { - if (bufSize < sizeof(outBuf)) outBuf[bufSize++] = c; +inline void DEBUG_OUT(unsigned char c) +{ + if (bufSize < sizeof(outBuf)) + outBuf[bufSize++] = c; } -struct Stick { - int horiz; - int vert; +struct Stick +{ + int horiz; + int vert; }; // Sum of states of all controls for a pad (Not including toggles). -struct ButtonSum { - int buttons[16]; - Stick sticks[2]; +struct ButtonSum +{ + int buttons[16]; + Stick sticks[2]; }; -#define PAD_SAVE_STATE_VERSION 4 +#define PAD_SAVE_STATE_VERSION 4 // Freeze data, for a single pad. Basically has all pad state that // a PS2 can set. -struct PadFreezeData { - // Digital / Analog / DS2 Native - u8 mode; +struct PadFreezeData +{ + // Digital / Analog / DS2 Native + u8 mode; - u8 modeLock; + u8 modeLock; - // In config mode - u8 config; + // In config mode + u8 config; - u8 vibrate[8]; - u8 umask[2]; + u8 vibrate[8]; + u8 umask[2]; - // Vibration indices. - u8 vibrateI[2]; + // Vibration indices. + u8 vibrateI[2]; - // Last vibration value sent to controller. - // Only used so as not to call vibration - // functions when old and new values are both 0. - u8 currentVibrate[2]; + // Last vibration value sent to controller. + // Only used so as not to call vibration + // functions when old and new values are both 0. + u8 currentVibrate[2]; - // Next vibrate val to send to controller. If next and current are - // both 0, nothing is sent to the controller. Otherwise, it's sent - // on every update. - u8 nextVibrate[2]; + // Next vibrate val to send to controller. If next and current are + // both 0, nothing is sent to the controller. Otherwise, it's sent + // on every update. + u8 nextVibrate[2]; }; -class Pad : public PadFreezeData { +class Pad : public PadFreezeData +{ public: - // Current pad state. - ButtonSum sum; - // State of locked buttons. Already included by sum, used - // as initial value of sum. - ButtonSum lockedSum; + // Current pad state. + ButtonSum sum; + // State of locked buttons. Already included by sum, used + // as initial value of sum. + ButtonSum lockedSum; - // Flags for which controls (buttons or axes) are locked, if any. - DWORD lockedState; + // Flags for which controls (buttons or axes) are locked, if any. + DWORD lockedState; - // Used to keep track of which pads I'm running. - // Note that initialized pads *can* be disabled. - // I keep track of state of non-disabled non-initialized - // pads, but should never be asked for their state. - u8 initialized; + // Used to keep track of which pads I'm running. + // Note that initialized pads *can* be disabled. + // I keep track of state of non-disabled non-initialized + // pads, but should never be asked for their state. + u8 initialized; - // Set to 1 if the state of this pad has been updated since its state - // was last queried. - char stateUpdated; + // Set to 1 if the state of this pad has been updated since its state + // was last queried. + char stateUpdated; - // initialized and not disabled (and mtap state for slots > 0). - u8 enabled; + // initialized and not disabled (and mtap state for slots > 0). + u8 enabled; } pads[2][4]; // Active slots for each port. @@ -228,16 +239,20 @@ int slots[2]; int portInitialized[2]; // Force value to be from 0 to 255. -u8 Cap (int i) { - if (i<0) return 0; - if (i>255) return 255; - return (u8) i; +u8 Cap(int i) +{ + if (i < 0) + return 0; + if (i > 255) + return 255; + return (u8)i; } -inline void ReleaseModifierKeys() { - QueueKeyEvent(VK_SHIFT, KEYRELEASE); - QueueKeyEvent(VK_MENU, KEYRELEASE); - QueueKeyEvent(VK_CONTROL, KEYRELEASE); +inline void ReleaseModifierKeys() +{ + QueueKeyEvent(VK_SHIFT, KEYRELEASE); + QueueKeyEvent(VK_MENU, KEYRELEASE); + QueueKeyEvent(VK_CONTROL, KEYRELEASE); } // RefreshEnabledDevices() enables everything that can potentially @@ -249,175 +264,178 @@ inline void ReleaseModifierKeys() { // keyboards if window is not focused. Releases game devices if // background monitoring is not checked. // And releases games if not focused and config.background is not set. -void UpdateEnabledDevices(int updateList = 0) { - // Enable all devices I might want. Can ignore the rest. - RefreshEnabledDevices(updateList); - // Figure out which pads I'm getting input for. - for (int port = 0; port<2; port++) { - for (int slot = 0; slot<4; slot++) { - if (slot && !config.multitap[port]) { - pads[port][slot].enabled = 0; - } - else { - pads[port][slot].enabled = pads[port][slot].initialized && config.padConfigs[port][slot].type != DisabledPad; - } - } - } - for (int i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; +void UpdateEnabledDevices(int updateList = 0) +{ + // Enable all devices I might want. Can ignore the rest. + RefreshEnabledDevices(updateList); + // Figure out which pads I'm getting input for. + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + if (slot && !config.multitap[port]) { + pads[port][slot].enabled = 0; + } else { + pads[port][slot].enabled = pads[port][slot].initialized && config.padConfigs[port][slot].type != DisabledPad; + } + } + } + for (int i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; - if (!dev->enabled) continue; - if (!dev->attached) { - dm->DisableDevice(i); - continue; - } + if (!dev->enabled) + continue; + if (!dev->attached) { + dm->DisableDevice(i); + continue; + } - // Disable ignore keyboard if don't have focus or there are no keys to ignore. - if (dev->api == IGNORE_KEYBOARD) { - if ((config.keyboardApi == NO_API || !dev->pads[0][0].numBindings) || !activeWindow) { - dm->DisableDevice(i); - } - continue; - } - // Keep for PCSX2 keyboard shotcuts, unless unfocused. - if (dev->type == KEYBOARD) { - if (!activeWindow) dm->DisableDevice(i); - } - // Keep for cursor hiding consistency, unless unfocused. - // miceEnabled tracks state of mouse enable/disable button, not if mouse API is set to disabled. - else if (dev->type == MOUSE) { - if (!miceEnabled || !activeWindow) dm->DisableDevice(i); - } - else if (!activeWindow && !config.background) dm->DisableDevice(i); - else { - int numActiveBindings = 0; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - if (pads[port][slot].enabled) { - numActiveBindings += dev->pads[port][slot].numBindings + dev->pads[port][slot].numFFBindings; - } - } - } - if (!numActiveBindings) - dm->DisableDevice(i); - } - } + // Disable ignore keyboard if don't have focus or there are no keys to ignore. + if (dev->api == IGNORE_KEYBOARD) { + if ((config.keyboardApi == NO_API || !dev->pads[0][0].numBindings) || !activeWindow) { + dm->DisableDevice(i); + } + continue; + } + // Keep for PCSX2 keyboard shotcuts, unless unfocused. + if (dev->type == KEYBOARD) { + if (!activeWindow) + dm->DisableDevice(i); + } + // Keep for cursor hiding consistency, unless unfocused. + // miceEnabled tracks state of mouse enable/disable button, not if mouse API is set to disabled. + else if (dev->type == MOUSE) { + if (!miceEnabled || !activeWindow) + dm->DisableDevice(i); + } else if (!activeWindow && !config.background) + dm->DisableDevice(i); + else { + int numActiveBindings = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + if (pads[port][slot].enabled) { + numActiveBindings += dev->pads[port][slot].numBindings + dev->pads[port][slot].numFFBindings; + } + } + } + if (!numActiveBindings) + dm->DisableDevice(i); + } + } } #ifdef _MSC_VER -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, void* lpvReserved) { - hInst = hInstance; - if (fdwReason == DLL_PROCESS_ATTACH) { - InitializeCriticalSection( &updateLock ); +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, void *lpvReserved) +{ + hInst = hInstance; + if (fdwReason == DLL_PROCESS_ATTACH) { + InitializeCriticalSection(&updateLock); - DisableThreadLibraryCalls(hInstance); - } - else if (fdwReason == DLL_PROCESS_DETACH) { - while (openCount) - PADclose(); - PADshutdown(); - UninitLibUsb(); - DeleteCriticalSection( &updateLock ); - } - return 1; + DisableThreadLibraryCalls(hInstance); + } else if (fdwReason == DLL_PROCESS_DETACH) { + while (openCount) + PADclose(); + PADshutdown(); + UninitLibUsb(); + DeleteCriticalSection(&updateLock); + } + return 1; } #endif -void AddForce(ButtonSum *sum, u8 cmd, int delta = 255) { - if (!delta) return; - if (cmd<0x14) { - sum->buttons[cmd-0x10] += delta; - } - // D-pad. Command numbering is based on ordering of digital values. - else if (cmd < 0x18) { - sum->buttons[cmd-0x08] += delta; - } - else if (cmd < 0x20) { - sum->buttons[cmd-0x10-4] += delta; - } - // Left stick. - else if (cmd < 0x24) { - if (cmd == 32) { - sum->sticks[1].vert -= delta; - } - else if (cmd == 33) { - sum->sticks[1].horiz += delta; - } - else if (cmd == 34) { - sum->sticks[1].vert += delta; - } - else if (cmd == 35) { - sum->sticks[1].horiz -= delta; - } - } - // Right stick. - else if (cmd < 0x28) { - if (cmd == 36) { - sum->sticks[0].vert -= delta; - } - else if (cmd == 37) { - sum->sticks[0].horiz += delta; - } - else if (cmd == 38) { - sum->sticks[0].vert += delta; - } - else if (cmd == 39) { - sum->sticks[0].horiz -= delta; - } - } +void AddForce(ButtonSum *sum, u8 cmd, int delta = 255) +{ + if (!delta) + return; + if (cmd < 0x14) { + sum->buttons[cmd - 0x10] += delta; + } + // D-pad. Command numbering is based on ordering of digital values. + else if (cmd < 0x18) { + sum->buttons[cmd - 0x08] += delta; + } else if (cmd < 0x20) { + sum->buttons[cmd - 0x10 - 4] += delta; + } + // Left stick. + else if (cmd < 0x24) { + if (cmd == 32) { + sum->sticks[1].vert -= delta; + } else if (cmd == 33) { + sum->sticks[1].horiz += delta; + } else if (cmd == 34) { + sum->sticks[1].vert += delta; + } else if (cmd == 35) { + sum->sticks[1].horiz -= delta; + } + } + // Right stick. + else if (cmd < 0x28) { + if (cmd == 36) { + sum->sticks[0].vert -= delta; + } else if (cmd == 37) { + sum->sticks[0].horiz += delta; + } else if (cmd == 38) { + sum->sticks[0].vert += delta; + } else if (cmd == 39) { + sum->sticks[0].horiz -= delta; + } + } } -void ProcessButtonBinding(Binding *b, ButtonSum *sum, int value) { - if (value < b->deadZone || !value) return; - - if ( config.turboKeyHack == 1 ){ // send a tabulator keypress to emulator - //printf("%x\n", b->command); - if ( b->command == 0x11 ){ // L3 button - static unsigned int LastCheck = 0; - unsigned int t = timeGetTime(); - if (t - LastCheck < 300 ) return; - QueueKeyEvent(VK_TAB, KEYPRESS); - LastCheck = t; - } - } +void ProcessButtonBinding(Binding *b, ButtonSum *sum, int value) +{ + if (value < b->deadZone || !value) + return; - int sensitivity = b->sensitivity; - if (sensitivity < 0) { - sensitivity = -sensitivity; - value = (1<<16)-value; - } - if (value < 0) return; + if (config.turboKeyHack == 1) { // send a tabulator keypress to emulator + //printf("%x\n", b->command); + if (b->command == 0x11) { // L3 button + static unsigned int LastCheck = 0; + unsigned int t = timeGetTime(); + if (t - LastCheck < 300) + return; + QueueKeyEvent(VK_TAB, KEYPRESS); + LastCheck = t; + } + } - /* Note: Value ranges of FULLY_DOWN, and sensitivity of + int sensitivity = b->sensitivity; + if (sensitivity < 0) { + sensitivity = -sensitivity; + value = (1 << 16) - value; + } + if (value < 0) + return; + + /* Note: Value ranges of FULLY_DOWN, and sensitivity of * BASE_SENSITIVITY corresponds to an axis/button being exactly fully down. * Math in next line takes care of those two conditions, rounding as necessary. * Done using __int64s because overflows will occur when * sensitivity > BASE_SENSITIVITY and/or value > FULLY_DOWN. Latter only happens * for relative axis. */ - int force = (int)((((sensitivity*(255*(__int64)value)) + BASE_SENSITIVITY/2)/BASE_SENSITIVITY + FULLY_DOWN/2)/FULLY_DOWN); - AddForce(sum, b->command, force); + int force = (int)((((sensitivity * (255 * (__int64)value)) + BASE_SENSITIVITY / 2) / BASE_SENSITIVITY + FULLY_DOWN / 2) / FULLY_DOWN); + AddForce(sum, b->command, force); } // Restricts d-pad/analog stick values to be from -255 to 255 and button values to be from 0 to 255. // With D-pad in DS2 native mode, the negative and positive ranges are both independently from 0 to 255, // which is why I use 9 bits of all sticks. For left and right sticks, I have to remove a bit before sending. -void CapSum(ButtonSum *sum) { - int i; - for (i=0; i<2; i++) { +void CapSum(ButtonSum *sum) +{ + int i; + for (i = 0; i < 2; i++) { #ifdef __linux__ - int div = std::max(abs(sum->sticks[i].horiz), abs(sum->sticks[i].vert)); + int div = std::max(abs(sum->sticks[i].horiz), abs(sum->sticks[i].vert)); #else - int div = max(abs(sum->sticks[i].horiz), abs(sum->sticks[i].vert)); + int div = max(abs(sum->sticks[i].horiz), abs(sum->sticks[i].vert)); #endif - if (div > 255) { - sum->sticks[i].horiz = sum->sticks[i].horiz * 255 / div; - sum->sticks[i].vert = sum->sticks[i].vert * 255 / div; - } - } - for (i=0; i<16; i++) { - sum->buttons[i] = Cap(sum->buttons[i]); - } + if (div > 255) { + sum->sticks[i].horiz = sum->sticks[i].horiz * 255 / div; + sum->sticks[i].vert = sum->sticks[i].vert * 255 / div; + } + } + for (i = 0; i < 16; i++) { + sum->buttons[i] = Cap(sum->buttons[i]); + } } // Counter similar to stateUpdated for each pad, except used for PADkeyEvent instead. @@ -435,393 +453,403 @@ char padReadKeyUpdated[4] = {0, 0, 0, 0}; #ifdef _MSC_VER struct EnterScopedSection { - CRITICAL_SECTION& m_cs; + CRITICAL_SECTION &m_cs; - EnterScopedSection( CRITICAL_SECTION& cs ) : m_cs( cs ) { - EnterCriticalSection( &m_cs ); - } + EnterScopedSection(CRITICAL_SECTION &cs) + : m_cs(cs) + { + EnterCriticalSection(&m_cs); + } - ~EnterScopedSection() { - LeaveCriticalSection( &m_cs ); - } + ~EnterScopedSection() + { + LeaveCriticalSection(&m_cs); + } }; #endif -void Update(unsigned int port, unsigned int slot) { - char *stateUpdated; - if (port < 2) { - stateUpdated = &pads[port][slot].stateUpdated; - } - else if (port < 6) { - stateUpdated = padReadKeyUpdated+port-2; - } - else return; +void Update(unsigned int port, unsigned int slot) +{ + char *stateUpdated; + if (port < 2) { + stateUpdated = &pads[port][slot].stateUpdated; + } else if (port < 6) { + stateUpdated = padReadKeyUpdated + port - 2; + } else + return; - if (*stateUpdated > 0) { - stateUpdated[0] --; - return; - } + if (*stateUpdated > 0) { + stateUpdated[0]--; + return; + } - // Lock prior to timecheck code to avoid pesky race conditions. +// Lock prior to timecheck code to avoid pesky race conditions. #ifdef __linux__ - std::lock_guard lock(updateLock); + std::lock_guard lock(updateLock); #else - EnterScopedSection padlock( updateLock ); + EnterScopedSection padlock(updateLock); #endif - static unsigned int LastCheck = 0; - unsigned int t = timeGetTime(); - if (t - LastCheck < 15 || !openCount) return; + static unsigned int LastCheck = 0; + unsigned int t = timeGetTime(); + if (t - LastCheck < 15 || !openCount) + return; #ifdef _MSC_VER - if (windowThreadId != GetCurrentThreadId()) { - if (stateUpdated[0] < 0) { - if (!updateQueued) { - updateQueued = 1; - PostMessage(hWnd, WMA_FORCE_UPDATE, FORCE_UPDATE_WPARAM, FORCE_UPDATE_LPARAM); - } - } else - { - stateUpdated[0] --; - } - return; - } + if (windowThreadId != GetCurrentThreadId()) { + if (stateUpdated[0] < 0) { + if (!updateQueued) { + updateQueued = 1; + PostMessage(hWnd, WMA_FORCE_UPDATE, FORCE_UPDATE_WPARAM, FORCE_UPDATE_LPARAM); + } + } else { + stateUpdated[0]--; + } + return; + } #endif - LastCheck = t; + LastCheck = t; - int i; - ButtonSum s[2][4]; - u8 lockStateChanged[2][4]; - memset(lockStateChanged, 0, sizeof(lockStateChanged)); + int i; + ButtonSum s[2][4]; + u8 lockStateChanged[2][4]; + memset(lockStateChanged, 0, sizeof(lockStateChanged)); - for (i=0; i<8; i++) { - s[i&1][i>>1] = pads[i&1][i>>1].lockedSum; - } + for (i = 0; i < 8; i++) { + s[i & 1][i >> 1] = pads[i & 1][i >> 1].lockedSum; + } #ifdef __linux__ - InitInfo info = { - 0, 0, GSdsp, GSwin - }; + InitInfo info = { + 0, 0, GSdsp, GSwin}; #else - InitInfo info = { - 0, 0, hWndTop, &hWndGSProc - }; + InitInfo info = { + 0, 0, hWndTop, &hWndGSProc}; #endif - dm->Update(&info); - static int turbo = 0; - turbo++; - for (i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; - // Skip both disabled devices and inactive enabled devices. - // Shouldn't be any of the latter, in general, but just in case... - if (!dev->active) continue; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - if (config.padConfigs[port][slot].type == DisabledPad || !pads[port][slot].initialized) continue; - for (int j=0; jpads[port][slot].numBindings; j++) { - Binding *b = dev->pads[port][slot].bindings+j; - int cmd = b->command; - int state = dev->virtualControlState[b->controlIndex]; - if (!(turbo & b->turbo)) { - if (cmd > 0x0F && cmd != 0x28) { - ProcessButtonBinding(b, &s[port][slot], state); - } - else if ((state>>15) && !(dev->oldVirtualControlState[b->controlIndex]>>15)) { - if (cmd == 0x0F) { - miceEnabled = !miceEnabled; - UpdateEnabledDevices(); - } - else if (cmd == 0x0C) { - lockStateChanged[port][slot] |= LOCK_BUTTONS; - } - else if (cmd == 0x0E) { - lockStateChanged[port][slot] |= LOCK_DIRECTION; - } - else if (cmd == 0x0D) { - lockStateChanged[port][slot] |= LOCK_BOTH; - } - else if (cmd == 0x28) { - if (!pads[port][slot].modeLock) { - if (pads[port][slot].mode != MODE_DIGITAL) - pads[port][slot].mode = MODE_DIGITAL; - else - pads[port][slot].mode = MODE_ANALOG; - } - } - } - } - } - } - } - } - dm->PostRead(); + dm->Update(&info); + static int turbo = 0; + turbo++; + for (i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; + // Skip both disabled devices and inactive enabled devices. + // Shouldn't be any of the latter, in general, but just in case... + if (!dev->active) + continue; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + if (config.padConfigs[port][slot].type == DisabledPad || !pads[port][slot].initialized) + continue; + for (int j = 0; j < dev->pads[port][slot].numBindings; j++) { + Binding *b = dev->pads[port][slot].bindings + j; + int cmd = b->command; + int state = dev->virtualControlState[b->controlIndex]; + if (!(turbo & b->turbo)) { + if (cmd > 0x0F && cmd != 0x28) { + ProcessButtonBinding(b, &s[port][slot], state); + } else if ((state >> 15) && !(dev->oldVirtualControlState[b->controlIndex] >> 15)) { + if (cmd == 0x0F) { + miceEnabled = !miceEnabled; + UpdateEnabledDevices(); + } else if (cmd == 0x0C) { + lockStateChanged[port][slot] |= LOCK_BUTTONS; + } else if (cmd == 0x0E) { + lockStateChanged[port][slot] |= LOCK_DIRECTION; + } else if (cmd == 0x0D) { + lockStateChanged[port][slot] |= LOCK_BOTH; + } else if (cmd == 0x28) { + if (!pads[port][slot].modeLock) { + if (pads[port][slot].mode != MODE_DIGITAL) + pads[port][slot].mode = MODE_DIGITAL; + else + pads[port][slot].mode = MODE_ANALOG; + } + } + } + } + } + } + } + } + dm->PostRead(); - { - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - for (int motor=0; motor<2; motor++) { - // TODO: Probably be better to send all of these at once. - if (pads[port][slot].nextVibrate[motor] | pads[port][slot].currentVibrate[motor]) { - pads[port][slot].currentVibrate[motor] = pads[port][slot].nextVibrate[motor]; - dm->SetEffect(port,slot, motor, pads[port][slot].nextVibrate[motor]); - } - } - } - } + { + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + for (int motor = 0; motor < 2; motor++) { + // TODO: Probably be better to send all of these at once. + if (pads[port][slot].nextVibrate[motor] | pads[port][slot].currentVibrate[motor]) { + pads[port][slot].currentVibrate[motor] = pads[port][slot].nextVibrate[motor]; + dm->SetEffect(port, slot, motor, pads[port][slot].nextVibrate[motor]); + } + } + } + } - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - pads[port][slot].stateUpdated = 1; - if (config.padConfigs[port][slot].type == DisabledPad || !pads[port][slot].initialized) continue; - if (config.padConfigs[port][slot].type == GuitarPad) { - if (!config.GH2) { - s[port][slot].sticks[0].vert = -s[port][slot].sticks[0].vert; - } - // GH2 hack. - else if (config.GH2) { - const unsigned int oldIdList[5] = {ID_R2, ID_CIRCLE, ID_TRIANGLE, ID_CROSS, ID_SQUARE}; - const unsigned int idList[5] = {ID_L2, ID_L1, ID_R1, ID_R2, ID_CROSS}; - int values[5]; - int i; - for (i=0; i<5; i++) { - int id = oldIdList[i] - 0x1104; - values[i] = s[port][slot].buttons[id]; - s[port][slot].buttons[id] = 0; - } - s[port][slot].buttons[ID_TRIANGLE-0x1104] = values[1]; - for (i=0; i<5; i++) { - int id = idList[i] - 0x1104; - s[port][slot].buttons[id] = values[i]; - } - if (s[port][slot].buttons[14] <= 48 && s[port][slot].buttons[12] <= 48) { - for (int i=0; i<5; i++) { - unsigned int id = idList[i] - 0x1104; - if (pads[port][slot].sum.buttons[id] < s[port][slot].buttons[id]) { - s[port][slot].buttons[id] = pads[port][slot].sum.buttons[id]; - } - } - } - else if (pads[port][slot].sum.buttons[14] <= 48 && pads[port][slot].sum.buttons[12] <= 48) { - for (int i=0; i<5; i++) { - unsigned int id = idList[i] - 0x1104; - if (pads[port][slot].sum.buttons[id]) { - s[port][slot].buttons[id] = 0; - } - } - } - } - } + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + pads[port][slot].stateUpdated = 1; + if (config.padConfigs[port][slot].type == DisabledPad || !pads[port][slot].initialized) + continue; + if (config.padConfigs[port][slot].type == GuitarPad) { + if (!config.GH2) { + s[port][slot].sticks[0].vert = -s[port][slot].sticks[0].vert; + } + // GH2 hack. + else if (config.GH2) { + const unsigned int oldIdList[5] = {ID_R2, ID_CIRCLE, ID_TRIANGLE, ID_CROSS, ID_SQUARE}; + const unsigned int idList[5] = {ID_L2, ID_L1, ID_R1, ID_R2, ID_CROSS}; + int values[5]; + int i; + for (i = 0; i < 5; i++) { + int id = oldIdList[i] - 0x1104; + values[i] = s[port][slot].buttons[id]; + s[port][slot].buttons[id] = 0; + } + s[port][slot].buttons[ID_TRIANGLE - 0x1104] = values[1]; + for (i = 0; i < 5; i++) { + int id = idList[i] - 0x1104; + s[port][slot].buttons[id] = values[i]; + } + if (s[port][slot].buttons[14] <= 48 && s[port][slot].buttons[12] <= 48) { + for (int i = 0; i < 5; i++) { + unsigned int id = idList[i] - 0x1104; + if (pads[port][slot].sum.buttons[id] < s[port][slot].buttons[id]) { + s[port][slot].buttons[id] = pads[port][slot].sum.buttons[id]; + } + } + } else if (pads[port][slot].sum.buttons[14] <= 48 && pads[port][slot].sum.buttons[12] <= 48) { + for (int i = 0; i < 5; i++) { + unsigned int id = idList[i] - 0x1104; + if (pads[port][slot].sum.buttons[id]) { + s[port][slot].buttons[id] = 0; + } + } + } + } + } - if (pads[port][slot].mode == 0x41) { - for (int i=0; i<=1; i++) { - if (s[port][slot].sticks[i].horiz >= 100) - s[port][slot].buttons[13] += s[port][slot].sticks[i].horiz; - if (s[port][slot].sticks[i].horiz <= -100) - s[port][slot].buttons[15] -= s[port][slot].sticks[i].horiz; - if (s[port][slot].sticks[i].vert >= 100) - s[port][slot].buttons[14] += s[port][slot].sticks[i].vert; - if (s[port][slot].sticks[i].vert <= -100) - s[port][slot].buttons[12] -= s[port][slot].sticks[i].vert; - } - } + if (pads[port][slot].mode == 0x41) { + for (int i = 0; i <= 1; i++) { + if (s[port][slot].sticks[i].horiz >= 100) + s[port][slot].buttons[13] += s[port][slot].sticks[i].horiz; + if (s[port][slot].sticks[i].horiz <= -100) + s[port][slot].buttons[15] -= s[port][slot].sticks[i].horiz; + if (s[port][slot].sticks[i].vert >= 100) + s[port][slot].buttons[14] += s[port][slot].sticks[i].vert; + if (s[port][slot].sticks[i].vert <= -100) + s[port][slot].buttons[12] -= s[port][slot].sticks[i].vert; + } + } - CapSum(&s[port][slot]); - if (lockStateChanged[port][slot]) { - if (lockStateChanged[port][slot] & LOCK_BOTH) { - if (pads[port][slot].lockedState != (LOCK_DIRECTION | LOCK_BUTTONS)) { - // Enable the one that's not enabled. - lockStateChanged[port][slot] ^= pads[port][slot].lockedState^(LOCK_DIRECTION | LOCK_BUTTONS); - } - else { - // Disable both - lockStateChanged[port][slot] ^= LOCK_DIRECTION | LOCK_BUTTONS; - } - } - if (lockStateChanged[port][slot] & LOCK_DIRECTION) { - if (pads[port][slot].lockedState & LOCK_DIRECTION) { - memset(pads[port][slot].lockedSum.sticks, 0, sizeof(pads[port][slot].lockedSum.sticks)); - } - else { - memcpy(pads[port][slot].lockedSum.sticks, s[port][slot].sticks, sizeof(pads[port][slot].lockedSum.sticks)); - } - pads[port][slot].lockedState ^= LOCK_DIRECTION; - } - if (lockStateChanged[port][slot] & LOCK_BUTTONS) { - if (pads[port][slot].lockedState & LOCK_BUTTONS) { - memset(pads[port][slot].lockedSum.buttons, 0, sizeof(pads[port][slot].lockedSum.buttons)); - } - else { - memcpy(pads[port][slot].lockedSum.buttons, s[port][slot].buttons, sizeof(pads[port][slot].lockedSum.buttons)); - } - pads[port][slot].lockedState ^= LOCK_BUTTONS; - } - for (i=0; i< (int)sizeof(pads[port][slot].lockedSum)/4; i++) { - if (((int*)&pads[port][slot].lockedSum)[i]) break; - } - if (i==sizeof(pads[port][slot].lockedSum)/4) { - pads[port][slot].lockedState = 0; - } - } - } - } - } - for (i=0; i<8; i++) { - pads[i&1][i>>1].sum = s[i&1][i>>1]; - } + CapSum(&s[port][slot]); + if (lockStateChanged[port][slot]) { + if (lockStateChanged[port][slot] & LOCK_BOTH) { + if (pads[port][slot].lockedState != (LOCK_DIRECTION | LOCK_BUTTONS)) { + // Enable the one that's not enabled. + lockStateChanged[port][slot] ^= pads[port][slot].lockedState ^ (LOCK_DIRECTION | LOCK_BUTTONS); + } else { + // Disable both + lockStateChanged[port][slot] ^= LOCK_DIRECTION | LOCK_BUTTONS; + } + } + if (lockStateChanged[port][slot] & LOCK_DIRECTION) { + if (pads[port][slot].lockedState & LOCK_DIRECTION) { + memset(pads[port][slot].lockedSum.sticks, 0, sizeof(pads[port][slot].lockedSum.sticks)); + } else { + memcpy(pads[port][slot].lockedSum.sticks, s[port][slot].sticks, sizeof(pads[port][slot].lockedSum.sticks)); + } + pads[port][slot].lockedState ^= LOCK_DIRECTION; + } + if (lockStateChanged[port][slot] & LOCK_BUTTONS) { + if (pads[port][slot].lockedState & LOCK_BUTTONS) { + memset(pads[port][slot].lockedSum.buttons, 0, sizeof(pads[port][slot].lockedSum.buttons)); + } else { + memcpy(pads[port][slot].lockedSum.buttons, s[port][slot].buttons, sizeof(pads[port][slot].lockedSum.buttons)); + } + pads[port][slot].lockedState ^= LOCK_BUTTONS; + } + for (i = 0; i < (int)sizeof(pads[port][slot].lockedSum) / 4; i++) { + if (((int *)&pads[port][slot].lockedSum)[i]) + break; + } + if (i == sizeof(pads[port][slot].lockedSum) / 4) { + pads[port][slot].lockedState = 0; + } + } + } + } + } + for (i = 0; i < 8; i++) { + pads[i & 1][i >> 1].sum = s[i & 1][i >> 1]; + } - padReadKeyUpdated[0] = padReadKeyUpdated[1] = padReadKeyUpdated[2] = 1; + padReadKeyUpdated[0] = padReadKeyUpdated[1] = padReadKeyUpdated[2] = 1; - if( stateUpdated[0] > 0 ) - --stateUpdated[0]; + if (stateUpdated[0] > 0) + --stateUpdated[0]; } -void CALLBACK PADupdate(int port) { - Update(port+3, 0); +void CALLBACK PADupdate(int port) +{ + Update(port + 3, 0); } -inline void SetVibrate(int port, int slot, int motor, u8 val) { - pads[port][slot].nextVibrate[motor] = val; +inline void SetVibrate(int port, int slot, int motor, u8 val) +{ + pads[port][slot].nextVibrate[motor] = val; } -u32 CALLBACK PS2EgetLibType(void) { - ps2e = 1; - return PS2E_LT_PAD; +u32 CALLBACK PS2EgetLibType(void) +{ + ps2e = 1; + return PS2E_LT_PAD; } -u32 CALLBACK PS2EgetLibVersion2(u32 type) { - ps2e = 1; - if (type == PS2E_LT_PAD) - return (PS2E_PAD_VERSION<<16) | VERSION; - return 0; +u32 CALLBACK PS2EgetLibVersion2(u32 type) +{ + ps2e = 1; + if (type == PS2E_LT_PAD) + return (PS2E_PAD_VERSION << 16) | VERSION; + return 0; } #ifdef _MSC_VER // Used in about and config screens. -void GetNameAndVersionString(wchar_t *out) { +void GetNameAndVersionString(wchar_t *out) +{ #if defined(PCSX2_DEBUG) - wsprintfW(out, L"LilyPad Debug %i.%i.%i (%lld)", (VERSION>>8)&0xFF, VERSION&0xFF, (VERSION>>24)&0xFF, SVN_REV); + wsprintfW(out, L"LilyPad Debug %i.%i.%i (%lld)", (VERSION >> 8) & 0xFF, VERSION & 0xFF, (VERSION >> 24) & 0xFF, SVN_REV); #else - wsprintfW(out, L"LilyPad %i.%i.%i (%lld)", (VERSION>>8)&0xFF, VERSION&0xFF, (VERSION>>24)&0xFF, SVN_REV); + wsprintfW(out, L"LilyPad %i.%i.%i (%lld)", (VERSION >> 8) & 0xFF, VERSION & 0xFF, (VERSION >> 24) & 0xFF, SVN_REV); #endif } #endif -char* CALLBACK PSEgetLibName() { +char *CALLBACK PSEgetLibName() +{ #if defined(PCSX2_DEBUG) - static char version[50]; - sprintf(version, "LilyPad Debug (%lld)", SVN_REV); - return version; + static char version[50]; + sprintf(version, "LilyPad Debug (%lld)", SVN_REV); + return version; #else - static char version[50]; - sprintf(version, "LilyPad (%lld)", SVN_REV); - return version; + static char version[50]; + sprintf(version, "LilyPad (%lld)", SVN_REV); + return version; #endif } -char* CALLBACK PS2EgetLibName(void) { - ps2e = 1; - return PSEgetLibName(); +char *CALLBACK PS2EgetLibName(void) +{ + ps2e = 1; + return PSEgetLibName(); } //void CALLBACK PADgsDriverInfo(GSdriverInfo *info) { // info=info; //} -void CALLBACK PADshutdown() { - DEBUG_TEXT_OUT("LilyPad shutdown.\n\n"); - for (int i=0; i<8; i++) - pads[i&1][i>>1].initialized = 0; - portInitialized[0] = portInitialized[1] = 0; - UnloadConfigs(); +void CALLBACK PADshutdown() +{ + DEBUG_TEXT_OUT("LilyPad shutdown.\n\n"); + for (int i = 0; i < 8; i++) + pads[i & 1][i >> 1].initialized = 0; + portInitialized[0] = portInitialized[1] = 0; + UnloadConfigs(); } -inline void StopVibrate() { - for (int i=0; i<8; i++) { - SetVibrate(i&1, i>>1, 0, 0); - SetVibrate(i&1, i>>1, 1, 0); - } +inline void StopVibrate() +{ + for (int i = 0; i < 8; i++) { + SetVibrate(i & 1, i >> 1, 0, 0); + SetVibrate(i & 1, i >> 1, 1, 0); + } } -inline void ResetVibrate(int port, int slot) { - SetVibrate(port, slot, 0, 0); - SetVibrate(port, slot, 1, 0); - pads[port][slot].vibrate[0] = 0x5A; - for (int i = 1; i < 8; ++i) - pads[port][slot].vibrate[i] = 0xFF; +inline void ResetVibrate(int port, int slot) +{ + SetVibrate(port, slot, 0, 0); + SetVibrate(port, slot, 1, 0); + pads[port][slot].vibrate[0] = 0x5A; + for (int i = 1; i < 8; ++i) + pads[port][slot].vibrate[i] = 0xFF; } -void ResetPad(int port, int slot) { - // Lines before memset currently don't do anything useful, - // but allow this function to be called at any time. +void ResetPad(int port, int slot) +{ + // Lines before memset currently don't do anything useful, + // but allow this function to be called at any time. - // Need to backup, so can be called at any point. - u8 enabled = pads[port][slot].enabled; + // Need to backup, so can be called at any point. + u8 enabled = pads[port][slot].enabled; - // Currently should never do anything. - SetVibrate(port, slot, 0, 0); - SetVibrate(port, slot, 1, 0); + // Currently should never do anything. + SetVibrate(port, slot, 0, 0); + SetVibrate(port, slot, 1, 0); - memset(&pads[port][slot], 0, sizeof(pads[0][0])); - pads[port][slot].mode = MODE_DIGITAL; - pads[port][slot].umask[0] = pads[port][slot].umask[1] = 0xFF; - // Sets up vibrate variable. - ResetVibrate(port, slot); - pads[port][slot].initialized = 1; + memset(&pads[port][slot], 0, sizeof(pads[0][0])); + pads[port][slot].mode = MODE_DIGITAL; + pads[port][slot].umask[0] = pads[port][slot].umask[1] = 0xFF; + // Sets up vibrate variable. + ResetVibrate(port, slot); + pads[port][slot].initialized = 1; - pads[port][slot].enabled = enabled; + pads[port][slot].enabled = enabled; } -struct QueryInfo { - u8 port; - u8 slot; - u8 lastByte; - u8 currentCommand; - u8 numBytes; - u8 queryDone; - u8 response[42]; +struct QueryInfo +{ + u8 port; + u8 slot; + u8 lastByte; + u8 currentCommand; + u8 numBytes; + u8 queryDone; + u8 response[42]; } query = {0, 0, 0, 0, 0, 0xFF, {0xF3}}; #ifdef _MSC_VER int saveStateIndex = 0; #endif -s32 CALLBACK PADinit(u32 flags) { - // Note: Won't load settings if already loaded. - if (LoadSettings() < 0) { - return -1; - } - int port = (flags & 3); - if (port == 3) { - if (PADinit(1) == -1) return -1; - return PADinit(2); - } +s32 CALLBACK PADinit(u32 flags) +{ + // Note: Won't load settings if already loaded. + if (LoadSettings() < 0) { + return -1; + } + int port = (flags & 3); + if (port == 3) { + if (PADinit(1) == -1) + return -1; + return PADinit(2); + } - #if defined(PCSX2_DEBUG) && defined(_MSC_VER) - int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); - tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF; - _CrtSetDbgFlag( tmpFlag ); - #endif - - port --; - - for (int i=0; i<4; i++) { - ResetPad(port, i); - } - slots[port] = 0; - portInitialized[port] = 1; - - query.lastByte = 1; - query.numBytes = 0; - ClearKeyQueue(); -#ifdef __linux__ - R_ClearKeyQueue(); +#if defined(PCSX2_DEBUG) && defined(_MSC_VER) + int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + tmpFlag |= _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag(tmpFlag); #endif - // Just in case, when resuming emulation. - ReleaseModifierKeys(); - DEBUG_TEXT_OUT("LilyPad initialized\n\n"); - return 0; + port--; + + for (int i = 0; i < 4; i++) { + ResetPad(port, i); + } + slots[port] = 0; + portInitialized[port] = 1; + + query.lastByte = 1; + query.numBytes = 0; + ClearKeyQueue(); +#ifdef __linux__ + R_ClearKeyQueue(); +#endif + // Just in case, when resuming emulation. + ReleaseModifierKeys(); + + DEBUG_TEXT_OUT("LilyPad initialized\n\n"); + return 0; } @@ -829,691 +857,700 @@ s32 CALLBACK PADinit(u32 flags) { // Note to self: Has to be a define for the sizeof() to work right. // Note to self 2: All are the same size, anyways, except for longer full DS2 response // and shorter digital mode response. -#define SET_RESULT(a) { \ - memcpy(query.response+2, a, sizeof(a)); \ - query.numBytes = 2+sizeof(a); \ -} +#define SET_RESULT(a) \ + { \ + memcpy(query.response + 2, a, sizeof(a)); \ + query.numBytes = 2 + sizeof(a); \ + } -#define SET_FINAL_RESULT(a) { \ - memcpy(query.response+2, a, sizeof(a));\ - query.numBytes = 2+sizeof(a); \ - query.queryDone = 1; \ -} +#define SET_FINAL_RESULT(a) \ + { \ + memcpy(query.response + 2, a, sizeof(a)); \ + query.numBytes = 2 + sizeof(a); \ + query.queryDone = 1; \ + } static const u8 ConfigExit[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //static const u8 ConfigExit[7] = {0x5A, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}; -static const u8 noclue[7] = {0x5A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5A}; -static u8 queryMaskMode[7] = {0x5A, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x5A}; +static const u8 noclue[7] = {0x5A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5A}; +static u8 queryMaskMode[7] = {0x5A, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x5A}; //static const u8 DSNonNativeMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const u8 setMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static const u8 setMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // DS2 -static const u8 queryModelDS2[7] = {0x5A, 0x03, 0x02, 0x00, 0x02, 0x01, 0x00}; +static const u8 queryModelDS2[7] = {0x5A, 0x03, 0x02, 0x00, 0x02, 0x01, 0x00}; // DS1 -static const u8 queryModelDS1[7] = {0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00}; +static const u8 queryModelDS1[7] = {0x5A, 0x01, 0x02, 0x00, 0x02, 0x01, 0x00}; -static const u8 queryAct[2][7] = {{0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, - {0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14}}; +static const u8 queryAct[2][7] = {{0x5A, 0x00, 0x00, 0x01, 0x02, 0x00, 0x0A}, + {0x5A, 0x00, 0x00, 0x01, 0x01, 0x01, 0x14}}; -static const u8 queryComb[7] = {0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}; +static const u8 queryComb[7] = {0x5A, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00}; -static const u8 queryMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static const u8 queryMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static const u8 setNativeMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A}; +static const u8 setNativeMode[7] = {0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A}; #ifdef _MSC_VER // Implements a couple of the hacks that affect whatever top-level window // the GS viewport belongs to (title, screensaver) -ExtraWndProcResult TitleHackWndProc(HWND hWndTop, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - switch (uMsg) { - case WM_SETTEXT: - if (config.saveStateTitle) { - wchar_t text[200]; - int len; - if (IsWindowUnicode(hWndTop)) { - len = wcslen((wchar_t*) lParam); - if (len < sizeof(text)/sizeof(wchar_t)) wcscpy(text, (wchar_t*) lParam); - } - else { - len = MultiByteToWideChar(CP_ACP, 0, (char*) lParam, -1, text, sizeof(text)/sizeof(wchar_t)); - } - if (len > 0 && len < 150 && !wcsstr(text, L" | State(Lilypad) ")) { - wsprintfW(text+len, L" | State(Lilypad) %i", saveStateIndex); - SetWindowText(hWndTop, text); - return NO_WND_PROC; - } - } - break; - case WM_SYSCOMMAND: - if ((wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) && config.disableScreenSaver) - return NO_WND_PROC; - break; - default: - break; - } - return CONTINUE_BLISSFULLY; +ExtraWndProcResult TitleHackWndProc(HWND hWndTop, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) +{ + switch (uMsg) { + case WM_SETTEXT: + if (config.saveStateTitle) { + wchar_t text[200]; + int len; + if (IsWindowUnicode(hWndTop)) { + len = wcslen((wchar_t *)lParam); + if (len < sizeof(text) / sizeof(wchar_t)) + wcscpy(text, (wchar_t *)lParam); + } else { + len = MultiByteToWideChar(CP_ACP, 0, (char *)lParam, -1, text, sizeof(text) / sizeof(wchar_t)); + } + if (len > 0 && len < 150 && !wcsstr(text, L" | State(Lilypad) ")) { + wsprintfW(text + len, L" | State(Lilypad) %i", saveStateIndex); + SetWindowText(hWndTop, text); + return NO_WND_PROC; + } + } + break; + case WM_SYSCOMMAND: + if ((wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER) && config.disableScreenSaver) + return NO_WND_PROC; + break; + default: + break; + } + return CONTINUE_BLISSFULLY; } // Useful sequence before changing into active/inactive state. // Handles hooking/unhooking of mouse and KB and also mouse cursor visibility. // towardsActive==true indicates we're gaining activity (on focus etc), false is for losing activity (on close, kill focus, etc). -void PrepareActivityState(bool towardsActive) { - if (!towardsActive) - ReleaseModifierKeys(); - activeWindow = towardsActive; - UpdateEnabledDevices(); +void PrepareActivityState(bool towardsActive) +{ + if (!towardsActive) + ReleaseModifierKeys(); + activeWindow = towardsActive; + UpdateEnabledDevices(); } // responsible for monitoring device addition/removal, focus changes, and viewport closures. -ExtraWndProcResult StatusWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - switch (uMsg) { - case WMA_FORCE_UPDATE: - if (wParam == FORCE_UPDATE_WPARAM && lParam == FORCE_UPDATE_LPARAM) { - if (updateQueued) { - updateQueued = 0; - Update(5, 0); - } - return NO_WND_PROC; - } - case WM_DEVICECHANGE: - if (wParam == DBT_DEVNODES_CHANGED) { - UpdateEnabledDevices(1); - } - break; - case WM_ACTIVATE: - // Release any buttons PCSX2 may think are down when - // losing/gaining focus. - // Note - I never managed to see this case entered, but SET/KILLFOCUS are entered. - avih 2014-04-16 - PrepareActivityState(LOWORD(wParam) != WA_INACTIVE); - break; - case WM_CLOSE: - if (config.closeHacks & 1) { - QueueKeyEvent(VK_ESCAPE, KEYPRESS); - return NO_WND_PROC; - } - else if (config.closeHacks & 2) { - ExitProcess(0); - return NO_WND_PROC; - } - break; - case WM_DESTROY: - QueueKeyEvent(VK_ESCAPE, KEYPRESS); - break; - case WM_KILLFOCUS: - PrepareActivityState(false); - break; - case WM_SETFOCUS: - PrepareActivityState(true); - break; - default: - break; - } - return CONTINUE_BLISSFULLY; +ExtraWndProcResult StatusWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) +{ + switch (uMsg) { + case WMA_FORCE_UPDATE: + if (wParam == FORCE_UPDATE_WPARAM && lParam == FORCE_UPDATE_LPARAM) { + if (updateQueued) { + updateQueued = 0; + Update(5, 0); + } + return NO_WND_PROC; + } + case WM_DEVICECHANGE: + if (wParam == DBT_DEVNODES_CHANGED) { + UpdateEnabledDevices(1); + } + break; + case WM_ACTIVATE: + // Release any buttons PCSX2 may think are down when + // losing/gaining focus. + // Note - I never managed to see this case entered, but SET/KILLFOCUS are entered. - avih 2014-04-16 + PrepareActivityState(LOWORD(wParam) != WA_INACTIVE); + break; + case WM_CLOSE: + if (config.closeHacks & 1) { + QueueKeyEvent(VK_ESCAPE, KEYPRESS); + return NO_WND_PROC; + } else if (config.closeHacks & 2) { + ExitProcess(0); + return NO_WND_PROC; + } + break; + case WM_DESTROY: + QueueKeyEvent(VK_ESCAPE, KEYPRESS); + break; + case WM_KILLFOCUS: + PrepareActivityState(false); + break; + case WM_SETFOCUS: + PrepareActivityState(true); + break; + default: + break; + } + return CONTINUE_BLISSFULLY; } // All that's needed to force hiding the cursor in the proper thread. // Could have a special case elsewhere, but this make sure it's called // only once, rather than repeatedly. -ExtraWndProcResult HideCursorProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - ShowCursor(0); - return CONTINUE_BLISSFULLY_AND_RELEASE_PROC; +ExtraWndProcResult HideCursorProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) +{ + ShowCursor(0); + return CONTINUE_BLISSFULLY_AND_RELEASE_PROC; } char restoreFullScreen = 0; // This hack sends ALT+ENTER to the window to toggle fullscreen. // PCSX2 doesn't need it (it exits full screen on ESC on its own). -DWORD WINAPI MaximizeWindowThreadProc(void *lpParameter) { - Sleep(100); - keybd_event(VK_LMENU, MapVirtualKey(VK_LMENU, MAPVK_VK_TO_VSC), 0, 0); - keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC), 0, 0); - Sleep(10); - keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); - keybd_event(VK_LMENU, MapVirtualKey(VK_LMENU, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); - return 0; +DWORD WINAPI MaximizeWindowThreadProc(void *lpParameter) +{ + Sleep(100); + keybd_event(VK_LMENU, MapVirtualKey(VK_LMENU, MAPVK_VK_TO_VSC), 0, 0); + keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC), 0, 0); + Sleep(10); + keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); + keybd_event(VK_LMENU, MapVirtualKey(VK_LMENU, MAPVK_VK_TO_VSC), KEYEVENTF_KEYUP, 0); + return 0; } #endif -void CALLBACK PADconfigure() { - if (openCount) { - return; - } - Configure(); +void CALLBACK PADconfigure() +{ + if (openCount) { + return; + } + Configure(); } #ifdef _MSC_VER -DWORD WINAPI RenameWindowThreadProc(void *lpParameter) { - wchar_t newTitle[200]; - if (hWndTop) { - int len = GetWindowTextW(hWndTop, newTitle, 200); - if (len > 0 && len < 199) { - wchar_t *end; - if (end = wcsstr(newTitle, L" | State ")) *end = 0; - SetWindowTextW(hWndTop, newTitle); - } - } - return 0; +DWORD WINAPI RenameWindowThreadProc(void *lpParameter) +{ + wchar_t newTitle[200]; + if (hWndTop) { + int len = GetWindowTextW(hWndTop, newTitle, 200); + if (len > 0 && len < 199) { + wchar_t *end; + if (end = wcsstr(newTitle, L" | State ")) + *end = 0; + SetWindowTextW(hWndTop, newTitle); + } + } + return 0; } -void SaveStateChanged() { - if (config.saveStateTitle) { - // GSDX only checks its window's message queue at certain points or something, so - // have to do this in another thread to prevent deadlock. - HANDLE hThread = CreateThread(0, 0, RenameWindowThreadProc, 0, 0, 0); - if (hThread) CloseHandle(hThread); - } +void SaveStateChanged() +{ + if (config.saveStateTitle) { + // GSDX only checks its window's message queue at certain points or something, so + // have to do this in another thread to prevent deadlock. + HANDLE hThread = CreateThread(0, 0, RenameWindowThreadProc, 0, 0, 0); + if (hThread) + CloseHandle(hThread); + } } #endif -s32 CALLBACK PADopen(void *pDsp) { - if (openCount++) return 0; - DEBUG_TEXT_OUT("LilyPad opened\n\n"); +s32 CALLBACK PADopen(void *pDsp) +{ + if (openCount++) + return 0; + DEBUG_TEXT_OUT("LilyPad opened\n\n"); - miceEnabled = !config.mouseUnfocus; + miceEnabled = !config.mouseUnfocus; #ifdef _MSC_VER - if (!hWnd) { - if (IsWindow((HWND)pDsp)) { - hWnd = (HWND) pDsp; - } - else if (pDsp && !IsBadReadPtr(pDsp, 4) && IsWindow(*(HWND*) pDsp)) { - hWnd = *(HWND*) pDsp; - } - else { - openCount = 0; - MessageBoxA(GetActiveWindow(), - "Invalid Window handle passed to LilyPad.\n" - "\n" - "Either your emulator or gs plugin is buggy,\n" - "Despite the fact the emulator is about to\n" - "blame LilyPad for failing to initialize.", - "Non-LilyPad Error", MB_OK | MB_ICONERROR); - return -1; - } - hWndTop = hWnd; - while (GetWindowLong (hWndTop, GWL_STYLE) & WS_CHILD) - hWndTop = GetParent (hWndTop); + if (!hWnd) { + if (IsWindow((HWND)pDsp)) { + hWnd = (HWND)pDsp; + } else if (pDsp && !IsBadReadPtr(pDsp, 4) && IsWindow(*(HWND *)pDsp)) { + hWnd = *(HWND *)pDsp; + } else { + openCount = 0; + MessageBoxA(GetActiveWindow(), + "Invalid Window handle passed to LilyPad.\n" + "\n" + "Either your emulator or gs plugin is buggy,\n" + "Despite the fact the emulator is about to\n" + "blame LilyPad for failing to initialize.", + "Non-LilyPad Error", MB_OK | MB_ICONERROR); + return -1; + } + hWndTop = hWnd; + while (GetWindowLong(hWndTop, GWL_STYLE) & WS_CHILD) + hWndTop = GetParent(hWndTop); - if (!hWndGSProc.SetWndHandle(hWnd)) { - openCount = 0; - return -1; - } + if (!hWndGSProc.SetWndHandle(hWnd)) { + openCount = 0; + return -1; + } - // Implements most hacks, as well as enabling/disabling mouse - // capture when focus changes. - updateQueued = 0; - hWndGSProc.Eat(StatusWndProc, 0); + // Implements most hacks, as well as enabling/disabling mouse + // capture when focus changes. + updateQueued = 0; + hWndGSProc.Eat(StatusWndProc, 0); - if(hWnd != hWndTop) { - if (!hWndTopProc.SetWndHandle(hWndTop)) { - openCount = 0; - return -1; - } - hWndTopProc.Eat(TitleHackWndProc, 0); - } - else - hWndGSProc.Eat(TitleHackWndProc, 0); + if (hWnd != hWndTop) { + if (!hWndTopProc.SetWndHandle(hWndTop)) { + openCount = 0; + return -1; + } + hWndTopProc.Eat(TitleHackWndProc, 0); + } else + hWndGSProc.Eat(TitleHackWndProc, 0); - if (config.forceHide) { - hWndGSProc.Eat(HideCursorProc, 0); - } - SaveStateChanged(); + if (config.forceHide) { + hWndGSProc.Eat(HideCursorProc, 0); + } + SaveStateChanged(); - windowThreadId = GetWindowThreadProcessId(hWndTop, 0); - } + windowThreadId = GetWindowThreadProcessId(hWndTop, 0); + } - if (restoreFullScreen) { - if (!IsWindowMaximized(hWndTop)) { - HANDLE hThread = CreateThread(0, 0, MaximizeWindowThreadProc, hWndTop, 0, 0); - if (hThread) CloseHandle(hThread); - } - restoreFullScreen = 0; - } + if (restoreFullScreen) { + if (!IsWindowMaximized(hWndTop)) { + HANDLE hThread = CreateThread(0, 0, MaximizeWindowThreadProc, hWndTop, 0, 0); + if (hThread) + CloseHandle(hThread); + } + restoreFullScreen = 0; + } #endif - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - memset(&pads[port][slot].sum, 0, sizeof(pads[port][slot].sum)); - memset(&pads[port][slot].lockedSum, 0, sizeof(pads[port][slot].lockedSum)); - pads[port][slot].lockedState = 0; - } - } + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + memset(&pads[port][slot].sum, 0, sizeof(pads[port][slot].sum)); + memset(&pads[port][slot].lockedSum, 0, sizeof(pads[port][slot].lockedSum)); + pads[port][slot].lockedState = 0; + } + } #ifdef _MSC_VER - // I'd really rather use this line, but GetActiveWindow() does not have complete specs. - // It *seems* to return null when no window from this thread has focus, but the - // Microsoft specs seem to imply it returns the window from this thread that would have focus, - // if any window did (topmost in this thread?). Which isn't what I want, and doesn't seem - // to be what it actually does. - // activeWindow = GetActiveWindow() == hWnd; +// I'd really rather use this line, but GetActiveWindow() does not have complete specs. +// It *seems* to return null when no window from this thread has focus, but the +// Microsoft specs seem to imply it returns the window from this thread that would have focus, +// if any window did (topmost in this thread?). Which isn't what I want, and doesn't seem +// to be what it actually does. +// activeWindow = GetActiveWindow() == hWnd; - // activeWindow = (GetAncestor(hWnd, GA_ROOT) == GetAncestor(GetForegroundWindow(), GA_ROOT)); +// activeWindow = (GetAncestor(hWnd, GA_ROOT) == GetAncestor(GetForegroundWindow(), GA_ROOT)); #else - // Not used so far - GSdsp = *(Display**)pDsp; - GSwin = (Window)*(((uptr*)pDsp)+1); + // Not used so far + GSdsp = *(Display **)pDsp; + GSwin = (Window) * (((uptr *)pDsp) + 1); #endif - activeWindow = 1; - UpdateEnabledDevices(); - return 0; + activeWindow = 1; + UpdateEnabledDevices(); + return 0; } -void CALLBACK PADclose() { - if (openCount && !--openCount) { - DEBUG_TEXT_OUT("LilyPad closed\n\n"); +void CALLBACK PADclose() +{ + if (openCount && !--openCount) { + DEBUG_TEXT_OUT("LilyPad closed\n\n"); #ifdef _MSC_VER - updateQueued = 0; - hWndGSProc.Release(); - hWndTopProc.Release(); - dm->ReleaseInput(); - hWnd = 0; - hWndTop = 0; + updateQueued = 0; + hWndGSProc.Release(); + hWndTopProc.Release(); + dm->ReleaseInput(); + hWnd = 0; + hWndTop = 0; #else - R_ClearKeyQueue(); + R_ClearKeyQueue(); #endif - ClearKeyQueue(); - } + ClearKeyQueue(); + } } -u8 CALLBACK PADstartPoll(int port) { - DEBUG_NEW_SET(); - port--; - if ((unsigned int)port <= 1 && pads[port][slots[port]].enabled) { - query.queryDone = 0; - query.port = port; - query.slot = slots[port]; - query.numBytes = 2; - query.lastByte = 0; - DEBUG_IN(port); - DEBUG_OUT(0xFF); - DEBUG_IN(slots[port]); - DEBUG_OUT(pads[port][slots[port]].enabled); - return 0xFF; - } - else { - query.queryDone = 1; - query.numBytes = 0; - query.lastByte = 1; - DEBUG_IN(0); - DEBUG_OUT(0); - DEBUG_IN(port); - DEBUG_OUT(0); - return 0; - } +u8 CALLBACK PADstartPoll(int port) +{ + DEBUG_NEW_SET(); + port--; + if ((unsigned int)port <= 1 && pads[port][slots[port]].enabled) { + query.queryDone = 0; + query.port = port; + query.slot = slots[port]; + query.numBytes = 2; + query.lastByte = 0; + DEBUG_IN(port); + DEBUG_OUT(0xFF); + DEBUG_IN(slots[port]); + DEBUG_OUT(pads[port][slots[port]].enabled); + return 0xFF; + } else { + query.queryDone = 1; + query.numBytes = 0; + query.lastByte = 1; + DEBUG_IN(0); + DEBUG_OUT(0); + DEBUG_IN(port); + DEBUG_OUT(0); + return 0; + } } -inline int IsDualshock2(u8 port, u8 slot) { - return config.padConfigs[query.port][query.slot].type == Dualshock2Pad || - (config.padConfigs[query.port][query.slot].type == GuitarPad && config.GH2); +inline int IsDualshock2(u8 port, u8 slot) +{ + return config.padConfigs[query.port][query.slot].type == Dualshock2Pad || + (config.padConfigs[query.port][query.slot].type == GuitarPad && config.GH2); } -u8 CALLBACK PADpoll(u8 value) { - DEBUG_IN(value); - if (query.lastByte+1 >= query.numBytes) { - DEBUG_OUT(0); - return 0; - } - if (query.lastByte && query.queryDone) { - DEBUG_OUT(query.response[1+query.lastByte]); - return query.response[++query.lastByte]; - } +u8 CALLBACK PADpoll(u8 value) +{ + DEBUG_IN(value); + if (query.lastByte + 1 >= query.numBytes) { + DEBUG_OUT(0); + return 0; + } + if (query.lastByte && query.queryDone) { + DEBUG_OUT(query.response[1 + query.lastByte]); + return query.response[++query.lastByte]; + } - int i; - Pad *pad = &pads[query.port][query.slot]; - if (query.lastByte == 0) { - query.lastByte++; - query.currentCommand = value; - switch(value) { - // CONFIG_MODE - case 0x43: - if (pad->config) { - if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) { - pad->mode = MODE_ANALOG; - } - // In config mode. Might not actually be leaving it. - SET_RESULT(ConfigExit); - DEBUG_OUT(0xF3); - return 0xF3; - } - // READ_DATA_AND_VIBRATE - case 0x42: - query.response[2] = 0x5A; - { - Update(query.port, query.slot); - ButtonSum *sum = &pad->sum; + int i; + Pad *pad = &pads[query.port][query.slot]; + if (query.lastByte == 0) { + query.lastByte++; + query.currentCommand = value; + switch (value) { + // CONFIG_MODE + case 0x43: + if (pad->config) { + if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) { + pad->mode = MODE_ANALOG; + } + // In config mode. Might not actually be leaving it. + SET_RESULT(ConfigExit); + DEBUG_OUT(0xF3); + return 0xF3; + } + // READ_DATA_AND_VIBRATE + case 0x42: + query.response[2] = 0x5A; + { + Update(query.port, query.slot); + ButtonSum *sum = &pad->sum; - u8 b1 = 0xFF, b2 = 0xFF; - for (i = 0; i<4; i++) { - b1 -= (sum->buttons[i] > 0) << i; - } - for (i = 0; i<8; i++) { - b2 -= (sum->buttons[i+4] > 0) << i; - } + u8 b1 = 0xFF, b2 = 0xFF; + for (i = 0; i < 4; i++) { + b1 -= (sum->buttons[i] > 0) << i; + } + for (i = 0; i < 8; i++) { + b2 -= (sum->buttons[i + 4] > 0) << i; + } - if (config.padConfigs[query.port][query.slot].type == GuitarPad && !config.GH2) { - sum->buttons[15] = 255; - // Not sure about this. Forces wammy to be from 0 to 0x7F. - // if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0; - } + if (config.padConfigs[query.port][query.slot].type == GuitarPad && !config.GH2) { + sum->buttons[15] = 255; + // Not sure about this. Forces wammy to be from 0 to 0x7F. + // if (sum->sticks[2].vert > 0) sum->sticks[2].vert = 0; + } - for (i = 4; i<8; i++) { - b1 -= (sum->buttons[i+8] > 0) << i; - } + for (i = 4; i < 8; i++) { + b1 -= (sum->buttons[i + 8] > 0) << i; + } - //Left, Right and Down are always pressed on Pop'n Music controller. - if (config.padConfigs[query.port][query.slot].type == PopnPad) - b1=b1 & 0x1f; + //Left, Right and Down are always pressed on Pop'n Music controller. + if (config.padConfigs[query.port][query.slot].type == PopnPad) + b1 = b1 & 0x1f; - query.response[3] = b1; - query.response[4] = b2; + query.response[3] = b1; + query.response[4] = b2; - query.numBytes = 5; - if (pad->mode != MODE_DIGITAL) { - query.response[5] = Cap((sum->sticks[0].horiz+255)/2); - query.response[6] = Cap((sum->sticks[0].vert+255)/2); - query.response[7] = Cap((sum->sticks[1].horiz+255)/2); - query.response[8] = Cap((sum->sticks[1].vert+255)/2); + query.numBytes = 5; + if (pad->mode != MODE_DIGITAL) { + query.response[5] = Cap((sum->sticks[0].horiz + 255) / 2); + query.response[6] = Cap((sum->sticks[0].vert + 255) / 2); + query.response[7] = Cap((sum->sticks[1].horiz + 255) / 2); + query.response[8] = Cap((sum->sticks[1].vert + 255) / 2); - query.numBytes = 9; - if (pad->mode != MODE_ANALOG) { - // Good idea? No clue. - //query.response[3] &= pad->mask[0]; - //query.response[4] &= pad->mask[1]; + query.numBytes = 9; + if (pad->mode != MODE_ANALOG) { + // Good idea? No clue. + //query.response[3] &= pad->mask[0]; + //query.response[4] &= pad->mask[1]; - // No need to cap these, already done int CapSum(). - query.response[9] = (unsigned char)sum->buttons[13]; //D-pad right - query.response[10] = (unsigned char)sum->buttons[15]; //D-pad left - query.response[11] = (unsigned char)sum->buttons[12]; //D-pad up - query.response[12] = (unsigned char)sum->buttons[14]; //D-pad down + // No need to cap these, already done int CapSum(). + query.response[9] = (unsigned char)sum->buttons[13]; //D-pad right + query.response[10] = (unsigned char)sum->buttons[15]; //D-pad left + query.response[11] = (unsigned char)sum->buttons[12]; //D-pad up + query.response[12] = (unsigned char)sum->buttons[14]; //D-pad down - query.response[13] = (unsigned char) sum->buttons[8]; - query.response[14] = (unsigned char) sum->buttons[9]; - query.response[15] = (unsigned char) sum->buttons[10]; - query.response[16] = (unsigned char) sum->buttons[11]; - query.response[17] = (unsigned char) sum->buttons[6]; - query.response[18] = (unsigned char) sum->buttons[7]; - query.response[19] = (unsigned char) sum->buttons[4]; - query.response[20] = (unsigned char) sum->buttons[5]; - query.numBytes = 21; - } - } - } + query.response[13] = (unsigned char)sum->buttons[8]; + query.response[14] = (unsigned char)sum->buttons[9]; + query.response[15] = (unsigned char)sum->buttons[10]; + query.response[16] = (unsigned char)sum->buttons[11]; + query.response[17] = (unsigned char)sum->buttons[6]; + query.response[18] = (unsigned char)sum->buttons[7]; + query.response[19] = (unsigned char)sum->buttons[4]; + query.response[20] = (unsigned char)sum->buttons[5]; + query.numBytes = 21; + } + } + } - query.lastByte=1; - DEBUG_OUT(pad->mode); - return pad->mode; - // SET_VREF_PARAM - case 0x40: - SET_FINAL_RESULT(noclue); - break; - // QUERY_DS2_ANALOG_MODE - case 0x41: - // Right? Wrong? No clue. - if (pad->mode == MODE_DIGITAL) { - queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0; - queryMaskMode[6] = 0x00; - } - else { - queryMaskMode[1] = pad->umask[0]; - queryMaskMode[2] = pad->umask[1]; - queryMaskMode[3] = 0x03; - // Not entirely sure about this. - //queryMaskMode[3] = 0x01 | (pad->mode == MODE_DS2_NATIVE)*2; - queryMaskMode[6] = 0x5A; - } - SET_FINAL_RESULT(queryMaskMode); - break; - // SET_MODE_AND_LOCK - case 0x44: - SET_RESULT(setMode); - ResetVibrate(query.port, query.slot); - break; - // QUERY_MODEL_AND_MODE - case 0x45: - if (IsDualshock2(query.port, query.slot)) { - SET_FINAL_RESULT(queryModelDS2) - } - else { - SET_FINAL_RESULT(queryModelDS1); - } - // Not digital mode. - query.response[5] = (pad->mode & 0xF) != 1; - break; - // QUERY_ACT - case 0x46: - SET_RESULT(queryAct[0]); - break; - // QUERY_COMB - case 0x47: - SET_FINAL_RESULT(queryComb); - break; - // QUERY_MODE - case 0x4C: - SET_RESULT(queryMode); - break; - // VIBRATION_TOGGLE - case 0x4D: - memcpy(query.response+2, pad->vibrate, 7); - query.numBytes = 9; - ResetVibrate(query.port, query.slot); - break; - // SET_DS2_NATIVE_MODE - case 0x4F: - if (IsDualshock2(query.port, query.slot)) { - SET_RESULT(setNativeMode); - } - else { - SET_FINAL_RESULT(setNativeMode); - } - break; - default: - query.numBytes = 0; - query.queryDone = 1; - break; - } - DEBUG_OUT(0xF3); - return 0xF3; - } - else { - query.lastByte++; - switch (query.currentCommand) { - // READ_DATA_AND_VIBRATE - case 0x42: - if (query.lastByte == pad->vibrateI[0]) { - SetVibrate(query.port, query.slot, 1, 255*(value&1)); - } - else if (query.lastByte == pad->vibrateI[1]) { - SetVibrate(query.port, query.slot, 0, value); - } - break; - // CONFIG_MODE - case 0x43: - if (query.lastByte == 3) { - query.queryDone = 1; - pad->config = value; - } - break; - // SET_MODE_AND_LOCK - case 0x44: - if (query.lastByte == 3 && value < 2) { - static const u8 modes[2] = {MODE_DIGITAL, MODE_ANALOG}; - pad->mode = modes[value]; - } - else if (query.lastByte == 4) { - if (value == 3) { - pad->modeLock = 3; - } - else { - pad->modeLock = 0; - if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) { - pad->mode = MODE_ANALOG; - } - } - query.queryDone = 1; - } - break; - // QUERY_ACT - case 0x46: - if (query.lastByte == 3) { - if (value<2) SET_RESULT(queryAct[value]) - // bunch of 0's - // else SET_RESULT(setMode); - query.queryDone = 1; - } - break; - // QUERY_MODE - case 0x4C: - if (query.lastByte == 3 && value<2) { - query.response[6] = 4+value*3; - query.queryDone = 1; - } - // bunch of 0's - //else data = setMode; - break; - // VIBRATION_TOGGLE - case 0x4D: - if (query.lastByte>=3) { - if (value == 0) { - pad->vibrateI[0] = (u8)query.lastByte; - } - else if (value == 1) { - pad->vibrateI[1] = (u8)query.lastByte; - } - pad->vibrate[query.lastByte-2] = value; - } - break; - // SET_DS2_NATIVE_MODE - case 0x4F: - if (query.lastByte == 3 || query.lastByte == 4) { - pad->umask[query.lastByte-3] = value; - } - else if (query.lastByte == 5) { - if (!(value & 1)) { - pad->mode = MODE_DIGITAL; - } - else if (!(value & 2)) { - pad->mode = MODE_ANALOG; - } - else { - pad->mode = MODE_DS2_NATIVE; - } - } - break; - default: - DEBUG_OUT(0); - return 0; - } - DEBUG_OUT(query.response[query.lastByte]); - return query.response[query.lastByte]; - } + query.lastByte = 1; + DEBUG_OUT(pad->mode); + return pad->mode; + // SET_VREF_PARAM + case 0x40: + SET_FINAL_RESULT(noclue); + break; + // QUERY_DS2_ANALOG_MODE + case 0x41: + // Right? Wrong? No clue. + if (pad->mode == MODE_DIGITAL) { + queryMaskMode[1] = queryMaskMode[2] = queryMaskMode[3] = 0; + queryMaskMode[6] = 0x00; + } else { + queryMaskMode[1] = pad->umask[0]; + queryMaskMode[2] = pad->umask[1]; + queryMaskMode[3] = 0x03; + // Not entirely sure about this. + //queryMaskMode[3] = 0x01 | (pad->mode == MODE_DS2_NATIVE)*2; + queryMaskMode[6] = 0x5A; + } + SET_FINAL_RESULT(queryMaskMode); + break; + // SET_MODE_AND_LOCK + case 0x44: + SET_RESULT(setMode); + ResetVibrate(query.port, query.slot); + break; + // QUERY_MODEL_AND_MODE + case 0x45: + if (IsDualshock2(query.port, query.slot)) { + SET_FINAL_RESULT(queryModelDS2) + } else { + SET_FINAL_RESULT(queryModelDS1); + } + // Not digital mode. + query.response[5] = (pad->mode & 0xF) != 1; + break; + // QUERY_ACT + case 0x46: + SET_RESULT(queryAct[0]); + break; + // QUERY_COMB + case 0x47: + SET_FINAL_RESULT(queryComb); + break; + // QUERY_MODE + case 0x4C: + SET_RESULT(queryMode); + break; + // VIBRATION_TOGGLE + case 0x4D: + memcpy(query.response + 2, pad->vibrate, 7); + query.numBytes = 9; + ResetVibrate(query.port, query.slot); + break; + // SET_DS2_NATIVE_MODE + case 0x4F: + if (IsDualshock2(query.port, query.slot)) { + SET_RESULT(setNativeMode); + } else { + SET_FINAL_RESULT(setNativeMode); + } + break; + default: + query.numBytes = 0; + query.queryDone = 1; + break; + } + DEBUG_OUT(0xF3); + return 0xF3; + } else { + query.lastByte++; + switch (query.currentCommand) { + // READ_DATA_AND_VIBRATE + case 0x42: + if (query.lastByte == pad->vibrateI[0]) { + SetVibrate(query.port, query.slot, 1, 255 * (value & 1)); + } else if (query.lastByte == pad->vibrateI[1]) { + SetVibrate(query.port, query.slot, 0, value); + } + break; + // CONFIG_MODE + case 0x43: + if (query.lastByte == 3) { + query.queryDone = 1; + pad->config = value; + } + break; + // SET_MODE_AND_LOCK + case 0x44: + if (query.lastByte == 3 && value < 2) { + static const u8 modes[2] = {MODE_DIGITAL, MODE_ANALOG}; + pad->mode = modes[value]; + } else if (query.lastByte == 4) { + if (value == 3) { + pad->modeLock = 3; + } else { + pad->modeLock = 0; + if (pad->mode == MODE_DIGITAL && config.padConfigs[query.port][query.slot].autoAnalog && !ps2e) { + pad->mode = MODE_ANALOG; + } + } + query.queryDone = 1; + } + break; + // QUERY_ACT + case 0x46: + if (query.lastByte == 3) { + if (value < 2) + SET_RESULT(queryAct[value]) + // bunch of 0's + // else SET_RESULT(setMode); + query.queryDone = 1; + } + break; + // QUERY_MODE + case 0x4C: + if (query.lastByte == 3 && value < 2) { + query.response[6] = 4 + value * 3; + query.queryDone = 1; + } + // bunch of 0's + //else data = setMode; + break; + // VIBRATION_TOGGLE + case 0x4D: + if (query.lastByte >= 3) { + if (value == 0) { + pad->vibrateI[0] = (u8)query.lastByte; + } else if (value == 1) { + pad->vibrateI[1] = (u8)query.lastByte; + } + pad->vibrate[query.lastByte - 2] = value; + } + break; + // SET_DS2_NATIVE_MODE + case 0x4F: + if (query.lastByte == 3 || query.lastByte == 4) { + pad->umask[query.lastByte - 3] = value; + } else if (query.lastByte == 5) { + if (!(value & 1)) { + pad->mode = MODE_DIGITAL; + } else if (!(value & 2)) { + pad->mode = MODE_ANALOG; + } else { + pad->mode = MODE_DS2_NATIVE; + } + } + break; + default: + DEBUG_OUT(0); + return 0; + } + DEBUG_OUT(query.response[query.lastByte]); + return query.response[query.lastByte]; + } } // returns: 1 if supports pad1 // 2 if supports pad2 // 3 if both are supported -u32 CALLBACK PADquery() { - return 3; +u32 CALLBACK PADquery() +{ + return 3; } #ifdef _MSC_VER -INT_PTR CALLBACK AboutDialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - if (uMsg == WM_INITDIALOG) { - wchar_t idString[100]; - GetNameAndVersionString(idString); - SetDlgItemTextW(hWndDlg, IDC_VERSION, idString); - } - else if (uMsg == WM_COMMAND && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)) { - EndDialog(hWndDlg, 0); - return 1; - } - return 0; +INT_PTR CALLBACK AboutDialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WM_INITDIALOG) { + wchar_t idString[100]; + GetNameAndVersionString(idString); + SetDlgItemTextW(hWndDlg, IDC_VERSION, idString); + } else if (uMsg == WM_COMMAND && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)) { + EndDialog(hWndDlg, 0); + return 1; + } + return 0; } #endif -void CALLBACK PADabout() { +void CALLBACK PADabout() +{ #ifdef _MSC_VER - DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), 0, AboutDialogProc); + DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), 0, AboutDialogProc); #endif } -s32 CALLBACK PADtest() { - return 0; +s32 CALLBACK PADtest() +{ + return 0; } -keyEvent* CALLBACK PADkeyEvent() { - // If running both pads, ignore every other call. So if two keys pressed in same interval... - static char eventCount = 0; - eventCount++; - if (eventCount < openCount) { - return 0; - } - eventCount = 0; +keyEvent *CALLBACK PADkeyEvent() +{ + // If running both pads, ignore every other call. So if two keys pressed in same interval... + static char eventCount = 0; + eventCount++; + if (eventCount < openCount) { + return 0; + } + eventCount = 0; - Update(2, 0); - static keyEvent ev; - if (!GetQueuedKeyEvent(&ev)) return 0; + Update(2, 0); + static keyEvent ev; + if (!GetQueuedKeyEvent(&ev)) + return 0; #ifdef _MSC_VER - static char shiftDown = 0; - static char altDown = 0; - if (miceEnabled && (ev.key == VK_ESCAPE || (int)ev.key == -2) && ev.evt == KEYPRESS) { - // Disable mouse/KB hooks on escape (before going into paused mode). - // This is a hack, since PADclose (which is called on pause) should enevtually also deactivate the - // mouse/kb capture. In practice, WindowsMessagingMouse::Deactivate is called from PADclose, but doesn't - // manage to release the mouse, maybe due to the thread from which it's called or some - // state or somehow being too late. - // This explicitly triggers inactivity (releasing mouse/kb hooks) before PCSX2 starts to close the plugins. - // Regardless, the mouse/kb hooks will get re-enabled on resume if required without need for further hacks. + static char shiftDown = 0; + static char altDown = 0; + if (miceEnabled && (ev.key == VK_ESCAPE || (int)ev.key == -2) && ev.evt == KEYPRESS) { + // Disable mouse/KB hooks on escape (before going into paused mode). + // This is a hack, since PADclose (which is called on pause) should enevtually also deactivate the + // mouse/kb capture. In practice, WindowsMessagingMouse::Deactivate is called from PADclose, but doesn't + // manage to release the mouse, maybe due to the thread from which it's called or some + // state or somehow being too late. + // This explicitly triggers inactivity (releasing mouse/kb hooks) before PCSX2 starts to close the plugins. + // Regardless, the mouse/kb hooks will get re-enabled on resume if required without need for further hacks. - PrepareActivityState(false); - } + PrepareActivityState(false); + } - if ((ev.key == VK_ESCAPE || (int)ev.key == -2) && ev.evt == KEYPRESS && config.escapeFullscreenHack) { - static int t; - if ((int)ev.key != -2 && IsWindowMaximized(hWndTop)) { - t = timeGetTime(); - QueueKeyEvent(-2, KEYPRESS); - HANDLE hThread = CreateThread(0, 0, MaximizeWindowThreadProc, 0, 0, 0); - if (hThread) CloseHandle(hThread); - restoreFullScreen = 1; - return 0; - } - if (ev.key != VK_ESCAPE) { - if (timeGetTime() - t < 1000) { - QueueKeyEvent(-2, KEYPRESS); - return 0; - } - } - ev.key = VK_ESCAPE; - } + if ((ev.key == VK_ESCAPE || (int)ev.key == -2) && ev.evt == KEYPRESS && config.escapeFullscreenHack) { + static int t; + if ((int)ev.key != -2 && IsWindowMaximized(hWndTop)) { + t = timeGetTime(); + QueueKeyEvent(-2, KEYPRESS); + HANDLE hThread = CreateThread(0, 0, MaximizeWindowThreadProc, 0, 0, 0); + if (hThread) + CloseHandle(hThread); + restoreFullScreen = 1; + return 0; + } + if (ev.key != VK_ESCAPE) { + if (timeGetTime() - t < 1000) { + QueueKeyEvent(-2, KEYPRESS); + return 0; + } + } + ev.key = VK_ESCAPE; + } - if (ev.key == VK_F2 && ev.evt == KEYPRESS) { - saveStateIndex += 1 - 2*shiftDown; - saveStateIndex = (saveStateIndex+10)%10; - SaveStateChanged(); - } + if (ev.key == VK_F2 && ev.evt == KEYPRESS) { + saveStateIndex += 1 - 2 * shiftDown; + saveStateIndex = (saveStateIndex + 10) % 10; + SaveStateChanged(); + } - // So don't change skip mode on alt-F4. - if (ev.key == VK_F4 && altDown) { - return 0; - } + // So don't change skip mode on alt-F4. + if (ev.key == VK_F4 && altDown) { + return 0; + } - if (ev.key == VK_LSHIFT || ev.key == VK_RSHIFT || ev.key == VK_SHIFT) { - ev.key = VK_SHIFT; - shiftDown = (ev.evt == KEYPRESS); - } - else if (ev.key == VK_LCONTROL || ev.key == VK_RCONTROL) { - ev.key = VK_CONTROL; - } - else if (ev.key == VK_LMENU || ev.key == VK_RMENU || ev.key == VK_SHIFT) { - ev.key = VK_MENU; - altDown = (ev.evt == KEYPRESS); - } + if (ev.key == VK_LSHIFT || ev.key == VK_RSHIFT || ev.key == VK_SHIFT) { + ev.key = VK_SHIFT; + shiftDown = (ev.evt == KEYPRESS); + } else if (ev.key == VK_LCONTROL || ev.key == VK_RCONTROL) { + ev.key = VK_CONTROL; + } else if (ev.key == VK_LMENU || ev.key == VK_RMENU || ev.key == VK_SHIFT) { + ev.key = VK_MENU; + altDown = (ev.evt == KEYPRESS); + } #endif - return &ev; + return &ev; } -struct PadPluginFreezeData { +struct PadPluginFreezeData +{ char format[8]; // Currently all different versions are incompatible. // May split into major/minor with some compatibility rules. @@ -1527,25 +1564,26 @@ struct PadPluginFreezeData { QueryInfo query; }; -s32 CALLBACK PADfreeze(int mode, freezeData *data) { - if (!data) - { - printf("LilyPad savestate null pointer!\n"); - return -1; - } - - if (mode == FREEZE_SIZE) { - data->size = sizeof(PadPluginFreezeData); +s32 CALLBACK PADfreeze(int mode, freezeData *data) +{ + if (!data) { + printf("LilyPad savestate null pointer!\n"); + return -1; } - else if (mode == FREEZE_LOAD) { - PadPluginFreezeData &pdata = *(PadPluginFreezeData*)(data->data); + + if (mode == FREEZE_SIZE) { + data->size = sizeof(PadPluginFreezeData); + } else if (mode == FREEZE_LOAD) { + PadPluginFreezeData &pdata = *(PadPluginFreezeData *)(data->data); StopVibrate(); if (data->size != sizeof(PadPluginFreezeData) || pdata.version != PAD_SAVE_STATE_VERSION || - strcmp(pdata.format, "PadMode")) return 0; + strcmp(pdata.format, "PadMode")) + return 0; + + if (pdata.port >= 2) + return 0; - if( pdata.port >= 2 ) return 0; - query = pdata.query; if (pdata.query.slot < 4) { query = pdata.query; @@ -1553,8 +1591,8 @@ s32 CALLBACK PADfreeze(int mode, freezeData *data) { // Tales of the Abyss - pad fix // - restore data for both ports - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { u8 mode = pdata.padData[port][slot].mode; if (mode != MODE_DIGITAL && mode != MODE_ANALOG && mode != MODE_DS2_NATIVE) { @@ -1562,16 +1600,16 @@ s32 CALLBACK PADfreeze(int mode, freezeData *data) { } // Not sure if the cast is strictly necessary, but feel safest with it there... - *(PadFreezeData*)&pads[port][slot] = pdata.padData[port][slot]; + *(PadFreezeData *)&pads[port][slot] = pdata.padData[port][slot]; } if (pdata.slot[port] < 4) - slots[port] = pdata.slot[port]; + slots[port] = pdata.slot[port]; } - } - else if (mode == FREEZE_SAVE) { - if (data->size != sizeof(PadPluginFreezeData)) return 0; - PadPluginFreezeData &pdata = *(PadPluginFreezeData*)(data->data); + } else if (mode == FREEZE_SAVE) { + if (data->size != sizeof(PadPluginFreezeData)) + return 0; + PadPluginFreezeData &pdata = *(PadPluginFreezeData *)(data->data); // Tales of the Abyss - pad fix @@ -1583,59 +1621,66 @@ s32 CALLBACK PADfreeze(int mode, freezeData *data) { pdata.port = 0; pdata.query = query; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { pdata.padData[port][slot] = pads[port][slot]; } pdata.slot[port] = slots[port]; } - } - else return -1; + } else + return -1; return 0; } -u32 CALLBACK PADreadPort1 (PadDataS* pads) { - PADstartPoll(1); - PADpoll(0x42); - memcpy(pads, query.response+1, 7); - pads->controllerType = pads[0].controllerType>>4; - memset (pads+7, 0, sizeof(PadDataS)-7); - return 0; +u32 CALLBACK PADreadPort1(PadDataS *pads) +{ + PADstartPoll(1); + PADpoll(0x42); + memcpy(pads, query.response + 1, 7); + pads->controllerType = pads[0].controllerType >> 4; + memset(pads + 7, 0, sizeof(PadDataS) - 7); + return 0; } -u32 CALLBACK PADreadPort2 (PadDataS* pads) { - PADstartPoll(2); - PADpoll(0x42); - memcpy(pads, query.response+1, 7); - pads->controllerType = pads->controllerType>>4; - memset (pads+7, 0, sizeof(PadDataS)-7); - return 0; +u32 CALLBACK PADreadPort2(PadDataS *pads) +{ + PADstartPoll(2); + PADpoll(0x42); + memcpy(pads, query.response + 1, 7); + pads->controllerType = pads->controllerType >> 4; + memset(pads + 7, 0, sizeof(PadDataS) - 7); + return 0; } -u32 CALLBACK PSEgetLibType() { - return 8; +u32 CALLBACK PSEgetLibType() +{ + return 8; } -u32 CALLBACK PSEgetLibVersion() { - return (VERSION & 0xFFFFFF); +u32 CALLBACK PSEgetLibVersion() +{ + return (VERSION & 0xFFFFFF); } -s32 CALLBACK PADqueryMtap(u8 port) { - port--; - if (port > 1) return 0; - return config.multitap[port]; +s32 CALLBACK PADqueryMtap(u8 port) +{ + port--; + if (port > 1) + return 0; + return config.multitap[port]; } -s32 CALLBACK PADsetSlot(u8 port, u8 slot) { - port--; - slot--; - if (port > 1 || slot > 3) { - return 0; - } - // Even if no pad there, record the slot, as it is the active slot regardless. - slots[port] = slot; - // First slot always allowed. - // return pads[port][slot].enabled | !slot; - return 1; +s32 CALLBACK PADsetSlot(u8 port, u8 slot) +{ + port--; + slot--; + if (port > 1 || slot > 3) { + return 0; + } + // Even if no pad there, record the slot, as it is the active slot regardless. + slots[port] = slot; + // First slot always allowed. + // return pads[port][slot].enabled | !slot; + return 1; } diff --git a/plugins/LilyPad/Linux/Config.cpp b/plugins/LilyPad/Linux/Config.cpp index 214bb54ea4..74243a4e2e 100644 --- a/plugins/LilyPad/Linux/Config.cpp +++ b/plugins/LilyPad/Linux/Config.cpp @@ -28,393 +28,411 @@ u8 ps2e = 0; #if 0 remove 0x10F0 to compute the cmd value -#define ID_SENSITIVITY 0x1007 -#define ID_LOCK_BUTTONS 0x10FC -#define ID_LOCK 0x10FD -#define ID_LOCK_DIRECTION 0x10FE -#define ID_MOUSE 0x10FF -#define ID_SELECT 0x1100 -#define ID_L3 0x1101 -#define ID_R3 0x1102 -#define ID_START 0x1103 -#define ID_DPAD_UP 0x1104 -#define ID_DPAD_RIGHT 0x1105 -#define ID_DPAD_DOWN 0x1106 -#define ID_DPAD_LEFT 0x1107 -#define ID_L2 0x1108 -#define ID_R2 0x1109 -#define ID_L1 0x110A -#define ID_R1 0x110B -#define ID_TRIANGLE 0x110C -#define ID_CIRCLE 0x110D -#define ID_CROSS 0x110E -#define ID_SQUARE 0x110F -#define ID_LSTICK_UP 0x1110 -#define ID_LSTICK_RIGHT 0x1111 -#define ID_LSTICK_DOWN 0x1112 -#define ID_LSTICK_LEFT 0x1113 -#define ID_RSTICK_UP 0x1114 -#define ID_RSTICK_RIGHT 0x1115 -#define ID_RSTICK_DOWN 0x1116 -#define ID_RSTICK_LEFT 0x1117 -#define ID_ANALOG 0x1118 -#define ID_DELETE 0x11FF -#define ID_DEBUG 0x1200 -#define ID_IGNORE 0x1201 -#define ID_CLEAR 0x1202 -#define ID_REFRESH 0x1202 -#define ID_SAVE 0x1204 -#define ID_LOAD 0x1205 -#define ID_BIG_MOTOR 0x120A -#define ID_SMALL_MOTOR 0x120B -#define ID_TEST 0x1300 -#define ID_CONTROLS 0x1301 -#define ID_FF 0x1304 +#define ID_SENSITIVITY 0x1007 +#define ID_LOCK_BUTTONS 0x10FC +#define ID_LOCK 0x10FD +#define ID_LOCK_DIRECTION 0x10FE +#define ID_MOUSE 0x10FF +#define ID_SELECT 0x1100 +#define ID_L3 0x1101 +#define ID_R3 0x1102 +#define ID_START 0x1103 +#define ID_DPAD_UP 0x1104 +#define ID_DPAD_RIGHT 0x1105 +#define ID_DPAD_DOWN 0x1106 +#define ID_DPAD_LEFT 0x1107 +#define ID_L2 0x1108 +#define ID_R2 0x1109 +#define ID_L1 0x110A +#define ID_R1 0x110B +#define ID_TRIANGLE 0x110C +#define ID_CIRCLE 0x110D +#define ID_CROSS 0x110E +#define ID_SQUARE 0x110F +#define ID_LSTICK_UP 0x1110 +#define ID_LSTICK_RIGHT 0x1111 +#define ID_LSTICK_DOWN 0x1112 +#define ID_LSTICK_LEFT 0x1113 +#define ID_RSTICK_UP 0x1114 +#define ID_RSTICK_RIGHT 0x1115 +#define ID_RSTICK_DOWN 0x1116 +#define ID_RSTICK_LEFT 0x1117 +#define ID_ANALOG 0x1118 +#define ID_DELETE 0x11FF +#define ID_DEBUG 0x1200 +#define ID_IGNORE 0x1201 +#define ID_CLEAR 0x1202 +#define ID_REFRESH 0x1202 +#define ID_SAVE 0x1204 +#define ID_LOAD 0x1205 +#define ID_BIG_MOTOR 0x120A +#define ID_SMALL_MOTOR 0x120B +#define ID_TEST 0x1300 +#define ID_CONTROLS 0x1301 +#define ID_FF 0x1304 #endif -struct GeneralSettingsBool { - const wchar_t *name; - unsigned int ControlId; - u8 defaultValue; +struct GeneralSettingsBool +{ + const wchar_t *name; + unsigned int ControlId; + u8 defaultValue; }; // XXX: I try to remove only gui stuff -void DeleteBinding(int port, int slot, Device *dev, Binding *b) { - fprintf(stderr, "delete binding %d:%d\n", port, slot); - Binding *bindings = dev->pads[port][slot].bindings; - int i = b - bindings; - memmove(bindings+i, bindings+i+1, sizeof(Binding) * (dev->pads[port][slot].numBindings - i - 1)); - dev->pads[port][slot].numBindings--; +void DeleteBinding(int port, int slot, Device *dev, Binding *b) +{ + fprintf(stderr, "delete binding %d:%d\n", port, slot); + Binding *bindings = dev->pads[port][slot].bindings; + int i = b - bindings; + memmove(bindings + i, bindings + i + 1, sizeof(Binding) * (dev->pads[port][slot].numBindings - i - 1)); + dev->pads[port][slot].numBindings--; } -void DeleteBinding(int port, int slot, Device *dev, ForceFeedbackBinding *b) { - ForceFeedbackBinding *bindings = dev->pads[port][slot].ffBindings; - int i = b - bindings; - memmove(bindings+i, bindings+i+1, sizeof(Binding) * (dev->pads[port][slot].numFFBindings - i - 1)); - dev->pads[port][slot].numFFBindings--; +void DeleteBinding(int port, int slot, Device *dev, ForceFeedbackBinding *b) +{ + ForceFeedbackBinding *bindings = dev->pads[port][slot].ffBindings; + int i = b - bindings; + memmove(bindings + i, bindings + i + 1, sizeof(Binding) * (dev->pads[port][slot].numFFBindings - i - 1)); + dev->pads[port][slot].numFFBindings--; } -int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int slot, int command, int sensitivity, int turbo, int deadZone) { - // Checks needed because I use this directly when loading bindings. - if (port > 1 || slot>3) { - return -1; - } - if (!sensitivity) sensitivity = BASE_SENSITIVITY; - if ((uid>>16) & (PSHBTN|TGLBTN)) { - deadZone = 0; - } - else if (!deadZone) { - if ((uid>>16) & PRESSURE_BTN) { - deadZone = 1; - } - else { - deadZone = DEFAULT_DEADZONE; - } - } - // Relative axes can have negative sensitivity. - else if (((uid>>16) & 0xFF) == RELAXIS) { - sensitivity = abs(sensitivity); - } - VirtualControl *c = dev->GetVirtualControl(uid); - if (!c) return -1; - // Add before deleting. Means I won't scroll up one line when scrolled down to bottom. - int controlIndex = c - dev->virtualControls; - int index = 0; - PadBindings *p = dev->pads[port]+slot; - p->bindings = (Binding*) realloc(p->bindings, (p->numBindings+1) * sizeof(Binding)); - for (index = p->numBindings; index > 0; index--) { - if (p->bindings[index-1].controlIndex < controlIndex) break; - p->bindings[index] = p->bindings[index-1]; - } - Binding *b = p->bindings+index; - p->numBindings++; - b->command = command; - b->controlIndex = controlIndex; - b->turbo = turbo; - b->sensitivity = sensitivity; - b->deadZone = deadZone; - // Where it appears in listview. - //int count = ListBoundCommand(port, slot, dev, b); +int BindCommand(Device *dev, unsigned int uid, unsigned int port, unsigned int slot, int command, int sensitivity, int turbo, int deadZone) +{ + // Checks needed because I use this directly when loading bindings. + if (port > 1 || slot > 3) { + return -1; + } + if (!sensitivity) + sensitivity = BASE_SENSITIVITY; + if ((uid >> 16) & (PSHBTN | TGLBTN)) { + deadZone = 0; + } else if (!deadZone) { + if ((uid >> 16) & PRESSURE_BTN) { + deadZone = 1; + } else { + deadZone = DEFAULT_DEADZONE; + } + } + // Relative axes can have negative sensitivity. + else if (((uid >> 16) & 0xFF) == RELAXIS) { + sensitivity = abs(sensitivity); + } + VirtualControl *c = dev->GetVirtualControl(uid); + if (!c) + return -1; + // Add before deleting. Means I won't scroll up one line when scrolled down to bottom. + int controlIndex = c - dev->virtualControls; + int index = 0; + PadBindings *p = dev->pads[port] + slot; + p->bindings = (Binding *)realloc(p->bindings, (p->numBindings + 1) * sizeof(Binding)); + for (index = p->numBindings; index > 0; index--) { + if (p->bindings[index - 1].controlIndex < controlIndex) + break; + p->bindings[index] = p->bindings[index - 1]; + } + Binding *b = p->bindings + index; + p->numBindings++; + b->command = command; + b->controlIndex = controlIndex; + b->turbo = turbo; + b->sensitivity = sensitivity; + b->deadZone = deadZone; + // Where it appears in listview. + //int count = ListBoundCommand(port, slot, dev, b); - int newBindingIndex = index; - index = 0; - while (index < p->numBindings) { - if (index == newBindingIndex) { - index ++; - continue; - } - b = p->bindings + index; - int nuke = 0; - if (config.multipleBinding) { - if (b->controlIndex == controlIndex && b->command == command) - nuke = 1; - } - else { - int uid2 = dev->virtualControls[b->controlIndex].uid; - if (b->controlIndex == controlIndex || (!((uid2^uid) & 0xFFFFFF) && ((uid|uid2) & (UID_POV | UID_AXIS)))) - nuke = 1; - } - if (!nuke) { - index++; - continue; - } - if (index < newBindingIndex) { - newBindingIndex--; - //count --; - } - DeleteBinding(port, slot, dev, b); - } - if (!config.multipleBinding) { - for (int port2=0; port2<2; port2++) { - for (int slot2=0; slot2<4; slot2++) { - if (port2==(int)port && slot2 == (int)slot) continue; - PadBindings *p = dev->pads[port2]+slot2; - for (int i=0; i < p->numBindings; i++) { - Binding *b = p->bindings+i; - int uid2 = dev->virtualControls[b->controlIndex].uid; - if (b->controlIndex == controlIndex || (!((uid2^uid) & 0xFFFFFF) && ((uid|uid2) & (UID_POV | UID_AXIS)))) { - DeleteBinding(port2, slot2, dev, b); - i--; - } - } - } - } - } + int newBindingIndex = index; + index = 0; + while (index < p->numBindings) { + if (index == newBindingIndex) { + index++; + continue; + } + b = p->bindings + index; + int nuke = 0; + if (config.multipleBinding) { + if (b->controlIndex == controlIndex && b->command == command) + nuke = 1; + } else { + int uid2 = dev->virtualControls[b->controlIndex].uid; + if (b->controlIndex == controlIndex || (!((uid2 ^ uid) & 0xFFFFFF) && ((uid | uid2) & (UID_POV | UID_AXIS)))) + nuke = 1; + } + if (!nuke) { + index++; + continue; + } + if (index < newBindingIndex) { + newBindingIndex--; + //count --; + } + DeleteBinding(port, slot, dev, b); + } + if (!config.multipleBinding) { + for (int port2 = 0; port2 < 2; port2++) { + for (int slot2 = 0; slot2 < 4; slot2++) { + if (port2 == (int)port && slot2 == (int)slot) + continue; + PadBindings *p = dev->pads[port2] + slot2; + for (int i = 0; i < p->numBindings; i++) { + Binding *b = p->bindings + i; + int uid2 = dev->virtualControls[b->controlIndex].uid; + if (b->controlIndex == controlIndex || (!((uid2 ^ uid) & 0xFFFFFF) && ((uid | uid2) & (UID_POV | UID_AXIS)))) { + DeleteBinding(port2, slot2, dev, b); + i--; + } + } + } + } + } - //return count; - return 0; + //return count; + return 0; } // Ties together config data structure, config files, and general config // dialog. const GeneralSettingsBool BoolOptionsInfo[] = { - {L"Force Cursor Hide", 0 /*IDC_FORCE_HIDE*/, 0}, - {L"Mouse Unfocus", 0 /*IDC_MOUSE_UNFOCUS*/, 1}, - {L"Background", 0 /*IDC_BACKGROUND*/, 1}, - {L"Multiple Bindings", 0 /*IDC_MULTIPLE_BINDING*/, 0}, + {L"Force Cursor Hide", 0 /*IDC_FORCE_HIDE*/, 0}, + {L"Mouse Unfocus", 0 /*IDC_MOUSE_UNFOCUS*/, 1}, + {L"Background", 0 /*IDC_BACKGROUND*/, 1}, + {L"Multiple Bindings", 0 /*IDC_MULTIPLE_BINDING*/, 0}, - {L"DirectInput Game Devices", 0 /*IDC_G_DI*/, 1}, - {L"XInput", 0 /*IDC_G_XI*/, 1}, - {L"DualShock 3", 0 /*IDC_G_DS3*/, 0}, + {L"DirectInput Game Devices", 0 /*IDC_G_DI*/, 1}, + {L"XInput", 0 /*IDC_G_XI*/, 1}, + {L"DualShock 3", 0 /*IDC_G_DS3*/, 0}, - {L"Multitap 1", 0 /*IDC_MULTITAP1*/, 0}, - {L"Multitap 2", 0 /*IDC_MULTITAP2*/, 0}, + {L"Multitap 1", 0 /*IDC_MULTITAP1*/, 0}, + {L"Multitap 2", 0 /*IDC_MULTITAP2*/, 0}, - {L"Escape Fullscreen Hack", 0 /*IDC_ESCAPE_FULLSCREEN_HACK*/, 1}, - {L"Disable Screen Saver", 0 /*IDC_DISABLE_SCREENSAVER*/, 1}, - {L"Logging", 0 /*IDC_DEBUG_FILE*/, 0}, + {L"Escape Fullscreen Hack", 0 /*IDC_ESCAPE_FULLSCREEN_HACK*/, 1}, + {L"Disable Screen Saver", 0 /*IDC_DISABLE_SCREENSAVER*/, 1}, + {L"Logging", 0 /*IDC_DEBUG_FILE*/, 0}, - {L"Save State in Title", 0 /*IDC_SAVE_STATE_TITLE*/, 0}, //No longer required, PCSX2 now handles it - avih 2011-05-17 - {L"GH2", 0 /*IDC_GH2_HACK*/, 0}, - {L"Turbo Key Hack", 0 /*IDC_TURBO_KEY_HACK*/, 0}, + {L"Save State in Title", 0 /*IDC_SAVE_STATE_TITLE*/, 0}, //No longer required, PCSX2 now handles it - avih 2011-05-17 + {L"GH2", 0 /*IDC_GH2_HACK*/, 0}, + {L"Turbo Key Hack", 0 /*IDC_TURBO_KEY_HACK*/, 0}, }; -void CALLBACK PADsetSettingsDir( const char *dir ) +void CALLBACK PADsetSettingsDir(const char *dir) { - CfgHelper::SetSettingsDir(dir); + CfgHelper::SetSettingsDir(dir); } -int SaveSettings(wchar_t *file=0) { - CfgHelper cfg; +int SaveSettings(wchar_t *file = 0) +{ + CfgHelper cfg; - for (size_t i=0; inumDevices; i++) { - wchar_t id[50]; - wchar_t temp[50], temp2[1000]; - wsprintfW(id, L"Device %i", i); - Device *dev = dm->devices[i]; - wchar_t *name = dev->displayName; - while (name[0] == '[') { - wchar_t *name2 = wcschr(name, ']'); - if (!name2) break; - name = name2+1; - while (iswspace(name[0])) name++; - } + for (int i = 0; i < dm->numDevices; i++) { + wchar_t id[50]; + wchar_t temp[50], temp2[1000]; + wsprintfW(id, L"Device %i", i); + Device *dev = dm->devices[i]; + wchar_t *name = dev->displayName; + while (name[0] == '[') { + wchar_t *name2 = wcschr(name, ']'); + if (!name2) + break; + name = name2 + 1; + while (iswspace(name[0])) + name++; + } - cfg.WriteStr(id, L"Display Name", name); - cfg.WriteStr(id, L"Instance ID", dev->instanceID); - if (dev->productID) { - cfg.WriteStr(id, L"Product ID", dev->productID); - } - cfg.WriteInt(id, L"API", dev->api); - cfg.WriteInt(id, L"Type", dev->type); - int ffBindingCount = 0; - int bindingCount = 0; - for (int port=0; port<2; port++) { - for (int slot=0; slot<4; slot++) { - for (int j=0; jpads[port][slot].numBindings; j++) { - Binding *b = dev->pads[port][slot].bindings+j; - VirtualControl *c = &dev->virtualControls[b->controlIndex]; - wsprintfW(temp, L"Binding %i", bindingCount++); - wsprintfW(temp2, L"0x%08X, %i, %i, %i, %i, %i, %i", c->uid, port, b->command, b->sensitivity, b->turbo, slot, b->deadZone); - cfg.WriteStr(id, temp, temp2); - } + cfg.WriteStr(id, L"Display Name", name); + cfg.WriteStr(id, L"Instance ID", dev->instanceID); + if (dev->productID) { + cfg.WriteStr(id, L"Product ID", dev->productID); + } + cfg.WriteInt(id, L"API", dev->api); + cfg.WriteInt(id, L"Type", dev->type); + int ffBindingCount = 0; + int bindingCount = 0; + for (int port = 0; port < 2; port++) { + for (int slot = 0; slot < 4; slot++) { + for (int j = 0; j < dev->pads[port][slot].numBindings; j++) { + Binding *b = dev->pads[port][slot].bindings + j; + VirtualControl *c = &dev->virtualControls[b->controlIndex]; + wsprintfW(temp, L"Binding %i", bindingCount++); + wsprintfW(temp2, L"0x%08X, %i, %i, %i, %i, %i, %i", c->uid, port, b->command, b->sensitivity, b->turbo, slot, b->deadZone); + cfg.WriteStr(id, temp, temp2); + } - for (int j=0; jpads[port][slot].numFFBindings; j++) { - ForceFeedbackBinding *b = dev->pads[port][slot].ffBindings+j; - ForceFeedbackEffectType *eff = &dev->ffEffectTypes[b->effectIndex]; - wsprintfW(temp, L"FF Binding %i", ffBindingCount++); - wsprintfW(temp2, L"%s %i, %i, %i", eff->effectID, port, b->motor, slot); - for (int k=0; knumFFAxes; k++) { - ForceFeedbackAxis *axis = dev->ffAxes + k; - AxisEffectInfo *info = b->axes + k; - //wsprintfW(wcschr(temp2,0), L", %i, %i", axis->id, info->force); - // Not secure because I'm too lazy to compute the remaining size - wprintf(wcschr(temp2, 0), L", %i, %i", axis->id, info->force); - } - cfg.WriteStr(id, temp, temp2); - } - } - } - } + for (int j = 0; j < dev->pads[port][slot].numFFBindings; j++) { + ForceFeedbackBinding *b = dev->pads[port][slot].ffBindings + j; + ForceFeedbackEffectType *eff = &dev->ffEffectTypes[b->effectIndex]; + wsprintfW(temp, L"FF Binding %i", ffBindingCount++); + wsprintfW(temp2, L"%s %i, %i, %i", eff->effectID, port, b->motor, slot); + for (int k = 0; k < dev->numFFAxes; k++) { + ForceFeedbackAxis *axis = dev->ffAxes + k; + AxisEffectInfo *info = b->axes + k; + //wsprintfW(wcschr(temp2,0), L", %i, %i", axis->id, info->force); + // Not secure because I'm too lazy to compute the remaining size + wprintf(wcschr(temp2, 0), L", %i, %i", axis->id, info->force); + } + cfg.WriteStr(id, temp, temp2); + } + } + } + } - return 0; + return 0; } -int LoadSettings(int force, wchar_t *file) { - if (dm && !force) return 0; +int LoadSettings(int force, wchar_t *file) +{ + if (dm && !force) + return 0; - // Could just do ClearDevices() instead, but if I ever add any extra stuff, - // this will still work. - UnloadConfigs(); - dm = new InputDeviceManager(); + // Could just do ClearDevices() instead, but if I ever add any extra stuff, + // this will still work. + UnloadConfigs(); + dm = new InputDeviceManager(); - CfgHelper cfg; + CfgHelper cfg; - for (size_t i=0; i= 100) break; - continue; - } - wchar_t *id2 = 0; - if (cfg.ReadStr(id, L"Product ID", temp4) && temp4[0]) - id2 = temp4; + int i = 0; + int multipleBinding = config.multipleBinding; + // Disabling multiple binding only prevents new multiple bindings. + config.multipleBinding = 1; + while (1) { + wchar_t id[50]; + wchar_t temp[50], temp2[1000], temp3[1000], temp4[1000]; + wsprintfW(id, L"Device %i", i++); + if (!cfg.ReadStr(id, L"Display Name", temp2) || !temp2[0] || + !cfg.ReadStr(id, L"Instance ID", temp3) || !temp3[0]) { + if (i >= 100) + break; + continue; + } + wchar_t *id2 = 0; + if (cfg.ReadStr(id, L"Product ID", temp4) && temp4[0]) + id2 = temp4; - int api = cfg.ReadInt(id, L"API"); - int type = cfg.ReadInt(id, L"Type"); - if (!api || !type) continue; + int api = cfg.ReadInt(id, L"API"); + int type = cfg.ReadInt(id, L"Type"); + if (!api || !type) + continue; - Device *dev = new Device((DeviceAPI)api, (DeviceType)type, temp2, temp3, id2); - dev->attached = 0; - dm->AddDevice(dev); - int j = 0; - int last = 0; - while (1) { - wsprintfW(temp, L"Binding %i", j++); - if (!cfg.ReadStr(id, temp, temp2)) { - if (j >= 100) { - if (!last) break; - last = 0; - } - continue; - } - last = 1; - unsigned int uid; - int port, command, sensitivity, turbo, slot = 0, deadZone = 0; - int w = 0; - char string[1000]; - while (temp2[w]) { - string[w] = (char)temp2[w]; - w++; - } - string[w] = 0; - int len = sscanf(string, " %u , %i , %i , %i , %i , %i , %i", &uid, &port, &command, &sensitivity, &turbo, &slot, &deadZone); - if (len >= 5 && type) { - VirtualControl *c = dev->GetVirtualControl(uid); - if (!c) c = dev->AddVirtualControl(uid, -1); - if (c) { - BindCommand(dev, uid, port, slot, command, sensitivity, turbo, deadZone); - } - } - } - j = 0; - while (1) { - wsprintfW(temp, L"FF Binding %i", j++); - if (!cfg.ReadStr(id, temp, temp2)) { - if (j >= 10) { - if (!last) break; - last = 0; - } - continue; - } - last = 1; - int port, slot, motor; - int w = 0; - char string[1000]; - char effect[1000]; - while (temp2[w]) { - string[w] = (char)temp2[w]; - w++; - } - string[w] = 0; - // wcstok not in ntdll. More effore than its worth to shave off - // whitespace without it. - if (sscanf(string, " %s %i , %i , %i", effect, &port, &motor, &slot) == 4) { - char *s = strchr(strchr(strchr(string, ',')+1, ',')+1, ','); - if (!s) continue; - s++; - w = 0; - while (effect[w]) { - temp2[w] = effect[w]; - w++; - } - temp2[w] = 0; - ForceFeedbackEffectType *eff = dev->GetForcefeedbackEffect(temp2); - if (!eff) { - // At the moment, don't record effect types. - // Only used internally, anyways, so not an issue. - dev->AddFFEffectType(temp2, temp2, EFFECT_CONSTANT); - // eff = &dev->ffEffectTypes[dev->numFFEffectTypes-1]; - } + Device *dev = new Device((DeviceAPI)api, (DeviceType)type, temp2, temp3, id2); + dev->attached = 0; + dm->AddDevice(dev); + int j = 0; + int last = 0; + while (1) { + wsprintfW(temp, L"Binding %i", j++); + if (!cfg.ReadStr(id, temp, temp2)) { + if (j >= 100) { + if (!last) + break; + last = 0; + } + continue; + } + last = 1; + unsigned int uid; + int port, command, sensitivity, turbo, slot = 0, deadZone = 0; + int w = 0; + char string[1000]; + while (temp2[w]) { + string[w] = (char)temp2[w]; + w++; + } + string[w] = 0; + int len = sscanf(string, " %u , %i , %i , %i , %i , %i , %i", &uid, &port, &command, &sensitivity, &turbo, &slot, &deadZone); + if (len >= 5 && type) { + VirtualControl *c = dev->GetVirtualControl(uid); + if (!c) + c = dev->AddVirtualControl(uid, -1); + if (c) { + BindCommand(dev, uid, port, slot, command, sensitivity, turbo, deadZone); + } + } + } + j = 0; + while (1) { + wsprintfW(temp, L"FF Binding %i", j++); + if (!cfg.ReadStr(id, temp, temp2)) { + if (j >= 10) { + if (!last) + break; + last = 0; + } + continue; + } + last = 1; + int port, slot, motor; + int w = 0; + char string[1000]; + char effect[1000]; + while (temp2[w]) { + string[w] = (char)temp2[w]; + w++; + } + string[w] = 0; + // wcstok not in ntdll. More effore than its worth to shave off + // whitespace without it. + if (sscanf(string, " %s %i , %i , %i", effect, &port, &motor, &slot) == 4) { + char *s = strchr(strchr(strchr(string, ',') + 1, ',') + 1, ','); + if (!s) + continue; + s++; + w = 0; + while (effect[w]) { + temp2[w] = effect[w]; + w++; + } + temp2[w] = 0; + ForceFeedbackEffectType *eff = dev->GetForcefeedbackEffect(temp2); + if (!eff) { + // At the moment, don't record effect types. + // Only used internally, anyways, so not an issue. + dev->AddFFEffectType(temp2, temp2, EFFECT_CONSTANT); + // eff = &dev->ffEffectTypes[dev->numFFEffectTypes-1]; + } #if 0 ForceFeedbackBinding *b; CreateEffectBinding(dev, temp2, port, slot, motor, &b); @@ -437,45 +455,47 @@ int LoadSettings(int force, wchar_t *file) { } } #endif - } - } - } - config.multipleBinding = multipleBinding; + } + } + } + config.multipleBinding = multipleBinding; - //TODO RefreshEnabledDevicesAndDisplay(1); - RefreshEnabledDevices(1); // XXX For the moment only a subfonction + //TODO RefreshEnabledDevicesAndDisplay(1); + RefreshEnabledDevices(1); // XXX For the moment only a subfonction - return 0; + return 0; } -void UnloadConfigs() { - if (dm) { - delete dm; - dm = 0; - } +void UnloadConfigs() +{ + if (dm) { + delete dm; + dm = 0; + } } -void RefreshEnabledDevices(int updateDeviceList) { - // Clears all device state. - static int lastXInputState = -1; - if (updateDeviceList || lastXInputState != config.gameApis.xInput) { - EnumDevices(config.gameApis.xInput); - lastXInputState = config.gameApis.xInput; - } +void RefreshEnabledDevices(int updateDeviceList) +{ + // Clears all device state. + static int lastXInputState = -1; + if (updateDeviceList || lastXInputState != config.gameApis.xInput) { + EnumDevices(config.gameApis.xInput); + lastXInputState = config.gameApis.xInput; + } - for (int i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; + for (int i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; - // XXX windows magic? - if (!dev->attached && dev->displayName[0] != '[') { - wchar_t *newName = (wchar_t*) malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12)); - wsprintfW(newName, L"[Detached] %s", dev->displayName); - free(dev->displayName); - dev->displayName = newName; - } + // XXX windows magic? + if (!dev->attached && dev->displayName[0] != '[') { + wchar_t *newName = (wchar_t *)malloc(sizeof(wchar_t) * (wcslen(dev->displayName) + 12)); + wsprintfW(newName, L"[Detached] %s", dev->displayName); + free(dev->displayName); + dev->displayName = newName; + } - dm->EnableDevice(i); -#if 0 // windows magic? + dm->EnableDevice(i); +#if 0 // windows magic? if ((dev->type == KEYBOARD && dev->api == IGNORE_KEYBOARD) || (dev->type == KEYBOARD && dev->api == config.keyboardApi) || (dev->type == MOUSE && dev->api == config.mouseApi) || @@ -496,13 +516,14 @@ void RefreshEnabledDevices(int updateDeviceList) { dm->DisableDevice(i); } #endif - } + } } -void Configure() { - // Can end up here without PADinit() being called first. - LoadSettings(); - // Can also end up here after running emulator a bit, and possibly - // disabling some devices due to focus changes, or releasing mouse. - RefreshEnabledDevices(0); +void Configure() +{ + // Can end up here without PADinit() being called first. + LoadSettings(); + // Can also end up here after running emulator a bit, and possibly + // disabling some devices due to focus changes, or releasing mouse. + RefreshEnabledDevices(0); } diff --git a/plugins/LilyPad/Linux/ConfigHelper.cpp b/plugins/LilyPad/Linux/ConfigHelper.cpp index e7f299f65d..b731b54cc1 100644 --- a/plugins/LilyPad/Linux/ConfigHelper.cpp +++ b/plugins/LilyPad/Linux/ConfigHelper.cpp @@ -22,91 +22,91 @@ wxString CfgHelper::m_path = L"inis/LilyPad.ini"; -void CfgHelper::SetSettingsDir(const char* dir) +void CfgHelper::SetSettingsDir(const char *dir) { - m_path = wxString::FromAscii(dir) + L"/LilyPad.ini"; + m_path = wxString::FromAscii(dir) + L"/LilyPad.ini"; } CfgHelper::CfgHelper() { - m_config = new wxFileConfig(L"", L"", m_path, L"", wxCONFIG_USE_LOCAL_FILE); + m_config = new wxFileConfig(L"", L"", m_path, L"", wxCONFIG_USE_LOCAL_FILE); } CfgHelper::~CfgHelper() { - delete m_config; + delete m_config; } -void CfgHelper::setIni(const wchar_t* Section) +void CfgHelper::setIni(const wchar_t *Section) { - m_config->SetPath(wxsFormat(L"/%s", Section)); + m_config->SetPath(wxsFormat(L"/%s", Section)); } -void CfgHelper::WriteBool(const wchar_t* Section, const wchar_t* Name, bool Value) +void CfgHelper::WriteBool(const wchar_t *Section, const wchar_t *Name, bool Value) { - setIni(Section); - m_config->Write(Name, Value); + setIni(Section); + m_config->Write(Name, Value); } -void CfgHelper::WriteInt(const wchar_t* Section, const wchar_t* Name, int Value) +void CfgHelper::WriteInt(const wchar_t *Section, const wchar_t *Name, int Value) { - setIni(Section); - m_config->Write(Name, Value); + setIni(Section); + m_config->Write(Name, Value); } -void CfgHelper::WriteFloat(const wchar_t* Section, const wchar_t* Name, float Value) +void CfgHelper::WriteFloat(const wchar_t *Section, const wchar_t *Name, float Value) { - setIni(Section); - m_config->Write(Name, (double)Value); + setIni(Section); + m_config->Write(Name, (double)Value); } -void CfgHelper::WriteStr(const wchar_t* Section, const wchar_t* Name, const wxString& Data) +void CfgHelper::WriteStr(const wchar_t *Section, const wchar_t *Name, const wxString &Data) { - setIni(Section); - m_config->Write(Name, Data); + setIni(Section); + m_config->Write(Name, Data); } -bool CfgHelper::ReadBool(const wchar_t *Section,const wchar_t* Name, bool Default) +bool CfgHelper::ReadBool(const wchar_t *Section, const wchar_t *Name, bool Default) { - bool ret; + bool ret; - setIni(Section); - m_config->Read(Name, &ret, Default); + setIni(Section); + m_config->Read(Name, &ret, Default); - return ret; + return ret; } -int CfgHelper::ReadInt(const wchar_t* Section, const wchar_t* Name,int Default) +int CfgHelper::ReadInt(const wchar_t *Section, const wchar_t *Name, int Default) { - int ret; + int ret; - setIni(Section); - m_config->Read(Name, &ret, Default); + setIni(Section); + m_config->Read(Name, &ret, Default); - return ret; + return ret; } -float CfgHelper::ReadFloat(const wchar_t* Section, const wchar_t* Name, float Default) +float CfgHelper::ReadFloat(const wchar_t *Section, const wchar_t *Name, float Default) { - double ret; + double ret; - setIni(Section); - m_config->Read(Name, &ret, (double)Default); + setIni(Section); + m_config->Read(Name, &ret, (double)Default); - return (float)ret; + return (float)ret; } -int CfgHelper::ReadStr(const wchar_t* Section, const wchar_t* Name, wchar_t* Data, const wchar_t* Default) +int CfgHelper::ReadStr(const wchar_t *Section, const wchar_t *Name, wchar_t *Data, const wchar_t *Default) { - setIni(Section); - wcscpy(Data, m_config->Read(Name, Default).wc_str()); - return wcslen(Data); + setIni(Section); + wcscpy(Data, m_config->Read(Name, Default).wc_str()); + return wcslen(Data); } -int CfgHelper::ReadStr(const wchar_t* Section, const wchar_t* Name, wxString& Data, const wchar_t* Default) +int CfgHelper::ReadStr(const wchar_t *Section, const wchar_t *Name, wxString &Data, const wchar_t *Default) { - setIni(Section); - Data = m_config->Read(Name, Default); - return Data.size(); + setIni(Section); + Data = m_config->Read(Name, Default); + return Data.size(); } diff --git a/plugins/LilyPad/Linux/ConfigHelper.h b/plugins/LilyPad/Linux/ConfigHelper.h index 6a74b9ae26..0cabd0560c 100644 --- a/plugins/LilyPad/Linux/ConfigHelper.h +++ b/plugins/LilyPad/Linux/ConfigHelper.h @@ -20,29 +20,29 @@ #include "Global.h" #include -extern void CfgSetSettingsDir(const char* dir); +extern void CfgSetSettingsDir(const char *dir); -class CfgHelper { - wxFileConfig* m_config; - static wxString m_path; +class CfgHelper +{ + wxFileConfig *m_config; + static wxString m_path; - void setIni(const wchar_t* Section); + void setIni(const wchar_t *Section); - public: - CfgHelper(); - ~CfgHelper(); +public: + CfgHelper(); + ~CfgHelper(); - void WriteBool(const wchar_t* Section, const wchar_t* Name, bool Value); - void WriteInt(const wchar_t* Section, const wchar_t* Name, int Value); - void WriteFloat(const wchar_t* Section, const wchar_t* Name, float Value); - void WriteStr(const wchar_t* Section, const wchar_t* Name, const wxString& Data); + void WriteBool(const wchar_t *Section, const wchar_t *Name, bool Value); + void WriteInt(const wchar_t *Section, const wchar_t *Name, int Value); + void WriteFloat(const wchar_t *Section, const wchar_t *Name, float Value); + void WriteStr(const wchar_t *Section, const wchar_t *Name, const wxString &Data); - bool ReadBool(const wchar_t *Section,const wchar_t* Name, bool Default = false); - int ReadStr(const wchar_t* Section, const wchar_t* Name, wxString& Data, const wchar_t* Default = 0); - int ReadStr(const wchar_t* Section, const wchar_t* Name, wchar_t* Data, const wchar_t* Default = 0); - int ReadInt(const wchar_t* Section, const wchar_t* Name,int Default = 0); - float ReadFloat(const wchar_t* Section, const wchar_t* Name, float Default = 0.0f); - - static void SetSettingsDir(const char* dir); + bool ReadBool(const wchar_t *Section, const wchar_t *Name, bool Default = false); + int ReadStr(const wchar_t *Section, const wchar_t *Name, wxString &Data, const wchar_t *Default = 0); + int ReadStr(const wchar_t *Section, const wchar_t *Name, wchar_t *Data, const wchar_t *Default = 0); + int ReadInt(const wchar_t *Section, const wchar_t *Name, int Default = 0); + float ReadFloat(const wchar_t *Section, const wchar_t *Name, float Default = 0.0f); + static void SetSettingsDir(const char *dir); }; diff --git a/plugins/LilyPad/Linux/JoyEvdev.cpp b/plugins/LilyPad/Linux/JoyEvdev.cpp index d82c51762c..5a61b2c316 100644 --- a/plugins/LilyPad/Linux/JoyEvdev.cpp +++ b/plugins/LilyPad/Linux/JoyEvdev.cpp @@ -20,189 +20,191 @@ #include "Linux/JoyEvdev.h" #include "Linux/bitmaskros.h" -JoyEvdev::JoyEvdev(int fd, bool ds3, const wchar_t *id) : Device(LNX_JOY, OTHER, id, id), m_fd(fd) { - // XXX LNX_JOY => DS3 or ??? +JoyEvdev::JoyEvdev(int fd, bool ds3, const wchar_t *id) + : Device(LNX_JOY, OTHER, id, id) + , m_fd(fd) +{ + // XXX LNX_JOY => DS3 or ??? - m_abs.clear(); - m_btn.clear(); - m_rel.clear(); - int last = 0; + m_abs.clear(); + m_btn.clear(); + m_rel.clear(); + int last = 0; - uint8_t abs_bitmap[nUcharsForNBits(ABS_CNT)] = {0}; - uint8_t btn_bitmap[nUcharsForNBits(KEY_CNT)] = {0}; - uint8_t rel_bitmap[nUcharsForNBits(REL_CNT)] = {0}; + uint8_t abs_bitmap[nUcharsForNBits(ABS_CNT)] = {0}; + uint8_t btn_bitmap[nUcharsForNBits(KEY_CNT)] = {0}; + uint8_t rel_bitmap[nUcharsForNBits(REL_CNT)] = {0}; - // Add buttons - if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(btn_bitmap)), btn_bitmap) >= 0) { - for (int bit = BTN_MISC; bit < KEY_CNT; bit++) { - if (testBit(bit, btn_bitmap)) { - AddPhysicalControl(PSHBTN, last, 0); - m_btn.push_back(bit); - last++; - } - } - } + // Add buttons + if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(btn_bitmap)), btn_bitmap) >= 0) { + for (int bit = BTN_MISC; bit < KEY_CNT; bit++) { + if (testBit(bit, btn_bitmap)) { + AddPhysicalControl(PSHBTN, last, 0); + m_btn.push_back(bit); + last++; + } + } + } - // Add Absolute axis - if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmap)), abs_bitmap) >= 0) { - for (int bit = 0; bit < ABS_CNT; bit++) { - ControlType type = ABSAXIS; // FIXME DS3 + // Add Absolute axis + if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmap)), abs_bitmap) >= 0) { + for (int bit = 0; bit < ABS_CNT; bit++) { + ControlType type = ABSAXIS; // FIXME DS3 - if (testBit(bit, abs_bitmap)) { - input_absinfo info; - if (ioctl(m_fd, EVIOCGABS(bit), &info) < 0) { - fprintf(stderr, "Invalid IOCTL EVIOCGID\n"); - continue; - } + if (testBit(bit, abs_bitmap)) { + input_absinfo info; + if (ioctl(m_fd, EVIOCGABS(bit), &info) < 0) { + fprintf(stderr, "Invalid IOCTL EVIOCGID\n"); + continue; + } - AddPhysicalControl(ABSAXIS, last, 0); - last++; - if (std::abs(info.value - 127) < 2) { - fprintf(stderr, "HALF Axis info %d=>%d, current %d, flat %d, resolution %d\n", info.minimum, info.maximum, info.value, info.flat, info.resolution); + AddPhysicalControl(ABSAXIS, last, 0); + last++; + if (std::abs(info.value - 127) < 2) { + fprintf(stderr, "HALF Axis info %d=>%d, current %d, flat %d, resolution %d\n", info.minimum, info.maximum, info.value, info.flat, info.resolution); - // Half axis must be split into 2 parts... - AddPhysicalControl(ABSAXIS, last, 0); - last++; + // Half axis must be split into 2 parts... + AddPhysicalControl(ABSAXIS, last, 0); + last++; - m_abs.push_back(abs_info(bit, info.minimum, info.value, type)); - m_abs.push_back(abs_info(bit, info.value, info.maximum, type)); - } else { - fprintf(stderr, "FULL Axis info %d=>%d, current %d, flat %d, resolution %d\n", info.minimum, info.maximum, info.value, info.flat, info.resolution); + m_abs.push_back(abs_info(bit, info.minimum, info.value, type)); + m_abs.push_back(abs_info(bit, info.value, info.maximum, type)); + } else { + fprintf(stderr, "FULL Axis info %d=>%d, current %d, flat %d, resolution %d\n", info.minimum, info.maximum, info.value, info.flat, info.resolution); - m_abs.push_back(abs_info(bit, info.minimum, info.maximum, type)); - } - } - } - } + m_abs.push_back(abs_info(bit, info.minimum, info.maximum, type)); + } + } + } + } - // Add relative axis - if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmap)), rel_bitmap) >= 0) { - for (int bit = 0; bit < REL_CNT; bit++) { - if (testBit(bit, rel_bitmap)) { - AddPhysicalControl(RELAXIS, last, last); - m_rel.push_back(bit); - last++; + // Add relative axis + if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmap)), rel_bitmap) >= 0) { + for (int bit = 0; bit < REL_CNT; bit++) { + if (testBit(bit, rel_bitmap)) { + AddPhysicalControl(RELAXIS, last, last); + m_rel.push_back(bit); + last++; - fprintf(stderr, "Add relative nb %d\n", bit); - } - } - } + fprintf(stderr, "Add relative nb %d\n", bit); + } + } + } - fprintf(stderr, "New device created. Found axe:%zu, buttons:%zu, m_rel:%zu\n\n", m_abs.size(), m_btn.size(), m_rel.size()); + fprintf(stderr, "New device created. Found axe:%zu, buttons:%zu, m_rel:%zu\n\n", m_abs.size(), m_btn.size(), m_rel.size()); } -JoyEvdev::~JoyEvdev() { - close(m_fd); +JoyEvdev::~JoyEvdev() +{ + close(m_fd); } -int JoyEvdev::Activate(InitInfo* args) { - AllocState(); +int JoyEvdev::Activate(InitInfo *args) +{ + AllocState(); - uint16_t size = m_abs.size()+m_rel.size()+m_btn.size(); - memset(physicalControlState, 0, sizeof(int)*size); + uint16_t size = m_abs.size() + m_rel.size() + m_btn.size(); + memset(physicalControlState, 0, sizeof(int) * size); - active = 1; - return 1; + active = 1; + return 1; } -int JoyEvdev::Update() { +int JoyEvdev::Update() +{ struct input_event events[32]; - int len; - int status = 0; - //fprintf(stderr, "Update was called\n"); - - // Do a big read to reduce kernel validation + int len; + int status = 0; + //fprintf(stderr, "Update was called\n"); + + // Do a big read to reduce kernel validation while ((len = read(m_fd, events, (sizeof events))) > 0) { - int evt_nb = len / sizeof(input_event); - //fprintf(stderr, "Poll %d events available\n", evt_nb); - for (int i = 0; i < evt_nb; i++) { - switch(events[i].type) { - case EV_ABS: - { - for (size_t idx = 0; idx < m_abs.size(); idx++) { - if (m_abs[idx].code == events[i].code) { - // XXX strict or not ? - if ((events[i].value >= m_abs[idx].min) && (events[i].value <= m_abs[idx].max)) { - // XXX FIX shitty api - int scale = m_abs[idx].scale(events[i].value); - fprintf(stderr, "axis value %d scaled to %d\n", events[i].value, scale); - physicalControlState[idx + m_btn.size()] = scale; - status = 1; - } - } - } - } - break; - case EV_KEY: - { - for (size_t idx = 0; idx < m_btn.size(); idx++) { - if (m_btn[idx] == events[i].code) { - fprintf(stderr, "Event KEY:%d detected with value %d\n", events[i].code, events[i].value); - physicalControlState[idx] = FULLY_DOWN * events[i].value; - status = 1; - break; - } - } + int evt_nb = len / sizeof(input_event); + //fprintf(stderr, "Poll %d events available\n", evt_nb); + for (int i = 0; i < evt_nb; i++) { + switch (events[i].type) { + case EV_ABS: { + for (size_t idx = 0; idx < m_abs.size(); idx++) { + if (m_abs[idx].code == events[i].code) { + // XXX strict or not ? + if ((events[i].value >= m_abs[idx].min) && (events[i].value <= m_abs[idx].max)) { + // XXX FIX shitty api + int scale = m_abs[idx].scale(events[i].value); + fprintf(stderr, "axis value %d scaled to %d\n", events[i].value, scale); + physicalControlState[idx + m_btn.size()] = scale; + status = 1; + } + } + } + } break; + case EV_KEY: { + for (size_t idx = 0; idx < m_btn.size(); idx++) { + if (m_btn[idx] == events[i].code) { + fprintf(stderr, "Event KEY:%d detected with value %d\n", events[i].code, events[i].value); + physicalControlState[idx] = FULLY_DOWN * events[i].value; + status = 1; + break; + } + } - } - break; - case EV_REL: - // XXX - break; - default: - break; - } - } + } break; + case EV_REL: + // XXX + break; + default: + break; + } + } + } - } - - return status; + return status; } -static std::wstring CorrectJoySupport(int fd) { - struct input_id id; - if (ioctl(fd, EVIOCGID, &id) < 0) { - fprintf(stderr, "Invalid IOCTL EVIOCGID\n"); - return L""; - } +static std::wstring CorrectJoySupport(int fd) +{ + struct input_id id; + if (ioctl(fd, EVIOCGID, &id) < 0) { + fprintf(stderr, "Invalid IOCTL EVIOCGID\n"); + return L""; + } - char dev_name[128]; - if (ioctl(fd, EVIOCGNAME(128), dev_name) < 0) { - fprintf(stderr, "Invalid IOCTL EVIOCGNAME\n"); - return L""; - } + char dev_name[128]; + if (ioctl(fd, EVIOCGNAME(128), dev_name) < 0) { + fprintf(stderr, "Invalid IOCTL EVIOCGNAME\n"); + return L""; + } - fprintf(stderr, "Found input device => bustype:%x, vendor:%x, product:%x, version:%x\n", id.bustype, id.vendor, id.product, id.version); - fprintf(stderr, "\tName:%s\n", dev_name); + fprintf(stderr, "Found input device => bustype:%x, vendor:%x, product:%x, version:%x\n", id.bustype, id.vendor, id.product, id.version); + fprintf(stderr, "\tName:%s\n", dev_name); - std::string s(dev_name); - return std::wstring(s.begin(), s.end()); + std::string s(dev_name); + return std::wstring(s.begin(), s.end()); } -void EnumJoystickEvdev() { - // Technically it must be done with udev but another lib for - // avoid a loop is too much for me (even if udev is mandatory - // so maybe later) - int found_devices = 0; - std::string input_root("/dev/input/event"); - for (int i = 0; i < 32; i++) { - std::string dev = input_root + std::to_string(i); +void EnumJoystickEvdev() +{ + // Technically it must be done with udev but another lib for + // avoid a loop is too much for me (even if udev is mandatory + // so maybe later) + int found_devices = 0; + std::string input_root("/dev/input/event"); + for (int i = 0; i < 32; i++) { + std::string dev = input_root + std::to_string(i); - int fd = open(dev.c_str(), O_RDWR | O_NONBLOCK); - if (fd < 0) { - continue; - } - - std::wstring id = CorrectJoySupport(fd); - if (id.size() != 0) { - bool ds3 = id.find(L"PLAYSTATION(R)3") != std::string::npos; - if (ds3) { - fprintf(stderr, "DS3 device detected !!!\n"); - } - dm->AddDevice(new JoyEvdev(fd, ds3, id.c_str())); - } else if (fd >= 0) - close(fd); - } + int fd = open(dev.c_str(), O_RDWR | O_NONBLOCK); + if (fd < 0) { + continue; + } + std::wstring id = CorrectJoySupport(fd); + if (id.size() != 0) { + bool ds3 = id.find(L"PLAYSTATION(R)3") != std::string::npos; + if (ds3) { + fprintf(stderr, "DS3 device detected !!!\n"); + } + dm->AddDevice(new JoyEvdev(fd, ds3, id.c_str())); + } else if (fd >= 0) + close(fd); + } } diff --git a/plugins/LilyPad/Linux/JoyEvdev.h b/plugins/LilyPad/Linux/JoyEvdev.h index b084aa2441..b5b27c4f37 100644 --- a/plugins/LilyPad/Linux/JoyEvdev.h +++ b/plugins/LilyPad/Linux/JoyEvdev.h @@ -23,55 +23,62 @@ #include #include -struct abs_info { - uint16_t code; - int32_t min; - int32_t max; +struct abs_info +{ + uint16_t code; + int32_t min; + int32_t max; - int32_t factor; - int32_t translation; + int32_t factor; + int32_t translation; - abs_info(int32_t _code, int32_t _min, int32_t _max, ControlType type) : code(_code), min(_min), max(_max) { - translation = 0; - // Note: ABSAXIS ranges from -64K to 64K - // Note: PSHBTN ranges from 0 to 64K - if ((min == 0) && (max == 255)) { - if (type == ABSAXIS) { - translation = 128; - factor = FULLY_DOWN/128; - } else { - factor = FULLY_DOWN/256; - } - } else if ((min == -1) && (max == 1)) { - factor = FULLY_DOWN; - } else if ((min == 0) && (std::abs(max - 127) < 2)) { - translation = 64; - factor = -FULLY_DOWN/64; - } else if ((max == 255) && (std::abs(min - 127) < 2)) { - translation = 64+128; - factor = FULLY_DOWN/64; - } else { - fprintf(stderr, "Scale not supported\n"); - factor = 0; - } - } + abs_info(int32_t _code, int32_t _min, int32_t _max, ControlType type) + : code(_code) + , min(_min) + , max(_max) + { + translation = 0; + // Note: ABSAXIS ranges from -64K to 64K + // Note: PSHBTN ranges from 0 to 64K + if ((min == 0) && (max == 255)) { + if (type == ABSAXIS) { + translation = 128; + factor = FULLY_DOWN / 128; + } else { + factor = FULLY_DOWN / 256; + } + } else if ((min == -1) && (max == 1)) { + factor = FULLY_DOWN; + } else if ((min == 0) && (std::abs(max - 127) < 2)) { + translation = 64; + factor = -FULLY_DOWN / 64; + } else if ((max == 255) && (std::abs(min - 127) < 2)) { + translation = 64 + 128; + factor = FULLY_DOWN / 64; + } else { + fprintf(stderr, "Scale not supported\n"); + factor = 0; + } + } - int scale(int32_t value) { - return (value - translation) * factor; - } + int scale(int32_t value) + { + return (value - translation) * factor; + } }; -class JoyEvdev : public Device { - int m_fd; - std::vector m_abs; - std::vector m_btn; - std::vector m_rel; +class JoyEvdev : public Device +{ + int m_fd; + std::vector m_abs; + std::vector m_btn; + std::vector m_rel; - public: - JoyEvdev(int fd, bool ds3, const wchar_t *id); - ~JoyEvdev(); - int Activate(InitInfo* args); - int Update(); +public: + JoyEvdev(int fd, bool ds3, const wchar_t *id); + ~JoyEvdev(); + int Activate(InitInfo *args); + int Update(); }; void EnumJoystickEvdev(); diff --git a/plugins/LilyPad/Linux/KeyboardMouse.cpp b/plugins/LilyPad/Linux/KeyboardMouse.cpp index efcc7de491..49b715c1c9 100644 --- a/plugins/LilyPad/Linux/KeyboardMouse.cpp +++ b/plugins/LilyPad/Linux/KeyboardMouse.cpp @@ -20,19 +20,20 @@ // actually it is even more but it is enough to distinguish different key #define MAX_KEYCODE (0xFF) -LinuxKeyboard::LinuxKeyboard() : - Device(LNX_KEYBOARD, KEYBOARD, L"displayName", L"instanceID", L"deviceID") +LinuxKeyboard::LinuxKeyboard() + : Device(LNX_KEYBOARD, KEYBOARD, L"displayName", L"instanceID", L"deviceID") { - for (int i=0; iAddDevice(new LinuxKeyboard()); +void EnumLnx() +{ + dm->AddDevice(new LinuxKeyboard()); } diff --git a/plugins/LilyPad/Linux/KeyboardMouse.h b/plugins/LilyPad/Linux/KeyboardMouse.h index b336b2a842..443148301a 100644 --- a/plugins/LilyPad/Linux/KeyboardMouse.h +++ b/plugins/LilyPad/Linux/KeyboardMouse.h @@ -19,11 +19,12 @@ #include "InputManager.h" #include "KeyboardQueue.h" -class LinuxKeyboard : public Device { - public: - LinuxKeyboard(); - int Activate(InitInfo* args); - int Update(); +class LinuxKeyboard : public Device +{ +public: + LinuxKeyboard(); + int Activate(InitInfo *args); + int Update(); }; void EnumLnx(); diff --git a/plugins/LilyPad/Linux/KeyboardQueue.cpp b/plugins/LilyPad/Linux/KeyboardQueue.cpp index aac11ad12b..3af8d3112d 100644 --- a/plugins/LilyPad/Linux/KeyboardQueue.cpp +++ b/plugins/LilyPad/Linux/KeyboardQueue.cpp @@ -32,30 +32,35 @@ static u8 R_lastQueuedEvent = 0; static u8 R_nextQueuedEvent = 0; static keyEvent R_queuedEvents[R_EVENT_QUEUE_LEN]; -void R_QueueKeyEvent(const keyEvent &evt) { - std::lock_guard lock(core_event); - - R_queuedEvents[R_lastQueuedEvent] = evt; - R_lastQueuedEvent = (R_lastQueuedEvent + 1) % R_EVENT_QUEUE_LEN; - // In case someone has a severe Parkingson's disease - assert(R_nextQueuedEvent != R_lastQueuedEvent); -} - -int R_GetQueuedKeyEvent(keyEvent *event) { - if (R_lastQueuedEvent == R_nextQueuedEvent) return 0; - - std::lock_guard lock(core_event); - *event = R_queuedEvents[R_nextQueuedEvent]; - R_nextQueuedEvent = (R_nextQueuedEvent + 1) % R_EVENT_QUEUE_LEN; - return 1; -} - -void R_ClearKeyQueue() { - R_lastQueuedEvent = R_nextQueuedEvent; -} - -EXPORT_C_(void) PADWriteEvent(keyEvent &evt) +void R_QueueKeyEvent(const keyEvent &evt) { - R_QueueKeyEvent(evt); + std::lock_guard lock(core_event); + + R_queuedEvents[R_lastQueuedEvent] = evt; + R_lastQueuedEvent = (R_lastQueuedEvent + 1) % R_EVENT_QUEUE_LEN; + // In case someone has a severe Parkingson's disease + assert(R_nextQueuedEvent != R_lastQueuedEvent); +} + +int R_GetQueuedKeyEvent(keyEvent *event) +{ + if (R_lastQueuedEvent == R_nextQueuedEvent) + return 0; + + std::lock_guard lock(core_event); + *event = R_queuedEvents[R_nextQueuedEvent]; + R_nextQueuedEvent = (R_nextQueuedEvent + 1) % R_EVENT_QUEUE_LEN; + return 1; +} + +void R_ClearKeyQueue() +{ + R_lastQueuedEvent = R_nextQueuedEvent; +} + +EXPORT_C_(void) +PADWriteEvent(keyEvent &evt) +{ + R_QueueKeyEvent(evt); } #endif diff --git a/plugins/LilyPad/Linux/bitmaskros.h b/plugins/LilyPad/Linux/bitmaskros.h index 2543022255..2c2d45fd90 100644 --- a/plugins/LilyPad/Linux/bitmaskros.h +++ b/plugins/LilyPad/Linux/bitmaskros.h @@ -21,20 +21,20 @@ */ /* Number of bits for 1 unsigned char */ -#define nBitsPerUchar (sizeof(unsigned char) * 8) +#define nBitsPerUchar (sizeof(unsigned char) * 8) /* Number of unsigned chars to contain a given number of bits */ -#define nUcharsForNBits(nBits) ((((nBits)-1)/nBitsPerUchar)+1) +#define nUcharsForNBits(nBits) ((((nBits)-1) / nBitsPerUchar) + 1) /* Index=Offset of given bit in 1 unsigned char */ -#define bitOffsetInUchar(bit) ((bit)%nBitsPerUchar) +#define bitOffsetInUchar(bit) ((bit) % nBitsPerUchar) /* Index=Offset of the unsigned char associated to the bit at the given index=offset */ -#define ucharIndexForBit(bit) ((bit)/nBitsPerUchar) +#define ucharIndexForBit(bit) ((bit) / nBitsPerUchar) /* Value of an unsigned char with bit set at given index=offset */ -#define ucharValueForBit(bit) (((unsigned char)(1))<> bitOffsetInUchar(bit)) & 1) +#define testBit(bit, array) ((array[ucharIndexForBit(bit)] >> bitOffsetInUchar(bit)) & 1) diff --git a/plugins/LilyPad/RawInput.cpp b/plugins/LilyPad/RawInput.cpp index 748d1f30a2..71596a8bee 100644 --- a/plugins/LilyPad/RawInput.cpp +++ b/plugins/LilyPad/RawInput.cpp @@ -26,44 +26,48 @@ ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output); -int GetRawKeyboards(HWND hWnd) { - RAWINPUTDEVICE Rid; - Rid.hwndTarget = hWnd; +int GetRawKeyboards(HWND hWnd) +{ + RAWINPUTDEVICE Rid; + Rid.hwndTarget = hWnd; - Rid.dwFlags = 0; - Rid.usUsagePage = 0x01; - Rid.usUsage = 0x06; - return RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); + Rid.dwFlags = 0; + Rid.usUsagePage = 0x01; + Rid.usUsage = 0x06; + return RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); } -void ReleaseRawKeyboards() { - RAWINPUTDEVICE Rid; - Rid.hwndTarget = 0; +void ReleaseRawKeyboards() +{ + RAWINPUTDEVICE Rid; + Rid.hwndTarget = 0; - Rid.dwFlags = RIDEV_REMOVE; - Rid.usUsagePage = 0x01; - Rid.usUsage = 0x06; - RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); + Rid.dwFlags = RIDEV_REMOVE; + Rid.usUsagePage = 0x01; + Rid.usUsage = 0x06; + RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); } -int GetRawMice(HWND hWnd) { - RAWINPUTDEVICE Rid; - Rid.hwndTarget = hWnd; +int GetRawMice(HWND hWnd) +{ + RAWINPUTDEVICE Rid; + Rid.hwndTarget = hWnd; - Rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE; - Rid.usUsagePage = 0x01; - Rid.usUsage = 0x02; - return RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); + Rid.dwFlags = RIDEV_NOLEGACY | RIDEV_CAPTUREMOUSE; + Rid.usUsagePage = 0x01; + Rid.usUsage = 0x02; + return RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); } -void ReleaseRawMice() { - RAWINPUTDEVICE Rid; - Rid.hwndTarget = 0; +void ReleaseRawMice() +{ + RAWINPUTDEVICE Rid; + Rid.hwndTarget = 0; - Rid.dwFlags = RIDEV_REMOVE; - Rid.usUsagePage = 0x01; - Rid.usUsage = 0x02; - RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); + Rid.dwFlags = RIDEV_REMOVE; + Rid.usUsagePage = 0x01; + Rid.usUsage = 0x02; + RegisterRawInputDevices(&Rid, 1, sizeof(Rid)); } // Count of active raw keyboard devices. @@ -72,234 +76,256 @@ static int rawKeyboardActivatedCount = 0; // Same for mice. static int rawMouseActivatedCount = 0; -class RawInputKeyboard : public WindowsKeyboard { +class RawInputKeyboard : public WindowsKeyboard +{ public: - HANDLE hDevice; + HANDLE hDevice; - RawInputKeyboard(HANDLE hDevice, wchar_t *name, wchar_t *instanceID=0) : WindowsKeyboard(RAW, name, instanceID) { - this->hDevice = hDevice; - } + RawInputKeyboard(HANDLE hDevice, wchar_t *name, wchar_t *instanceID = 0) + : WindowsKeyboard(RAW, name, instanceID) + { + this->hDevice = hDevice; + } - int Activate(InitInfo *initInfo) { - Deactivate(); + int Activate(InitInfo *initInfo) + { + Deactivate(); - hWndProc = initInfo->hWndProc; + hWndProc = initInfo->hWndProc; - active = 1; - if (!rawKeyboardActivatedCount++) { - if (!rawMouseActivatedCount) - hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); + active = 1; + if (!rawKeyboardActivatedCount++) { + if (!rawMouseActivatedCount) + hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); - if (!GetRawKeyboards(hWndProc->hWndEaten)) { - Deactivate(); - return 0; - } - } + if (!GetRawKeyboards(hWndProc->hWndEaten)) { + Deactivate(); + return 0; + } + } - InitState(); - return 1; - } + InitState(); + return 1; + } - void Deactivate() { - FreeState(); - if (active) { - active = 0; - rawKeyboardActivatedCount --; - if (!rawKeyboardActivatedCount) { - ReleaseRawKeyboards(); - if (!rawMouseActivatedCount) - hWndProc->ReleaseExtraProc(RawInputWndProc); - } - } - } + void Deactivate() + { + FreeState(); + if (active) { + active = 0; + rawKeyboardActivatedCount--; + if (!rawKeyboardActivatedCount) { + ReleaseRawKeyboards(); + if (!rawMouseActivatedCount) + hWndProc->ReleaseExtraProc(RawInputWndProc); + } + } + } }; -class RawInputMouse : public WindowsMouse { +class RawInputMouse : public WindowsMouse +{ public: - HANDLE hDevice; + HANDLE hDevice; - RawInputMouse(HANDLE hDevice, wchar_t *name, wchar_t *instanceID=0, wchar_t *productID=0) : WindowsMouse(RAW, 0, name, instanceID, productID) { - this->hDevice = hDevice; - } + RawInputMouse(HANDLE hDevice, wchar_t *name, wchar_t *instanceID = 0, wchar_t *productID = 0) + : WindowsMouse(RAW, 0, name, instanceID, productID) + { + this->hDevice = hDevice; + } - int Activate(InitInfo *initInfo) { - Deactivate(); + int Activate(InitInfo *initInfo) + { + Deactivate(); - hWndProc = initInfo->hWndProc; + hWndProc = initInfo->hWndProc; - active = 1; + active = 1; - // Have to be careful with order. At worst, one unmatched call to ReleaseRawMice on - // EatWndProc fail. In all other cases, no unmatched initialization/cleanup - // lines. - if (!rawMouseActivatedCount++) { - GetMouseCapture(hWndProc->hWndEaten); - if (!rawKeyboardActivatedCount) - hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); + // Have to be careful with order. At worst, one unmatched call to ReleaseRawMice on + // EatWndProc fail. In all other cases, no unmatched initialization/cleanup + // lines. + if (!rawMouseActivatedCount++) { + GetMouseCapture(hWndProc->hWndEaten); + if (!rawKeyboardActivatedCount) + hWndProc->Eat(RawInputWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); - if (!GetRawMice(hWndProc->hWndEaten)) { - Deactivate(); - return 0; - } - } + if (!GetRawMice(hWndProc->hWndEaten)) { + Deactivate(); + return 0; + } + } - AllocState(); - return 1; - } + AllocState(); + return 1; + } - void Deactivate() { - FreeState(); - if (active) { - active = 0; - rawMouseActivatedCount --; - if (!rawMouseActivatedCount) { - ReleaseRawMice(); - ReleaseMouseCapture(); - if (!rawKeyboardActivatedCount) { - hWndProc->ReleaseExtraProc(RawInputWndProc); - } - } - } - } + void Deactivate() + { + FreeState(); + if (active) { + active = 0; + rawMouseActivatedCount--; + if (!rawMouseActivatedCount) { + ReleaseRawMice(); + ReleaseMouseCapture(); + if (!rawKeyboardActivatedCount) { + hWndProc->ReleaseExtraProc(RawInputWndProc); + } + } + } + } }; -ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - if (uMsg == WM_INPUT) { - if (GET_RAWINPUT_CODE_WPARAM (wParam) == RIM_INPUT) { - RAWINPUT in; - unsigned int size = sizeof(RAWINPUT); - if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER)) > 0) { - for (int i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; - if (dev->api != RAW || !dev->active) continue; - if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD) { - RawInputKeyboard* rik = (RawInputKeyboard*)dev; - if (rik->hDevice != in.header.hDevice) continue; +ExtraWndProcResult RawInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) +{ + if (uMsg == WM_INPUT) { + if (GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT) { + RAWINPUT in; + unsigned int size = sizeof(RAWINPUT); + if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &in, &size, sizeof(RAWINPUTHEADER)) > 0) { + for (int i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; + if (dev->api != RAW || !dev->active) + continue; + if (in.header.dwType == RIM_TYPEKEYBOARD && dev->type == KEYBOARD) { + RawInputKeyboard *rik = (RawInputKeyboard *)dev; + if (rik->hDevice != in.header.hDevice) + continue; - u32 uMsg = in.data.keyboard.Message; - if (!(in.data.keyboard.VKey>>8)) - rik->UpdateKey((u8) in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)); - } - else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE) { - RawInputMouse* rim = (RawInputMouse*)dev; - if (rim->hDevice != in.header.hDevice) continue; - if (in.data.mouse.usFlags) { - // Never been set for me, and specs on what most of them - // actually mean is sorely lacking. Also, specs erroneously - // indicate MOUSE_MOVE_RELATIVE is a flag, when it's really - // 0... - continue; - } + u32 uMsg = in.data.keyboard.Message; + if (!(in.data.keyboard.VKey >> 8)) + rik->UpdateKey((u8)in.data.keyboard.VKey, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)); + } else if (in.header.dwType == RIM_TYPEMOUSE && dev->type == MOUSE) { + RawInputMouse *rim = (RawInputMouse *)dev; + if (rim->hDevice != in.header.hDevice) + continue; + if (in.data.mouse.usFlags) { + // Never been set for me, and specs on what most of them + // actually mean is sorely lacking. Also, specs erroneously + // indicate MOUSE_MOVE_RELATIVE is a flag, when it's really + // 0... + continue; + } - unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF; - int button = 0; - while (buttons) { - if (buttons & 3) { - // 2 is up, 1 is down. Up takes precedence over down. - rim->UpdateButton(button, !(buttons & 2)); - } - button++; - buttons >>= 2; - } - if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { - rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData)/WHEEL_DELTA); - } - if (in.data.mouse.lLastX || in.data.mouse.lLastY) { - rim->UpdateAxis(0, in.data.mouse.lLastX); - rim->UpdateAxis(1, in.data.mouse.lLastY); - } - } - } - } - } - } - else if (uMsg == WM_ACTIVATE) { - for (int i=0; inumDevices; i++) { - Device *dev = dm->devices[i]; - if (dev->api != RAW || dev->physicalControlState == 0) continue; - memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls); - } - } - else if (uMsg == WM_SIZE && rawMouseActivatedCount) { - // Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt. - WindowsMouse::WindowResized(hWnd); - } + unsigned short buttons = in.data.mouse.usButtonFlags & 0x3FF; + int button = 0; + while (buttons) { + if (buttons & 3) { + // 2 is up, 1 is down. Up takes precedence over down. + rim->UpdateButton(button, !(buttons & 2)); + } + button++; + buttons >>= 2; + } + if (in.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { + rim->UpdateAxis(2, ((short)in.data.mouse.usButtonData) / WHEEL_DELTA); + } + if (in.data.mouse.lLastX || in.data.mouse.lLastY) { + rim->UpdateAxis(0, in.data.mouse.lLastX); + rim->UpdateAxis(1, in.data.mouse.lLastY); + } + } + } + } + } + } else if (uMsg == WM_ACTIVATE) { + for (int i = 0; i < dm->numDevices; i++) { + Device *dev = dm->devices[i]; + if (dev->api != RAW || dev->physicalControlState == 0) + continue; + memset(dev->physicalControlState, 0, sizeof(int) * dev->numPhysicalControls); + } + } else if (uMsg == WM_SIZE && rawMouseActivatedCount) { + // Doesn't really matter for raw mice, as I disable legacy stuff, but shouldn't hurt. + WindowsMouse::WindowResized(hWnd); + } - return CONTINUE_BLISSFULLY; + return CONTINUE_BLISSFULLY; } -void EnumRawInputDevices() { - int count = 0; - if (GetRawInputDeviceList(0, (unsigned int*)&count, sizeof(RAWINPUTDEVICELIST)) != (UINT)-1 && count > 0) { - wchar_t *instanceID = (wchar_t *) malloc(41000*sizeof(wchar_t)); - wchar_t *keyName = instanceID + 11000; - wchar_t *displayName = keyName + 10000; - wchar_t *productID = displayName + 10000; +void EnumRawInputDevices() +{ + int count = 0; + if (GetRawInputDeviceList(0, (unsigned int *)&count, sizeof(RAWINPUTDEVICELIST)) != (UINT)-1 && count > 0) { + wchar_t *instanceID = (wchar_t *)malloc(41000 * sizeof(wchar_t)); + wchar_t *keyName = instanceID + 11000; + wchar_t *displayName = keyName + 10000; + wchar_t *productID = displayName + 10000; - RAWINPUTDEVICELIST *list = (RAWINPUTDEVICELIST*) malloc(sizeof(RAWINPUTDEVICELIST) * count); - int keyboardCount = 1; - int mouseCount = 1; - count = GetRawInputDeviceList(list, (unsigned int*)&count, sizeof(RAWINPUTDEVICELIST)); + RAWINPUTDEVICELIST *list = (RAWINPUTDEVICELIST *)malloc(sizeof(RAWINPUTDEVICELIST) * count); + int keyboardCount = 1; + int mouseCount = 1; + count = GetRawInputDeviceList(list, (unsigned int *)&count, sizeof(RAWINPUTDEVICELIST)); - // Not necessary, but reminder that count is -1 on failure. - if (count > 0) { - for (int i=0; i 0) { + for (int i = 0; i < count; i++) { + if (list[i].dwType != RIM_TYPEKEYBOARD && list[i].dwType != RIM_TYPEMOUSE) + continue; - UINT bufferLen = 10000; - int nameLen = GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &bufferLen); - if (nameLen >= 4) { - // nameLen includes terminating null. - nameLen--; + UINT bufferLen = 10000; + int nameLen = GetRawInputDeviceInfo(list[i].hDevice, RIDI_DEVICENAME, instanceID, &bufferLen); + if (nameLen >= 4) { + // nameLen includes terminating null. + nameLen--; - // Strip out GUID parts of instanceID to make it a generic product id, - // and reformat it to point to registry entry containing device description. - wcscpy(productID, instanceID); - wchar_t *temp = 0; - for (int j=0; j<3; j++) { - wchar_t *s = wcschr(productID, '#'); - if (!s) break; - *s = '\\'; - if (j==2) { - *s = 0; - } - if (j==1) temp = s; - } + // Strip out GUID parts of instanceID to make it a generic product id, + // and reformat it to point to registry entry containing device description. + wcscpy(productID, instanceID); + wchar_t *temp = 0; + for (int j = 0; j < 3; j++) { + wchar_t *s = wcschr(productID, '#'); + if (!s) + break; + *s = '\\'; + if (j == 2) { + *s = 0; + } + if (j == 1) + temp = s; + } - wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID+3); - if (temp) *temp = 0; - int haveDescription = 0; - HKEY hKey; - if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey)) { - DWORD type; - DWORD len = 10000 * sizeof(wchar_t); - if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE*)displayName, &len) && - len && type == REG_SZ) { - wchar_t *temp2 = wcsrchr(displayName, ';'); - if (!temp2) temp2 = displayName; - else temp2++; - // Could do without this, but more effort than it's worth. - wcscpy(keyName, temp2); - haveDescription = 1; - } - RegCloseKey(hKey); - } - if (list[i].dwType == RIM_TYPEKEYBOARD) { - if (!haveDescription) wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++); - else wsprintfW(displayName, L"Raw KB: %s", keyName); - dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID)); - } - else if (list[i].dwType == RIM_TYPEMOUSE) { - if (!haveDescription) wsprintfW(displayName, L"Raw Mouse %i", mouseCount++); - else wsprintfW(displayName, L"Raw MS: %s", keyName); - dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID)); - } - } - } - } - free(list); - free(instanceID); - dm->AddDevice(new RawInputKeyboard(0, L"Simulated Keyboard")); - dm->AddDevice(new RawInputMouse(0, L"Simulated Mouse")); - } + wsprintfW(keyName, L"SYSTEM\\CurrentControlSet\\Enum%s", productID + 3); + if (temp) + *temp = 0; + int haveDescription = 0; + HKEY hKey; + if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &hKey)) { + DWORD type; + DWORD len = 10000 * sizeof(wchar_t); + if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"DeviceDesc", 0, &type, (BYTE *)displayName, &len) && + len && type == REG_SZ) { + wchar_t *temp2 = wcsrchr(displayName, ';'); + if (!temp2) + temp2 = displayName; + else + temp2++; + // Could do without this, but more effort than it's worth. + wcscpy(keyName, temp2); + haveDescription = 1; + } + RegCloseKey(hKey); + } + if (list[i].dwType == RIM_TYPEKEYBOARD) { + if (!haveDescription) + wsprintfW(displayName, L"Raw Keyboard %i", keyboardCount++); + else + wsprintfW(displayName, L"Raw KB: %s", keyName); + dm->AddDevice(new RawInputKeyboard(list[i].hDevice, displayName, instanceID)); + } else if (list[i].dwType == RIM_TYPEMOUSE) { + if (!haveDescription) + wsprintfW(displayName, L"Raw Mouse %i", mouseCount++); + else + wsprintfW(displayName, L"Raw MS: %s", keyName); + dm->AddDevice(new RawInputMouse(list[i].hDevice, displayName, instanceID, productID)); + } + } + } + } + free(list); + free(instanceID); + dm->AddDevice(new RawInputKeyboard(0, L"Simulated Keyboard")); + dm->AddDevice(new RawInputMouse(0, L"Simulated Mouse")); + } } diff --git a/plugins/LilyPad/VKey.cpp b/plugins/LilyPad/VKey.cpp index 3f1b5b4811..24952fe643 100644 --- a/plugins/LilyPad/VKey.cpp +++ b/plugins/LilyPad/VKey.cpp @@ -18,68 +18,91 @@ #include "Global.h" #include "VKey.h" -wchar_t *GetVKStringW(unsigned char vk) { - int flag; - static wchar_t t[20]; - switch(vk) { - case 0x0C: return L"Clear"; - case 0x13: return L"Pause"; +wchar_t *GetVKStringW(unsigned char vk) +{ + int flag; + static wchar_t t[20]; + switch (vk) { + case 0x0C: + return L"Clear"; + case 0x13: + return L"Pause"; - case 0x21:// return "Page Up"; - case 0x22:// return "Page Down"; - case 0x23:// return "End"; - case 0x24:// return "Home"; - case 0x25:// return "Left"; - case 0x26:// return "Up"; - case 0x27:// return "Right"; - case 0x28:// return "Down"; - case 0x2D:// return "Insert"; - case 0x2E:// return "Delete"; - case 0x5B:// return "Left Windows"; - case 0x5C:// return "Right Windows"; - case 0x5D:// return "Application"; - case 0x6F:// return "Num /"; - flag = 1<<24; - break; + case 0x21: // return "Page Up"; + case 0x22: // return "Page Down"; + case 0x23: // return "End"; + case 0x24: // return "Home"; + case 0x25: // return "Left"; + case 0x26: // return "Up"; + case 0x27: // return "Right"; + case 0x28: // return "Down"; + case 0x2D: // return "Insert"; + case 0x2E: // return "Delete"; + case 0x5B: // return "Left Windows"; + case 0x5C: // return "Right Windows"; + case 0x5D: // return "Application"; + case 0x6F: // return "Num /"; + flag = 1 << 24; + break; - case 0x29: return L"Select"; - case 0x2A: return L"Print"; - case 0x2B: return L"Execute"; - case 0x2C: return L"Prnt Scrn"; - case 0x2F: return L"Help"; + case 0x29: + return L"Select"; + case 0x2A: + return L"Print"; + case 0x2B: + return L"Execute"; + case 0x2C: + return L"Prnt Scrn"; + case 0x2F: + return L"Help"; - case 0x6C: return L"|"; - case 0x90: return L"Num Lock"; + case 0x6C: + return L"|"; + case 0x90: + return L"Num Lock"; - case 0xA0: return L"Left Shift"; - case 0xA1: return L"Right Shift"; - case 0xA2: return L"Left Ctrl"; - case 0xA3: return L"Right Ctrl"; - case 0xA4: return L"Left Alt"; - case 0xA5: return L"Right Alt"; + case 0xA0: + return L"Left Shift"; + case 0xA1: + return L"Right Shift"; + case 0xA2: + return L"Left Ctrl"; + case 0xA3: + return L"Right Ctrl"; + case 0xA4: + return L"Left Alt"; + case 0xA5: + return L"Right Alt"; - case 0xA6: return L"Back"; - case 0xA7: return L"Forward"; - case 0xA8: return L"Refresh"; - case 0xA9: return L"Stop"; - case 0xAA: return L"Search"; - case 0xAB: return L"Favorites"; - case 0xAC: return L"Browser"; + case 0xA6: + return L"Back"; + case 0xA7: + return L"Forward"; + case 0xA8: + return L"Refresh"; + case 0xA9: + return L"Stop"; + case 0xAA: + return L"Search"; + case 0xAB: + return L"Favorites"; + case 0xAC: + return L"Browser"; - case 0xFA: return L"Play"; - case 0xFB: return L"Zoom"; - default: - flag = 0; - break; - } - int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC); - if (res && GetKeyNameText((res<<16) | flag, t, 20)) { - // don't trust windows - t[19] = 0; - } - else { - wsprintfW(t, L"Key %i", vk); - } - return t; + case 0xFA: + return L"Play"; + case 0xFB: + return L"Zoom"; + default: + flag = 0; + break; + } + int res = MapVirtualKey(vk, MAPVK_VK_TO_VSC); + if (res && GetKeyNameText((res << 16) | flag, t, 20)) { + // don't trust windows + t[19] = 0; + } else { + wsprintfW(t, L"Key %i", vk); + } + return t; } - diff --git a/plugins/LilyPad/WindowsKeyboard.cpp b/plugins/LilyPad/WindowsKeyboard.cpp index a7d0599544..83b134b76e 100644 --- a/plugins/LilyPad/WindowsKeyboard.cpp +++ b/plugins/LilyPad/WindowsKeyboard.cpp @@ -21,45 +21,51 @@ #include "WindowsKeyboard.h" #include "KeyboardQueue.h" -WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) : -Device(api, KEYBOARD, displayName, instanceID, deviceID) { - for (int i=0; i<256; i++) { - AddPhysicalControl(PSHBTN, i, i); - } +WindowsKeyboard::WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) + : Device(api, KEYBOARD, displayName, instanceID, deviceID) +{ + for (int i = 0; i < 256; i++) { + AddPhysicalControl(PSHBTN, i, i); + } } -wchar_t *WindowsKeyboard::GetPhysicalControlName(PhysicalControl *control) { - int id = control->id; - if (control->type == PSHBTN && id >= 0 && id < 256) { - wchar_t *w = GetVKStringW(id); - if (w) return w; - } - return Device::GetPhysicalControlName(control); +wchar_t *WindowsKeyboard::GetPhysicalControlName(PhysicalControl *control) +{ + int id = control->id; + if (control->type == PSHBTN && id >= 0 && id < 256) { + wchar_t *w = GetVKStringW(id); + if (w) + return w; + } + return Device::GetPhysicalControlName(control); } -void WindowsKeyboard::UpdateKey(int vkey, int state) { - if (vkey > 7 && vkey < 256) { - int newState = state * FULLY_DOWN; - if (newState != physicalControlState[vkey]) { - // Check for alt-F4 to avoid toggling skip mode incorrectly. - if (vkey != VK_F4 || !(physicalControlState[VK_MENU] || physicalControlState[VK_RMENU] || physicalControlState[VK_LMENU])) { - int event = KEYPRESS; - if (!newState) event = KEYRELEASE; - QueueKeyEvent(vkey, event); - } - } - physicalControlState[vkey] = newState; - } +void WindowsKeyboard::UpdateKey(int vkey, int state) +{ + if (vkey > 7 && vkey < 256) { + int newState = state * FULLY_DOWN; + if (newState != physicalControlState[vkey]) { + // Check for alt-F4 to avoid toggling skip mode incorrectly. + if (vkey != VK_F4 || !(physicalControlState[VK_MENU] || physicalControlState[VK_RMENU] || physicalControlState[VK_LMENU])) { + int event = KEYPRESS; + if (!newState) + event = KEYRELEASE; + QueueKeyEvent(vkey, event); + } + } + physicalControlState[vkey] = newState; + } } -void WindowsKeyboard::InitState() { - AllocState(); - for (int vkey=5; vkey<256; vkey++) { - int value = (unsigned short)(((short)GetAsyncKeyState(vkey))>>15); - value += value&1; - if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT) { - value = 0; - } - physicalControlState[vkey] = value; - } +void WindowsKeyboard::InitState() +{ + AllocState(); + for (int vkey = 5; vkey < 256; vkey++) { + int value = (unsigned short)(((short)GetAsyncKeyState(vkey)) >> 15); + value += value & 1; + if (vkey == VK_CONTROL || vkey == VK_MENU || vkey == VK_SHIFT) { + value = 0; + } + physicalControlState[vkey] = value; + } } diff --git a/plugins/LilyPad/WindowsKeyboard.h b/plugins/LilyPad/WindowsKeyboard.h index 00d86eb0a2..2e7fa4c86c 100644 --- a/plugins/LilyPad/WindowsKeyboard.h +++ b/plugins/LilyPad/WindowsKeyboard.h @@ -16,12 +16,13 @@ */ // Shared functionality for WM and RAW keyboards. -class WindowsKeyboard : public Device { +class WindowsKeyboard : public Device +{ public: - WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID=0, wchar_t *deviceID=0); - wchar_t *GetPhysicalControlName(PhysicalControl *control); - void UpdateKey(int vkey, int state); - // Calls AllocState() and initializes to current keyboard state using - // GetAsyncKeyState(). - void InitState(); + WindowsKeyboard(DeviceAPI api, wchar_t *displayName, wchar_t *instanceID = 0, wchar_t *deviceID = 0); + wchar_t *GetPhysicalControlName(PhysicalControl *control); + void UpdateKey(int vkey, int state); + // Calls AllocState() and initializes to current keyboard state using + // GetAsyncKeyState(). + void InitState(); }; diff --git a/plugins/LilyPad/WindowsMessaging.cpp b/plugins/LilyPad/WindowsMessaging.cpp index eafce496b5..c2454ece7d 100644 --- a/plugins/LilyPad/WindowsMessaging.cpp +++ b/plugins/LilyPad/WindowsMessaging.cpp @@ -32,160 +32,162 @@ class WindowsMessagingMouse; static WindowsMessagingKeyboard *wmk = 0; static WindowsMessagingMouse *wmm = 0; -class WindowsMessagingKeyboard : public WindowsKeyboard { +class WindowsMessagingKeyboard : public WindowsKeyboard +{ public: + WindowsMessagingKeyboard() + : WindowsKeyboard(WM, L"WM Keyboard") + { + } - WindowsMessagingKeyboard() : WindowsKeyboard(WM, L"WM Keyboard") { - } + int Activate(InitInfo *initInfo) + { + // Redundant. Should match the next line. + // Deactivate(); + if (wmk) + wmk->Deactivate(); - int Activate(InitInfo *initInfo) { - // Redundant. Should match the next line. - // Deactivate(); - if (wmk) wmk->Deactivate(); + hWndProc = initInfo->hWndProc; - hWndProc = initInfo->hWndProc; + if (!wmm) + hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); - if (!wmm) - hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); + wmk = this; + InitState(); - wmk = this; - InitState(); + active = 1; + return 1; + } - active = 1; - return 1; - } - - void Deactivate() { - if (active) { - if (!wmm) - hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); - wmk = 0; - active = 0; - FreeState(); - } - } + void Deactivate() + { + if (active) { + if (!wmm) + hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); + wmk = 0; + active = 0; + FreeState(); + } + } - void CheckKey(int vkey) { - UpdateKey(vkey, 1&(((unsigned short)GetAsyncKeyState(vkey))>>15)); - } + void CheckKey(int vkey) + { + UpdateKey(vkey, 1 & (((unsigned short)GetAsyncKeyState(vkey)) >> 15)); + } }; -class WindowsMessagingMouse : public WindowsMouse { +class WindowsMessagingMouse : public WindowsMouse +{ public: + WindowsMessagingMouse() + : WindowsMouse(WM, 1, L"WM Mouse") + { + } - WindowsMessagingMouse() : WindowsMouse(WM, 1, L"WM Mouse") { - } + int Activate(InitInfo *initInfo) + { + // Redundant. Should match the next line. + // Deactivate(); + if (wmm) + wmm->Deactivate(); + hWndProc = initInfo->hWndProc; - int Activate(InitInfo *initInfo) { - // Redundant. Should match the next line. - // Deactivate(); - if (wmm) wmm->Deactivate(); - hWndProc = initInfo->hWndProc; + if (!wmk) + hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); - if (!wmk) - hWndProc->Eat(WindowsMessagingWndProc, EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES); + GetMouseCapture(hWndProc->hWndEaten); - GetMouseCapture(hWndProc->hWndEaten); + active = 1; - active = 1; + wmm = this; + AllocState(); - wmm = this; - AllocState(); + return 1; + } - return 1; - } - - void Deactivate() { - if (active) { - if (!wmk) - hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); - ReleaseMouseCapture(); - wmm = 0; - active = 0; - FreeState(); - } - } + void Deactivate() + { + if (active) { + if (!wmk) + hWndProc->ReleaseExtraProc(WindowsMessagingWndProc); + ReleaseMouseCapture(); + wmm = 0; + active = 0; + FreeState(); + } + } }; -ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) { - if (wmk) { - if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) { - if (wParam == VK_SHIFT) { - wmk->CheckKey(VK_RSHIFT); - wmk->CheckKey(VK_LSHIFT); - } - else if (wParam == VK_CONTROL) { - wmk->CheckKey(VK_RCONTROL); - wmk->CheckKey(VK_LCONTROL); - } - else if (wParam == VK_MENU) { - wmk->CheckKey(VK_RMENU); - wmk->CheckKey(VK_LMENU); - } - else - wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)); - return NO_WND_PROC; - } - // Needed to prevent default handling of keys in some situations. - else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) { - return NO_WND_PROC; - } - else if (uMsg == WM_ACTIVATE) { - // Not really needed, but doesn't hurt. - memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls); - } - } - if (wmm) { - if (uMsg == WM_MOUSEMOVE) { - POINT p; - GetCursorPos(&p); - // Need check to prevent cursor movement cascade. - if (p.x != wmm->center.x || p.y != wmm->center.y) { - wmm->UpdateAxis(0, p.x - wmm->center.x); - wmm->UpdateAxis(1, p.y - wmm->center.y); +ExtraWndProcResult WindowsMessagingWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *output) +{ + if (wmk) { + if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN || uMsg == WM_KEYUP || uMsg == WM_SYSKEYUP) { + if (wParam == VK_SHIFT) { + wmk->CheckKey(VK_RSHIFT); + wmk->CheckKey(VK_LSHIFT); + } else if (wParam == VK_CONTROL) { + wmk->CheckKey(VK_RCONTROL); + wmk->CheckKey(VK_LCONTROL); + } else if (wParam == VK_MENU) { + wmk->CheckKey(VK_RMENU); + wmk->CheckKey(VK_LMENU); + } else + wmk->UpdateKey(wParam, (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)); + return NO_WND_PROC; + } + // Needed to prevent default handling of keys in some situations. + else if (uMsg == WM_CHAR || uMsg == WM_UNICHAR) { + return NO_WND_PROC; + } else if (uMsg == WM_ACTIVATE) { + // Not really needed, but doesn't hurt. + memset(wmk->physicalControlState, 0, sizeof(int) * wmk->numPhysicalControls); + } + } + if (wmm) { + if (uMsg == WM_MOUSEMOVE) { + POINT p; + GetCursorPos(&p); + // Need check to prevent cursor movement cascade. + if (p.x != wmm->center.x || p.y != wmm->center.y) { + wmm->UpdateAxis(0, p.x - wmm->center.x); + wmm->UpdateAxis(1, p.y - wmm->center.y); - SetCursorPos(wmm->center.x, wmm->center.y); - } - return NO_WND_PROC; - } - else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) { - wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN); - return NO_WND_PROC; - } - else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) { - wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN); - return NO_WND_PROC; - } - else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) { - wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN); - return NO_WND_PROC; - } - else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) { - wmm->UpdateButton(3+((wParam>>16) == XBUTTON2), uMsg == WM_XBUTTONDOWN); - return NO_WND_PROC; - } - else if (uMsg == WM_MOUSEWHEEL) { - wmm->UpdateAxis(2, ((int)wParam>>16)/WHEEL_DELTA); - return NO_WND_PROC; - } - else if (uMsg == WM_MOUSEHWHEEL) { - wmm->UpdateAxis(3, ((int)wParam>>16)/WHEEL_DELTA); - return NO_WND_PROC; - } - else if (uMsg == WM_SIZE && wmm->active) { - WindowsMouse::WindowResized(hWnd); - } - // Taken care of elsewhere. When binding, killing focus means stop reading input. - // When running PCSX2, I release all mouse and keyboard input elsewhere. - /*else if (uMsg == WM_KILLFOCUS) { + SetCursorPos(wmm->center.x, wmm->center.y); + } + return NO_WND_PROC; + } else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP) { + wmm->UpdateButton(0, uMsg == WM_LBUTTONDOWN); + return NO_WND_PROC; + } else if (uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONUP) { + wmm->UpdateButton(1, uMsg == WM_RBUTTONDOWN); + return NO_WND_PROC; + } else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP) { + wmm->UpdateButton(2, uMsg == WM_MBUTTONDOWN); + return NO_WND_PROC; + } else if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP) { + wmm->UpdateButton(3 + ((wParam >> 16) == XBUTTON2), uMsg == WM_XBUTTONDOWN); + return NO_WND_PROC; + } else if (uMsg == WM_MOUSEWHEEL) { + wmm->UpdateAxis(2, ((int)wParam >> 16) / WHEEL_DELTA); + return NO_WND_PROC; + } else if (uMsg == WM_MOUSEHWHEEL) { + wmm->UpdateAxis(3, ((int)wParam >> 16) / WHEEL_DELTA); + return NO_WND_PROC; + } else if (uMsg == WM_SIZE && wmm->active) { + WindowsMouse::WindowResized(hWnd); + } + // Taken care of elsewhere. When binding, killing focus means stop reading input. + // When running PCSX2, I release all mouse and keyboard input elsewhere. + /*else if (uMsg == WM_KILLFOCUS) { wmm->Deactivate(); }//*/ - } - return CONTINUE_BLISSFULLY; + } + return CONTINUE_BLISSFULLY; } -void EnumWindowsMessagingDevices() { - dm->AddDevice(new WindowsMessagingKeyboard()); - dm->AddDevice(new WindowsMessagingMouse()); +void EnumWindowsMessagingDevices() +{ + dm->AddDevice(new WindowsMessagingKeyboard()); + dm->AddDevice(new WindowsMessagingMouse()); } diff --git a/plugins/LilyPad/WindowsMouse.cpp b/plugins/LilyPad/WindowsMouse.cpp index 9e9e642ecc..8064b74b99 100644 --- a/plugins/LilyPad/WindowsMouse.cpp +++ b/plugins/LilyPad/WindowsMouse.cpp @@ -23,71 +23,80 @@ POINT WindowsMouse::origCursorPos; POINT WindowsMouse::center; -WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) : -Device(api, MOUSE, displayName, instanceID, deviceID) { - int i; - for (i=0; i<5; i++) { - AddPhysicalControl(PSHBTN, i, i); - } +WindowsMouse::WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID, wchar_t *deviceID) + : Device(api, MOUSE, displayName, instanceID, deviceID) +{ + int i; + for (i = 0; i < 5; i++) { + AddPhysicalControl(PSHBTN, i, i); + } - for (i=0; i<3+hWheel; i++) { - AddPhysicalControl(RELAXIS, i+5, i+5); - } + for (i = 0; i < 3 + hWheel; i++) { + AddPhysicalControl(RELAXIS, i + 5, i + 5); + } } -wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control) { - wchar_t *names[9] = { - L"L Button", - L"R Button", - L"M Button", - L"Mouse 4", - L"Mouse 5", - L"X Axis", - L"Y Axis", - L"Y Wheel", - L"X Wheel" - }; - if (control->id < 9) return names[control->id]; - return Device::GetPhysicalControlName(control); +wchar_t *WindowsMouse::GetPhysicalControlName(PhysicalControl *control) +{ + wchar_t *names[9] = { + L"L Button", + L"R Button", + L"M Button", + L"Mouse 4", + L"Mouse 5", + L"X Axis", + L"Y Axis", + L"Y Wheel", + L"X Wheel"}; + if (control->id < 9) + return names[control->id]; + return Device::GetPhysicalControlName(control); } -void WindowsMouse::UpdateButton(unsigned int button, int state) { - if (button > 4) return; - physicalControlState[button] = (state << 16); +void WindowsMouse::UpdateButton(unsigned int button, int state) +{ + if (button > 4) + return; + physicalControlState[button] = (state << 16); } -void WindowsMouse::UpdateAxis(unsigned int axis, int delta) { - if (axis > 3) return; - // 1 mouse pixel = 1/8th way down. - physicalControlState[5+axis] += (delta<<(16 - 3*(axis < 2))); +void WindowsMouse::UpdateAxis(unsigned int axis, int delta) +{ + if (axis > 3) + return; + // 1 mouse pixel = 1/8th way down. + physicalControlState[5 + axis] += (delta << (16 - 3 * (axis < 2))); } -void WindowsMouse::WindowResized(HWND hWnd) { - RECT r; - GetWindowRect(hWnd, &r); - ClipCursor(&r); - center.x = (r.left + r.right)/2; - center.y = (r.top + r.bottom)/2; - SetCursorPos(center.x, center.y); +void WindowsMouse::WindowResized(HWND hWnd) +{ + RECT r; + GetWindowRect(hWnd, &r); + ClipCursor(&r); + center.x = (r.left + r.right) / 2; + center.y = (r.top + r.bottom) / 2; + SetCursorPos(center.x, center.y); } -void WindowsMouse::GetMouseCapture(HWND hWnd) { - SetCapture(hWnd); - ShowCursor(0); +void WindowsMouse::GetMouseCapture(HWND hWnd) +{ + SetCapture(hWnd); + ShowCursor(0); - GetCursorPos(&origCursorPos); + GetCursorPos(&origCursorPos); - RECT r; - GetWindowRect(hWnd, &r); - ClipCursor(&r); - center.x = (r.left + r.right)/2; - center.y = (r.top + r.bottom)/2; - SetCursorPos(center.x, center.y); + RECT r; + GetWindowRect(hWnd, &r); + ClipCursor(&r); + center.x = (r.left + r.right) / 2; + center.y = (r.top + r.bottom) / 2; + SetCursorPos(center.x, center.y); } -void WindowsMouse::ReleaseMouseCapture() { - ClipCursor(0); - ReleaseCapture(); - ShowCursor(1); - SetCursorPos(origCursorPos.x, origCursorPos.y); +void WindowsMouse::ReleaseMouseCapture() +{ + ClipCursor(0); + ReleaseCapture(); + ShowCursor(1); + SetCursorPos(origCursorPos.x, origCursorPos.y); } diff --git a/plugins/LilyPad/WindowsMouse.h b/plugins/LilyPad/WindowsMouse.h index 4a8f45b6b4..323cbe64be 100644 --- a/plugins/LilyPad/WindowsMouse.h +++ b/plugins/LilyPad/WindowsMouse.h @@ -16,26 +16,27 @@ */ // Shared functionality for WM and RAW keyboards. -class WindowsMouse : public Device { +class WindowsMouse : public Device +{ public: - // Used by GetMouseCapture()/ReleaseMouseCapture() - // Static because can have multiple raw mice active at once, - // and only get/release capture once. - static POINT origCursorPos; - static POINT center; + // Used by GetMouseCapture()/ReleaseMouseCapture() + // Static because can have multiple raw mice active at once, + // and only get/release capture once. + static POINT origCursorPos; + static POINT center; - static void GetMouseCapture(HWND hWnd); - static void WindowResized(HWND hWnd); - static void ReleaseMouseCapture(); + static void GetMouseCapture(HWND hWnd); + static void WindowResized(HWND hWnd); + static void ReleaseMouseCapture(); - // hWheel variable lets me display no horizontal wheel for raw input, just to make it clear - // that it's not supported. - WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID=0, wchar_t *deviceID=0); - wchar_t *GetPhysicalControlName(PhysicalControl *control); - // State is 0 for up, 1 for down. - void UpdateButton(unsigned int button, int state); - // 0/1 are x/y. 2 is vert wheel, 3 is horiz wheel. - // Delta is in my micro units. change of (1<<16) is 1 full unit, with - // the default sensitivity. - void UpdateAxis(unsigned int axis, int delta); + // hWheel variable lets me display no horizontal wheel for raw input, just to make it clear + // that it's not supported. + WindowsMouse(DeviceAPI api, int hWheel, wchar_t *displayName, wchar_t *instanceID = 0, wchar_t *deviceID = 0); + wchar_t *GetPhysicalControlName(PhysicalControl *control); + // State is 0 for up, 1 for down. + void UpdateButton(unsigned int button, int state); + // 0/1 are x/y. 2 is vert wheel, 3 is horiz wheel. + // Delta is in my micro units. change of (1<<16) is 1 full unit, with + // the default sensitivity. + void UpdateAxis(unsigned int axis, int delta); }; diff --git a/plugins/LilyPad/WndProcEater.cpp b/plugins/LilyPad/WndProcEater.cpp index 32f34602d2..0379005d18 100644 --- a/plugins/LilyPad/WndProcEater.cpp +++ b/plugins/LilyPad/WndProcEater.cpp @@ -20,128 +20,136 @@ WndProcEater::WndProcEater() { - hWndEaten = 0; - eatenWndProc = 0; + hWndEaten = 0; + eatenWndProc = 0; - extraProcs = 0; - numExtraProcs = 0; + extraProcs = 0; + numExtraProcs = 0; - hMutex = CreateMutex(0, 0, L"LilyPad"); + hMutex = CreateMutex(0, 0, L"LilyPad"); } WndProcEater::~WndProcEater() throw() { - if (hMutex) { - ReleaseMutex(hMutex); - CloseHandle(hMutex); - } + if (hMutex) { + ReleaseMutex(hMutex); + CloseHandle(hMutex); + } } -void WndProcEater::ReleaseExtraProc(ExtraWndProc proc) { - // Probably isn't needed, but just in case... - if (hMutex) WaitForSingleObject(hMutex, 100); +void WndProcEater::ReleaseExtraProc(ExtraWndProc proc) +{ + // Probably isn't needed, but just in case... + if (hMutex) + WaitForSingleObject(hMutex, 100); - //printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc ); + //printf( "(Lilypad) Regurgitating! -> 0x%x\n", proc ); - for (int i=0; i res) res = res2; - } - } + ExtraWndProcResult res2 = extraProcs[i].proc(hWnd, uMsg, wParam, lParam, &out); + if (res2 != res) { + if (res2 == CONTINUE_BLISSFULLY_AND_RELEASE_PROC) { + ReleaseExtraProc(extraProcs[i].proc); + i--; + } else if (res2 > res) + res = res2; + } + } - if (res != NO_WND_PROC) { - if (out == WM_DESTROY) { - Release(); - } - if (res == CONTINUE_BLISSFULLY) - out = CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam); - else if (res == USE_DEFAULT_WND_PROC) - out = DefWindowProc(hWnd, uMsg, wParam, lParam); - } - return out; + if (res != NO_WND_PROC) { + if (out == WM_DESTROY) { + Release(); + } + if (res == CONTINUE_BLISSFULLY) + out = CallWindowProc(eatenWndProc, hWnd, uMsg, wParam, lParam); + else if (res == USE_DEFAULT_WND_PROC) + out = DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return out; } static LRESULT CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - WndProcEater* obj = (WndProcEater*)GetProp(hWnd, L"LilyHaxxor"); - return (obj == NULL) ? - DefWindowProc(hWnd, uMsg, wParam, lParam) : - obj->_OverrideWndProc( hWnd, uMsg, wParam, lParam ); + WndProcEater *obj = (WndProcEater *)GetProp(hWnd, L"LilyHaxxor"); + return (obj == NULL) ? + DefWindowProc(hWnd, uMsg, wParam, lParam) : + obj->_OverrideWndProc(hWnd, uMsg, wParam, lParam); } bool WndProcEater::SetWndHandle(HWND hWnd) { - if(hWnd == hWndEaten) return true; + if (hWnd == hWndEaten) + return true; - //printf( "(Lilypad) (Re)-Setting window handle! -> this=0x%08x, hWnd=0x%08x\n", this, hWnd ); + //printf( "(Lilypad) (Re)-Setting window handle! -> this=0x%08x, hWnd=0x%08x\n", this, hWnd ); - Release(); - SetProp(hWnd, L"LilyHaxxor", (HANDLE)this); + Release(); + SetProp(hWnd, L"LilyHaxxor", (HANDLE) this); - eatenWndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)OverrideWndProc); - hWndEaten = (eatenWndProc) ? hWnd : 0; + eatenWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)OverrideWndProc); + hWndEaten = (eatenWndProc) ? hWnd : 0; - return !!hWndEaten; + return !!hWndEaten; } -void WndProcEater::Eat(ExtraWndProc proc, DWORD flags) { +void WndProcEater::Eat(ExtraWndProc proc, DWORD flags) +{ - // check if Subclassing failed to init during SetWndHandle - if (!hWndEaten) return; + // check if Subclassing failed to init during SetWndHandle + if (!hWndEaten) + return; - // Probably isn't needed, but just in case... - if (hMutex) WaitForSingleObject(hMutex, 100); + // Probably isn't needed, but just in case... + if (hMutex) + WaitForSingleObject(hMutex, 100); - //printf( "(Lilypad) EatingWndProc! -> 0x%x\n", proc ); + //printf( "(Lilypad) EatingWndProc! -> 0x%x\n", proc ); - extraProcs = (ExtraWndProcInfo*) realloc(extraProcs, sizeof(ExtraWndProcInfo)*(numExtraProcs+1)); - extraProcs[numExtraProcs].proc = proc; - extraProcs[numExtraProcs].flags = flags; - numExtraProcs++; + extraProcs = (ExtraWndProcInfo *)realloc(extraProcs, sizeof(ExtraWndProcInfo) * (numExtraProcs + 1)); + extraProcs[numExtraProcs].proc = proc; + extraProcs[numExtraProcs].flags = flags; + numExtraProcs++; } diff --git a/plugins/LilyPad/WndProcEater.h b/plugins/LilyPad/WndProcEater.h index c7fa2ce225..bf324a715f 100644 --- a/plugins/LilyPad/WndProcEater.h +++ b/plugins/LilyPad/WndProcEater.h @@ -15,45 +15,46 @@ * with PCSX2. If not, see . */ -#define EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES 1 +#define EATPROC_NO_UPDATE_WHILE_UPDATING_DEVICES 1 /* Need this to let window be subclassed multiple times but still clean up nicely. */ enum ExtraWndProcResult { - CONTINUE_BLISSFULLY, - // Calls ReleaseExtraProc without messing up order. - CONTINUE_BLISSFULLY_AND_RELEASE_PROC, - USE_DEFAULT_WND_PROC, - NO_WND_PROC + CONTINUE_BLISSFULLY, + // Calls ReleaseExtraProc without messing up order. + CONTINUE_BLISSFULLY_AND_RELEASE_PROC, + USE_DEFAULT_WND_PROC, + NO_WND_PROC }; typedef ExtraWndProcResult (*ExtraWndProc)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *out); -struct ExtraWndProcInfo { - ExtraWndProc proc; - DWORD flags; +struct ExtraWndProcInfo +{ + ExtraWndProc proc; + DWORD flags; }; class WndProcEater { public: - HWND hWndEaten; - WNDPROC eatenWndProc; - ExtraWndProcInfo* extraProcs; - int numExtraProcs; + HWND hWndEaten; + WNDPROC eatenWndProc; + ExtraWndProcInfo *extraProcs; + int numExtraProcs; - HANDLE hMutex; + HANDLE hMutex; public: - WndProcEater(); - virtual ~WndProcEater() throw(); + WndProcEater(); + virtual ~WndProcEater() throw(); - bool SetWndHandle(HWND hWnd); - void Eat(ExtraWndProc proc, DWORD flags); - void ReleaseExtraProc(ExtraWndProc proc); - void Release(); + bool SetWndHandle(HWND hWnd); + void Eat(ExtraWndProc proc, DWORD flags); + void ReleaseExtraProc(ExtraWndProc proc); + void Release(); - LRESULT _OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + LRESULT _OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; extern WndProcEater hWndGSProc; diff --git a/plugins/LilyPad/XInputEnum.cpp b/plugins/LilyPad/XInputEnum.cpp index 9a5a5d57df..100d185aef 100644 --- a/plugins/LilyPad/XInputEnum.cpp +++ b/plugins/LilyPad/XInputEnum.cpp @@ -27,43 +27,43 @@ typedef struct { - float SCP_UP; - float SCP_RIGHT; - float SCP_DOWN; - float SCP_LEFT; + float SCP_UP; + float SCP_RIGHT; + float SCP_DOWN; + float SCP_LEFT; - float SCP_LX; - float SCP_LY; + float SCP_LX; + float SCP_LY; - float SCP_L1; - float SCP_L2; - float SCP_L3; + float SCP_L1; + float SCP_L2; + float SCP_L3; - float SCP_RX; - float SCP_RY; + float SCP_RX; + float SCP_RY; - float SCP_R1; - float SCP_R2; - float SCP_R3; + float SCP_R1; + float SCP_R2; + float SCP_R3; - float SCP_T; - float SCP_C; - float SCP_X; - float SCP_S; + float SCP_T; + float SCP_C; + float SCP_X; + float SCP_S; - float SCP_SELECT; - float SCP_START; + float SCP_SELECT; + float SCP_START; - float SCP_PS; + float SCP_PS; } SCP_EXTN; // This way, I don't require that XInput junk be installed. typedef void(CALLBACK *_XInputEnable)(BOOL enable); -typedef DWORD(CALLBACK *_XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE* pState); -typedef DWORD(CALLBACK *_XInputGetExtended)(DWORD dwUserIndex, SCP_EXTN* pPressure); -typedef DWORD(CALLBACK *_XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration); +typedef DWORD(CALLBACK *_XInputGetStateEx)(DWORD dwUserIndex, XINPUT_STATE *pState); +typedef DWORD(CALLBACK *_XInputGetExtended)(DWORD dwUserIndex, SCP_EXTN *pPressure); +typedef DWORD(CALLBACK *_XInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION *pVibration); _XInputEnable pXInputEnable = 0; _XInputGetStateEx pXInputGetStateEx = 0; @@ -73,215 +73,230 @@ _XInputSetState pXInputSetState = 0; static int xInputActiveCount = 0; // Completely unncessary, really. -__forceinline int ShortToAxis(int v) { - // If positive and at least 1 << 14, increment. - v += (!((v>>15)&1)) & ((v>>14)&1); - // Just double. - return v * 2; +__forceinline int ShortToAxis(int v) +{ + // If positive and at least 1 << 14, increment. + v += (!((v >> 15) & 1)) & ((v >> 14) & 1); + // Just double. + return v * 2; } -class XInputDevice : public Device { - // Cached last vibration values by pad and motor. - // Need this, as only one value is changed at a time. - int ps2Vibration[2][4][2]; - // Minor optimization - cache last set vibration values - // When there's no change, no need to do anything. - XINPUT_VIBRATION xInputVibration; +class XInputDevice : public Device +{ + // Cached last vibration values by pad and motor. + // Need this, as only one value is changed at a time. + int ps2Vibration[2][4][2]; + // Minor optimization - cache last set vibration values + // When there's no change, no need to do anything. + XINPUT_VIBRATION xInputVibration; + public: - int index; + int index; - XInputDevice(int index, wchar_t *displayName) : Device(XINPUT, OTHER, displayName) { - memset(ps2Vibration, 0, sizeof(ps2Vibration)); - memset(&xInputVibration, 0, sizeof(xInputVibration)); - this->index = index; - int i; - for (i=0; i<17; i++) { // Skip empty bit - AddPhysicalControl(PRESSURE_BTN, i + (i > 10), 0); - } - for (; i<21; i++) { - AddPhysicalControl(ABSAXIS, i + 2, 0); - } - AddFFAxis(L"Slow Motor", 0); - AddFFAxis(L"Fast Motor", 1); - AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT); - } + XInputDevice(int index, wchar_t *displayName) + : Device(XINPUT, OTHER, displayName) + { + memset(ps2Vibration, 0, sizeof(ps2Vibration)); + memset(&xInputVibration, 0, sizeof(xInputVibration)); + this->index = index; + int i; + for (i = 0; i < 17; i++) { // Skip empty bit + AddPhysicalControl(PRESSURE_BTN, i + (i > 10), 0); + } + for (; i < 21; i++) { + AddPhysicalControl(ABSAXIS, i + 2, 0); + } + AddFFAxis(L"Slow Motor", 0); + AddFFAxis(L"Fast Motor", 1); + AddFFEffectType(L"Constant Effect", L"Constant", EFFECT_CONSTANT); + } - wchar_t *GetPhysicalControlName(PhysicalControl *c) { - const static wchar_t *names[] = { - L"D-pad Up", - L"D-pad Down", - L"D-pad Left", - L"D-pad Right", - L"Start", - L"Back", - L"Left Thumb", - L"Right Thumb", - L"Left Shoulder", - L"Right Shoulder", - L"Guide", - L"A", - L"B", - L"X", - L"Y", - L"Left Trigger", - L"Right Trigger", - L"Left Thumb X", - L"Left Thumb Y", - L"Right Thumb X", - L"Right Thumb Y", - }; - unsigned int i = (unsigned int) (c - physicalControls); - if (i < 21) { - return (wchar_t*)names[i]; - } - return Device::GetPhysicalControlName(c); - } + wchar_t *GetPhysicalControlName(PhysicalControl *c) + { + const static wchar_t *names[] = { + L"D-pad Up", + L"D-pad Down", + L"D-pad Left", + L"D-pad Right", + L"Start", + L"Back", + L"Left Thumb", + L"Right Thumb", + L"Left Shoulder", + L"Right Shoulder", + L"Guide", + L"A", + L"B", + L"X", + L"Y", + L"Left Trigger", + L"Right Trigger", + L"Left Thumb X", + L"Left Thumb Y", + L"Right Thumb X", + L"Right Thumb Y", + }; + unsigned int i = (unsigned int)(c - physicalControls); + if (i < 21) { + return (wchar_t *)names[i]; + } + return Device::GetPhysicalControlName(c); + } - int Activate(InitInfo *initInfo) { - if (active) Deactivate(); - if (!xInputActiveCount) { - pXInputEnable(1); - } - xInputActiveCount++; - active = 1; - AllocState(); - return 1; - } + int Activate(InitInfo *initInfo) + { + if (active) + Deactivate(); + if (!xInputActiveCount) { + pXInputEnable(1); + } + xInputActiveCount++; + active = 1; + AllocState(); + return 1; + } - int Update() { - if (!active) return 0; - XINPUT_STATE state; - if (ERROR_SUCCESS != pXInputGetStateEx(index, &state)) { - Deactivate(); - return 0; - } - SCP_EXTN pressure; - if (!pXInputGetExtended || (ERROR_SUCCESS != pXInputGetExtended(index, &pressure))) { - int buttons = state.Gamepad.wButtons; - for (int i = 0; i < 15; i++) { - physicalControlState[i] = ((buttons >> physicalControls[i].id) & 1) << 16; - } - physicalControlState[15] = (int)(state.Gamepad.bLeftTrigger * 257.005); - physicalControlState[16] = (int)(state.Gamepad.bRightTrigger * 257.005); - physicalControlState[17] = ShortToAxis(state.Gamepad.sThumbLX); - physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbLY); - physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRX); - physicalControlState[20] = ShortToAxis(state.Gamepad.sThumbRY); - } else { - physicalControlState[0] = (int)(pressure.SCP_UP * FULLY_DOWN); - physicalControlState[1] = (int)(pressure.SCP_DOWN * FULLY_DOWN); - physicalControlState[2] = (int)(pressure.SCP_LEFT * FULLY_DOWN); - physicalControlState[3] = (int)(pressure.SCP_RIGHT * FULLY_DOWN); - physicalControlState[4] = (int)(pressure.SCP_START * FULLY_DOWN); - physicalControlState[5] = (int)(pressure.SCP_SELECT * FULLY_DOWN); - physicalControlState[6] = (int)(pressure.SCP_L3 * FULLY_DOWN); - physicalControlState[7] = (int)(pressure.SCP_R3 * FULLY_DOWN); - physicalControlState[8] = (int)(pressure.SCP_L1 * FULLY_DOWN); - physicalControlState[9] = (int)(pressure.SCP_R1 * FULLY_DOWN); - physicalControlState[10] = (int)(pressure.SCP_PS * FULLY_DOWN); - physicalControlState[11] = (int)(pressure.SCP_X * FULLY_DOWN); - physicalControlState[12] = (int)(pressure.SCP_C * FULLY_DOWN); - physicalControlState[13] = (int)(pressure.SCP_S * FULLY_DOWN); - physicalControlState[14] = (int)(pressure.SCP_T * FULLY_DOWN); - physicalControlState[15] = (int)(pressure.SCP_L2 * FULLY_DOWN); - physicalControlState[16] = (int)(pressure.SCP_R2 * FULLY_DOWN); - physicalControlState[17] = (int)(pressure.SCP_LX * FULLY_DOWN); - physicalControlState[18] = (int)(pressure.SCP_LY * FULLY_DOWN); - physicalControlState[19] = (int)(pressure.SCP_RX * FULLY_DOWN); - physicalControlState[20] = (int)(pressure.SCP_RY * FULLY_DOWN); - } - return 1; - } + int Update() + { + if (!active) + return 0; + XINPUT_STATE state; + if (ERROR_SUCCESS != pXInputGetStateEx(index, &state)) { + Deactivate(); + return 0; + } + SCP_EXTN pressure; + if (!pXInputGetExtended || (ERROR_SUCCESS != pXInputGetExtended(index, &pressure))) { + int buttons = state.Gamepad.wButtons; + for (int i = 0; i < 15; i++) { + physicalControlState[i] = ((buttons >> physicalControls[i].id) & 1) << 16; + } + physicalControlState[15] = (int)(state.Gamepad.bLeftTrigger * 257.005); + physicalControlState[16] = (int)(state.Gamepad.bRightTrigger * 257.005); + physicalControlState[17] = ShortToAxis(state.Gamepad.sThumbLX); + physicalControlState[18] = ShortToAxis(state.Gamepad.sThumbLY); + physicalControlState[19] = ShortToAxis(state.Gamepad.sThumbRX); + physicalControlState[20] = ShortToAxis(state.Gamepad.sThumbRY); + } else { + physicalControlState[0] = (int)(pressure.SCP_UP * FULLY_DOWN); + physicalControlState[1] = (int)(pressure.SCP_DOWN * FULLY_DOWN); + physicalControlState[2] = (int)(pressure.SCP_LEFT * FULLY_DOWN); + physicalControlState[3] = (int)(pressure.SCP_RIGHT * FULLY_DOWN); + physicalControlState[4] = (int)(pressure.SCP_START * FULLY_DOWN); + physicalControlState[5] = (int)(pressure.SCP_SELECT * FULLY_DOWN); + physicalControlState[6] = (int)(pressure.SCP_L3 * FULLY_DOWN); + physicalControlState[7] = (int)(pressure.SCP_R3 * FULLY_DOWN); + physicalControlState[8] = (int)(pressure.SCP_L1 * FULLY_DOWN); + physicalControlState[9] = (int)(pressure.SCP_R1 * FULLY_DOWN); + physicalControlState[10] = (int)(pressure.SCP_PS * FULLY_DOWN); + physicalControlState[11] = (int)(pressure.SCP_X * FULLY_DOWN); + physicalControlState[12] = (int)(pressure.SCP_C * FULLY_DOWN); + physicalControlState[13] = (int)(pressure.SCP_S * FULLY_DOWN); + physicalControlState[14] = (int)(pressure.SCP_T * FULLY_DOWN); + physicalControlState[15] = (int)(pressure.SCP_L2 * FULLY_DOWN); + physicalControlState[16] = (int)(pressure.SCP_R2 * FULLY_DOWN); + physicalControlState[17] = (int)(pressure.SCP_LX * FULLY_DOWN); + physicalControlState[18] = (int)(pressure.SCP_LY * FULLY_DOWN); + physicalControlState[19] = (int)(pressure.SCP_RX * FULLY_DOWN); + physicalControlState[20] = (int)(pressure.SCP_RY * FULLY_DOWN); + } + return 1; + } - void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) { - ps2Vibration[port][slot][motor] = force; - int newVibration[2] = {0,0}; - for (int p=0; p<2; p++) { - for (int s=0; s<4; s++) { - for (int i=0; iaxes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); - newVibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); - } - } - } - newVibration[0] = abs(newVibration[0]); - if (newVibration[0] > 65535) { - newVibration[0] = 65535; - } - newVibration[1] = abs(newVibration[1]); - if (newVibration[1] > 65535) { - newVibration[1] = 65535; - } - if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed) { - XINPUT_VIBRATION newv = {(WORD)newVibration[0], (WORD)newVibration[1]}; - if (ERROR_SUCCESS == pXInputSetState(index, &newv)) { - xInputVibration = newv; - } - } - } + void SetEffects(unsigned char port, unsigned int slot, unsigned char motor, unsigned char force) + { + ps2Vibration[port][slot][motor] = force; + int newVibration[2] = {0, 0}; + for (int p = 0; p < 2; p++) { + for (int s = 0; s < 4; s++) { + for (int i = 0; i < pads[p][s].numFFBindings; i++) { + // Technically should also be a *65535/BASE_SENSITIVITY, but that's close enough to 1 for me. + ForceFeedbackBinding *ffb = &pads[p][s].ffBindings[i]; + newVibration[0] += (int)((ffb->axes[0].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); + newVibration[1] += (int)((ffb->axes[1].force * (__int64)ps2Vibration[p][s][ffb->motor]) / 255); + } + } + } + newVibration[0] = abs(newVibration[0]); + if (newVibration[0] > 65535) { + newVibration[0] = 65535; + } + newVibration[1] = abs(newVibration[1]); + if (newVibration[1] > 65535) { + newVibration[1] = 65535; + } + if (newVibration[0] || newVibration[1] || newVibration[0] != xInputVibration.wLeftMotorSpeed || newVibration[1] != xInputVibration.wRightMotorSpeed) { + XINPUT_VIBRATION newv = {(WORD)newVibration[0], (WORD)newVibration[1]}; + if (ERROR_SUCCESS == pXInputSetState(index, &newv)) { + xInputVibration = newv; + } + } + } - void SetEffect(ForceFeedbackBinding *binding, unsigned char force) { - PadBindings pBackup = pads[0][0]; - pads[0][0].ffBindings = binding; - pads[0][0].numFFBindings = 1; - SetEffects(0, 0, binding->motor, 255); - pads[0][0] = pBackup; - } + void SetEffect(ForceFeedbackBinding *binding, unsigned char force) + { + PadBindings pBackup = pads[0][0]; + pads[0][0].ffBindings = binding; + pads[0][0].numFFBindings = 1; + SetEffects(0, 0, binding->motor, 255); + pads[0][0] = pBackup; + } - void Deactivate() { - memset(&xInputVibration, 0, sizeof(xInputVibration)); - memset(ps2Vibration, 0, sizeof(ps2Vibration)); - pXInputSetState(index, &xInputVibration); + void Deactivate() + { + memset(&xInputVibration, 0, sizeof(xInputVibration)); + memset(ps2Vibration, 0, sizeof(ps2Vibration)); + pXInputSetState(index, &xInputVibration); - FreeState(); - if (active) { - if (!--xInputActiveCount) { - pXInputEnable(0); - } - active = 0; - } - } + FreeState(); + if (active) { + if (!--xInputActiveCount) { + pXInputEnable(0); + } + active = 0; + } + } - ~XInputDevice() { - } + ~XInputDevice() + { + } }; -void EnumXInputDevices() { - wchar_t temp[30]; - if (!pXInputSetState) { - // Also used as flag to indicute XInput not installed, so - // don't repeatedly try to load it. - if (pXInputEnable) return; +void EnumXInputDevices() +{ + wchar_t temp[30]; + if (!pXInputSetState) { + // Also used as flag to indicute XInput not installed, so + // don't repeatedly try to load it. + if (pXInputEnable) + return; - // Prefer XInput 1.3 since SCP only has an XInput 1.3 wrapper right now. - // Also use LoadLibrary and not LoadLibraryEx for XInput 1.3, since some - // Windows 7 systems have issues with it. - // FIXME: Missing FreeLibrary call. - HMODULE hMod = LoadLibrary(L"xinput1_3.dll"); - if (hMod == nullptr && IsWindows8OrGreater()) { - hMod = LoadLibraryEx(L"XInput1_4.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); - } + // Prefer XInput 1.3 since SCP only has an XInput 1.3 wrapper right now. + // Also use LoadLibrary and not LoadLibraryEx for XInput 1.3, since some + // Windows 7 systems have issues with it. + // FIXME: Missing FreeLibrary call. + HMODULE hMod = LoadLibrary(L"xinput1_3.dll"); + if (hMod == nullptr && IsWindows8OrGreater()) { + hMod = LoadLibraryEx(L"XInput1_4.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); + } - if (hMod) { - if ((pXInputEnable = (_XInputEnable) GetProcAddress(hMod, "XInputEnable")) && - ((pXInputGetStateEx = (_XInputGetStateEx) GetProcAddress(hMod, (LPCSTR)100)) || // Try Ex version first - (pXInputGetStateEx = (_XInputGetStateEx) GetProcAddress(hMod, "XInputGetState")))) { - pXInputGetExtended = (_XInputGetExtended)GetProcAddress(hMod, "XInputGetExtended"); - pXInputSetState = (_XInputSetState) GetProcAddress(hMod, "XInputSetState"); - } - } - if (!pXInputSetState) { - pXInputEnable = (_XInputEnable)-1; - return; - } - } - pXInputEnable(1); - for (int i = 0; i < 4; i++) { - wsprintfW(temp, L"XInput Pad %i", i); - dm->AddDevice(new XInputDevice(i, temp)); - } - pXInputEnable(0); + if (hMod) { + if ((pXInputEnable = (_XInputEnable)GetProcAddress(hMod, "XInputEnable")) && + ((pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, (LPCSTR)100)) || // Try Ex version first + (pXInputGetStateEx = (_XInputGetStateEx)GetProcAddress(hMod, "XInputGetState")))) { + pXInputGetExtended = (_XInputGetExtended)GetProcAddress(hMod, "XInputGetExtended"); + pXInputSetState = (_XInputSetState)GetProcAddress(hMod, "XInputSetState"); + } + } + if (!pXInputSetState) { + pXInputEnable = (_XInputEnable)-1; + return; + } + } + pXInputEnable(1); + for (int i = 0; i < 4; i++) { + wsprintfW(temp, L"XInput Pad %i", i); + dm->AddDevice(new XInputDevice(i, temp)); + } + pXInputEnable(0); } - diff --git a/plugins/LilyPad/usb.h b/plugins/LilyPad/usb.h index ede3e902e7..c11277093f 100644 --- a/plugins/LilyPad/usb.h +++ b/plugins/LilyPad/usb.h @@ -57,39 +57,39 @@ /* * Device and/or Interface Class codes */ -#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ -#define USB_CLASS_AUDIO 1 -#define USB_CLASS_COMM 2 -#define USB_CLASS_HID 3 -#define USB_CLASS_PRINTER 7 -#define USB_CLASS_MASS_STORAGE 8 -#define USB_CLASS_HUB 9 -#define USB_CLASS_DATA 10 -#define USB_CLASS_VENDOR_SPEC 0xff +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_DATA 10 +#define USB_CLASS_VENDOR_SPEC 0xff /* * Descriptor types */ -#define USB_DT_DEVICE 0x01 -#define USB_DT_CONFIG 0x02 -#define USB_DT_STRING 0x03 -#define USB_DT_INTERFACE 0x04 -#define USB_DT_ENDPOINT 0x05 +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 -#define USB_DT_HID 0x21 -#define USB_DT_REPORT 0x22 -#define USB_DT_PHYSICAL 0x23 -#define USB_DT_HUB 0x29 +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 +#define USB_DT_PHYSICAL 0x23 +#define USB_DT_HUB 0x29 /* * Descriptor sizes per descriptor type */ -#define USB_DT_DEVICE_SIZE 18 -#define USB_DT_CONFIG_SIZE 9 -#define USB_DT_INTERFACE_SIZE 9 -#define USB_DT_ENDPOINT_SIZE 7 -#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ -#define USB_DT_HUB_NONVAR_SIZE 7 +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define USB_DT_HUB_NONVAR_SIZE 7 /* ensure byte-packed structures */ @@ -97,159 +97,168 @@ /* All standard descriptors have these 2 fields in common */ -struct usb_descriptor_header { - unsigned char bLength; - unsigned char bDescriptorType; +struct usb_descriptor_header +{ + unsigned char bLength; + unsigned char bDescriptorType; }; /* String descriptor */ -struct usb_string_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short wData[1]; +struct usb_string_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wData[1]; }; /* HID descriptor */ -struct usb_hid_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short bcdHID; - unsigned char bCountryCode; - unsigned char bNumDescriptors; +struct usb_hid_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdHID; + unsigned char bCountryCode; + unsigned char bNumDescriptors; }; /* Endpoint descriptor */ -#define USB_MAXENDPOINTS 32 -struct usb_endpoint_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned char bEndpointAddress; - unsigned char bmAttributes; - unsigned short wMaxPacketSize; - unsigned char bInterval; - unsigned char bRefresh; - unsigned char bSynchAddress; +#define USB_MAXENDPOINTS 32 +struct usb_endpoint_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bEndpointAddress; + unsigned char bmAttributes; + unsigned short wMaxPacketSize; + unsigned char bInterval; + unsigned char bRefresh; + unsigned char bSynchAddress; - unsigned char *extra; /* Extra descriptors */ - int extralen; + unsigned char *extra; /* Extra descriptors */ + int extralen; }; -#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ -#define USB_ENDPOINT_DIR_MASK 0x80 +#define USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 -#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ -#define USB_ENDPOINT_TYPE_CONTROL 0 -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 -#define USB_ENDPOINT_TYPE_BULK 2 -#define USB_ENDPOINT_TYPE_INTERRUPT 3 +#define USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_TYPE_CONTROL 0 +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 1 +#define USB_ENDPOINT_TYPE_BULK 2 +#define USB_ENDPOINT_TYPE_INTERRUPT 3 /* Interface descriptor */ -#define USB_MAXINTERFACES 32 -struct usb_interface_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned char bInterfaceNumber; - unsigned char bAlternateSetting; - unsigned char bNumEndpoints; - unsigned char bInterfaceClass; - unsigned char bInterfaceSubClass; - unsigned char bInterfaceProtocol; - unsigned char iInterface; +#define USB_MAXINTERFACES 32 +struct usb_interface_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bInterfaceNumber; + unsigned char bAlternateSetting; + unsigned char bNumEndpoints; + unsigned char bInterfaceClass; + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char iInterface; - struct usb_endpoint_descriptor *endpoint; + struct usb_endpoint_descriptor *endpoint; - unsigned char *extra; /* Extra descriptors */ - int extralen; + unsigned char *extra; /* Extra descriptors */ + int extralen; }; -#define USB_MAXALTSETTING 128 /* Hard limit */ +#define USB_MAXALTSETTING 128 /* Hard limit */ -struct usb_interface { - struct usb_interface_descriptor *altsetting; +struct usb_interface +{ + struct usb_interface_descriptor *altsetting; - int num_altsetting; + int num_altsetting; }; /* Configuration descriptor information.. */ -#define USB_MAXCONFIG 8 -struct usb_config_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short wTotalLength; - unsigned char bNumInterfaces; - unsigned char bConfigurationValue; - unsigned char iConfiguration; - unsigned char bmAttributes; - unsigned char MaxPower; +#define USB_MAXCONFIG 8 +struct usb_config_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short wTotalLength; + unsigned char bNumInterfaces; + unsigned char bConfigurationValue; + unsigned char iConfiguration; + unsigned char bmAttributes; + unsigned char MaxPower; - struct usb_interface *interface; + struct usb_interface *interface; - unsigned char *extra; /* Extra descriptors */ - int extralen; + unsigned char *extra; /* Extra descriptors */ + int extralen; }; /* Device descriptor */ -struct usb_device_descriptor { - unsigned char bLength; - unsigned char bDescriptorType; - unsigned short bcdUSB; - unsigned char bDeviceClass; - unsigned char bDeviceSubClass; - unsigned char bDeviceProtocol; - unsigned char bMaxPacketSize0; - unsigned short idVendor; - unsigned short idProduct; - unsigned short bcdDevice; - unsigned char iManufacturer; - unsigned char iProduct; - unsigned char iSerialNumber; - unsigned char bNumConfigurations; +struct usb_device_descriptor +{ + unsigned char bLength; + unsigned char bDescriptorType; + unsigned short bcdUSB; + unsigned char bDeviceClass; + unsigned char bDeviceSubClass; + unsigned char bDeviceProtocol; + unsigned char bMaxPacketSize0; + unsigned short idVendor; + unsigned short idProduct; + unsigned short bcdDevice; + unsigned char iManufacturer; + unsigned char iProduct; + unsigned char iSerialNumber; + unsigned char bNumConfigurations; }; -struct usb_ctrl_setup { - unsigned char bRequestType; - unsigned char bRequest; - unsigned short wValue; - unsigned short wIndex; - unsigned short wLength; +struct usb_ctrl_setup +{ + unsigned char bRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; }; /* * Standard requests */ -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 /* 0x02 is reserved */ -#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_FEATURE 0x03 /* 0x04 is reserved */ -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C -#define USB_TYPE_STANDARD (0x00 << 5) -#define USB_TYPE_CLASS (0x01 << 5) -#define USB_TYPE_VENDOR (0x02 << 5) -#define USB_TYPE_RESERVED (0x03 << 5) +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) -#define USB_RECIP_DEVICE 0x00 -#define USB_RECIP_INTERFACE 0x01 -#define USB_RECIP_ENDPOINT 0x02 -#define USB_RECIP_OTHER 0x03 +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 /* * Various libusb API related stuff */ -#define USB_ENDPOINT_IN 0x80 -#define USB_ENDPOINT_OUT 0x00 +#define USB_ENDPOINT_IN 0x80 +#define USB_ENDPOINT_OUT 0x00 /* Error codes */ -#define USB_ERROR_BEGIN 500000 +#define USB_ERROR_BEGIN 500000 /* * This is supposed to look weird. This file is generated from autoconf @@ -261,49 +270,54 @@ struct usb_ctrl_setup { /* struct usb_device; */ /* struct usb_bus; */ -struct usb_device { - struct usb_device *next, *prev; +struct usb_device +{ + struct usb_device *next, *prev; - char filename[LIBUSB_PATH_MAX]; + char filename[LIBUSB_PATH_MAX]; - struct usb_bus *bus; + struct usb_bus *bus; - struct usb_device_descriptor descriptor; - struct usb_config_descriptor *config; + struct usb_device_descriptor descriptor; + struct usb_config_descriptor *config; - void *dev; /* Darwin support */ + void *dev; /* Darwin support */ - unsigned char devnum; + unsigned char devnum; - unsigned char num_children; - struct usb_device **children; + unsigned char num_children; + struct usb_device **children; }; -struct usb_bus { - struct usb_bus *next, *prev; +struct usb_bus +{ + struct usb_bus *next, *prev; - char dirname[LIBUSB_PATH_MAX]; + char dirname[LIBUSB_PATH_MAX]; - struct usb_device *devices; - unsigned long location; + struct usb_device *devices; + unsigned long location; - struct usb_device *root_dev; + struct usb_device *root_dev; }; /* Version information, Windows specific */ -struct usb_version { - struct { - int major; - int minor; - int micro; - int nano; - } dll; - struct { - int major; - int minor; - int micro; - int nano; - } driver; +struct usb_version +{ + struct + { + int major; + int minor; + int micro; + int nano; + } dll; + struct + { + int major; + int minor; + int micro; + int nano; + } driver; }; @@ -324,92 +338,92 @@ typedef struct usb_dev_handle usb_dev_handle; extern "C" { #endif - /* Function prototypes */ +/* Function prototypes */ - /* usb.c */ - usb_dev_handle *usb_open(struct usb_device *dev); - int usb_close(usb_dev_handle *dev); - int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, - size_t buflen); - int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, - size_t buflen); +/* usb.c */ +usb_dev_handle *usb_open(struct usb_device *dev); +int usb_close(usb_dev_handle *dev); +int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, + size_t buflen); +int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, + size_t buflen); - /* descriptors.c */ - int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, - unsigned char type, unsigned char index, - void *buf, int size); - int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, - unsigned char index, void *buf, int size); +/* descriptors.c */ +int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, + unsigned char type, unsigned char index, + void *buf, int size); +int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, + unsigned char index, void *buf, int size); - /* .c */ - int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, - int timeout); - int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, +/* .c */ +int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); +int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); +int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); +int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, + int timeout); +int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, + int value, int index, char *bytes, int size, int timeout); - int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, - int timeout); - int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, - int timeout); - int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, - int value, int index, char *bytes, int size, - int timeout); - int usb_set_configuration(usb_dev_handle *dev, int configuration); - int usb_claim_interface(usb_dev_handle *dev, int interface); - int usb_release_interface(usb_dev_handle *dev, int interface); - int usb_set_altinterface(usb_dev_handle *dev, int alternate); - int usb_resetep(usb_dev_handle *dev, unsigned int ep); - int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); - int usb_reset(usb_dev_handle *dev); +int usb_set_configuration(usb_dev_handle *dev, int configuration); +int usb_claim_interface(usb_dev_handle *dev, int interface); +int usb_release_interface(usb_dev_handle *dev, int interface); +int usb_set_altinterface(usb_dev_handle *dev, int alternate); +int usb_resetep(usb_dev_handle *dev, unsigned int ep); +int usb_clear_halt(usb_dev_handle *dev, unsigned int ep); +int usb_reset(usb_dev_handle *dev); - char *usb_strerror(void); +char *usb_strerror(void); - void usb_init(void); - void usb_set_debug(int level); - int usb_find_busses(void); - int usb_find_devices(void); - struct usb_device *usb_device(usb_dev_handle *dev); - struct usb_bus *usb_get_busses(void); +void usb_init(void); +void usb_set_debug(int level); +int usb_find_busses(void); +int usb_find_devices(void); +struct usb_device *usb_device(usb_dev_handle *dev); +struct usb_bus *usb_get_busses(void); - /* Windows specific functions */ +/* Windows specific functions */ - #define LIBUSB_HAS_INSTALL_SERVICE_NP 1 - int usb_install_service_np(void); - void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, +#define LIBUSB_HAS_INSTALL_SERVICE_NP 1 +int usb_install_service_np(void); +void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); + +#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 +int usb_uninstall_service_np(void); +void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show); - #define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1 - int usb_uninstall_service_np(void); - void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, - LPSTR cmd_line, int cmd_show); +#define LIBUSB_HAS_INSTALL_DRIVER_NP 1 +int usb_install_driver_np(const char *inf_file); +void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); - #define LIBUSB_HAS_INSTALL_DRIVER_NP 1 - int usb_install_driver_np(const char *inf_file); - void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, - LPSTR cmd_line, int cmd_show); +#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 +int usb_touch_inf_file_np(const char *inf_file); +void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, + LPSTR cmd_line, int cmd_show); - #define LIBUSB_HAS_TOUCH_INF_FILE_NP 1 - int usb_touch_inf_file_np(const char *inf_file); - void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, - LPSTR cmd_line, int cmd_show); +#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 +int usb_install_needs_restart_np(void); - #define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1 - int usb_install_needs_restart_np(void); +const struct usb_version *usb_get_version(void); - const struct usb_version *usb_get_version(void); +int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep, int pktsize); +int usb_bulk_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); +int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, + unsigned char ep); - int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, - unsigned char ep, int pktsize); - int usb_bulk_setup_async(usb_dev_handle *dev, void **context, - unsigned char ep); - int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, - unsigned char ep); - - int usb_submit_async(void *context, char *bytes, int size); - int usb_reap_async(void *context, int timeout); - int usb_reap_async_nocancel(void *context, int timeout); - int usb_cancel_async(void *context); - int usb_free_async(void **context); +int usb_submit_async(void *context, char *bytes, int size); +int usb_reap_async(void *context, int timeout); +int usb_reap_async_nocancel(void *context, int timeout); +int usb_cancel_async(void *context); +int usb_free_async(void **context); #ifdef __cplusplus @@ -418,4 +432,3 @@ extern "C" { #endif #endif /* __USB_H__ */ -