gosu 0.7.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. data/COPYING.txt +29 -0
  2. data/Gosu/Async.hpp +48 -0
  3. data/Gosu/Audio.hpp +145 -0
  4. data/Gosu/AutoLink.hpp +16 -0
  5. data/Gosu/Bitmap.hpp +85 -0
  6. data/Gosu/ButtonsMac.hpp +114 -0
  7. data/Gosu/ButtonsWin.hpp +111 -0
  8. data/Gosu/ButtonsX.hpp +115 -0
  9. data/Gosu/Color.hpp +172 -0
  10. data/Gosu/Directories.hpp +36 -0
  11. data/Gosu/Font.hpp +59 -0
  12. data/Gosu/Fwd.hpp +31 -0
  13. data/Gosu/Gosu.hpp +26 -0
  14. data/Gosu/Graphics.hpp +86 -0
  15. data/Gosu/GraphicsBase.hpp +45 -0
  16. data/Gosu/IO.hpp +255 -0
  17. data/Gosu/Image.hpp +148 -0
  18. data/Gosu/ImageData.hpp +45 -0
  19. data/Gosu/Input.hpp +116 -0
  20. data/Gosu/Math.hpp +95 -0
  21. data/Gosu/Platform.hpp +61 -0
  22. data/Gosu/RotFlip.hpp +116 -0
  23. data/Gosu/Sockets.hpp +129 -0
  24. data/Gosu/Text.hpp +47 -0
  25. data/Gosu/TextInput.hpp +57 -0
  26. data/Gosu/Timing.hpp +16 -0
  27. data/Gosu/Utility.hpp +24 -0
  28. data/Gosu/WinUtility.hpp +76 -0
  29. data/Gosu/Window.hpp +84 -0
  30. data/GosuImpl/Async.cpp +37 -0
  31. data/GosuImpl/AudioFmod.cpp +417 -0
  32. data/GosuImpl/AudioSDL.cpp +255 -0
  33. data/GosuImpl/DirectoriesMac.mm +38 -0
  34. data/GosuImpl/DirectoriesUnix.cpp +48 -0
  35. data/GosuImpl/DirectoriesWin.cpp +42 -0
  36. data/GosuImpl/FileUnix.cpp +100 -0
  37. data/GosuImpl/FileWin.cpp +83 -0
  38. data/GosuImpl/Graphics/Bitmap.cpp +116 -0
  39. data/GosuImpl/Graphics/BitmapBMP.cpp +232 -0
  40. data/GosuImpl/Graphics/BitmapColorKey.cpp +39 -0
  41. data/GosuImpl/Graphics/BitmapPNG.cpp +276 -0
  42. data/GosuImpl/Graphics/BitmapUtils.cpp +67 -0
  43. data/GosuImpl/Graphics/BlockAllocator.cpp +127 -0
  44. data/GosuImpl/Graphics/BlockAllocator.hpp +34 -0
  45. data/GosuImpl/Graphics/Color.cpp +126 -0
  46. data/GosuImpl/Graphics/Common.hpp +21 -0
  47. data/GosuImpl/Graphics/DrawOp.hpp +154 -0
  48. data/GosuImpl/Graphics/Font.cpp +110 -0
  49. data/GosuImpl/Graphics/Graphics.cpp +295 -0
  50. data/GosuImpl/Graphics/Image.cpp +159 -0
  51. data/GosuImpl/Graphics/LargeImageData.cpp +115 -0
  52. data/GosuImpl/Graphics/LargeImageData.hpp +37 -0
  53. data/GosuImpl/Graphics/RotFlip.cpp +184 -0
  54. data/GosuImpl/Graphics/TexChunk.cpp +77 -0
  55. data/GosuImpl/Graphics/TexChunk.hpp +40 -0
  56. data/GosuImpl/Graphics/Text.cpp +223 -0
  57. data/GosuImpl/Graphics/TextMac.cpp +242 -0
  58. data/GosuImpl/Graphics/TextPangoFT.cpp +186 -0
  59. data/GosuImpl/Graphics/TextWin.cpp +172 -0
  60. data/GosuImpl/Graphics/Texture.cpp +104 -0
  61. data/GosuImpl/Graphics/Texture.hpp +34 -0
  62. data/GosuImpl/IO.cpp +48 -0
  63. data/GosuImpl/InputMac.mm +677 -0
  64. data/GosuImpl/InputWin.cpp +444 -0
  65. data/GosuImpl/InputX.cpp +158 -0
  66. data/GosuImpl/MacUtility.hpp +48 -0
  67. data/GosuImpl/Math.cpp +49 -0
  68. data/GosuImpl/RubyGosu.swg +474 -0
  69. data/GosuImpl/RubyGosuStub.mm +17 -0
  70. data/GosuImpl/RubyGosu_DllMain.cxx +30 -0
  71. data/GosuImpl/RubyGosu_wrap.cxx +8521 -0
  72. data/GosuImpl/RubyGosu_wrap.h +31 -0
  73. data/GosuImpl/Sockets/CommSocket.cpp +304 -0
  74. data/GosuImpl/Sockets/ListenerSocket.cpp +60 -0
  75. data/GosuImpl/Sockets/MessageSocket.cpp +136 -0
  76. data/GosuImpl/Sockets/Socket.cpp +145 -0
  77. data/GosuImpl/Sockets/Sockets.hpp +66 -0
  78. data/GosuImpl/TextInputMac.mm +207 -0
  79. data/GosuImpl/TextInputWin.cpp +197 -0
  80. data/GosuImpl/TextInputX.cpp +201 -0
  81. data/GosuImpl/TextTTFWin.cpp +247 -0
  82. data/GosuImpl/TimingUnix.cpp +17 -0
  83. data/GosuImpl/TimingWin.cpp +28 -0
  84. data/GosuImpl/Utility.cpp +140 -0
  85. data/GosuImpl/WinMain.cpp +69 -0
  86. data/GosuImpl/WinUtility.cpp +137 -0
  87. data/GosuImpl/WindowMac.mm +466 -0
  88. data/GosuImpl/WindowWin.cpp +447 -0
  89. data/GosuImpl/WindowX.cpp +392 -0
  90. data/GosuImpl/X11vroot.h +118 -0
  91. data/README.txt +13 -0
  92. data/Rakefile +178 -0
  93. data/examples/ChipmunkIntegration.rb +275 -0
  94. data/examples/CptnRuby.rb +231 -0
  95. data/examples/MoreChipmunkAndRMagick.rb +155 -0
  96. data/examples/OpenGLIntegration.rb +232 -0
  97. data/examples/RMagickIntegration.rb +449 -0
  98. data/examples/TextInput.cpp +170 -0
  99. data/examples/TextInput.rb +139 -0
  100. data/examples/Tutorial.cpp +215 -0
  101. data/examples/Tutorial.rb +137 -0
  102. data/examples/media/Beep.wav +0 -0
  103. data/examples/media/CptnRuby Gem.png +0 -0
  104. data/examples/media/CptnRuby Map.txt +25 -0
  105. data/examples/media/CptnRuby Tileset.png +0 -0
  106. data/examples/media/CptnRuby.png +0 -0
  107. data/examples/media/Cursor.png +0 -0
  108. data/examples/media/Earth.png +0 -0
  109. data/examples/media/Explosion.wav +0 -0
  110. data/examples/media/LargeStar.png +0 -0
  111. data/examples/media/Sky.jpg +0 -0
  112. data/examples/media/Smoke.png +0 -0
  113. data/examples/media/Soldier.png +0 -0
  114. data/examples/media/Space.png +0 -0
  115. data/examples/media/Star.png +0 -0
  116. data/examples/media/Starfighter.bmp +0 -0
  117. data/linux/Makefile.in +98 -0
  118. data/linux/configure +5658 -0
  119. data/linux/configure.ac +126 -0
  120. data/linux/extconf.rb +11 -0
  121. data/mac/English.lproj/InfoPlist.strings +0 -0
  122. data/mac/Gosu-Info.plist +26 -0
  123. data/mac/Gosu.xcodeproj/project.pbxproj +1194 -0
  124. data/mac/RubyGosu Template-Info.plist +26 -0
  125. data/mac/libboost_thread_1_34_1_universal.a +0 -0
  126. data/mac/libboost_thread_d_1_34_1_universal.a +0 -0
  127. data/mac/libfmod_universal.a +0 -0
  128. data/mac/libpng_universal.a +0 -0
  129. data/mac/libz_universal.a +0 -0
  130. data/reference/Async_8hpp-source.html +70 -0
  131. data/reference/Audio_8hpp-source.html +114 -0
  132. data/reference/Audio_8hpp.html +50 -0
  133. data/reference/AutoLink_8hpp-source.html +38 -0
  134. data/reference/AutoLink_8hpp.html +34 -0
  135. data/reference/Bitmap_8hpp-source.html +85 -0
  136. data/reference/Bitmap_8hpp.html +58 -0
  137. data/reference/ButtonsMac_8hpp-source.html +133 -0
  138. data/reference/ButtonsWin_8hpp-source.html +133 -0
  139. data/reference/ButtonsX_8hpp-source.html +134 -0
  140. data/reference/Color_8hpp-source.html +169 -0
  141. data/reference/Color_8hpp.html +85 -0
  142. data/reference/Directories_8hpp-source.html +42 -0
  143. data/reference/Directories_8hpp.html +46 -0
  144. data/reference/Font_8hpp-source.html +65 -0
  145. data/reference/Font_8hpp.html +41 -0
  146. data/reference/Fwd_8hpp-source.html +52 -0
  147. data/reference/Fwd_8hpp.html +37 -0
  148. data/reference/Gosu_8hpp-source.html +48 -0
  149. data/reference/Gosu_8hpp.html +34 -0
  150. data/reference/GraphicsBase_8hpp-source.html +57 -0
  151. data/reference/GraphicsBase_8hpp.html +56 -0
  152. data/reference/Graphics_8hpp-source.html +96 -0
  153. data/reference/Graphics_8hpp.html +53 -0
  154. data/reference/IO_8hpp-source.html +255 -0
  155. data/reference/IO_8hpp.html +74 -0
  156. data/reference/ImageData_8hpp-source.html +62 -0
  157. data/reference/ImageData_8hpp.html +43 -0
  158. data/reference/Image_8hpp-source.html +126 -0
  159. data/reference/Image_8hpp.html +48 -0
  160. data/reference/Input_8hpp-source.html +118 -0
  161. data/reference/Input_8hpp.html +50 -0
  162. data/reference/Math_8hpp-source.html +92 -0
  163. data/reference/Math_8hpp.html +74 -0
  164. data/reference/Platform_8hpp-source.html +83 -0
  165. data/reference/Platform_8hpp.html +73 -0
  166. data/reference/RotFlip_8hpp-source.html +138 -0
  167. data/reference/RotFlip_8hpp.html +77 -0
  168. data/reference/Sockets_8hpp-source.html +130 -0
  169. data/reference/Sockets_8hpp.html +66 -0
  170. data/reference/TextInput_8hpp-source.html +64 -0
  171. data/reference/TextInput_8hpp.html +41 -0
  172. data/reference/Text_8hpp-source.html +51 -0
  173. data/reference/Text_8hpp.html +46 -0
  174. data/reference/Timing_8hpp-source.html +36 -0
  175. data/reference/Timing_8hpp.html +42 -0
  176. data/reference/Utility_8hpp-source.html +44 -0
  177. data/reference/Utility_8hpp.html +48 -0
  178. data/reference/WinUtility_8hpp-source.html +79 -0
  179. data/reference/WinUtility_8hpp.html +64 -0
  180. data/reference/Window_8hpp-source.html +91 -0
  181. data/reference/Window_8hpp.html +41 -0
  182. data/reference/annotated.html +51 -0
  183. data/reference/classGosu_1_1Audio-members.html +34 -0
  184. data/reference/classGosu_1_1Audio.html +46 -0
  185. data/reference/classGosu_1_1Bitmap-members.html +44 -0
  186. data/reference/classGosu_1_1Bitmap.html +263 -0
  187. data/reference/classGosu_1_1Buffer-members.html +44 -0
  188. data/reference/classGosu_1_1Buffer.html +78 -0
  189. data/reference/classGosu_1_1Buffer.png +0 -0
  190. data/reference/classGosu_1_1Button-members.html +36 -0
  191. data/reference/classGosu_1_1Button.html +143 -0
  192. data/reference/classGosu_1_1Color-members.html +56 -0
  193. data/reference/classGosu_1_1Color.html +387 -0
  194. data/reference/classGosu_1_1File-members.html +41 -0
  195. data/reference/classGosu_1_1File.html +69 -0
  196. data/reference/classGosu_1_1File.png +0 -0
  197. data/reference/classGosu_1_1Font-members.html +39 -0
  198. data/reference/classGosu_1_1Font.html +309 -0
  199. data/reference/classGosu_1_1Graphics-members.html +50 -0
  200. data/reference/classGosu_1_1Graphics.html +234 -0
  201. data/reference/classGosu_1_1Image-members.html +45 -0
  202. data/reference/classGosu_1_1Image.html +518 -0
  203. data/reference/classGosu_1_1ImageData-members.html +37 -0
  204. data/reference/classGosu_1_1ImageData.html +60 -0
  205. data/reference/classGosu_1_1Input-members.html +44 -0
  206. data/reference/classGosu_1_1Input.html +223 -0
  207. data/reference/classGosu_1_1MessageSocket-members.html +40 -0
  208. data/reference/classGosu_1_1MessageSocket.html +233 -0
  209. data/reference/classGosu_1_1Resource-members.html +39 -0
  210. data/reference/classGosu_1_1Resource.html +116 -0
  211. data/reference/classGosu_1_1Resource.png +0 -0
  212. data/reference/classGosu_1_1Sample-members.html +37 -0
  213. data/reference/classGosu_1_1Sample.html +200 -0
  214. data/reference/classGosu_1_1SampleInstance-members.html +38 -0
  215. data/reference/classGosu_1_1SampleInstance.html +169 -0
  216. data/reference/classGosu_1_1Song-members.html +43 -0
  217. data/reference/classGosu_1_1Song.html +260 -0
  218. data/reference/classGosu_1_1TextInput-members.html +38 -0
  219. data/reference/classGosu_1_1TextInput.html +121 -0
  220. data/reference/classGosu_1_1Window-members.html +50 -0
  221. data/reference/classGosu_1_1Window.html +271 -0
  222. data/reference/doxyfile +233 -0
  223. data/reference/doxygen.css +433 -0
  224. data/reference/doxygen.png +0 -0
  225. data/reference/files.html +54 -0
  226. data/reference/functions.html +236 -0
  227. data/reference/functions_enum.html +45 -0
  228. data/reference/functions_func.html +227 -0
  229. data/reference/functions_vars.html +47 -0
  230. data/reference/hierarchy.html +53 -0
  231. data/reference/index.html +26 -0
  232. data/reference/namespaceGosu.html +2890 -0
  233. data/reference/namespaceGosu_1_1Colors.html +70 -0
  234. data/reference/namespaceGosu_1_1Win.html +275 -0
  235. data/reference/namespacemembers.html +216 -0
  236. data/reference/namespacemembers_enum.html +52 -0
  237. data/reference/namespacemembers_eval.html +54 -0
  238. data/reference/namespacemembers_func.html +185 -0
  239. data/reference/namespacemembers_type.html +46 -0
  240. data/reference/namespacemembers_vars.html +46 -0
  241. data/reference/namespaces.html +35 -0
  242. data/reference/tab_b.gif +0 -0
  243. data/reference/tab_l.gif +0 -0
  244. data/reference/tab_r.gif +0 -0
  245. data/reference/tabs.css +102 -0
  246. data/windows/Gosu.sln +29 -0
  247. data/windows/Gosu.vcproj +553 -0
  248. data/windows/RubyGosu.vcproj +138 -0
  249. metadata +305 -0
@@ -0,0 +1,444 @@
1
+ #include <Gosu/Input.hpp>
2
+ #include <Gosu/Platform.hpp>
3
+ #include <Gosu/WinUtility.hpp>
4
+ #include <boost/array.hpp>
5
+ #include <boost/shared_ptr.hpp>
6
+ #include <cwchar>
7
+ #include <iomanip>
8
+ #include <sstream>
9
+ #include <stdexcept>
10
+ #include <vector>
11
+
12
+ #ifndef DIRECTINPUT_VERSION
13
+ #define DIRECTINPUT_VERSION 0x0800
14
+ #endif
15
+ #include <dinput.h>
16
+
17
+ namespace {
18
+ boost::array<bool, Gosu::numButtons> buttons;
19
+ }
20
+
21
+ struct Gosu::Input::Impl
22
+ {
23
+ TextInput* textInput;
24
+ Impl() : textInput(0) {}
25
+
26
+ HWND window;
27
+ boost::shared_ptr<IDirectInput8> input;
28
+
29
+ typedef boost::shared_ptr<IDirectInputDevice8> Device;
30
+ Device keyboard, mouse;
31
+ std::vector<Device> gamepads;
32
+
33
+ double mouseX, mouseY;
34
+ double mouseFactorX, mouseFactorY;
35
+ bool swapMouse;
36
+
37
+ struct EventInfo
38
+ {
39
+ enum { buttonUp, buttonDown } action;
40
+ unsigned id;
41
+ };
42
+ typedef std::vector<EventInfo> Events;
43
+ Events events;
44
+
45
+ static const unsigned inputBufferSize = 32;
46
+ static const int stickRange = 500;
47
+ static const int stickThreshold = 250;
48
+
49
+ // For devices with buffered data.
50
+ void forceButton(unsigned id, bool down, bool collectEvent)
51
+ {
52
+ buttons.at(id) = down;
53
+
54
+ if (!collectEvent)
55
+ return;
56
+
57
+ EventInfo newEvent;
58
+ if (down)
59
+ newEvent.action = EventInfo::buttonDown;
60
+ else
61
+ newEvent.action = EventInfo::buttonUp;
62
+ newEvent.id = id;
63
+ events.push_back(newEvent);
64
+ }
65
+
66
+ // For polled devices, or when there's no data.
67
+ void setButton(unsigned id, bool down, bool collectEvent)
68
+ {
69
+ if (buttons.at(id) != down)
70
+ forceButton(id, down, collectEvent);
71
+ }
72
+
73
+ static void throwError(const char* action, HRESULT hr)
74
+ {
75
+ std::ostringstream stream;
76
+ stream << "While " << action << ", the following DirectInput "
77
+ << "error occured: " << std::hex << std::setw(8) << hr;
78
+ throw std::runtime_error(stream.str());
79
+ // IMPR: Error string!
80
+ }
81
+
82
+ static inline HRESULT check(const char* action, HRESULT hr)
83
+ {
84
+ if (FAILED(hr))
85
+ throwError(action, hr);
86
+
87
+ return hr;
88
+ }
89
+
90
+ // Callback that adjusts all found axes to [-stickRange, +stickRange].
91
+ static BOOL CALLBACK axisCallback(LPCDIDEVICEOBJECTINSTANCE instance,
92
+ LPVOID userData)
93
+ {
94
+ IDirectInputDevice8* dev = static_cast<IDirectInputDevice8*>(userData);
95
+
96
+ DIPROPRANGE range;
97
+ range.diph.dwSize = sizeof(DIPROPRANGE);
98
+ range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
99
+ range.diph.dwHow = DIPH_BYID;
100
+ range.diph.dwObj = instance->dwType;
101
+ range.lMin = -stickRange;
102
+ range.lMax = +stickRange;
103
+ dev->SetProperty(DIPROP_RANGE, &range.diph);
104
+
105
+ return DIENUM_CONTINUE;
106
+ }
107
+
108
+ // Callback that lists all gamepads.
109
+ static BOOL CALLBACK gamepadCallback(LPCDIDEVICEINSTANCE device,
110
+ LPVOID userData)
111
+ {
112
+ Impl* pimpl = static_cast<Impl*>(userData);
113
+
114
+ IDirectInputDevice8* gamepad;
115
+ if (FAILED(pimpl->input->CreateDevice(device->guidInstance,
116
+ &gamepad, 0)))
117
+ {
118
+ return DIENUM_CONTINUE;
119
+ }
120
+
121
+ if (FAILED(gamepad->SetDataFormat(&c_dfDIJoystick)) ||
122
+ FAILED(gamepad->SetCooperativeLevel(pimpl->window,
123
+ DISCL_EXCLUSIVE | DISCL_FOREGROUND)) ||
124
+ FAILED(gamepad->EnumObjects(axisCallback, gamepad, DIDFT_AXIS)))
125
+ {
126
+ gamepad->Release();
127
+ return DIENUM_CONTINUE;
128
+ }
129
+
130
+ pimpl->gamepads.push_back(Win::shareComPtr(gamepad));
131
+
132
+ return DIENUM_CONTINUE;
133
+ }
134
+
135
+ void updateMousePos()
136
+ {
137
+ POINT pos;
138
+ Win::check(::GetCursorPos(&pos));
139
+ Win::check(::ScreenToClient(window, &pos));
140
+
141
+ mouseX = pos.x;
142
+ mouseY = pos.y;
143
+ }
144
+
145
+ void updateButtons(bool collectEvents)
146
+ {
147
+ DIDEVICEOBJECTDATA data[inputBufferSize];
148
+ DWORD inOut;
149
+ HRESULT hr;
150
+
151
+ inOut = inputBufferSize;
152
+ hr = mouse->GetDeviceData(sizeof data[0], data, &inOut, 0);
153
+ switch(hr)
154
+ {
155
+ case DI_OK:
156
+ case DI_BUFFEROVERFLOW:
157
+ {
158
+ // Everything's ok: Update buttons and fire events.
159
+ for (unsigned i = 0; i < inOut; ++i)
160
+ {
161
+ bool down = (data[i].dwData & 0x80) != 0;
162
+
163
+ switch (data[i].dwOfs)
164
+ {
165
+ case DIMOFS_BUTTON0:
166
+ {
167
+ unsigned id = swapMouse ? msRight : msLeft;
168
+ forceButton(id, down, collectEvents);
169
+ break;
170
+ }
171
+ case DIMOFS_BUTTON1:
172
+ {
173
+ unsigned id = swapMouse ? msLeft : msRight;
174
+ forceButton(id, down, collectEvents);
175
+ break;
176
+ }
177
+ case DIMOFS_BUTTON2:
178
+ {
179
+ forceButton(msMiddle, down, collectEvents);
180
+ break;
181
+ }
182
+ case DIMOFS_Z:
183
+ {
184
+ if (!collectEvents || data[i].dwData == 0)
185
+ break;
186
+
187
+ EventInfo event;
188
+ event.action = EventInfo::buttonDown;
189
+ if (int(data[i].dwData) < 0)
190
+ event.id = msWheelDown;
191
+ else
192
+ event.id = msWheelUp;
193
+ events.push_back(event);
194
+ break;
195
+ }
196
+ }
197
+ }
198
+ break;
199
+ }
200
+
201
+ case DIERR_NOTACQUIRED:
202
+ case DIERR_INPUTLOST:
203
+ {
204
+ // Cannot fetch new events: Release all buttons.
205
+ for (unsigned id = msRangeBegin; id < msRangeEnd; ++id)
206
+ setButton(id, false, collectEvents);
207
+ mouse->Acquire();
208
+ break;
209
+ }
210
+ }
211
+
212
+ inOut = inputBufferSize;
213
+ hr = keyboard->GetDeviceData(sizeof data[0], data, &inOut, 0);
214
+ switch (hr)
215
+ {
216
+ case DI_OK:
217
+ case DI_BUFFEROVERFLOW:
218
+ {
219
+ for (unsigned i = 0; i < inOut; ++i)
220
+ forceButton(data[i].dwOfs, (data[i].dwData & 0x80) != 0, collectEvents);
221
+ break;
222
+ }
223
+
224
+ case DIERR_NOTACQUIRED:
225
+ case DIERR_INPUTLOST:
226
+ {
227
+ for (unsigned id = kbRangeBegin; id < kbRangeEnd; ++id)
228
+ setButton(id, false, collectEvents);
229
+ keyboard->Acquire();
230
+ break;
231
+ }
232
+ }
233
+
234
+ boost::array<bool, gpNum> gpBuffer;
235
+ gpBuffer.assign(false);
236
+ for (unsigned gp = 0; gp < gamepads.size(); ++gp)
237
+ {
238
+ gamepads[gp]->Poll();
239
+
240
+ DIJOYSTATE joy;
241
+ hr = gamepads[gp]->GetDeviceState(sizeof joy, &joy);
242
+ switch (hr)
243
+ {
244
+ case DI_OK:
245
+ {
246
+ if (joy.lX < -stickThreshold)
247
+ gpBuffer[gpLeft - gpRangeBegin] = true;
248
+ else if (joy.lX > stickThreshold)
249
+ gpBuffer[gpRight - gpRangeBegin] = true;
250
+
251
+ if (joy.lY < -stickThreshold)
252
+ gpBuffer[gpUp - gpRangeBegin] = true;
253
+ else if (joy.lY > stickThreshold)
254
+ gpBuffer[gpDown - gpRangeBegin] = true;
255
+
256
+ for (unsigned id = gpButton0; id < gpRangeEnd; ++id)
257
+ if (joy.rgbButtons[id - gpButton0])
258
+ gpBuffer[id - gpRangeBegin] = true;
259
+
260
+ break;
261
+ }
262
+
263
+ case DIERR_NOTACQUIRED:
264
+ case DIERR_INPUTLOST:
265
+ {
266
+ gamepads[gp]->Acquire();
267
+
268
+ break;
269
+ }
270
+ }
271
+ }
272
+ for (unsigned id = gpRangeBegin; id < gpRangeEnd; ++id)
273
+ setButton(id, gpBuffer[id - gpRangeBegin], collectEvents);
274
+ }
275
+ };
276
+
277
+ Gosu::Input::Input(HWND window)
278
+ : pimpl(new Impl)
279
+ {
280
+ pimpl->window = window;
281
+ pimpl->mouseFactorX = pimpl->mouseFactorY = 1.0;
282
+
283
+ // Create the main input object (only necessary for setup).
284
+
285
+ IDirectInput8* inputRaw;
286
+ Impl::check("creating the main DirectInput object",
287
+ ::DirectInput8Create(Win::instance(), DIRECTINPUT_VERSION,
288
+ IID_IDirectInput8, reinterpret_cast<void**>(&inputRaw), 0));
289
+ pimpl->input = Win::shareComPtr(inputRaw);
290
+
291
+
292
+ // Prepare property struct for setting the amount of data to buffer.
293
+
294
+ DIPROPDWORD bufferSize;
295
+ bufferSize.diph.dwSize = sizeof(DIPROPDWORD);
296
+ bufferSize.diph.dwHeaderSize = sizeof(DIPROPHEADER);
297
+ bufferSize.diph.dwHow = DIPH_DEVICE;
298
+ bufferSize.diph.dwObj = 0;
299
+ bufferSize.dwData = Impl::inputBufferSize;
300
+
301
+
302
+ // Set up the system keyboard.
303
+
304
+ IDirectInputDevice8* kbRaw;
305
+ Impl::check("creating the keyboard device object",
306
+ pimpl->input->CreateDevice(GUID_SysKeyboard, &kbRaw, 0));
307
+ pimpl->keyboard = Win::shareComPtr(kbRaw);
308
+
309
+ Impl::check("setting the keyboard's data format",
310
+ kbRaw->SetDataFormat(&c_dfDIKeyboard));
311
+ Impl::check("setting the keyboard's cooperative level",
312
+ kbRaw->SetCooperativeLevel(window,
313
+ DISCL_FOREGROUND | DISCL_NONEXCLUSIVE));
314
+ Impl::check("setting the keyboard's buffer size",
315
+ kbRaw->SetProperty(DIPROP_BUFFERSIZE, &bufferSize.diph));
316
+
317
+ kbRaw->Acquire();
318
+
319
+
320
+ // Set up the system mouse.
321
+
322
+ IDirectInputDevice8* mouseRaw;
323
+ Impl::check("creating the mouse device object",
324
+ pimpl->input->CreateDevice(GUID_SysMouse, &mouseRaw, 0));
325
+ pimpl->mouse = Win::shareComPtr(mouseRaw);
326
+
327
+ Impl::check("setting the mouse's data format",
328
+ mouseRaw->SetDataFormat(&c_dfDIMouse));
329
+ Impl::check("setting the mouse's cooperative level",
330
+ mouseRaw->SetCooperativeLevel(window,
331
+ DISCL_FOREGROUND | DISCL_NONEXCLUSIVE));
332
+ Impl::check("setting the mouse's buffer size",
333
+ mouseRaw->SetProperty(DIPROP_BUFFERSIZE, &bufferSize.diph));
334
+
335
+ mouseRaw->Acquire();
336
+
337
+ pimpl->swapMouse = ::GetSystemMetrics(SM_SWAPBUTTON) != 0;
338
+
339
+
340
+ // Set up all gamepads.
341
+
342
+ pimpl->input->EnumDevices(DI8DEVCLASS_GAMECTRL, Impl::gamepadCallback,
343
+ pimpl.get(), DIEDFL_ATTACHEDONLY);
344
+
345
+
346
+ // Get into a usable default state.
347
+
348
+ pimpl->updateMousePos();
349
+ buttons.assign(false);
350
+ }
351
+
352
+ Gosu::Input::~Input()
353
+ {
354
+ }
355
+
356
+ Gosu::Button Gosu::Input::charToId(wchar_t ch)
357
+ {
358
+ SHORT vkey = ::VkKeyScan(/*std::*/towlower(ch));
359
+
360
+ // No key found?
361
+ if (HIBYTE(vkey) == static_cast<unsigned char>(-1) &&
362
+ LOBYTE(vkey) == static_cast<unsigned char>(-1))
363
+ {
364
+ return noButton;
365
+ }
366
+
367
+ // Key needs special modifier keys?
368
+ if (HIBYTE(vkey) != 0)
369
+ return noButton;
370
+
371
+ // Now try to translate the virtual key code into a scan code.
372
+ return Button(::MapVirtualKey(vkey, 0));
373
+ }
374
+
375
+ wchar_t Gosu::Input::idToChar(Gosu::Button btn)
376
+ {
377
+ // Only translate keyboard ids.
378
+ if (btn.getId() > 255)
379
+ return 0;
380
+
381
+ // Special case...?
382
+ if (btn.getId() == kbSpace)
383
+ return L' ';
384
+
385
+ // Try to get the key name.
386
+ // (Three elements so too-long names will make GKNT return 3 and we'll know.)
387
+ wchar_t buf[3];
388
+ if (::GetKeyNameText(btn.getId() << 16, buf, 3) == 1)
389
+ return /*std::*/towlower(buf[0]);
390
+
391
+ return 0;
392
+ }
393
+
394
+ bool Gosu::Input::down(Button btn) const
395
+ {
396
+ return buttons.at(btn.getId());
397
+ }
398
+
399
+ double Gosu::Input::mouseX() const
400
+ {
401
+ return pimpl->mouseX * pimpl->mouseFactorX;
402
+ }
403
+
404
+ double Gosu::Input::mouseY() const
405
+ {
406
+ return pimpl->mouseY * pimpl->mouseFactorY;
407
+ }
408
+
409
+ void Gosu::Input::setMouseFactors(double factorX, double factorY)
410
+ {
411
+ pimpl->mouseFactorX = factorX;
412
+ pimpl->mouseFactorY = factorY;
413
+ }
414
+
415
+ void Gosu::Input::update()
416
+ {
417
+ pimpl->updateMousePos();
418
+ pimpl->updateButtons(true);
419
+ Impl::Events events;
420
+ events.swap(pimpl->events);
421
+ for (unsigned i = 0; i < events.size(); ++i)
422
+ {
423
+ if (events[i].action == Impl::EventInfo::buttonDown)
424
+ {
425
+ if (onButtonDown)
426
+ onButtonDown(Button(events[i].id));
427
+ }
428
+ else
429
+ {
430
+ if (onButtonUp)
431
+ onButtonUp(Button(events[i].id));
432
+ }
433
+ }
434
+ }
435
+
436
+ Gosu::TextInput* Gosu::Input::textInput() const
437
+ {
438
+ return pimpl->textInput;
439
+ }
440
+
441
+ void Gosu::Input::setTextInput(TextInput* textInput)
442
+ {
443
+ pimpl->textInput = textInput;
444
+ }
@@ -0,0 +1,158 @@
1
+ #include <Gosu/Input.hpp>
2
+ #include <Gosu/TextInput.hpp>
3
+ #include <Gosu/Utility.hpp>
4
+ #include <vector>
5
+ #include <map>
6
+
7
+ struct Gosu::Input::Impl
8
+ {
9
+ TextInput* textInput;
10
+ std::vector< ::XEvent> eventList;
11
+ std::map<unsigned int, bool> keyMap;
12
+ double mouseX, mouseY, mouseFactorX, mouseFactorY;
13
+ ::Display* display;
14
+ Impl() : textInput(0) {}
15
+ };
16
+
17
+ Gosu::Input::Input(::Display* dpy)
18
+ : pimpl(new Impl)
19
+ {
20
+ // IMPR: Get current position?
21
+ pimpl->mouseX = pimpl->mouseY = 0;
22
+ pimpl->mouseFactorX = pimpl->mouseFactorY = 1.0;
23
+ pimpl->display = dpy;
24
+ }
25
+
26
+ Gosu::Input::~Input()
27
+ {
28
+ }
29
+
30
+ bool Gosu::Input::feedXEvent(::XEvent& event, Gosu::Window* window)
31
+ {
32
+ if(event.type == VisibilityNotify ||
33
+ event.type == CirculateRequest ||
34
+ event.type == ConfigureRequest ||
35
+ event.type == MapRequest ||
36
+ event.type == ResizeRequest ||
37
+ event.type == ClientMessage)
38
+ return false;
39
+
40
+ pimpl->eventList.push_back(event);
41
+ return true;
42
+ }
43
+
44
+ bool Gosu::Input::down(Gosu::Button btn) const
45
+ {
46
+ // Will default to false for unknown indices (good).
47
+ return pimpl->keyMap[btn.getId()];
48
+ }
49
+
50
+ Gosu::Button Gosu::Input::charToId(wchar_t ch)
51
+ {
52
+ return Gosu::Button(ch);
53
+ }
54
+
55
+ wchar_t Gosu::Input::idToChar(Button btn)
56
+ {
57
+ return btn.getId();
58
+ }
59
+
60
+ double Gosu::Input::mouseX() const
61
+ {
62
+ return pimpl->mouseX * pimpl->mouseFactorX;
63
+ }
64
+
65
+ double Gosu::Input::mouseY() const
66
+ {
67
+ return pimpl->mouseY * pimpl->mouseFactorY;
68
+ }
69
+
70
+ void Gosu::Input::setMouseFactors(double factorX, double factorY)
71
+ {
72
+ pimpl->mouseFactorX = factorX;
73
+ pimpl->mouseFactorY = factorY;
74
+ }
75
+
76
+ void Gosu::Input::update()
77
+ {
78
+ for (unsigned int i = 0; i < pimpl->eventList.size(); i++)
79
+ {
80
+ ::XEvent event = pimpl->eventList[i];
81
+
82
+ if (textInput() && textInput()->feedXEvent(pimpl->display, &event))
83
+ continue;
84
+
85
+ if (event.type == KeyPress)
86
+ {
87
+ // char buf[8];
88
+ // unsigned chars = XLookupString(&event.xkey, buf, sizeof buf, 0, 0);
89
+ // unsigned keysym = XKeycodeToKeysym(pimpl->display, event.xkey.keycode, 0);
90
+ // unsigned id = (chars == 0) ? keysym : widen(buf).at(0);
91
+
92
+ unsigned id = XKeycodeToKeysym(pimpl->display, event.xkey.keycode, 0);
93
+ pimpl->keyMap[id] = true;
94
+ if (onButtonDown)
95
+ onButtonDown(Button(id));
96
+ }
97
+ else if (event.type == KeyRelease)
98
+ {
99
+ // char buf[8];
100
+ // unsigned chars = XLookupString(&event.xkey, buf, sizeof buf, 0, 0);
101
+ // unsigned keysym = XKeycodeToKeysym(pimpl->display, event.xkey.keycode, 0);
102
+ // unsigned id = (chars == 0) ? keysym : widen(buf).at(0);
103
+
104
+ unsigned id = XKeycodeToKeysym(pimpl->display, event.xkey.keycode, 0);
105
+ pimpl->keyMap[id] = false;
106
+ if (onButtonUp)
107
+ onButtonUp(Button(id));
108
+ }
109
+ else if (event.type == ButtonPress)
110
+ {
111
+ unsigned id;
112
+ switch (event.xbutton.button)
113
+ {
114
+ case Button1: id = msLeft; break;
115
+ case Button2: id = msMiddle; break;
116
+ case Button3: id = msRight; break;
117
+ case Button4: id = msWheelUp; break;
118
+ case Button5: id = msWheelDown; break;
119
+ default: continue;
120
+ }
121
+ pimpl->keyMap[id] = true;
122
+ // TODO: Here, above, below, who came up with that cast? Uh :)
123
+ if (onButtonDown)
124
+ onButtonDown(*reinterpret_cast<Button*>(&id));
125
+ }
126
+ else if (event.type == ButtonRelease)
127
+ {
128
+ unsigned id;
129
+ switch (event.xbutton.button)
130
+ {
131
+ case Button1: id = msLeft; break;
132
+ case Button2: id = msMiddle; break;
133
+ case Button3: id = msRight; break;
134
+ default: continue;
135
+ }
136
+ pimpl->keyMap[id] = false;
137
+ if (onButtonUp)
138
+ onButtonUp(*reinterpret_cast<Button*>(&id));
139
+ }
140
+ else if (event.type == MotionNotify)
141
+ {
142
+ pimpl->mouseX = event.xbutton.x;
143
+ pimpl->mouseY = event.xbutton.y;
144
+ }
145
+ }
146
+ pimpl->eventList.clear();
147
+ }
148
+
149
+ Gosu::TextInput* Gosu::Input::textInput() const
150
+ {
151
+ return pimpl->textInput;
152
+ }
153
+
154
+ void Gosu::Input::setTextInput(TextInput* textInput)
155
+ {
156
+ pimpl->textInput = textInput;
157
+ }
158
+