gosu 0.7.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+