1 /** @file directinput.cpp DirectInput for Windows.
2 * @ingroup input
3 *
4 * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
5 * @authors Copyright © 2005-2013 Daniel Swanson <danij@dengine.net>
6 *
7 * @par License
8 * GPL: http://www.gnu.org/licenses/gpl.html
9 *
10 * <small>This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. This program is distributed in the hope that it
14 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details. You should have received a copy of the GNU
17 * General Public License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA</small>
20 */
21
22 #ifdef __CLIENT__
23
24 #include "directinput.h"
25 #include "dd_winit.h"
26 #include <de/Log>
27 #include <doomsday/doomsdayapp.h>
28
29 static LPDIRECTINPUT8 dInput;
30 static LPDIRECTINPUT dInput3;
31
DirectInput_ErrorMsg(HRESULT hr)32 const char* DirectInput_ErrorMsg(HRESULT hr)
33 {
34 return hr == DI_OK ? "OK" : hr == DIERR_GENERIC ? "Generic error" : hr ==
35 DI_PROPNOEFFECT ? "Property has no effect" : hr ==
36 DIERR_INVALIDPARAM ? "Invalid parameter" : hr ==
37 DIERR_NOTINITIALIZED ? "Not initialized" : hr ==
38 DIERR_UNSUPPORTED ? "Unsupported" : hr ==
39 DIERR_NOTFOUND ? "Not found" : "?";
40 }
41
DirectInput_Init(void)42 int DirectInput_Init(void)
43 {
44 HRESULT hr;
45
46 if(dInput || dInput3) return true;
47
48 // Create the DirectInput interface instance. Try version 8 first.
49 if(FAILED(hr = CoCreateInstance(CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
50 IID_IDirectInput8, (LPVOID*)&dInput)) ||
51 FAILED(hr = dInput->Initialize((HINSTANCE) DoomsdayApp::app().moduleHandle(), DIRECTINPUT_VERSION)))
52 {
53 LOGDEV_INPUT_ERROR("DirectInput 8 init failed (0x%x)") << hr;
54
55 // Try the older version 3 interface instead.
56 // I'm not sure if this works correctly.
57 if(FAILED(hr = CoCreateInstance(CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
58 IID_IDirectInput2W, (LPVOID*)&dInput3)) ||
59 FAILED(hr = dInput3->Initialize((HINSTANCE) DoomsdayApp::app().moduleHandle(), 0x0300)))
60 {
61 LOGDEV_INPUT_ERROR("Failed to create DirectInput 3 object (0x%x)") << hr;
62 return false;
63 }
64
65 LOG_INPUT_NOTE("Using DirectInput 3 as fallback");
66 }
67
68 if(!dInput && !dInput3)
69 {
70 LOG_INPUT_ERROR("DirectInput init failed");
71 return false;
72 }
73
74 return true;
75 }
76
DirectInput_Shutdown(void)77 void DirectInput_Shutdown(void)
78 {
79 if(dInput)
80 {
81 IDirectInput_Release(dInput);
82 dInput = 0;
83 }
84 if(dInput3)
85 {
86 IDirectInput_Release(dInput3);
87 dInput3 = 0;
88 }
89 }
90
DirectInput_IVersion8()91 LPDIRECTINPUT8 DirectInput_IVersion8()
92 {
93 return dInput;
94 }
95
DirectInput_IVersion3()96 LPDIRECTINPUT DirectInput_IVersion3()
97 {
98 return dInput3;
99 }
100
DirectInput_KillDevice(LPDIRECTINPUTDEVICE8 * dev)101 void DirectInput_KillDevice(LPDIRECTINPUTDEVICE8* dev)
102 {
103 if(*dev) (*dev)->Unacquire();
104 I_SAFE_RELEASE(*dev);
105 }
106
107 #endif // __CLIENT__
108