Mercurial > vba-clojure
diff src/win32/DirectInput.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/DirectInput.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,1242 @@ 1.4 +//#define USE_GETASYNCKEYSTATE_FOR_KEYBOARD 1.5 + 1.6 +#include "stdafx.h" 1.7 + 1.8 +#define DIRECTINPUT_VERSION 0x0500 1.9 +#include "dinput.h" 1.10 + 1.11 +#include "resource.h" 1.12 +#include "Input.h" 1.13 +#include "Reg.h" 1.14 +#include "WinResUtil.h" 1.15 + 1.16 +// master keyboard translation table 1.17 +static const struct { 1.18 + int dik; 1.19 + int vk; 1.20 + int ascii; 1.21 +} win_key_trans_table[] = { 1.22 + // dinput key virtual key ascii 1.23 + { DIK_ESCAPE, VK_ESCAPE, 27 }, 1.24 + { DIK_1, '1', '1' }, 1.25 + { DIK_2, '2', '2' }, 1.26 + { DIK_3, '3', '3' }, 1.27 + { DIK_4, '4', '4' }, 1.28 + { DIK_5, '5', '5' }, 1.29 + { DIK_6, '6', '6' }, 1.30 + { DIK_7, '7', '7' }, 1.31 + { DIK_8, '8', '8' }, 1.32 + { DIK_9, '9', '9' }, 1.33 + { DIK_0, '0', '0' }, 1.34 + { DIK_MINUS, VK_OEM_MINUS, '-' }, 1.35 + { DIK_EQUALS, VK_OEM_PLUS, '=' }, 1.36 + { DIK_BACK, VK_BACK, 8 }, 1.37 + { DIK_TAB, VK_TAB, 9 }, 1.38 + { DIK_Q, 'Q', 'Q' }, 1.39 + { DIK_W, 'W', 'W' }, 1.40 + { DIK_E, 'E', 'E' }, 1.41 + { DIK_R, 'R', 'R' }, 1.42 + { DIK_T, 'T', 'T' }, 1.43 + { DIK_Y, 'Y', 'Y' }, 1.44 + { DIK_U, 'U', 'U' }, 1.45 + { DIK_I, 'I', 'I' }, 1.46 + { DIK_O, 'O', 'O' }, 1.47 + { DIK_P, 'P', 'P' }, 1.48 + { DIK_LBRACKET, VK_OEM_4, '[' }, 1.49 + { DIK_RBRACKET, VK_OEM_6, ']' }, 1.50 + { DIK_RETURN, VK_RETURN, 13 }, 1.51 + { DIK_LCONTROL, VK_LCONTROL, 0 }, 1.52 + { DIK_A, 'A', 'A' }, 1.53 + { DIK_S, 'S', 'S' }, 1.54 + { DIK_D, 'D', 'D' }, 1.55 + { DIK_F, 'F', 'F' }, 1.56 + { DIK_G, 'G', 'G' }, 1.57 + { DIK_H, 'H', 'H' }, 1.58 + { DIK_J, 'J', 'J' }, 1.59 + { DIK_K, 'K', 'K' }, 1.60 + { DIK_L, 'L', 'L' }, 1.61 + { DIK_SEMICOLON, VK_OEM_1, ';' }, 1.62 + { DIK_APOSTROPHE, VK_OEM_7, '\'' }, 1.63 + { DIK_GRAVE, VK_OEM_3, '`' }, 1.64 + { DIK_LSHIFT, VK_LSHIFT, 0 }, 1.65 + { DIK_BACKSLASH, VK_OEM_5, '\\' }, 1.66 + { DIK_Z, 'Z', 'Z' }, 1.67 + { DIK_X, 'X', 'X' }, 1.68 + { DIK_C, 'C', 'C' }, 1.69 + { DIK_V, 'V', 'V' }, 1.70 + { DIK_B, 'B', 'B' }, 1.71 + { DIK_N, 'N', 'N' }, 1.72 + { DIK_M, 'M', 'M' }, 1.73 + { DIK_COMMA, VK_OEM_COMMA, ',' }, 1.74 + { DIK_PERIOD, VK_OEM_PERIOD, '.' }, 1.75 + { DIK_SLASH, VK_OEM_2, '/' }, 1.76 + { DIK_RSHIFT, VK_RSHIFT, 0 }, 1.77 + { DIK_MULTIPLY, VK_MULTIPLY, '*' }, 1.78 + { DIK_LMENU, VK_LMENU, 0 }, 1.79 + { DIK_SPACE, VK_SPACE, ' ' }, 1.80 + { DIK_CAPITAL, VK_CAPITAL, 0 }, 1.81 + { DIK_F1, VK_F1, 0 }, 1.82 + { DIK_F2, VK_F2, 0 }, 1.83 + { DIK_F3, VK_F3, 0 }, 1.84 + { DIK_F4, VK_F4, 0 }, 1.85 + { DIK_F5, VK_F5, 0 }, 1.86 + { DIK_F6, VK_F6, 0 }, 1.87 + { DIK_F7, VK_F7, 0 }, 1.88 + { DIK_F8, VK_F8, 0 }, 1.89 + { DIK_F9, VK_F9, 0 }, 1.90 + { DIK_F10, VK_F10, 0 }, 1.91 + { DIK_NUMLOCK, VK_NUMLOCK, 0 }, 1.92 + { DIK_SCROLL, VK_SCROLL, 0 }, 1.93 + { DIK_NUMPAD7, VK_NUMPAD7, 0 }, 1.94 + { DIK_NUMPAD8, VK_NUMPAD8, 0 }, 1.95 + { DIK_NUMPAD9, VK_NUMPAD9, 0 }, 1.96 + { DIK_SUBTRACT, VK_SUBTRACT, 0 }, 1.97 + { DIK_NUMPAD4, VK_NUMPAD4, 0 }, 1.98 + { DIK_NUMPAD5, VK_NUMPAD5, 0 }, 1.99 + { DIK_NUMPAD6, VK_NUMPAD6, 0 }, 1.100 + { DIK_ADD, VK_ADD, 0 }, 1.101 + { DIK_NUMPAD1, VK_NUMPAD1, 0 }, 1.102 + { DIK_NUMPAD2, VK_NUMPAD2, 0 }, 1.103 + { DIK_NUMPAD3, VK_NUMPAD3, 0 }, 1.104 + { DIK_NUMPAD0, VK_NUMPAD0, 0 }, 1.105 + { DIK_DECIMAL, VK_DECIMAL, 0 }, 1.106 + { DIK_F11, VK_F11, 0 }, 1.107 + { DIK_F12, VK_F12, 0 }, 1.108 + { DIK_F13, VK_F13, 0 }, 1.109 + { DIK_F14, VK_F14, 0 }, 1.110 + { DIK_F15, VK_F15, 0 }, 1.111 + { DIK_NUMPADENTER, VK_RETURN, 0 }, 1.112 + { DIK_RCONTROL, VK_RCONTROL, 0 }, 1.113 + { DIK_DIVIDE, VK_DIVIDE, 0 }, 1.114 + { DIK_SYSRQ, 0, 0 }, 1.115 + { DIK_RMENU, VK_RMENU, 0 }, 1.116 + { DIK_HOME, VK_HOME, 0 }, 1.117 + { DIK_UP, VK_UP, 0 }, 1.118 + { DIK_PRIOR, VK_PRIOR, 0 }, 1.119 + { DIK_LEFT, VK_LEFT, 0 }, 1.120 + { DIK_RIGHT, VK_RIGHT, 0 }, 1.121 + { DIK_END, VK_END, 0 }, 1.122 + { DIK_DOWN, VK_DOWN, 0 }, 1.123 + { DIK_NEXT, VK_NEXT, 0 }, 1.124 + { DIK_INSERT, VK_INSERT, 0 }, 1.125 + { DIK_DELETE, VK_DELETE, 0 }, 1.126 + { DIK_LWIN, VK_LWIN, 0 }, 1.127 + { DIK_RWIN, VK_RWIN, 0 }, 1.128 + { DIK_APPS, VK_APPS, 0 }, 1.129 + { DIK_PAUSE, VK_PAUSE, 0 }, 1.130 + { 0, VK_CANCEL, 0 }, 1.131 + 1.132 + // New keys introduced in Windows 2000. These have no MAME codes to 1.133 + // preserve compatibility with old config files that may refer to them 1.134 + // as e.g. FORWARD instead of e.g. KEYCODE_WEBFORWARD. They need table 1.135 + // entries anyway because otherwise they aren't recognized when 1.136 + // GetAsyncKeyState polling is used (as happens currently when MAME is 1.137 + // paused). Some codes are missing because the mapping to vkey codes 1.138 + // isn't clear, and MapVirtualKey is no help. 1.139 + 1.140 + { DIK_MUTE, VK_VOLUME_MUTE, 0 }, 1.141 + { DIK_VOLUMEDOWN, VK_VOLUME_DOWN, 0 }, 1.142 + { DIK_VOLUMEUP, VK_VOLUME_UP, 0 }, 1.143 + { DIK_WEBHOME, VK_BROWSER_HOME, 0 }, 1.144 + { DIK_WEBSEARCH, VK_BROWSER_SEARCH, 0 }, 1.145 + { DIK_WEBFAVORITES, VK_BROWSER_FAVORITES, 0 }, 1.146 + { DIK_WEBREFRESH, VK_BROWSER_REFRESH, 0 }, 1.147 + { DIK_WEBSTOP, VK_BROWSER_STOP, 0 }, 1.148 + { DIK_WEBFORWARD, VK_BROWSER_FORWARD, 0 }, 1.149 + { DIK_WEBBACK, VK_BROWSER_BACK, 0 }, 1.150 + { DIK_MAIL, VK_LAUNCH_MAIL, 0 }, 1.151 + { DIK_MEDIASELECT, VK_LAUNCH_MEDIA_SELECT, 0 }, 1.152 +}; 1.153 + 1.154 +extern void directXMessage(const char *); 1.155 +extern void winlog(const char *msg, ...); 1.156 + 1.157 +#define POV_UP 1 1.158 +#define POV_DOWN 2 1.159 +#define POV_RIGHT 4 1.160 +#define POV_LEFT 8 1.161 + 1.162 +class DirectInput : public Input 1.163 +{ 1.164 +private: 1.165 + HINSTANCE dinputDLL; 1.166 +public: 1.167 + virtual void checkDevices(); 1.168 + DirectInput(); 1.169 + virtual ~DirectInput(); 1.170 + 1.171 + virtual bool initialize(); 1.172 + virtual bool readDevices(); 1.173 + virtual u32 readDevice(int which, bool sensor); 1.174 + virtual CString getKeyName(LONG_PTR key); 1.175 + virtual void checkKeys(); 1.176 + virtual void activate(); 1.177 + virtual void loadSettings(); 1.178 + virtual void saveSettings(); 1.179 +}; 1.180 + 1.181 +struct deviceInfo 1.182 +{ 1.183 + LPDIRECTINPUTDEVICE device; 1.184 + BOOL isPolled; 1.185 + int nButtons; 1.186 + int nAxes; 1.187 + int nPovs; 1.188 + BOOL first; 1.189 + struct 1.190 + { 1.191 + DWORD offset; 1.192 + LONG center; 1.193 + LONG negative; 1.194 + LONG positive; 1.195 + } axis[8]; 1.196 + int needed; 1.197 + union 1.198 + { 1.199 + UCHAR data[256]; 1.200 + DIJOYSTATE state; 1.201 + }; 1.202 +}; 1.203 + 1.204 +static deviceInfo * currentDevice = NULL; 1.205 +static int numDevices = 1; 1.206 +static deviceInfo * pDevices = NULL; 1.207 +static LPDIRECTINPUT pDirectInput = NULL; 1.208 +static int joyDebug = 0; 1.209 +static int axisNumber = 0; 1.210 + 1.211 +USHORT joypad[4][13] = { 1.212 + { 1.213 + DIK_LEFT, DIK_RIGHT, 1.214 + DIK_UP, DIK_DOWN, 1.215 + DIK_Z, DIK_X, 1.216 + DIK_RETURN, DIK_BACK, 1.217 + DIK_A, DIK_S, 1.218 + DIK_SPACE, DIK_F12, 1.219 + DIK_C 1.220 + }, 1.221 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1.222 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 1.223 + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 1.224 +}; 1.225 + 1.226 +USHORT motion[4] = { 1.227 + DIK_NUMPAD4, DIK_NUMPAD6, DIK_NUMPAD8, DIK_NUMPAD2 1.228 +}; 1.229 + 1.230 +static int winReadKey(char *name, int num) 1.231 +{ 1.232 + char buffer[80]; 1.233 + 1.234 + sprintf(buffer, "Joy%d_%s", num, name); 1.235 + 1.236 + return regQueryDwordValue(buffer, (DWORD)-1); 1.237 +} 1.238 + 1.239 +void winReadKeys() 1.240 +{ 1.241 + int key = -1; 1.242 + 1.243 + for (int i = 0; i < 4; i++) 1.244 + { 1.245 + key = winReadKey("Left", i); 1.246 + if (key != -1) 1.247 + joypad[i][KEY_LEFT] = key; 1.248 + key = winReadKey("Right", i); 1.249 + if (key != -1) 1.250 + joypad[i][KEY_RIGHT] = key; 1.251 + key = winReadKey("Up", i); 1.252 + if (key != -1) 1.253 + joypad[i][KEY_UP] = key; 1.254 + key = winReadKey("Down", i); 1.255 + if (key != -1) 1.256 + joypad[i][KEY_DOWN] = key; 1.257 + key = winReadKey("A", i); 1.258 + if (key != -1) 1.259 + joypad[i][KEY_BUTTON_A] = key; 1.260 + key = winReadKey("B", i); 1.261 + if (key != -1) 1.262 + joypad[i][KEY_BUTTON_B] = key; 1.263 + key = winReadKey("L", i); 1.264 + if (key != -1) 1.265 + joypad[i][KEY_BUTTON_L] = key; 1.266 + key = winReadKey("R", i); 1.267 + if (key != -1) 1.268 + joypad[i][KEY_BUTTON_R] = key; 1.269 + key = winReadKey("Start", i); 1.270 + if (key != -1) 1.271 + joypad[i][KEY_BUTTON_START] = key; 1.272 + key = winReadKey("Select", i); 1.273 + if (key != -1) 1.274 + joypad[i][KEY_BUTTON_SELECT] = key; 1.275 + key = winReadKey("Speed", i); 1.276 + if (key != -1) 1.277 + joypad[i][KEY_BUTTON_SPEED] = key; 1.278 + key = winReadKey("Capture", i); 1.279 + if (key != -1) 1.280 + joypad[i][KEY_BUTTON_CAPTURE] = key; 1.281 + key = winReadKey("GS", i); 1.282 + if (key != -1) 1.283 + joypad[i][KEY_BUTTON_GS] = key; 1.284 + } 1.285 + key = regQueryDwordValue("Motion_Left", (DWORD)-1); 1.286 + if (key != -1) 1.287 + motion[KEY_LEFT] = key; 1.288 + key = regQueryDwordValue("Motion_Right", (DWORD)-1); 1.289 + if (key != -1) 1.290 + motion[KEY_RIGHT] = key; 1.291 + key = regQueryDwordValue("Motion_Up", (DWORD)-1); 1.292 + if (key != -1) 1.293 + motion[KEY_UP] = key; 1.294 + key = regQueryDwordValue("Motion_Down", (DWORD)-1); 1.295 + if (key != -1) 1.296 + motion[KEY_DOWN] = key; 1.297 +} 1.298 + 1.299 +static void winSaveKey(char *name, int num, USHORT value) 1.300 +{ 1.301 + char buffer[80]; 1.302 + 1.303 + sprintf(buffer, "Joy%d_%s", num, name); 1.304 + 1.305 + regSetDwordValue(buffer, value); 1.306 +} 1.307 + 1.308 +void winSaveKeys() 1.309 +{ 1.310 + for (int i = 0; i < 4; i++) 1.311 + { 1.312 + winSaveKey("Left", i, joypad[i][KEY_LEFT]); 1.313 + winSaveKey("Right", i, joypad[i][KEY_RIGHT]); 1.314 + winSaveKey("Up", i, joypad[i][KEY_UP]); 1.315 + winSaveKey("Speed", i, joypad[i][KEY_BUTTON_SPEED]); 1.316 + winSaveKey("Capture", i, joypad[i][KEY_BUTTON_CAPTURE]); 1.317 + winSaveKey("GS", i, joypad[i][KEY_BUTTON_GS]); 1.318 + winSaveKey("Down", i, joypad[i][KEY_DOWN]); 1.319 + winSaveKey("A", i, joypad[i][KEY_BUTTON_A]); 1.320 + winSaveKey("B", i, joypad[i][KEY_BUTTON_B]); 1.321 + winSaveKey("L", i, joypad[i][KEY_BUTTON_L]); 1.322 + winSaveKey("R", i, joypad[i][KEY_BUTTON_R]); 1.323 + winSaveKey("Start", i, joypad[i][KEY_BUTTON_START]); 1.324 + winSaveKey("Select", i, joypad[i][KEY_BUTTON_SELECT]); 1.325 + } 1.326 + regSetDwordValue("joyVersion", 1); 1.327 + 1.328 + regSetDwordValue("Motion_Left", 1.329 + motion[KEY_LEFT]); 1.330 + regSetDwordValue("Motion_Right", 1.331 + motion[KEY_RIGHT]); 1.332 + regSetDwordValue("Motion_Up", 1.333 + motion[KEY_UP]); 1.334 + regSetDwordValue("Motion_Down", 1.335 + motion[KEY_DOWN]); 1.336 +} 1.337 + 1.338 +static BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE*pdidoi, 1.339 + VOID*pContext) 1.340 +{ 1.341 + DIPROPRANGE diprg; 1.342 + diprg.diph.dwSize = sizeof(DIPROPRANGE); 1.343 + diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); 1.344 + diprg.diph.dwHow = DIPH_BYOFFSET; 1.345 + diprg.diph.dwObj = pdidoi->dwOfs; // Specify the enumerated axis 1.346 + 1.347 + diprg.lMin = -32768; 1.348 + diprg.lMax = 32767; 1.349 + // try to set the range 1.350 + if (FAILED(currentDevice->device->SetProperty(DIPROP_RANGE, &diprg.diph))) 1.351 + { 1.352 + // Get the range for the axis 1.353 + if (FAILED(currentDevice->device-> 1.354 + GetProperty(DIPROP_RANGE, &diprg.diph))) 1.355 + { 1.356 + return DIENUM_STOP; 1.357 + } 1.358 + } 1.359 + 1.360 + DIPROPDWORD didz; 1.361 + 1.362 + didz.diph.dwSize = sizeof(didz); 1.363 + didz.diph.dwHeaderSize = sizeof(DIPROPHEADER); 1.364 + didz.diph.dwHow = DIPH_BYOFFSET; 1.365 + didz.diph.dwObj = pdidoi->dwOfs; 1.366 + 1.367 + didz.dwData = 5000; 1.368 + 1.369 + currentDevice->device->SetProperty(DIPROP_DEADZONE, &didz.diph); 1.370 + 1.371 + LONG center = (diprg.lMin + diprg.lMax)/2; 1.372 + LONG threshold = (diprg.lMax - center)/2; 1.373 + 1.374 + // only 8 axis supported 1.375 + if (axisNumber < 8) 1.376 + { 1.377 + currentDevice->axis[axisNumber].center = center; 1.378 + currentDevice->axis[axisNumber].negative = center - threshold; 1.379 + currentDevice->axis[axisNumber].positive = center + threshold; 1.380 + currentDevice->axis[axisNumber].offset = pdidoi->dwOfs; 1.381 + } 1.382 + axisNumber++; 1.383 + return DIENUM_CONTINUE; 1.384 +} 1.385 + 1.386 +static BOOL CALLBACK EnumPovsCallback(const DIDEVICEOBJECTINSTANCE*pdidoi, 1.387 + VOID*pContext) 1.388 +{ 1.389 + return DIENUM_CONTINUE; 1.390 +} 1.391 + 1.392 +static BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE pInst, 1.393 + LPVOID lpvContext) 1.394 +{ 1.395 + ZeroMemory(&pDevices[numDevices], sizeof(deviceInfo)); 1.396 + 1.397 + HRESULT hRet = pDirectInput->CreateDevice(pInst->guidInstance, 1.398 + &pDevices[numDevices].device, 1.399 + NULL); 1.400 + 1.401 + if (hRet != DI_OK) 1.402 + return DIENUM_STOP; 1.403 + 1.404 + DIDEVCAPS caps; 1.405 + caps.dwSize = sizeof(DIDEVCAPS); 1.406 + 1.407 + hRet = pDevices[numDevices].device->GetCapabilities(&caps); 1.408 + 1.409 + if (hRet == DI_OK) 1.410 + { 1.411 + if (caps.dwFlags & DIDC_POLLEDDATAFORMAT || 1.412 + caps.dwFlags & DIDC_POLLEDDEVICE) 1.413 + pDevices[numDevices].isPolled = TRUE; 1.414 + 1.415 + pDevices[numDevices].nButtons = caps.dwButtons; 1.416 + pDevices[numDevices].nAxes = caps.dwAxes; 1.417 + pDevices[numDevices].nPovs = caps.dwPOVs; 1.418 + 1.419 + for (int i = 0; i < 6; i++) 1.420 + { 1.421 + pDevices[numDevices].axis[i].center = 0x8000; 1.422 + pDevices[numDevices].axis[i].negative = 0x4000; 1.423 + pDevices[numDevices].axis[i].positive = 0xc000; 1.424 + } 1.425 + } 1.426 + else if (joyDebug) 1.427 + winlog("Failed to get device capabilities %08x\n", hRet); 1.428 + 1.429 + if (joyDebug) 1.430 + { 1.431 + // don't translate. debug only 1.432 + winlog("******************************\n"); 1.433 + winlog("Joystick %2d name : %s\n", numDevices, pInst->tszProductName); 1.434 + } 1.435 + 1.436 + numDevices++; 1.437 + 1.438 + return DIENUM_CONTINUE; 1.439 +} 1.440 + 1.441 +BOOL CALLBACK DIEnumDevicesCallback2(LPCDIDEVICEINSTANCE pInst, 1.442 + LPVOID lpvContext) 1.443 +{ 1.444 + numDevices++; 1.445 + 1.446 + return DIENUM_CONTINUE; 1.447 +} 1.448 + 1.449 +static int getPovState(DWORD value) 1.450 +{ 1.451 + int state = 0; 1.452 + if (LOWORD(value) != 0xFFFF) 1.453 + { 1.454 + if (value < 9000 || value > 27000) 1.455 + state |= POV_UP; 1.456 + if (value > 0 && value < 18000) 1.457 + state |= POV_RIGHT; 1.458 + if (value > 9000 && value < 27000) 1.459 + state |= POV_DOWN; 1.460 + if (value > 18000) 1.461 + state |= POV_LEFT; 1.462 + } 1.463 + return state; 1.464 +} 1.465 + 1.466 +static void checkKeys() 1.467 +{ 1.468 + LONG_PTR dev = 0; 1.469 + int i; 1.470 + 1.471 + for (i = 0; i < numDevices; i++) 1.472 + pDevices[i].needed = 0; 1.473 + 1.474 + for (i = 0; i < 4; i++) 1.475 + { 1.476 + dev = joypad[i][KEY_LEFT] >> 8; 1.477 + if (dev < numDevices && dev >= 0) 1.478 + pDevices[dev].needed = 1; 1.479 + else 1.480 + joypad[i][KEY_LEFT] = DIK_LEFT; 1.481 + 1.482 + dev = joypad[i][KEY_RIGHT] >> 8; 1.483 + if (dev < numDevices && dev >= 0) 1.484 + pDevices[dev].needed = 1; 1.485 + else 1.486 + joypad[i][KEY_RIGHT] = DIK_RIGHT; 1.487 + 1.488 + dev = joypad[i][KEY_UP] >> 8; 1.489 + if (dev < numDevices && dev >= 0) 1.490 + pDevices[dev].needed = 1; 1.491 + else 1.492 + joypad[i][KEY_UP] = DIK_UP; 1.493 + 1.494 + dev = joypad[i][KEY_DOWN] >> 8; 1.495 + if (dev < numDevices && dev >= 0) 1.496 + pDevices[dev].needed = 1; 1.497 + else 1.498 + joypad[i][KEY_DOWN] = DIK_DOWN; 1.499 + 1.500 + dev = joypad[i][KEY_BUTTON_A] >> 8; 1.501 + if (dev < numDevices && dev >= 0) 1.502 + pDevices[dev].needed = 1; 1.503 + else 1.504 + joypad[i][KEY_BUTTON_A] = DIK_Z; 1.505 + 1.506 + dev = joypad[i][KEY_BUTTON_B] >> 8; 1.507 + if (dev < numDevices && dev >= 0) 1.508 + pDevices[dev].needed = 1; 1.509 + else 1.510 + joypad[i][KEY_BUTTON_B] = DIK_X; 1.511 + 1.512 + dev = joypad[i][KEY_BUTTON_L] >> 8; 1.513 + if (dev < numDevices && dev >= 0) 1.514 + pDevices[dev].needed = 1; 1.515 + else 1.516 + joypad[i][KEY_BUTTON_L] = DIK_A; 1.517 + 1.518 + dev = joypad[i][KEY_BUTTON_R] >> 8; 1.519 + if (dev < numDevices && dev >= 0) 1.520 + pDevices[dev].needed = 1; 1.521 + else 1.522 + joypad[i][KEY_BUTTON_R] = DIK_S; 1.523 + 1.524 + dev = joypad[i][KEY_BUTTON_START] >> 8; 1.525 + if (dev < numDevices && dev >= 0) 1.526 + pDevices[dev].needed = 1; 1.527 + else 1.528 + joypad[i][KEY_BUTTON_START] = DIK_RETURN; 1.529 + 1.530 + dev = joypad[i][KEY_BUTTON_SELECT] >> 8; 1.531 + if (dev < numDevices && dev >= 0) 1.532 + pDevices[dev].needed = 1; 1.533 + else 1.534 + joypad[i][KEY_BUTTON_SELECT] = DIK_BACK; 1.535 + 1.536 + dev = joypad[i][KEY_BUTTON_SPEED] >> 8; 1.537 + if (dev < numDevices && dev >= 0) 1.538 + pDevices[dev].needed = 1; 1.539 + else 1.540 + joypad[i][KEY_BUTTON_SPEED] = DIK_SPACE; 1.541 + 1.542 + dev = joypad[i][KEY_BUTTON_CAPTURE] >> 8; 1.543 + if (dev < numDevices && dev >= 0) 1.544 + pDevices[dev].needed = 1; 1.545 + else 1.546 + joypad[i][KEY_BUTTON_CAPTURE] = DIK_F12; 1.547 + 1.548 + dev = joypad[i][KEY_BUTTON_GS] >> 8; 1.549 + if (dev < numDevices && dev >= 0) 1.550 + pDevices[dev].needed = 1; 1.551 + else 1.552 + joypad[i][KEY_BUTTON_GS] = DIK_C; 1.553 + } 1.554 + 1.555 + dev = motion[KEY_UP] >> 8; 1.556 + if (dev < numDevices && dev >= 0) 1.557 + pDevices[dev].needed = 1; 1.558 + else 1.559 + motion[KEY_UP] = DIK_NUMPAD8; 1.560 + 1.561 + dev = motion[KEY_DOWN] >> 8; 1.562 + if (dev < numDevices && dev >= 0) 1.563 + pDevices[dev].needed = 1; 1.564 + else 1.565 + motion[KEY_DOWN] = DIK_NUMPAD2; 1.566 + 1.567 + dev = motion[KEY_LEFT] >> 8; 1.568 + if (dev < numDevices && dev >= 0) 1.569 + pDevices[dev].needed = 1; 1.570 + else 1.571 + motion[KEY_LEFT] = DIK_NUMPAD4; 1.572 + 1.573 + dev = motion[KEY_RIGHT] >> 8; 1.574 + if (dev < numDevices && dev >= 0) 1.575 + pDevices[dev].needed = 1; 1.576 + else 1.577 + motion[KEY_RIGHT] = DIK_NUMPAD6; 1.578 +} 1.579 + 1.580 +#define KEYDOWN(buffer, key) (buffer[key] & 0x80) 1.581 + 1.582 +static bool IsKeyDownAsync (WORD KeyIdent) 1.583 +{ 1.584 + //if (KeyIdent == 0 || KeyIdent == VK_ESCAPE) // if it's the 'disabled' key, it's never pressed 1.585 + // return false; 1.586 + 1.587 + //if (!GUI.BackgroundInput && GUI.hWnd != GetForegroundWindow()) 1.588 + // return false; 1.589 + 1.590 + // the pause key is special, need this to catch all presses of it 1.591 + // Both GetKeyState and GetAsyncKeyState cannot catch it anyway, 1.592 + // so this should be handled in WM_KEYDOWN message. 1.593 + if (KeyIdent == VK_PAUSE) 1.594 + { 1.595 + return false; 1.596 +// if(GetAsyncKeyState(VK_PAUSE)) // not &'ing this with 0x8000 is intentional and necessary 1.597 +// return true; 1.598 + } 1.599 + 1.600 + if (KeyIdent == VK_CAPITAL || KeyIdent == VK_NUMLOCK || KeyIdent == VK_SCROLL) 1.601 + return ((GetKeyState(KeyIdent) & 0x01) != 0); 1.602 + else 1.603 + return ((GetAsyncKeyState(KeyIdent) & 0x8000) != 0); 1.604 + //return ((GetKeyState (KeyIdent) & 0x80) != 0); 1.605 +} 1.606 + 1.607 +static bool readKeyboard() 1.608 +{ 1.609 +#ifndef USE_GETASYNCKEYSTATE_FOR_KEYBOARD 1.610 + if (pDevices[0].needed) 1.611 + { 1.612 + HRESULT hret = pDevices[0].device-> 1.613 + GetDeviceState(256, 1.614 + (LPVOID)pDevices[0].data); 1.615 + 1.616 + if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) 1.617 + { 1.618 + hret = pDevices[0].device->Acquire(); 1.619 + if (hret != DI_OK) 1.620 + return false; 1.621 + hret = pDevices[0].device->GetDeviceState(256, (LPVOID)pDevices[0].data); 1.622 + } 1.623 + 1.624 + return hret == DI_OK; 1.625 + } 1.626 +#else 1.627 + for (int i = 0; i < sizeof(win_key_trans_table)/sizeof(win_key_trans_table[0]); i++) { 1.628 + pDevices[0].data[win_key_trans_table[i].dik] = IsKeyDownAsync(win_key_trans_table[i].vk) ? 0x80 : 0; 1.629 + } 1.630 +#endif 1.631 + return true; 1.632 +} 1.633 + 1.634 +static bool readJoystick(int joy) 1.635 +{ 1.636 + if (pDevices[joy].needed) 1.637 + { 1.638 + if (pDevices[joy].isPolled) 1.639 + ((LPDIRECTINPUTDEVICE2)pDevices[joy].device)->Poll(); 1.640 + 1.641 + HRESULT hret = pDevices[joy].device-> 1.642 + GetDeviceState(sizeof(DIJOYSTATE), 1.643 + (LPVOID)&pDevices[joy].state); 1.644 + 1.645 + if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) 1.646 + { 1.647 + hret = pDevices[joy].device->Acquire(); 1.648 + 1.649 + if (hret == DI_OK) 1.650 + { 1.651 + if (pDevices[joy].isPolled) 1.652 + ((LPDIRECTINPUTDEVICE2)pDevices[joy].device)->Poll(); 1.653 + 1.654 + hret = pDevices[joy].device-> 1.655 + GetDeviceState(sizeof(DIJOYSTATE), 1.656 + (LPVOID)&pDevices[joy].state); 1.657 + } 1.658 + } 1.659 + 1.660 + return hret == DI_OK; 1.661 + } 1.662 + 1.663 + return true; 1.664 +} 1.665 + 1.666 +static void checkKeyboard() 1.667 +{ 1.668 + // mham fix. Patch #1378104 1.669 + UCHAR keystate[256]; 1.670 + HRESULT hret = pDevices[0].device->Acquire(); 1.671 + 1.672 + if (pDevices[0].first) 1.673 + { 1.674 + pDevices[0].device->GetDeviceState(256, (LPVOID)pDevices[0].data); 1.675 + pDevices[0].first = FALSE; 1.676 + return; 1.677 + } 1.678 + 1.679 + hret = pDevices[0].device-> 1.680 + GetDeviceState(256, (LPVOID)keystate); 1.681 + 1.682 + if (hret == DIERR_INPUTLOST || hret == DIERR_NOTACQUIRED) 1.683 + { 1.684 + return; 1.685 + } 1.686 + 1.687 + if (hret == DI_OK) 1.688 + { 1.689 + for (int i = 0; i < 256; i++) 1.690 + { 1.691 + if (keystate[i] == pDevices[0].data[i]) 1.692 + continue; 1.693 + if (KEYDOWN(keystate, i)) 1.694 + { 1.695 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, 0, i); 1.696 + break; 1.697 + } 1.698 + } 1.699 + } 1.700 + memcpy(pDevices[0].data, keystate, sizeof(UCHAR) * 256); 1.701 +} 1.702 + 1.703 +static void checkJoypads() 1.704 +{ 1.705 + DIDEVICEOBJECTINSTANCE di; 1.706 + 1.707 + ZeroMemory(&di, sizeof(DIDEVICEOBJECTINSTANCE)); 1.708 + 1.709 + di.dwSize = sizeof(DIDEVICEOBJECTINSTANCE); 1.710 + 1.711 + int i = 0; 1.712 + 1.713 + DIJOYSTATE joystick; 1.714 + 1.715 + for (i = 1; i < numDevices; i++) 1.716 + { 1.717 + HRESULT hret = pDevices[i].device->Acquire(); 1.718 + 1.719 + if (pDevices[i].isPolled) 1.720 + ((LPDIRECTINPUTDEVICE2)pDevices[i].device)->Poll(); 1.721 + 1.722 + hret = pDevices[i].device->GetDeviceState(sizeof(joystick), &joystick); 1.723 + 1.724 + int j; 1.725 + 1.726 + if (pDevices[i].first) 1.727 + { 1.728 + memcpy(&pDevices[i].state, &joystick, sizeof(joystick)); 1.729 + pDevices[i].first = FALSE; 1.730 + continue; 1.731 + } 1.732 + 1.733 + for (j = 0; j < pDevices[i].nButtons; j++) 1.734 + { 1.735 + if (((pDevices[i].state.rgbButtons[j] ^ joystick.rgbButtons[j]) 1.736 + & joystick.rgbButtons[j]) & 0x80) 1.737 + { 1.738 + HWND focus = GetFocus(); 1.739 + 1.740 + SendMessage(focus, JOYCONFIG_MESSAGE, i, j+128); 1.741 + } 1.742 + } 1.743 + 1.744 + for (j = 0; j < pDevices[i].nAxes && j < 8; j++) 1.745 + { 1.746 + LONG value = pDevices[i].axis[j].center; 1.747 + LONG old = 0; 1.748 + switch (pDevices[i].axis[j].offset) 1.749 + { 1.750 + case DIJOFS_X: 1.751 + value = joystick.lX; 1.752 + old = pDevices[i].state.lX; 1.753 + break; 1.754 + case DIJOFS_Y: 1.755 + value = joystick.lY; 1.756 + old = pDevices[i].state.lY; 1.757 + break; 1.758 + case DIJOFS_Z: 1.759 + value = joystick.lZ; 1.760 + old = pDevices[i].state.lZ; 1.761 + break; 1.762 + case DIJOFS_RX: 1.763 + value = joystick.lRx; 1.764 + old = pDevices[i].state.lRx; 1.765 + break; 1.766 + case DIJOFS_RY: 1.767 + value = joystick.lRy; 1.768 + old = pDevices[i].state.lRy; 1.769 + break; 1.770 + case DIJOFS_RZ: 1.771 + value = joystick.lRz; 1.772 + old = pDevices[i].state.lRz; 1.773 + break; 1.774 + case DIJOFS_SLIDER(0): 1.775 + value = joystick.rglSlider[0]; 1.776 + old = pDevices[i].state.rglSlider[0]; 1.777 + break; 1.778 + case DIJOFS_SLIDER(1): 1.779 + value = joystick.rglSlider[1]; 1.780 + old = pDevices[i].state.rglSlider[1]; 1.781 + break; 1.782 + } 1.783 + if (value != old) 1.784 + { 1.785 + if (value < pDevices[i].axis[j].negative) 1.786 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<1)); 1.787 + else if (value > pDevices[i].axis[j].positive) 1.788 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<1)+1); 1.789 + } 1.790 + } 1.791 + 1.792 + for (j = 0; j < 4 && j < pDevices[i].nPovs; j++) 1.793 + { 1.794 + if (LOWORD(pDevices[i].state.rgdwPOV[j]) != LOWORD(joystick.rgdwPOV[j])) 1.795 + { 1.796 + int state = getPovState(joystick.rgdwPOV[j]); 1.797 + 1.798 + if (state & POV_UP) 1.799 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x20); 1.800 + else if (state & POV_DOWN) 1.801 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x21); 1.802 + else if (state & POV_RIGHT) 1.803 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x22); 1.804 + else if (state & POV_LEFT) 1.805 + SendMessage(GetFocus(), JOYCONFIG_MESSAGE, i, (j<<2)+0x23); 1.806 + } 1.807 + } 1.808 + 1.809 + memcpy(&pDevices[i].state, &joystick, sizeof(joystick)); 1.810 + } 1.811 +} 1.812 + 1.813 +BOOL checkKey(LONG_PTR key) 1.814 +{ 1.815 + LONG_PTR dev = (key >> 8); 1.816 + 1.817 + LONG_PTR k = (key & 255); 1.818 + 1.819 + if (dev == 0) 1.820 + { 1.821 + return KEYDOWN(pDevices[0].data, k); 1.822 + } 1.823 + else if (dev >= numDevices) 1.824 + { 1.825 + return FALSE; 1.826 + } 1.827 + else 1.828 + { 1.829 + if (k < 16) 1.830 + { 1.831 + LONG_PTR axis = k >> 1; 1.832 + LONG value = pDevices[dev].axis[axis].center; 1.833 + switch (pDevices[dev].axis[axis].offset) 1.834 + { 1.835 + case DIJOFS_X: 1.836 + value = pDevices[dev].state.lX; 1.837 + break; 1.838 + case DIJOFS_Y: 1.839 + value = pDevices[dev].state.lY; 1.840 + break; 1.841 + case DIJOFS_Z: 1.842 + value = pDevices[dev].state.lZ; 1.843 + break; 1.844 + case DIJOFS_RX: 1.845 + value = pDevices[dev].state.lRx; 1.846 + break; 1.847 + case DIJOFS_RY: 1.848 + value = pDevices[dev].state.lRy; 1.849 + break; 1.850 + case DIJOFS_RZ: 1.851 + value = pDevices[dev].state.lRz; 1.852 + break; 1.853 + case DIJOFS_SLIDER(0): 1.854 + value = pDevices[dev].state.rglSlider[0]; 1.855 + break; 1.856 + case DIJOFS_SLIDER(1): 1.857 + value = pDevices[dev].state.rglSlider[1]; 1.858 + break; 1.859 + } 1.860 + 1.861 + if (k & 1) 1.862 + return value > pDevices[dev].axis[axis].positive; 1.863 + return value < pDevices[dev].axis[axis].negative; 1.864 + } 1.865 + else if (k < 48) 1.866 + { 1.867 + LONG_PTR hat = (k >> 2) & 3; 1.868 + int state = getPovState(pDevices[dev].state.rgdwPOV[hat]); 1.869 + BOOL res = FALSE; 1.870 + switch (k & 3) 1.871 + { 1.872 + case 0: 1.873 + res = state & POV_UP; 1.874 + break; 1.875 + case 1: 1.876 + res = state & POV_DOWN; 1.877 + break; 1.878 + case 2: 1.879 + res = state & POV_RIGHT; 1.880 + break; 1.881 + case 3: 1.882 + res = state & POV_LEFT; 1.883 + break; 1.884 + } 1.885 + return res; 1.886 + } 1.887 + else if (k >= 128) 1.888 + { 1.889 + return pDevices[dev].state.rgbButtons[k-128] & 0x80; 1.890 + } 1.891 + } 1.892 + 1.893 + return FALSE; 1.894 +} 1.895 + 1.896 +DirectInput::DirectInput() 1.897 +{ 1.898 + dinputDLL = NULL; 1.899 +} 1.900 + 1.901 +DirectInput::~DirectInput() 1.902 +{ 1.903 + saveSettings(); 1.904 + if (pDirectInput != NULL) 1.905 + { 1.906 + if (pDevices) 1.907 + { 1.908 + for (int i = 0; i < numDevices; i++) 1.909 + { 1.910 + if (pDevices[i].device) 1.911 + { 1.912 + pDevices[i].device->Unacquire(); 1.913 + pDevices[i].device->Release(); 1.914 + pDevices[i].device = NULL; 1.915 + } 1.916 + } 1.917 + free(pDevices); 1.918 + pDevices = NULL; 1.919 + } 1.920 + 1.921 + pDirectInput->Release(); 1.922 + pDirectInput = NULL; 1.923 + } 1.924 + 1.925 + if (dinputDLL) 1.926 + { 1.927 + /**/ ::FreeLibrary(dinputDLL); 1.928 + dinputDLL = NULL; 1.929 + } 1.930 +} 1.931 + 1.932 +bool DirectInput::initialize() 1.933 +{ 1.934 + joyDebug = GetPrivateProfileInt("config", 1.935 + "joyDebug", 1.936 + 0, 1.937 + "VBA.ini"); 1.938 + dinputDLL = /**/ ::LoadLibrary("DINPUT.DLL"); 1.939 + HRESULT (WINAPI *DInputCreate)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *); 1.940 + if (dinputDLL != NULL) 1.941 + { 1.942 + DInputCreate = (HRESULT (WINAPI *)(HINSTANCE, DWORD, LPDIRECTINPUT *, IUnknown *)) 1.943 + GetProcAddress(dinputDLL, "DirectInputCreateA"); 1.944 + 1.945 + if (DInputCreate == NULL) 1.946 + { 1.947 + directXMessage("DirectInputCreateA"); 1.948 + return false; 1.949 + } 1.950 + } 1.951 + else 1.952 + { 1.953 + directXMessage("DINPUT.DLL"); 1.954 + return false; 1.955 + } 1.956 + 1.957 + HRESULT hret = DInputCreate(AfxGetInstanceHandle(), 1.958 + DIRECTINPUT_VERSION, 1.959 + &pDirectInput, 1.960 + NULL); 1.961 + if (hret != DI_OK) 1.962 + { 1.963 + // errorMessage(myLoadString(IDS_ERROR_DISP_CREATE), hret); 1.964 + return false; 1.965 + } 1.966 + 1.967 + hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK, 1.968 + DIEnumDevicesCallback2, 1.969 + NULL, 1.970 + DIEDFL_ATTACHEDONLY); 1.971 + 1.972 + pDevices = (deviceInfo *)calloc(numDevices, sizeof(deviceInfo)); 1.973 + 1.974 + hret = pDirectInput->CreateDevice(GUID_SysKeyboard, &pDevices[0].device, NULL); 1.975 + pDevices[0].isPolled = false; 1.976 + pDevices[0].needed = true; 1.977 + pDevices[0].first = true; 1.978 + 1.979 + if (hret != DI_OK) 1.980 + { 1.981 + // errorMessage(myLoadString(IDS_ERROR_DISP_CREATEDEVICE), hret); 1.982 + return false; 1.983 + } 1.984 + 1.985 + numDevices = 1; 1.986 + 1.987 + hret = pDirectInput->EnumDevices(DIDEVTYPE_JOYSTICK, 1.988 + DIEnumDevicesCallback, 1.989 + NULL, 1.990 + DIEDFL_ATTACHEDONLY); 1.991 + 1.992 + // hret = pDevices[0].device->SetCooperativeLevel(hWindow, 1.993 + // DISCL_FOREGROUND| 1.994 + // DISCL_NONEXCLUSIVE); 1.995 + 1.996 + if (hret != DI_OK) 1.997 + { 1.998 + // errorMessage(myLoadString(IDS_ERROR_DISP_LEVEL), hret); 1.999 + return false; 1.1000 + } 1.1001 + 1.1002 + hret = pDevices[0].device->SetDataFormat(&c_dfDIKeyboard); 1.1003 + 1.1004 + if (hret != DI_OK) 1.1005 + { 1.1006 + // errorMessage(myLoadString(IDS_ERROR_DISP_DATAFORMAT), hret); 1.1007 + return false; 1.1008 + } 1.1009 + 1.1010 + for (int i = 1; i < numDevices; i++) 1.1011 + { 1.1012 + pDevices[i].device->SetDataFormat(&c_dfDIJoystick); 1.1013 + pDevices[i].needed = false; 1.1014 + pDevices[i].first = true; 1.1015 + currentDevice = &pDevices[i]; 1.1016 + axisNumber = 0; 1.1017 + currentDevice->device->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS); 1.1018 + currentDevice->device->EnumObjects(EnumPovsCallback, NULL, DIDFT_POV); 1.1019 + if (joyDebug) 1.1020 + { 1.1021 + // don't translate. debug only 1.1022 + winlog("Joystick %2d polled : %d\n", i, currentDevice->isPolled); 1.1023 + winlog("Joystick %2d buttons : %d\n", i, currentDevice->nButtons); 1.1024 + winlog("Joystick %2d povs : %d\n", i, currentDevice->nPovs); 1.1025 + winlog("Joystick %2d axes : %d\n", i, currentDevice->nAxes); 1.1026 + for (int j = 0; j < currentDevice->nAxes; j++) 1.1027 + { 1.1028 + winlog("Axis %2d offset : %08lx\n", j, currentDevice->axis[j]. 1.1029 + offset); 1.1030 + winlog("Axis %2d center : %08lx\n", j, currentDevice->axis[j]. 1.1031 + center); 1.1032 + winlog("Axis %2d negative : %08lx\n", j, currentDevice->axis[j]. 1.1033 + negative); 1.1034 + winlog("Axis %2d positive : %08lx\n", j, currentDevice->axis[j]. 1.1035 + positive); 1.1036 + } 1.1037 + } 1.1038 + 1.1039 + currentDevice = NULL; 1.1040 + } 1.1041 + 1.1042 + for (int i = 0; i < numDevices; i++) 1.1043 + pDevices[i].device->Acquire(); 1.1044 + 1.1045 + return true; 1.1046 +} 1.1047 + 1.1048 +bool DirectInput::readDevices() 1.1049 +{ 1.1050 + bool ok = true; 1.1051 + for (int i = 0; i < numDevices; i++) 1.1052 + { 1.1053 + if (pDevices[i].needed) 1.1054 + { 1.1055 + ok = (i > 0 ? readJoystick(i) : readKeyboard()) || ok; 1.1056 + } 1.1057 + } 1.1058 + return ok; 1.1059 +} 1.1060 + 1.1061 +bool inputActive = true; // used to disable all input when the window is inactive 1.1062 + 1.1063 +u32 DirectInput::readDevice(int i, bool sensor) 1.1064 +{ 1.1065 + // this old hack is evil 1.1066 + extern int systemGetDefaultJoypad(); 1.1067 + extern int32 gbSgbMode, gbSgbMultiplayer; 1.1068 + if (!(gbSgbMode && gbSgbMultiplayer)) 1.1069 + i = systemGetDefaultJoypad(); 1.1070 + 1.1071 + u32 res = 0; 1.1072 + 1.1073 + // manual input 1.1074 + if (inputActive) 1.1075 + { 1.1076 + if (checkKey(joypad[i][KEY_BUTTON_A])) 1.1077 + res |= BUTTON_MASK_A; 1.1078 + if (checkKey(joypad[i][KEY_BUTTON_B])) 1.1079 + res |= BUTTON_MASK_B; 1.1080 + if (checkKey(joypad[i][KEY_BUTTON_SELECT])) 1.1081 + res |= BUTTON_MASK_SELECT; 1.1082 + if (checkKey(joypad[i][KEY_BUTTON_START])) 1.1083 + res |= BUTTON_MASK_START; 1.1084 + if (checkKey(joypad[i][KEY_RIGHT])) 1.1085 + res |= BUTTON_MASK_RIGHT; 1.1086 + if (checkKey(joypad[i][KEY_LEFT])) 1.1087 + res |= BUTTON_MASK_LEFT; 1.1088 + if (checkKey(joypad[i][KEY_UP])) 1.1089 + res |= BUTTON_MASK_UP; 1.1090 + if (checkKey(joypad[i][KEY_DOWN])) 1.1091 + res |= BUTTON_MASK_DOWN; 1.1092 + if (checkKey(joypad[i][KEY_BUTTON_R])) 1.1093 + res |= BUTTON_MASK_R; 1.1094 + if (checkKey(joypad[i][KEY_BUTTON_L])) 1.1095 + res |= BUTTON_MASK_L; 1.1096 + 1.1097 + // unused 1.1098 + if (checkKey(motion[KEY_LEFT])) 1.1099 + res |= BUTTON_MASK_LEFT_MOTION; 1.1100 + else if (checkKey(motion[KEY_RIGHT])) 1.1101 + res |= BUTTON_MASK_RIGHT_MOTION; 1.1102 + if (checkKey(motion[KEY_UP])) 1.1103 + res |= BUTTON_MASK_UP_MOTION; 1.1104 + else if (checkKey(motion[KEY_DOWN])) 1.1105 + res |= BUTTON_MASK_DOWN_MOTION; 1.1106 + } 1.1107 + 1.1108 + u32 hackedButtons = 0; 1.1109 + if (inputActive) 1.1110 + { 1.1111 + // the "non-button" buttons (what a hack!) 1.1112 + if (checkKey(joypad[i][KEY_BUTTON_SPEED])) 1.1113 + hackedButtons |= BUTTON_MASK_SPEED; 1.1114 + if (checkKey(joypad[i][KEY_BUTTON_CAPTURE])) 1.1115 + hackedButtons |= BUTTON_MASK_CAPTURE; 1.1116 + if (checkKey(joypad[i][KEY_BUTTON_GS])) 1.1117 + hackedButtons |= BUTTON_MASK_GAMESHARK; 1.1118 + } 1.1119 + 1.1120 + extern bool systemIsSpedUp(); 1.1121 + if (systemIsSpedUp()) 1.1122 + hackedButtons |= BUTTON_MASK_SPEED; 1.1123 + 1.1124 + return res | hackedButtons; 1.1125 +} 1.1126 + 1.1127 +CString DirectInput::getKeyName(LONG_PTR key) 1.1128 +{ 1.1129 + LONG_PTR d = (key >> 8); 1.1130 + LONG_PTR k = key & 255; 1.1131 + 1.1132 + DIDEVICEOBJECTINSTANCE di; 1.1133 + 1.1134 + ZeroMemory(&di, sizeof(DIDEVICEOBJECTINSTANCE)); 1.1135 + 1.1136 + di.dwSize = sizeof(DIDEVICEOBJECTINSTANCE); 1.1137 + 1.1138 + CString winBuffer = winResLoadString(IDS_ERROR); 1.1139 + 1.1140 + if (d == 0) 1.1141 + { 1.1142 + pDevices[0].device->GetObjectInfo(&di, (DWORD)key, DIPH_BYOFFSET); 1.1143 + winBuffer = di.tszName; 1.1144 + } 1.1145 + else if (d < numDevices) 1.1146 + { 1.1147 + if (k < 16) 1.1148 + { 1.1149 + if (k < 4) 1.1150 + { 1.1151 + switch (k) 1.1152 + { 1.1153 + case 0: 1.1154 + winBuffer.Format(winResLoadString(IDS_JOY_LEFT), d); 1.1155 + break; 1.1156 + case 1: 1.1157 + winBuffer.Format(winResLoadString(IDS_JOY_RIGHT), d); 1.1158 + break; 1.1159 + case 2: 1.1160 + winBuffer.Format(winResLoadString(IDS_JOY_UP), d); 1.1161 + break; 1.1162 + case 3: 1.1163 + winBuffer.Format(winResLoadString(IDS_JOY_DOWN), d); 1.1164 + break; 1.1165 + } 1.1166 + } 1.1167 + else 1.1168 + { 1.1169 + pDevices[d].device->GetObjectInfo(&di, 1.1170 + pDevices[d].axis[k>>1].offset, 1.1171 + DIPH_BYOFFSET); 1.1172 + if (k & 1) 1.1173 + winBuffer.Format("Joy %d %s +", d, di.tszName); 1.1174 + else 1.1175 + winBuffer.Format("Joy %d %s -", d, di.tszName); 1.1176 + } 1.1177 + } 1.1178 + else if (k < 48) 1.1179 + { 1.1180 + LONG_PTR hat = (k >> 2) & 3; 1.1181 + pDevices[d].device->GetObjectInfo(&di, 1.1182 + (DWORD)DIJOFS_POV(hat), 1.1183 + DIPH_BYOFFSET); 1.1184 + char * dir = "up"; 1.1185 + LONG_PTR dd = k & 3; 1.1186 + if (dd == 1) 1.1187 + dir = "down"; 1.1188 + else if (dd == 2) 1.1189 + dir = "right"; 1.1190 + else if (dd == 3) 1.1191 + dir = "left"; 1.1192 + winBuffer.Format("Joy %d %s %s", d, di.tszName, dir); 1.1193 + } 1.1194 + else 1.1195 + { 1.1196 + pDevices[d].device->GetObjectInfo(&di, 1.1197 + (DWORD)DIJOFS_BUTTON(k-128), 1.1198 + DIPH_BYOFFSET); 1.1199 + winBuffer.Format(winResLoadString(IDS_JOY_BUTTON), d, di.tszName); 1.1200 + } 1.1201 + } 1.1202 + else 1.1203 + { 1.1204 + // Joystick isn't plugged in. We can't decipher k, so just show its value. 1.1205 + winBuffer.Format("Joy %d (%d)", d, k); 1.1206 + } 1.1207 + 1.1208 + return winBuffer; 1.1209 +} 1.1210 + 1.1211 +void DirectInput::checkKeys() 1.1212 +{ 1.1213 + ::checkKeys(); 1.1214 +} 1.1215 + 1.1216 +Input *newDirectInput() 1.1217 +{ 1.1218 + return new DirectInput; 1.1219 +} 1.1220 + 1.1221 +void DirectInput::checkDevices() 1.1222 +{ 1.1223 + checkJoypads(); 1.1224 + checkKeyboard(); 1.1225 +} 1.1226 + 1.1227 +void DirectInput::activate() 1.1228 +{ 1.1229 + for (int i = 0; i < numDevices; i++) 1.1230 + { 1.1231 + if (pDevices != NULL && pDevices[i].device != NULL) 1.1232 + pDevices[i].device->Acquire(); 1.1233 + } 1.1234 +} 1.1235 + 1.1236 +void DirectInput::loadSettings() 1.1237 +{ 1.1238 + winReadKeys(); 1.1239 +} 1.1240 + 1.1241 +void DirectInput::saveSettings() 1.1242 +{ 1.1243 + winSaveKeys(); 1.1244 +} 1.1245 +