gosu 0.15.2 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dependencies/SDL/include/SDL.h +138 -0
- data/dependencies/SDL/include/SDL_assert.h +293 -0
- data/dependencies/SDL/include/SDL_atomic.h +295 -0
- data/dependencies/SDL/include/SDL_audio.h +859 -0
- data/dependencies/SDL/include/SDL_bits.h +121 -0
- data/dependencies/SDL/include/SDL_blendmode.h +123 -0
- data/dependencies/SDL/include/SDL_clipboard.h +71 -0
- data/dependencies/SDL/include/SDL_config.h +55 -0
- data/dependencies/SDL/include/SDL_config_android.h +182 -0
- data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
- data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
- data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
- data/dependencies/SDL/include/SDL_config_os2.h +188 -0
- data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
- data/dependencies/SDL/include/SDL_config_psp.h +165 -0
- data/dependencies/SDL/include/SDL_config_windows.h +288 -0
- data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
- data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
- data/dependencies/SDL/include/SDL_copying.h +20 -0
- data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
- data/dependencies/SDL/include/SDL_egl.h +1676 -0
- data/dependencies/SDL/include/SDL_endian.h +263 -0
- data/dependencies/SDL/include/SDL_error.h +112 -0
- data/dependencies/SDL/include/SDL_events.h +827 -0
- data/dependencies/SDL/include/SDL_filesystem.h +136 -0
- data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
- data/dependencies/SDL/include/SDL_gesture.h +87 -0
- data/dependencies/SDL/include/SDL_haptic.h +1247 -0
- data/dependencies/SDL/include/SDL_hints.h +1578 -0
- data/dependencies/SDL/include/SDL_joystick.h +499 -0
- data/dependencies/SDL/include/SDL_keyboard.h +217 -0
- data/dependencies/SDL/include/SDL_keycode.h +351 -0
- data/dependencies/SDL/include/SDL_loadso.h +81 -0
- data/dependencies/SDL/include/SDL_locale.h +101 -0
- data/dependencies/SDL/include/SDL_log.h +211 -0
- data/dependencies/SDL/include/SDL_main.h +180 -0
- data/dependencies/SDL/include/SDL_messagebox.h +146 -0
- data/dependencies/SDL/include/SDL_metal.h +117 -0
- data/dependencies/SDL/include/SDL_misc.h +75 -0
- data/dependencies/SDL/include/SDL_mouse.h +302 -0
- data/dependencies/SDL/include/SDL_mutex.h +251 -0
- data/dependencies/SDL/include/SDL_name.h +33 -0
- data/dependencies/SDL/include/SDL_opengl.h +2183 -0
- data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
- data/dependencies/SDL/include/SDL_opengles.h +39 -0
- data/dependencies/SDL/include/SDL_opengles2.h +52 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
- data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
- data/dependencies/SDL/include/SDL_pixels.h +479 -0
- data/dependencies/SDL/include/SDL_platform.h +198 -0
- data/dependencies/SDL/include/SDL_power.h +75 -0
- data/dependencies/SDL/include/SDL_quit.h +58 -0
- data/dependencies/SDL/include/SDL_rect.h +174 -0
- data/dependencies/SDL/include/SDL_render.h +1158 -0
- data/dependencies/SDL/include/SDL_revision.h +2 -0
- data/dependencies/SDL/include/SDL_rwops.h +283 -0
- data/dependencies/SDL/include/SDL_scancode.h +413 -0
- data/dependencies/SDL/include/SDL_sensor.h +267 -0
- data/dependencies/SDL/include/SDL_shape.h +144 -0
- data/dependencies/SDL/include/SDL_stdinc.h +647 -0
- data/dependencies/SDL/include/SDL_surface.h +563 -0
- data/dependencies/SDL/include/SDL_system.h +325 -0
- data/dependencies/SDL/include/SDL_syswm.h +354 -0
- data/dependencies/SDL/include/SDL_test.h +69 -0
- data/dependencies/SDL/include/SDL_test_assert.h +105 -0
- data/dependencies/SDL/include/SDL_test_common.h +218 -0
- data/dependencies/SDL/include/SDL_test_compare.h +69 -0
- data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
- data/dependencies/SDL/include/SDL_test_font.h +81 -0
- data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
- data/dependencies/SDL/include/SDL_test_harness.h +134 -0
- data/dependencies/SDL/include/SDL_test_images.h +78 -0
- data/dependencies/SDL/include/SDL_test_log.h +67 -0
- data/dependencies/SDL/include/SDL_test_md5.h +129 -0
- data/dependencies/SDL/include/SDL_test_memory.h +63 -0
- data/dependencies/SDL/include/SDL_test_random.h +115 -0
- data/dependencies/SDL/include/SDL_thread.h +366 -0
- data/dependencies/SDL/include/SDL_timer.h +115 -0
- data/dependencies/SDL/include/SDL_touch.h +102 -0
- data/dependencies/SDL/include/SDL_types.h +29 -0
- data/dependencies/SDL/include/SDL_version.h +162 -0
- data/dependencies/SDL/include/SDL_video.h +1282 -0
- data/dependencies/SDL/include/SDL_vulkan.h +276 -0
- data/dependencies/SDL/include/begin_code.h +166 -0
- data/dependencies/SDL/include/close_code.h +40 -0
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/dependencies/SDL_sound/SDL_sound.c +795 -0
- data/dependencies/SDL_sound/SDL_sound.h +725 -0
- data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
- data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
- data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
- data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
- data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
- data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
- data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
- data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
- data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
- data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
- data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
- data/dependencies/SDL_sound/dr_flac.h +5906 -0
- data/dependencies/SDL_sound/dr_mp3.h +2832 -0
- data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
- data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
- data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
- data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
- data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
- data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
- data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
- data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
- data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
- data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
- data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
- data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
- data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
- data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
- data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
- data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
- data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
- data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
- data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
- data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
- data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
- data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
- data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
- data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
- data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
- data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
- data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
- data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
- data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
- data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
- data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
- data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
- data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
- data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
- data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
- data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
- data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
- data/dependencies/al_soft/AL/al.h +655 -0
- data/dependencies/al_soft/AL/alc.h +270 -0
- data/dependencies/al_soft/AL/alext.h +585 -0
- data/dependencies/al_soft/AL/efx-creative.h +3 -0
- data/dependencies/al_soft/AL/efx-presets.h +402 -0
- data/dependencies/al_soft/AL/efx.h +762 -0
- data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
- data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
- data/{src → dependencies/stb}/stb_image.h +330 -127
- data/{src → dependencies/stb}/stb_image_write.h +156 -85
- data/{src → dependencies/stb}/stb_truetype.h +192 -69
- data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
- data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
- data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
- data/ext/gosu/extconf.rb +56 -22
- data/{Gosu → include/Gosu}/Audio.hpp +6 -8
- data/{Gosu → include/Gosu}/AutoLink.hpp +0 -0
- data/include/Gosu/Bitmap.hpp +100 -0
- data/{Gosu → include/Gosu}/Buttons.hpp +94 -35
- data/{Gosu → include/Gosu}/Channel.h +0 -0
- data/{Gosu → include/Gosu}/Color.h +0 -0
- data/{Gosu → include/Gosu}/Color.hpp +0 -0
- data/{Gosu → include/Gosu}/Directories.hpp +0 -0
- data/{Gosu → include/Gosu}/Font.h +0 -0
- data/{Gosu → include/Gosu}/Font.hpp +0 -0
- data/{Gosu → include/Gosu}/Fwd.hpp +0 -0
- data/{Gosu → include/Gosu}/Gosu.h +3 -0
- data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
- data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
- data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
- data/{Gosu → include/Gosu}/IO.hpp +0 -0
- data/{Gosu → include/Gosu}/Image.h +0 -0
- data/{Gosu → include/Gosu}/Image.hpp +7 -6
- data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
- data/{Gosu → include/Gosu}/Input.hpp +30 -15
- data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
- data/{Gosu → include/Gosu}/Math.hpp +0 -0
- data/{Gosu → include/Gosu}/Platform.hpp +0 -0
- data/{Gosu → include/Gosu}/Sample.h +0 -0
- data/{Gosu → include/Gosu}/Song.h +0 -0
- data/{Gosu → include/Gosu}/Text.hpp +0 -0
- data/{Gosu → include/Gosu}/TextInput.h +0 -0
- data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
- data/{Gosu → include/Gosu}/Timing.hpp +0 -0
- data/{Gosu → include/Gosu}/Utility.hpp +1 -1
- data/{Gosu → include/Gosu}/Version.hpp +0 -0
- data/{Gosu → include/Gosu}/Window.h +2 -0
- data/{Gosu → include/Gosu}/Window.hpp +21 -13
- data/lib/OpenAL32.dll +0 -0
- data/lib/SDL2.dll +0 -0
- data/lib/gosu.rb +0 -3
- data/lib/gosu/patches.rb +0 -9
- data/lib/gosu/swig_patches.rb +3 -2
- data/lib/libmpg123.dll +0 -0
- data/lib/libsndfile.dll +0 -0
- data/lib64/OpenAL32.dll +0 -0
- data/lib64/SDL2.dll +0 -0
- data/lib64/libmpg123.dll +0 -0
- data/lib64/libsndfile.dll +0 -0
- data/rdoc/gosu.rb +95 -20
- data/src/Audio.cpp +50 -224
- data/src/AudioFile.hpp +17 -37
- data/src/AudioFileAudioToolbox.cpp +237 -0
- data/src/AudioFileSDLSound.cpp +147 -0
- data/src/AudioImpl.cpp +3 -12
- data/src/AudioImpl.hpp +3 -1
- data/src/Bitmap.cpp +85 -83
- data/src/BitmapIO.cpp +52 -58
- data/src/Constants.cpp +80 -33
- data/src/Font.cpp +3 -1
- data/src/GosuWrapper.cpp +19 -0
- data/src/Graphics.cpp +7 -4
- data/src/Image.cpp +13 -16
- data/src/Input.cpp +408 -159
- data/src/LargeImageData.cpp +1 -1
- data/src/MarkupParser.cpp +2 -1
- data/src/RubyGosu.cxx +349 -83
- data/src/RubyGosu.h +4 -2
- data/src/TexChunk.cpp +1 -1
- data/src/TextBuilder.cpp +3 -1
- data/src/Texture.cpp +1 -1
- data/src/TrueTypeFont.cpp +1 -1
- data/src/Utility.cpp +11 -7
- data/src/Window.cpp +30 -39
- data/src/WindowWrapper.cpp +28 -0
- metadata +207 -52
- data/Gosu/Bitmap.hpp +0 -113
- data/src/AudioToolboxFile.hpp +0 -210
- data/src/OggFile.hpp +0 -92
- data/src/SndFile.hpp +0 -174
- data/src/WinMain.cpp +0 -64
data/src/Constants.cpp
CHANGED
@@ -47,7 +47,6 @@ unsigned Gosu_IF_TILEABLE_BOTTOM = Gosu::IF_TILEABLE_BOTTOM;
|
|
47
47
|
unsigned Gosu_IF_TILEABLE = Gosu::IF_TILEABLE;
|
48
48
|
unsigned Gosu_IF_RETRO = Gosu::IF_RETRO;
|
49
49
|
|
50
|
-
unsigned Gosu_KB_RANGE_BEGIN = Gosu::KB_RANGE_BEGIN;
|
51
50
|
unsigned Gosu_KB_ESCAPE = Gosu::KB_ESCAPE;
|
52
51
|
unsigned Gosu_KB_F1 = Gosu::KB_F1;
|
53
52
|
unsigned Gosu_KB_F2 = Gosu::KB_F2;
|
@@ -147,9 +146,7 @@ unsigned Gosu_KB_NUMPAD_PLUS = Gosu::KB_NUMPAD_PLUS;
|
|
147
146
|
unsigned Gosu_KB_NUMPAD_MINUS = Gosu::KB_NUMPAD_MINUS;
|
148
147
|
unsigned Gosu_KB_NUMPAD_MULTIPLY = Gosu::KB_NUMPAD_MULTIPLY;
|
149
148
|
unsigned Gosu_KB_NUMPAD_DIVIDE = Gosu::KB_NUMPAD_DIVIDE;
|
150
|
-
unsigned Gosu_KB_RANGE_END = Gosu::KB_RANGE_END;
|
151
149
|
|
152
|
-
unsigned Gosu_MS_RANGE_BEGIN = Gosu::MS_RANGE_BEGIN;
|
153
150
|
unsigned Gosu_MS_LEFT = Gosu::MS_LEFT;
|
154
151
|
unsigned Gosu_MS_MIDDLE = Gosu::MS_MIDDLE;
|
155
152
|
unsigned Gosu_MS_RIGHT = Gosu::MS_RIGHT;
|
@@ -163,13 +160,11 @@ unsigned Gosu_MS_OTHER_4 = Gosu::MS_OTHER_4;
|
|
163
160
|
unsigned Gosu_MS_OTHER_5 = Gosu::MS_OTHER_5;
|
164
161
|
unsigned Gosu_MS_OTHER_6 = Gosu::MS_OTHER_6;
|
165
162
|
unsigned Gosu_MS_OTHER_7 = Gosu::MS_OTHER_7;
|
166
|
-
unsigned Gosu_MS_RANGE_END = Gosu::MS_RANGE_END;
|
167
163
|
|
168
|
-
unsigned
|
169
|
-
unsigned
|
170
|
-
unsigned
|
171
|
-
unsigned
|
172
|
-
unsigned Gosu_GP_DOWN = Gosu::GP_DOWN;
|
164
|
+
unsigned Gosu_GP_DPAD_LEFT = Gosu::GP_DPAD_LEFT;
|
165
|
+
unsigned Gosu_GP_DPAD_RIGHT = Gosu::GP_DPAD_RIGHT;
|
166
|
+
unsigned Gosu_GP_DPAD_UP = Gosu::GP_DPAD_UP;
|
167
|
+
unsigned Gosu_GP_DPAD_DOWN = Gosu::GP_DPAD_DOWN;
|
173
168
|
unsigned Gosu_GP_BUTTON_0 = Gosu::GP_BUTTON_0;
|
174
169
|
unsigned Gosu_GP_BUTTON_1 = Gosu::GP_BUTTON_1;
|
175
170
|
unsigned Gosu_GP_BUTTON_2 = Gosu::GP_BUTTON_2;
|
@@ -187,10 +182,10 @@ unsigned Gosu_GP_BUTTON_13 = Gosu::GP_BUTTON_13;
|
|
187
182
|
unsigned Gosu_GP_BUTTON_14 = Gosu::GP_BUTTON_14;
|
188
183
|
unsigned Gosu_GP_BUTTON_15 = Gosu::GP_BUTTON_15;
|
189
184
|
|
190
|
-
unsigned
|
191
|
-
unsigned
|
192
|
-
unsigned
|
193
|
-
unsigned
|
185
|
+
unsigned Gosu_GP_0_DPAD_LEFT = Gosu::GP_0_DPAD_LEFT;
|
186
|
+
unsigned Gosu_GP_0_DPAD_RIGHT = Gosu::GP_0_DPAD_RIGHT;
|
187
|
+
unsigned Gosu_GP_0_DPAD_UP = Gosu::GP_0_DPAD_UP;
|
188
|
+
unsigned Gosu_GP_0_DPAD_DOWN = Gosu::GP_0_DPAD_DOWN;
|
194
189
|
unsigned Gosu_GP_0_BUTTON_0 = Gosu::GP_0_BUTTON_0;
|
195
190
|
unsigned Gosu_GP_0_BUTTON_1 = Gosu::GP_0_BUTTON_1;
|
196
191
|
unsigned Gosu_GP_0_BUTTON_2 = Gosu::GP_0_BUTTON_2;
|
@@ -208,10 +203,10 @@ unsigned Gosu_GP_0_BUTTON_13 = Gosu::GP_0_BUTTON_13;
|
|
208
203
|
unsigned Gosu_GP_0_BUTTON_14 = Gosu::GP_0_BUTTON_14;
|
209
204
|
unsigned Gosu_GP_0_BUTTON_15 = Gosu::GP_0_BUTTON_15;
|
210
205
|
|
211
|
-
unsigned
|
212
|
-
unsigned
|
213
|
-
unsigned
|
214
|
-
unsigned
|
206
|
+
unsigned Gosu_GP_1_DPAD_LEFT = Gosu::GP_1_DPAD_LEFT;
|
207
|
+
unsigned Gosu_GP_1_DPAD_RIGHT = Gosu::GP_1_DPAD_RIGHT;
|
208
|
+
unsigned Gosu_GP_1_DPAD_UP = Gosu::GP_1_DPAD_UP;
|
209
|
+
unsigned Gosu_GP_1_DPAD_DOWN = Gosu::GP_1_DPAD_DOWN;
|
215
210
|
unsigned Gosu_GP_1_BUTTON_0 = Gosu::GP_1_BUTTON_0;
|
216
211
|
unsigned Gosu_GP_1_BUTTON_1 = Gosu::GP_1_BUTTON_1;
|
217
212
|
unsigned Gosu_GP_1_BUTTON_2 = Gosu::GP_1_BUTTON_2;
|
@@ -229,10 +224,10 @@ unsigned Gosu_GP_1_BUTTON_13 = Gosu::GP_1_BUTTON_13;
|
|
229
224
|
unsigned Gosu_GP_1_BUTTON_14 = Gosu::GP_1_BUTTON_14;
|
230
225
|
unsigned Gosu_GP_1_BUTTON_15 = Gosu::GP_1_BUTTON_15;
|
231
226
|
|
232
|
-
unsigned
|
233
|
-
unsigned
|
234
|
-
unsigned
|
235
|
-
unsigned
|
227
|
+
unsigned Gosu_GP_2_DPAD_LEFT = Gosu::GP_2_DPAD_LEFT;
|
228
|
+
unsigned Gosu_GP_2_DPAD_RIGHT = Gosu::GP_2_DPAD_RIGHT;
|
229
|
+
unsigned Gosu_GP_2_DPAD_UP = Gosu::GP_2_DPAD_UP;
|
230
|
+
unsigned Gosu_GP_2_DPAD_DOWN = Gosu::GP_2_DPAD_DOWN;
|
236
231
|
unsigned Gosu_GP_2_BUTTON_0 = Gosu::GP_2_BUTTON_0;
|
237
232
|
unsigned Gosu_GP_2_BUTTON_1 = Gosu::GP_2_BUTTON_1;
|
238
233
|
unsigned Gosu_GP_2_BUTTON_2 = Gosu::GP_2_BUTTON_2;
|
@@ -250,10 +245,10 @@ unsigned Gosu_GP_2_BUTTON_13 = Gosu::GP_2_BUTTON_13;
|
|
250
245
|
unsigned Gosu_GP_2_BUTTON_14 = Gosu::GP_2_BUTTON_14;
|
251
246
|
unsigned Gosu_GP_2_BUTTON_15 = Gosu::GP_2_BUTTON_15;
|
252
247
|
|
253
|
-
unsigned
|
254
|
-
unsigned
|
255
|
-
unsigned
|
256
|
-
unsigned
|
248
|
+
unsigned Gosu_GP_3_DPAD_LEFT = Gosu::GP_3_DPAD_LEFT;
|
249
|
+
unsigned Gosu_GP_3_DPAD_RIGHT = Gosu::GP_3_DPAD_RIGHT;
|
250
|
+
unsigned Gosu_GP_3_DPAD_UP = Gosu::GP_3_DPAD_UP;
|
251
|
+
unsigned Gosu_GP_3_DPAD_DOWN = Gosu::GP_3_DPAD_DOWN;
|
257
252
|
unsigned Gosu_GP_3_BUTTON_0 = Gosu::GP_3_BUTTON_0;
|
258
253
|
unsigned Gosu_GP_3_BUTTON_1 = Gosu::GP_3_BUTTON_1;
|
259
254
|
unsigned Gosu_GP_3_BUTTON_2 = Gosu::GP_3_BUTTON_2;
|
@@ -271,17 +266,69 @@ unsigned Gosu_GP_3_BUTTON_13 = Gosu::GP_3_BUTTON_13;
|
|
271
266
|
unsigned Gosu_GP_3_BUTTON_14 = Gosu::GP_3_BUTTON_14;
|
272
267
|
unsigned Gosu_GP_3_BUTTON_15 = Gosu::GP_3_BUTTON_15;
|
273
268
|
|
274
|
-
unsigned
|
269
|
+
unsigned Gosu_GP_LEFT = Gosu::GP_LEFT;
|
270
|
+
unsigned Gosu_GP_RIGHT = Gosu::GP_RIGHT;
|
271
|
+
unsigned Gosu_GP_UP = Gosu::GP_UP;
|
272
|
+
unsigned Gosu_GP_DOWN = Gosu::GP_DOWN;
|
273
|
+
|
274
|
+
unsigned Gosu_GP_0_LEFT = Gosu::GP_0_LEFT;
|
275
|
+
unsigned Gosu_GP_0_RIGHT = Gosu::GP_0_RIGHT;
|
276
|
+
unsigned Gosu_GP_0_UP = Gosu::GP_0_UP;
|
277
|
+
unsigned Gosu_GP_0_DOWN = Gosu::GP_0_DOWN;
|
278
|
+
|
279
|
+
unsigned Gosu_GP_1_LEFT = Gosu::GP_1_LEFT;
|
280
|
+
unsigned Gosu_GP_1_RIGHT = Gosu::GP_1_RIGHT;
|
281
|
+
unsigned Gosu_GP_1_UP = Gosu::GP_1_UP;
|
282
|
+
unsigned Gosu_GP_1_DOWN = Gosu::GP_1_DOWN;
|
283
|
+
|
284
|
+
unsigned Gosu_GP_2_LEFT = Gosu::GP_2_LEFT;
|
285
|
+
unsigned Gosu_GP_2_RIGHT = Gosu::GP_2_RIGHT;
|
286
|
+
unsigned Gosu_GP_2_UP = Gosu::GP_2_UP;
|
287
|
+
unsigned Gosu_GP_2_DOWN = Gosu::GP_2_DOWN;
|
288
|
+
|
289
|
+
unsigned Gosu_GP_3_LEFT = Gosu::GP_3_LEFT;
|
290
|
+
unsigned Gosu_GP_3_RIGHT = Gosu::GP_3_RIGHT;
|
291
|
+
unsigned Gosu_GP_3_UP = Gosu::GP_3_UP;
|
292
|
+
unsigned Gosu_GP_3_DOWN = Gosu::GP_3_DOWN;
|
293
|
+
|
294
|
+
unsigned Gosu_GP_LEFT_STICK_X_AXIS = Gosu::GP_LEFT_STICK_Y_AXIS;
|
295
|
+
unsigned Gosu_GP_LEFT_STICK_Y_AXIS = Gosu::GP_LEFT_STICK_Y_AXIS;
|
296
|
+
unsigned Gosu_GP_RIGHT_STICK_X_AXIS = Gosu::GP_RIGHT_STICK_X_AXIS;
|
297
|
+
unsigned Gosu_GP_RIGHT_STICK_Y_AXIS = Gosu::GP_RIGHT_STICK_Y_AXIS;
|
298
|
+
unsigned Gosu_GP_LEFT_TRIGGER_AXIS = Gosu::GP_LEFT_TRIGGER_AXIS;
|
299
|
+
unsigned Gosu_GP_RIGHT_TRIGGER_AXIS = Gosu::GP_RIGHT_TRIGGER_AXIS;
|
300
|
+
|
301
|
+
unsigned Gosu_GP_0_LEFT_STICK_X_AXIS = Gosu::GP_0_LEFT_STICK_Y_AXIS;
|
302
|
+
unsigned Gosu_GP_0_LEFT_STICK_Y_AXIS = Gosu::GP_0_LEFT_STICK_Y_AXIS;
|
303
|
+
unsigned Gosu_GP_0_RIGHT_STICK_X_AXIS = Gosu::GP_0_RIGHT_STICK_X_AXIS;
|
304
|
+
unsigned Gosu_GP_0_RIGHT_STICK_Y_AXIS = Gosu::GP_0_RIGHT_STICK_Y_AXIS;
|
305
|
+
unsigned Gosu_GP_0_LEFT_TRIGGER_AXIS = Gosu::GP_0_LEFT_TRIGGER_AXIS;
|
306
|
+
unsigned Gosu_GP_0_RIGHT_TRIGGER_AXIS = Gosu::GP_0_RIGHT_TRIGGER_AXIS;
|
307
|
+
|
308
|
+
unsigned Gosu_GP_1_LEFT_STICK_X_AXIS = Gosu::GP_1_LEFT_STICK_Y_AXIS;
|
309
|
+
unsigned Gosu_GP_1_LEFT_STICK_Y_AXIS = Gosu::GP_1_LEFT_STICK_Y_AXIS;
|
310
|
+
unsigned Gosu_GP_1_RIGHT_STICK_X_AXIS = Gosu::GP_1_RIGHT_STICK_X_AXIS;
|
311
|
+
unsigned Gosu_GP_1_RIGHT_STICK_Y_AXIS = Gosu::GP_1_RIGHT_STICK_Y_AXIS;
|
312
|
+
unsigned Gosu_GP_1_LEFT_TRIGGER_AXIS = Gosu::GP_1_LEFT_TRIGGER_AXIS;
|
313
|
+
unsigned Gosu_GP_1_RIGHT_TRIGGER_AXIS = Gosu::GP_1_RIGHT_TRIGGER_AXIS;
|
314
|
+
|
315
|
+
unsigned Gosu_GP_2_LEFT_STICK_X_AXIS = Gosu::GP_2_LEFT_STICK_Y_AXIS;
|
316
|
+
unsigned Gosu_GP_2_LEFT_STICK_Y_AXIS = Gosu::GP_2_LEFT_STICK_Y_AXIS;
|
317
|
+
unsigned Gosu_GP_2_RIGHT_STICK_X_AXIS = Gosu::GP_2_RIGHT_STICK_X_AXIS;
|
318
|
+
unsigned Gosu_GP_2_RIGHT_STICK_Y_AXIS = Gosu::GP_2_RIGHT_STICK_Y_AXIS;
|
319
|
+
unsigned Gosu_GP_2_LEFT_TRIGGER_AXIS = Gosu::GP_2_LEFT_TRIGGER_AXIS;
|
320
|
+
unsigned Gosu_GP_2_RIGHT_TRIGGER_AXIS = Gosu::GP_2_RIGHT_TRIGGER_AXIS;
|
321
|
+
|
322
|
+
unsigned Gosu_GP_3_LEFT_STICK_X_AXIS = Gosu::GP_3_LEFT_STICK_Y_AXIS;
|
323
|
+
unsigned Gosu_GP_3_LEFT_STICK_Y_AXIS = Gosu::GP_3_LEFT_STICK_Y_AXIS;
|
324
|
+
unsigned Gosu_GP_3_RIGHT_STICK_X_AXIS = Gosu::GP_3_RIGHT_STICK_X_AXIS;
|
325
|
+
unsigned Gosu_GP_3_RIGHT_STICK_Y_AXIS = Gosu::GP_3_RIGHT_STICK_Y_AXIS;
|
326
|
+
unsigned Gosu_GP_3_LEFT_TRIGGER_AXIS = Gosu::GP_3_LEFT_TRIGGER_AXIS;
|
327
|
+
unsigned Gosu_GP_3_RIGHT_TRIGGER_AXIS = Gosu::GP_3_RIGHT_TRIGGER_AXIS;
|
275
328
|
|
276
|
-
unsigned Gosu_NUM_BUTTONS = Gosu::NUM_BUTTONS;
|
277
329
|
unsigned Gosu_NUM_GAMEPADS = Gosu::NUM_GAMEPADS;
|
278
330
|
unsigned Gosu_NO_BUTTON = Gosu::NO_BUTTON;
|
279
331
|
|
280
|
-
unsigned Gosu_KB_NUM = Gosu::KB_NUM;
|
281
|
-
unsigned Gosu_MS_NUM = Gosu::MS_NUM;
|
282
|
-
unsigned Gosu_GP_NUM = Gosu::GP_NUM;
|
283
|
-
unsigned Gosu_GP_NUM_PER_GAMEPAD = Gosu::GP_NUM_PER_GAMEPAD;
|
284
|
-
|
285
332
|
#ifdef __cplusplus
|
286
333
|
}
|
287
|
-
#endif
|
334
|
+
#endif
|
data/src/Font.cpp
CHANGED
data/src/GosuWrapper.cpp
CHANGED
@@ -203,6 +203,25 @@ unsigned Gosu_button_char_to_id(const char *btn)
|
|
203
203
|
return Gosu::Input::char_to_id(btn).id();
|
204
204
|
}
|
205
205
|
|
206
|
+
const char *Gosu_button_name(int btn)
|
207
|
+
{
|
208
|
+
static thread_local std::string name;
|
209
|
+
name = Gosu::Input::button_name((Gosu::ButtonName)btn);
|
210
|
+
return name.empty() ? nullptr : name.c_str();
|
211
|
+
}
|
212
|
+
|
213
|
+
const char *Gosu_gamepad_name(int id)
|
214
|
+
{
|
215
|
+
static thread_local std::string name;
|
216
|
+
name = Gosu::Input::gamepad_name(id);
|
217
|
+
return name.empty() ? nullptr : name.c_str();
|
218
|
+
}
|
219
|
+
|
220
|
+
double Gosu_axis(int btn)
|
221
|
+
{
|
222
|
+
return Gosu::Input::axis((Gosu::ButtonName)btn);
|
223
|
+
}
|
224
|
+
|
206
225
|
int Gosu_fps()
|
207
226
|
{
|
208
227
|
return Gosu::fps();
|
data/src/Graphics.cpp
CHANGED
@@ -287,7 +287,9 @@ Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()
|
|
287
287
|
|
288
288
|
// This is the actual render-to-texture step.
|
289
289
|
Image result = OffScreenTarget(width, height, image_flags).render([&] {
|
290
|
+
#ifndef GOSU_IS_OPENGLES
|
290
291
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
292
|
+
#endif
|
291
293
|
glClearColor(0, 0, 0, 0);
|
292
294
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
293
295
|
glEnable(GL_BLEND);
|
@@ -296,7 +298,9 @@ Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()
|
|
296
298
|
queues.back().perform_draw_ops_and_code();
|
297
299
|
queues.pop_back();
|
298
300
|
glFlush();
|
301
|
+
#ifndef GOSU_IS_OPENGLES
|
299
302
|
glPopAttrib();
|
303
|
+
#endif
|
300
304
|
});
|
301
305
|
|
302
306
|
// Restore previous matrix and glViewport.
|
@@ -434,7 +438,7 @@ unique_ptr<Gosu::ImageData> Gosu::Graphics::create_image(const Bitmap& src,
|
|
434
438
|
}
|
435
439
|
else {
|
436
440
|
Bitmap bmp(src_width, src_height);
|
437
|
-
bmp.insert(
|
441
|
+
bmp.insert(0, 0, src, src_x, src_y, src_width, src_height);
|
438
442
|
data = texture->try_alloc(bmp, 0);
|
439
443
|
}
|
440
444
|
|
@@ -445,14 +449,13 @@ unique_ptr<Gosu::ImageData> Gosu::Graphics::create_image(const Bitmap& src,
|
|
445
449
|
// Too large to fit on a single texture.
|
446
450
|
if (src_width > max_size - 2 || src_height > max_size - 2) {
|
447
451
|
Bitmap bmp(src_width, src_height);
|
448
|
-
bmp.insert(
|
452
|
+
bmp.insert(0, 0, src, src_x, src_y, src_width, src_height);
|
449
453
|
unique_ptr<ImageData> lidi;
|
450
454
|
lidi.reset(new LargeImageData(bmp, max_size - 2, max_size - 2, flags));
|
451
455
|
return lidi;
|
452
456
|
}
|
453
457
|
|
454
|
-
Bitmap bmp;
|
455
|
-
apply_border_flags(bmp, src, src_x, src_y, src_width, src_height, flags);
|
458
|
+
Bitmap bmp = apply_border_flags(flags, src, src_x, src_y, src_width, src_height);
|
456
459
|
|
457
460
|
// Try to put the bitmap into one of the already allocated textures.
|
458
461
|
for (const auto& texture : textures) {
|
data/src/Image.cpp
CHANGED
@@ -13,32 +13,30 @@ Gosu::Image::Image()
|
|
13
13
|
{
|
14
14
|
}
|
15
15
|
|
16
|
-
Gosu::Image::Image(const string& filename, unsigned
|
16
|
+
Gosu::Image::Image(const string& filename, unsigned image_flags)
|
17
17
|
{
|
18
18
|
// Forward.
|
19
|
-
Bitmap
|
20
|
-
|
21
|
-
Image(bmp, flags).data_.swap(data_);
|
19
|
+
Bitmap bitmap = load_image_file(filename);
|
20
|
+
Image{bitmap, image_flags}.data_.swap(data_);
|
22
21
|
}
|
23
22
|
|
24
|
-
Gosu::Image::Image(const string& filename,
|
25
|
-
unsigned
|
23
|
+
Gosu::Image::Image(const string& filename, int src_x, int src_y, int src_width, int src_height,
|
24
|
+
unsigned image_flags)
|
26
25
|
{
|
27
26
|
// Forward.
|
28
|
-
Bitmap
|
29
|
-
|
30
|
-
Image(bmp, src_x, src_y, src_width, src_height, flags).data_.swap(data_);
|
27
|
+
Bitmap bitmap = load_image_file(filename);
|
28
|
+
Image{bitmap, src_x, src_y, src_width, src_height, image_flags}.data_.swap(data_);
|
31
29
|
}
|
32
30
|
|
33
|
-
Gosu::Image::Image(const Bitmap& source, unsigned
|
31
|
+
Gosu::Image::Image(const Bitmap& source, unsigned image_flags)
|
34
32
|
{
|
35
33
|
// Forward.
|
36
|
-
Image
|
34
|
+
Image{source, 0, 0, source.width(), source.height(), image_flags}.data_.swap(data_);
|
37
35
|
}
|
38
36
|
|
39
|
-
Gosu::Image::Image(const Bitmap& source,
|
40
|
-
unsigned
|
41
|
-
: data_(Graphics::create_image(source, src_x, src_y, src_width, src_height,
|
37
|
+
Gosu::Image::Image(const Bitmap& source, int src_x, int src_y, int src_width, int src_height,
|
38
|
+
unsigned image_flags)
|
39
|
+
: data_(Graphics::create_image(source, src_x, src_y, src_width, src_height, image_flags))
|
42
40
|
{
|
43
41
|
}
|
44
42
|
|
@@ -141,7 +139,6 @@ vector<Gosu::Image> Gosu::load_tiles(const Bitmap& bmp, int tile_width, int tile
|
|
141
139
|
vector<Gosu::Image> Gosu::load_tiles(const string& filename, int tile_width, int tile_height,
|
142
140
|
unsigned flags)
|
143
141
|
{
|
144
|
-
Bitmap bmp;
|
145
|
-
load_image_file(bmp, filename);
|
142
|
+
Bitmap bmp = load_image_file(filename);
|
146
143
|
return load_tiles(bmp, tile_width, tile_height, flags);
|
147
144
|
}
|
data/src/Input.cpp
CHANGED
@@ -6,89 +6,80 @@
|
|
6
6
|
#include <Gosu/Utility.hpp>
|
7
7
|
|
8
8
|
#include <SDL.h>
|
9
|
-
#include
|
9
|
+
#include <utf8proc.h>
|
10
10
|
|
11
11
|
#include <cwctype>
|
12
12
|
#include <cstdlib>
|
13
13
|
#include <algorithm>
|
14
14
|
#include <array>
|
15
|
+
#include <mutex>
|
15
16
|
using namespace std;
|
16
17
|
|
17
|
-
// Workaround for broken SDL_GetGlobalMouseState, see below.
|
18
|
-
#ifdef GOSU_IS_MAC
|
19
|
-
#import <CoreGraphics/CoreGraphics.h>
|
20
|
-
#import <AppKit/AppKit.h>
|
21
|
-
#endif
|
22
|
-
|
23
18
|
static void require_sdl_video()
|
24
19
|
{
|
25
|
-
static
|
26
|
-
|
20
|
+
static std::once_flag initialized;
|
21
|
+
|
22
|
+
std::call_once(initialized, [] {
|
27
23
|
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
28
|
-
|
29
|
-
atexit([] { SDL_QuitSubSystem(SDL_INIT_VIDEO); });
|
30
|
-
}
|
24
|
+
});
|
31
25
|
}
|
32
26
|
|
33
|
-
static
|
27
|
+
static const unsigned NUM_BUTTONS_PER_GAMEPAD =
|
28
|
+
(Gosu::GP_RANGE_END - Gosu::GP_RANGE_BEGIN + 1 - 4) / (Gosu::NUM_GAMEPADS + 1) - 3;
|
29
|
+
static const unsigned NUM_AXES_PER_GAMEPAD =
|
30
|
+
(Gosu::GP_AXES_RANGE_END - Gosu::GP_AXES_RANGE_BEGIN + 1) / (Gosu::NUM_GAMEPADS + 1);
|
31
|
+
static const unsigned NUM_BUTTONS = Gosu::GP_RANGE_END + 1;
|
32
|
+
|
33
|
+
static array<bool, NUM_BUTTONS> button_states = {false};
|
34
|
+
static array<double, NUM_AXES_PER_GAMEPAD * (Gosu::NUM_GAMEPADS + 1)> axis_states = {0.0};
|
35
|
+
static vector<shared_ptr<SDL_Joystick>> open_joysticks;
|
36
|
+
static vector<shared_ptr<SDL_GameController>> open_game_controllers;
|
37
|
+
// Stores joystick instance id or -1 if empty
|
38
|
+
static array<int, Gosu::NUM_GAMEPADS> gamepad_slots = {-1, -1, -1, -1};
|
34
39
|
|
35
40
|
struct Gosu::Input::Impl
|
36
41
|
{
|
42
|
+
struct InputEvent
|
43
|
+
{
|
44
|
+
enum {
|
45
|
+
ButtonUp,
|
46
|
+
ButtonDown,
|
47
|
+
GamepadConnected,
|
48
|
+
GamepadDisconnected
|
49
|
+
} type;
|
50
|
+
int id = -1;
|
51
|
+
int gamepad_instance_id = -1;
|
52
|
+
};
|
53
|
+
|
37
54
|
Input& input;
|
38
55
|
SDL_Window* window;
|
39
|
-
|
56
|
+
|
40
57
|
TextInput* text_input = nullptr;
|
41
58
|
double mouse_x, mouse_y;
|
42
59
|
double mouse_scale_x = 1;
|
43
60
|
double mouse_scale_y = 1;
|
44
61
|
double mouse_offset_x = 0;
|
45
62
|
double mouse_offset_y = 0;
|
46
|
-
|
63
|
+
|
47
64
|
Impl(Input& input, SDL_Window* window)
|
48
65
|
: input(input), window(window)
|
49
66
|
{
|
50
67
|
require_sdl_video();
|
51
|
-
|
68
|
+
|
52
69
|
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
53
|
-
|
54
|
-
int num_gamepads = min<int>(Gosu::NUM_GAMEPADS, SDL_NumJoysticks());
|
55
|
-
|
56
|
-
for (int i = 0; i < num_gamepads; ++i) {
|
57
|
-
// Prefer the SDL_GameController API...
|
58
|
-
if (SDL_IsGameController(i)) {
|
59
|
-
if (SDL_GameController* game_controller = SDL_GameControllerOpen(i)) {
|
60
|
-
game_controllers.push_back(game_controller);
|
61
|
-
continue;
|
62
|
-
}
|
63
|
-
}
|
64
|
-
// ...but fall back on the good, old SDL_Joystick API.
|
65
|
-
if (SDL_Joystick* joystick = SDL_JoystickOpen(i)) {
|
66
|
-
joysticks.push_back(joystick);
|
67
|
-
}
|
68
|
-
}
|
69
70
|
}
|
70
|
-
|
71
|
+
|
71
72
|
~Impl()
|
72
73
|
{
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
game_controllers.clear();
|
77
|
-
|
74
|
+
open_joysticks.clear();
|
75
|
+
open_game_controllers.clear();
|
76
|
+
|
78
77
|
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
79
78
|
}
|
80
|
-
|
79
|
+
|
81
80
|
void update_mouse_position()
|
82
81
|
{
|
83
|
-
#if
|
84
|
-
// Avoid SDL_GetGlobalMouseState on macOS until this bug is fixed:
|
85
|
-
// https://bugzilla.libsdl.org/show_bug.cgi?id=4255
|
86
|
-
int window_x, window_y;
|
87
|
-
SDL_GetWindowPosition(window, &window_x, &window_y);
|
88
|
-
auto mouse_position = NSEvent.mouseLocation;
|
89
|
-
mouse_x = mouse_position.x - window_x;
|
90
|
-
mouse_y = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - mouse_position.y) - window_y;
|
91
|
-
#elif SDL_VERSION_ATLEAST(2, 0, 5)
|
82
|
+
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
92
83
|
// SDL_GetGlobalMouseState was added in SDL 2.0.4, but it only started using the same
|
93
84
|
// coordinate system as SDL_GetWindowPosition on X11 in 2.0.5.
|
94
85
|
int x, y, window_x, window_y;
|
@@ -103,7 +94,7 @@ struct Gosu::Input::Impl
|
|
103
94
|
mouse_y = y;
|
104
95
|
#endif
|
105
96
|
}
|
106
|
-
|
97
|
+
|
107
98
|
void set_mouse_position(double x, double y)
|
108
99
|
{
|
109
100
|
SDL_WarpMouseInWindow(window,
|
@@ -120,13 +111,13 @@ struct Gosu::Input::Impl
|
|
120
111
|
mouse_x = x, mouse_y = y;
|
121
112
|
#endif
|
122
113
|
}
|
123
|
-
|
114
|
+
|
124
115
|
bool feed_sdl_event(const SDL_Event* e)
|
125
116
|
{
|
126
117
|
switch (e->type) {
|
127
118
|
case SDL_KEYDOWN:
|
128
119
|
case SDL_KEYUP: {
|
129
|
-
if (e->key.repeat == 0 && e->key.keysym.scancode <= KB_RANGE_END) {
|
120
|
+
if (e->key.repeat == 0 && e->key.keysym.scancode <= static_cast<int>(KB_RANGE_END)) {
|
130
121
|
enqueue_event(e->key.keysym.scancode, e->type == SDL_KEYDOWN);
|
131
122
|
return true;
|
132
123
|
}
|
@@ -153,160 +144,377 @@ struct Gosu::Input::Impl
|
|
153
144
|
}
|
154
145
|
break;
|
155
146
|
}
|
147
|
+
case SDL_JOYDEVICEADDED: {
|
148
|
+
if (available_gamepad_slot_index() == -1) {
|
149
|
+
break;
|
150
|
+
}
|
151
|
+
int gamepad_slot = -1;
|
152
|
+
int joystick_instance_id = -1;
|
153
|
+
|
154
|
+
// Loop through attached gamepads as e->jdevice.which cannot be trusted (always 0)
|
155
|
+
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
156
|
+
// Prefer the SDL_GameController API...
|
157
|
+
if (SDL_IsGameController(i)) {
|
158
|
+
if (SDL_GameController *game_controller = SDL_GameControllerOpen(i)) {
|
159
|
+
gamepad_slot = available_gamepad_slot_index();
|
160
|
+
joystick_instance_id = SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(game_controller));
|
161
|
+
if (gamepad_instance_id_is_known(joystick_instance_id)) {
|
162
|
+
continue;
|
163
|
+
}
|
164
|
+
open_game_controllers.emplace_back(
|
165
|
+
shared_ptr<SDL_GameController>(game_controller, SDL_GameControllerClose)
|
166
|
+
);
|
167
|
+
}
|
168
|
+
}
|
169
|
+
// ...but fall back on the good, old SDL_Joystick API.
|
170
|
+
else if (SDL_Joystick *joystick = SDL_JoystickOpen(i)) {
|
171
|
+
gamepad_slot = available_gamepad_slot_index();
|
172
|
+
joystick_instance_id = SDL_JoystickInstanceID(joystick);
|
173
|
+
if (gamepad_instance_id_is_known(joystick_instance_id)) {
|
174
|
+
continue;
|
175
|
+
}
|
176
|
+
open_joysticks.emplace_back(
|
177
|
+
shared_ptr<SDL_Joystick>(joystick, SDL_JoystickClose)
|
178
|
+
);
|
179
|
+
}
|
180
|
+
|
181
|
+
// Reserve gamepad slot and issue gamepad connection event
|
182
|
+
if (gamepad_slot >= 0 && joystick_instance_id >= 0) {
|
183
|
+
gamepad_slots[gamepad_slot] = joystick_instance_id;
|
184
|
+
enqueue_gamepad_connection_event(gamepad_slot, true, -1);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
break;
|
188
|
+
}
|
189
|
+
case SDL_JOYDEVICEREMOVED: {
|
190
|
+
int gamepad_slot = gamepad_slot_index(e->jdevice.which);
|
191
|
+
if (gamepad_slot >= 0) {
|
192
|
+
enqueue_gamepad_connection_event(gamepad_slot, false, e->jdevice.which);
|
193
|
+
}
|
194
|
+
break;
|
195
|
+
}
|
156
196
|
}
|
157
197
|
return false;
|
158
198
|
}
|
159
|
-
|
160
|
-
|
161
|
-
|
199
|
+
|
200
|
+
double scale_axis(double value)
|
201
|
+
{
|
202
|
+
return value >= 0 ? value / SDL_JOYSTICK_AXIS_MAX : -value / SDL_JOYSTICK_AXIS_MIN;
|
203
|
+
}
|
204
|
+
|
205
|
+
// returns the gamepad slot index (0..NUM_GAMEPADS - 1) for the joystick instance id or -1 if not found
|
206
|
+
int gamepad_slot_index(int joystick_instance_id) const
|
207
|
+
{
|
208
|
+
for (int i = 0; i < gamepad_slots.size(); i++) {
|
209
|
+
if (gamepad_slots[i] == joystick_instance_id) {
|
210
|
+
return i;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
return -1;
|
215
|
+
}
|
216
|
+
|
217
|
+
// returns first available gamepad slot or -1 if non are available
|
218
|
+
int available_gamepad_slot_index() const
|
219
|
+
{
|
220
|
+
for (int i = 0; i < gamepad_slots.size(); i++) {
|
221
|
+
if (gamepad_slots[i] == -1) {
|
222
|
+
return i;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
return -1;
|
227
|
+
}
|
228
|
+
|
229
|
+
// returns whether the gamepad using the joystick instance id is known
|
230
|
+
bool gamepad_instance_id_is_known(int id)
|
231
|
+
{
|
232
|
+
for (int j = 0; j < gamepad_slots.size(); j++) {
|
233
|
+
if (gamepad_slots[j] == id) {
|
234
|
+
return true;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
return false;
|
239
|
+
}
|
240
|
+
|
241
|
+
// frees the gamepad slot associated with this joystick instance id
|
242
|
+
// and frees the SDL_GameController/SDL_Joystick
|
243
|
+
void free_gamepad_slot(int instance_id)
|
244
|
+
{
|
245
|
+
int index = gamepad_slot_index(instance_id);
|
246
|
+
|
247
|
+
for (int i = 0; i < open_game_controllers.size(); i++) {
|
248
|
+
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(open_game_controllers[i].get());
|
249
|
+
if (SDL_JoystickInstanceID(joystick) == instance_id) {
|
250
|
+
open_game_controllers.erase(open_game_controllers.begin() + i);
|
251
|
+
gamepad_slots[index] = -1;
|
252
|
+
return;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
for (int i = 0; i < open_joysticks.size(); i++) {
|
257
|
+
if (SDL_JoystickInstanceID(open_joysticks[i].get()) == instance_id) {
|
258
|
+
open_joysticks.erase(open_joysticks.begin() + i);
|
259
|
+
gamepad_slots[index] = -1;
|
260
|
+
return;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
struct GamepadBuffer
|
266
|
+
{
|
267
|
+
array<bool, NUM_BUTTONS_PER_GAMEPAD> buttons = { false };
|
268
|
+
array<bool, 4> directions = { false };
|
269
|
+
array<double, NUM_AXES_PER_GAMEPAD> axes = { 0.0 };
|
270
|
+
};
|
271
|
+
|
162
272
|
void poll_gamepads()
|
163
273
|
{
|
164
|
-
// This gamepad is an OR-ed version of all the other gamepads.
|
165
|
-
//
|
166
|
-
//
|
167
|
-
GamepadBuffer any_gamepad
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
274
|
+
// This gamepad is an OR-ed version of all the other gamepads.
|
275
|
+
// If button3 is pressed on any attached gamepad, down(GP_BUTTON_3) will return true.
|
276
|
+
// This is handy for singleplayer games where you don't care which gamepad that player uses.
|
277
|
+
GamepadBuffer any_gamepad;
|
278
|
+
|
279
|
+
// Reset all axes values, they will be recalculated below.
|
280
|
+
axis_states.fill(0.0);
|
281
|
+
|
282
|
+
for (int i = 0; i < gamepad_slots.size(); ++i) {
|
283
|
+
if (gamepad_slots[i] == -1) {
|
284
|
+
continue;
|
285
|
+
}
|
286
|
+
|
174
287
|
// Poll data from SDL, using either of two API interfaces.
|
175
|
-
|
176
|
-
|
177
|
-
poll_game_controller(game_controller
|
288
|
+
GamepadBuffer current_gamepad;
|
289
|
+
if (SDL_GameController* game_controller = SDL_GameControllerFromInstanceID(gamepad_slots[i])) {
|
290
|
+
current_gamepad = poll_game_controller(game_controller);
|
178
291
|
}
|
179
292
|
else {
|
180
|
-
|
181
|
-
|
293
|
+
current_gamepad = poll_joystick(SDL_JoystickFromInstanceID(gamepad_slots[i]));
|
294
|
+
}
|
295
|
+
|
296
|
+
int axis_offset = NUM_AXES_PER_GAMEPAD * (i + 1);
|
297
|
+
for (int a = 0; a < NUM_AXES_PER_GAMEPAD; ++a) {
|
298
|
+
// Transfer the axes values into the global axis_state array..
|
299
|
+
axis_states[a + axis_offset] = current_gamepad.axes[a];
|
300
|
+
// Also transfer the gamepad-specific axes values into the "any gamepad" slots.
|
301
|
+
// (Values with a higher amplitude override smaller ones.)
|
302
|
+
if (abs(current_gamepad.axes[a]) > abs(axis_states[a])) {
|
303
|
+
axis_states[a] = current_gamepad.axes[a];
|
304
|
+
}
|
182
305
|
}
|
183
|
-
|
306
|
+
|
184
307
|
// Now at the same time, enqueue all events for this particular
|
185
308
|
// gamepad, and OR the keyboard state into any_gamepad.
|
186
|
-
int offset = GP_RANGE_BEGIN +
|
187
|
-
for (int j = 0; j < current_gamepad.size(); ++j) {
|
188
|
-
any_gamepad[j] = any_gamepad[j] || current_gamepad[j];
|
189
|
-
|
190
|
-
if (current_gamepad[j] && !button_states[j + offset]) {
|
309
|
+
int offset = GP_RANGE_BEGIN + NUM_BUTTONS_PER_GAMEPAD * (i + 1);
|
310
|
+
for (int j = 0; j < current_gamepad.buttons.size(); ++j) {
|
311
|
+
any_gamepad.buttons[j] = any_gamepad.buttons[j] || current_gamepad.buttons[j];
|
312
|
+
|
313
|
+
if (current_gamepad.buttons[j] && !button_states[j + offset]) {
|
191
314
|
button_states[j + offset] = true;
|
192
315
|
enqueue_event(j + offset, true);
|
193
316
|
}
|
194
|
-
else if (!current_gamepad[j] && button_states[j + offset]) {
|
317
|
+
else if (!current_gamepad.buttons[j] && button_states[j + offset]) {
|
195
318
|
button_states[j + offset] = false;
|
196
319
|
enqueue_event(j + offset, false);
|
197
320
|
}
|
198
321
|
}
|
322
|
+
int direction_offset = GP_LEFT + 4 * (i + 1);
|
323
|
+
for (int d = 0; d < 4; ++d) {
|
324
|
+
any_gamepad.directions[d] = any_gamepad.directions[d] || current_gamepad.directions[d];
|
325
|
+
|
326
|
+
if (current_gamepad.directions[d] && !button_states[d + direction_offset]) {
|
327
|
+
button_states[d + direction_offset] = true;
|
328
|
+
enqueue_event(d + direction_offset, true);
|
329
|
+
}
|
330
|
+
else if (!current_gamepad.directions[d] && button_states[d + direction_offset]) {
|
331
|
+
button_states[d + direction_offset] = false;
|
332
|
+
enqueue_event(d + direction_offset, false);
|
333
|
+
}
|
334
|
+
}
|
199
335
|
}
|
200
|
-
|
336
|
+
|
201
337
|
// And lastly, enqueue events for the virtual "any" gamepad.
|
202
|
-
for (int j = 0; j < any_gamepad.size(); ++j) {
|
203
|
-
if (any_gamepad[j] && !button_states[j + GP_RANGE_BEGIN]) {
|
338
|
+
for (int j = 0; j < any_gamepad.buttons.size(); ++j) {
|
339
|
+
if (any_gamepad.buttons[j] && !button_states[j + GP_RANGE_BEGIN]) {
|
204
340
|
button_states[j + GP_RANGE_BEGIN] = true;
|
205
341
|
enqueue_event(j + GP_RANGE_BEGIN, true);
|
206
342
|
}
|
207
|
-
else if (!any_gamepad[j] && button_states[j + GP_RANGE_BEGIN]) {
|
343
|
+
else if (!any_gamepad.buttons[j] && button_states[j + GP_RANGE_BEGIN]) {
|
208
344
|
button_states[j + GP_RANGE_BEGIN] = false;
|
209
345
|
enqueue_event(j + GP_RANGE_BEGIN, false);
|
210
346
|
}
|
211
347
|
}
|
348
|
+
for (int d = 0; d < 4; ++d) {
|
349
|
+
if (any_gamepad.directions[d] && !button_states[d + GP_LEFT]) {
|
350
|
+
button_states[d + GP_LEFT] = true;
|
351
|
+
enqueue_event(d + GP_LEFT, true);
|
352
|
+
}
|
353
|
+
else if (!any_gamepad.directions[d] && button_states[d + GP_LEFT]) {
|
354
|
+
button_states[d + GP_LEFT] = false;
|
355
|
+
enqueue_event(d + GP_LEFT, false);
|
356
|
+
}
|
357
|
+
}
|
212
358
|
}
|
213
|
-
|
359
|
+
|
214
360
|
void dispatch_enqueued_events()
|
215
361
|
{
|
216
|
-
for (
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
362
|
+
for (const InputEvent& event : event_queue) {
|
363
|
+
switch (event.type) {
|
364
|
+
case InputEvent::ButtonDown:
|
365
|
+
button_states[event.id] = true;
|
366
|
+
if (input.on_button_down) {
|
367
|
+
input.on_button_down(Button(event.id));
|
368
|
+
}
|
369
|
+
break;
|
370
|
+
case InputEvent::ButtonUp:
|
371
|
+
button_states[event.id] = false;
|
372
|
+
if (input.on_button_up) {
|
373
|
+
input.on_button_up(Button(event.id));
|
374
|
+
}
|
375
|
+
break;
|
376
|
+
case InputEvent::GamepadConnected:
|
377
|
+
if (input.on_gamepad_connected) {
|
378
|
+
input.on_gamepad_connected(event.id);
|
379
|
+
}
|
380
|
+
break;
|
381
|
+
case InputEvent::GamepadDisconnected:
|
382
|
+
if (input.on_gamepad_disconnected) {
|
383
|
+
input.on_gamepad_disconnected(event.id);
|
384
|
+
}
|
385
|
+
free_gamepad_slot(event.gamepad_instance_id);
|
386
|
+
break;
|
226
387
|
}
|
227
388
|
}
|
228
389
|
event_queue.clear();
|
229
390
|
}
|
230
|
-
|
391
|
+
|
231
392
|
private:
|
232
393
|
// For button down event: Button name value (>= 0)
|
233
394
|
// For button up event: ~Button name value (< 0)
|
234
|
-
vector<
|
395
|
+
vector<InputEvent> event_queue;
|
235
396
|
|
236
|
-
void enqueue_event(
|
397
|
+
void enqueue_event(unsigned id, bool down)
|
237
398
|
{
|
238
|
-
|
399
|
+
InputEvent event;
|
400
|
+
event.type = down ? InputEvent::ButtonDown : InputEvent::ButtonUp;
|
401
|
+
event.id = id;
|
402
|
+
event_queue.push_back(event);
|
239
403
|
}
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
404
|
+
|
405
|
+
void enqueue_gamepad_connection_event(int gamepad_index_id, bool connected, int instance_id)
|
406
|
+
{
|
407
|
+
InputEvent event;
|
408
|
+
event.type = connected ? InputEvent::GamepadConnected : InputEvent::GamepadDisconnected;
|
409
|
+
event.id = gamepad_index_id;
|
410
|
+
event.gamepad_instance_id = instance_id;
|
411
|
+
event_queue.push_back(event);
|
412
|
+
}
|
413
|
+
|
414
|
+
GamepadBuffer poll_game_controller(SDL_GameController* controller)
|
249
415
|
{
|
250
|
-
gamepad
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
gamepad[
|
256
|
-
|
257
|
-
|
258
|
-
SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX)
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
SDL_GameControllerGetAxis(controller,
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
416
|
+
GamepadBuffer gamepad;
|
417
|
+
|
418
|
+
// Poll axes first.
|
419
|
+
gamepad.axes[GP_LEFT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] =
|
420
|
+
scale_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX));
|
421
|
+
gamepad.axes[GP_LEFT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] =
|
422
|
+
scale_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY));
|
423
|
+
gamepad.axes[GP_RIGHT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] =
|
424
|
+
scale_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX));
|
425
|
+
gamepad.axes[GP_RIGHT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] =
|
426
|
+
scale_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY));
|
427
|
+
gamepad.axes[GP_LEFT_TRIGGER_AXIS - GP_AXES_RANGE_BEGIN] =
|
428
|
+
scale_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT));
|
429
|
+
gamepad.axes[GP_RIGHT_TRIGGER_AXIS - GP_AXES_RANGE_BEGIN] =
|
430
|
+
scale_axis(SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT));
|
431
|
+
|
432
|
+
gamepad.buttons[GP_DPAD_LEFT - GP_RANGE_BEGIN] =
|
433
|
+
SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
434
|
+
gamepad.buttons[GP_DPAD_RIGHT - GP_RANGE_BEGIN] =
|
435
|
+
SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
436
|
+
gamepad.buttons[GP_DPAD_UP - GP_RANGE_BEGIN] =
|
437
|
+
SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP);
|
438
|
+
gamepad.buttons[GP_DPAD_DOWN - GP_RANGE_BEGIN] =
|
439
|
+
SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
440
|
+
|
270
441
|
int button = 0;
|
271
442
|
for (; button < SDL_CONTROLLER_BUTTON_DPAD_UP; ++button) {
|
272
|
-
gamepad[GP_BUTTON_0 + button - GP_RANGE_BEGIN] =
|
443
|
+
gamepad.buttons[GP_BUTTON_0 + button - GP_RANGE_BEGIN] =
|
273
444
|
SDL_GameControllerGetButton(controller, (SDL_GameControllerButton) button);
|
274
445
|
}
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
446
|
+
// Represent the triggers as buttons in addition to them being axes.
|
447
|
+
gamepad.buttons[GP_BUTTON_0 + button++ - GP_RANGE_BEGIN] =
|
448
|
+
gamepad.axes[GP_LEFT_TRIGGER_AXIS] >= 0.5;
|
449
|
+
gamepad.buttons[GP_BUTTON_0 + button++ - GP_RANGE_BEGIN] =
|
450
|
+
gamepad.axes[GP_RIGHT_TRIGGER_AXIS] >= 0.5;
|
451
|
+
|
452
|
+
merge_directions(gamepad);
|
453
|
+
return gamepad;
|
279
454
|
}
|
280
|
-
|
281
|
-
|
455
|
+
|
456
|
+
GamepadBuffer poll_joystick(SDL_Joystick* joystick)
|
282
457
|
{
|
458
|
+
GamepadBuffer gamepad;
|
459
|
+
|
460
|
+
// Just guess that the first four axes are equivalent to two analog sticks.
|
283
461
|
int axes = SDL_JoystickNumAxes(joystick);
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
gamepad[(axis % 2 ? GP_DOWN : GP_RIGHT) - GP_RANGE_BEGIN] = true;
|
292
|
-
}
|
462
|
+
if (axes > 0) {
|
463
|
+
gamepad.axes[GP_LEFT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] =
|
464
|
+
scale_axis(SDL_JoystickGetAxis(joystick, 0));
|
465
|
+
}
|
466
|
+
if (axes > 1) {
|
467
|
+
gamepad.axes[GP_LEFT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] =
|
468
|
+
scale_axis(SDL_JoystickGetAxis(joystick, 1));
|
293
469
|
}
|
294
|
-
|
470
|
+
if (axes > 2) {
|
471
|
+
gamepad.axes[GP_RIGHT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] =
|
472
|
+
scale_axis(SDL_JoystickGetAxis(joystick, 2));
|
473
|
+
}
|
474
|
+
if (axes > 3) {
|
475
|
+
gamepad.axes[GP_RIGHT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] =
|
476
|
+
scale_axis(SDL_JoystickGetAxis(joystick, 3));
|
477
|
+
}
|
478
|
+
|
479
|
+
// All hats are merged into the DPad.
|
295
480
|
int hats = SDL_JoystickNumHats(joystick);
|
296
481
|
for (int hat = 0; hat < hats; ++hat) {
|
297
482
|
Uint8 value = SDL_JoystickGetHat(joystick, hat);
|
298
|
-
if (value & SDL_HAT_LEFT) gamepad[
|
299
|
-
if (value & SDL_HAT_RIGHT) gamepad[
|
300
|
-
if (value & SDL_HAT_UP) gamepad[
|
301
|
-
if (value & SDL_HAT_DOWN) gamepad[
|
483
|
+
if (value & SDL_HAT_LEFT) gamepad.buttons[GP_DPAD_LEFT - GP_RANGE_BEGIN] = true;
|
484
|
+
if (value & SDL_HAT_RIGHT) gamepad.buttons[GP_DPAD_RIGHT - GP_RANGE_BEGIN] = true;
|
485
|
+
if (value & SDL_HAT_UP) gamepad.buttons[GP_DPAD_UP - GP_RANGE_BEGIN] = true;
|
486
|
+
if (value & SDL_HAT_DOWN) gamepad.buttons[GP_DPAD_DOWN - GP_RANGE_BEGIN] = true;
|
302
487
|
}
|
303
|
-
|
304
|
-
int buttons = min<int>(
|
488
|
+
|
489
|
+
int buttons = min<int>(NUM_BUTTONS_PER_GAMEPAD - 4, SDL_JoystickNumButtons(joystick));
|
305
490
|
for (int button = 0; button < buttons; ++button) {
|
306
491
|
if (SDL_JoystickGetButton(joystick, button)) {
|
307
|
-
gamepad[GP_BUTTON_0 + button - GP_RANGE_BEGIN] = true;
|
492
|
+
gamepad.buttons[GP_BUTTON_0 + button - GP_RANGE_BEGIN] = true;
|
308
493
|
}
|
309
494
|
}
|
495
|
+
|
496
|
+
merge_directions(gamepad);
|
497
|
+
return gamepad;
|
498
|
+
}
|
499
|
+
|
500
|
+
void merge_directions(GamepadBuffer& gamepad)
|
501
|
+
{
|
502
|
+
gamepad.directions[0] =
|
503
|
+
gamepad.buttons[GP_DPAD_LEFT - GP_RANGE_BEGIN] ||
|
504
|
+
gamepad.axes[GP_LEFT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] <= -0.5 ||
|
505
|
+
gamepad.axes[GP_RIGHT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] <= -0.5;
|
506
|
+
gamepad.directions[1] =
|
507
|
+
gamepad.buttons[GP_DPAD_RIGHT - GP_RANGE_BEGIN] ||
|
508
|
+
gamepad.axes[GP_LEFT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] >= +0.5 ||
|
509
|
+
gamepad.axes[GP_RIGHT_STICK_X_AXIS - GP_AXES_RANGE_BEGIN] >= +0.5;
|
510
|
+
gamepad.directions[2] =
|
511
|
+
gamepad.buttons[GP_DPAD_UP - GP_RANGE_BEGIN] ||
|
512
|
+
gamepad.axes[GP_LEFT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] <= -0.5 ||
|
513
|
+
gamepad.axes[GP_RIGHT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] <= -0.5;
|
514
|
+
gamepad.directions[3] =
|
515
|
+
gamepad.buttons[GP_DPAD_DOWN - GP_RANGE_BEGIN] ||
|
516
|
+
gamepad.axes[GP_LEFT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] >= +0.5 ||
|
517
|
+
gamepad.axes[GP_RIGHT_STICK_Y_AXIS - GP_AXES_RANGE_BEGIN] >= +0.5;
|
310
518
|
}
|
311
519
|
};
|
312
520
|
|
@@ -328,23 +536,23 @@ bool Gosu::Input::feed_sdl_event(void* event)
|
|
328
536
|
string Gosu::Input::id_to_char(Button btn)
|
329
537
|
{
|
330
538
|
require_sdl_video();
|
331
|
-
|
539
|
+
|
332
540
|
if (btn.id() > KB_RANGE_END) return "";
|
333
|
-
|
541
|
+
|
334
542
|
// SDL_GetKeyName returns "Space" for this value, but we want the character value.
|
335
543
|
if (btn.id() == KB_SPACE) return " ";
|
336
|
-
|
544
|
+
|
337
545
|
SDL_Keycode keycode = SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(btn.id()));
|
338
546
|
if (keycode == SDLK_UNKNOWN) return "";
|
339
|
-
|
547
|
+
|
340
548
|
const char* name = SDL_GetKeyName(keycode);
|
341
549
|
if (name == nullptr) return "";
|
342
|
-
|
550
|
+
|
343
551
|
u32string codepoints = utf8_to_composed_utc4(name);
|
344
|
-
|
552
|
+
|
345
553
|
// Filter out names that are more than one logical character.
|
346
554
|
if (codepoints.length() != 1) return "";
|
347
|
-
|
555
|
+
|
348
556
|
// Always return lower case to be consistent with previous versions of Gosu.
|
349
557
|
codepoints[0] = utf8proc_tolower(codepoints[0]);
|
350
558
|
// Convert back to UTF-8.
|
@@ -356,18 +564,59 @@ string Gosu::Input::id_to_char(Button btn)
|
|
356
564
|
Gosu::Button Gosu::Input::char_to_id(string ch)
|
357
565
|
{
|
358
566
|
require_sdl_video();
|
359
|
-
|
567
|
+
|
360
568
|
SDL_Keycode keycode = SDL_GetKeyFromName(ch.c_str());
|
361
569
|
return keycode == SDLK_UNKNOWN ? NO_BUTTON : Button(SDL_GetScancodeFromKey(keycode));
|
362
570
|
}
|
363
571
|
|
572
|
+
std::string Gosu::Input::button_name(Button btn)
|
573
|
+
{
|
574
|
+
require_sdl_video();
|
575
|
+
|
576
|
+
SDL_Keycode keycode = SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(btn.id()));
|
577
|
+
return SDL_GetKeyName(keycode);
|
578
|
+
}
|
579
|
+
|
580
|
+
std::string Gosu::Input::gamepad_name(int index)
|
581
|
+
{
|
582
|
+
if (index < 0 || index > gamepad_slots.size() - 1) {
|
583
|
+
return "";
|
584
|
+
}
|
585
|
+
|
586
|
+
int instance_id = gamepad_slots[index];
|
587
|
+
|
588
|
+
if (instance_id == -1) {
|
589
|
+
return "";
|
590
|
+
}
|
591
|
+
|
592
|
+
if (SDL_GameController* game_controller = SDL_GameControllerFromInstanceID(instance_id)) {
|
593
|
+
return SDL_GameControllerName(game_controller);
|
594
|
+
}
|
595
|
+
else if (SDL_Joystick* joystick = SDL_JoystickFromInstanceID(instance_id)) {
|
596
|
+
return SDL_JoystickName(joystick);
|
597
|
+
}
|
598
|
+
|
599
|
+
return "";
|
600
|
+
}
|
601
|
+
|
364
602
|
bool Gosu::Input::down(Gosu::Button btn)
|
365
603
|
{
|
366
604
|
if (btn == NO_BUTTON || btn.id() >= NUM_BUTTONS) return false;
|
367
|
-
|
605
|
+
|
368
606
|
return button_states[btn.id()];
|
369
607
|
}
|
370
608
|
|
609
|
+
double Gosu::Input::axis(Gosu::Button btn)
|
610
|
+
{
|
611
|
+
unsigned axis_id = btn.id() - GP_LEFT_STICK_X_AXIS;
|
612
|
+
|
613
|
+
if (axis_id >= axis_states.size()) {
|
614
|
+
throw std::out_of_range("Invalid axis ID: " + std::to_string(btn.id()));
|
615
|
+
}
|
616
|
+
|
617
|
+
return axis_states[axis_id];
|
618
|
+
}
|
619
|
+
|
371
620
|
double Gosu::Input::mouse_x() const
|
372
621
|
{
|
373
622
|
return pimpl->mouse_x * pimpl->mouse_scale_x + pimpl->mouse_offset_x;
|
@@ -395,7 +644,7 @@ void Gosu::Input::set_mouse_factors(double scale_x, double scale_y,
|
|
395
644
|
const Gosu::Touches& Gosu::Input::current_touches() const
|
396
645
|
{
|
397
646
|
// We could use the SDL 2 touch API to implement this.
|
398
|
-
|
647
|
+
|
399
648
|
static Gosu::Touches none;
|
400
649
|
return none;
|
401
650
|
}
|
@@ -435,7 +684,7 @@ void Gosu::Input::set_text_input(TextInput* text_input)
|
|
435
684
|
else if (pimpl->text_input == nullptr && text_input) {
|
436
685
|
SDL_StartTextInput();
|
437
686
|
}
|
438
|
-
|
687
|
+
|
439
688
|
pimpl->text_input = text_input;
|
440
689
|
}
|
441
690
|
|