gosu 0.12.1 → 0.13.0
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.
- checksums.yaml +4 -4
- data/Gosu/Audio.hpp +23 -25
- data/Gosu/Graphics.hpp +16 -12
- data/Gosu/Image.hpp +3 -0
- data/Gosu/Version.hpp +2 -2
- data/lib/gosu.rb +2 -2
- data/lib/gosu/compat.rb +1 -1
- data/lib/gosu/patches.rb +5 -0
- data/lib/gosu/swig_patches.rb +1 -1
- data/rdoc/gosu.rb +10 -10
- data/src/Audio.cpp +93 -228
- data/src/AudioImpl.cpp +94 -0
- data/src/AudioImpl.hpp +33 -0
- data/src/AudioToolboxFile.hpp +14 -18
- data/src/Bitmap.cpp +36 -30
- data/src/BitmapIO.cpp +14 -23
- data/src/BlockAllocator.cpp +7 -10
- data/src/BlockAllocator.hpp +2 -4
- data/src/Channel.cpp +89 -0
- data/src/Color.cpp +4 -9
- data/src/DirectoriesApple.cpp +13 -13
- data/src/DirectoriesUnix.cpp +8 -7
- data/src/DirectoriesWin.cpp +12 -11
- data/src/EmptyImageData.hpp +54 -0
- data/src/FileUnix.cpp +12 -9
- data/src/FileWin.cpp +8 -7
- data/src/Font.cpp +12 -13
- data/src/FormattedString.cpp +237 -0
- data/src/FormattedString.hpp +14 -265
- data/src/GosuViewController.cpp +2 -5
- data/src/Graphics.cpp +38 -39
- data/src/IO.cpp +11 -10
- data/src/Image.cpp +16 -9
- data/src/Input.cpp +16 -15
- data/src/InputUIKit.cpp +8 -7
- data/src/Macro.cpp +11 -11
- data/src/Math.cpp +9 -8
- data/src/RubyGosu.cxx +129 -99
- data/src/TextApple.cpp +19 -13
- data/src/TextInput.cpp +23 -22
- data/src/TextWin.cpp +17 -19
- data/src/Texture.cpp +15 -10
- data/src/Transform.cpp +13 -17
- data/src/Utility.cpp +3 -2
- data/src/UtilityApple.cpp +10 -11
- data/src/UtilityWin.cpp +2 -1
- data/src/Version.cpp +5 -4
- data/src/WinMain.cpp +3 -3
- data/src/WinUtility.cpp +7 -6
- data/src/Window.cpp +11 -10
- data/src/WindowUIKit.cpp +9 -8
- data/src/stb_image.h +782 -480
- data/src/stb_image_write.h +425 -15
- data/src/stb_vorbis.c +82 -32
- metadata +8 -4
- data/src/ALChannelManagement.hpp +0 -119
data/src/GosuViewController.cpp
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#import "GosuGLView.h"
|
5
5
|
#import "GosuViewController.h"
|
6
6
|
#import "GraphicsImpl.hpp"
|
7
|
+
#import "AudioImpl.hpp"
|
7
8
|
#import <Gosu/Gosu.hpp>
|
8
9
|
|
9
10
|
#import <AudioToolbox/AudioSession.h>
|
@@ -15,19 +16,15 @@ namespace Gosu
|
|
15
16
|
{
|
16
17
|
void register_frame();
|
17
18
|
}
|
18
|
-
|
19
|
-
ALCcontext* shared_openal_context();
|
20
19
|
}
|
21
20
|
|
22
|
-
// TODO: This has been written on iOS 3.x.
|
23
|
-
// Is this still the best way to handle interruptions?
|
24
21
|
static void handle_audio_interruption(void* unused, UInt32 inInterruptionState)
|
25
22
|
{
|
26
23
|
if (inInterruptionState == kAudioSessionBeginInterruption) {
|
27
24
|
alcMakeContextCurrent(nullptr);
|
28
25
|
}
|
29
26
|
else if (inInterruptionState == kAudioSessionEndInterruption) {
|
30
|
-
alcMakeContextCurrent(Gosu::
|
27
|
+
alcMakeContextCurrent(Gosu::al_context());
|
31
28
|
}
|
32
29
|
}
|
33
30
|
|
data/src/Graphics.cpp
CHANGED
@@ -13,6 +13,7 @@
|
|
13
13
|
#include <algorithm>
|
14
14
|
#include <functional>
|
15
15
|
#include <memory>
|
16
|
+
using namespace std;
|
16
17
|
|
17
18
|
namespace Gosu
|
18
19
|
{
|
@@ -23,20 +24,20 @@ namespace Gosu
|
|
23
24
|
Graphics& current_graphics()
|
24
25
|
{
|
25
26
|
if (current_graphics_pointer == nullptr) {
|
26
|
-
throw
|
27
|
+
throw logic_error("Gosu::Graphics can only be drawn to while rendering");
|
27
28
|
}
|
28
29
|
|
29
30
|
return *current_graphics_pointer;
|
30
31
|
}
|
31
32
|
|
32
|
-
|
33
|
+
vector<shared_ptr<Texture>> textures;
|
33
34
|
|
34
35
|
DrawOpQueueStack queues;
|
35
36
|
|
36
37
|
DrawOpQueue& current_queue()
|
37
38
|
{
|
38
39
|
if (queues.empty()) {
|
39
|
-
throw
|
40
|
+
throw logic_error("There is no rendering queue for this operation");
|
40
41
|
}
|
41
42
|
return queues.back();
|
42
43
|
}
|
@@ -56,7 +57,7 @@ struct Gosu::Graphics::Impl
|
|
56
57
|
{
|
57
58
|
double scale_x = 1.0 * phys_width / virt_width;
|
58
59
|
double scale_y = 1.0 * phys_height / virt_height;
|
59
|
-
double scale_factor =
|
60
|
+
double scale_factor = min(scale_x, scale_y);
|
60
61
|
|
61
62
|
Transform scale_transform = scale(scale_factor);
|
62
63
|
Transform translate_transform = translate(black_width, black_height);
|
@@ -130,7 +131,7 @@ void Gosu::Graphics::set_resolution(unsigned virtual_width, unsigned virtual_hei
|
|
130
131
|
double horizontal_black_bar_width, double vertical_black_bar_height)
|
131
132
|
{
|
132
133
|
if (virtual_width == 0 || virtual_height == 0) {
|
133
|
-
throw
|
134
|
+
throw invalid_argument("Invalid virtual resolution.");
|
134
135
|
}
|
135
136
|
|
136
137
|
pimpl->virt_width = virtual_width;
|
@@ -141,10 +142,10 @@ void Gosu::Graphics::set_resolution(unsigned virtual_width, unsigned virtual_hei
|
|
141
142
|
pimpl->update_base_transform();
|
142
143
|
}
|
143
144
|
|
144
|
-
void Gosu::Graphics::frame(const
|
145
|
+
void Gosu::Graphics::frame(const function<void ()>& f)
|
145
146
|
{
|
146
147
|
if (current_graphics_pointer != nullptr) {
|
147
|
-
throw
|
148
|
+
throw logic_error("Cannot nest calls to Gosu::Graphics::begin()");
|
148
149
|
}
|
149
150
|
|
150
151
|
// Cancel all recording or whatever that might still be in progress...
|
@@ -152,7 +153,7 @@ void Gosu::Graphics::frame(const std::function<void ()>& f)
|
|
152
153
|
|
153
154
|
if (pimpl->warmed_up_queues.size() == 1) {
|
154
155
|
// If we already have a "warmed up" queue, use that instead.
|
155
|
-
// -> All
|
156
|
+
// -> All internal std::vectors will already have a lot of capacity.
|
156
157
|
// This helps reduce allocations during normal operation.
|
157
158
|
queues.clear();
|
158
159
|
queues.swap(pimpl->warmed_up_queues);
|
@@ -222,14 +223,14 @@ void Gosu::Graphics::flush()
|
|
222
223
|
current_queue().clear_queue();
|
223
224
|
}
|
224
225
|
|
225
|
-
void Gosu::Graphics::gl(const
|
226
|
+
void Gosu::Graphics::gl(const function<void ()>& f)
|
226
227
|
{
|
227
228
|
if (current_queue().recording()) {
|
228
|
-
throw
|
229
|
+
throw logic_error("Custom OpenGL is not allowed while creating a macro");
|
229
230
|
}
|
230
231
|
|
231
232
|
#ifdef GOSU_IS_OPENGLES
|
232
|
-
throw
|
233
|
+
throw logic_error("Custom OpenGL ES is not supported yet");
|
233
234
|
#else
|
234
235
|
Graphics& cg = current_graphics();
|
235
236
|
|
@@ -243,10 +244,10 @@ void Gosu::Graphics::gl(const std::function<void ()>& f)
|
|
243
244
|
#endif
|
244
245
|
}
|
245
246
|
|
246
|
-
void Gosu::Graphics::gl(Gosu::ZPos z, const
|
247
|
+
void Gosu::Graphics::gl(Gosu::ZPos z, const function<void ()>& f)
|
247
248
|
{
|
248
249
|
#ifdef GOSU_IS_OPENGLES
|
249
|
-
throw
|
250
|
+
throw logic_error("Custom OpenGL ES is not supported yet");
|
250
251
|
#else
|
251
252
|
current_queue().gl([f] {
|
252
253
|
Graphics& cg = current_graphics();
|
@@ -258,7 +259,7 @@ void Gosu::Graphics::gl(Gosu::ZPos z, const std::function<void ()>& f)
|
|
258
259
|
}
|
259
260
|
|
260
261
|
void Gosu::Graphics::clip_to(double x, double y, double width, double height,
|
261
|
-
const
|
262
|
+
const function<void ()>& f)
|
262
263
|
{
|
263
264
|
double screen_height = current_graphics().pimpl->phys_height;
|
264
265
|
current_queue().begin_clipping(x, y, width, height, screen_height);
|
@@ -266,21 +267,20 @@ void Gosu::Graphics::clip_to(double x, double y, double width, double height,
|
|
266
267
|
current_queue().end_clipping();
|
267
268
|
}
|
268
269
|
|
269
|
-
|
270
|
-
|
270
|
+
unique_ptr<Gosu::ImageData> Gosu::Graphics::record(int width, int height,
|
271
|
+
const function<void ()>& f)
|
271
272
|
{
|
272
273
|
queues.resize(queues.size() + 1);
|
273
274
|
current_queue().set_recording();
|
274
275
|
|
275
276
|
f();
|
276
277
|
|
277
|
-
|
278
|
+
unique_ptr<ImageData> result(new Macro(current_queue(), width, height));
|
278
279
|
queues.pop_back();
|
279
280
|
return result;
|
280
281
|
}
|
281
282
|
|
282
|
-
void Gosu::Graphics::transform(const Gosu::Transform& transform,
|
283
|
-
const std::function<void ()>& f)
|
283
|
+
void Gosu::Graphics::transform(const Gosu::Transform& transform, const function<void ()>& f)
|
284
284
|
{
|
285
285
|
current_queue().push_transform(transform);
|
286
286
|
f();
|
@@ -341,6 +341,12 @@ void Gosu::Graphics::draw_quad(double x1, double y1, Color c1, double x2, double
|
|
341
341
|
current_queue().schedule_draw_op(op);
|
342
342
|
}
|
343
343
|
|
344
|
+
void Gosu::Graphics::draw_rect(double x, double y, double width, double height, Color c,
|
345
|
+
ZPos z, Gosu::AlphaMode mode)
|
346
|
+
{
|
347
|
+
draw_quad(x, y, c, x + width, y, c, x, y + height, c, x + width, y + height, c, z, mode);
|
348
|
+
}
|
349
|
+
|
344
350
|
void Gosu::Graphics::schedule_draw_op(const Gosu::DrawOp& op)
|
345
351
|
{
|
346
352
|
current_queue().schedule_draw_op(op);
|
@@ -363,7 +369,7 @@ void Gosu::Graphics::set_physical_resolution(unsigned phys_width, unsigned phys_
|
|
363
369
|
pimpl->update_base_transform();
|
364
370
|
}
|
365
371
|
|
366
|
-
|
372
|
+
unique_ptr<Gosu::ImageData> Gosu::Graphics::create_image(const Bitmap& src,
|
367
373
|
unsigned src_x, unsigned src_y, unsigned src_width, unsigned src_height, unsigned flags)
|
368
374
|
{
|
369
375
|
static const unsigned max_size = MAX_TEXTURE_SIZE;
|
@@ -380,8 +386,8 @@ std::unique_ptr<Gosu::ImageData> Gosu::Graphics::create_image(const Bitmap& src,
|
|
380
386
|
src_width == src_height &&
|
381
387
|
(src_width & (src_width - 1)) == 0 &&
|
382
388
|
src_width >= 64 && src_width <= max_size) {
|
383
|
-
|
384
|
-
|
389
|
+
shared_ptr<Texture> texture(new Texture(src_width, wants_retro));
|
390
|
+
unique_ptr<ImageData> data;
|
385
391
|
|
386
392
|
// Use the source bitmap directly if the source area completely covers
|
387
393
|
// it.
|
@@ -394,19 +400,17 @@ std::unique_ptr<Gosu::ImageData> Gosu::Graphics::create_image(const Bitmap& src,
|
|
394
400
|
data = texture->try_alloc(texture, bmp, 0);
|
395
401
|
}
|
396
402
|
|
397
|
-
if (!data.get())
|
398
|
-
|
399
|
-
}
|
400
|
-
return std::move(data);
|
403
|
+
if (!data.get()) throw logic_error("Internal texture block allocation error");
|
404
|
+
return data;
|
401
405
|
}
|
402
406
|
|
403
407
|
// Too large to fit on a single texture.
|
404
408
|
if (src_width > max_size - 2 || src_height > max_size - 2) {
|
405
409
|
Bitmap bmp(src_width, src_height);
|
406
410
|
bmp.insert(src, 0, 0, src_x, src_y, src_width, src_height);
|
407
|
-
|
411
|
+
unique_ptr<ImageData> lidi;
|
408
412
|
lidi.reset(new LargeImageData(bmp, max_size - 2, max_size - 2, flags));
|
409
|
-
return
|
413
|
+
return lidi;
|
410
414
|
}
|
411
415
|
|
412
416
|
Bitmap bmp;
|
@@ -416,24 +420,19 @@ std::unique_ptr<Gosu::ImageData> Gosu::Graphics::create_image(const Bitmap& src,
|
|
416
420
|
for (auto texture : textures) {
|
417
421
|
if (texture->retro() != wants_retro) continue;
|
418
422
|
|
419
|
-
|
423
|
+
unique_ptr<ImageData> data;
|
420
424
|
data = texture->try_alloc(texture, bmp, 1);
|
421
|
-
if (data.get())
|
422
|
-
return std::move(data);
|
423
|
-
}
|
425
|
+
if (data.get()) return data;
|
424
426
|
}
|
425
427
|
|
426
428
|
// All textures are full: Create a new one.
|
427
429
|
|
428
|
-
|
430
|
+
shared_ptr<Texture> texture;
|
429
431
|
texture.reset(new Texture(max_size, wants_retro));
|
430
432
|
textures.push_back(texture);
|
431
433
|
|
432
|
-
|
434
|
+
unique_ptr<ImageData> data;
|
433
435
|
data = texture->try_alloc(texture, bmp, 1);
|
434
|
-
if (!data.get())
|
435
|
-
|
436
|
-
}
|
437
|
-
|
438
|
-
return std::move(data);
|
436
|
+
if (!data.get()) throw logic_error("Internal texture block allocation error");
|
437
|
+
return data;
|
439
438
|
}
|
data/src/IO.cpp
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
#include <Gosu/IO.hpp>
|
2
2
|
#include <cassert>
|
3
3
|
#include <cstring>
|
4
|
+
using namespace std;
|
4
5
|
|
5
|
-
void Gosu::Reader::read(void* dest,
|
6
|
+
void Gosu::Reader::read(void* dest, size_t length)
|
6
7
|
{
|
7
8
|
res->read(pos, length, dest);
|
8
9
|
seek(length);
|
9
10
|
}
|
10
11
|
|
11
|
-
void Gosu::Writer::write(const void* source,
|
12
|
+
void Gosu::Writer::write(const void* source, size_t length)
|
12
13
|
{
|
13
14
|
// Try to resize the source if necessary.
|
14
15
|
if (pos + length > res->size()) {
|
@@ -19,40 +20,40 @@ void Gosu::Writer::write(const void* source, std::size_t length)
|
|
19
20
|
seek(length);
|
20
21
|
}
|
21
22
|
|
22
|
-
|
23
|
+
size_t Gosu::Buffer::size() const
|
23
24
|
{
|
24
25
|
return buf.size();
|
25
26
|
}
|
26
27
|
|
27
|
-
void Gosu::Buffer::resize(
|
28
|
+
void Gosu::Buffer::resize(size_t new_size)
|
28
29
|
{
|
29
30
|
buf.resize(new_size);
|
30
31
|
}
|
31
32
|
|
32
|
-
void Gosu::Buffer::read(
|
33
|
+
void Gosu::Buffer::read(size_t offset, size_t length, void* dest_buffer) const
|
33
34
|
{
|
34
35
|
assert (offset + length <= size());
|
35
36
|
if (length) {
|
36
|
-
|
37
|
+
memcpy(dest_buffer, &buf[offset], length);
|
37
38
|
}
|
38
39
|
}
|
39
40
|
|
40
|
-
void Gosu::Buffer::write(
|
41
|
+
void Gosu::Buffer::write(size_t offset, size_t length, const void* source_buffer)
|
41
42
|
{
|
42
43
|
assert (offset + length <= size());
|
43
44
|
if (length) {
|
44
|
-
|
45
|
+
memcpy(&buf[offset], source_buffer, length);
|
45
46
|
}
|
46
47
|
}
|
47
48
|
|
48
|
-
void Gosu::load_file(Buffer& buffer, const
|
49
|
+
void Gosu::load_file(Buffer& buffer, const string& filename)
|
49
50
|
{
|
50
51
|
File file(filename);
|
51
52
|
buffer.resize(file.size());
|
52
53
|
file.read(0, buffer.size(), buffer.data());
|
53
54
|
}
|
54
55
|
|
55
|
-
void Gosu::save_file(const Buffer& buffer, const
|
56
|
+
void Gosu::save_file(const Buffer& buffer, const string& filename)
|
56
57
|
{
|
57
58
|
File file(filename, FM_REPLACE);
|
58
59
|
file.write(0, buffer.size(), buffer.data());
|
data/src/Image.cpp
CHANGED
@@ -5,8 +5,15 @@
|
|
5
5
|
#include <Gosu/ImageData.hpp>
|
6
6
|
#include <Gosu/Math.hpp>
|
7
7
|
#include <stdexcept>
|
8
|
+
#include "EmptyImageData.hpp"
|
9
|
+
using namespace std;
|
8
10
|
|
9
|
-
Gosu::Image::Image(
|
11
|
+
Gosu::Image::Image()
|
12
|
+
: data_(EmptyImageData::instance_ptr())
|
13
|
+
{
|
14
|
+
}
|
15
|
+
|
16
|
+
Gosu::Image::Image(const string& filename, unsigned flags)
|
10
17
|
{
|
11
18
|
// Forward.
|
12
19
|
Bitmap bmp;
|
@@ -14,7 +21,7 @@ Gosu::Image::Image(const std::string& filename, unsigned flags)
|
|
14
21
|
Image(bmp, flags).data_.swap(data_);
|
15
22
|
}
|
16
23
|
|
17
|
-
Gosu::Image::Image(const
|
24
|
+
Gosu::Image::Image(const string& filename, unsigned src_x, unsigned src_y, unsigned src_width,
|
18
25
|
unsigned src_height, unsigned flags)
|
19
26
|
{
|
20
27
|
// Forward.
|
@@ -35,11 +42,11 @@ Gosu::Image::Image(const Bitmap& source, unsigned src_x, unsigned src_y, unsigne
|
|
35
42
|
{
|
36
43
|
}
|
37
44
|
|
38
|
-
Gosu::Image::Image(
|
45
|
+
Gosu::Image::Image(unique_ptr<ImageData>&& data)
|
39
46
|
: data_(data.release())
|
40
47
|
{
|
41
48
|
if (this->data_.get() == nullptr) {
|
42
|
-
throw
|
49
|
+
throw invalid_argument("Gosu::Image cannot be initialized with nullptr");
|
43
50
|
}
|
44
51
|
}
|
45
52
|
|
@@ -101,11 +108,11 @@ Gosu::ImageData& Gosu::Image::data() const
|
|
101
108
|
return *data_;
|
102
109
|
}
|
103
110
|
|
104
|
-
|
105
|
-
|
111
|
+
vector<Gosu::Image> Gosu::load_tiles(const Bitmap& bmp, int tile_width, int tile_height,
|
112
|
+
unsigned flags)
|
106
113
|
{
|
107
114
|
int tiles_x, tiles_y;
|
108
|
-
|
115
|
+
vector<Image> images;
|
109
116
|
|
110
117
|
if (tile_width > 0) {
|
111
118
|
tiles_x = bmp.width() / tile_width;
|
@@ -133,8 +140,8 @@ std::vector<Gosu::Image> Gosu::load_tiles(const Bitmap& bmp, int tile_width, int
|
|
133
140
|
return images;
|
134
141
|
}
|
135
142
|
|
136
|
-
|
137
|
-
|
143
|
+
vector<Gosu::Image> Gosu::load_tiles(const string& filename, int tile_width, int tile_height,
|
144
|
+
unsigned flags)
|
138
145
|
{
|
139
146
|
Bitmap bmp;
|
140
147
|
load_image_file(bmp, filename);
|
data/src/Input.cpp
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
#include <cstdlib>
|
10
10
|
#include <algorithm>
|
11
11
|
#include <array>
|
12
|
+
using namespace std;
|
12
13
|
|
13
14
|
static void require_sdl_video()
|
14
15
|
{
|
@@ -16,11 +17,11 @@ static void require_sdl_video()
|
|
16
17
|
if (!initialized) {
|
17
18
|
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
18
19
|
initialized = true;
|
19
|
-
|
20
|
+
atexit([] { SDL_QuitSubSystem(SDL_INIT_VIDEO); });
|
20
21
|
}
|
21
22
|
}
|
22
23
|
|
23
|
-
static
|
24
|
+
static array<bool, Gosu::NUM_BUTTONS> button_states = { { false } };
|
24
25
|
|
25
26
|
struct Gosu::Input::Impl
|
26
27
|
{
|
@@ -41,7 +42,7 @@ struct Gosu::Input::Impl
|
|
41
42
|
|
42
43
|
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
43
44
|
|
44
|
-
int num_gamepads =
|
45
|
+
int num_gamepads = min<int>(Gosu::NUM_GAMEPADS, SDL_NumJoysticks());
|
45
46
|
|
46
47
|
for (int i = 0; i < num_gamepads; ++i) {
|
47
48
|
// Prefer the SDL_GameController API...
|
@@ -60,9 +61,9 @@ struct Gosu::Input::Impl
|
|
60
61
|
|
61
62
|
~Impl()
|
62
63
|
{
|
63
|
-
|
64
|
+
for_each(joysticks.begin(), joysticks.end(), &SDL_JoystickClose);
|
64
65
|
joysticks.clear();
|
65
|
-
|
66
|
+
for_each(game_controllers.begin(), game_controllers.end(), &SDL_GameControllerClose);
|
66
67
|
game_controllers.clear();
|
67
68
|
|
68
69
|
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
@@ -139,7 +140,7 @@ struct Gosu::Input::Impl
|
|
139
140
|
return false;
|
140
141
|
}
|
141
142
|
|
142
|
-
typedef
|
143
|
+
typedef array<bool, GP_NUM_PER_GAMEPAD> GamepadBuffer;
|
143
144
|
|
144
145
|
void poll_gamepads()
|
145
146
|
{
|
@@ -148,7 +149,7 @@ struct Gosu::Input::Impl
|
|
148
149
|
// true. This is handy for singleplayer games.
|
149
150
|
GamepadBuffer any_gamepad = { false };
|
150
151
|
|
151
|
-
|
152
|
+
size_t available_gamepads = game_controllers.size() + joysticks.size();
|
152
153
|
|
153
154
|
for (int i = 0; i < available_gamepads; ++i) {
|
154
155
|
GamepadBuffer current_gamepad = { false };
|
@@ -213,15 +214,15 @@ struct Gosu::Input::Impl
|
|
213
214
|
private:
|
214
215
|
// For button down event: Button name value (>= 0)
|
215
216
|
// For button up event: ~Button name value (< 0)
|
216
|
-
|
217
|
+
vector<int> event_queue;
|
217
218
|
|
218
219
|
void enqueue_event(int id, bool down)
|
219
220
|
{
|
220
221
|
event_queue.push_back(down ? id : ~id);
|
221
222
|
}
|
222
223
|
|
223
|
-
|
224
|
-
|
224
|
+
vector<SDL_Joystick*> joysticks;
|
225
|
+
vector<SDL_GameController*> game_controllers;
|
225
226
|
|
226
227
|
// SDL returns axis values in the range -2^15 through 2^15-1, so we consider -2^14 through
|
227
228
|
// 2^14 (half of that range) the dead zone.
|
@@ -283,7 +284,7 @@ private:
|
|
283
284
|
if (value & SDL_HAT_DOWN) gamepad[GP_DOWN - GP_RANGE_BEGIN] = true;
|
284
285
|
}
|
285
286
|
|
286
|
-
int buttons =
|
287
|
+
int buttons = min<int>(GP_NUM_PER_GAMEPAD - 4, SDL_JoystickNumButtons(joystick));
|
287
288
|
for (int button = 0; button < buttons; ++button) {
|
288
289
|
if (SDL_JoystickGetButton(joystick, button)) {
|
289
290
|
gamepad[GP_BUTTON_0 + button - GP_RANGE_BEGIN] = true;
|
@@ -307,7 +308,7 @@ bool Gosu::Input::feed_sdl_event(void* event)
|
|
307
308
|
pimpl->feed_sdl_event(static_cast<SDL_Event*>(event));
|
308
309
|
}
|
309
310
|
|
310
|
-
|
311
|
+
string Gosu::Input::id_to_char(Button btn)
|
311
312
|
{
|
312
313
|
require_sdl_video();
|
313
314
|
|
@@ -322,17 +323,17 @@ std::string Gosu::Input::id_to_char(Button btn)
|
|
322
323
|
const char* name = SDL_GetKeyName(keycode);
|
323
324
|
if (name == nullptr) return "";
|
324
325
|
|
325
|
-
|
326
|
+
wstring wname = utf8_to_wstring(name);
|
326
327
|
if (wname.length() != 1) return "";
|
327
328
|
|
328
329
|
// Convert to lower case to be consistent with previous versions of Gosu.
|
329
330
|
// German umlauts are already reported in lower-case by SDL, anyway.
|
330
331
|
// (This should handle Turkish i/I just fine because it uses the current locale.)
|
331
|
-
wname[0] = (wchar_t)
|
332
|
+
wname[0] = (wchar_t) towlower((int) wname[0]);
|
332
333
|
return wstring_to_utf8(wname);
|
333
334
|
}
|
334
335
|
|
335
|
-
Gosu::Button Gosu::Input::char_to_id(
|
336
|
+
Gosu::Button Gosu::Input::char_to_id(string ch)
|
336
337
|
{
|
337
338
|
require_sdl_video();
|
338
339
|
|