00001
00002 #include "revolt.h"
00003 #include "input.h"
00004 #include "dx.h"
00005 #include "main.h"
00006 #include "ctrlread.h"
00007 #include "control.h"
00008
00009
00010
00011 char Keys[256];
00012 char LastKeys[256];
00013 DIMOUSESTATE Mouse;
00014
00015 static IDirectInput8 *DI;
00016 static IDirectInputDevice8 *KeyboardDevice;
00017 static IDirectInputDevice8 *MouseDevice;
00018 long JoystickNum, CurrentJoystick;
00019 JOYSTICK Joystick[MAX_JOYSTICKS];
00020 DIJOYSTATE JoystickState;
00021
00023
00025
00026 unsigned char ShiftKey[] = {
00027 '0', ')',
00028 '1', '!',
00029 '2', '"',
00030 '3', '£',
00031 '4', '$',
00032 '5', '%',
00033 '6', '^',
00034 '7', '&',
00035 '8', '*',
00036 '9', '(',
00037
00038 '-', '_',
00039 '=', '+',
00040 92 , '|',
00041
00042 '[', '{',
00043 ']', '}',
00044 ';', ':',
00045 39 , '@',
00046 '#', '~',
00047 ',', '<',
00048 '.', '>',
00049 '/', '?',
00050 '`', '¬',
00051
00052 255,
00053 };
00054
00056
00058
00059 long InitInput(HINSTANCE inst)
00060 {
00061 HRESULT r;
00062
00063
00064
00065 r = DirectInput8Create(inst, DIRECTINPUT_VERSION, IID_IDirectInput8A, (LPVOID *) &DI, NULL);
00066 if (r != DI_OK)
00067 {
00068 ErrorDX(r, "Can't create input object!");
00069 QuitGame = TRUE;
00070 return FALSE;
00071 }
00072
00073
00074
00075 r = DI->CreateDevice(GUID_SysKeyboard, &KeyboardDevice, NULL);
00076 if (r != DI_OK)
00077 {
00078 ErrorDX(r, "Can't create keyboard device");
00079 QuitGame = TRUE;
00080 return FALSE;
00081 }
00082
00083 r = KeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
00084 if (r != DI_OK)
00085 {
00086 ErrorDX(r, "Can't set keyboard data format");
00087 QuitGame = TRUE;
00088 return FALSE;
00089 }
00090
00091 r = KeyboardDevice->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
00092 if (r != DI_OK)
00093 {
00094 ErrorDX(r, "Can't set keyboard coop level");
00095 return FALSE;
00096 }
00097
00098
00099
00100 r = DI->CreateDevice(GUID_SysMouse, &MouseDevice, NULL);
00101 if (r != DI_OK)
00102 {
00103 ErrorDX(r, "Can't create mouse device");
00104 QuitGame = TRUE;
00105 return FALSE;
00106 }
00107
00108 r = MouseDevice->SetDataFormat(&c_dfDIMouse);
00109 if (r != DI_OK)
00110 {
00111 ErrorDX(r, "Can't set mouse data format");
00112 QuitGame = TRUE;
00113 return FALSE;
00114 }
00115
00116
00117 r = MouseDevice->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
00118 if (r != DI_OK)
00119 {
00120 ErrorDX(r, "Can't set mouse coop level");
00121 return FALSE;
00122 }
00123
00124
00125
00126 CurrentJoystick = -1;
00127 JoystickNum = 0;
00128
00129 r = DI->EnumDevices(DI8DEVCLASS_GAMECTRL, (LPDIENUMDEVICESCALLBACK)EnumJoystickCallback, NULL, DIEDFL_ATTACHEDONLY);
00130 if (r != DI_OK)
00131 {
00132 ErrorDX(r, "Can't enumerate joysticks!");
00133 QuitGame = TRUE;
00134 return FALSE;
00135 }
00136
00137
00138
00139 return TRUE;
00140 }
00142
00144
00145 void SetMouseExclusive(long flag)
00146 {
00147 MouseDevice->Unacquire();
00148 MouseDevice->SetCooperativeLevel(hwnd, flag ? DISCL_EXCLUSIVE | DISCL_FOREGROUND : DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
00149 }
00150
00152
00154
00155 BOOL CALLBACK EnumJoystickCallback(DIDEVICEINSTANCE *inst, void *user)
00156 {
00157 long i;
00158 HRESULT r;
00159 JOYSTICK *joy = &Joystick[JoystickNum];
00160 DIPROPRANGE range;
00161 DIPROPDWORD deadzone, saturation;
00162 IDirectInputDevice8 *dev;
00163
00164
00165
00166 r = DI->CreateDevice(inst->guidInstance, &dev, NULL);
00167 if (r != DI_OK)
00168 {
00169 return DIENUM_CONTINUE;
00170 }
00171
00172 r = dev->QueryInterface(IID_IDirectInputDevice2, (void**)&joy->Device);
00173 RELEASE(dev);
00174 if (r != DI_OK)
00175 {
00176 return DIENUM_CONTINUE;
00177 }
00178
00179 r = joy->Device->SetDataFormat(&c_dfDIJoystick);
00180 if (r != DI_OK)
00181 {
00182 RELEASE(joy->Device);
00183 return DIENUM_CONTINUE;
00184 }
00185
00186 r = joy->Device->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
00187 if (r != DI_OK)
00188 {
00189 RELEASE(joy->Device);
00190 return DIENUM_CONTINUE;
00191 }
00192
00193 joy->Caps.dwSize = sizeof(joy->Caps);
00194 r = joy->Device->GetCapabilities(&joy->Caps);
00195 if (r != DI_OK)
00196 {
00197 RELEASE(joy->Device);
00198 return DIENUM_CONTINUE;
00199 }
00200
00201
00202
00203 range.diph.dwSize = sizeof(range);
00204 range.diph.dwHeaderSize = sizeof(range.diph);
00205 range.diph.dwObj = 0;
00206 range.diph.dwHow = DIPH_DEVICE;
00207 range.lMin = -CTRL_RANGE_MAX;
00208 range.lMax = CTRL_RANGE_MAX;
00209
00210 r = joy->Device->SetProperty(DIPROP_RANGE, &range.diph);
00211 if (r != DI_OK)
00212 {
00213 RELEASE(joy->Device);
00214 return DIENUM_CONTINUE;
00215 }
00216
00217
00218
00219 deadzone.diph.dwSize = sizeof(deadzone);
00220 deadzone.diph.dwHeaderSize = sizeof(deadzone.diph);
00221 deadzone.diph.dwObj = 0;
00222 deadzone.diph.dwHow = DIPH_DEVICE;
00223 deadzone.dwData = 1000;
00224
00225 r = joy->Device->SetProperty(DIPROP_DEADZONE, &deadzone.diph);
00226 if (r != DI_OK)
00227 {
00228 RELEASE(joy->Device);
00229 return DIENUM_CONTINUE;
00230 }
00231
00232
00233
00234 saturation.diph.dwSize = sizeof(saturation);
00235 saturation.diph.dwHeaderSize = sizeof(saturation.diph);
00236 saturation.diph.dwObj = 0;
00237 saturation.diph.dwHow = DIPH_DEVICE;
00238 saturation.dwData = 9000;
00239
00240 r = joy->Device->SetProperty(DIPROP_SATURATION, &saturation.diph);
00241 if (r != DI_OK)
00242 {
00243 RELEASE(joy->Device);
00244 return DIENUM_CONTINUE;
00245 }
00246
00247
00248
00249 for (i = 0 ; i < MAX_AXIS ; i++) joy->Axis[i] = FALSE;
00250
00251 r = joy->Device->EnumObjects((LPDIENUMDEVICEOBJECTSCALLBACK)EnumObjectsCallback, (void*)joy, DIDFT_ALL);
00252 if (r != DI_OK)
00253 {
00254 RELEASE(joy->Device);
00255 return DIENUM_CONTINUE;
00256 }
00257
00258
00259
00260 memcpy(joy->Name, inst->tszProductName, MAX_PATH);
00261
00262
00263
00264 JoystickNum++;
00265 if (JoystickNum == MAX_JOYSTICKS) return DIENUM_STOP;
00266 else return DIENUM_CONTINUE;
00267 }
00268
00270
00272
00273 BOOL CALLBACK EnumObjectsCallback(DIDEVICEOBJECTINSTANCE *inst, void *user)
00274 {
00275 JOYSTICK *joy = (JOYSTICK*)user;
00276
00277
00278
00279 if (inst->dwType & DIDFT_ABSAXIS)
00280 {
00281 if (inst->guidType == GUID_XAxis) joy->Axis[X_AXIS] = TRUE;
00282 if (inst->guidType == GUID_YAxis) joy->Axis[Y_AXIS] = TRUE;
00283 if (inst->guidType == GUID_ZAxis) joy->Axis[Z_AXIS] = TRUE;
00284 if (inst->guidType == GUID_RxAxis) joy->Axis[ROTX_AXIS] = TRUE;
00285 if (inst->guidType == GUID_RyAxis) joy->Axis[ROTY_AXIS] = TRUE;
00286 if (inst->guidType == GUID_RzAxis) joy->Axis[ROTZ_AXIS] = TRUE;
00287 }
00288
00289
00290
00291 return DIENUM_CONTINUE;
00292 }
00293
00295
00297
00298 void KillInput(void)
00299 {
00300 long i;
00301
00302
00303
00304 KeyboardDevice->Unacquire();
00305 RELEASE(KeyboardDevice);
00306
00307
00308
00309 MouseDevice->Unacquire();
00310 RELEASE(MouseDevice);
00311
00312
00313
00314 for (i = 0 ; i < JoystickNum ; i++)
00315 {
00316 Joystick[i].Device->Unacquire();
00317 RELEASE(Joystick[i].Device);
00318 }
00319
00320
00321
00322 RELEASE(DI);
00323 }
00324
00326
00328
00329 void ReadKeyboard(void)
00330 {
00331 long i;
00332
00333
00334
00335 for (i = 0 ; i < 256 ; i++)
00336 LastKeys[i] = Keys[i];
00337
00338
00339
00340 KeyboardDevice->Acquire();
00341 KeyboardDevice->GetDeviceState(sizeof(Keys), &Keys);
00342 }
00343
00345
00347
00348 void ReadMouse(void)
00349 {
00350
00351
00352
00353 MouseDevice->Acquire();
00354 MouseDevice->GetDeviceState(sizeof(Mouse), &Mouse);
00355 }
00356
00358
00360
00361 void ReadJoystick(void)
00362 {
00363
00364
00365
00366 if (CurrentJoystick == -1)
00367 return;
00368
00369
00370
00371 Joystick[CurrentJoystick].Device->Acquire();
00372 Joystick[CurrentJoystick].Device->Poll();
00373 Joystick[CurrentJoystick].Device->GetDeviceState(sizeof(JoystickState), &JoystickState);
00374 }
00375
00377
00379
00380 unsigned char GetKeyPress(void)
00381 {
00382 short i;
00383 unsigned char *p;
00384 unsigned long vk, ch;
00385
00386
00387
00388 for (i = 0 ; i < 255 ; i++) if (Keys[i] && !LastKeys[i])
00389 {
00390
00391
00392
00393 vk = MapVirtualKey(i, 1);
00394 if (!vk) continue;
00395
00396 ch = MapVirtualKey(vk, 2);
00397 if (!ch) continue;
00398
00399
00400
00401 if (Keys[DIK_LSHIFT] || Keys[DIK_RSHIFT])
00402 {
00403 p = ShiftKey;
00404 while (*p != 255 && *p != ch) p += 2;
00405 if (*p == ch) ch = *(p + 1);
00406 }
00407
00408
00409
00410 else
00411 {
00412 if (ch >= 'A' && ch <= 'Z' && !(GetKeyState(VK_CAPITAL) & 1)) ch += ('a' - 'A');
00413 }
00414
00415 return (unsigned char)ch;
00416 }
00417
00418
00419
00420 return FALSE;
00421 }